diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2005-04-23 15:49:16 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-06-27 17:43:47 -0400 |
commit | 507ca9bc0476662f3463888d583864834eab1e11 (patch) | |
tree | 421a373de235fcb4cb46a4723a1e9f00a71f709a /drivers/usb/serial/keyspan_pda.c | |
parent | f4df0e334a9fc731689e8ba4f42a0d72a7491348 (diff) |
[PATCH] USB: add ability for usb-serial drivers to determine if their write urb is currently being used.
This removes a lot of racy and buggy code by trying to check the status of the urb.
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/keyspan_pda.c')
-rw-r--r-- | drivers/usb/serial/keyspan_pda.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 7fd0aa9eccf6..635c384cb15a 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -520,9 +520,13 @@ static int keyspan_pda_write(struct usb_serial_port *port, | |||
520 | the TX urb is in-flight (wait until it completes) | 520 | the TX urb is in-flight (wait until it completes) |
521 | the device is full (wait until it says there is room) | 521 | the device is full (wait until it says there is room) |
522 | */ | 522 | */ |
523 | if (port->write_urb->status == -EINPROGRESS || priv->tx_throttled ) { | 523 | spin_lock(&port->lock); |
524 | return( 0 ); | 524 | if (port->write_urb_busy || priv->tx_throttled) { |
525 | spin_unlock(&port->lock); | ||
526 | return 0; | ||
525 | } | 527 | } |
528 | port->write_urb_busy = 1; | ||
529 | spin_unlock(&port->lock); | ||
526 | 530 | ||
527 | /* At this point the URB is in our control, nobody else can submit it | 531 | /* At this point the URB is in our control, nobody else can submit it |
528 | again (the only sudden transition was the one from EINPROGRESS to | 532 | again (the only sudden transition was the one from EINPROGRESS to |
@@ -570,7 +574,7 @@ static int keyspan_pda_write(struct usb_serial_port *port, | |||
570 | memcpy (port->write_urb->transfer_buffer, buf, count); | 574 | memcpy (port->write_urb->transfer_buffer, buf, count); |
571 | /* send the data out the bulk port */ | 575 | /* send the data out the bulk port */ |
572 | port->write_urb->transfer_buffer_length = count; | 576 | port->write_urb->transfer_buffer_length = count; |
573 | 577 | ||
574 | priv->tx_room -= count; | 578 | priv->tx_room -= count; |
575 | 579 | ||
576 | port->write_urb->dev = port->serial->dev; | 580 | port->write_urb->dev = port->serial->dev; |
@@ -593,6 +597,8 @@ static int keyspan_pda_write(struct usb_serial_port *port, | |||
593 | 597 | ||
594 | rc = count; | 598 | rc = count; |
595 | exit: | 599 | exit: |
600 | if (rc < 0) | ||
601 | port->write_urb_busy = 0; | ||
596 | return rc; | 602 | return rc; |
597 | } | 603 | } |
598 | 604 | ||
@@ -602,6 +608,7 @@ static void keyspan_pda_write_bulk_callback (struct urb *urb, struct pt_regs *re | |||
602 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 608 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
603 | struct keyspan_pda_private *priv; | 609 | struct keyspan_pda_private *priv; |
604 | 610 | ||
611 | port->write_urb_busy = 0; | ||
605 | priv = usb_get_serial_port_data(port); | 612 | priv = usb_get_serial_port_data(port); |
606 | 613 | ||
607 | /* queue up a wakeup at scheduler time */ | 614 | /* queue up a wakeup at scheduler time */ |
@@ -626,12 +633,12 @@ static int keyspan_pda_write_room (struct usb_serial_port *port) | |||
626 | static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port) | 633 | static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port) |
627 | { | 634 | { |
628 | struct keyspan_pda_private *priv; | 635 | struct keyspan_pda_private *priv; |
629 | 636 | ||
630 | priv = usb_get_serial_port_data(port); | 637 | priv = usb_get_serial_port_data(port); |
631 | 638 | ||
632 | /* when throttled, return at least WAKEUP_CHARS to tell select() (via | 639 | /* when throttled, return at least WAKEUP_CHARS to tell select() (via |
633 | n_tty.c:normal_poll() ) that we're not writeable. */ | 640 | n_tty.c:normal_poll() ) that we're not writeable. */ |
634 | if( port->write_urb->status == -EINPROGRESS || priv->tx_throttled ) | 641 | if (port->write_urb_busy || priv->tx_throttled) |
635 | return 256; | 642 | return 256; |
636 | return 0; | 643 | return 0; |
637 | } | 644 | } |