diff options
| author | Vijayavardhan Vennapusa <vvreddy@codeaurora.org> | 2016-04-20 15:02:52 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-12-13 20:55:21 -0800 |
| commit | 98eba6ebf2ad229103f327618d3a84be7e4abb39 (patch) | |
| tree | ddb881c1a4293928c115e6fd49a492e52bc8e314 | |
| parent | 3162449f7d245d45f007d4ea3224576ddf1bcc63 (diff) | |
USB: gadget: f_qdss: Add proper checks in usb_qdss_close()
On qdsss channel close, driver is dequeuing endless request without
checking whether qdss is active or not. This might crash if qdss channel
is closed when non QDSS composition is active. Fix the issue by having
proper checks and if qdss is not active, just return without performing
dequeue operation.
Change-Id: I667ea843f77794e9384c22ece218853331751db6
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
Signed-off-by: Chandana Kishori Chiluveru <cchiluve@codeaurora.org>
| -rw-r--r-- | drivers/usb/gadget/function/f_qdss.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/usb/gadget/function/f_qdss.c b/drivers/usb/gadget/function/f_qdss.c index 8e04d9451b67..16bd7d890d3e 100644 --- a/drivers/usb/gadget/function/f_qdss.c +++ b/drivers/usb/gadget/function/f_qdss.c @@ -844,32 +844,37 @@ EXPORT_SYMBOL(usb_qdss_open); void usb_qdss_close(struct usb_qdss_ch *ch) { struct f_qdss *qdss = ch->priv_usb; - struct usb_gadget *gadget = qdss->gadget; + struct usb_gadget *gadget; unsigned long flags; int status; pr_debug("usb_qdss_close\n"); spin_lock_irqsave(&qdss_lock, flags); + if (!qdss || !qdss->usb_connected) { + ch->app_conn = 0; + spin_unlock_irqrestore(&qdss_lock, flags); + return; + } + usb_ep_dequeue(qdss->port.data, qdss->endless_req); usb_ep_free_request(qdss->port.data, qdss->endless_req); qdss->endless_req = NULL; + gadget = qdss->gadget; ch->app_conn = 0; spin_unlock_irqrestore(&qdss_lock, flags); - if (qdss->usb_connected) { - status = uninit_data(qdss->port.data); - if (status) - pr_err("%s: uninit_data error\n", __func__); + status = uninit_data(qdss->port.data); + if (status) + pr_err("%s: uninit_data error\n", __func__); - status = set_qdss_data_connection( + status = set_qdss_data_connection( gadget, qdss->port.data, qdss->port.data->address, 0); - if (status) - pr_err("%s:qdss_disconnect error\n", __func__); - } + if (status) + pr_err("%s:qdss_disconnect error\n", __func__); usb_gadget_restart(gadget); } EXPORT_SYMBOL(usb_qdss_close); |
