diff options
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 95 |
1 files changed, 20 insertions, 75 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 80c1f4d8e910..f1a1f0fb6d1b 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -43,8 +43,6 @@ | |||
43 | #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" | 43 | #define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" |
44 | #define DRIVER_DESC "USB Serial Driver core" | 44 | #define DRIVER_DESC "USB Serial Driver core" |
45 | 45 | ||
46 | static void port_free(struct usb_serial_port *port); | ||
47 | |||
48 | /* Driver structure we register with the USB core */ | 46 | /* Driver structure we register with the USB core */ |
49 | static struct usb_driver usb_serial_driver = { | 47 | static struct usb_driver usb_serial_driver = { |
50 | .name = "usbserial", | 48 | .name = "usbserial", |
@@ -145,27 +143,16 @@ static void destroy_serial(struct kref *kref) | |||
145 | 143 | ||
146 | serial->type->release(serial); | 144 | serial->type->release(serial); |
147 | 145 | ||
148 | for (i = 0; i < serial->num_ports; ++i) { | 146 | /* Now that nothing is using the ports, they can be freed */ |
147 | for (i = 0; i < serial->num_port_pointers; ++i) { | ||
149 | port = serial->port[i]; | 148 | port = serial->port[i]; |
150 | if (port) | 149 | if (port) { |
150 | port->serial = NULL; | ||
151 | put_device(&port->dev); | 151 | put_device(&port->dev); |
152 | } | ||
153 | |||
154 | /* If this is a "fake" port, we have to clean it up here, as it will | ||
155 | * not get cleaned up in port_release() as it was never registered with | ||
156 | * the driver core */ | ||
157 | if (serial->num_ports < serial->num_port_pointers) { | ||
158 | for (i = serial->num_ports; | ||
159 | i < serial->num_port_pointers; ++i) { | ||
160 | port = serial->port[i]; | ||
161 | if (port) | ||
162 | port_free(port); | ||
163 | } | 152 | } |
164 | } | 153 | } |
165 | 154 | ||
166 | usb_put_dev(serial->dev); | 155 | usb_put_dev(serial->dev); |
167 | |||
168 | /* free up any memory that we allocated */ | ||
169 | kfree(serial); | 156 | kfree(serial); |
170 | } | 157 | } |
171 | 158 | ||
@@ -201,8 +188,6 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
201 | port = serial->port[portNumber]; | 188 | port = serial->port[portNumber]; |
202 | if (!port || serial->disconnected) | 189 | if (!port || serial->disconnected) |
203 | retval = -ENODEV; | 190 | retval = -ENODEV; |
204 | else | ||
205 | get_device(&port->dev); | ||
206 | /* | 191 | /* |
207 | * Note: Our locking order requirement does not allow port->mutex | 192 | * Note: Our locking order requirement does not allow port->mutex |
208 | * to be acquired while serial->disc_mutex is held. | 193 | * to be acquired while serial->disc_mutex is held. |
@@ -213,7 +198,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
213 | 198 | ||
214 | if (mutex_lock_interruptible(&port->mutex)) { | 199 | if (mutex_lock_interruptible(&port->mutex)) { |
215 | retval = -ERESTARTSYS; | 200 | retval = -ERESTARTSYS; |
216 | goto bailout_port_put; | 201 | goto bailout_serial_put; |
217 | } | 202 | } |
218 | 203 | ||
219 | ++port->port.count; | 204 | ++port->port.count; |
@@ -273,8 +258,6 @@ bailout_mutex_unlock: | |||
273 | tty->driver_data = NULL; | 258 | tty->driver_data = NULL; |
274 | tty_port_tty_set(&port->port, NULL); | 259 | tty_port_tty_set(&port->port, NULL); |
275 | mutex_unlock(&port->mutex); | 260 | mutex_unlock(&port->mutex); |
276 | bailout_port_put: | ||
277 | put_device(&port->dev); | ||
278 | bailout_serial_put: | 261 | bailout_serial_put: |
279 | usb_serial_put(serial); | 262 | usb_serial_put(serial); |
280 | return retval; | 263 | return retval; |
@@ -333,14 +316,13 @@ static void serial_do_free(struct tty_struct *tty) | |||
333 | 316 | ||
334 | serial = port->serial; | 317 | serial = port->serial; |
335 | owner = serial->type->driver.owner; | 318 | owner = serial->type->driver.owner; |
336 | put_device(&port->dev); | 319 | |
337 | /* Mustn't dereference port any more */ | ||
338 | mutex_lock(&serial->disc_mutex); | 320 | mutex_lock(&serial->disc_mutex); |
339 | if (!serial->disconnected) | 321 | if (!serial->disconnected) |
340 | usb_autopm_put_interface(serial->interface); | 322 | usb_autopm_put_interface(serial->interface); |
341 | mutex_unlock(&serial->disc_mutex); | 323 | mutex_unlock(&serial->disc_mutex); |
324 | |||
342 | usb_serial_put(serial); | 325 | usb_serial_put(serial); |
343 | /* Mustn't dereference serial any more */ | ||
344 | module_put(owner); | 326 | module_put(owner); |
345 | } | 327 | } |
346 | 328 | ||
@@ -581,14 +563,6 @@ static void usb_serial_port_work(struct work_struct *work) | |||
581 | tty_kref_put(tty); | 563 | tty_kref_put(tty); |
582 | } | 564 | } |
583 | 565 | ||
584 | static void port_release(struct device *dev) | ||
585 | { | ||
586 | struct usb_serial_port *port = to_usb_serial_port(dev); | ||
587 | |||
588 | dbg ("%s - %s", __func__, dev_name(dev)); | ||
589 | port_free(port); | ||
590 | } | ||
591 | |||
592 | static void kill_traffic(struct usb_serial_port *port) | 566 | static void kill_traffic(struct usb_serial_port *port) |
593 | { | 567 | { |
594 | usb_kill_urb(port->read_urb); | 568 | usb_kill_urb(port->read_urb); |
@@ -608,8 +582,12 @@ static void kill_traffic(struct usb_serial_port *port) | |||
608 | usb_kill_urb(port->interrupt_out_urb); | 582 | usb_kill_urb(port->interrupt_out_urb); |
609 | } | 583 | } |
610 | 584 | ||
611 | static void port_free(struct usb_serial_port *port) | 585 | static void port_release(struct device *dev) |
612 | { | 586 | { |
587 | struct usb_serial_port *port = to_usb_serial_port(dev); | ||
588 | |||
589 | dbg ("%s - %s", __func__, dev_name(dev)); | ||
590 | |||
613 | /* | 591 | /* |
614 | * Stop all the traffic before cancelling the work, so that | 592 | * Stop all the traffic before cancelling the work, so that |
615 | * nobody will restart it by calling usb_serial_port_softint. | 593 | * nobody will restart it by calling usb_serial_port_softint. |
@@ -955,6 +933,11 @@ int usb_serial_probe(struct usb_interface *interface, | |||
955 | mutex_init(&port->mutex); | 933 | mutex_init(&port->mutex); |
956 | INIT_WORK(&port->work, usb_serial_port_work); | 934 | INIT_WORK(&port->work, usb_serial_port_work); |
957 | serial->port[i] = port; | 935 | serial->port[i] = port; |
936 | port->dev.parent = &interface->dev; | ||
937 | port->dev.driver = NULL; | ||
938 | port->dev.bus = &usb_serial_bus_type; | ||
939 | port->dev.release = &port_release; | ||
940 | device_initialize(&port->dev); | ||
958 | } | 941 | } |
959 | 942 | ||
960 | /* set up the endpoint information */ | 943 | /* set up the endpoint information */ |
@@ -1097,15 +1080,10 @@ int usb_serial_probe(struct usb_interface *interface, | |||
1097 | /* register all of the individual ports with the driver core */ | 1080 | /* register all of the individual ports with the driver core */ |
1098 | for (i = 0; i < num_ports; ++i) { | 1081 | for (i = 0; i < num_ports; ++i) { |
1099 | port = serial->port[i]; | 1082 | port = serial->port[i]; |
1100 | port->dev.parent = &interface->dev; | ||
1101 | port->dev.driver = NULL; | ||
1102 | port->dev.bus = &usb_serial_bus_type; | ||
1103 | port->dev.release = &port_release; | ||
1104 | |||
1105 | dev_set_name(&port->dev, "ttyUSB%d", port->number); | 1083 | dev_set_name(&port->dev, "ttyUSB%d", port->number); |
1106 | dbg ("%s - registering %s", __func__, dev_name(&port->dev)); | 1084 | dbg ("%s - registering %s", __func__, dev_name(&port->dev)); |
1107 | port->dev_state = PORT_REGISTERING; | 1085 | port->dev_state = PORT_REGISTERING; |
1108 | retval = device_register(&port->dev); | 1086 | retval = device_add(&port->dev); |
1109 | if (retval) { | 1087 | if (retval) { |
1110 | dev_err(&port->dev, "Error registering port device, " | 1088 | dev_err(&port->dev, "Error registering port device, " |
1111 | "continuing\n"); | 1089 | "continuing\n"); |
@@ -1123,39 +1101,7 @@ exit: | |||
1123 | return 0; | 1101 | return 0; |
1124 | 1102 | ||
1125 | probe_error: | 1103 | probe_error: |
1126 | for (i = 0; i < num_bulk_in; ++i) { | 1104 | usb_serial_put(serial); |
1127 | port = serial->port[i]; | ||
1128 | if (!port) | ||
1129 | continue; | ||
1130 | usb_free_urb(port->read_urb); | ||
1131 | kfree(port->bulk_in_buffer); | ||
1132 | } | ||
1133 | for (i = 0; i < num_bulk_out; ++i) { | ||
1134 | port = serial->port[i]; | ||
1135 | if (!port) | ||
1136 | continue; | ||
1137 | usb_free_urb(port->write_urb); | ||
1138 | kfree(port->bulk_out_buffer); | ||
1139 | } | ||
1140 | for (i = 0; i < num_interrupt_in; ++i) { | ||
1141 | port = serial->port[i]; | ||
1142 | if (!port) | ||
1143 | continue; | ||
1144 | usb_free_urb(port->interrupt_in_urb); | ||
1145 | kfree(port->interrupt_in_buffer); | ||
1146 | } | ||
1147 | for (i = 0; i < num_interrupt_out; ++i) { | ||
1148 | port = serial->port[i]; | ||
1149 | if (!port) | ||
1150 | continue; | ||
1151 | usb_free_urb(port->interrupt_out_urb); | ||
1152 | kfree(port->interrupt_out_buffer); | ||
1153 | } | ||
1154 | |||
1155 | /* free up any memory that we allocated */ | ||
1156 | for (i = 0; i < serial->num_port_pointers; ++i) | ||
1157 | kfree(serial->port[i]); | ||
1158 | kfree(serial); | ||
1159 | return -EIO; | 1105 | return -EIO; |
1160 | } | 1106 | } |
1161 | EXPORT_SYMBOL_GPL(usb_serial_probe); | 1107 | EXPORT_SYMBOL_GPL(usb_serial_probe); |
@@ -1206,8 +1152,7 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1206 | } | 1152 | } |
1207 | serial->type->disconnect(serial); | 1153 | serial->type->disconnect(serial); |
1208 | 1154 | ||
1209 | /* let the last holder of this object | 1155 | /* let the last holder of this object cause it to be cleaned up */ |
1210 | * cause it to be cleaned up */ | ||
1211 | usb_serial_put(serial); | 1156 | usb_serial_put(serial); |
1212 | dev_info(dev, "device disconnected\n"); | 1157 | dev_info(dev, "device disconnected\n"); |
1213 | } | 1158 | } |