mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-02 00:24:12 +08:00
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 <felipe.balbi@linux.intel.com>
This commit is contained in:
parent
374a1020d2
commit
7d5e650a5f
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user