usb: dwc3: ep0: use immediate SETUP on TRB
authorFelipe Balbi <felipe.balbi@linux.intel.com>
Fri, 7 Apr 2017 10:34:21 +0000 (13:34 +0300)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Tue, 11 Apr 2017 07:58:28 +0000 (10:58 +0300)
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 <felipe.balbi@linux.intel.com>
drivers/usb/dwc3/core.h
drivers/usb/dwc3/ep0.c
drivers/usb/dwc3/gadget.c

index 2ad8ce2..bbb7c3f 100644 (file)
@@ -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;
index e689ced..da5e085 100644 (file)
@@ -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);
 }
 
index 640e4aa..4787d6f 100644 (file)
@@ -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)