mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
USB serial fixes for 7.2-rc2
Here is a fix for an information leak in the keyspan_pda driver and three fixes for digi_acceleport addressing stuck rx if a port is closed while throttled, a hard lockup on disconnect and write buffer corruption. Included are also some new modem device ids. All have been in linux-next for a few days with no reported issues. -----BEGIN PGP SIGNATURE----- iJEEABYKADkWIQQHbPq+cpGvN/peuzMLxc3C7H1lCAUCakd3IxsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQC8XNwux9ZQhbZAEAwMNsbp0cXHxNt1ork9xu dxPabcqTYZ5FwOEGktY7k4oA+we0wwuk/5862uDVzG+hNESL65XIDfuPrtLq7l1C 4ZoO =ZNNY -----END PGP SIGNATURE----- Merge tag 'usb-serial-7.2-rc2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial into usb-linus Johan writes: USB serial fixes for 7.2-rc2 Here is a fix for an information leak in the keyspan_pda driver and three fixes for digi_acceleport addressing stuck rx if a port is closed while throttled, a hard lockup on disconnect and write buffer corruption. Included are also some new modem device ids. All have been in linux-next for a few days with no reported issues. * tag 'usb-serial-7.2-rc2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/johan/usb-serial: USB: serial: keyspan_pda: fix information leak USB: serial: option: add Telit Cinterion FE990D50 compositions USB: serial: digi_acceleport: fix broken rx after throttle USB: serial: digi_acceleport: fix hard lockup on disconnect USB: serial: digi_acceleport: fix write buffer corruption
This commit is contained in:
commit
07acd41f72
|
|
@ -392,12 +392,14 @@ static int digi_write_oob_command(struct usb_serial_port *port,
|
|||
len &= ~3;
|
||||
memcpy(oob_port->write_urb->transfer_buffer, buf, len);
|
||||
oob_port->write_urb->transfer_buffer_length = len;
|
||||
|
||||
ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);
|
||||
if (ret == 0) {
|
||||
oob_priv->dp_write_urb_in_use = 1;
|
||||
count -= len;
|
||||
buf += len;
|
||||
}
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
oob_priv->dp_write_urb_in_use = 1;
|
||||
count -= len;
|
||||
buf += len;
|
||||
}
|
||||
spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags);
|
||||
if (ret)
|
||||
|
|
@ -427,20 +429,22 @@ static int digi_write_inb_command(struct usb_serial_port *port,
|
|||
int len;
|
||||
struct digi_port *priv = usb_get_serial_port_data(port);
|
||||
unsigned char *data = port->write_urb->transfer_buffer;
|
||||
unsigned long expire;
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(&port->dev, "digi_write_inb_command: TOP: port=%d, count=%d\n",
|
||||
priv->dp_port_num, count);
|
||||
|
||||
if (timeout)
|
||||
timeout += jiffies;
|
||||
else
|
||||
timeout = ULONG_MAX;
|
||||
expire = jiffies + timeout;
|
||||
|
||||
spin_lock_irqsave(&priv->dp_port_lock, flags);
|
||||
while (count > 0 && ret == 0) {
|
||||
while (priv->dp_write_urb_in_use &&
|
||||
time_before(jiffies, timeout)) {
|
||||
while (priv->dp_write_urb_in_use) {
|
||||
if (timeout && time_after(jiffies, expire)) {
|
||||
ret = -ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
cond_wait_interruptible_timeout_irqrestore(
|
||||
&priv->write_wait, DIGI_RETRY_TIMEOUT,
|
||||
&priv->dp_port_lock, flags);
|
||||
|
|
@ -449,6 +453,9 @@ static int digi_write_inb_command(struct usb_serial_port *port,
|
|||
spin_lock_irqsave(&priv->dp_port_lock, flags);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
/* len must be a multiple of 4 and small enough to */
|
||||
/* guarantee the write will send buffered data first, */
|
||||
/* so commands are in order with data and not split */
|
||||
|
|
@ -1069,6 +1076,7 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||
unsigned char buf[32];
|
||||
struct digi_port *priv = usb_get_serial_port_data(port);
|
||||
struct ktermios not_termios;
|
||||
int throttled;
|
||||
|
||||
/* be sure the device is started up */
|
||||
if (digi_startup_device(port->serial) != 0)
|
||||
|
|
@ -1096,6 +1104,21 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||
not_termios.c_iflag = ~tty->termios.c_iflag;
|
||||
digi_set_termios(tty, port, ¬_termios);
|
||||
}
|
||||
|
||||
spin_lock_irq(&priv->dp_port_lock);
|
||||
throttled = priv->dp_throttle_restart;
|
||||
priv->dp_throttled = 0;
|
||||
priv->dp_throttle_restart = 0;
|
||||
spin_unlock_irq(&priv->dp_port_lock);
|
||||
|
||||
if (throttled) {
|
||||
ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
|
||||
if (ret) {
|
||||
dev_err(&port->dev, "failed to submit read urb: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ static int keyspan_pda_write_start(struct usb_serial_port *port)
|
|||
if (count == room)
|
||||
schedule_work(&priv->unthrottle_work);
|
||||
|
||||
return count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void keyspan_pda_write_bulk_callback(struct urb *urb)
|
||||
|
|
|
|||
|
|
@ -1325,6 +1325,22 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x30), /* Telit FE990D50 (RNDIS) */
|
||||
.driver_info = NCTRL(6) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0990, 0xff, 0xff, 0x60) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x30), /* Telit FE990D50 (rmnet) */
|
||||
.driver_info = NCTRL(5) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0991, 0xff, 0xff, 0x60) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x30), /* Telit FE990D50 (MBIM) */
|
||||
.driver_info = NCTRL(6) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0992, 0xff, 0xff, 0x60) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x30), /* Telit FE990D50 (ECM) */
|
||||
.driver_info = NCTRL(6) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x40) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x0993, 0xff, 0xff, 0x60) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1031, 0xff), /* Telit LE910C1-EUX */
|
||||
.driver_info = NCTRL(0) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user