diff options
author | Oliver Neukum <oliver@neukum.org> | 2008-01-16 17:18:52 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-02-01 23:35:03 +0100 |
commit | a1cd7e99b343543af2be4c8c5755e26f6bfd725a (patch) | |
tree | 41f8de097dd0889a9c6d02fa0a22b16d5146de46 /drivers/usb/serial/usb-serial.c | |
parent | USB: add support for SuperH OHCI (diff) | |
download | linux-a1cd7e99b343543af2be4c8c5755e26f6bfd725a.tar.xz linux-a1cd7e99b343543af2be4c8c5755e26f6bfd725a.zip |
USB: stop io performed by mos7720 upon close()
This fixes a problem where the mos7720 driver will make io to a device from
which it has been logically disconnected. It does so by introducing a flag by
which the generic usb serial code can signal the subdrivers their
disconnection and appropriate locking.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 28315b05c9cc..3ce98e8d7bce 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -634,6 +634,7 @@ static struct usb_serial * create_serial (struct usb_device *dev, serial->type = driver; serial->interface = interface; kref_init(&serial->kref); + mutex_init(&serial->disc_mutex); return serial; } @@ -1089,20 +1090,22 @@ void usb_serial_disconnect(struct usb_interface *interface) usb_serial_console_disconnect(serial); dbg ("%s", __FUNCTION__); + mutex_lock(&serial->disc_mutex); usb_set_intfdata (interface, NULL); - if (serial) { - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - if (port) { - if (port->tty) - tty_hangup(port->tty); - kill_traffic(port); - } + /* must set a flag, to signal subdrivers */ + serial->disconnected = 1; + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + if (port) { + if (port->tty) + tty_hangup(port->tty); + kill_traffic(port); } - /* let the last holder of this object - * cause it to be cleaned up */ - usb_serial_put(serial); } + /* let the last holder of this object + * cause it to be cleaned up */ + mutex_unlock(&serial->disc_mutex); + usb_serial_put(serial); dev_info(dev, "device disconnected\n"); } @@ -1112,9 +1115,6 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) struct usb_serial_port *port; int i, r = 0; - if (!serial) /* device has been disconnected */ - return 0; - for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; if (port) |