Commit a8c4ea7a authored by Atsushi Nemoto's avatar Atsushi Nemoto Committed by John W. Linville

zd1211rw: Use DMA-aware buffer for usb transfer

The zd1211rw driver uses unaligned stack buffer for USB control
message.  But it might cause stack corruption on non-coherent
platform, such as MIPS.  Use DMA-aware buffers for USB transfer.
Signed-off-by: default avatarAtsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent e039fa4a
...@@ -169,10 +169,11 @@ static int upload_code(struct usb_device *udev, ...@@ -169,10 +169,11 @@ static int upload_code(struct usb_device *udev,
if (flags & REBOOT) { if (flags & REBOOT) {
u8 ret; u8 ret;
/* Use "DMA-aware" buffer. */
r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
USB_REQ_FIRMWARE_CONFIRM, USB_REQ_FIRMWARE_CONFIRM,
USB_DIR_IN | USB_TYPE_VENDOR, USB_DIR_IN | USB_TYPE_VENDOR,
0, 0, &ret, sizeof(ret), 5000 /* ms */); 0, 0, p, sizeof(ret), 5000 /* ms */);
if (r != sizeof(ret)) { if (r != sizeof(ret)) {
dev_err(&udev->dev, dev_err(&udev->dev,
"control request firmeware confirmation failed." "control request firmeware confirmation failed."
...@@ -181,6 +182,7 @@ static int upload_code(struct usb_device *udev, ...@@ -181,6 +182,7 @@ static int upload_code(struct usb_device *udev,
r = -ENODEV; r = -ENODEV;
goto error; goto error;
} }
ret = p[0];
if (ret & 0x80) { if (ret & 0x80) {
dev_err(&udev->dev, dev_err(&udev->dev,
"Internal error while downloading." "Internal error while downloading."
...@@ -312,22 +314,31 @@ int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len) ...@@ -312,22 +314,31 @@ int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len)
{ {
int r; int r;
struct usb_device *udev = zd_usb_to_usbdev(usb); struct usb_device *udev = zd_usb_to_usbdev(usb);
u8 *buf;
/* Use "DMA-aware" buffer. */
buf = kmalloc(len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0, USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0,
data, len, 5000); buf, len, 5000);
if (r < 0) { if (r < 0) {
dev_err(&udev->dev, dev_err(&udev->dev,
"read over firmware interface failed: %d\n", r); "read over firmware interface failed: %d\n", r);
return r; goto exit;
} else if (r != len) { } else if (r != len) {
dev_err(&udev->dev, dev_err(&udev->dev,
"incomplete read over firmware interface: %d/%d\n", "incomplete read over firmware interface: %d/%d\n",
r, len); r, len);
return -EIO; r = -EIO;
goto exit;
} }
r = 0;
return 0; memcpy(data, buf, len);
exit:
kfree(buf);
return r;
} }
#define urb_dev(urb) (&(urb)->dev->dev) #define urb_dev(urb) (&(urb)->dev->dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment