aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 1967a7edc10c..d595aa5586a7 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -141,6 +141,14 @@ static void destroy_serial(struct kref *kref)
141 if (serial->minor != SERIAL_TTY_NO_MINOR) 141 if (serial->minor != SERIAL_TTY_NO_MINOR)
142 return_serial(serial); 142 return_serial(serial);
143 143
144 serial->type->release(serial);
145
146 for (i = 0; i < serial->num_ports; ++i) {
147 port = serial->port[i];
148 if (port)
149 put_device(&port->dev);
150 }
151
144 /* If this is a "fake" port, we have to clean it up here, as it will 152 /* If this is a "fake" port, we have to clean it up here, as it will
145 * not get cleaned up in port_release() as it was never registered with 153 * not get cleaned up in port_release() as it was never registered with
146 * the driver core */ 154 * the driver core */
@@ -148,9 +156,8 @@ static void destroy_serial(struct kref *kref)
148 for (i = serial->num_ports; 156 for (i = serial->num_ports;
149 i < serial->num_port_pointers; ++i) { 157 i < serial->num_port_pointers; ++i) {
150 port = serial->port[i]; 158 port = serial->port[i];
151 if (!port) 159 if (port)
152 continue; 160 port_free(port);
153 port_free(port);
154 } 161 }
155 } 162 }
156 163
@@ -1046,10 +1053,15 @@ int usb_serial_probe(struct usb_interface *interface,
1046 1053
1047 dev_set_name(&port->dev, "ttyUSB%d", port->number); 1054 dev_set_name(&port->dev, "ttyUSB%d", port->number);
1048 dbg ("%s - registering %s", __func__, dev_name(&port->dev)); 1055 dbg ("%s - registering %s", __func__, dev_name(&port->dev));
1056 port->dev_state = PORT_REGISTERING;
1049 retval = device_register(&port->dev); 1057 retval = device_register(&port->dev);
1050 if (retval) 1058 if (retval) {
1051 dev_err(&port->dev, "Error registering port device, " 1059 dev_err(&port->dev, "Error registering port device, "
1052 "continuing\n"); 1060 "continuing\n");
1061 port->dev_state = PORT_UNREGISTERED;
1062 } else {
1063 port->dev_state = PORT_REGISTERED;
1064 }
1053 } 1065 }
1054 1066
1055 usb_serial_console_init(debug, minor); 1067 usb_serial_console_init(debug, minor);
@@ -1113,10 +1125,6 @@ void usb_serial_disconnect(struct usb_interface *interface)
1113 serial->disconnected = 1; 1125 serial->disconnected = 1;
1114 mutex_unlock(&serial->disc_mutex); 1126 mutex_unlock(&serial->disc_mutex);
1115 1127
1116 /* Unfortunately, many of the sub-drivers expect the port structures
1117 * to exist when their shutdown method is called, so we have to go
1118 * through this awkward two-step unregistration procedure.
1119 */
1120 for (i = 0; i < serial->num_ports; ++i) { 1128 for (i = 0; i < serial->num_ports; ++i) {
1121 port = serial->port[i]; 1129 port = serial->port[i];
1122 if (port) { 1130 if (port) {
@@ -1130,17 +1138,25 @@ void usb_serial_disconnect(struct usb_interface *interface)
1130 } 1138 }
1131 kill_traffic(port); 1139 kill_traffic(port);
1132 cancel_work_sync(&port->work); 1140 cancel_work_sync(&port->work);
1133 device_del(&port->dev); 1141 if (port->dev_state == PORT_REGISTERED) {
1134 } 1142
1135 } 1143 /* Make sure the port is bound so that the
1136 serial->type->shutdown(serial); 1144 * driver's port_remove method is called.
1137 for (i = 0; i < serial->num_ports; ++i) { 1145 */
1138 port = serial->port[i]; 1146 if (!port->dev.driver) {
1139 if (port) { 1147 int rc;
1140 put_device(&port->dev); 1148
1141 serial->port[i] = NULL; 1149 port->dev.driver =
1150 &serial->type->driver;
1151 rc = device_bind_driver(&port->dev);
1152 }
1153 port->dev_state = PORT_UNREGISTERING;
1154 device_del(&port->dev);
1155 port->dev_state = PORT_UNREGISTERED;
1156 }
1142 } 1157 }
1143 } 1158 }
1159 serial->type->disconnect(serial);
1144 1160
1145 /* let the last holder of this object 1161 /* let the last holder of this object
1146 * cause it to be cleaned up */ 1162 * cause it to be cleaned up */
@@ -1318,7 +1334,8 @@ static void fixup_generic(struct usb_serial_driver *device)
1318 set_to_generic_if_null(device, chars_in_buffer); 1334 set_to_generic_if_null(device, chars_in_buffer);
1319 set_to_generic_if_null(device, read_bulk_callback); 1335 set_to_generic_if_null(device, read_bulk_callback);
1320 set_to_generic_if_null(device, write_bulk_callback); 1336 set_to_generic_if_null(device, write_bulk_callback);
1321 set_to_generic_if_null(device, shutdown); 1337 set_to_generic_if_null(device, disconnect);
1338 set_to_generic_if_null(device, release);
1322} 1339}
1323 1340
1324int usb_serial_register(struct usb_serial_driver *driver) 1341int usb_serial_register(struct usb_serial_driver *driver)