From 7d5e650a5fdb82ec1994497de174650767862a49 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 7 Apr 2017 13:34:21 +0300 Subject: [PATCH] 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: Felipe Balbi --- drivers/usb/dwc3/core.h | 4 ---- drivers/usb/dwc3/ep0.c | 11 ++++++----- drivers/usb/dwc3/gadget.c | 39 ++++++++++++--------------------------- 3 files changed, 18 insertions(+), 36 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 2ad8ce2a02e8..bbb7c3f6749e 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -760,12 +760,10 @@ struct dwc3_scratchpad_array { /** * 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_bounce: bounce buffer for ep0 * @zlp_buf: used when request->zero is set * @setup_buf: used while precessing STD USB requests - * @ctrl_req_addr: dma address of ctrl_req * @ep0_trb: dma address of ep0_trb * @ep0_usb_req: dummy req used while handling STD USB requests * @ep0_bounce_addr: dma address of ep0_bounce @@ -859,14 +857,12 @@ struct dwc3_scratchpad_array { * increments or 0 to disable. */ struct dwc3 { - struct usb_ctrlrequest *ctrl_req; struct dwc3_trb *ep0_trb; void *bounce; void *ep0_bounce; void *zlp_buf; void *scratchbuf; u8 *setup_buf; - dma_addr_t ctrl_req_addr; dma_addr_t ep0_trb_addr; dma_addr_t bounce_addr; dma_addr_t ep0_bounce_addr; diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index e689cede9b0e..da5e085e7889 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -283,7 +283,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) 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); ret = dwc3_ep0_start_trans(dwc, 0); WARN_ON(ret < 0); @@ -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, const struct dwc3_event_depevt *event) { - struct usb_ctrlrequest *ctrl = dwc->ctrl_req; + struct usb_ctrlrequest *ctrl = (void *) dwc->ep0_trb; int ret = -EINVAL; u32 len; @@ -916,7 +916,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, 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); ret = dwc3_ep0_start_trans(dwc, epnum); WARN_ON(ret < 0); @@ -997,8 +997,9 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, req->direction = !!dep->number; if (req->request.length == 0) { + dwc3_ep0_prepare_one_trb(dwc, dep->number, - dwc->ctrl_req_addr, 0, + dwc->ep0_trb_addr, 0, DWC3_TRBCTL_CONTROL_DATA, false); ret = dwc3_ep0_start_trans(dwc, dep->number); } 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) : DWC3_TRBCTL_CONTROL_STATUS2; 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); } diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 640e4aa5482d..4787d6f449fa 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3144,27 +3144,19 @@ int dwc3_gadget_init(struct dwc3 *dwc) 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, sizeof(*dwc->ep0_trb) * 2, &dwc->ep0_trb_addr, GFP_KERNEL); if (!dwc->ep0_trb) { dev_err(dwc->dev, "failed to allocate ep0 trb\n"); ret = -ENOMEM; - goto err1; + goto err0; } dwc->setup_buf = kzalloc(DWC3_EP0_BOUNCE_SIZE, GFP_KERNEL); if (!dwc->setup_buf) { ret = -ENOMEM; - goto err2; + goto err1; } dwc->ep0_bounce = dma_alloc_coherent(dwc->sysdev, @@ -3173,20 +3165,20 @@ int dwc3_gadget_init(struct dwc3 *dwc) if (!dwc->ep0_bounce) { dev_err(dwc->dev, "failed to allocate ep0 bounce buffer\n"); ret = -ENOMEM; - goto err3; + goto err2; } dwc->zlp_buf = kzalloc(DWC3_ZLP_BUF_SIZE, GFP_KERNEL); if (!dwc->zlp_buf) { ret = -ENOMEM; - goto err4; + goto err3; } dwc->bounce = dma_alloc_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, &dwc->bounce_addr, GFP_KERNEL); if (!dwc->bounce) { ret = -ENOMEM; - goto err5; + goto err4; } init_completion(&dwc->ep0_in_setup); @@ -3226,38 +3218,34 @@ int dwc3_gadget_init(struct dwc3 *dwc) ret = dwc3_gadget_init_endpoints(dwc, dwc->num_eps); if (ret) - goto err6; + goto err5; ret = usb_add_gadget_udc(dwc->dev, &dwc->gadget); if (ret) { dev_err(dwc->dev, "failed to register udc\n"); - goto err6; + goto err5; } return 0; -err6: +err5: dma_free_coherent(dwc->sysdev, DWC3_BOUNCE_SIZE, dwc->bounce, dwc->bounce_addr); -err5: +err4: kfree(dwc->zlp_buf); -err4: +err3: dwc3_gadget_free_endpoints(dwc); dma_free_coherent(dwc->sysdev, DWC3_EP0_BOUNCE_SIZE, dwc->ep0_bounce, dwc->ep0_bounce_addr); -err3: +err2: kfree(dwc->setup_buf); -err2: +err1: dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb) * 2, 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: return ret; } @@ -3280,9 +3268,6 @@ void dwc3_gadget_exit(struct dwc3 *dwc) dma_free_coherent(dwc->sysdev, sizeof(*dwc->ep0_trb) * 2, 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) -- 2.20.1