aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2011-02-10 09:33:29 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-02-17 13:51:12 -0500
commit16871dcac74c63227aa92e0012f3004a648c2062 (patch)
tree9cfb094c3e86ed37fe1a99a2f8024dd3860f0e43 /drivers/usb/serial
parent433508ae30f13c0bf6905e576c42899a8535f0bb (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.c23
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}
665EXPORT_SYMBOL(usb_wwan_suspend); 665EXPORT_SYMBOL(usb_wwan_suspend);
666 666
667static 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
667static void play_delayed(struct usb_serial_port *port) 679static 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