From fc11efe2800f2f9ba2ccb268321642b7e9f73a65 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 12 Mar 2014 19:09:39 +0100 Subject: USB: serial: continue to read on errors Make sure to try to resubmit the read urb on errors. Currently a recoverable error would lead to reduced throughput as only one urb will be used until the port is closed and reopened (or resumed or unthrottled). Also upgrade error messages from debug to error log level. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers/usb/serial/generic.c') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index b63ce023f96f..d7f39ea7d6ac 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -359,16 +359,29 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb) dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i, urb->actual_length); - - if (urb->status) { - dev_dbg(&port->dev, "%s - non-zero urb status: %d\n", - __func__, urb->status); + switch (urb->status) { + case 0: + break; + case -ENOENT: + case -ECONNRESET: + case -ESHUTDOWN: + dev_dbg(&port->dev, "%s - urb stopped: %d\n", + __func__, urb->status); + return; + case -EPIPE: + dev_err(&port->dev, "%s - urb stopped: %d\n", + __func__, urb->status); return; + default: + dev_err(&port->dev, "%s - nonzero urb status: %d\n", + __func__, urb->status); + goto resubmit; } usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); port->serial->type->process_read_urb(urb); +resubmit: /* Throttle the device if requested by tty */ spin_lock_irqsave(&port->lock, flags); port->throttled = port->throttle_req; -- cgit v1.2.2 From bd58c7bd6fd5f803b4127717bda9cc6c30d0c806 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 12 Mar 2014 19:09:40 +0100 Subject: USB: serial: continue to write on errors Do not discard buffered data and make sure to try to resubmit the write urbs on errors. Currently a recoverable error would lead to more data than necessary being dropped. Also upgrade error messages from debug to error log level. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'drivers/usb/serial/generic.c') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index d7f39ea7d6ac..33d7f4092308 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -397,7 +397,6 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) { unsigned long flags; struct usb_serial_port *port = urb->context; - int status = urb->status; int i; for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) @@ -409,17 +408,27 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) set_bit(i, &port->write_urbs_free); spin_unlock_irqrestore(&port->lock, flags); - if (status) { - dev_dbg(&port->dev, "%s - non-zero urb status: %d\n", - __func__, status); - - spin_lock_irqsave(&port->lock, flags); - kfifo_reset_out(&port->write_fifo); - spin_unlock_irqrestore(&port->lock, flags); - } else { - usb_serial_generic_write_start(port, GFP_ATOMIC); + switch (urb->status) { + case 0: + break; + case -ENOENT: + case -ECONNRESET: + case -ESHUTDOWN: + dev_dbg(&port->dev, "%s - urb stopped: %d\n", + __func__, urb->status); + return; + case -EPIPE: + dev_err_console(port, "%s - urb stopped: %d\n", + __func__, urb->status); + return; + default: + dev_err_console(port, "%s - nonzero urb status: %d\n", + __func__, urb->status); + goto resubmit; } +resubmit: + usb_serial_generic_write_start(port, GFP_ATOMIC); usb_serial_port_softint(port); } EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); -- cgit v1.2.2 From ca0400d2caf0d6f18445feea79c8c5a4ccf77e61 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 12 Mar 2014 19:09:41 +0100 Subject: USB: serial: add missing braces Add missing braces to conditional branches and one loop in usb-serial core and generic implementation. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/generic.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/usb/serial/generic.c') diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 33d7f4092308..1bd192290b08 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -332,9 +332,9 @@ void usb_serial_generic_process_read_urb(struct urb *urb) * stuff like 3G modems, so shortcircuit it in the 99.9999999% of * cases where the USB serial is not a console anyway. */ - if (!port->port.console || !port->sysrq) + if (!port->port.console || !port->sysrq) { tty_insert_flip_string(&port->port, ch, urb->actual_length); - else { + } else { for (i = 0; i < urb->actual_length; i++, ch++) { if (!usb_serial_handle_sysrq_char(port, *ch)) tty_insert_flip_char(&port->port, *ch, TTY_NORMAL); @@ -388,8 +388,9 @@ resubmit: if (!port->throttled) { spin_unlock_irqrestore(&port->lock, flags); usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC); - } else + } else { spin_unlock_irqrestore(&port->lock, flags); + } } EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); @@ -399,10 +400,10 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) struct usb_serial_port *port = urb->context; int i; - for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) + for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) { if (port->write_urbs[i] == urb) break; - + } spin_lock_irqsave(&port->lock, flags); port->tx_bytes -= urb->transfer_buffer_length; set_bit(i, &port->write_urbs_free); -- cgit v1.2.2