summaryrefslogtreecommitdiff
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2014-05-26 21:23:07 +0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-28 02:04:05 +0400
commit71c149b901e367db5dae1ec83bb82d14d01ad4cb (patch)
treed046de38a73c75f91a7df73bce9c70a5b8c0328c /drivers/usb/serial
parent7d8825bed46a28688f97cc934ecb326cc4ce2d2e (diff)
downloadlinux-71c149b901e367db5dae1ec83bb82d14d01ad4cb.tar.xz
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/serial')
-rw-r--r--drivers/usb/serial/sierra.c63
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)