diff options
author | Felipe Balbi <balbi@ti.com> | 2011-12-19 04:32:34 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-02-28 07:48:54 -0500 |
commit | 0fc9a1be09d9f8b19bcf64ab96836cb92beb0970 (patch) | |
tree | 0aa8fa3ad9f5341356ba82b4ab7765077df5055e /drivers/usb/dwc3 | |
parent | a698908d3b3be915ac20cd37faeff1216f6b4fe8 (diff) |
usb: dwc3: gadget: use generic map/unmap routines
those routines have everything we need to map/unmap
USB requests and it's better to use them.
In order to achieve that, we had to add a simple
change on how we allocate and use our setup buffer;
we cannot allocate it from coherent anymore otherwise
the generic map/unmap routines won't be able to easily
know that the GetStatus request already has a DMA
address.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/dwc3')
-rw-r--r-- | drivers/usb/dwc3/core.h | 2 | ||||
-rw-r--r-- | drivers/usb/dwc3/ep0.c | 16 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.c | 93 | ||||
-rw-r--r-- | drivers/usb/dwc3/gadget.h | 2 |
4 files changed, 30 insertions, 83 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 9e57f8e9bf17..a72f42ffbbee 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h | |||
@@ -572,7 +572,6 @@ struct dwc3_request { | |||
572 | * @ctrl_req_addr: dma address of ctrl_req | 572 | * @ctrl_req_addr: dma address of ctrl_req |
573 | * @ep0_trb: dma address of ep0_trb | 573 | * @ep0_trb: dma address of ep0_trb |
574 | * @ep0_usb_req: dummy req used while handling STD USB requests | 574 | * @ep0_usb_req: dummy req used while handling STD USB requests |
575 | * @setup_buf_addr: dma address of setup_buf | ||
576 | * @ep0_bounce_addr: dma address of ep0_bounce | 575 | * @ep0_bounce_addr: dma address of ep0_bounce |
577 | * @lock: for synchronizing | 576 | * @lock: for synchronizing |
578 | * @dev: pointer to our struct device | 577 | * @dev: pointer to our struct device |
@@ -609,7 +608,6 @@ struct dwc3 { | |||
609 | u8 *setup_buf; | 608 | u8 *setup_buf; |
610 | dma_addr_t ctrl_req_addr; | 609 | dma_addr_t ctrl_req_addr; |
611 | dma_addr_t ep0_trb_addr; | 610 | dma_addr_t ep0_trb_addr; |
612 | dma_addr_t setup_buf_addr; | ||
613 | dma_addr_t ep0_bounce_addr; | 611 | dma_addr_t ep0_bounce_addr; |
614 | struct dwc3_request ep0_usb_req; | 612 | struct dwc3_request ep0_usb_req; |
615 | /* device lock */ | 613 | /* device lock */ |
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 2f51de57593a..24137d8563c9 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -309,7 +309,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc, | |||
309 | dep = dwc->eps[0]; | 309 | dep = dwc->eps[0]; |
310 | dwc->ep0_usb_req.dep = dep; | 310 | dwc->ep0_usb_req.dep = dep; |
311 | dwc->ep0_usb_req.request.length = sizeof(*response_pkt); | 311 | dwc->ep0_usb_req.request.length = sizeof(*response_pkt); |
312 | dwc->ep0_usb_req.request.dma = dwc->setup_buf_addr; | 312 | dwc->ep0_usb_req.request.buf = dwc->setup_buf; |
313 | dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl; | 313 | dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl; |
314 | 314 | ||
315 | return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req); | 315 | return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req); |
@@ -686,7 +686,12 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc, | |||
686 | DWC3_TRBCTL_CONTROL_DATA); | 686 | DWC3_TRBCTL_CONTROL_DATA); |
687 | } else if ((req->request.length % dep->endpoint.maxpacket) | 687 | } else if ((req->request.length % dep->endpoint.maxpacket) |
688 | && (event->endpoint_number == 0)) { | 688 | && (event->endpoint_number == 0)) { |
689 | dwc3_map_buffer_to_dma(req); | 689 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, |
690 | event->endpoint_number); | ||
691 | if (ret) { | ||
692 | dev_dbg(dwc->dev, "failed to map request\n"); | ||
693 | return; | ||
694 | } | ||
690 | 695 | ||
691 | WARN_ON(req->request.length > dep->endpoint.maxpacket); | 696 | WARN_ON(req->request.length > dep->endpoint.maxpacket); |
692 | 697 | ||
@@ -701,7 +706,12 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc, | |||
701 | dwc->ep0_bounce_addr, dep->endpoint.maxpacket, | 706 | dwc->ep0_bounce_addr, dep->endpoint.maxpacket, |
702 | DWC3_TRBCTL_CONTROL_DATA); | 707 | DWC3_TRBCTL_CONTROL_DATA); |
703 | } else { | 708 | } else { |
704 | dwc3_map_buffer_to_dma(req); | 709 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, |
710 | event->endpoint_number); | ||
711 | if (ret) { | ||
712 | dev_dbg(dwc->dev, "failed to map request\n"); | ||
713 | return; | ||
714 | } | ||
705 | 715 | ||
706 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, | 716 | ret = dwc3_ep0_start_trans(dwc, event->endpoint_number, |
707 | req->request.dma, req->request.length, | 717 | req->request.dma, req->request.length, |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a1a04d00a9e4..1009e7e47a24 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -54,70 +54,6 @@ | |||
54 | #include "gadget.h" | 54 | #include "gadget.h" |
55 | #include "io.h" | 55 | #include "io.h" |
56 | 56 | ||
57 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
58 | |||
59 | void dwc3_map_buffer_to_dma(struct dwc3_request *req) | ||
60 | { | ||
61 | struct dwc3 *dwc = req->dep->dwc; | ||
62 | |||
63 | if (req->request.length == 0) { | ||
64 | /* req->request.dma = dwc->setup_buf_addr; */ | ||
65 | return; | ||
66 | } | ||
67 | |||
68 | if (req->request.num_sgs) { | ||
69 | int mapped; | ||
70 | |||
71 | mapped = dma_map_sg(dwc->dev, req->request.sg, | ||
72 | req->request.num_sgs, | ||
73 | req->direction ? DMA_TO_DEVICE | ||
74 | : DMA_FROM_DEVICE); | ||
75 | if (mapped < 0) { | ||
76 | dev_err(dwc->dev, "failed to map SGs\n"); | ||
77 | return; | ||
78 | } | ||
79 | |||
80 | req->request.num_mapped_sgs = mapped; | ||
81 | return; | ||
82 | } | ||
83 | |||
84 | if (req->request.dma == DMA_ADDR_INVALID) { | ||
85 | req->request.dma = dma_map_single(dwc->dev, req->request.buf, | ||
86 | req->request.length, req->direction | ||
87 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
88 | req->mapped = true; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | void dwc3_unmap_buffer_from_dma(struct dwc3_request *req) | ||
93 | { | ||
94 | struct dwc3 *dwc = req->dep->dwc; | ||
95 | |||
96 | if (req->request.length == 0) { | ||
97 | req->request.dma = DMA_ADDR_INVALID; | ||
98 | return; | ||
99 | } | ||
100 | |||
101 | if (req->request.num_mapped_sgs) { | ||
102 | req->request.dma = DMA_ADDR_INVALID; | ||
103 | dma_unmap_sg(dwc->dev, req->request.sg, | ||
104 | req->request.num_sgs, | ||
105 | req->direction ? DMA_TO_DEVICE | ||
106 | : DMA_FROM_DEVICE); | ||
107 | |||
108 | req->request.num_mapped_sgs = 0; | ||
109 | return; | ||
110 | } | ||
111 | |||
112 | if (req->mapped) { | ||
113 | dma_unmap_single(dwc->dev, req->request.dma, | ||
114 | req->request.length, req->direction | ||
115 | ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
116 | req->mapped = 0; | ||
117 | req->request.dma = DMA_ADDR_INVALID; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | 57 | void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, |
122 | int status) | 58 | int status) |
123 | { | 59 | { |
@@ -144,14 +80,15 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
144 | if (req->request.status == -EINPROGRESS) | 80 | if (req->request.status == -EINPROGRESS) |
145 | req->request.status = status; | 81 | req->request.status = status; |
146 | 82 | ||
147 | dwc3_unmap_buffer_from_dma(req); | 83 | usb_gadget_unmap_request(&dwc->gadget, &req->request, |
84 | req->direction); | ||
148 | 85 | ||
149 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", | 86 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", |
150 | req, dep->name, req->request.actual, | 87 | req, dep->name, req->request.actual, |
151 | req->request.length, status); | 88 | req->request.length, status); |
152 | 89 | ||
153 | spin_unlock(&dwc->lock); | 90 | spin_unlock(&dwc->lock); |
154 | req->request.complete(&req->dep->endpoint, &req->request); | 91 | req->request.complete(&dep->endpoint, &req->request); |
155 | spin_lock(&dwc->lock); | 92 | spin_lock(&dwc->lock); |
156 | } | 93 | } |
157 | 94 | ||
@@ -563,7 +500,6 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep, | |||
563 | 500 | ||
564 | req->epnum = dep->number; | 501 | req->epnum = dep->number; |
565 | req->dep = dep; | 502 | req->dep = dep; |
566 | req->request.dma = DMA_ADDR_INVALID; | ||
567 | 503 | ||
568 | return &req->request; | 504 | return &req->request; |
569 | } | 505 | } |
@@ -822,7 +758,8 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, | |||
822 | * here and stop, unmap, free and del each of the linked | 758 | * here and stop, unmap, free and del each of the linked |
823 | * requests instead of we do now. | 759 | * requests instead of we do now. |
824 | */ | 760 | */ |
825 | dwc3_unmap_buffer_from_dma(req); | 761 | usb_gadget_unmap_request(&dwc->gadget, &req->request, |
762 | req->direction); | ||
826 | list_del(&req->list); | 763 | list_del(&req->list); |
827 | return ret; | 764 | return ret; |
828 | } | 765 | } |
@@ -838,6 +775,9 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param, | |||
838 | 775 | ||
839 | static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | 776 | static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) |
840 | { | 777 | { |
778 | struct dwc3 *dwc = dep->dwc; | ||
779 | int ret; | ||
780 | |||
841 | req->request.actual = 0; | 781 | req->request.actual = 0; |
842 | req->request.status = -EINPROGRESS; | 782 | req->request.status = -EINPROGRESS; |
843 | req->direction = dep->direction; | 783 | req->direction = dep->direction; |
@@ -855,7 +795,11 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
855 | * This will also avoid Host cancelling URBs due to too | 795 | * This will also avoid Host cancelling URBs due to too |
856 | * many NACKs. | 796 | * many NACKs. |
857 | */ | 797 | */ |
858 | dwc3_map_buffer_to_dma(req); | 798 | ret = usb_gadget_map_request(&dwc->gadget, &req->request, |
799 | dep->direction); | ||
800 | if (ret) | ||
801 | return ret; | ||
802 | |||
859 | list_add_tail(&req->list, &dep->request_list); | 803 | list_add_tail(&req->list, &dep->request_list); |
860 | 804 | ||
861 | /* | 805 | /* |
@@ -2150,9 +2094,8 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc) | |||
2150 | goto err1; | 2094 | goto err1; |
2151 | } | 2095 | } |
2152 | 2096 | ||
2153 | dwc->setup_buf = dma_alloc_coherent(dwc->dev, | 2097 | dwc->setup_buf = kzalloc(sizeof(*dwc->setup_buf) * 2, |
2154 | sizeof(*dwc->setup_buf) * 2, | 2098 | GFP_KERNEL); |
2155 | &dwc->setup_buf_addr, GFP_KERNEL); | ||
2156 | if (!dwc->setup_buf) { | 2099 | if (!dwc->setup_buf) { |
2157 | dev_err(dwc->dev, "failed to allocate setup buffer\n"); | 2100 | dev_err(dwc->dev, "failed to allocate setup buffer\n"); |
2158 | ret = -ENOMEM; | 2101 | ret = -ENOMEM; |
@@ -2243,8 +2186,7 @@ err4: | |||
2243 | dwc->ep0_bounce_addr); | 2186 | dwc->ep0_bounce_addr); |
2244 | 2187 | ||
2245 | err3: | 2188 | err3: |
2246 | dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2, | 2189 | kfree(dwc->setup_buf); |
2247 | dwc->setup_buf, dwc->setup_buf_addr); | ||
2248 | 2190 | ||
2249 | err2: | 2191 | err2: |
2250 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | 2192 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), |
@@ -2273,8 +2215,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc) | |||
2273 | dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce, | 2215 | dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce, |
2274 | dwc->ep0_bounce_addr); | 2216 | dwc->ep0_bounce_addr); |
2275 | 2217 | ||
2276 | dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2, | 2218 | kfree(dwc->setup_buf); |
2277 | dwc->setup_buf, dwc->setup_buf_addr); | ||
2278 | 2219 | ||
2279 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), | 2220 | dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb), |
2280 | dwc->ep0_trb, dwc->ep0_trb_addr); | 2221 | dwc->ep0_trb, dwc->ep0_trb_addr); |
diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index d97f467d41cc..12f1e104977f 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h | |||
@@ -108,8 +108,6 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, | |||
108 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value); | 108 | int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value); |
109 | int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, | 109 | int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, |
110 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params); | 110 | unsigned cmd, struct dwc3_gadget_ep_cmd_params *params); |
111 | void dwc3_map_buffer_to_dma(struct dwc3_request *req); | ||
112 | void dwc3_unmap_buffer_from_dma(struct dwc3_request *req); | ||
113 | 111 | ||
114 | /** | 112 | /** |
115 | * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW | 113 | * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW |