commit 166b6eed405d08338af1cf2d8ea617a29e6edc83 Author: Simon Arlott Date: Fri Nov 26 17:50:33 2010 +0000 allow concurrent waiting to work diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 63ddb2f..397f8d5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1806,8 +1806,8 @@ static int ftdi_process_packet(struct tty_struct *tty, status = packet[0] & FTDI_STATUS_B0_MASK; if (status != priv->prev_status) { priv->diff_status |= status ^ priv->prev_status; - wake_up_interruptible(&priv->delta_msr_wait); priv->prev_status = status; + wake_up_interruptible_all(&priv->delta_msr_wait); } flag = TTY_NORMAL; @@ -2141,6 +2141,7 @@ static int ftdi_ioctl(struct tty_struct *tty, struct file *file, { struct usb_serial_port *port = tty->driver_data; struct ftdi_private *priv = usb_get_serial_port_data(port); + char status; dbg("%s cmd 0x%04x", __func__, cmd); @@ -2164,19 +2165,15 @@ static int ftdi_ioctl(struct tty_struct *tty, struct file *file, * This code is borrowed from linux/drivers/char/serial.c */ case TIOCMIWAIT: + if (priv != NULL) + status = priv->prev_status; while (priv != NULL) { interruptible_sleep_on(&priv->delta_msr_wait); /* see if a signal did it */ if (signal_pending(current)) return -ERESTARTSYS; else { - char diff = priv->diff_status; - - if (diff == 0) - return -EIO; /* no change => error */ - - /* Consume all events */ - priv->diff_status = 0; + char diff = status ^ priv->prev_status; /* Return 0 if caller wanted to know about these bits */