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

Commit 54696754 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

USB: serial: iuu_phoenix: fix DMA from stack



commit 54d0a3ab80f49f19ee916def62fe067596833403 upstream.

Stack-allocated buffers cannot be used for DMA (on all architectures) so
allocate the flush command buffer using kmalloc().

Fixes: 60a8fc01 ("USB: add iuu_phoenix driver")
Cc: stable <stable@vger.kernel.org>     # 2.6.25
Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f725e361
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -553,23 +553,29 @@ static int iuu_uart_flush(struct usb_serial_port *port)
	struct device *dev = &port->dev;
	int i;
	int status;
	u8 rxcmd = IUU_UART_RX;
	u8 *rxcmd;
	struct iuu_private *priv = usb_get_serial_port_data(port);

	if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0)
		return -EIO;

	rxcmd = kmalloc(1, GFP_KERNEL);
	if (!rxcmd)
		return -ENOMEM;

	rxcmd[0] = IUU_UART_RX;

	for (i = 0; i < 2; i++) {
		status = bulk_immediate(port, &rxcmd, 1);
		status = bulk_immediate(port, rxcmd, 1);
		if (status != IUU_OPERATION_OK) {
			dev_dbg(dev, "%s - uart_flush_write error\n", __func__);
			return status;
			goto out_free;
		}

		status = read_immediate(port, &priv->len, 1);
		if (status != IUU_OPERATION_OK) {
			dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
			return status;
			goto out_free;
		}

		if (priv->len > 0) {
@@ -577,12 +583,16 @@ static int iuu_uart_flush(struct usb_serial_port *port)
			status = read_immediate(port, priv->buf, priv->len);
			if (status != IUU_OPERATION_OK) {
				dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
				return status;
				goto out_free;
			}
		}
	}
	dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__);
	iuu_led(port, 0, 0xF000, 0, 0xFF);

out_free:
	kfree(rxcmd);

	return status;
}