From 8a7298d361827a1f244415dde62b1b07688d6a3a Mon Sep 17 00:00:00 2001 From: Peter Hurley Date: Sat, 23 Feb 2013 10:11:35 -0500 Subject: usb/serial: Remove unnecessary check for console The tty port ops shutdown() routine is not called for console ports; remove extra check. Signed-off-by: Peter Hurley Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a19ed74d770d..8424478e0b76 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -256,22 +256,18 @@ static int serial_open(struct tty_struct *tty, struct file *filp) * serial_down - shut down hardware * @tport: tty port to shut down * - * Shut down a USB serial port unless it is the console. We never - * shut down the console hardware as it will always be in use. Serialized - * against activate by the tport mutex and kept to matching open/close pairs + * Shut down a USB serial port. Serialized against activate by the + * tport mutex and kept to matching open/close pairs * of calls by the ASYNCB_INITIALIZED flag. + * + * Not called if tty is console. */ static void serial_down(struct tty_port *tport) { struct usb_serial_port *port = container_of(tport, struct usb_serial_port, port); struct usb_serial_driver *drv = port->serial->type; - /* - * The console is magical. Do not hang up the console hardware - * or there will be tears. - */ - if (port->port.console) - return; + if (drv->close) drv->close(port); } -- cgit v1.2.3 From 93e4f47f4d1a3483f009202e8a66a3a08de5c4b6 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 15 Mar 2013 12:08:54 +0800 Subject: USB: serial: comments on suspend failure If suspend callback fails in system sleep context, usb core will ignore the failure and let system sleep go ahead further, so this patch comments on the case and requires that serial->type->suspend() MUST return 0 in system sleep context. Acked-by: Johan Hovold Signed-off-by: Ming Lei Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index bbe7f2eb8160..2fc05004c1b6 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1137,6 +1137,11 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) serial->suspending = 1; + /* + * serial->type->suspend() MUST return 0 in system sleep context, + * otherwise, the resume callback has to recover device from + * previous suspend failure. + */ if (serial->type->suspend) { r = serial->type->suspend(serial, message); if (r < 0) { -- cgit v1.2.3 From 395e08da8adfe873c5f79e549bb6b7fa5d9f3832 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:23 +0100 Subject: USB: serial: rename tty-port callbacks Rename the tty-port callbacks using a common prefix to more clearly separate them from the tty and usb driver callbacks. Rename serial_down to serial_port_shutdown to match the callback name. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 2fc05004c1b6..3e290fc2adc4 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -225,7 +225,7 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty) return retval; } -static int serial_activate(struct tty_port *tport, struct tty_struct *tty) +static int serial_port_activate(struct tty_port *tport, struct tty_struct *tty) { struct usb_serial_port *port = container_of(tport, struct usb_serial_port, port); @@ -254,7 +254,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp) } /** - * serial_down - shut down hardware + * serial_port_shutdown - shut down hardware * @tport: tty port to shut down * * Shut down a USB serial port. Serialized against activate by the @@ -263,7 +263,7 @@ static int serial_open(struct tty_struct *tty, struct file *filp) * * Not called if tty is console. */ -static void serial_down(struct tty_port *tport) +static void serial_port_shutdown(struct tty_port *tport) { struct usb_serial_port *port = container_of(tport, struct usb_serial_port, port); @@ -677,7 +677,7 @@ static struct usb_serial_driver *search_serial_device( return NULL; } -static int serial_carrier_raised(struct tty_port *port) +static int serial_port_carrier_raised(struct tty_port *port) { struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); struct usb_serial_driver *drv = p->serial->type; @@ -688,7 +688,7 @@ static int serial_carrier_raised(struct tty_port *port) return 1; } -static void serial_dtr_rts(struct tty_port *port, int on) +static void serial_port_dtr_rts(struct tty_port *port, int on) { struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); struct usb_serial *serial = p->serial; @@ -708,10 +708,10 @@ static void serial_dtr_rts(struct tty_port *port, int on) } static const struct tty_port_operations serial_port_ops = { - .carrier_raised = serial_carrier_raised, - .dtr_rts = serial_dtr_rts, - .activate = serial_activate, - .shutdown = serial_down, + .carrier_raised = serial_port_carrier_raised, + .dtr_rts = serial_port_dtr_rts, + .activate = serial_port_activate, + .shutdown = serial_port_shutdown, }; static int usb_serial_probe(struct usb_interface *interface, -- cgit v1.2.3 From 9993b42b638ec031a55bfe1bc16317cbb5c69722 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:24 +0100 Subject: USB: serial: remove redundant comments Remove redundant comments and fix some minor coding style issues. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 3e290fc2adc4..262beefca71e 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -14,7 +14,6 @@ * * See Documentation/usb/usb-serial.txt for more information on using this * driver - * */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -49,7 +48,6 @@ drivers depend on it. */ -/* initially all NULL */ static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; static DEFINE_MUTEX(table_lock); static LIST_HEAD(usb_serial_driver_list); @@ -338,7 +336,6 @@ static int serial_write(struct tty_struct *tty, const unsigned char *buf, dev_dbg(tty->dev, "%s - port %d, %d byte(s)\n", __func__, port->number, count); - /* pass on to the driver specific version of this function */ retval = port->serial->type->write(tty, port, buf, count); if (retval < 0) retval = usb_translate_errors(retval); @@ -351,7 +348,7 @@ static int serial_write_room(struct tty_struct *tty) struct usb_serial_port *port = tty->driver_data; dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); - /* pass on to the driver specific version of this function */ + return port->serial->type->write_room(tty); } @@ -381,7 +378,6 @@ static void serial_throttle(struct tty_struct *tty) dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); - /* pass on to the driver specific version of this function */ if (port->serial->type->throttle) port->serial->type->throttle(tty); } @@ -392,7 +388,6 @@ static void serial_unthrottle(struct tty_struct *tty) dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); - /* pass on to the driver specific version of this function */ if (port->serial->type->unthrottle) port->serial->type->unthrottle(tty); } @@ -406,12 +401,11 @@ static int serial_ioctl(struct tty_struct *tty, dev_dbg(tty->dev, "%s - port %d, cmd 0x%.4x\n", __func__, port->number, cmd); - /* pass on to the driver specific version of this function - if it is available */ - if (port->serial->type->ioctl) { + if (port->serial->type->ioctl) retval = port->serial->type->ioctl(tty, cmd, arg); - } else + else retval = -ENOIOCTLCMD; + return retval; } @@ -421,8 +415,6 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old) dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); - /* pass on to the driver specific version of this function - if it is available */ if (port->serial->type->set_termios) port->serial->type->set_termios(tty, port, old); else @@ -435,10 +427,9 @@ static int serial_break(struct tty_struct *tty, int break_state) dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); - /* pass on to the driver specific version of this function - if it is available */ if (port->serial->type->break_ctl) port->serial->type->break_ctl(tty, break_state); + return 0; } @@ -1471,7 +1462,6 @@ void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_driver } EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers); -/* Module information */ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From d12e211d44844930b7460ffab43ff9b078a45369 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:25 +0100 Subject: USB: serial: clean up debug info Remove redundant port number from debug output (already printed as part of device name). Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 262beefca71e..fee8d8a04f7b 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -247,7 +247,8 @@ static int serial_open(struct tty_struct *tty, struct file *filp) { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); + return tty_port_open(&port->port, tty, filp); } @@ -275,7 +276,8 @@ static void serial_hangup(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); + tty_port_hangup(&port->port); } @@ -283,7 +285,8 @@ static void serial_close(struct tty_struct *tty, struct file *filp) { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); + tty_port_close(&port->port, tty, filp); } @@ -302,14 +305,14 @@ static void serial_cleanup(struct tty_struct *tty) struct usb_serial *serial; struct module *owner; + dev_dbg(tty->dev, "%s\n", __func__); + /* The console is magical. Do not hang up the console hardware * or there will be tears. */ if (port->port.console) return; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); - tty->driver_data = NULL; serial = port->serial; @@ -333,8 +336,7 @@ static int serial_write(struct tty_struct *tty, const unsigned char *buf, if (port->serial->dev->state == USB_STATE_NOTATTACHED) goto exit; - dev_dbg(tty->dev, "%s - port %d, %d byte(s)\n", __func__, - port->number, count); + dev_dbg(tty->dev, "%s - %d byte(s)\n", __func__, count); retval = port->serial->type->write(tty, port, buf, count); if (retval < 0) @@ -347,7 +349,7 @@ static int serial_write_room(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); return port->serial->type->write_room(tty); } @@ -358,7 +360,7 @@ static int serial_chars_in_buffer(struct tty_struct *tty) struct usb_serial *serial = port->serial; int count = 0; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); mutex_lock(&serial->disc_mutex); /* if the device was unplugged then any remaining characters @@ -376,7 +378,7 @@ static void serial_throttle(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); if (port->serial->type->throttle) port->serial->type->throttle(tty); @@ -386,7 +388,7 @@ static void serial_unthrottle(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); if (port->serial->type->unthrottle) port->serial->type->unthrottle(tty); @@ -398,8 +400,7 @@ static int serial_ioctl(struct tty_struct *tty, struct usb_serial_port *port = tty->driver_data; int retval = -ENODEV; - dev_dbg(tty->dev, "%s - port %d, cmd 0x%.4x\n", __func__, - port->number, cmd); + dev_dbg(tty->dev, "%s - cmd 0x%.4x\n", __func__, cmd); if (port->serial->type->ioctl) retval = port->serial->type->ioctl(tty, cmd, arg); @@ -413,7 +414,7 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old) { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); if (port->serial->type->set_termios) port->serial->type->set_termios(tty, port, old); @@ -425,7 +426,7 @@ static int serial_break(struct tty_struct *tty, int break_state) { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); if (port->serial->type->break_ctl) port->serial->type->break_ctl(tty, break_state); @@ -483,7 +484,7 @@ static int serial_tiocmget(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); if (port->serial->type->tiocmget) return port->serial->type->tiocmget(tty); @@ -495,7 +496,7 @@ static int serial_tiocmset(struct tty_struct *tty, { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); if (port->serial->type->tiocmset) return port->serial->type->tiocmset(tty, set, clear); @@ -507,7 +508,7 @@ static int serial_get_icount(struct tty_struct *tty, { struct usb_serial_port *port = tty->driver_data; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); if (port->serial->type->get_icount) return port->serial->type->get_icount(tty, icount); @@ -535,7 +536,7 @@ static void usb_serial_port_work(struct work_struct *work) if (!tty) return; - dev_dbg(tty->dev, "%s - port %d\n", __func__, port->number); + dev_dbg(tty->dev, "%s\n", __func__); tty_wakeup(tty); tty_kref_put(tty); -- cgit v1.2.3 From 6b03f7f79f5610ad119dc99643be20b44095c265 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:26 +0100 Subject: USB: serial: remove redundant allocation error messages Failed allocations already get an OOM message and a stack dump. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index fee8d8a04f7b..e7f97b58e914 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -603,10 +603,8 @@ static struct usb_serial *create_serial(struct usb_device *dev, struct usb_serial *serial; serial = kzalloc(sizeof(*serial), GFP_KERNEL); - if (!serial) { - dev_err(&dev->dev, "%s - out of memory\n", __func__); + if (!serial) return NULL; - } serial->dev = usb_get_dev(dev); serial->type = driver; serial->interface = usb_get_intf(interface); @@ -750,7 +748,6 @@ static int usb_serial_probe(struct usb_interface *interface, serial = create_serial(dev, interface, type); if (!serial) { module_put(type->driver.owner); - dev_err(ddev, "%s - out of memory\n", __func__); return -ENOMEM; } @@ -914,16 +911,12 @@ static int usb_serial_probe(struct usb_interface *interface, for (j = 0; j < ARRAY_SIZE(port->read_urbs); ++j) { set_bit(j, &port->read_urbs_free); port->read_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); - if (!port->read_urbs[j]) { - dev_err(ddev, "No free urbs available\n"); + if (!port->read_urbs[j]) goto probe_error; - } port->bulk_in_buffers[j] = kmalloc(buffer_size, GFP_KERNEL); - if (!port->bulk_in_buffers[j]) { - dev_err(ddev, "Couldn't allocate bulk_in_buffer\n"); + if (!port->bulk_in_buffers[j]) goto probe_error; - } usb_fill_bulk_urb(port->read_urbs[j], dev, usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), @@ -950,16 +943,12 @@ static int usb_serial_probe(struct usb_interface *interface, for (j = 0; j < ARRAY_SIZE(port->write_urbs); ++j) { set_bit(j, &port->write_urbs_free); port->write_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); - if (!port->write_urbs[j]) { - dev_err(ddev, "No free urbs available\n"); + if (!port->write_urbs[j]) goto probe_error; - } port->bulk_out_buffers[j] = kmalloc(buffer_size, GFP_KERNEL); - if (!port->bulk_out_buffers[j]) { - dev_err(ddev, "Couldn't allocate bulk_out_buffer\n"); + if (!port->bulk_out_buffers[j]) goto probe_error; - } usb_fill_bulk_urb(port->write_urbs[j], dev, usb_sndbulkpipe(dev, endpoint->bEndpointAddress), @@ -977,19 +966,15 @@ static int usb_serial_probe(struct usb_interface *interface, endpoint = interrupt_in_endpoint[i]; port = serial->port[i]; port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!port->interrupt_in_urb) { - dev_err(ddev, "No free urbs available\n"); + if (!port->interrupt_in_urb) goto probe_error; - } buffer_size = usb_endpoint_maxp(endpoint); port->interrupt_in_endpointAddress = endpoint->bEndpointAddress; port->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL); - if (!port->interrupt_in_buffer) { - dev_err(ddev, "Couldn't allocate interrupt_in_buffer\n"); + if (!port->interrupt_in_buffer) goto probe_error; - } usb_fill_int_urb(port->interrupt_in_urb, dev, usb_rcvintpipe(dev, endpoint->bEndpointAddress), @@ -1006,20 +991,16 @@ static int usb_serial_probe(struct usb_interface *interface, endpoint = interrupt_out_endpoint[i]; port = serial->port[i]; port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!port->interrupt_out_urb) { - dev_err(ddev, "No free urbs available\n"); + if (!port->interrupt_out_urb) goto probe_error; - } buffer_size = usb_endpoint_maxp(endpoint); port->interrupt_out_size = buffer_size; port->interrupt_out_endpointAddress = endpoint->bEndpointAddress; port->interrupt_out_buffer = kmalloc(buffer_size, GFP_KERNEL); - if (!port->interrupt_out_buffer) { - dev_err(ddev, "Couldn't allocate interrupt_out_buffer\n"); + if (!port->interrupt_out_buffer) goto probe_error; - } usb_fill_int_urb(port->interrupt_out_urb, dev, usb_sndintpipe(dev, endpoint->bEndpointAddress), -- cgit v1.2.3 From 0f16cfe39eeef47c91aa3c3bf2b49954d5313a58 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:42 +0100 Subject: USB: serial: remove generic disconnect callback Remove the now empty generic disconnect callback and make the disconnect callback non-mandatory. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 6 ------ drivers/usb/serial/usb-serial.c | 4 ++-- include/linux/usb/serial.h | 1 - 3 files changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index a6d0ac638e0a..4d421f3f8a7c 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -45,7 +45,6 @@ struct usb_serial_driver usb_serial_generic_device = { }, .id_table = generic_device_ids, .num_ports = 1, - .disconnect = usb_serial_generic_disconnect, .release = usb_serial_generic_release, .throttle = usb_serial_generic_throttle, .unthrottle = usb_serial_generic_unthrottle, @@ -500,11 +499,6 @@ int usb_serial_generic_resume(struct usb_serial *serial) } EXPORT_SYMBOL_GPL(usb_serial_generic_resume); -void usb_serial_generic_disconnect(struct usb_serial *serial) -{ -} -EXPORT_SYMBOL_GPL(usb_serial_generic_disconnect); - void usb_serial_generic_release(struct usb_serial *serial) { } diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index e7f97b58e914..569b6792c218 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1095,7 +1095,8 @@ static void usb_serial_disconnect(struct usb_interface *interface) device_del(&port->dev); } } - serial->type->disconnect(serial); + if (serial->type->disconnect) + serial->type->disconnect(serial); /* let the last holder of this object cause it to be cleaned up */ usb_serial_put(serial); @@ -1304,7 +1305,6 @@ static void fixup_generic(struct usb_serial_driver *device) set_to_generic_if_null(device, chars_in_buffer); set_to_generic_if_null(device, read_bulk_callback); set_to_generic_if_null(device, write_bulk_callback); - set_to_generic_if_null(device, disconnect); set_to_generic_if_null(device, release); set_to_generic_if_null(device, process_read_urb); set_to_generic_if_null(device, prepare_write_buffer); diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 1819b59aab2a..437dfd6787f9 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -329,7 +329,6 @@ extern void usb_serial_generic_read_bulk_callback(struct urb *urb); extern void usb_serial_generic_write_bulk_callback(struct urb *urb); extern void usb_serial_generic_throttle(struct tty_struct *tty); extern void usb_serial_generic_unthrottle(struct tty_struct *tty); -extern void usb_serial_generic_disconnect(struct usb_serial *serial); extern void usb_serial_generic_release(struct usb_serial *serial); extern int usb_serial_generic_register(void); extern void usb_serial_generic_deregister(void); -- cgit v1.2.3 From 79b80b8a1141ba0605e917a6fc12d44383ab29b8 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:43 +0100 Subject: USB: serial: remove generic release callback Remove empty generic release implementation and make the release callback non-mandatory (like attach, probe and disconnect). Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 5 ----- drivers/usb/serial/usb-serial.c | 3 +-- include/linux/usb/serial.h | 1 - 3 files changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 4d421f3f8a7c..aa71f6e72f61 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -45,7 +45,6 @@ struct usb_serial_driver usb_serial_generic_device = { }, .id_table = generic_device_ids, .num_ports = 1, - .release = usb_serial_generic_release, .throttle = usb_serial_generic_throttle, .unthrottle = usb_serial_generic_unthrottle, .resume = usb_serial_generic_resume, @@ -498,7 +497,3 @@ int usb_serial_generic_resume(struct usb_serial *serial) return c ? -EIO : 0; } EXPORT_SYMBOL_GPL(usb_serial_generic_resume); - -void usb_serial_generic_release(struct usb_serial *serial) -{ -} diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 569b6792c218..4819fd9a639a 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -137,7 +137,7 @@ static void destroy_serial(struct kref *kref) if (serial->minor != SERIAL_TTY_NO_MINOR) return_serial(serial); - if (serial->attached) + if (serial->attached && serial->type->release) serial->type->release(serial); /* Now that nothing is using the ports, they can be freed */ @@ -1305,7 +1305,6 @@ static void fixup_generic(struct usb_serial_driver *device) set_to_generic_if_null(device, chars_in_buffer); set_to_generic_if_null(device, read_bulk_callback); set_to_generic_if_null(device, write_bulk_callback); - set_to_generic_if_null(device, release); set_to_generic_if_null(device, process_read_urb); set_to_generic_if_null(device, prepare_write_buffer); } diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 437dfd6787f9..3f8f5e3c76d5 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -329,7 +329,6 @@ extern void usb_serial_generic_read_bulk_callback(struct urb *urb); extern void usb_serial_generic_write_bulk_callback(struct urb *urb); extern void usb_serial_generic_throttle(struct tty_struct *tty); extern void usb_serial_generic_unthrottle(struct tty_struct *tty); -extern void usb_serial_generic_release(struct usb_serial *serial); extern int usb_serial_generic_register(void); extern void usb_serial_generic_deregister(void); extern int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port, -- cgit v1.2.3 From c3452f5e444446fad9bb1957d22a25334798f94c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:44 +0100 Subject: USB: serial: clean up generic-operation handling Most USB serial drivers are, and should be, using as much of the generic implementation as possible. Rename the fixup_generic function to a more descriptive name. Reword the related debug message in a more neutral tone (and remember to add the missing newline). Finally, move the operations initialisation to after the initial sanity checks. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4819fd9a639a..3eb4d06e49be 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1291,12 +1291,12 @@ module_exit(usb_serial_exit); do { \ if (!type->function) { \ type->function = usb_serial_generic_##function; \ - pr_debug("Had to override the " #function \ - " usb serial operation with the generic one.");\ - } \ + pr_debug("%s: using generic " #function "\n", \ + type->driver.name); \ + } \ } while (0) -static void fixup_generic(struct usb_serial_driver *device) +static void usb_serial_operations_init(struct usb_serial_driver *device) { set_to_generic_if_null(device, open); set_to_generic_if_null(device, write); @@ -1316,8 +1316,6 @@ static int usb_serial_register(struct usb_serial_driver *driver) if (usb_disabled()) return -ENODEV; - fixup_generic(driver); - if (!driver->description) driver->description = driver->driver.name; if (!driver->usb_driver) { @@ -1326,6 +1324,8 @@ static int usb_serial_register(struct usb_serial_driver *driver) return -EINVAL; } + usb_serial_operations_init(driver); + /* Add this device to our list of devices */ mutex_lock(&table_lock); list_add(&driver->driver_list, &usb_serial_driver_list); -- cgit v1.2.3 From a4a83100a1653a389a5efaa68ad32c9b89010910 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:46 +0100 Subject: USB: serial: fix port release We should not call kill_traffic (and usb_kill_urb) once disconnect returns. Any pending urbs are killed at disconnect and new submissions are prevented by usb_unbind_interface (and usb_disable_interface). Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 3eb4d06e49be..456792952db6 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -572,13 +572,6 @@ static void port_release(struct device *dev) dev_dbg(dev, "%s\n", __func__); - /* - * Stop all the traffic before cancelling the work, so that - * nobody will restart it by calling usb_serial_port_softint. - */ - kill_traffic(port); - cancel_work_sync(&port->work); - usb_free_urb(port->interrupt_in_urb); usb_free_urb(port->interrupt_out_urb); for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { -- cgit v1.2.3 From 69a3d2125796b3452da1b9fce851af96ac24b3a9 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:47 +0100 Subject: USB: serial: rename port release Rename port_release so that all usb_serial_port functions have a common prefix. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 456792952db6..db0b646d5dc9 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -565,7 +565,7 @@ static void kill_traffic(struct usb_serial_port *port) usb_kill_urb(port->interrupt_out_urb); } -static void port_release(struct device *dev) +static void usb_serial_port_release(struct device *dev) { struct usb_serial_port *port = to_usb_serial_port(dev); int i; @@ -888,7 +888,7 @@ static int usb_serial_probe(struct usb_interface *interface, port->dev.parent = &interface->dev; port->dev.driver = NULL; port->dev.bus = &usb_serial_bus_type; - port->dev.release = &port_release; + port->dev.release = &usb_serial_port_release; device_initialize(&port->dev); } -- cgit v1.2.3 From 6a5c821cad1459ec2b5fd5778f46d13c4255a7bf Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:49 +0100 Subject: USB: serial: use urb poison to reliably kill traffic Use usb_poison_urb to reliably kill all urbs on disconnect and suspend. This way there will be no question that the urbs cannot be resubmitted by buggy subdrivers. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 55 +++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 18 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index db0b646d5dc9..0b39d013c505 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -542,27 +542,30 @@ static void usb_serial_port_work(struct work_struct *work) tty_kref_put(tty); } -static void kill_traffic(struct usb_serial_port *port) +static void usb_serial_port_poison_urbs(struct usb_serial_port *port) { int i; for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) - usb_kill_urb(port->read_urbs[i]); + usb_poison_urb(port->read_urbs[i]); for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) - usb_kill_urb(port->write_urbs[i]); - /* - * This is tricky. - * Some drivers submit the read_urb in the - * handler for the write_urb or vice versa - * this order determines the order in which - * usb_kill_urb() must be used to reliably - * kill the URBs. As it is unknown here, - * both orders must be used in turn. - * The call below is not redundant. - */ - usb_kill_urb(port->read_urb); - usb_kill_urb(port->interrupt_in_urb); - usb_kill_urb(port->interrupt_out_urb); + usb_poison_urb(port->write_urbs[i]); + + usb_poison_urb(port->interrupt_in_urb); + usb_poison_urb(port->interrupt_out_urb); +} + +static void usb_serial_port_unpoison_urbs(struct usb_serial_port *port) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) + usb_unpoison_urb(port->read_urbs[i]); + for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) + usb_unpoison_urb(port->write_urbs[i]); + + usb_unpoison_urb(port->interrupt_in_urb); + usb_unpoison_urb(port->interrupt_out_urb); } static void usb_serial_port_release(struct device *dev) @@ -1082,7 +1085,7 @@ static void usb_serial_disconnect(struct usb_interface *interface) tty_vhangup(tty); tty_kref_put(tty); } - kill_traffic(port); + usb_serial_port_poison_urbs(port); cancel_work_sync(&port->work); if (device_is_registered(&port->dev)) device_del(&port->dev); @@ -1120,7 +1123,7 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; if (port) - kill_traffic(port); + usb_serial_port_poison_urbs(port); } err_out: @@ -1128,11 +1131,25 @@ err_out: } EXPORT_SYMBOL(usb_serial_suspend); +static void usb_serial_unpoison_port_urbs(struct usb_serial *serial) +{ + struct usb_serial_port *port; + int i; + + for (i = 0; i < serial->num_ports; ++i) { + port = serial->port[i]; + if (port) + usb_serial_port_unpoison_urbs(port); + } +} + int usb_serial_resume(struct usb_interface *intf) { struct usb_serial *serial = usb_get_intfdata(intf); int rv; + usb_serial_unpoison_port_urbs(serial); + serial->suspending = 0; if (serial->type->resume) rv = serial->type->resume(serial); @@ -1148,6 +1165,8 @@ static int usb_serial_reset_resume(struct usb_interface *intf) struct usb_serial *serial = usb_get_intfdata(intf); int rv; + usb_serial_unpoison_port_urbs(serial); + serial->suspending = 0; if (serial->type->reset_resume) rv = serial->type->reset_resume(serial); -- cgit v1.2.3 From 143d9d961608b737d90a813deaaf91affb41c83c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:51 +0100 Subject: USB: serial: add tiocmiwait subdriver operation Add tiocmiwait operation to struct usb_serial_driver. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 15 +++++++++++---- include/linux/usb/serial.h | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 0b39d013c505..ada400d6594b 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -402,10 +402,17 @@ static int serial_ioctl(struct tty_struct *tty, dev_dbg(tty->dev, "%s - cmd 0x%.4x\n", __func__, cmd); - if (port->serial->type->ioctl) - retval = port->serial->type->ioctl(tty, cmd, arg); - else - retval = -ENOIOCTLCMD; + switch (cmd) { + case TIOCMIWAIT: + if (port->serial->type->tiocmiwait) + retval = port->serial->type->tiocmiwait(tty, arg); + break; + default: + if (port->serial->type->ioctl) + retval = port->serial->type->ioctl(tty, cmd, arg); + else + retval = -ENOIOCTLCMD; + } return retval; } diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 3f8f5e3c76d5..9c8b53f80f48 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -272,6 +272,7 @@ struct usb_serial_driver { int (*tiocmget)(struct tty_struct *tty); int (*tiocmset)(struct tty_struct *tty, unsigned int set, unsigned int clear); + int (*tiocmiwait)(struct tty_struct *tty, unsigned long arg); int (*get_icount)(struct tty_struct *tty, struct serial_icounter_struct *icount); /* Called by the tty layer for port level work. There may or may not -- cgit v1.2.3 From c371de14b9a23aadb57accab0ca2e5dd28de7f16 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:36:53 +0100 Subject: USB: serial: wake up MSR-wait queue on disconnect Make sure processes waiting for modem-status changes are woken up at disconnect. This is needed for custom subdriver TIOCMIWAIT-implementations which do not yet handle hangup. Even though processes on the tty-port wait queue are woken up at hangup the wake-up call in usb-serial disconnect is still needed if a woken-up process may go back to sleep (e.g. due to an incomplete TIOCMIWAIT-implementation). If a disconnect occurs after a hangup, any process waiting for changes will not be woken up a second time by the tty-layer as the port will then have been disassociated from the tty. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index ada400d6594b..456881620727 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1093,6 +1093,7 @@ static void usb_serial_disconnect(struct usb_interface *interface) tty_kref_put(tty); } usb_serial_port_poison_urbs(port); + wake_up_interruptible(&port->port.delta_msr_wait); cancel_work_sync(&port->work); if (device_is_registered(&port->dev)) device_del(&port->dev); -- cgit v1.2.3 From 659597b77493959c699b4e99841a2c778eaa70bc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 21 Mar 2013 12:37:51 +0100 Subject: USB: serial: update copyright information Update copyright information. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 +- drivers/usb/serial/generic.c | 2 +- drivers/usb/serial/usb-serial.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1199dc52e388..9a5295efc74d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1,7 +1,7 @@ /* * USB FTDI SIO driver * - * Copyright (C) 2009 - 2010 + * Copyright (C) 2009 - 2013 * Johan Hovold (jhovold@gmail.com) * Copyright (C) 1999 - 2001 * Greg Kroah-Hartman (greg@kroah.com) diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 5e55761b2cb8..297665fdd16d 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -1,7 +1,7 @@ /* * USB Serial Converter Generic functions * - * Copyright (C) 2010 - 2011 Johan Hovold (jhovold@gmail.com) + * Copyright (C) 2010 - 2013 Johan Hovold (jhovold@gmail.com) * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 456881620727..5eb96df8de05 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1,6 +1,7 @@ /* * USB Serial Converter driver * + * Copyright (C) 2009 - 2013 Johan Hovold (jhovold@gmail.com) * Copyright (C) 1999 - 2012 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2000 Peter Berger (pberger@brimson.com) * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com) -- cgit v1.2.3 From b13379758f17e66d60f1f288bf917762c54ebd2f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 28 Mar 2013 11:02:24 -0700 Subject: Revert "USB: serial: fix hang when opening port" This reverts commit eba0e3c3a0ba7b96f01cbe997680f6a4401a0bfc. When merged together (usb-linus and usb-next), this fix isn't needed and causes a build error. Revert the commit to solve the build issue. Reported-by: Stephen Rothwell Cc: Ming Lei Cc: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/usb/serial/usb-serial.c') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 57e6f53a3dac..5eb96df8de05 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -892,7 +892,6 @@ static int usb_serial_probe(struct usb_interface *interface, port->port.ops = &serial_port_ops; port->serial = serial; spin_lock_init(&port->lock); - init_waitqueue_head(&port->delta_msr_wait); /* Keep this for private driver use for the moment but should probably go away */ INIT_WORK(&port->work, usb_serial_port_work); -- cgit v1.2.3