cdc-acm: call usb_autopm_get_interface_upgrade in acm_tty_write
Subsystems (2)
PATCH v3 2/3 cdc-acm: call usb_autopm_get_interface_upgrade in acm_tty_write
From: Zhang Yanmin <[email protected]>
acm device might be used as ldisc device by n_gsm driver. gsmtty_write and other gsm functions calls acm_tty_write indirectly while they holds spinlocks.
Meanwhile, application might access ACM tty device directly.
Here we choose to call usb_autopm_get_interface_upgrade instead of usb_autopm_get_interface_async to make sure above 2 scenarios can work well.
Signed-off-by Zhang Yanmin <[email protected]>
--- drivers/usb/class/cdc-acm.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/usb/class/cdc-acm.c +6 -7
@@ -689,10 +689,15 @@ static int acm_tty_write(struct tty_struct *tty,dev_vdbg (&acm->data->dev,"%s - count %d\n" , __func__, count); + stat =usb_autopm_get_interface_upgrade (acm->control); +if (stat) +return stat; +spin_lock_irqsave (&acm->write_lock, flags); wbn =acm_wb_alloc (acm);if (wbn <0 ) {spin_unlock_irqrestore (&acm->write_lock, flags); +usb_autopm_put_interface (acm->control);return 0 ; } wb = &acm->wb[wbn];
@@ -700,6 +705,7 @@ static int acm_tty_write(struct tty_struct *tty,if (!acm->dev) { wb->use =0 ;spin_unlock_irqrestore (&acm->write_lock, flags); +usb_autopm_put_interface (acm->control);return -ENODEV ; }
@@ -708,13 +714,6 @@ static int acm_tty_write(struct tty_struct *tty,memcpy (wb->buf, buf, count); wb->len = count; - stat =usb_autopm_get_interface_async (acm->control); -if (stat) { - wb->use =0 ; -spin_unlock_irqrestore (&acm->write_lock, flags); -return stat; - } -if (acm->susp_count) {usb_anchor_urb (wb->urb, &acm->delayed);spin_unlock_irqrestore (&acm->write_lock, flags);
Signature · 1 line
1.9.1