USB: serial: option: add support for Novatel E371 PCIe card
[pandora-kernel.git] / drivers / usb / serial / ssu100.c
index 87362e4..bf1f8ea 100644 (file)
@@ -78,7 +78,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;
 };
 
@@ -387,8 +386,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
        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)));
@@ -396,6 +396,9 @@ static int wait_modem_info(struct usb_serial_port *port, unsigned int arg)
                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);
@@ -478,7 +481,6 @@ static int ssu100_attach(struct usb_serial *serial)
        }
 
        spin_lock_init(&priv->status_lock);
-       init_waitqueue_head(&priv->delta_msr_wait);
        usb_set_serial_port_data(port, priv);
 
        return ssu100_initdevice(serial->dev);
@@ -533,19 +535,16 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on)
 
        dbg("%s\n", __func__);
 
-       mutex_lock(&port->serial->disc_mutex);
-       if (!port->serial->disconnected) {
-               /* Disable flow control */
-               if (!on &&
-                   ssu100_setregister(dev, 0, UART_MCR, 0) < 0)
+       /* Disable flow control */
+       if (!on) {
+               if (ssu100_setregister(dev, 0, UART_MCR, 0) < 0)
                        dev_err(&port->dev, "error from flowcontrol urb\n");
-               /* drop RTS and DTR */
-               if (on)
-                       set_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
-               else
-                       clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
        }
-       mutex_unlock(&port->serial->disc_mutex);
+       /* drop RTS and DTR */
+       if (on)
+               set_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
+       else
+               clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS);
 }
 
 static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)
@@ -567,7 +566,7 @@ static void ssu100_update_msr(struct usb_serial_port *port, u8 msr)
                        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);
        }
 }