diff options
author | Akihiro Tsukada <tskd08@gmail.com> | 2018-04-08 13:21:38 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-05-05 07:15:48 -0400 |
commit | 86f65c218123c4e36fd855fbbc38147ffaf29974 (patch) | |
tree | 74efeafe28cd8d1ca30f028891208d0152a860bb | |
parent | 87360e68b33f12c9e5b08636a3e349f851eba706 (diff) |
media: dvb-usb-v2/gl861: ensure USB message buffers DMA'able
i2c message buf might be on stack.
Signed-off-by: Akihiro Tsukada <tskd08@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/gl861.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c index b1dbb9af380b..4817dfd3e659 100644 --- a/drivers/media/usb/dvb-usb-v2/gl861.c +++ b/drivers/media/usb/dvb-usb-v2/gl861.c @@ -20,6 +20,8 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, u16 value = addr << (8 + 1); int wo = (rbuf == NULL || rlen == 0); /* write-only */ u8 req, type; + u8 *buf; + int ret; if (wo) { req = GL861_REQ_I2C_WRITE; @@ -42,11 +44,23 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, KBUILD_MODNAME, wlen); return -EINVAL; } - + buf = NULL; + if (rlen > 0) { + buf = kmalloc(rlen, GFP_KERNEL); + if (!buf) + return -ENOMEM; + } usleep_range(1000, 2000); /* avoid I2C errors */ - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type, - value, index, rbuf, rlen, 2000); + 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); + } + + return ret; } /* I2C */ |