summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMayank Rana <mrana@codeaurora.org>2016-08-18 18:08:39 -0700
committerMayank Rana <mrana@codeaurora.org>2016-08-29 17:38:42 -0700
commitfae741edccbb7d560454e1b87140591b7412d451 (patch)
tree527f39f03f957dcb982dfaddc678f00970812fbf
parent008f057bbab6dd6629b7e1a3b8c67b650a6b9ef1 (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>
-rw-r--r--drivers/usb/gadget/function/f_gsi.c37
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__);
}