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