diff options
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
| -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 | } |
