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 <[email protected]>
---
 drivers/usb/serial/generic.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

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);
-- 
1.8.3.2

--
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

Reply via email to