diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2008-05-16 04:27:05 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:48:12 -0400 |
commit | a8c4ea7a10f3c45eee27efb3954c3e03c297f0a7 (patch) | |
tree | 9042a6c059a7177180ade896a8c22dff4b1db59a | |
parent | e039fa4a4195ac4ee895e6f3d1334beed63256fe (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.c | 23 |
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); |
339 | exit: | ||
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) |