diff options
author | Mayank Rana <mrana@codeaurora.org> | 2016-08-18 18:08:39 -0700 |
---|---|---|
committer | Mayank Rana <mrana@codeaurora.org> | 2016-08-29 17:38:42 -0700 |
commit | fae741edccbb7d560454e1b87140591b7412d451 (patch) | |
tree | 527f39f03f957dcb982dfaddc678f00970812fbf /drivers/usb | |
parent | 008f057bbab6dd6629b7e1a3b8c67b650a6b9ef1 (diff) |
usb: gsi: Queue control notification on gsi_resume
There is delay seen in queueing notification when response is
available after performing function remote wakeup. This change
queues control notification from gsi_resume() for RMNET/MBIM and
ECM case when notify_count is 1 (i.e. remote wakeup is performed
but notify request is not queued.) to make sure that host is
notified before it timeouts for response and starts data transfer.
CRs-Fixed: 1033093
Change-Id: Ic55667df93c8bd51df06b48709bc420c082fbcf5
Signed-off-by: Mayank Rana <mrana@codeaurora.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/gadget/function/f_gsi.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c index a629723d19cb..17e37ca5e53f 100644 --- a/drivers/usb/gadget/function/f_gsi.c +++ b/drivers/usb/gadget/function/f_gsi.c @@ -1334,6 +1334,12 @@ static int gsi_ctrl_send_notification(struct f_gsi *gsi, return -ENODEV; } + if (atomic_inc_return(&gsi->c_port.notify_count) != 1) { + log_event_dbg("delay ep_queue: notify req is busy %d", + atomic_read(&gsi->c_port.notify_count)); + return 0; + } + event = req->buf; switch (state) { @@ -1389,12 +1395,6 @@ static int gsi_ctrl_send_notification(struct f_gsi *gsi, log_event_dbg("send Notify type %02x", event->bNotificationType); - if (atomic_inc_return(&gsi->c_port.notify_count) != 1) { - log_event_dbg("delay ep_queue: notify req is busy %d", - atomic_read(&gsi->c_port.notify_count)); - return 0; - } - return queue_notification_request(gsi); } @@ -1444,7 +1444,8 @@ static void gsi_rndis_response_available(void *_rndis) { struct f_gsi *gsi = _rndis; - gsi_ctrl_send_notification(gsi, GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE); + gsi_ctrl_send_notification(gsi, + GSI_CTRL_NOTIFY_RESPONSE_AVAILABLE); } static void gsi_rndis_command_complete(struct usb_ep *ep, @@ -2028,6 +2029,8 @@ static void gsi_suspend(struct usb_function *f) queue_work(gsi->d_port.ipa_usb_wq, &gsi->d_port.usb_ipa_w); } + log_event_dbg("%s: notify_count = %d\n", + __func__, atomic_read(&gsi->c_port.notify_count)); log_event_dbg("gsi suspended"); } @@ -2052,6 +2055,21 @@ static void gsi_resume(struct usb_function *f) else remote_wakeup_allowed = f->config->cdev->gadget->remote_wakeup; + if (gsi->c_port.notify && !gsi->c_port.notify->desc) + config_ep_by_speed(cdev->gadget, f, gsi->c_port.notify); + + log_event_dbg("%s: notify_count = %d\n", + __func__, atomic_read(&gsi->c_port.notify_count)); + + /* Send notification to host for RMNET, RNDIS and MBIM Interface */ + if ((gsi->prot_id == IPA_USB_MBIM || + gsi->prot_id == IPA_USB_RNDIS || + gsi->prot_id == IPA_USB_RMNET) && + (atomic_read(&gsi->c_port.notify_count) >= 1)) { + log_event_dbg("%s: force_queue\n", __func__); + queue_notification_request(gsi); + } + if (!remote_wakeup_allowed) { /* Configure EPs for GSI */ @@ -2082,11 +2100,6 @@ static void gsi_resume(struct usb_function *f) post_event(&gsi->d_port, EVT_RESUMED); queue_work(gsi->d_port.ipa_usb_wq, &gsi->d_port.usb_ipa_w); - - if (gsi->c_port.notify && !gsi->c_port.notify->desc) - config_ep_by_speed(cdev->gadget, f, gsi->c_port.notify); - - atomic_set(&gsi->c_port.notify_count, 0); log_event_dbg("%s: completed", __func__); } |