Hi, the mos7720 driver sends two commands to the device whenever it is closed. It does so unconditionally even if the device has been disconnected. It seems to me that this is wrong. Making sure that this does not happen for disconnected devices takes a bit of infrastructure in the generic part. However I am not sure whether this interfeeres with hanging up the tty. What do you think?
Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]> Regards Oliver ---- --- linux-2.6.24-rc5-vanilla/include/linux/usb/serial.h 2007-12-20 13:14:04.000000000 +0100 +++ linux-2.6.24-rc5-work/include/linux/usb/serial.h 2007-12-20 12:39:40.000000000 +0100 @@ -128,6 +128,7 @@ struct usb_serial { struct usb_device * dev; struct usb_serial_driver * type; struct usb_interface * interface; + unsigned char disconnected; unsigned char minor; unsigned char num_ports; unsigned char num_port_pointers; @@ -137,6 +138,7 @@ struct usb_serial { char num_bulk_out; struct usb_serial_port * port[MAX_NUM_PORTS]; struct kref kref; + struct mutex disc_mutex; void * private; }; #define to_usb_serial(d) container_of(d, struct usb_serial, kref) --- linux-2.6.24-rc5-vanilla/drivers/usb/serial/usb-serial.c 2007-12-20 13:13:53.000000000 +0100 +++ linux-2.6.24-rc5-work/drivers/usb/serial/usb-serial.c 2007-12-20 12:45:00.000000000 +0100 @@ -625,6 +625,7 @@ static struct usb_serial * create_serial serial->type = driver; serial->interface = interface; kref_init(&serial->kref); + mutex_init(&serial->disc_mutex); return serial; } @@ -1080,20 +1081,22 @@ void usb_serial_disconnect(struct usb_in 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 use extra flag, as intfdata can be reset */ + 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"); } --- linux-2.6.24-rc5-vanilla/drivers/usb/serial/mos7720.c 2007-12-20 13:13:53.000000000 +0100 +++ linux-2.6.24-rc5-work/drivers/usb/serial/mos7720.c 2007-12-20 12:39:36.000000000 +0100 @@ -564,22 +564,25 @@ static void mos7720_close(struct usb_ser } /* While closing port, shutdown all bulk read, write * - * and interrupt read if they exists */ - if (serial->dev) { - dbg("Shutdown bulk write"); - usb_kill_urb(port->write_urb); - dbg("Shutdown bulk read"); - usb_kill_urb(port->read_urb); + * and interrupt read if they exists, otherwise nop */ + dbg("Shutdown bulk write"); + usb_kill_urb(port->write_urb); + dbg("Shutdown bulk read"); + usb_kill_urb(port->read_urb); + + mutex_lock(&serial->disc_mutex); + /* these commands must not be issued if the device has + * been disconnected */ + if (!serial->disconnected) { + data = 0x00; + send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, + 0x04, &data); + + data = 0x00; + send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, + 0x01, &data); } - - data = 0x00; - send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, - 0x04, &data); - - data = 0x00; - send_mos_cmd(serial, MOS_WRITE, port->number - port->serial->minor, - 0x01, &data); - + mutex_unlock(&serial->disc_mutex); mos7720_port->open = 0; dbg("Leaving %s", __FUNCTION__); - To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html