USB: usb-serial: call port_probe and port_remove at the right times
This patch (as1253) prevents the usb-serial core from calling a
driver's port_probe and port_remove methods more than once per port.
It also removes some unnecessary try_module_get() calls and adds a
missing port_remove method call in a failure path.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index 83bbb5b..ba555c5 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -59,23 +59,22 @@
retval = -ENODEV;
goto exit;
}
+ if (port->dev_state != PORT_REGISTERING)
+ goto exit;
driver = port->serial->type;
if (driver->port_probe) {
- if (!try_module_get(driver->driver.owner)) {
- dev_err(dev, "module get failed, exiting\n");
- retval = -EIO;
- goto exit;
- }
retval = driver->port_probe(port);
- module_put(driver->driver.owner);
if (retval)
goto exit;
}
retval = device_create_file(dev, &dev_attr_port_number);
- if (retval)
+ if (retval) {
+ if (driver->port_remove)
+ retval = driver->port_remove(port);
goto exit;
+ }
minor = port->number;
tty_register_device(usb_serial_tty_driver, minor, dev);
@@ -98,19 +97,15 @@
if (!port)
return -ENODEV;
+ if (port->dev_state != PORT_UNREGISTERING)
+ return retval;
+
device_remove_file(&port->dev, &dev_attr_port_number);
driver = port->serial->type;
- if (driver->port_remove) {
- if (!try_module_get(driver->driver.owner)) {
- dev_err(dev, "module get failed, exiting\n");
- retval = -EIO;
- goto exit;
- }
+ if (driver->port_remove)
retval = driver->port_remove(port);
- module_put(driver->driver.owner);
- }
-exit:
+
minor = port->number;
tty_unregister_device(usb_serial_tty_driver, minor);
dev_info(dev, "%s converter now disconnected from ttyUSB%d\n",