diff options
| author | Oliver Neukum <oliver@neukum.org> | 2009-10-07 05:01:38 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-10-09 16:52:09 -0400 |
| commit | a1c33952b729eba4cedb8dbe54765921f2b3062f (patch) | |
| tree | dbdf6757ee483ee07cede1fd340b27b8018a1bb7 /drivers | |
| parent | 638325154572ba2113a18669fe3b299caa2dabd9 (diff) | |
USB: serial: fix race between unthrottle and completion handler in visor
usb:usbserial:visor: fix race between unthrottle and completion handler
visor_unthrottle() mustn't resubmit the URB unconditionally
as the URB may still be running.
the same bug as opticon.
Signed-off-by: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/usb/serial/visor.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index b9341f0e452b..ad1f9232292d 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
| @@ -595,20 +595,23 @@ static void visor_unthrottle(struct tty_struct *tty) | |||
| 595 | { | 595 | { |
| 596 | struct usb_serial_port *port = tty->driver_data; | 596 | struct usb_serial_port *port = tty->driver_data; |
| 597 | struct visor_private *priv = usb_get_serial_port_data(port); | 597 | struct visor_private *priv = usb_get_serial_port_data(port); |
| 598 | int result; | 598 | int result, was_throttled; |
| 599 | 599 | ||
| 600 | dbg("%s - port %d", __func__, port->number); | 600 | dbg("%s - port %d", __func__, port->number); |
| 601 | spin_lock_irq(&priv->lock); | 601 | spin_lock_irq(&priv->lock); |
| 602 | priv->throttled = 0; | 602 | priv->throttled = 0; |
| 603 | was_throttled = priv->actually_throttled; | ||
| 603 | priv->actually_throttled = 0; | 604 | priv->actually_throttled = 0; |
| 604 | spin_unlock_irq(&priv->lock); | 605 | spin_unlock_irq(&priv->lock); |
| 605 | 606 | ||
| 606 | port->read_urb->dev = port->serial->dev; | 607 | if (was_throttled) { |
| 607 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); | 608 | port->read_urb->dev = port->serial->dev; |
| 608 | if (result) | 609 | result = usb_submit_urb(port->read_urb, GFP_KERNEL); |
| 609 | dev_err(&port->dev, | 610 | if (result) |
| 610 | "%s - failed submitting read urb, error %d\n", | 611 | dev_err(&port->dev, |
| 612 | "%s - failed submitting read urb, error %d\n", | ||
| 611 | __func__, result); | 613 | __func__, result); |
| 614 | } | ||
| 612 | } | 615 | } |
| 613 | 616 | ||
| 614 | static int palm_os_3_probe(struct usb_serial *serial, | 617 | static int palm_os_3_probe(struct usb_serial *serial, |
