static DEFINE_MUTEX(table_lock);
 static LIST_HEAD(usb_serial_driver_list);
 
+/*
+ * Look up the serial structure.  If it is found and it hasn't been
+ * disconnected, return with its disc_mutex held and its refcount
+ * incremented.  Otherwise return NULL.
+ */
 struct usb_serial *usb_serial_get_by_index(unsigned index)
 {
        struct usb_serial *serial;
        mutex_lock(&table_lock);
        serial = serial_table[index];
 
-       if (serial)
-               kref_get(&serial->kref);
+       if (serial) {
+               mutex_lock(&serial->disc_mutex);
+               if (serial->disconnected) {
+                       mutex_unlock(&serial->disc_mutex);
+                       serial = NULL;
+               } else {
+                       kref_get(&serial->kref);
+               }
+       }
        mutex_unlock(&table_lock);
        return serial;
 }
 
        dbg("%s", __func__);
 
+       mutex_lock(&table_lock);
        for (i = 0; i < serial->num_ports; ++i)
                serial_table[serial->minor + i] = NULL;
+       mutex_unlock(&table_lock);
 }
 
 static void destroy_serial(struct kref *kref)
 
 void usb_serial_put(struct usb_serial *serial)
 {
-       mutex_lock(&table_lock);
        kref_put(&serial->kref, destroy_serial);
-       mutex_unlock(&table_lock);
 }
 
 /*****************************************************************************
                        return retval;
                /* allow the driver to update it */
                serial = usb_serial_get_by_index(tty->index);
-               if (serial->type->init_termios)
-                       serial->type->init_termios(tty);
-               usb_serial_put(serial);
+               if (serial) {
+                       if (serial->type->init_termios)
+                               serial->type->init_termios(tty);
+                       usb_serial_put(serial);
+                       mutex_unlock(&serial->disc_mutex);
+               }
        }
        /* Final install (we use the default method) */
        tty_driver_kref_get(driver);
                return -ENODEV;
        }
 
-       mutex_lock(&serial->disc_mutex);
        portNumber = tty->index - serial->minor;
        port = serial->port[portNumber];
        if (!port || serial->disconnected)
 
                seq_putc(m, '\n');
                usb_serial_put(serial);
+               mutex_unlock(&serial->disc_mutex);
        }
        return 0;
 }