aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/visor.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/visor.c')
-rw-r--r--drivers/usb/serial/visor.c64
1 files changed, 33 insertions, 31 deletions
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index ffbe601cde2a..7d84a7647e81 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -5,9 +5,9 @@
5 * Copyright (C) 1999 - 2004 5 * Copyright (C) 1999 - 2004
6 * Greg Kroah-Hartman (greg@kroah.com) 6 * Greg Kroah-Hartman (greg@kroah.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or
9 * it under the terms of the GNU General Public License as published by 9 * modify it under the terms of the GNU General Public License version
10 * the Free Software Foundation; either version 2 of the License. 10 * 2 as published by the Free Software Foundation.
11 * 11 *
12 * See Documentation/usb/usb-serial.txt for more information on using this driver 12 * See Documentation/usb/usb-serial.txt for more information on using this driver
13 * 13 *
@@ -273,7 +273,8 @@ struct visor_private {
273 int bytes_in; 273 int bytes_in;
274 int bytes_out; 274 int bytes_out;
275 int outstanding_urbs; 275 int outstanding_urbs;
276 int throttled; 276 unsigned char throttled;
277 unsigned char actually_throttled;
277}; 278};
278 279
279/* number of outstanding urbs to prevent userspace DoS from happening */ 280/* number of outstanding urbs to prevent userspace DoS from happening */
@@ -484,16 +485,17 @@ static void visor_write_bulk_callback (struct urb *urb)
484{ 485{
485 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 486 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
486 struct visor_private *priv = usb_get_serial_port_data(port); 487 struct visor_private *priv = usb_get_serial_port_data(port);
488 int status = urb->status;
487 unsigned long flags; 489 unsigned long flags;
488 490
489 /* free up the transfer buffer, as usb_free_urb() does not do this */ 491 /* free up the transfer buffer, as usb_free_urb() does not do this */
490 kfree (urb->transfer_buffer); 492 kfree (urb->transfer_buffer);
491 493
492 dbg("%s - port %d", __FUNCTION__, port->number); 494 dbg("%s - port %d", __FUNCTION__, port->number);
493 495
494 if (urb->status) 496 if (status)
495 dbg("%s - nonzero write bulk status received: %d", 497 dbg("%s - nonzero write bulk status received: %d",
496 __FUNCTION__, urb->status); 498 __FUNCTION__, status);
497 499
498 spin_lock_irqsave(&priv->lock, flags); 500 spin_lock_irqsave(&priv->lock, flags);
499 --priv->outstanding_urbs; 501 --priv->outstanding_urbs;
@@ -508,15 +510,16 @@ static void visor_read_bulk_callback (struct urb *urb)
508 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 510 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
509 struct visor_private *priv = usb_get_serial_port_data(port); 511 struct visor_private *priv = usb_get_serial_port_data(port);
510 unsigned char *data = urb->transfer_buffer; 512 unsigned char *data = urb->transfer_buffer;
513 int status = urb->status;
511 struct tty_struct *tty; 514 struct tty_struct *tty;
512 unsigned long flags;
513 int throttled;
514 int result; 515 int result;
516 int available_room;
515 517
516 dbg("%s - port %d", __FUNCTION__, port->number); 518 dbg("%s - port %d", __FUNCTION__, port->number);
517 519
518 if (urb->status) { 520 if (status) {
519 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status); 521 dbg("%s - nonzero read bulk status received: %d",
522 __FUNCTION__, status);
520 return; 523 return;
521 } 524 }
522 525
@@ -524,17 +527,20 @@ static void visor_read_bulk_callback (struct urb *urb)
524 527
525 tty = port->tty; 528 tty = port->tty;
526 if (tty && urb->actual_length) { 529 if (tty && urb->actual_length) {
527 tty_buffer_request_room(tty, urb->actual_length); 530 available_room = tty_buffer_request_room(tty, urb->actual_length);
528 tty_insert_flip_string(tty, data, urb->actual_length); 531 if (available_room) {
529 tty_flip_buffer_push(tty); 532 tty_insert_flip_string(tty, data, available_room);
533 tty_flip_buffer_push(tty);
534 }
535 spin_lock(&priv->lock);
536 priv->bytes_in += available_room;
537
538 } else {
539 spin_lock(&priv->lock);
530 } 540 }
531 spin_lock_irqsave(&priv->lock, flags);
532 priv->bytes_in += urb->actual_length;
533 throttled = priv->throttled;
534 spin_unlock_irqrestore(&priv->lock, flags);
535 541
536 /* Continue trying to always read if we should */ 542 /* Continue trying to always read if we should */
537 if (!throttled) { 543 if (!priv->throttled) {
538 usb_fill_bulk_urb (port->read_urb, port->serial->dev, 544 usb_fill_bulk_urb (port->read_urb, port->serial->dev,
539 usb_rcvbulkpipe(port->serial->dev, 545 usb_rcvbulkpipe(port->serial->dev,
540 port->bulk_in_endpointAddress), 546 port->bulk_in_endpointAddress),
@@ -544,16 +550,19 @@ static void visor_read_bulk_callback (struct urb *urb)
544 result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 550 result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
545 if (result) 551 if (result)
546 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); 552 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
553 } else {
554 priv->actually_throttled = 1;
547 } 555 }
548 return; 556 spin_unlock(&priv->lock);
549} 557}
550 558
551static void visor_read_int_callback (struct urb *urb) 559static void visor_read_int_callback (struct urb *urb)
552{ 560{
553 struct usb_serial_port *port = (struct usb_serial_port *)urb->context; 561 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
562 int status = urb->status;
554 int result; 563 int result;
555 564
556 switch (urb->status) { 565 switch (status) {
557 case 0: 566 case 0:
558 /* success */ 567 /* success */
559 break; 568 break;
@@ -562,11 +571,11 @@ static void visor_read_int_callback (struct urb *urb)
562 case -ESHUTDOWN: 571 case -ESHUTDOWN:
563 /* this urb is terminated, clean up */ 572 /* this urb is terminated, clean up */
564 dbg("%s - urb shutting down with status: %d", 573 dbg("%s - urb shutting down with status: %d",
565 __FUNCTION__, urb->status); 574 __FUNCTION__, status);
566 return; 575 return;
567 default: 576 default:
568 dbg("%s - nonzero urb status received: %d", 577 dbg("%s - nonzero urb status received: %d",
569 __FUNCTION__, urb->status); 578 __FUNCTION__, status);
570 goto exit; 579 goto exit;
571 } 580 }
572 581
@@ -608,6 +617,7 @@ static void visor_unthrottle (struct usb_serial_port *port)
608 dbg("%s - port %d", __FUNCTION__, port->number); 617 dbg("%s - port %d", __FUNCTION__, port->number);
609 spin_lock_irqsave(&priv->lock, flags); 618 spin_lock_irqsave(&priv->lock, flags);
610 priv->throttled = 0; 619 priv->throttled = 0;
620 priv->actually_throttled = 0;
611 spin_unlock_irqrestore(&priv->lock, flags); 621 spin_unlock_irqrestore(&priv->lock, flags);
612 622
613 port->read_urb->dev = port->serial->dev; 623 port->read_urb->dev = port->serial->dev;
@@ -938,14 +948,6 @@ static void visor_set_termios (struct usb_serial_port *port, struct ktermios *ol
938 } 948 }
939 949
940 cflag = port->tty->termios->c_cflag; 950 cflag = port->tty->termios->c_cflag;
941 /* check that they really want us to change something */
942 if (old_termios) {
943 if ((cflag == old_termios->c_cflag) &&
944 (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
945 dbg("%s - nothing to change...", __FUNCTION__);
946 return;
947 }
948 }
949 951
950 /* get the byte size */ 952 /* get the byte size */
951 switch (cflag & CSIZE) { 953 switch (cflag & CSIZE) {