|
@@ -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) */
|
|
@@ -1691,10 +1689,8 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
|
|
|
|
|
|
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);
|
|
@@ -1840,8 +1836,7 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
|
|
|
{
|
|
|
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);
|
|
|
|
|
@@ -1989,7 +1984,7 @@ static int ftdi_process_packet(struct usb_serial_port *port,
|
|
|
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;
|
|
|
}
|
|
|
|
|
@@ -2440,11 +2435,15 @@ static int ftdi_ioctl(struct tty_struct *tty,
|
|
|
*/
|
|
|
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)) ||
|
|
@@ -2454,8 +2453,6 @@ static int ftdi_ioctl(struct tty_struct *tty,
|
|
|
}
|
|
|
cprev = cnow;
|
|
|
}
|
|
|
- return -EIO;
|
|
|
- break;
|
|
|
case TIOCSERGETLSR:
|
|
|
return get_lsr_info(port, (struct serial_struct __user *)arg);
|
|
|
break;
|