diff options
author | Mika Båtsman <mika.batsman@gmail.com> | 2018-05-16 22:32:19 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-07-27 12:39:57 +0200 |
commit | 48db0089bff6f9154f6bd98ce7a6ae3786fa8ebe (patch) | |
tree | 67478a272e75ba6184eb6e799df11e734787eb26 /drivers/media/usb | |
parent | media: media-types.rst: codec entities can have more than one source pad (diff) | |
download | linux-48db0089bff6f9154f6bd98ce7a6ae3786fa8ebe.tar.xz linux-48db0089bff6f9154f6bd98ce7a6ae3786fa8ebe.zip |
media: gl861: fix probe of dvb_usb_gl861
Probe of dvb_usb_gl861 was working at least with v4.4. Noticed the issue
with v4.13 but according to similar issues the problem started with v4.9.
[ 15.288065] transfer buffer not dma capable
[ 15.288090] WARNING: CPU: 2 PID: 493 at drivers/usb/core/hcd.c:1595 usb_hcd_map_urb_for_dma+0x4e2/0x640
...CUT...
[ 15.288791] dvb_usb_gl861: probe of 3-7:1.0 failed with error -5
Tested with MSI Mega Sky 580 DVB-T Tuner [GL861]
[mchehab+samsung@kernel.org: rebased on the top of upstream]
Cc: stable@vger.kernel.org
Signed-off-by: Mika Båtsman <mika.batsman@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/usb')
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/gl861.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c index 9d154fdae45b..fee4b30df778 100644 --- a/drivers/media/usb/dvb-usb-v2/gl861.c +++ b/drivers/media/usb/dvb-usb-v2/gl861.c @@ -26,10 +26,14 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, if (wo) { req = GL861_REQ_I2C_WRITE; type = GL861_WRITE; + buf = kmemdup(wbuf, wlen, GFP_KERNEL); } else { /* rw */ req = GL861_REQ_I2C_READ; type = GL861_READ; + buf = kmalloc(rlen, GFP_KERNEL); } + if (!buf) + return -ENOMEM; switch (wlen) { case 1: @@ -42,24 +46,19 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, default: dev_err(&d->udev->dev, "%s: wlen=%d, aborting\n", KBUILD_MODNAME, wlen); + kfree(buf); return -EINVAL; } - buf = NULL; - if (rlen > 0) { - buf = kmalloc(rlen, GFP_KERNEL); - if (!buf) - return -ENOMEM; - } + usleep_range(1000, 2000); /* avoid I2C errors */ ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type, value, index, buf, rlen, 2000); - if (rlen > 0) { - if (ret > 0) - memcpy(rbuf, buf, rlen); - kfree(buf); - } + if (!wo && ret > 0) + memcpy(rbuf, buf, rlen); + + kfree(buf); return ret; } |