diff options
author | Oliver Neukum <oliver@neukum.org> | 2011-02-10 15:33:29 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-17 10:51:12 -0800 |
commit | 16871dcac74c63227aa92e0012f3004a648c2062 (patch) | |
tree | 9cfb094c3e86ed37fe1a99a2f8024dd3860f0e43 /drivers/usb/serial | |
parent | 433508ae30f13c0bf6905e576c42899a8535f0bb (diff) |
usb_wwan: error case of resume
If an error happens during resumption.
The remaining data has to be cleanly discarded and the pm
counters have to be adjusted.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/usb_wwan.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 84fe1b6ba11..fe5e48eb969 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -664,6 +664,18 @@ int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) } EXPORT_SYMBOL(usb_wwan_suspend); +static void unbusy_queued_urb(struct urb *urb, struct usb_wwan_port_private *portdata) +{ + int i; + + for (i = 0; i < N_OUT_URB; i++) { + if (urb == portdata->out_urbs[i]) { + clear_bit(i, &portdata->out_busy); + break; + } + } +} + static void play_delayed(struct usb_serial_port *port) { struct usb_wwan_intf_private *data; @@ -675,8 +687,17 @@ static void play_delayed(struct usb_serial_port *port) data = port->serial->private; while ((urb = usb_get_from_anchor(&portdata->delayed))) { err = usb_submit_urb(urb, GFP_ATOMIC); - if (!err) + if (!err) { data->in_flight++; + } else { + /* we have to throw away the rest */ + do { + unbusy_queued_urb(urb, portdata); + //extremely dirty + atomic_dec(&port->serial->interface->dev.power.usage_count); + } while ((urb = usb_get_from_anchor(&portdata->delayed))); + break; + } } } |