3.16.62-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Mika Båtsman <mika.bats...@gmail.com>

commit 48db0089bff6f9154f6bd98ce7a6ae3786fa8ebe upstream.

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+sams...@kernel.org: rebased on the top of upstream]
Signed-off-by: Mika Båtsman <mika.bats...@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+sams...@kernel.org>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <b...@decadent.org.uk>
---
 drivers/media/usb/dvb-usb-v2/gl861.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

--- 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_
        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_
        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;
-       }
+
        msleep(1); /* 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;
 }
 

Reply via email to