btrfs-don-t-drop-path-when-printing-out-tree-errors-in-scrub.patch
usb-serial-add-modem-status-change-wait-queue.patch
usb-serial-fix-hang-when-opening-port.patch
+usb-quatech2-fix-use-after-free-in-tiocmiwait.patch
+usb-mos7840-fix-broken-tiocmiwait.patch
+usb-io_ti-fix-use-after-free-in-tiocmiwait.patch
+usb-oti6858-fix-use-after-free-in-tiocmiwait.patch
+usb-ftdi_sio-fix-use-after-free-in-tiocmiwait.patch
+usb-pl2303-fix-use-after-free-in-tiocmiwait.patch
+usb-mos7840-fix-use-after-free-in-tiocmiwait.patch
+usb-spcp8x5-fix-use-after-free-in-tiocmiwait.patch
+usb-ssu100-fix-use-after-free-in-tiocmiwait.patch
+usb-ch341-fix-use-after-free-in-tiocmiwait.patch
+usb-io_edgeport-fix-use-after-free-in-tiocmiwait.patch
+usb-f81232-fix-use-after-free-in-tiocmiwait.patch
+usb-ark3116-fix-use-after-free-in-tiocmiwait.patch
+usb-mct_u232-fix-use-after-free-in-tiocmiwait.patch
+usb-cypress_m8-fix-use-after-free-in-tiocmiwait.patch
+usb-ti_usb_3410_5052-fix-use-after-free-in-tiocmiwait.patch
--- /dev/null
+From 5018860321dc7a9e50a75d5f319bc981298fb5b7 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:11 +0100
+Subject: USB: ark3116: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 5018860321dc7a9e50a75d5f319bc981298fb5b7 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ark3116.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/serial/ark3116.c
++++ b/drivers/usb/serial/ark3116.c
+@@ -62,7 +62,6 @@ static int is_irda(struct usb_serial *se
+ }
+
+ struct ark3116_private {
+- wait_queue_head_t delta_msr_wait;
+ struct async_icount icount;
+ int irda; /* 1 for irda device */
+
+@@ -146,7 +145,6 @@ static int ark3116_port_probe(struct usb
+ if (!priv)
+ return -ENOMEM;
+
+- init_waitqueue_head(&priv->delta_msr_wait);
+ mutex_init(&priv->hw_lock);
+ spin_lock_init(&priv->status_lock);
+
+@@ -456,10 +454,14 @@ static int ark3116_ioctl(struct tty_stru
+ case TIOCMIWAIT:
+ for (;;) {
+ struct async_icount prev = priv->icount;
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ if ((prev.rng == priv->icount.rng) &&
+ (prev.dsr == priv->icount.dsr) &&
+ (prev.dcd == priv->icount.dcd) &&
+@@ -580,7 +582,7 @@ static void ark3116_update_msr(struct us
+ priv->icount.dcd++;
+ if (msr & UART_MSR_TERI)
+ priv->icount.rng++;
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ }
+ }
+
--- /dev/null
+From fa1e11d5231c001c80a479160b5832933c5d35fb Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:12 +0100
+Subject: USB: ch341: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit fa1e11d5231c001c80a479160b5832933c5d35fb upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ch341.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/ch341.c
++++ b/drivers/usb/serial/ch341.c
+@@ -80,7 +80,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
+
+ struct ch341_private {
+ spinlock_t lock; /* access lock */
+- wait_queue_head_t delta_msr_wait; /* wait queue for modem status */
+ unsigned baud_rate; /* set baud rate */
+ u8 line_control; /* set line control value RTS/DTR */
+ u8 line_status; /* active status of modem control inputs */
+@@ -252,7 +251,6 @@ static int ch341_port_probe(struct usb_s
+ return -ENOMEM;
+
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->delta_msr_wait);
+ priv->baud_rate = DEFAULT_BAUD_RATE;
+ priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
+
+@@ -298,7 +296,7 @@ static void ch341_dtr_rts(struct usb_ser
+ priv->line_control &= ~(CH341_BIT_RTS | CH341_BIT_DTR);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ch341_set_handshake(port->serial->dev, priv->line_control);
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ }
+
+ static void ch341_close(struct usb_serial_port *port)
+@@ -491,7 +489,7 @@ static void ch341_read_int_callback(stru
+ tty_kref_put(tty);
+ }
+
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ }
+
+ exit:
+@@ -517,11 +515,14 @@ static int wait_modem_info(struct usb_se
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ while (!multi_change) {
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->line_status;
+ multi_change = priv->multi_status_change;
--- /dev/null
+From 356050d8b1e526db093e9d2c78daf49d6bf418e3 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:13 +0100
+Subject: USB: cypress_m8: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 356050d8b1e526db093e9d2c78daf49d6bf418e3 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Also remove bogus test for private data pointer being NULL as it is
+never assigned in the loop.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/cypress_m8.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/serial/cypress_m8.c
++++ b/drivers/usb/serial/cypress_m8.c
+@@ -111,7 +111,6 @@ struct cypress_private {
+ int baud_rate; /* stores current baud rate in
+ integer form */
+ int isthrottled; /* if throttled, discard reads */
+- wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */
+ char prev_status, diff_status; /* used for TIOCMIWAIT */
+ /* we pass a pointer to this as the argument sent to
+ cypress_set_termios old_termios */
+@@ -449,7 +448,6 @@ static int cypress_generic_port_probe(st
+ kfree(priv);
+ return -ENOMEM;
+ }
+- init_waitqueue_head(&priv->delta_msr_wait);
+
+ usb_reset_configuration(serial->dev);
+
+@@ -868,12 +866,16 @@ static int cypress_ioctl(struct tty_stru
+ switch (cmd) {
+ /* This code comes from drivers/char/serial.c and ftdi_sio.c */
+ case TIOCMIWAIT:
+- while (priv != NULL) {
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ for (;;) {
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+- else {
++
++ if (port->serial->disconnected)
++ return -EIO;
++
++ {
+ char diff = priv->diff_status;
+ if (diff == 0)
+ return -EIO; /* no change => error */
+@@ -1187,7 +1189,7 @@ static void cypress_read_int_callback(st
+ if (priv->current_status != priv->prev_status) {
+ priv->diff_status |= priv->current_status ^
+ priv->prev_status;
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ priv->prev_status = priv->current_status;
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
--- /dev/null
+From 508f940f1407656076a2e7d8f7fa059b567ecac2 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:14 +0100
+Subject: USB: f81232: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 508f940f1407656076a2e7d8f7fa059b567ecac2 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/f81232.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/serial/f81232.c
++++ b/drivers/usb/serial/f81232.c
+@@ -47,7 +47,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
+
+ struct f81232_private {
+ spinlock_t lock;
+- wait_queue_head_t delta_msr_wait;
+ u8 line_control;
+ u8 line_status;
+ };
+@@ -112,7 +111,7 @@ static void f81232_process_read_urb(stru
+ line_status = priv->line_status;
+ priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
+ spin_unlock_irqrestore(&priv->lock, flags);
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+
+ if (!urb->actual_length)
+ return;
+@@ -261,11 +260,14 @@ static int wait_modem_info(struct usb_se
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ while (1) {
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->line_status;
+ spin_unlock_irqrestore(&priv->lock, flags);
+@@ -327,7 +329,6 @@ static int f81232_port_probe(struct usb_
+ return -ENOMEM;
+
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->delta_msr_wait);
+
+ usb_set_serial_port_data(port, priv);
+
--- /dev/null
+From 71ccb9b01981fabae27d3c98260ea4613207618e Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:15 +0100
+Subject: USB: ftdi_sio: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 71ccb9b01981fabae27d3c98260ea4613207618e upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+When switching to tty ports, some lifetime assumptions were changed.
+Specifically, close can now be called before the final tty reference is
+dropped as part of hangup at device disconnect. Even with the ftdi
+private-data refcounting this means that the port private data can be
+freed while a process is sleeping on modem-status changes and thus
+cannot be relied on to detect disconnects when woken up.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 19 ++++++++-----------
+ 1 file changed, 8 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -69,9 +69,7 @@ struct ftdi_private {
+ int flags; /* some ASYNC_xxxx flags are supported */
+ unsigned long last_dtr_rts; /* saved modem control outputs */
+ struct async_icount icount;
+- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+ char prev_status; /* Used for TIOCMIWAIT */
+- bool dev_gone; /* Used to abort TIOCMIWAIT */
+ char transmit_empty; /* If transmitter is empty or not */
+ __u16 interface; /* FT2232C, FT2232H or FT4232H port interface
+ (0 for FT232/245) */
+@@ -1692,10 +1690,8 @@ static int ftdi_sio_port_probe(struct us
+
+ kref_init(&priv->kref);
+ mutex_init(&priv->cfg_lock);
+- init_waitqueue_head(&priv->delta_msr_wait);
+
+ priv->flags = ASYNC_LOW_LATENCY;
+- priv->dev_gone = false;
+
+ if (quirk && quirk->port_probe)
+ quirk->port_probe(priv);
+@@ -1841,8 +1837,7 @@ static int ftdi_sio_port_remove(struct u
+ {
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+
+- priv->dev_gone = true;
+- wake_up_interruptible_all(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+
+ remove_sysfs_attrs(port);
+
+@@ -1991,7 +1986,7 @@ static int ftdi_process_packet(struct tt
+ if (diff_status & FTDI_RS0_RLSD)
+ priv->icount.dcd++;
+
+- wake_up_interruptible_all(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ priv->prev_status = status;
+ }
+
+@@ -2448,11 +2443,15 @@ static int ftdi_ioctl(struct tty_struct
+ */
+ case TIOCMIWAIT:
+ cprev = priv->icount;
+- while (!priv->dev_gone) {
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ for (;;) {
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ cnow = priv->icount;
+ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+@@ -2462,8 +2461,6 @@ static int ftdi_ioctl(struct tty_struct
+ }
+ cprev = cnow;
+ }
+- return -EIO;
+- break;
+ case TIOCSERGETLSR:
+ return get_lsr_info(port, (struct serial_struct __user *)arg);
+ break;
--- /dev/null
+From 333576255d4cfc53efd056aad438568184b36af6 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:16 +0100
+Subject: USB: io_edgeport: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 333576255d4cfc53efd056aad438568184b36af6 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_edgeport.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -110,7 +110,6 @@ struct edgeport_port {
+ wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
+ wait_queue_head_t wait_open; /* for handling sleeping while waiting for open to finish */
+ wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */
+- wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
+
+ struct async_icount icount;
+ struct usb_serial_port *port; /* loop back to the owner of this object */
+@@ -884,7 +883,6 @@ static int edge_open(struct tty_struct *
+ /* initialize our wait queues */
+ init_waitqueue_head(&edge_port->wait_open);
+ init_waitqueue_head(&edge_port->wait_chase);
+- init_waitqueue_head(&edge_port->delta_msr_wait);
+ init_waitqueue_head(&edge_port->wait_command);
+
+ /* initialize our icount structure */
+@@ -1669,13 +1667,17 @@ static int edge_ioctl(struct tty_struct
+ dev_dbg(&port->dev, "%s (%d) TIOCMIWAIT\n", __func__, port->number);
+ cprev = edge_port->icount;
+ while (1) {
+- prepare_to_wait(&edge_port->delta_msr_wait,
++ prepare_to_wait(&port->delta_msr_wait,
+ &wait, TASK_INTERRUPTIBLE);
+ schedule();
+- finish_wait(&edge_port->delta_msr_wait, &wait);
++ finish_wait(&port->delta_msr_wait, &wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ cnow = edge_port->icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+@@ -2055,7 +2057,7 @@ static void handle_new_msr(struct edgepo
+ icount->dcd++;
+ if (newMsr & EDGEPORT_MSR_DELTA_RI)
+ icount->rng++;
+- wake_up_interruptible(&edge_port->delta_msr_wait);
++ wake_up_interruptible(&edge_port->port->delta_msr_wait);
+ }
+
+ /* Save the new modem status */
--- /dev/null
+From 7b2459690584f239650a365f3411ba2ec1c6d1e0 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:17 +0100
+Subject: USB: io_ti: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 7b2459690584f239650a365f3411ba2ec1c6d1e0 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_ti.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -87,9 +87,6 @@ struct edgeport_port {
+ int close_pending;
+ int lsr_event;
+ struct async_icount icount;
+- wait_queue_head_t delta_msr_wait; /* for handling sleeping while
+- waiting for msr change to
+- happen */
+ struct edgeport_serial *edge_serial;
+ struct usb_serial_port *port;
+ __u8 bUartMode; /* Port type, 0: RS232, etc. */
+@@ -1518,7 +1515,7 @@ static void handle_new_msr(struct edgepo
+ icount->dcd++;
+ if (msr & EDGEPORT_MSR_DELTA_RI)
+ icount->rng++;
+- wake_up_interruptible(&edge_port->delta_msr_wait);
++ wake_up_interruptible(&edge_port->port->delta_msr_wait);
+ }
+
+ /* Save the new modem status */
+@@ -1821,7 +1818,6 @@ static int edge_open(struct tty_struct *
+ dev = port->serial->dev;
+
+ memset(&(edge_port->icount), 0x00, sizeof(edge_port->icount));
+- init_waitqueue_head(&edge_port->delta_msr_wait);
+
+ /* turn off loopback */
+ status = ti_do_config(edge_port, UMPC_SET_CLR_LOOPBACK, 0);
+@@ -2488,10 +2484,14 @@ static int edge_ioctl(struct tty_struct
+ dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__);
+ cprev = edge_port->icount;
+ while (1) {
+- interruptible_sleep_on(&edge_port->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ cnow = edge_port->icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
--- /dev/null
+From cf1d24443677a0758cfa88ca40f24858b89261c0 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:18 +0100
+Subject: USB: mct_u232: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit cf1d24443677a0758cfa88ca40f24858b89261c0 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mct_u232.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/serial/mct_u232.c
++++ b/drivers/usb/serial/mct_u232.c
+@@ -114,8 +114,6 @@ struct mct_u232_private {
+ unsigned char last_msr; /* Modem Status Register */
+ unsigned int rx_flags; /* Throttling flags */
+ struct async_icount icount;
+- wait_queue_head_t msr_wait; /* for handling sleeping while waiting
+- for msr change to happen */
+ };
+
+ #define THROTTLED 0x01
+@@ -409,7 +407,6 @@ static int mct_u232_port_probe(struct us
+ return -ENOMEM;
+
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->msr_wait);
+
+ usb_set_serial_port_data(port, priv);
+
+@@ -606,7 +603,7 @@ static void mct_u232_read_int_callback(s
+ tty_kref_put(tty);
+ }
+ #endif
+- wake_up_interruptible(&priv->msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ exit:
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+@@ -815,13 +812,17 @@ static int mct_u232_ioctl(struct tty_st
+ cprev = mct_u232_port->icount;
+ spin_unlock_irqrestore(&mct_u232_port->lock, flags);
+ for ( ; ; ) {
+- prepare_to_wait(&mct_u232_port->msr_wait,
++ prepare_to_wait(&port->delta_msr_wait,
+ &wait, TASK_INTERRUPTIBLE);
+ schedule();
+- finish_wait(&mct_u232_port->msr_wait, &wait);
++ finish_wait(&port->delta_msr_wait, &wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&mct_u232_port->lock, flags);
+ cnow = mct_u232_port->icount;
+ spin_unlock_irqrestore(&mct_u232_port->lock, flags);
--- /dev/null
+From e670c6af12517d08a403487b1122eecf506021cf Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:19 +0100
+Subject: USB: mos7840: fix broken TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit e670c6af12517d08a403487b1122eecf506021cf upstream.
+
+Make sure waiting processes are woken on modem-status changes.
+
+Currently processes are only woken on termios changes regardless of
+whether the modem status has changed.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7840.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -423,6 +423,9 @@ static void mos7840_handle_new_msr(struc
+ icount->rng++;
+ smp_wmb();
+ }
++
++ mos7840_port->delta_msr_cond = 1;
++ wake_up_interruptible(&mos7840_port->delta_msr_wait);
+ }
+ }
+
+@@ -2021,8 +2024,6 @@ static void mos7840_change_port_settings
+ mos7840_port->read_urb_busy = false;
+ }
+ }
+- wake_up(&mos7840_port->delta_msr_wait);
+- mos7840_port->delta_msr_cond = 1;
+ dev_dbg(&port->dev, "%s - mos7840_port->shadowLCR is End %x\n", __func__,
+ mos7840_port->shadowLCR);
+ }
--- /dev/null
+From a14430db686b8e459e1cf070a6ecf391515c9ab9 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:20 +0100
+Subject: USB: mos7840: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit a14430db686b8e459e1cf070a6ecf391515c9ab9 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/mos7840.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/mos7840.c
++++ b/drivers/usb/serial/mos7840.c
+@@ -219,7 +219,6 @@ struct moschip_port {
+ char open;
+ char open_ports;
+ wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
+- wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
+ int delta_msr_cond;
+ struct async_icount icount;
+ struct usb_serial_port *port; /* loop back to the owner of this object */
+@@ -425,7 +424,7 @@ static void mos7840_handle_new_msr(struc
+ }
+
+ mos7840_port->delta_msr_cond = 1;
+- wake_up_interruptible(&mos7840_port->delta_msr_wait);
++ wake_up_interruptible(&port->port->delta_msr_wait);
+ }
+ }
+
+@@ -1134,7 +1133,6 @@ static int mos7840_open(struct tty_struc
+
+ /* initialize our wait queues */
+ init_waitqueue_head(&mos7840_port->wait_chase);
+- init_waitqueue_head(&mos7840_port->delta_msr_wait);
+
+ /* initialize our icount structure */
+ memset(&(mos7840_port->icount), 0x00, sizeof(mos7840_port->icount));
+@@ -2224,13 +2222,18 @@ static int mos7840_ioctl(struct tty_stru
+ while (1) {
+ /* interruptible_sleep_on(&mos7840_port->delta_msr_wait); */
+ mos7840_port->delta_msr_cond = 0;
+- wait_event_interruptible(mos7840_port->delta_msr_wait,
+- (mos7840_port->
++ wait_event_interruptible(port->delta_msr_wait,
++ (port->serial->disconnected ||
++ mos7840_port->
+ delta_msr_cond == 1));
+
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ cnow = mos7840_port->icount;
+ smp_rmb();
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
--- /dev/null
+From 8edfdab37157d2683e51b8be5d3d5697f66a9f7b Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:21 +0100
+Subject: USB: oti6858: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 8edfdab37157d2683e51b8be5d3d5697f66a9f7b upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/oti6858.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/serial/oti6858.c
++++ b/drivers/usb/serial/oti6858.c
+@@ -188,7 +188,6 @@ struct oti6858_private {
+ u8 setup_done;
+ struct delayed_work delayed_setup_work;
+
+- wait_queue_head_t intr_wait;
+ struct usb_serial_port *port; /* USB port with which associated */
+ };
+
+@@ -339,7 +338,6 @@ static int oti6858_port_probe(struct usb
+ return -ENOMEM;
+
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->intr_wait);
+ priv->port = port;
+ INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
+ INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
+@@ -664,11 +662,15 @@ static int wait_modem_info(struct usb_se
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ while (1) {
+- wait_event_interruptible(priv->intr_wait,
++ wait_event_interruptible(port->delta_msr_wait,
++ port->serial->disconnected ||
+ priv->status.pin_state != prev);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->status.pin_state & PIN_MASK;
+ spin_unlock_irqrestore(&priv->lock, flags);
+@@ -763,7 +765,7 @@ static void oti6858_read_int_callback(st
+
+ if (!priv->transient) {
+ if (xs->pin_state != priv->status.pin_state)
+- wake_up_interruptible(&priv->intr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ memcpy(&priv->status, xs, OTI6858_CTRL_PKT_SIZE);
+ }
+
--- /dev/null
+From 40509ca982c00c4b70fc00be887509feca0bff15 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:22 +0100
+Subject: USB: pl2303: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 40509ca982c00c4b70fc00be887509feca0bff15 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/pl2303.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/pl2303.c
++++ b/drivers/usb/serial/pl2303.c
+@@ -139,7 +139,6 @@ struct pl2303_serial_private {
+
+ struct pl2303_private {
+ spinlock_t lock;
+- wait_queue_head_t delta_msr_wait;
+ u8 line_control;
+ u8 line_status;
+ };
+@@ -233,7 +232,6 @@ static int pl2303_port_probe(struct usb_
+ return -ENOMEM;
+
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->delta_msr_wait);
+
+ usb_set_serial_port_data(port, priv);
+
+@@ -607,11 +605,14 @@ static int wait_modem_info(struct usb_se
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ while (1) {
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->line_status;
+ spin_unlock_irqrestore(&priv->lock, flags);
+@@ -719,7 +720,7 @@ static void pl2303_update_line_status(st
+ spin_unlock_irqrestore(&priv->lock, flags);
+ if (priv->line_status & UART_BREAK_ERROR)
+ usb_serial_handle_break(port);
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+
+ tty = tty_port_tty_get(&port->port);
+ if (!tty)
+@@ -784,7 +785,7 @@ static void pl2303_process_read_urb(stru
+ line_status = priv->line_status;
+ priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
+ spin_unlock_irqrestore(&priv->lock, flags);
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+
+ if (!urb->actual_length)
+ return;
--- /dev/null
+From 69f87f40d2b98e8b4ab82a121fd2bd584690b887 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:23 +0100
+Subject: USB: quatech2: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 69f87f40d2b98e8b4ab82a121fd2bd584690b887 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/quatech2.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/quatech2.c
++++ b/drivers/usb/serial/quatech2.c
+@@ -128,7 +128,6 @@ struct qt2_port_private {
+ u8 shadowLSR;
+ u8 shadowMSR;
+
+- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+ struct async_icount icount;
+
+ struct usb_serial_port *port;
+@@ -506,8 +505,9 @@ static int wait_modem_info(struct usb_se
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ while (1) {
+- wait_event_interruptible(priv->delta_msr_wait,
+- ((priv->icount.rng != prev.rng) ||
++ wait_event_interruptible(port->delta_msr_wait,
++ (port->serial->disconnected ||
++ (priv->icount.rng != prev.rng) ||
+ (priv->icount.dsr != prev.dsr) ||
+ (priv->icount.dcd != prev.dcd) ||
+ (priv->icount.cts != prev.cts)));
+@@ -515,6 +515,9 @@ static int wait_modem_info(struct usb_se
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->lock, flags);
+ cur = priv->icount;
+ spin_unlock_irqrestore(&priv->lock, flags);
+@@ -841,7 +844,6 @@ static int qt2_port_probe(struct usb_ser
+
+ spin_lock_init(&port_priv->lock);
+ spin_lock_init(&port_priv->urb_lock);
+- init_waitqueue_head(&port_priv->delta_msr_wait);
+ port_priv->port = port;
+
+ port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
+@@ -984,7 +986,7 @@ static void qt2_update_msr(struct usb_se
+ if (newMSR & UART_MSR_TERI)
+ port_priv->icount.rng++;
+
+- wake_up_interruptible(&port_priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ }
+ }
+
--- /dev/null
+From dbcea7615d8d7d58f6ff49d2c5568113f70effe9 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:24 +0100
+Subject: USB: spcp8x5: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit dbcea7615d8d7d58f6ff49d2c5568113f70effe9 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/spcp8x5.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/serial/spcp8x5.c
++++ b/drivers/usb/serial/spcp8x5.c
+@@ -149,7 +149,6 @@ enum spcp8x5_type {
+ struct spcp8x5_private {
+ spinlock_t lock;
+ enum spcp8x5_type type;
+- wait_queue_head_t delta_msr_wait;
+ u8 line_control;
+ u8 line_status;
+ };
+@@ -179,7 +178,6 @@ static int spcp8x5_port_probe(struct usb
+ return -ENOMEM;
+
+ spin_lock_init(&priv->lock);
+- init_waitqueue_head(&priv->delta_msr_wait);
+ priv->type = type;
+
+ usb_set_serial_port_data(port , priv);
+@@ -476,7 +474,7 @@ static void spcp8x5_process_read_urb(str
+ priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
+ spin_unlock_irqrestore(&priv->lock, flags);
+ /* wake up the wait for termios */
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+
+ if (!urb->actual_length)
+ return;
+@@ -526,12 +524,15 @@ static int spcp8x5_wait_modem_info(struc
+
+ while (1) {
+ /* wake up in bulk read */
+- interruptible_sleep_on(&priv->delta_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->lock, flags);
+ status = priv->line_status;
+ spin_unlock_irqrestore(&priv->lock, flags);
--- /dev/null
+From 43a66b4c417ad15f6d2f632ce67ad195bdf999e8 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:25 +0100
+Subject: USB: ssu100: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 43a66b4c417ad15f6d2f632ce67ad195bdf999e8 upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ssu100.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/ssu100.c
++++ b/drivers/usb/serial/ssu100.c
+@@ -61,7 +61,6 @@ struct ssu100_port_private {
+ spinlock_t status_lock;
+ u8 shadowLSR;
+ u8 shadowMSR;
+- wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
+ struct async_icount icount;
+ };
+
+@@ -355,8 +354,9 @@ static int wait_modem_info(struct usb_se
+ spin_unlock_irqrestore(&priv->status_lock, flags);
+
+ while (1) {
+- wait_event_interruptible(priv->delta_msr_wait,
+- ((priv->icount.rng != prev.rng) ||
++ wait_event_interruptible(port->delta_msr_wait,
++ (port->serial->disconnected ||
++ (priv->icount.rng != prev.rng) ||
+ (priv->icount.dsr != prev.dsr) ||
+ (priv->icount.dcd != prev.dcd) ||
+ (priv->icount.cts != prev.cts)));
+@@ -364,6 +364,9 @@ static int wait_modem_info(struct usb_se
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
++ if (port->serial->disconnected)
++ return -EIO;
++
+ spin_lock_irqsave(&priv->status_lock, flags);
+ cur = priv->icount;
+ spin_unlock_irqrestore(&priv->status_lock, flags);
+@@ -445,7 +448,6 @@ static int ssu100_port_probe(struct usb_
+ return -ENOMEM;
+
+ spin_lock_init(&priv->status_lock);
+- init_waitqueue_head(&priv->delta_msr_wait);
+
+ usb_set_serial_port_data(port, priv);
+
+@@ -537,7 +539,7 @@ static void ssu100_update_msr(struct usb
+ priv->icount.dcd++;
+ if (msr & UART_MSR_TERI)
+ priv->icount.rng++;
+- wake_up_interruptible(&priv->delta_msr_wait);
++ wake_up_interruptible(&port->delta_msr_wait);
+ }
+ }
+
--- /dev/null
+From fc98ab873aa3dbe783ce56a2ffdbbe7c7609521a Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Tue, 19 Mar 2013 09:21:26 +0100
+Subject: USB: ti_usb_3410_5052: fix use-after-free in TIOCMIWAIT
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit fc98ab873aa3dbe783ce56a2ffdbbe7c7609521a upstream.
+
+Use the port wait queue and make sure to check the serial disconnected
+flag before accessing private port data after waking up.
+
+This is is needed as the private port data (including the wait queue
+itself) can be gone when waking up after a disconnect.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ti_usb_3410_5052.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -74,7 +74,6 @@ struct ti_port {
+ int tp_flags;
+ int tp_closing_wait;/* in .01 secs */
+ struct async_icount tp_icount;
+- wait_queue_head_t tp_msr_wait; /* wait for msr change */
+ wait_queue_head_t tp_write_wait;
+ struct ti_device *tp_tdev;
+ struct usb_serial_port *tp_port;
+@@ -432,7 +431,6 @@ static int ti_port_probe(struct usb_seri
+ else
+ tport->tp_uart_base_addr = TI_UART2_BASE_ADDR;
+ tport->tp_closing_wait = closing_wait;
+- init_waitqueue_head(&tport->tp_msr_wait);
+ init_waitqueue_head(&tport->tp_write_wait);
+ if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) {
+ kfree(tport);
+@@ -784,9 +782,13 @@ static int ti_ioctl(struct tty_struct *t
+ dev_dbg(&port->dev, "%s - TIOCMIWAIT\n", __func__);
+ cprev = tport->tp_icount;
+ while (1) {
+- interruptible_sleep_on(&tport->tp_msr_wait);
++ interruptible_sleep_on(&port->delta_msr_wait);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
++
++ if (port->serial->disconnected)
++ return -EIO;
++
+ cnow = tport->tp_icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+@@ -1400,7 +1402,7 @@ static void ti_handle_new_msr(struct ti_
+ icount->dcd++;
+ if (msr & TI_MSR_DELTA_RI)
+ icount->rng++;
+- wake_up_interruptible(&tport->tp_msr_wait);
++ wake_up_interruptible(&tport->tp_port->delta_msr_wait);
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+ }
+