aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc3
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2011-12-19 04:32:34 -0500
committerFelipe Balbi <balbi@ti.com>2012-02-28 07:48:54 -0500
commit0fc9a1be09d9f8b19bcf64ab96836cb92beb0970 (patch)
tree0aa8fa3ad9f5341356ba82b4ab7765077df5055e /drivers/usb/dwc3
parenta698908d3b3be915ac20cd37faeff1216f6b4fe8 (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.h2
-rw-r--r--drivers/usb/dwc3/ep0.c16
-rw-r--r--drivers/usb/dwc3/gadget.c93
-rw-r--r--drivers/usb/dwc3/gadget.h2
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
59void 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
92void 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
121void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, 57void 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
839static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) 776static 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
2245err3: 2188err3:
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
2249err2: 2191err2:
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,
108int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value); 108int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value);
109int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep, 109int 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);
111void dwc3_map_buffer_to_dma(struct dwc3_request *req);
112void 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