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

Commit c65bfa62 authored by Mian Yousaf Kaukab's avatar Mian Yousaf Kaukab Committed by Felipe Balbi
Browse files

usb: musb: maintain three states for buffer mappings instead of two



If dma buffers are mapped by a higher layer, with a boolean musb_request.mapped
it is still possible to call dma_sync_single_for_device() from
musb_g_giveback(), even if txstate()/rxstate() has called unmap_dma_buffer()
before falling back to pio mode.

Moreover, check for musb_ep->dma is moved within map_dma_buffer() so where
applicable checks for it are removed. And where possible, checks for
is_dma_capable() are merged with buffer map state check.

Signed-off-by: default avatarMian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 06624818
Loading
Loading
Loading
Loading
+25 −20
Original line number Diff line number Diff line
@@ -92,11 +92,19 @@

/* ----------------------------------------------------------------------- */

#define is_buffer_mapped(req) (is_dma_capable() && \
					(req->map_state != UN_MAPPED))

/* Maps the buffer to dma  */

static inline void map_dma_buffer(struct musb_request *request,
				struct musb *musb)
			struct musb *musb, struct musb_ep *musb_ep)
{
	request->map_state = UN_MAPPED;

	if (!is_dma_capable() || !musb_ep->dma)
		return;

	if (request->request.dma == DMA_ADDR_INVALID) {
		request->request.dma = dma_map_single(
				musb->controller,
@@ -105,7 +113,7 @@ static inline void map_dma_buffer(struct musb_request *request,
				request->tx
					? DMA_TO_DEVICE
					: DMA_FROM_DEVICE);
		request->mapped = 1;
		request->map_state = MUSB_MAPPED;
	} else {
		dma_sync_single_for_device(musb->controller,
			request->request.dma,
@@ -113,7 +121,7 @@ static inline void map_dma_buffer(struct musb_request *request,
			request->tx
				? DMA_TO_DEVICE
				: DMA_FROM_DEVICE);
		request->mapped = 0;
		request->map_state = PRE_MAPPED;
	}
}

@@ -121,11 +129,14 @@ static inline void map_dma_buffer(struct musb_request *request,
static inline void unmap_dma_buffer(struct musb_request *request,
				struct musb *musb)
{
	if (!is_buffer_mapped(request))
		return;

	if (request->request.dma == DMA_ADDR_INVALID) {
		DBG(20, "not unmapping a never mapped buffer\n");
		return;
	}
	if (request->mapped) {
	if (request->map_state == MUSB_MAPPED) {
		dma_unmap_single(musb->controller,
			request->request.dma,
			request->request.length,
@@ -133,16 +144,15 @@ static inline void unmap_dma_buffer(struct musb_request *request,
				? DMA_TO_DEVICE
				: DMA_FROM_DEVICE);
		request->request.dma = DMA_ADDR_INVALID;
		request->mapped = 0;
	} else {
	} else { /* PRE_MAPPED */
		dma_sync_single_for_cpu(musb->controller,
			request->request.dma,
			request->request.length,
			request->tx
				? DMA_TO_DEVICE
				: DMA_FROM_DEVICE);

	}
	request->map_state = UN_MAPPED;
}

/*
@@ -172,7 +182,6 @@ __acquires(ep->musb->lock)

	ep->busy = 1;
	spin_unlock(&musb->lock);
	if (is_dma_capable() && ep->dma)
	unmap_dma_buffer(req, musb);
	if (request->status == 0)
		DBG(5, "%s done request %p,  %d/%d\n",
@@ -335,7 +344,7 @@ static void txstate(struct musb *musb, struct musb_request *req)
			csr);

#ifndef	CONFIG_MUSB_PIO_ONLY
	if (is_dma_capable() && musb_ep->dma) {
	if (is_buffer_mapped(req)) {
		struct dma_controller	*c = musb->dma_controller;
		size_t request_size;

@@ -436,7 +445,6 @@ static void txstate(struct musb *musb, struct musb_request *req)
		 * Unmap the dma buffer back to cpu if dma channel
		 * programming fails
		 */
		if (is_dma_capable() && musb_ep->dma)
		unmap_dma_buffer(req, musb);

		musb_write_fifo(musb_ep->hw_ep, fifo_count,
@@ -627,7 +635,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
		return;
	}

	if (is_cppi_enabled() && musb_ep->dma) {
	if (is_cppi_enabled() && is_buffer_mapped(req)) {
		struct dma_controller	*c = musb->dma_controller;
		struct dma_channel	*channel = musb_ep->dma;

@@ -658,7 +666,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
		len = musb_readw(epio, MUSB_RXCOUNT);
		if (request->actual < request->length) {
#ifdef CONFIG_USB_INVENTRA_DMA
			if (is_dma_capable() && musb_ep->dma) {
			if (is_buffer_mapped(req)) {
				struct dma_controller	*c;
				struct dma_channel	*channel;
				int			use_dma = 0;
@@ -742,7 +750,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
			fifo_count = min_t(unsigned, len, fifo_count);

#ifdef	CONFIG_USB_TUSB_OMAP_DMA
			if (tusb_dma_omap() && musb_ep->dma) {
			if (tusb_dma_omap() && is_buffer_mapped(req)) {
				struct dma_controller *c = musb->dma_controller;
				struct dma_channel *channel = musb_ep->dma;
				u32 dma_addr = request->dma + request->actual;
@@ -762,7 +770,7 @@ static void rxstate(struct musb *musb, struct musb_request *req)
			 * programming fails. This buffer is mapped if the
			 * channel allocation is successful
			 */
			 if (is_dma_capable() && musb_ep->dma) {
			 if (is_buffer_mapped(req)) {
				unmap_dma_buffer(req, musb);

				/*
@@ -1222,10 +1230,7 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
	request->epnum = musb_ep->current_epnum;
	request->tx = musb_ep->is_in;

	if (is_dma_capable() && musb_ep->dma)
		map_dma_buffer(request, musb);
	else
		request->mapped = 0;
	map_dma_buffer(request, musb, musb_ep);

	spin_lock_irqsave(&musb->lock, lockflags);

+7 −1
Original line number Diff line number Diff line
@@ -35,13 +35,19 @@
#ifndef __MUSB_GADGET_H
#define __MUSB_GADGET_H

enum buffer_map_state {
	UN_MAPPED = 0,
	PRE_MAPPED,
	MUSB_MAPPED
};

struct musb_request {
	struct usb_request	request;
	struct musb_ep		*ep;
	struct musb		*musb;
	u8 tx;			/* endpoint direction */
	u8 epnum;
	u8 mapped;
	enum buffer_map_state map_state;
};

static inline struct musb_request *to_musb_request(struct usb_request *req)