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.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index a06f2cdc6106..8fb105e03658 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -204,6 +204,8 @@ static int acm_write_start(struct acm *acm, int wbn)
usb_mark_last_busy(acm->dev);
#ifdef CONFIG_PM
while ((res = usb_get_from_anchor(&acm->deferred))) {
+ /* decrement ref count*/
+ usb_put_urb(res);
rc = usb_submit_urb(res, GFP_ATOMIC);
if (rc < 0) {
dbg("usb_submit_urb(pending request) failed: %d", rc);
@@ -505,6 +507,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
goto out;
}
+ if (acm_submit_read_urbs(acm, GFP_KERNEL))
+ goto bail_out;
+
acm->ctrlurb->dev = acm->dev;
if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) {
dev_err(&acm->control->dev,
@@ -518,9 +523,6 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
usb_autopm_put_interface(acm->control);
- if (acm_submit_read_urbs(acm, GFP_KERNEL))
- goto bail_out;
-
set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
rv = tty_port_block_til_ready(&acm->port, tty, filp);
@@ -1303,6 +1305,7 @@ static void acm_disconnect(struct usb_interface *intf)
struct acm *acm = usb_get_intfdata(intf);
struct usb_device *usb_dev = interface_to_usbdev(intf);
struct tty_struct *tty;
+ struct urb *res;
/* sibling interface is already cleaning up */
if (!acm)
@@ -1322,7 +1325,10 @@ static void acm_disconnect(struct usb_interface *intf)
stop_data_traffic(acm);
- usb_kill_anchored_urbs(&acm->deferred);
+ /* decrement ref count of anchored urbs */
+ while ((res = usb_get_from_anchor(&acm->deferred)))
+ usb_put_urb(res);
+
acm_write_buffers_free(acm);
usb_free_coherent(usb_dev, acm->ctrlsize, acm->ctrl_buffer,
acm->ctrl_dma);
@@ -1425,6 +1431,8 @@ static int acm_resume(struct usb_interface *intf)
spin_lock_irq(&acm->write_lock);
#ifdef CONFIG_PM
while ((res = usb_get_from_anchor(&acm->deferred))) {
+ /* decrement ref count*/
+ usb_put_urb(res);
rv = usb_submit_urb(res, GFP_ATOMIC);
if (rv < 0) {
dbg("usb_submit_urb(pending request)"