diff options
author | Alan Cox <alan@linux.intel.com> | 2009-10-06 11:06:36 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 18:18:04 -0500 |
commit | e1108a63e10d344284011cccc06328b2cd3e5da3 (patch) | |
tree | f5dc7d7ec62187cd8c808063d1187457ea7ccade | |
parent | d774a56d2353933cf21cc92a9d0012c7b69d09bf (diff) |
usb_serial: Use the shutdown() operation
As Alan Stern pointed out - now we have tty_port_open the shutdown method
and locking allow us to whack the other bits into the full helper methods
and provide a shutdown op which the tty port code will synchronize with
setup for us.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 39 |
1 files changed, 11 insertions, 28 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index b0649d92251f..829a46684e1d 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -254,15 +254,12 @@ static int serial_activate(struct tty_port *tport, struct tty_struct *tty) | |||
254 | struct usb_serial *serial = port->serial; | 254 | struct usb_serial *serial = port->serial; |
255 | int retval; | 255 | int retval; |
256 | 256 | ||
257 | if (mutex_lock_interruptible(&port->mutex)) | ||
258 | return -ERESTARTSYS; | ||
259 | mutex_lock(&serial->disc_mutex); | 257 | mutex_lock(&serial->disc_mutex); |
260 | if (serial->disconnected) | 258 | if (serial->disconnected) |
261 | retval = -ENODEV; | 259 | retval = -ENODEV; |
262 | else | 260 | else |
263 | retval = port->serial->type->open(tty, port); | 261 | retval = port->serial->type->open(tty, port); |
264 | mutex_unlock(&serial->disc_mutex); | 262 | mutex_unlock(&serial->disc_mutex); |
265 | mutex_unlock(&port->mutex); | ||
266 | return retval; | 263 | return retval; |
267 | } | 264 | } |
268 | 265 | ||
@@ -276,57 +273,40 @@ static int serial_open(struct tty_struct *tty, struct file *filp) | |||
276 | 273 | ||
277 | /** | 274 | /** |
278 | * serial_down - shut down hardware | 275 | * serial_down - shut down hardware |
279 | * @port: port to shut down | 276 | * @tport: tty port to shut down |
280 | * | 277 | * |
281 | * Shut down a USB serial port unless it is the console. We never | 278 | * Shut down a USB serial port unless it is the console. We never |
282 | * shut down the console hardware as it will always be in use. | 279 | * shut down the console hardware as it will always be in use. Serialized |
280 | * against activate by the tport mutex and kept to matching open/close pairs | ||
281 | * of calls by the ASYNCB_INITIALIZED flag. | ||
283 | */ | 282 | */ |
284 | static void serial_down(struct usb_serial_port *port) | 283 | static void serial_down(struct tty_port *tport) |
285 | { | 284 | { |
285 | struct usb_serial_port *port = | ||
286 | container_of(tport, struct usb_serial_port, port); | ||
286 | struct usb_serial_driver *drv = port->serial->type; | 287 | struct usb_serial_driver *drv = port->serial->type; |
287 | |||
288 | /* | 288 | /* |
289 | * The console is magical. Do not hang up the console hardware | 289 | * The console is magical. Do not hang up the console hardware |
290 | * or there will be tears. | 290 | * or there will be tears. |
291 | */ | 291 | */ |
292 | if (port->console) | 292 | if (port->console) |
293 | return; | 293 | return; |
294 | |||
295 | /* Don't call the close method if the hardware hasn't been | ||
296 | * initialized. | ||
297 | */ | ||
298 | if (!test_and_clear_bit(ASYNCB_INITIALIZED, &port->port.flags)) | ||
299 | return; | ||
300 | |||
301 | mutex_lock(&port->mutex); | ||
302 | if (drv->close) | 294 | if (drv->close) |
303 | drv->close(port); | 295 | drv->close(port); |
304 | mutex_unlock(&port->mutex); | ||
305 | } | 296 | } |
306 | 297 | ||
307 | static void serial_hangup(struct tty_struct *tty) | 298 | static void serial_hangup(struct tty_struct *tty) |
308 | { | 299 | { |
309 | struct usb_serial_port *port = tty->driver_data; | 300 | struct usb_serial_port *port = tty->driver_data; |
310 | |||
311 | dbg("%s - port %d", __func__, port->number); | 301 | dbg("%s - port %d", __func__, port->number); |
312 | |||
313 | serial_down(port); | ||
314 | tty_port_hangup(&port->port); | 302 | tty_port_hangup(&port->port); |
315 | } | 303 | } |
316 | 304 | ||
317 | static void serial_close(struct tty_struct *tty, struct file *filp) | 305 | static void serial_close(struct tty_struct *tty, struct file *filp) |
318 | { | 306 | { |
319 | struct usb_serial_port *port = tty->driver_data; | 307 | struct usb_serial_port *port = tty->driver_data; |
320 | |||
321 | dbg("%s - port %d", __func__, port->number); | 308 | dbg("%s - port %d", __func__, port->number); |
322 | 309 | tty_port_close(&port->port, tty, filp); | |
323 | if (tty_hung_up_p(filp)) | ||
324 | return; | ||
325 | if (tty_port_close_start(&port->port, tty, filp) == 0) | ||
326 | return; | ||
327 | serial_down(port); | ||
328 | tty_port_close_end(&port->port, tty); | ||
329 | tty_port_tty_set(&port->port, NULL); | ||
330 | } | 310 | } |
331 | 311 | ||
332 | /** | 312 | /** |
@@ -716,6 +696,7 @@ static const struct tty_port_operations serial_port_ops = { | |||
716 | .carrier_raised = serial_carrier_raised, | 696 | .carrier_raised = serial_carrier_raised, |
717 | .dtr_rts = serial_dtr_rts, | 697 | .dtr_rts = serial_dtr_rts, |
718 | .activate = serial_activate, | 698 | .activate = serial_activate, |
699 | .shutdown = serial_down, | ||
719 | }; | 700 | }; |
720 | 701 | ||
721 | int usb_serial_probe(struct usb_interface *interface, | 702 | int usb_serial_probe(struct usb_interface *interface, |
@@ -914,6 +895,8 @@ int usb_serial_probe(struct usb_interface *interface, | |||
914 | port->port.ops = &serial_port_ops; | 895 | port->port.ops = &serial_port_ops; |
915 | port->serial = serial; | 896 | port->serial = serial; |
916 | spin_lock_init(&port->lock); | 897 | spin_lock_init(&port->lock); |
898 | /* Keep this for private driver use for the moment but | ||
899 | should probably go away */ | ||
917 | mutex_init(&port->mutex); | 900 | mutex_init(&port->mutex); |
918 | INIT_WORK(&port->work, usb_serial_port_work); | 901 | INIT_WORK(&port->work, usb_serial_port_work); |
919 | serial->port[i] = port; | 902 | serial->port[i] = port; |