summaryrefslogtreecommitdiff
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.c47
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