diff options
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
| -rw-r--r-- | drivers/usb/serial/usb-serial.c | 31 | 
1 files changed, 10 insertions, 21 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 69230f01056..97355a15bbe 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1059,6 +1059,12 @@ int usb_serial_probe(struct usb_interface *interface,  		serial->attached = 1;  	} +	/* Avoid race with tty_open and serial_install by setting the +	 * disconnected flag and not clearing it until all ports have been +	 * registered. +	 */ +	serial->disconnected = 1; +  	if (get_free_serial(serial, num_ports, &minor) == NULL) {  		dev_err(&interface->dev, "No more free serial devices\n");  		goto probe_error; @@ -1070,19 +1076,16 @@ int usb_serial_probe(struct usb_interface *interface,  		port = serial->port[i];  		dev_set_name(&port->dev, "ttyUSB%d", port->number);  		dbg ("%s - registering %s", __func__, dev_name(&port->dev)); -		port->dev_state = PORT_REGISTERING;  		device_enable_async_suspend(&port->dev);  		retval = device_add(&port->dev); -		if (retval) { +		if (retval)  			dev_err(&port->dev, "Error registering port device, "  				"continuing\n"); -			port->dev_state = PORT_UNREGISTERED; -		} else { -			port->dev_state = PORT_REGISTERED; -		}  	} +	serial->disconnected = 0; +  	usb_serial_console_init(debug, minor);  exit: @@ -1124,22 +1127,8 @@ void usb_serial_disconnect(struct usb_interface *interface)  			}  			kill_traffic(port);  			cancel_work_sync(&port->work); -			if (port->dev_state == PORT_REGISTERED) { - -				/* Make sure the port is bound so that the -				 * driver's port_remove method is called. -				 */ -				if (!port->dev.driver) { -					int rc; - -					port->dev.driver = -							&serial->type->driver; -					rc = device_bind_driver(&port->dev); -				} -				port->dev_state = PORT_UNREGISTERING; +			if (device_is_registered(&port->dev))  				device_del(&port->dev); -				port->dev_state = PORT_UNREGISTERED; -			}  		}  	}  	serial->type->disconnect(serial);  |