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); */
