summaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/generic.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-04-14 12:00:36 -0300
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-04-14 12:00:36 -0300
commit277a163c83d7ba93fba1e8980d29a9f8bfcfba6c (patch)
treeccfd357d152292958957b6b8a993892e7a8cc95f /drivers/usb/serial/generic.c
parenta83b93a7480441a47856dc9104bea970e84cda87 (diff)
parentc9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff)
Merge tag 'v3.15-rc1' into patchwork
Linux 3.15-rc1 * tag 'v3.15-rc1': (12180 commits) Linux 3.15-rc1 mm: Initialize error in shmem_file_aio_read() cifs: Use min_t() when comparing "size_t" and "unsigned long" sym53c8xx_2: Set DID_REQUEUE return code when aborting squeue powerpc: Don't try to set LPCR unless we're in hypervisor mode futex: update documentation for ordering guarantees ceph: fix pr_fmt() redefinition vti: don't allow to add the same tunnel twice gre: don't allow to add the same tunnel twice drivers: net: xen-netfront: fix array initialization bug missing bits of "splice: fix racy pipe->buffers uses" cifs: fix the race in cifs_writev() ceph_sync_{,direct_}write: fix an oops on ceph_osdc_new_request() failure pktgen: be friendly to LLTX devices r8152: check RTL8152_UNPLUG net: sun4i-emac: add promiscuous support net/apne: replace IS_ERR and PTR_ERR with PTR_ERR_OR_ZERO blackfin: cleanup board files bf609: clock: drop unused clock bit set/clear functions Blackfin: bf537: rename "CONFIG_ADT75" ...
Diffstat (limited to 'drivers/usb/serial/generic.c')
-rw-r--r--drivers/usb/serial/generic.c61
1 files changed, 42 insertions, 19 deletions
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index b63ce023f96..1bd192290b0 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);
@@ -359,24 +359,38 @@ 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;
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);
@@ -384,29 +398,38 @@ 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)
+ 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);
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);