diff options
Diffstat (limited to 'drivers/usb/class/cdc-acm.c')
-rw-r--r-- | drivers/usb/class/cdc-acm.c | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 98c0e79110f4..d3bb2fc7fe2b 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -170,6 +170,9 @@ static int acm_write_start(struct acm *acm, int wbn) unsigned long flags; struct acm_wb *wb = &acm->wb[wbn]; int rc; +#ifdef CONFIG_PM + struct urb *res; +#endif spin_lock_irqsave(&acm->write_lock, flags); if (!acm->dev) { @@ -183,23 +186,32 @@ static int acm_write_start(struct acm *acm, int wbn) 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 +#else if (!acm->delayed_wb) acm->delayed_wb = wb; else usb_autopm_put_interface_async(acm->control); +#endif spin_unlock_irqrestore(&acm->write_lock, flags); return 0; /* A white lie */ } usb_mark_last_busy(acm->dev); - +#ifdef CONFIG_PM + while ((res = usb_get_from_anchor(&acm->deferred))) { + rc = usb_submit_urb(res, GFP_ATOMIC); + if (rc < 0) { + dbg("usb_submit_urb(pending request) failed: %d", rc); + usb_unanchor_urb(res); + acm_write_done(acm, res->context); + } + } +#endif rc = acm_start_wb(acm, wb); spin_unlock_irqrestore(&acm->write_lock, flags); @@ -1305,6 +1317,7 @@ static void acm_disconnect(struct usb_interface *intf) stop_data_traffic(acm); + usb_kill_anchored_urbs(&acm->deferred); acm_write_buffers_free(acm); usb_free_coherent(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma); @@ -1370,8 +1383,10 @@ 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; +#ifdef CONFIG_PM + struct urb *res; +#endif spin_lock_irq(&acm->read_lock); acm->susp_count -= 1; @@ -1384,19 +1399,21 @@ static int acm_resume(struct usb_interface *intf) 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); +#ifdef CONFIG_PM + while ((res = usb_get_from_anchor(&acm->deferred))) { + rv = usb_submit_urb(res, GFP_ATOMIC); + if (rv < 0) { + dbg("usb_submit_urb(pending request)" + " failed: %d", rv); + usb_unanchor_urb(res); + acm_write_done(acm, res->context); + } + } + spin_unlock_irq(&acm->write_lock); +#else if (acm->delayed_wb) { wb = acm->delayed_wb; acm->delayed_wb = NULL; @@ -1405,7 +1422,7 @@ static int acm_resume(struct usb_interface *intf) } else { spin_unlock_irq(&acm->write_lock); } - +#endif /* * delayed error checking because we must |