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>
This commit is contained in:
Felipe Balbi 2011-12-19 11:32:34 +02:00
parent a698908d3b
commit 0fc9a1be09
4 changed files with 30 additions and 83 deletions

View File

@ -572,7 +572,6 @@ struct dwc3_request {
* @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
* @setup_buf_addr: dma address of setup_buf
* @ep0_bounce_addr: dma address of ep0_bounce
* @lock: for synchronizing
* @dev: pointer to our struct device
@ -609,7 +608,6 @@ struct dwc3 {
u8 *setup_buf;
dma_addr_t ctrl_req_addr;
dma_addr_t ep0_trb_addr;
dma_addr_t setup_buf_addr;
dma_addr_t ep0_bounce_addr;
struct dwc3_request ep0_usb_req;
/* device lock */

View File

@ -309,7 +309,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
dep = dwc->eps[0];
dwc->ep0_usb_req.dep = dep;
dwc->ep0_usb_req.request.length = sizeof(*response_pkt);
dwc->ep0_usb_req.request.dma = dwc->setup_buf_addr;
dwc->ep0_usb_req.request.buf = dwc->setup_buf;
dwc->ep0_usb_req.request.complete = dwc3_ep0_status_cmpl;
return __dwc3_gadget_ep0_queue(dep, &dwc->ep0_usb_req);
@ -686,7 +686,12 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc,
DWC3_TRBCTL_CONTROL_DATA);
} else if ((req->request.length % dep->endpoint.maxpacket)
&& (event->endpoint_number == 0)) {
dwc3_map_buffer_to_dma(req);
ret = usb_gadget_map_request(&dwc->gadget, &req->request,
event->endpoint_number);
if (ret) {
dev_dbg(dwc->dev, "failed to map request\n");
return;
}
WARN_ON(req->request.length > dep->endpoint.maxpacket);
@ -701,7 +706,12 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc,
dwc->ep0_bounce_addr, dep->endpoint.maxpacket,
DWC3_TRBCTL_CONTROL_DATA);
} else {
dwc3_map_buffer_to_dma(req);
ret = usb_gadget_map_request(&dwc->gadget, &req->request,
event->endpoint_number);
if (ret) {
dev_dbg(dwc->dev, "failed to map request\n");
return;
}
ret = dwc3_ep0_start_trans(dwc, event->endpoint_number,
req->request.dma, req->request.length,

View File

@ -54,70 +54,6 @@
#include "gadget.h"
#include "io.h"
#define DMA_ADDR_INVALID (~(dma_addr_t)0)
void dwc3_map_buffer_to_dma(struct dwc3_request *req)
{
struct dwc3 *dwc = req->dep->dwc;
if (req->request.length == 0) {
/* req->request.dma = dwc->setup_buf_addr; */
return;
}
if (req->request.num_sgs) {
int mapped;
mapped = dma_map_sg(dwc->dev, req->request.sg,
req->request.num_sgs,
req->direction ? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
if (mapped < 0) {
dev_err(dwc->dev, "failed to map SGs\n");
return;
}
req->request.num_mapped_sgs = mapped;
return;
}
if (req->request.dma == DMA_ADDR_INVALID) {
req->request.dma = dma_map_single(dwc->dev, req->request.buf,
req->request.length, req->direction
? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->mapped = true;
}
}
void dwc3_unmap_buffer_from_dma(struct dwc3_request *req)
{
struct dwc3 *dwc = req->dep->dwc;
if (req->request.length == 0) {
req->request.dma = DMA_ADDR_INVALID;
return;
}
if (req->request.num_mapped_sgs) {
req->request.dma = DMA_ADDR_INVALID;
dma_unmap_sg(dwc->dev, req->request.sg,
req->request.num_sgs,
req->direction ? DMA_TO_DEVICE
: DMA_FROM_DEVICE);
req->request.num_mapped_sgs = 0;
return;
}
if (req->mapped) {
dma_unmap_single(dwc->dev, req->request.dma,
req->request.length, req->direction
? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->mapped = 0;
req->request.dma = DMA_ADDR_INVALID;
}
}
void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
int status)
{
@ -144,14 +80,15 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
if (req->request.status == -EINPROGRESS)
req->request.status = status;
dwc3_unmap_buffer_from_dma(req);
usb_gadget_unmap_request(&dwc->gadget, &req->request,
req->direction);
dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n",
req, dep->name, req->request.actual,
req->request.length, status);
spin_unlock(&dwc->lock);
req->request.complete(&req->dep->endpoint, &req->request);
req->request.complete(&dep->endpoint, &req->request);
spin_lock(&dwc->lock);
}
@ -563,7 +500,6 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep,
req->epnum = dep->number;
req->dep = dep;
req->request.dma = DMA_ADDR_INVALID;
return &req->request;
}
@ -822,7 +758,8 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
* here and stop, unmap, free and del each of the linked
* requests instead of we do now.
*/
dwc3_unmap_buffer_from_dma(req);
usb_gadget_unmap_request(&dwc->gadget, &req->request,
req->direction);
list_del(&req->list);
return ret;
}
@ -838,6 +775,9 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
{
struct dwc3 *dwc = dep->dwc;
int ret;
req->request.actual = 0;
req->request.status = -EINPROGRESS;
req->direction = dep->direction;
@ -855,7 +795,11 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
* This will also avoid Host cancelling URBs due to too
* many NACKs.
*/
dwc3_map_buffer_to_dma(req);
ret = usb_gadget_map_request(&dwc->gadget, &req->request,
dep->direction);
if (ret)
return ret;
list_add_tail(&req->list, &dep->request_list);
/*
@ -2150,9 +2094,8 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
goto err1;
}
dwc->setup_buf = dma_alloc_coherent(dwc->dev,
sizeof(*dwc->setup_buf) * 2,
&dwc->setup_buf_addr, GFP_KERNEL);
dwc->setup_buf = kzalloc(sizeof(*dwc->setup_buf) * 2,
GFP_KERNEL);
if (!dwc->setup_buf) {
dev_err(dwc->dev, "failed to allocate setup buffer\n");
ret = -ENOMEM;
@ -2243,8 +2186,7 @@ err4:
dwc->ep0_bounce_addr);
err3:
dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
dwc->setup_buf, dwc->setup_buf_addr);
kfree(dwc->setup_buf);
err2:
dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
@ -2273,8 +2215,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
dma_free_coherent(dwc->dev, 512, dwc->ep0_bounce,
dwc->ep0_bounce_addr);
dma_free_coherent(dwc->dev, sizeof(*dwc->setup_buf) * 2,
dwc->setup_buf, dwc->setup_buf_addr);
kfree(dwc->setup_buf);
dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
dwc->ep0_trb, dwc->ep0_trb_addr);

View File

@ -108,8 +108,6 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value);
int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
unsigned cmd, struct dwc3_gadget_ep_cmd_params *params);
void dwc3_map_buffer_to_dma(struct dwc3_request *req);
void dwc3_unmap_buffer_from_dma(struct dwc3_request *req);
/**
* dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW