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