--- drivers/usb/serial/usb-serial.c.alt 2006-12-17 14:57:40.000000000 +0100 +++ drivers/usb/serial/usb-serial.c 2006-12-20 18:22:41.000000000 +0100 @@ -59,6 +59,7 @@ static int debug; static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ +static DECLARE_MUTEX(table_lock); /* lock for serial_table */ static LIST_HEAD(usb_serial_driver_list); struct usb_serial *usb_serial_get_by_index(unsigned index) @@ -176,7 +177,9 @@ dbg("%s", __FUNCTION__); /* get the serial object associated with this tty pointer */ + mutex_lock(&table_lock); serial = usb_serial_get_by_index(tty->index); + mutex_unlock(&table_lock); if (!serial) { tty->driver_data = NULL; return -ENODEV; @@ -265,7 +268,9 @@ } mutex_unlock(&port->mutex); + mutex_lock(&table_lock); usb_serial_put(port->serial); + mutex_unlock(&table_lock); } static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) @@ -771,7 +776,9 @@ num_ports = type->num_ports; } + mutex_lock(&table_lock); if (get_free_serial (serial, num_ports, &minor) == NULL) { + mutex_unlock(&table_lock); dev_err(&interface->dev, "No more free serial devices\n"); kfree (serial); return -ENOMEM; @@ -921,6 +928,7 @@ if (retval > 0) { /* quietly accept this device, but don't bind to a serial port * as it's about to disappear */ + mutex_unlock(&table_lock); goto exit; } } @@ -941,6 +949,7 @@ "continuing\n"); } + mutex_unlock(&table_lock); usb_serial_console_init (debug, minor); exit: @@ -980,6 +989,7 @@ /* return the minor range that this device had */ return_serial (serial); + mutex_unlock(&table_lock); /* free up any memory that we allocated */ for (i = 0; i < serial->num_port_pointers; ++i) @@ -999,6 +1009,7 @@ dbg ("%s", __FUNCTION__); usb_set_intfdata (interface, NULL); + mutex_lock(&table_lock); if (serial) { for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; @@ -1009,6 +1020,7 @@ * cause it to be cleaned up */ usb_serial_put(serial); } + mutex_unlock(&table_lock); dev_info(dev, "device disconnected\n"); } @@ -1060,6 +1072,7 @@ usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; usb_serial_tty_driver->init_termios = tty_std_termios; usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; + init_MUTEX(&table_lock); tty_set_operations(usb_serial_tty_driver, &serial_ops); result = tty_register_driver(usb_serial_tty_driver); if (result) {