USB: serial: continue to write on errors
authorJohan Hovold <jhovold@gmail.com>
Wed, 12 Mar 2014 18:09:40 +0000 (19:09 +0100)
committerGreg Kroah-Hartman <greg@kroah.com>
Wed, 12 Mar 2014 19:44:49 +0000 (12:44 -0700)
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 <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
drivers/usb/serial/generic.c

index d7f39ea7d6acc8203392fbbe6e1ef6df727179fa..33d7f40923087cbfed43c4712747e339cf54f586 100644 (file)
@@ -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);