From: Luo Ji Date: Wed, 22 Nov 2017 04:18:57 +0000 (+0800) Subject: MA-10703 [Android] use the usb_ep_queue for muti request X-Git-Tag: rel_imx_4.9.88_2.0.0_ga~81 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=19c75116510c84d21560135847f258f4a52f5a8f;p=u-boot.git MA-10703 [Android] use the usb_ep_queue for muti request 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 --- diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index f5ceb19dbb..53dd2d62cb 100755 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -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;