Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0fc9a1be authored by Felipe Balbi's avatar Felipe Balbi
Browse files

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: default avatarFelipe Balbi <balbi@ti.com>
parent a698908d
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -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 */
+13 −3
Original line number Diff line number Diff line
@@ -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,
+17 −76
Original line number Diff line number Diff line
@@ -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 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc)
			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);
+0 −2
Original line number Diff line number Diff line
@@ -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