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: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
committed by
John W. Linville
parent
e039fa4a41
commit
a8c4ea7a10
@@ -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,
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
||||||
|
Reference in New Issue
Block a user