aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/cypress_m8.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-03-22 15:45:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-03-22 15:45:55 -0400
commit8f46c507a2245697d6b3af75552c76d2f4fb3ed2 (patch)
tree2d3372ae90c6dd549e4b664a65826770a5edf450 /drivers/usb/serial/cypress_m8.c
parent70dc52faae971cb7cfd6b0d3a5824886bb5045bb (diff)
parentfc98ab873aa3dbe783ce56a2ffdbbe7c7609521a (diff)
Merge tag 'usb-3.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB fixes from Greg Kroah-Hartman: "Here are a number of USB fixes that resolve issues that have been reported against 3.9-rc3." * tag 'usb-3.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (37 commits) USB: ti_usb_3410_5052: fix use-after-free in TIOCMIWAIT USB: ssu100: fix use-after-free in TIOCMIWAIT USB: spcp8x5: fix use-after-free in TIOCMIWAIT USB: quatech2: fix use-after-free in TIOCMIWAIT USB: pl2303: fix use-after-free in TIOCMIWAIT USB: oti6858: fix use-after-free in TIOCMIWAIT USB: mos7840: fix use-after-free in TIOCMIWAIT USB: mos7840: fix broken TIOCMIWAIT USB: mct_u232: fix use-after-free in TIOCMIWAIT USB: io_ti: fix use-after-free in TIOCMIWAIT USB: io_edgeport: fix use-after-free in TIOCMIWAIT USB: ftdi_sio: fix use-after-free in TIOCMIWAIT USB: f81232: fix use-after-free in TIOCMIWAIT USB: cypress_m8: fix use-after-free in TIOCMIWAIT USB: ch341: fix use-after-free in TIOCMIWAIT USB: ark3116: fix use-after-free in TIOCMIWAIT USB: serial: add modem-status-change wait queue USB: serial: fix interface refcounting USB: io_ti: fix get_icount for two port adapters USB: garmin_gps: fix memory leak on disconnect ...
Diffstat (limited to 'drivers/usb/serial/cypress_m8.c')
-rw-r--r--drivers/usb/serial/cypress_m8.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 8efa19d0e9fb..ba7352e4187e 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -111,7 +111,6 @@ struct cypress_private {
111 int baud_rate; /* stores current baud rate in 111 int baud_rate; /* stores current baud rate in
112 integer form */ 112 integer form */
113 int isthrottled; /* if throttled, discard reads */ 113 int isthrottled; /* if throttled, discard reads */
114 wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */
115 char prev_status, diff_status; /* used for TIOCMIWAIT */ 114 char prev_status, diff_status; /* used for TIOCMIWAIT */
116 /* we pass a pointer to this as the argument sent to 115 /* we pass a pointer to this as the argument sent to
117 cypress_set_termios old_termios */ 116 cypress_set_termios old_termios */
@@ -449,7 +448,6 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
449 kfree(priv); 448 kfree(priv);
450 return -ENOMEM; 449 return -ENOMEM;
451 } 450 }
452 init_waitqueue_head(&priv->delta_msr_wait);
453 451
454 usb_reset_configuration(serial->dev); 452 usb_reset_configuration(serial->dev);
455 453
@@ -868,12 +866,16 @@ static int cypress_ioctl(struct tty_struct *tty,
868 switch (cmd) { 866 switch (cmd) {
869 /* This code comes from drivers/char/serial.c and ftdi_sio.c */ 867 /* This code comes from drivers/char/serial.c and ftdi_sio.c */
870 case TIOCMIWAIT: 868 case TIOCMIWAIT:
871 while (priv != NULL) { 869 for (;;) {
872 interruptible_sleep_on(&priv->delta_msr_wait); 870 interruptible_sleep_on(&port->delta_msr_wait);
873 /* see if a signal did it */ 871 /* see if a signal did it */
874 if (signal_pending(current)) 872 if (signal_pending(current))
875 return -ERESTARTSYS; 873 return -ERESTARTSYS;
876 else { 874
875 if (port->serial->disconnected)
876 return -EIO;
877
878 {
877 char diff = priv->diff_status; 879 char diff = priv->diff_status;
878 if (diff == 0) 880 if (diff == 0)
879 return -EIO; /* no change => error */ 881 return -EIO; /* no change => error */
@@ -1187,7 +1189,7 @@ static void cypress_read_int_callback(struct urb *urb)
1187 if (priv->current_status != priv->prev_status) { 1189 if (priv->current_status != priv->prev_status) {
1188 priv->diff_status |= priv->current_status ^ 1190 priv->diff_status |= priv->current_status ^
1189 priv->prev_status; 1191 priv->prev_status;
1190 wake_up_interruptible(&priv->delta_msr_wait); 1192 wake_up_interruptible(&port->delta_msr_wait);
1191 priv->prev_status = priv->current_status; 1193 priv->prev_status = priv->current_status;
1192 } 1194 }
1193 spin_unlock_irqrestore(&priv->lock, flags); 1195 spin_unlock_irqrestore(&priv->lock, flags);