diff options
author | Dan Williams <dan.j.williams@intel.com> | 2009-09-08 20:55:21 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2009-09-08 20:55:21 -0400 |
commit | bbb20089a3275a19e475dbc21320c3742e3ca423 (patch) | |
tree | 216fdc1cbef450ca688135c5b8969169482d9a48 /drivers/usb/serial/usb-serial.c | |
parent | 3e48e656903e9fd8bc805c6a2c4264d7808d315b (diff) | |
parent | 657a77fa7284d8ae28dfa48f1dc5d919bf5b2843 (diff) |
Merge branch 'dmaengine' into async-tx-next
Conflicts:
crypto/async_tx/async_xor.c
drivers/dma/ioat/dma_v2.h
drivers/dma/ioat/pci.c
drivers/md/raid5.c
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 197 |
1 files changed, 135 insertions, 62 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index f331e2bde88a..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 | ||
@@ -238,9 +245,11 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
238 | goto bailout_interface_put; | 245 | goto bailout_interface_put; |
239 | mutex_unlock(&serial->disc_mutex); | 246 | mutex_unlock(&serial->disc_mutex); |
240 | } | 247 | } |
241 | |||
242 | mutex_unlock(&port->mutex); | 248 | mutex_unlock(&port->mutex); |
243 | return 0; | 249 | /* Now do the correct tty layer semantics */ |
250 | retval = tty_port_block_til_ready(&port->port, tty, filp); | ||
251 | if (retval == 0) | ||
252 | return 0; | ||
244 | 253 | ||
245 | bailout_interface_put: | 254 | bailout_interface_put: |
246 | usb_autopm_put_interface(serial->interface); | 255 | usb_autopm_put_interface(serial->interface); |
@@ -259,64 +268,89 @@ bailout_serial_put: | |||
259 | return retval; | 268 | return retval; |
260 | } | 269 | } |
261 | 270 | ||
262 | static void serial_close(struct tty_struct *tty, struct file *filp) | 271 | /** |
272 | * serial_do_down - shut down hardware | ||
273 | * @port: port to shut down | ||
274 | * | ||
275 | * Shut down a USB port unless it is the console. We never shut down the | ||
276 | * console hardware as it will always be in use. | ||
277 | * | ||
278 | * Don't free any resources at this point | ||
279 | */ | ||
280 | static void serial_do_down(struct usb_serial_port *port) | ||
263 | { | 281 | { |
264 | struct usb_serial_port *port = tty->driver_data; | 282 | struct usb_serial_driver *drv = port->serial->type; |
265 | struct usb_serial *serial; | 283 | struct usb_serial *serial; |
266 | struct module *owner; | 284 | struct module *owner; |
267 | int count; | ||
268 | 285 | ||
269 | if (!port) | 286 | /* The console is magical, do not hang up the console hardware |
287 | or there will be tears */ | ||
288 | if (port->console) | ||
270 | return; | 289 | return; |
271 | 290 | ||
272 | dbg("%s - port %d", __func__, port->number); | ||
273 | |||
274 | mutex_lock(&port->mutex); | 291 | mutex_lock(&port->mutex); |
275 | serial = port->serial; | 292 | serial = port->serial; |
276 | owner = serial->type->driver.owner; | 293 | owner = serial->type->driver.owner; |
277 | 294 | ||
278 | if (port->port.count == 0) { | 295 | if (drv->close) |
279 | mutex_unlock(&port->mutex); | 296 | drv->close(port); |
280 | return; | ||
281 | } | ||
282 | 297 | ||
283 | if (port->port.count == 1) | ||
284 | /* only call the device specific close if this | ||
285 | * port is being closed by the last owner. Ensure we do | ||
286 | * this before we drop the port count. The call is protected | ||
287 | * by the port mutex | ||
288 | */ | ||
289 | serial->type->close(tty, port, filp); | ||
290 | |||
291 | if (port->port.count == (port->console ? 2 : 1)) { | ||
292 | struct tty_struct *tty = tty_port_tty_get(&port->port); | ||
293 | if (tty) { | ||
294 | /* We must do this before we drop the port count to | ||
295 | zero. */ | ||
296 | if (tty->driver_data) | ||
297 | tty->driver_data = NULL; | ||
298 | tty_port_tty_set(&port->port, NULL); | ||
299 | tty_kref_put(tty); | ||
300 | } | ||
301 | } | ||
302 | |||
303 | --port->port.count; | ||
304 | count = port->port.count; | ||
305 | mutex_unlock(&port->mutex); | 298 | mutex_unlock(&port->mutex); |
306 | put_device(&port->dev); | 299 | } |
300 | |||
301 | /** | ||
302 | * serial_do_free - free resources post close/hangup | ||
303 | * @port: port to free up | ||
304 | * | ||
305 | * Do the resource freeing and refcount dropping for the port. We must | ||
306 | * be careful about ordering and we must avoid freeing up the console. | ||
307 | */ | ||
308 | |||
309 | static void serial_do_free(struct usb_serial_port *port) | ||
310 | { | ||
311 | struct usb_serial *serial; | ||
312 | struct module *owner; | ||
313 | |||
314 | /* The console is magical, do not hang up the console hardware | ||
315 | or there will be tears */ | ||
316 | if (port->console) | ||
317 | return; | ||
307 | 318 | ||
319 | serial = port->serial; | ||
320 | owner = serial->type->driver.owner; | ||
321 | put_device(&port->dev); | ||
308 | /* Mustn't dereference port any more */ | 322 | /* Mustn't dereference port any more */ |
309 | if (count == 0) { | 323 | mutex_lock(&serial->disc_mutex); |
310 | mutex_lock(&serial->disc_mutex); | 324 | if (!serial->disconnected) |
311 | if (!serial->disconnected) | 325 | usb_autopm_put_interface(serial->interface); |
312 | usb_autopm_put_interface(serial->interface); | 326 | mutex_unlock(&serial->disc_mutex); |
313 | mutex_unlock(&serial->disc_mutex); | ||
314 | } | ||
315 | usb_serial_put(serial); | 327 | usb_serial_put(serial); |
316 | |||
317 | /* Mustn't dereference serial any more */ | 328 | /* Mustn't dereference serial any more */ |
318 | if (count == 0) | 329 | module_put(owner); |
319 | module_put(owner); | 330 | } |
331 | |||
332 | static void serial_close(struct tty_struct *tty, struct file *filp) | ||
333 | { | ||
334 | struct usb_serial_port *port = tty->driver_data; | ||
335 | |||
336 | dbg("%s - port %d", __func__, port->number); | ||
337 | |||
338 | |||
339 | if (tty_port_close_start(&port->port, tty, filp) == 0) | ||
340 | return; | ||
341 | |||
342 | serial_do_down(port); | ||
343 | tty_port_close_end(&port->port, tty); | ||
344 | tty_port_tty_set(&port->port, NULL); | ||
345 | serial_do_free(port); | ||
346 | } | ||
347 | |||
348 | static void serial_hangup(struct tty_struct *tty) | ||
349 | { | ||
350 | struct usb_serial_port *port = tty->driver_data; | ||
351 | serial_do_down(port); | ||
352 | tty_port_hangup(&port->port); | ||
353 | serial_do_free(port); | ||
320 | } | 354 | } |
321 | 355 | ||
322 | static int serial_write(struct tty_struct *tty, const unsigned char *buf, | 356 | static int serial_write(struct tty_struct *tty, const unsigned char *buf, |
@@ -648,6 +682,29 @@ static struct usb_serial_driver *search_serial_device( | |||
648 | return NULL; | 682 | return NULL; |
649 | } | 683 | } |
650 | 684 | ||
685 | static int serial_carrier_raised(struct tty_port *port) | ||
686 | { | ||
687 | struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); | ||
688 | struct usb_serial_driver *drv = p->serial->type; | ||
689 | if (drv->carrier_raised) | ||
690 | return drv->carrier_raised(p); | ||
691 | /* No carrier control - don't block */ | ||
692 | return 1; | ||
693 | } | ||
694 | |||
695 | static void serial_dtr_rts(struct tty_port *port, int on) | ||
696 | { | ||
697 | struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); | ||
698 | struct usb_serial_driver *drv = p->serial->type; | ||
699 | if (drv->dtr_rts) | ||
700 | drv->dtr_rts(p, on); | ||
701 | } | ||
702 | |||
703 | static const struct tty_port_operations serial_port_ops = { | ||
704 | .carrier_raised = serial_carrier_raised, | ||
705 | .dtr_rts = serial_dtr_rts, | ||
706 | }; | ||
707 | |||
651 | int usb_serial_probe(struct usb_interface *interface, | 708 | int usb_serial_probe(struct usb_interface *interface, |
652 | const struct usb_device_id *id) | 709 | const struct usb_device_id *id) |
653 | { | 710 | { |
@@ -841,6 +898,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
841 | if (!port) | 898 | if (!port) |
842 | goto probe_error; | 899 | goto probe_error; |
843 | tty_port_init(&port->port); | 900 | tty_port_init(&port->port); |
901 | port->port.ops = &serial_port_ops; | ||
844 | port->serial = serial; | 902 | port->serial = serial; |
845 | spin_lock_init(&port->lock); | 903 | spin_lock_init(&port->lock); |
846 | mutex_init(&port->mutex); | 904 | mutex_init(&port->mutex); |
@@ -995,10 +1053,15 @@ int usb_serial_probe(struct usb_interface *interface, | |||
995 | 1053 | ||
996 | dev_set_name(&port->dev, "ttyUSB%d", port->number); | 1054 | dev_set_name(&port->dev, "ttyUSB%d", port->number); |
997 | 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; | ||
998 | retval = device_register(&port->dev); | 1057 | retval = device_register(&port->dev); |
999 | if (retval) | 1058 | if (retval) { |
1000 | dev_err(&port->dev, "Error registering port device, " | 1059 | dev_err(&port->dev, "Error registering port device, " |
1001 | "continuing\n"); | 1060 | "continuing\n"); |
1061 | port->dev_state = PORT_UNREGISTERED; | ||
1062 | } else { | ||
1063 | port->dev_state = PORT_REGISTERED; | ||
1064 | } | ||
1002 | } | 1065 | } |
1003 | 1066 | ||
1004 | usb_serial_console_init(debug, minor); | 1067 | usb_serial_console_init(debug, minor); |
@@ -1062,31 +1125,38 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1062 | serial->disconnected = 1; | 1125 | serial->disconnected = 1; |
1063 | mutex_unlock(&serial->disc_mutex); | 1126 | mutex_unlock(&serial->disc_mutex); |
1064 | 1127 | ||
1065 | /* Unfortunately, many of the sub-drivers expect the port structures | ||
1066 | * to exist when their shutdown method is called, so we have to go | ||
1067 | * through this awkward two-step unregistration procedure. | ||
1068 | */ | ||
1069 | for (i = 0; i < serial->num_ports; ++i) { | 1128 | for (i = 0; i < serial->num_ports; ++i) { |
1070 | port = serial->port[i]; | 1129 | port = serial->port[i]; |
1071 | if (port) { | 1130 | if (port) { |
1072 | struct tty_struct *tty = tty_port_tty_get(&port->port); | 1131 | struct tty_struct *tty = tty_port_tty_get(&port->port); |
1073 | if (tty) { | 1132 | if (tty) { |
1133 | /* The hangup will occur asynchronously but | ||
1134 | the object refcounts will sort out all the | ||
1135 | cleanup */ | ||
1074 | tty_hangup(tty); | 1136 | tty_hangup(tty); |
1075 | tty_kref_put(tty); | 1137 | tty_kref_put(tty); |
1076 | } | 1138 | } |
1077 | kill_traffic(port); | 1139 | kill_traffic(port); |
1078 | cancel_work_sync(&port->work); | 1140 | cancel_work_sync(&port->work); |
1079 | device_del(&port->dev); | 1141 | if (port->dev_state == PORT_REGISTERED) { |
1080 | } | 1142 | |
1081 | } | 1143 | /* Make sure the port is bound so that the |
1082 | serial->type->shutdown(serial); | 1144 | * driver's port_remove method is called. |
1083 | for (i = 0; i < serial->num_ports; ++i) { | 1145 | */ |
1084 | port = serial->port[i]; | 1146 | if (!port->dev.driver) { |
1085 | if (port) { | 1147 | int rc; |
1086 | put_device(&port->dev); | 1148 | |
1087 | 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 | } | ||
1088 | } | 1157 | } |
1089 | } | 1158 | } |
1159 | serial->type->disconnect(serial); | ||
1090 | 1160 | ||
1091 | /* let the last holder of this object | 1161 | /* let the last holder of this object |
1092 | * cause it to be cleaned up */ | 1162 | * cause it to be cleaned up */ |
@@ -1135,6 +1205,7 @@ static const struct tty_operations serial_ops = { | |||
1135 | .open = serial_open, | 1205 | .open = serial_open, |
1136 | .close = serial_close, | 1206 | .close = serial_close, |
1137 | .write = serial_write, | 1207 | .write = serial_write, |
1208 | .hangup = serial_hangup, | ||
1138 | .write_room = serial_write_room, | 1209 | .write_room = serial_write_room, |
1139 | .ioctl = serial_ioctl, | 1210 | .ioctl = serial_ioctl, |
1140 | .set_termios = serial_set_termios, | 1211 | .set_termios = serial_set_termios, |
@@ -1147,6 +1218,7 @@ static const struct tty_operations serial_ops = { | |||
1147 | .proc_fops = &serial_proc_fops, | 1218 | .proc_fops = &serial_proc_fops, |
1148 | }; | 1219 | }; |
1149 | 1220 | ||
1221 | |||
1150 | struct tty_driver *usb_serial_tty_driver; | 1222 | struct tty_driver *usb_serial_tty_driver; |
1151 | 1223 | ||
1152 | static int __init usb_serial_init(void) | 1224 | static int __init usb_serial_init(void) |
@@ -1262,7 +1334,8 @@ static void fixup_generic(struct usb_serial_driver *device) | |||
1262 | set_to_generic_if_null(device, chars_in_buffer); | 1334 | set_to_generic_if_null(device, chars_in_buffer); |
1263 | set_to_generic_if_null(device, read_bulk_callback); | 1335 | set_to_generic_if_null(device, read_bulk_callback); |
1264 | set_to_generic_if_null(device, write_bulk_callback); | 1336 | set_to_generic_if_null(device, write_bulk_callback); |
1265 | set_to_generic_if_null(device, shutdown); | 1337 | set_to_generic_if_null(device, disconnect); |
1338 | set_to_generic_if_null(device, release); | ||
1266 | } | 1339 | } |
1267 | 1340 | ||
1268 | int usb_serial_register(struct usb_serial_driver *driver) | 1341 | int usb_serial_register(struct usb_serial_driver *driver) |