diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2017-02-04 16:56:32 +0000 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2017-03-16 02:27:10 +0000 |
commit | d1166ae7a5bb5dcb09ed7e0b7fcdf465a1f7ddaa (patch) | |
tree | 545ceeb7ca28eaaa82585d3e2c8e56c5d26713fe /drivers/net | |
parent | 9b103e24c94d4d39e750aec53ca90a5392a6d14a (diff) | |
download | linux-stable-d1166ae7a5bb5dcb09ed7e0b7fcdf465a1f7ddaa.tar.gz linux-stable-d1166ae7a5bb5dcb09ed7e0b7fcdf465a1f7ddaa.tar.bz2 linux-stable-d1166ae7a5bb5dcb09ed7e0b7fcdf465a1f7ddaa.zip |
rtl8150: Use heap buffers for all register access
commit 7926aff5c57b577ab0f43364ff0c59d968f6a414 upstream.
Allocating USB buffers on the stack is not portable, and no longer
works on x86_64 (with VMAP_STACK enabled as per default).
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/usb/rtl8150.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 6e87e5710048..eab8fba1f8c9 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -155,16 +155,36 @@ static const char driver_name [] = "rtl8150"; */ static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) { - return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), - RTL8150_REQ_GET_REGS, RTL8150_REQT_READ, - indx, 0, data, size, 500); + void *buf; + int ret; + + buf = kmalloc(size, GFP_NOIO); + if (!buf) + return -ENOMEM; + + ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), + RTL8150_REQ_GET_REGS, RTL8150_REQT_READ, + indx, 0, buf, size, 500); + if (ret > 0 && ret <= size) + memcpy(data, buf, ret); + kfree(buf); + return ret; } -static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) +static int set_registers(rtl8150_t * dev, u16 indx, u16 size, const void *data) { - return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), - RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE, - indx, 0, data, size, 500); + void *buf; + int ret; + + buf = kmemdup(data, size, GFP_NOIO); + if (!buf) + return -ENOMEM; + + ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), + RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE, + indx, 0, buf, size, 500); + kfree(buf); + return ret; } static void async_set_reg_cb(struct urb *urb) |