| From 7926aff5c57b577ab0f43364ff0c59d968f6a414 Mon Sep 17 00:00:00 2001 |
| From: Ben Hutchings <ben@decadent.org.uk> |
| Date: Sat, 4 Feb 2017 16:56:32 +0000 |
| Subject: [PATCH] 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> |
| |
| diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c |
| index 95b7bd0d7abc..c81c79110cef 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) |
| -- |
| 2.12.0 |
| |