From: Oliver Neukum oneukum@suse.com
commit a8b3b519618f30a87a304c4e120267ce6f8dc68a upstream.
suspend() does its poisoning conditionally, resume() does it unconditionally. On a device with combined interfaces this will balance, on a device with two interfaces the counter will go negative and resubmission will fail.
Both actions need to be done conditionally.
Fixes: 6069e3e927c8f ("USB: cdc-acm: untangle a circular dependency between callback and softint") Signed-off-by: Oliver Neukum oneukum@suse.com Cc: stable stable@vger.kernel.org Link: https://lore.kernel.org/r/20210421074513.4327-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/usb/class/cdc-acm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index a1fa16a03ab9d..7f4f21ba8efcf 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1682,12 +1682,13 @@ static int acm_resume(struct usb_interface *intf) struct urb *urb; int rv = 0;
- acm_unpoison_urbs(acm); spin_lock_irq(&acm->write_lock);
if (--acm->susp_count) goto out;
+ acm_unpoison_urbs(acm); + if (tty_port_initialized(&acm->port)) { rv = usb_submit_urb(acm->ctrlurb, GFP_ATOMIC);