aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb_wwan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/usb_wwan.c')
-rw-r--r--drivers/usb/serial/usb_wwan.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 9c014e2ecd68..eb95aecc0015 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -261,7 +261,8 @@ int usb_wwan_write(struct tty_struct *tty, struct usb_serial_port *port,
261 intfdata->in_flight--; 261 intfdata->in_flight--;
262 spin_unlock_irqrestore(&intfdata->susp_lock, 262 spin_unlock_irqrestore(&intfdata->susp_lock,
263 flags); 263 flags);
264 continue; 264 usb_autopm_put_interface_async(port->serial->interface);
265 break;
265 } 266 }
266 } 267 }
267 268
@@ -308,11 +309,16 @@ static void usb_wwan_indat_callback(struct urb *urb)
308 /* Resubmit urb so we continue receiving */ 309 /* Resubmit urb so we continue receiving */
309 if (status != -ESHUTDOWN) { 310 if (status != -ESHUTDOWN) {
310 err = usb_submit_urb(urb, GFP_ATOMIC); 311 err = usb_submit_urb(urb, GFP_ATOMIC);
311 if (err && err != -EPERM) 312 if (err) {
312 printk(KERN_ERR "%s: resubmit read urb failed. " 313 if (err != -EPERM) {
313 "(%d)", __func__, err); 314 printk(KERN_ERR "%s: resubmit read urb failed. "
314 else 315 "(%d)", __func__, err);
316 /* busy also in error unless we are killed */
317 usb_mark_last_busy(port->serial->dev);
318 }
319 } else {
315 usb_mark_last_busy(port->serial->dev); 320 usb_mark_last_busy(port->serial->dev);
321 }
316 } 322 }
317 323
318 } 324 }
@@ -421,6 +427,7 @@ int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port)
421 spin_lock_irq(&intfdata->susp_lock); 427 spin_lock_irq(&intfdata->susp_lock);
422 portdata->opened = 1; 428 portdata->opened = 1;
423 spin_unlock_irq(&intfdata->susp_lock); 429 spin_unlock_irq(&intfdata->susp_lock);
430 /* this balances a get in the generic USB serial code */
424 usb_autopm_put_interface(serial->interface); 431 usb_autopm_put_interface(serial->interface);
425 432
426 return 0; 433 return 0;
@@ -447,7 +454,8 @@ void usb_wwan_close(struct usb_serial_port *port)
447 usb_kill_urb(portdata->in_urbs[i]); 454 usb_kill_urb(portdata->in_urbs[i]);
448 for (i = 0; i < N_OUT_URB; i++) 455 for (i = 0; i < N_OUT_URB; i++)
449 usb_kill_urb(portdata->out_urbs[i]); 456 usb_kill_urb(portdata->out_urbs[i]);
450 usb_autopm_get_interface(serial->interface); 457 /* balancing - important as an error cannot be handled*/
458 usb_autopm_get_interface_no_resume(serial->interface);
451 serial->interface->needs_remote_wakeup = 0; 459 serial->interface->needs_remote_wakeup = 0;
452 } 460 }
453} 461}
@@ -661,6 +669,18 @@ int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message)
661} 669}
662EXPORT_SYMBOL(usb_wwan_suspend); 670EXPORT_SYMBOL(usb_wwan_suspend);
663 671
672static void unbusy_queued_urb(struct urb *urb, struct usb_wwan_port_private *portdata)
673{
674 int i;
675
676 for (i = 0; i < N_OUT_URB; i++) {
677 if (urb == portdata->out_urbs[i]) {
678 clear_bit(i, &portdata->out_busy);
679 break;
680 }
681 }
682}
683
664static void play_delayed(struct usb_serial_port *port) 684static void play_delayed(struct usb_serial_port *port)
665{ 685{
666 struct usb_wwan_intf_private *data; 686 struct usb_wwan_intf_private *data;
@@ -672,8 +692,17 @@ static void play_delayed(struct usb_serial_port *port)
672 data = port->serial->private; 692 data = port->serial->private;
673 while ((urb = usb_get_from_anchor(&portdata->delayed))) { 693 while ((urb = usb_get_from_anchor(&portdata->delayed))) {
674 err = usb_submit_urb(urb, GFP_ATOMIC); 694 err = usb_submit_urb(urb, GFP_ATOMIC);
675 if (!err) 695 if (!err) {
676 data->in_flight++; 696 data->in_flight++;
697 } else {
698 /* we have to throw away the rest */
699 do {
700 unbusy_queued_urb(urb, portdata);
701 //extremely dirty
702 atomic_dec(&port->serial->interface->dev.power.usage_count);
703 } while ((urb = usb_get_from_anchor(&portdata->delayed)));
704 break;
705 }
677 } 706 }
678} 707}
679 708