};
#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)
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;
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);
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;
}
}
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);
#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)
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;
}
struct usb_request *in_req = fastboot_func->in_req;
int ret;
-
memcpy(in_req->buf, buffer, buffer_size);
in_req->length = buffer_size;
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;