usb: gadget: gsi: Fix incorrect repsonse available notifications

Two notify requests are being queued for one available modem
response. So for the first GET_ENCAPSULATED_RESPONSE we provide
the host with the available response. Now for the next
GET_ENCAPSULATED_COMMAND we notify the host that the response is
available even before the modem is ready with a response because
of the extra notify request queued on the interrupt endpoint.
This causes a STALL for the next GET_ENCAPSULATED_RESPONSE request.
This is caused because we are queueing a notify request from the
completion handler of the interrupt endpoint request when the
response queue is not empty.
Fix this by queuing a notify request when a new response is
available only after the current resposne is send to the Host.

Change-Id: If84bc315f2be910503328cc6b0e21be342c6eb37
Signed-off-by: Sriharsha Allenki <sallenki@codeaurora.org>
Signed-off-by: Mayank Rana <mrana@codeaurora.org>
This commit is contained in:
Sriharsha Allenki 2017-04-03 14:44:45 +05:30 committed by Mayank Rana
parent 26db194916
commit 343476df3e

View file

@ -1550,13 +1550,6 @@ static void gsi_ctrl_notify_resp_complete(struct usb_ep *ep,
event->bNotificationType, req->status);
/* FALLTHROUGH */
case 0:
/*
* handle multiple pending resp available
* notifications by queuing same until we're done,
* rest of the notification require queuing new
* request.
*/
gsi_ctrl_send_notification(gsi);
break;
}
}
@ -1651,6 +1644,14 @@ static void gsi_ctrl_reset_cmd_complete(struct usb_ep *ep,
gsi_ctrl_send_cpkt_tomodem(gsi, req->buf, 0);
}
static void gsi_ctrl_send_response_complete(struct usb_ep *ep,
struct usb_request *req)
{
struct f_gsi *gsi = req->context;
gsi_ctrl_send_notification(gsi);
}
static int
gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
{
@ -1737,6 +1738,8 @@ gsi_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
memcpy(req->buf, cpkt->buf, value);
gsi_ctrl_pkt_free(cpkt);
req->complete = gsi_ctrl_send_response_complete;
req->context = gsi;
log_event_dbg("copied encap_resp %d bytes",
value);
break;