diff options
author | Johan Hovold <jhovold@gmail.com> | 2014-05-26 19:23:07 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-27 15:04:05 -0700 |
commit | 71c149b901e367db5dae1ec83bb82d14d01ad4cb (patch) | |
tree | d046de38a73c75f91a7df73bce9c70a5b8c0328c /drivers/usb | |
parent | 7d8825bed46a28688f97cc934ecb326cc4ce2d2e (diff) | |
download | linux-71c149b901e367db5dae1ec83bb82d14d01ad4cb.tar.bz2 |
USB: sierra: refactor delayed-urb submission
Refactor and clean up delayed-urb submission at resume.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/sierra.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 1d42e8305b8e..967331964f36 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -981,12 +981,51 @@ static int sierra_suspend(struct usb_serial *serial, pm_message_t message) return 0; } +/* Caller must hold susp_lock. */ +static int sierra_submit_delayed_urbs(struct usb_serial_port *port) +{ + struct sierra_port_private *portdata = usb_get_serial_port_data(port); + struct sierra_intf_private *intfdata; + struct urb *urb; + int ec = 0; + int err; + + intfdata = usb_get_serial_data(port->serial); + + for (;;) { + urb = usb_get_from_anchor(&portdata->delayed); + if (!urb) + break; + + usb_anchor_urb(urb, &portdata->active); + intfdata->in_flight++; + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err) { + dev_err(&port->dev, "%s - submit urb failed: %d", + __func__, err); + ec++; + intfdata->in_flight--; + usb_unanchor_urb(urb); + kfree(urb->transfer_buffer); + usb_free_urb(urb); + + spin_lock(&portdata->lock); + portdata->outstanding_urbs--; + spin_unlock(&portdata->lock); + } + } + + if (ec) + return -EIO; + + return 0; +} + static int sierra_resume(struct usb_serial *serial) { struct usb_serial_port *port; struct sierra_intf_private *intfdata = usb_get_serial_data(serial); struct sierra_port_private *portdata; - struct urb *urb; int ec = 0; int i, err; @@ -998,25 +1037,9 @@ static int sierra_resume(struct usb_serial *serial) if (!portdata || !portdata->opened) continue; - while ((urb = usb_get_from_anchor(&portdata->delayed))) { - usb_anchor_urb(urb, &portdata->active); - intfdata->in_flight++; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0) { - dev_err(&port->dev, - "%s - submit urb failed: %d", - __func__, err); - ec++; - intfdata->in_flight--; - usb_unanchor_urb(urb); - kfree(urb->transfer_buffer); - usb_free_urb(urb); - spin_lock(&portdata->lock); - portdata->outstanding_urbs--; - spin_unlock(&portdata->lock); - continue; - } - } + err = sierra_submit_delayed_urbs(port); + if (err) + ec++; err = sierra_submit_rx_urbs(port, GFP_ATOMIC); if (err) |