diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2009-06-02 11:54:11 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:47 -0400 |
commit | c706ebdfc8955b850e477255a8c0f93f9f14712d (patch) | |
tree | 1f880601cdd2663ee4206783092d5fa9d90c8922 /drivers/usb/serial/usb-serial.c | |
parent | c6994e6f067cf0fc4c6cca3d164018b1150916f8 (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.c | 24 |
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); |