aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2008-05-16 04:27:05 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:48:12 -0400
commita8c4ea7a10f3c45eee27efb3954c3e03c297f0a7 (patch)
tree9042a6c059a7177180ade896a8c22dff4b1db59a
parente039fa4a4195ac4ee895e6f3d1334beed63256fe (diff)
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>
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index c8a0b34aecc8..6a51ae419e6f 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -169,10 +169,11 @@ static int upload_code(struct usb_device *udev,
169 if (flags & REBOOT) { 169 if (flags & REBOOT) {
170 u8 ret; 170 u8 ret;
171 171
172 /* Use "DMA-aware" buffer. */
172 r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 173 r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
173 USB_REQ_FIRMWARE_CONFIRM, 174 USB_REQ_FIRMWARE_CONFIRM,
174 USB_DIR_IN | USB_TYPE_VENDOR, 175 USB_DIR_IN | USB_TYPE_VENDOR,
175 0, 0, &ret, sizeof(ret), 5000 /* ms */); 176 0, 0, p, sizeof(ret), 5000 /* ms */);
176 if (r != sizeof(ret)) { 177 if (r != sizeof(ret)) {
177 dev_err(&udev->dev, 178 dev_err(&udev->dev,
178 "control request firmeware confirmation failed." 179 "control request firmeware confirmation failed."
@@ -181,6 +182,7 @@ static int upload_code(struct usb_device *udev,
181 r = -ENODEV; 182 r = -ENODEV;
182 goto error; 183 goto error;
183 } 184 }
185 ret = p[0];
184 if (ret & 0x80) { 186 if (ret & 0x80) {
185 dev_err(&udev->dev, 187 dev_err(&udev->dev,
186 "Internal error while downloading." 188 "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{ 314{
313 int r; 315 int r;
314 struct usb_device *udev = zd_usb_to_usbdev(usb); 316 struct usb_device *udev = zd_usb_to_usbdev(usb);
317 u8 *buf;
315 318
319 /* Use "DMA-aware" buffer. */
320 buf = kmalloc(len, GFP_KERNEL);
321 if (!buf)
322 return -ENOMEM;
316 r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 323 r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
317 USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0, 324 USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0,
318 data, len, 5000); 325 buf, len, 5000);
319 if (r < 0) { 326 if (r < 0) {
320 dev_err(&udev->dev, 327 dev_err(&udev->dev,
321 "read over firmware interface failed: %d\n", r); 328 "read over firmware interface failed: %d\n", r);
322 return r; 329 goto exit;
323 } else if (r != len) { 330 } else if (r != len) {
324 dev_err(&udev->dev, 331 dev_err(&udev->dev,
325 "incomplete read over firmware interface: %d/%d\n", 332 "incomplete read over firmware interface: %d/%d\n",
326 r, len); 333 r, len);
327 return -EIO; 334 r = -EIO;
335 goto exit;
328 } 336 }
329 337 r = 0;
330 return 0; 338 memcpy(data, buf, len);
339exit:
340 kfree(buf);
341 return r;
331} 342}
332 343
333#define urb_dev(urb) (&(urb)->dev->dev) 344#define urb_dev(urb) (&(urb)->dev->dev)