diff options
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
-rw-r--r-- | drivers/usb/class/cdc-acm.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 991089eee117..3d149f359a70 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -155,7 +155,6 @@ static int acm_start_wb(struct acm *acm, struct acm_wb *wb) wb->urb->transfer_dma = wb->dmah; wb->urb->transfer_buffer_length = wb->len; wb->urb->dev = acm->dev; - rc = usb_submit_urb(wb->urb, GFP_ATOMIC); if (rc < 0) { dev_err(&acm->data->dev, @@ -183,6 +182,15 @@ static int acm_write_start(struct acm *acm, int wbn) acm->susp_count); usb_autopm_get_interface_async(acm->control); if (acm->susp_count) { +#ifdef CONFIG_PM + printk("%s buffer urb\n", __func__); + acm->transmitting++; + wb->urb->transfer_buffer = wb->buf; + wb->urb->transfer_dma = wb->dmah; + wb->urb->transfer_buffer_length = wb->len; + wb->urb->dev = acm->dev; + usb_anchor_urb(wb->urb, &acm->deferred); +#endif if (!acm->delayed_wb) acm->delayed_wb = wb; else @@ -476,7 +484,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) if (usb_autopm_get_interface(acm->control) < 0) goto early_bail; else - acm->control->needs_remote_wakeup = 1; + acm->control->needs_remote_wakeup = 0; mutex_lock(&acm->mutex); if (acm->port.count++) { @@ -1080,6 +1088,9 @@ made_compressed_probe: acm->readsize = readsize; acm->rx_buflimit = num_rx_buf; INIT_WORK(&acm->work, acm_softint); + init_usb_anchor(&acm->deferred); + init_waitqueue_head(&acm->drain_wait); + spin_lock_init(&acm->throttle_lock); spin_lock_init(&acm->write_lock); spin_lock_init(&acm->read_lock); mutex_init(&acm->mutex); @@ -1349,6 +1360,7 @@ static int acm_resume(struct usb_interface *intf) struct acm *acm = usb_get_intfdata(intf); struct acm_wb *wb; int rv = 0; + struct urb *res; int cnt; spin_lock_irq(&acm->read_lock); @@ -1359,10 +1371,21 @@ static int acm_resume(struct usb_interface *intf) if (cnt) return 0; + mutex_lock(&acm->mutex); + +#ifdef CONFIG_PM + while ((res = usb_get_from_anchor(&acm->deferred))) { + printk("%s process buffered request \n", __func__); + rv = usb_submit_urb(res, GFP_ATOMIC); + if (rv < 0) { + dbg("usb_submit_urb(pending request) failed: %d", rv); + } + } +#endif + if (acm->port.count) { rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO); - spin_lock_irq(&acm->write_lock); if (acm->delayed_wb) { wb = acm->delayed_wb; @@ -1373,6 +1396,7 @@ static int acm_resume(struct usb_interface *intf) spin_unlock_irq(&acm->write_lock); } + /* * delayed error checking because we must * do the write path at all cost |