Commit 7d5e650a authored by Felipe Balbi's avatar Felipe Balbi

usb: dwc3: ep0: use immediate SETUP on TRB

If we pass TRB's own address on bpl/bph fields, we can get our SETUP
packet as immediate data on the TRB itself, without having to allocate
extra memory for it.
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 374a1020
...@@ -760,12 +760,10 @@ struct dwc3_scratchpad_array { ...@@ -760,12 +760,10 @@ struct dwc3_scratchpad_array {
/** /**
* struct dwc3 - representation of our controller * struct dwc3 - representation of our controller
* @ctrl_req: usb control request which is used for ep0
* @ep0_trb: trb which is used for the ctrl_req * @ep0_trb: trb which is used for the ctrl_req
* @ep0_bounce: bounce buffer for ep0 * @ep0_bounce: bounce buffer for ep0
* @zlp_buf: used when request->zero is set * @zlp_buf: used when request->zero is set
* @setup_buf: used while precessing STD USB requests * @setup_buf: used while precessing STD USB requests
* @ctrl_req_addr: dma address of ctrl_req
* @ep0_trb: dma address of ep0_trb * @ep0_trb: dma address of ep0_trb
* @ep0_usb_req: dummy req used while handling STD USB requests * @ep0_usb_req: dummy req used while handling STD USB requests
* @ep0_bounce_addr: dma address of ep0_bounce * @ep0_bounce_addr: dma address of ep0_bounce
...@@ -859,14 +857,12 @@ struct dwc3_scratchpad_array { ...@@ -859,14 +857,12 @@ struct dwc3_scratchpad_array {
* increments or 0 to disable. * increments or 0 to disable.
*/ */
struct dwc3 { struct dwc3 {
struct usb_ctrlrequest *ctrl_req;
struct dwc3_trb *ep0_trb; struct dwc3_trb *ep0_trb;
void *bounce; void *bounce;
void *ep0_bounce; void *ep0_bounce;
void *zlp_buf; void *zlp_buf;
void *scratchbuf; void *scratchbuf;
u8 *setup_buf; u8 *setup_buf;
dma_addr_t ctrl_req_addr;
dma_addr_t ep0_trb_addr; dma_addr_t ep0_trb_addr;
dma_addr_t bounce_addr; dma_addr_t bounce_addr;
dma_addr_t ep0_bounce_addr; dma_addr_t ep0_bounce_addr;
......
...@@ -283,7 +283,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) ...@@ -283,7 +283,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
complete(&dwc->ep0_in_setup); complete(&dwc->ep0_in_setup);
dwc3_ep0_prepare_one_trb(dwc, 0, dwc->ctrl_req_addr, 8, dwc3_ep0_prepare_one_trb(dwc, 0, dwc->ep0_trb_addr, 8,
DWC3_TRBCTL_CONTROL_SETUP, false); DWC3_TRBCTL_CONTROL_SETUP, false);
ret = dwc3_ep0_start_trans(dwc, 0); ret = dwc3_ep0_start_trans(dwc, 0);
WARN_ON(ret < 0); WARN_ON(ret < 0);
...@@ -794,7 +794,7 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) ...@@ -794,7 +794,7 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
const struct dwc3_event_depevt *event) const struct dwc3_event_depevt *event)
{ {
struct usb_ctrlrequest *ctrl = dwc->ctrl_req; struct usb_ctrlrequest *ctrl = (void *) dwc->ep0_trb;
int ret = -EINVAL; int ret = -EINVAL;
u32 len; u32 len;
...@@ -916,7 +916,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, ...@@ -916,7 +916,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
dwc->ep0_next_event = DWC3_EP0_COMPLETE; dwc->ep0_next_event = DWC3_EP0_COMPLETE;
dwc3_ep0_prepare_one_trb(dwc, epnum, dwc->ctrl_req_addr, dwc3_ep0_prepare_one_trb(dwc, epnum, dwc->ep0_trb_addr,
0, DWC3_TRBCTL_CONTROL_DATA, false); 0, DWC3_TRBCTL_CONTROL_DATA, false);
ret = dwc3_ep0_start_trans(dwc, epnum); ret = dwc3_ep0_start_trans(dwc, epnum);
WARN_ON(ret < 0); WARN_ON(ret < 0);
...@@ -997,8 +997,9 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, ...@@ -997,8 +997,9 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
req->direction = !!dep->number; req->direction = !!dep->number;
if (req->request.length == 0) { if (req->request.length == 0) {
dwc3_ep0_prepare_one_trb(dwc, dep->number, dwc3_ep0_prepare_one_trb(dwc, dep->number,
dwc->ctrl_req_addr, 0, dwc->ep0_trb_addr, 0,
DWC3_TRBCTL_CONTROL_DATA, false); DWC3_TRBCTL_CONTROL_DATA, false);
ret = dwc3_ep0_start_trans(dwc, dep->number); ret = dwc3_ep0_start_trans(dwc, dep->number);
} else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
...@@ -1056,7 +1057,7 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep) ...@@ -1056,7 +1057,7 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
: DWC3_TRBCTL_CONTROL_STATUS2; : DWC3_TRBCTL_CONTROL_STATUS2;
dwc3_ep0_prepare_one_trb(dwc, dep->number, dwc3_ep0_prepare_one_trb(dwc, dep->number,
dwc->ctrl_req_addr, 0, type, false); dwc->ep0_trb_addr, 0, type, false);
return dwc3_ep0_start_trans(dwc, dep->number); return dwc3_ep0_start_trans(dwc, dep->number);
} }
......
...@@ -3144,27 +3144,19 @@ int dwc3_gadget_init(struct dwc3 *dwc) ...@@ -3144,27 +3144,19 @@ int dwc3_gadget_init(struct dwc3 *dwc)
dwc->irq_gadget = irq; dwc->irq_gadget = irq;
dwc->ctrl_req = dma_alloc_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
&dwc->ctrl_req_addr, GFP_KERNEL);
if (!dwc->ctrl_req) {
dev_err(dwc->dev, "failed to allocate ctrl request\n");
ret = -ENOMEM;
goto err0;
}
dwc->ep0_trb = dma_alloc_coherent(dwc->sysdev, dwc->ep0_trb = dma_alloc_coherent(dwc->sysdev,
sizeof(*dwc->ep0_trb) * 2, sizeof(*dwc->ep0_trb) * 2,
&dwc->ep0_trb_addr, GFP_KERNEL); &dwc->ep0_trb_addr, GFP_KERNEL);
if (!dwc->ep0_trb) { if (!dwc->ep0_trb) {
dev_err(dwc->dev, "failed to allocate ep0 trb\n"); dev_err(dwc->dev, "failed to allocate ep0 trb\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err1; goto err0;
} }
dwc->setup_buf = kzalloc(DWC3_EP0_BOUNCE_SIZE, GFP_KERNEL); dwc->setup_buf = kzalloc(DWC3_EP0_BOUNCE_SIZE, GFP_KERNEL);
if (!dwc->setup_buf) { if (!dwc->setup_buf) {
ret = -ENOMEM; ret = -ENOMEM;
goto err2; goto err1;
} }
dwc->ep0_bounce = dma_alloc_coherent(dwc->sysdev, dwc->ep0_bounce = dma_alloc_coherent(dwc->sysdev,
...@@ -3173,20 +3165,20 @@ int dwc3_gadget_init(struct dwc3 *dwc) ...@@ -3173,20 +3165,20 @@ int dwc3_gadget_init(struct dwc3 *dwc)
if (!dwc->ep0_bounce) { if (!dwc->ep0_bounce) {
dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n"); dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err3; goto err2;
} }
dwc->zlp_buf = kzalloc(DWC3_ZLP_BUF_SIZE, GFP_KERNEL); dwc->zlp_buf = kzalloc(DWC3_ZLP_BUF_SIZE, GFP_KERNEL);
if (!dwc->zlp_buf) { if (!dwc->zlp_buf) {
ret = -ENOMEM; ret = -ENOMEM;
goto err4; goto err3;
} }
dwc->bounce = dma_alloc_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce = dma_alloc_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE,
&dwc->bounce_addr, GFP_KERNEL); &dwc->bounce_addr, GFP_KERNEL);
if (!dwc->bounce) { if (!dwc->bounce) {
ret = -ENOMEM; ret = -ENOMEM;
goto err5; goto err4;
} }
init_completion(&dwc->ep0_in_setup); init_completion(&dwc->ep0_in_setup);
...@@ -3226,38 +3218,34 @@ int dwc3_gadget_init(struct dwc3 *dwc) ...@@ -3226,38 +3218,34 @@ int dwc3_gadget_init(struct dwc3 *dwc)
ret = dwc3_gadget_init_endpoints(dwc, dwc->num_eps); ret = dwc3_gadget_init_endpoints(dwc, dwc->num_eps);
if (ret) if (ret)
goto err6; goto err5;
ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget);
if (ret) { if (ret) {
dev_err(dwc->dev, "failed to register udc\n"); dev_err(dwc->dev, "failed to register udc\n");
goto err6; goto err5;
} }
return 0; return 0;
err6: err5:
dma_free_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce, dma_free_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce,
dwc->bounce_addr); dwc->bounce_addr);
err5: err4:
kfree(dwc->zlp_buf); kfree(dwc->zlp_buf);
err4: err3:
dwc3_gadget_free_endpoints(dwc); dwc3_gadget_free_endpoints(dwc);
dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE, dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE,
dwc->ep0_bounce, dwc->ep0_bounce_addr); dwc->ep0_bounce, dwc->ep0_bounce_addr);
err3: err2:
kfree(dwc->setup_buf); kfree(dwc->setup_buf);
err2: err1:
dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb) * 2, dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb) * 2,
dwc->ep0_trb, dwc->ep0_trb_addr); dwc->ep0_trb, dwc->ep0_trb_addr);
err1:
dma_free_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
dwc->ctrl_req, dwc->ctrl_req_addr);
err0: err0:
return ret; return ret;
} }
...@@ -3280,9 +3268,6 @@ void dwc3_gadget_exit(struct dwc3 *dwc) ...@@ -3280,9 +3268,6 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb) * 2, dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb) * 2,
dwc->ep0_trb, dwc->ep0_trb_addr); dwc->ep0_trb, dwc->ep0_trb_addr);
dma_free_coherent(dwc->sysdev, sizeof(*dwc->ctrl_req),
dwc->ctrl_req, dwc->ctrl_req_addr);
} }
int dwc3_gadget_suspend(struct dwc3 *dwc) int dwc3_gadget_suspend(struct dwc3 *dwc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment