Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752303AbbE0Ctz (ORCPT ); Tue, 26 May 2015 22:49:55 -0400 Received: from mga02.intel.com ([134.134.136.20]:14771 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751700AbbE0Ctx (ORCPT ); Tue, 26 May 2015 22:49:53 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,502,1427785200"; d="scan'208";a="735801533" Message-ID: <556530CC.90906@linux.intel.com> Date: Wed, 27 May 2015 10:49:48 +0800 From: "Zhang, Yanmin" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: linux-kernel@vger.kernel.org, xinhuix.pan@intel.com, gregkh@linuxfoundation.org, alan@linux.intel.com Subject: [PATCH V2 2/3] cdc-acm: call usb_autopm_get_interface_upgrade in acm_tty_write Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2146 Lines: 67 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 --- drivers/usb/class/cdc-acm.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 5c8f581..6ad85a3 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -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); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/