diff -Nru a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c --- a/drivers/usb/serial/usbserial.c Tue Feb 26 15:02:46 2002 +++ b/drivers/usb/serial/usbserial.c Tue Feb 26 15:02:46 2002 @@ -553,12 +553,21 @@ return; } + down (&port->sem); + + if (tty->driver_data == NULL) { + /* disconnect beat us to the punch here, so handle it gracefully */ + goto exit; + } + /* pass on to the driver specific version of this function if it is available */ if (serial->type->close) { serial->type->close(port, filp); } else { generic_close(port, filp); } +exit: + up (&port->sem); } @@ -1350,8 +1359,10 @@ if (serial) { /* fail all future close/read/write/ioctl/etc calls */ for (i = 0; i < serial->num_ports; ++i) { + down (&serial->port[i].sem); if (serial->port[i].tty != NULL) serial->port[i].tty->driver_data = NULL; + up (&serial->port[i].sem); } serial->dev = NULL; diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c --- a/drivers/usb/serial/visor.c Tue Feb 26 15:02:46 2002 +++ b/drivers/usb/serial/visor.c Tue Feb 26 15:02:46 2002 @@ -363,8 +363,6 @@ if (!serial) return; - down (&port->sem); - --port->open_count; if (port->open_count <= 0) { @@ -389,7 +387,6 @@ port->active = 0; port->open_count = 0; } - up (&port->sem); /* Uncomment the following line if you want to see some statistics in your syslog */ /* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */