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

Reply via email to