On Thu, 13 Apr 2006, Paul Fulghum wrote: > Guennadi Liakhovetski wrote: > > Well, looked through the code again - I think, you are right. An updated > > version below. I just used your initial (slightly modified to my tastes:-)) > > approach - calling usb_serial_console_exit() from > > usb_serial_console_disconnect(). > > Looks good to me. Have you tested the case (with this patch) > of removing the adapter after boot and then reinserting it? > Does it resume sending output to the usb console?
With the version below it does:-) I thought it was by design so that after re-plug you get ttyUSB1, 2,... In fact it was just leaking a kref. Now it's perfect - you replug the dongle and your console is back! Thanks for catching this! Thanks Guennadi --- Guennadi Liakhovetski Prevent sending further output to a USB-serial console after the dongle is disconnected, take care not to leak kref. Signed-off-by: Guennadi Liakhovetski <[EMAIL PROTECTED]> diff -u -p a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c --- a/drivers/usb/serial/console.c 13 Jan 2005 21:09:08 -0000 +++ b/drivers/usb/serial/console.c 14 Apr 2006 09:53:40 -0000 @@ -202,7 +202,7 @@ static void usb_console_write(struct con struct usb_serial *serial; int retval = -ENODEV; - if (!port) + if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) return; serial = port->serial; @@ -234,6 +234,14 @@ static struct console usbcons = { .index = -1, }; +void usb_serial_console_disconnect(struct usb_serial *serial) +{ + if (serial && serial->port && serial->port[0] && serial->port[0] == usbcons_info.port) { + usb_serial_console_exit(); + usb_serial_put(serial); + } +} + void usb_serial_console_init (int serial_debug, int minor) { debug = serial_debug; @@ -259,6 +267,11 @@ void usb_serial_console_init (int serial void usb_serial_console_exit (void) { - unregister_console(&usbcons); + if (usbcons_info.port) { + unregister_console(&usbcons); + if (usbcons_info.port->open_count) + usbcons_info.port->open_count--; + usbcons_info.port = NULL; + } } diff -u -p a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c --- a/drivers/usb/serial/usb-serial.c 30 Mar 2006 19:18:07 -0000 +++ b/drivers/usb/serial/usb-serial.c 14 Apr 2006 09:53:27 -0000 @@ -69,6 +69,12 @@ struct usb_serial *usb_serial_get_by_ind return serial; } +static void destroy_serial(struct kref *kref); +void usb_serial_put(struct usb_serial *serial) +{ + kref_put(&serial->kref, destroy_serial); +} + static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_ports, unsigned int *minor) { unsigned int i, j; @@ -225,7 +231,7 @@ static int serial_open (struct tty_struc bailout_module_put: module_put(serial->type->driver.owner); bailout_kref_put: - kref_put(&serial->kref, destroy_serial); + usb_serial_put(serial); port->open_count = 0; up(&port->sem); return retval; @@ -263,7 +269,7 @@ static void serial_close(struct tty_stru } up(&port->sem); - kref_put(&port->serial->kref, destroy_serial); + usb_serial_put(port->serial); } static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) @@ -271,7 +277,7 @@ static int serial_write (struct tty_stru struct usb_serial_port *port = tty->driver_data; int retval = -EINVAL; - if (!port) + if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) goto exit; dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); @@ -468,7 +474,7 @@ static int serial_read_proc (char *page, begin += length; length = 0; } - kref_put(&serial->kref, destroy_serial); + usb_serial_put(serial); } *eof = 1; done: @@ -982,6 +988,7 @@ void usb_serial_disconnect(struct usb_in struct device *dev = &interface->dev; struct usb_serial_port *port; + usb_serial_console_disconnect(serial); dbg ("%s", __FUNCTION__); usb_set_intfdata (interface, NULL); @@ -993,7 +1000,7 @@ void usb_serial_disconnect(struct usb_in } /* let the last holder of this object * cause it to be cleaned up */ - kref_put(&serial->kref, destroy_serial); + usb_serial_put(serial); } dev_info(dev, "device disconnected\n"); } diff -u -p a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h --- a/drivers/usb/serial/usb-serial.h 30 Mar 2006 19:18:07 -0000 +++ b/drivers/usb/serial/usb-serial.h 14 Apr 2006 09:18:23 -0000 @@ -248,13 +248,16 @@ extern int ezusb_set_reset (struct usb_s #ifdef CONFIG_USB_SERIAL_CONSOLE extern void usb_serial_console_init (int debug, int minor); extern void usb_serial_console_exit (void); +extern void usb_serial_console_disconnect(struct usb_serial *serial); #else static inline void usb_serial_console_init (int debug, int minor) { } static inline void usb_serial_console_exit (void) { } +static inline void usb_serial_console_disconnect(struct usb_serial *serial) {} #endif /* Functions needed by other parts of the usbserial core */ extern struct usb_serial *usb_serial_get_by_index (unsigned int minor); +extern void usb_serial_put(struct usb_serial *serial); extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp); extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigned char *buf, int count); extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp); ------------------------------------------------------- This SF.Net email is sponsored by xPML, a groundbreaking scripting language that extends applications into web and mobile media. Attend the live webcast and join the prime developer group breaking into this new coding territory! http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642 _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel