diff options
Diffstat (limited to 'drivers/usb/serial/visor.c')
-rw-r--r-- | drivers/usb/serial/visor.c | 64 |
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 | ||
551 | static void visor_read_int_callback (struct urb *urb) | 559 | static 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) { |