diff options
author | Oliver Neukum <oliver@neukum.org> | 2011-02-10 09:33:29 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-17 13:51:12 -0500 |
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 84fe1b6ba11b..fe5e48eb9693 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) | |||
664 | } | 664 | } |
665 | EXPORT_SYMBOL(usb_wwan_suspend); | 665 | EXPORT_SYMBOL(usb_wwan_suspend); |
666 | 666 | ||
667 | static void unbusy_queued_urb(struct urb *urb, struct usb_wwan_port_private *portdata) | ||
668 | { | ||
669 | int i; | ||
670 | |||
671 | for (i = 0; i < N_OUT_URB; i++) { | ||
672 | if (urb == portdata->out_urbs[i]) { | ||
673 | clear_bit(i, &portdata->out_busy); | ||
674 | break; | ||
675 | } | ||
676 | } | ||
677 | } | ||
678 | |||
667 | static void play_delayed(struct usb_serial_port *port) | 679 | static void play_delayed(struct usb_serial_port *port) |
668 | { | 680 | { |
669 | struct usb_wwan_intf_private *data; | 681 | struct usb_wwan_intf_private *data; |
@@ -675,8 +687,17 @@ static void play_delayed(struct usb_serial_port *port) | |||
675 | data = port->serial->private; | 687 | data = port->serial->private; |
676 | while ((urb = usb_get_from_anchor(&portdata->delayed))) { | 688 | while ((urb = usb_get_from_anchor(&portdata->delayed))) { |
677 | err = usb_submit_urb(urb, GFP_ATOMIC); | 689 | err = usb_submit_urb(urb, GFP_ATOMIC); |
678 | if (!err) | 690 | if (!err) { |
679 | data->in_flight++; | 691 | data->in_flight++; |
692 | } else { | ||
693 | /* we have to throw away the rest */ | ||
694 | do { | ||
695 | unbusy_queued_urb(urb, portdata); | ||
696 | //extremely dirty | ||
697 | atomic_dec(&port->serial->interface->dev.power.usage_count); | ||
698 | } while ((urb = usb_get_from_anchor(&portdata->delayed))); | ||
699 | break; | ||
700 | } | ||
680 | } | 701 | } |
681 | } | 702 | } |
682 | 703 | ||