mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-09-21 15:12:04 +00:00
usb: ci_udc: pre-allocate ep0 req
Allocate ep0's USB request object when the UDC driver is probed. This
solves a couple of issues in the current code:
a) A request object always exists for ep0. Prior to this patch, if setup
transactions arrived in an unexpected order, handle_setup() would need
to reply to a setup transaction before any ep0 usb_req was created.
This issue was introduced in commit 2813006fec
"usb: ci_udc: allow
multiple buffer allocs per ep."
b) handle_ep_complete no longer /has/ to queue the ep0 request again
after every single request completion. This is currently required, since
handle_setup() assumes it can find some request object in ep0's request
queue. This patch doesn't actually stop handle_ep_complete() from always
requeueing the request, but the next patch will.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
This commit is contained in:
parent
054731b09e
commit
a2d8f92985
2 changed files with 17 additions and 1 deletions
|
@ -198,8 +198,14 @@ static void ci_invalidate_qtd(int ep_num)
|
|||
static struct usb_request *
|
||||
ci_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags)
|
||||
{
|
||||
struct ci_ep *ci_ep = container_of(ep, struct ci_ep, ep);
|
||||
int num;
|
||||
struct ci_req *ci_req;
|
||||
|
||||
num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
|
||||
if (num == 0 && controller.ep0_req)
|
||||
return &controller.ep0_req->req;
|
||||
|
||||
ci_req = memalign(ARCH_DMA_MINALIGN, sizeof(*ci_req));
|
||||
if (!ci_req)
|
||||
return NULL;
|
||||
|
@ -207,6 +213,9 @@ ci_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags)
|
|||
INIT_LIST_HEAD(&ci_req->queue);
|
||||
ci_req->b_buf = 0;
|
||||
|
||||
if (num == 0)
|
||||
controller.ep0_req = ci_req;
|
||||
|
||||
return &ci_req->req;
|
||||
}
|
||||
|
||||
|
@ -471,7 +480,7 @@ static void handle_setup(void)
|
|||
int num, in, _num, _in, i;
|
||||
char *buf;
|
||||
|
||||
ci_req = list_first_entry(&ci_ep->queue, struct ci_req, queue);
|
||||
ci_req = controller.ep0_req;
|
||||
req = &ci_req->req;
|
||||
head = ci_get_qh(0, 0); /* EP0 OUT */
|
||||
|
||||
|
@ -780,6 +789,12 @@ static int ci_udc_probe(void)
|
|||
&controller.gadget.ep_list);
|
||||
}
|
||||
|
||||
ci_ep_alloc_request(&controller.ep[0].ep, 0);
|
||||
if (!controller.ep0_req) {
|
||||
free(controller.epts);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ struct ci_ep {
|
|||
|
||||
struct ci_drv {
|
||||
struct usb_gadget gadget;
|
||||
struct ci_req *ep0_req;
|
||||
struct usb_gadget_driver *driver;
|
||||
struct ehci_ctrl *ctrl;
|
||||
struct ept_queue_head *epts;
|
||||
|
|
Loading…
Reference in a new issue