aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-06-02 11:54:11 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:47 -0400
commitc706ebdfc8955b850e477255a8c0f93f9f14712d (patch)
tree1f880601cdd2663ee4206783092d5fa9d90c8922 /drivers/usb/serial/usb-serial.c
parentc6994e6f067cf0fc4c6cca3d164018b1150916f8 (diff)
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>
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 1967a7edc10c..da890f030fac 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1046,10 +1046,15 @@ int usb_serial_probe(struct usb_interface *interface,
1046 1046
1047 dev_set_name(&port->dev, "ttyUSB%d", port->number); 1047 dev_set_name(&port->dev, "ttyUSB%d", port->number);
1048 dbg ("%s - registering %s", __func__, dev_name(&port->dev)); 1048 dbg ("%s - registering %s", __func__, dev_name(&port->dev));
1049 port->dev_state = PORT_REGISTERING;
1049 retval = device_register(&port->dev); 1050 retval = device_register(&port->dev);
1050 if (retval) 1051 if (retval) {
1051 dev_err(&port->dev, "Error registering port device, " 1052 dev_err(&port->dev, "Error registering port device, "
1052 "continuing\n"); 1053 "continuing\n");
1054 port->dev_state = PORT_UNREGISTERED;
1055 } else {
1056 port->dev_state = PORT_REGISTERED;
1057 }
1053 } 1058 }
1054 1059
1055 usb_serial_console_init(debug, minor); 1060 usb_serial_console_init(debug, minor);
@@ -1130,7 +1135,22 @@ void usb_serial_disconnect(struct usb_interface *interface)
1130 } 1135 }
1131 kill_traffic(port); 1136 kill_traffic(port);
1132 cancel_work_sync(&port->work); 1137 cancel_work_sync(&port->work);
1133 device_del(&port->dev); 1138 if (port->dev_state == PORT_REGISTERED) {
1139
1140 /* Make sure the port is bound so that the
1141 * driver's port_remove method is called.
1142 */
1143 if (!port->dev.driver) {
1144 int rc;
1145
1146 port->dev.driver =
1147 &serial->type->driver;
1148 rc = device_bind_driver(&port->dev);
1149 }
1150 port->dev_state = PORT_UNREGISTERING;
1151 device_del(&port->dev);
1152 port->dev_state = PORT_UNREGISTERED;
1153 }
1134 } 1154 }
1135 } 1155 }
1136 serial->type->shutdown(serial); 1156 serial->type->shutdown(serial);