Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -169,10 +169,11 @@ static int upload_code(struct usb_device *udev,
	if (flags & REBOOT) {
		u8 ret;

		/* Use "DMA-aware" buffer. */
		r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
			USB_REQ_FIRMWARE_CONFIRM,
			USB_DIR_IN | USB_TYPE_VENDOR,
			0, 0, &ret, sizeof(ret), 5000 /* ms */);
			0, 0, p, sizeof(ret), 5000 /* ms */);
		if (r != sizeof(ret)) {
			dev_err(&udev->dev,
				"control request firmeware confirmation failed."
@@ -181,6 +182,7 @@ static int upload_code(struct usb_device *udev,
				r = -ENODEV;
			goto error;
		}
		ret = p[0];
		if (ret & 0x80) {
			dev_err(&udev->dev,
				"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;
	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),
		USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0,
		data, len, 5000);
		buf, len, 5000);
	if (r < 0) {
		dev_err(&udev->dev,
			"read over firmware interface failed: %d\n", r);
		return r;
		goto exit;
	} else if (r != len) {
		dev_err(&udev->dev,
			"incomplete read over firmware interface: %d/%d\n",
			r, len);
		return -EIO;
		r = -EIO;
		goto exit;
	}

	return 0;
	r = 0;
	memcpy(data, buf, len);
exit:
	kfree(buf);
	return r;
}

#define urb_dev(urb) (&(urb)->dev->dev)