aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/cdc-acm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
-rw-r--r--drivers/usb/class/cdc-acm.c32
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index e72a657a6177..56419254ef75 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -573,6 +573,8 @@ static void acm_port_destruct(struct tty_port *port)
573static void acm_port_shutdown(struct tty_port *port) 573static void acm_port_shutdown(struct tty_port *port)
574{ 574{
575 struct acm *acm = container_of(port, struct acm, port); 575 struct acm *acm = container_of(port, struct acm, port);
576 struct urb *urb;
577 struct acm_wb *wb;
576 int i; 578 int i;
577 579
578 dev_dbg(&acm->control->dev, "%s\n", __func__); 580 dev_dbg(&acm->control->dev, "%s\n", __func__);
@@ -581,6 +583,16 @@ static void acm_port_shutdown(struct tty_port *port)
581 if (!acm->disconnected) { 583 if (!acm->disconnected) {
582 usb_autopm_get_interface(acm->control); 584 usb_autopm_get_interface(acm->control);
583 acm_set_control(acm, acm->ctrlout = 0); 585 acm_set_control(acm, acm->ctrlout = 0);
586
587 for (;;) {
588 urb = usb_get_from_anchor(&acm->delayed);
589 if (!urb)
590 break;
591 wb = urb->context;
592 wb->use = 0;
593 usb_autopm_put_interface_async(acm->control);
594 }
595
584 usb_kill_urb(acm->ctrlurb); 596 usb_kill_urb(acm->ctrlurb);
585 for (i = 0; i < ACM_NW; i++) 597 for (i = 0; i < ACM_NW; i++)
586 usb_kill_urb(acm->wb[i].urb); 598 usb_kill_urb(acm->wb[i].urb);
@@ -648,12 +660,9 @@ static int acm_tty_write(struct tty_struct *tty,
648 660
649 usb_autopm_get_interface_async(acm->control); 661 usb_autopm_get_interface_async(acm->control);
650 if (acm->susp_count) { 662 if (acm->susp_count) {
651 if (!acm->delayed_wb) 663 usb_anchor_urb(wb->urb, &acm->delayed);
652 acm->delayed_wb = wb;
653 else
654 usb_autopm_put_interface_async(acm->control);
655 spin_unlock_irqrestore(&acm->write_lock, flags); 664 spin_unlock_irqrestore(&acm->write_lock, flags);
656 return count; /* A white lie */ 665 return count;
657 } 666 }
658 usb_mark_last_busy(acm->dev); 667 usb_mark_last_busy(acm->dev);
659 668
@@ -1269,6 +1278,7 @@ made_compressed_probe:
1269 acm->bInterval = epread->bInterval; 1278 acm->bInterval = epread->bInterval;
1270 tty_port_init(&acm->port); 1279 tty_port_init(&acm->port);
1271 acm->port.ops = &acm_port_ops; 1280 acm->port.ops = &acm_port_ops;
1281 init_usb_anchor(&acm->delayed);
1272 1282
1273 buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); 1283 buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
1274 if (!buf) { 1284 if (!buf) {
@@ -1539,7 +1549,7 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)
1539static int acm_resume(struct usb_interface *intf) 1549static int acm_resume(struct usb_interface *intf)
1540{ 1550{
1541 struct acm *acm = usb_get_intfdata(intf); 1551 struct acm *acm = usb_get_intfdata(intf);
1542 struct acm_wb *wb; 1552 struct urb *urb;
1543 int rv = 0; 1553 int rv = 0;
1544 1554
1545 spin_lock_irq(&acm->read_lock); 1555 spin_lock_irq(&acm->read_lock);
@@ -1551,10 +1561,12 @@ static int acm_resume(struct usb_interface *intf)
1551 if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) { 1561 if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
1552 rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC); 1562 rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);
1553 1563
1554 if (acm->delayed_wb) { 1564 for (;;) {
1555 wb = acm->delayed_wb; 1565 urb = usb_get_from_anchor(&acm->delayed);
1556 acm->delayed_wb = NULL; 1566 if (!urb)
1557 acm_start_wb(acm, wb); 1567 break;
1568
1569 acm_start_wb(acm, urb->context);
1558 } 1570 }
1559 1571
1560 /* 1572 /*