diff options
author | Johan Hovold <jhovold@gmail.com> | 2014-03-12 14:09:40 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <greg@kroah.com> | 2014-03-12 15:44:49 -0400 |
commit | bd58c7bd6fd5f803b4127717bda9cc6c30d0c806 (patch) | |
tree | 6c25cb3bdac38906157f57bc6976c08beee59f5c /drivers/usb/serial | |
parent | fc11efe2800f2f9ba2ccb268321642b7e9f73a65 (diff) |
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 <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/generic.c | 29 |
1 files 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) | |||
397 | { | 397 | { |
398 | unsigned long flags; | 398 | unsigned long flags; |
399 | struct usb_serial_port *port = urb->context; | 399 | struct usb_serial_port *port = urb->context; |
400 | int status = urb->status; | ||
401 | int i; | 400 | int i; |
402 | 401 | ||
403 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) | 402 | for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) |
@@ -409,17 +408,27 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb) | |||
409 | set_bit(i, &port->write_urbs_free); | 408 | set_bit(i, &port->write_urbs_free); |
410 | spin_unlock_irqrestore(&port->lock, flags); | 409 | spin_unlock_irqrestore(&port->lock, flags); |
411 | 410 | ||
412 | if (status) { | 411 | switch (urb->status) { |
413 | dev_dbg(&port->dev, "%s - non-zero urb status: %d\n", | 412 | case 0: |
414 | __func__, status); | 413 | break; |
415 | 414 | case -ENOENT: | |
416 | spin_lock_irqsave(&port->lock, flags); | 415 | case -ECONNRESET: |
417 | kfifo_reset_out(&port->write_fifo); | 416 | case -ESHUTDOWN: |
418 | spin_unlock_irqrestore(&port->lock, flags); | 417 | dev_dbg(&port->dev, "%s - urb stopped: %d\n", |
419 | } else { | 418 | __func__, urb->status); |
420 | usb_serial_generic_write_start(port, GFP_ATOMIC); | 419 | return; |
420 | case -EPIPE: | ||
421 | dev_err_console(port, "%s - urb stopped: %d\n", | ||
422 | __func__, urb->status); | ||
423 | return; | ||
424 | default: | ||
425 | dev_err_console(port, "%s - nonzero urb status: %d\n", | ||
426 | __func__, urb->status); | ||
427 | goto resubmit; | ||
421 | } | 428 | } |
422 | 429 | ||
430 | resubmit: | ||
431 | usb_serial_generic_write_start(port, GFP_ATOMIC); | ||
423 | usb_serial_port_softint(port); | 432 | usb_serial_port_softint(port); |
424 | } | 433 | } |
425 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); | 434 | EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); |