From 507ca9bc0476662f3463888d583864834eab1e11 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 23 Apr 2005 12:49:16 -0700 Subject: [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 --- drivers/usb/serial/keyspan_pda.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers/usb/serial/keyspan_pda.c') diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 7fd0aa9eccf..635c384cb15 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, the TX urb is in-flight (wait until it completes) the device is full (wait until it says there is room) */ - if (port->write_urb->status == -EINPROGRESS || priv->tx_throttled ) { - return( 0 ); + spin_lock(&port->lock); + if (port->write_urb_busy || priv->tx_throttled) { + spin_unlock(&port->lock); + return 0; } + port->write_urb_busy = 1; + spin_unlock(&port->lock); /* At this point the URB is in our control, nobody else can submit it 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, memcpy (port->write_urb->transfer_buffer, buf, count); /* send the data out the bulk port */ port->write_urb->transfer_buffer_length = count; - + priv->tx_room -= count; port->write_urb->dev = port->serial->dev; @@ -593,6 +597,8 @@ static int keyspan_pda_write(struct usb_serial_port *port, rc = count; exit: + if (rc < 0) + port->write_urb_busy = 0; return rc; } @@ -602,6 +608,7 @@ static void keyspan_pda_write_bulk_callback (struct urb *urb, struct pt_regs *re struct usb_serial_port *port = (struct usb_serial_port *)urb->context; struct keyspan_pda_private *priv; + port->write_urb_busy = 0; priv = usb_get_serial_port_data(port); /* queue up a wakeup at scheduler time */ @@ -626,12 +633,12 @@ static int keyspan_pda_write_room (struct usb_serial_port *port) static int keyspan_pda_chars_in_buffer (struct usb_serial_port *port) { struct keyspan_pda_private *priv; - + priv = usb_get_serial_port_data(port); - + /* when throttled, return at least WAKEUP_CHARS to tell select() (via n_tty.c:normal_poll() ) that we're not writeable. */ - if( port->write_urb->status == -EINPROGRESS || priv->tx_throttled ) + if (port->write_urb_busy || priv->tx_throttled) return 256; return 0; } -- cgit v1.2.3