MA-10703 [Android] use the usb_ep_queue for muti request
authorLuo Ji <ji.luo@nxp.com>
Wed, 22 Nov 2017 04:18:57 +0000 (12:18 +0800)
committerLuo Ji <ji.luo@nxp.com>
Thu, 25 Jan 2018 11:38:53 +0000 (19:38 +0800)
It need to send muti data through usb for fastboot commands(fastboot getcar all)
this patch use usb_ep_queue to queue usb data.

Change-Id: I5fd2568683c43163a21417a0634dd194e31f3eb7
Signed-off-by: Luo Ji <ji.luo@nxp.com>
drivers/usb/gadget/f_fastboot.c

index f5ceb19..53dd2d6 100755 (executable)
@@ -121,15 +121,19 @@ boot_metric metrics = {
 };
 
 #ifdef CONFIG_USB_GADGET
-#define MAX_REQ_NUM 100
+typedef struct usb_req usb_req;
+struct usb_req {
+       struct usb_request *in_req;
+       usb_req *next;
+};
 
 struct f_fastboot {
        struct usb_function usb_function;
 
        /* IN/OUT EP's and corresponding requests */
        struct usb_ep *in_ep, *out_ep;
-       struct usb_request *in_req, *in_req_more[MAX_REQ_NUM], *out_req;
-       int next_req;
+       struct usb_request *in_req, *out_req;
+       usb_req *front, *rear;
 };
 
 static inline struct f_fastboot *func_to_fastboot(struct usb_function *f)
@@ -1912,6 +1916,24 @@ void fastboot_okay(const char *reason)
        strncat(fb_response_str, reason, FASTBOOT_RESPONSE_LEN - 4 - 1);
 }
 
+static void fastboot_fifo_complete(struct usb_ep *ep, struct usb_request *req)
+{
+       int status = req->status;
+       usb_req *request;
+
+       if (!status) {
+               if (fastboot_func->front != NULL) {
+                       request = fastboot_func->front;
+                       fastboot_func->front = fastboot_func->front->next;
+                       usb_ep_free_request(ep, request->in_req);
+                       free(request);
+               } else {
+                       printf("fail free request\n");
+               }
+               return;
+       }
+}
+
 static void fastboot_complete(struct usb_ep *ep, struct usb_request *req)
 {
        int status = req->status;
@@ -1973,7 +1995,7 @@ static void fastboot_unbind(struct usb_configuration *c, struct usb_function *f)
 
 static void fastboot_disable(struct usb_function *f)
 {
-       int i = 0;
+       usb_req *req;
        struct f_fastboot *f_fb = func_to_fastboot(f);
 
        usb_ep_disable(f_fb->out_ep);
@@ -1987,12 +2009,18 @@ static void fastboot_disable(struct usb_function *f)
        if (f_fb->in_req) {
                free(f_fb->in_req->buf);
                usb_ep_free_request(f_fb->in_ep, f_fb->in_req);
-               f_fb->in_req = NULL;
-       }
-       for (i = 0; i < MAX_REQ_NUM; i++) {
-               if (f_fb->in_req_more[i]) {
-                       usb_ep_free_request(f_fb->in_ep, f_fb->in_req_more[i]);
+
+               /* disable usb request FIFO */
+               while(f_fb->front != NULL) {
+                       req = f_fb->front;
+                       f_fb->front = f_fb->front->next;
+                       free(req->in_req->buf);
+                       usb_ep_free_request(f_fb->in_ep, req->in_req);
+                       free(req);
                }
+
+               f_fb->rear = NULL;
+               f_fb->in_req = NULL;
        }
 }
 
@@ -2018,7 +2046,7 @@ static struct usb_request *fastboot_start_ep(struct usb_ep *ep)
 static int fastboot_set_alt(struct usb_function *f,
                            unsigned interface, unsigned alt)
 {
-       int i, ret;
+       int ret;
        struct usb_composite_dev *cdev = f->config->cdev;
        struct usb_gadget *gadget = cdev->gadget;
        struct f_fastboot *f_fb = func_to_fastboot(f);
@@ -2066,15 +2094,7 @@ static int fastboot_set_alt(struct usb_function *f,
 #endif
        f_fb->in_req->complete = fastboot_complete;
 
-       for (i = 0; i < MAX_REQ_NUM; i++) {
-               f_fb->in_req_more[i] = fastboot_start_ep(f_fb->in_ep);
-               if (!f_fb->in_req_more[i]) {
-                       puts("failed alloc req in\n");
-                       ret = -EINVAL;
-                       goto err;
-               }
-               f_fb->in_req_more[i]->complete = fastboot_complete;
-       }
+       f_fb->front = f_fb->rear = NULL;
 
        ret = usb_ep_queue(f_fb->out_ep, f_fb->out_req, 0);
        if (ret)
@@ -2121,25 +2141,44 @@ DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add);
 
 static int fastboot_tx_write_more(const char *buffer)
 {
-       int next_req = fastboot_func->next_req;
-       struct usb_request *in_req = fastboot_func->in_req_more[next_req];
-       unsigned int buffer_size = strlen(buffer);
        int ret = 0;
 
-       memcpy(in_req->buf, buffer, buffer_size);
-       in_req->length = buffer_size;
+       /* alloc usb request FIFO node */
+       usb_req *req = (usb_req *)malloc(sizeof(usb_req));
+       if (!req) {
+               printf("failed alloc usb req!\n");
+               return -ENOMEM;
+       }
 
-       ret = usb_ep_queue(fastboot_func->in_ep, in_req, 0);
-       if (ret)
-               printf("Error %d on queue\n", ret);
+       /* usb request node FIFO enquene */
+       if ((fastboot_func->front == NULL) && (fastboot_func->rear == NULL)) {
+               fastboot_func->front = fastboot_func->rear = req;
+               req->next = NULL;
+       } else {
+               fastboot_func->rear->next = req;
+               fastboot_func->rear = req;
+               req->next = NULL;
+       }
 
-       if (in_req == fastboot_func->in_req_more[MAX_REQ_NUM-1]) {
-               fastboot_func->next_req = 0;
+       /* alloc in request for current node */
+       req->in_req = fastboot_start_ep(fastboot_func->in_ep);
+       if (!req->in_req) {
+               printf("failed alloc req in\n");
+               fastboot_disable(&(fastboot_func->usb_function));
+               return  -EINVAL;
+       }
+       req->in_req->complete = fastboot_fifo_complete;
+
+       memcpy(req->in_req->buf, buffer, strlen(buffer));
+       req->in_req->length = strlen(buffer);
+
+       ret = usb_ep_queue(fastboot_func->in_ep, req->in_req, 0);
+       if (ret) {
+               printf("Error %d on queue\n", ret);
                return -EINVAL;
-       } else {
-               fastboot_func->next_req++;
        }
 
+       ret = 0;
        return ret;
 }
 
@@ -2148,7 +2187,6 @@ static int fastboot_tx_write(const char *buffer, unsigned int buffer_size)
        struct usb_request *in_req = fastboot_func->in_req;
        int ret;
 
-
        memcpy(in_req->buf, buffer, buffer_size);
        in_req->length = buffer_size;
 
@@ -3016,8 +3054,10 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
        char *cmdbuf = req->buf;
        void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL;
        int i;
-       /*init the next_req if need muti USB request*/
-       fastboot_func->next_req = 0;
+
+       /* init in request FIFO pointer */
+       fastboot_func->front = NULL;
+       fastboot_func->rear  = NULL;
 
        if (req->status != 0 || req->length == 0)
                return;