OSDN Git Service

usb: gadget: gsi: Fix incorrect repsonse available notifications
authorSriharsha Allenki <sallenki@codeaurora.org>
Mon, 3 Apr 2017 09:14:45 +0000 (14:44 +0530)
committerMayank Rana <mrana@codeaurora.org>
Wed, 5 Apr 2017 16:23:51 +0000 (09:23 -0700)
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>
drivers/usb/gadget/function/f_gsi.c

index be53250..7216fdd 100644 (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;