aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/generic.c
diff options
context:
space:
mode:
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 b63ce023f96f..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)
332 * stuff like 3G modems, so shortcircuit it in the 99.9999999% of 332 * stuff like 3G modems, so shortcircuit it in the 99.9999999% of
333 * cases where the USB serial is not a console anyway. 333 * cases where the USB serial is not a console anyway.
334 */ 334 */
335 if (!port->port.console || !port->sysrq) 335 if (!port->port.console || !port->sysrq) {
336 tty_insert_flip_string(&port->port, ch, urb->actual_length); 336 tty_insert_flip_string(&port->port, ch, urb->actual_length);
337 else { 337 } else {
338 for (i = 0; i < urb->actual_length; i++, ch++) { 338 for (i = 0; i < urb->actual_length; i++, ch++) {
339 if (!usb_serial_handle_sysrq_char(port, *ch)) 339 if (!usb_serial_handle_sysrq_char(port, *ch))
340 tty_insert_flip_char(&port->port, *ch, TTY_NORMAL); 340 tty_insert_flip_char(&port->port, *ch, TTY_NORMAL);
@@ -359,24 +359,38 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)
359 359
360 dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i, 360 dev_dbg(&port->dev, "%s - urb %d, len %d\n", __func__, i,
361 urb->actual_length); 361 urb->actual_length);
362 362 switch (urb->status) {
363 if (urb->status) { 363 case 0:
364 dev_dbg(&port->dev, "%s - non-zero urb status: %d\n", 364 break;
365 __func__, urb->status); 365 case -ENOENT:
366 case -ECONNRESET:
367 case -ESHUTDOWN:
368 dev_dbg(&port->dev, "%s - urb stopped: %d\n",
369 __func__, urb->status);
366 return; 370 return;
371 case -EPIPE:
372 dev_err(&port->dev, "%s - urb stopped: %d\n",
373 __func__, urb->status);
374 return;
375 default:
376 dev_err(&port->dev, "%s - nonzero urb status: %d\n",
377 __func__, urb->status);
378 goto resubmit;
367 } 379 }
368 380
369 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data); 381 usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
370 port->serial->type->process_read_urb(urb); 382 port->serial->type->process_read_urb(urb);
371 383
384resubmit:
372 /* Throttle the device if requested by tty */ 385 /* Throttle the device if requested by tty */
373 spin_lock_irqsave(&port->lock, flags); 386 spin_lock_irqsave(&port->lock, flags);
374 port->throttled = port->throttle_req; 387 port->throttled = port->throttle_req;
375 if (!port->throttled) { 388 if (!port->throttled) {
376 spin_unlock_irqrestore(&port->lock, flags); 389 spin_unlock_irqrestore(&port->lock, flags);
377 usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC); 390 usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC);
378 } else 391 } else {
379 spin_unlock_irqrestore(&port->lock, flags); 392 spin_unlock_irqrestore(&port->lock, flags);
393 }
380} 394}
381EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); 395EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
382 396
@@ -384,29 +398,38 @@ void usb_serial_generic_write_bulk_callback(struct urb *urb)
384{ 398{
385 unsigned long flags; 399 unsigned long flags;
386 struct usb_serial_port *port = urb->context; 400 struct usb_serial_port *port = urb->context;
387 int status = urb->status;
388 int i; 401 int i;
389 402
390 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) 403 for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) {
391 if (port->write_urbs[i] == urb) 404 if (port->write_urbs[i] == urb)
392 break; 405 break;
393 406 }
394 spin_lock_irqsave(&port->lock, flags); 407 spin_lock_irqsave(&port->lock, flags);
395 port->tx_bytes -= urb->transfer_buffer_length; 408 port->tx_bytes -= urb->transfer_buffer_length;
396 set_bit(i, &port->write_urbs_free); 409 set_bit(i, &port->write_urbs_free);
397 spin_unlock_irqrestore(&port->lock, flags); 410 spin_unlock_irqrestore(&port->lock, flags);
398 411
399 if (status) { 412 switch (urb->status) {
400 dev_dbg(&port->dev, "%s - non-zero urb status: %d\n", 413 case 0:
401 __func__, status); 414 break;
402 415 case -ENOENT:
403 spin_lock_irqsave(&port->lock, flags); 416 case -ECONNRESET:
404 kfifo_reset_out(&port->write_fifo); 417 case -ESHUTDOWN:
405 spin_unlock_irqrestore(&port->lock, flags); 418 dev_dbg(&port->dev, "%s - urb stopped: %d\n",
406 } else { 419 __func__, urb->status);
407 usb_serial_generic_write_start(port, GFP_ATOMIC); 420 return;
421 case -EPIPE:
422 dev_err_console(port, "%s - urb stopped: %d\n",
423 __func__, urb->status);
424 return;
425 default:
426 dev_err_console(port, "%s - nonzero urb status: %d\n",
427 __func__, urb->status);
428 goto resubmit;
408 } 429 }
409 430
431resubmit:
432 usb_serial_generic_write_start(port, GFP_ATOMIC);
410 usb_serial_port_softint(port); 433 usb_serial_port_softint(port);
411} 434}
412EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); 435EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);