USB: keyspan: fix null-deref at disconnect and release
[pandora-kernel.git] / drivers / usb / serial / ark3116.c
index 18e875b..1a715f6 100644 (file)
@@ -49,7 +49,7 @@ static int debug;
 #define DRIVER_NAME "ark3116"
 
 /* usb timeout of 1 second */
-#define ARK_TIMEOUT (1*HZ)
+#define ARK_TIMEOUT 1000
 
 static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x6547, 0x0232) },
@@ -68,7 +68,6 @@ static int is_irda(struct usb_serial *serial)
 }
 
 struct ark3116_private {
-       wait_queue_head_t       delta_msr_wait;
        struct async_icount     icount;
        int                     irda;   /* 1 for irda device */
 
@@ -148,7 +147,6 @@ static int ark3116_attach(struct usb_serial *serial)
        if (!priv)
                return -ENOMEM;
 
-       init_waitqueue_head(&priv->delta_msr_wait);
        mutex_init(&priv->hw_lock);
        spin_lock_init(&priv->status_lock);
 
@@ -460,10 +458,14 @@ static int ark3116_ioctl(struct tty_struct *tty,
        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) &&
@@ -584,7 +586,7 @@ static void ark3116_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);
        }
 }