Skip to content

Commit

Permalink
usb: musb: introduce api for dma code to check compatibility with usb…
Browse files Browse the repository at this point in the history
… request

Gadget MUSB driver handles dma mappings in musb_gadget_queue(). Where as it is
possible for  dma code to reject the usb request later at ->channel_program()
called from txstate()/rxstate()

For example ->channel_program in tusb6010_omap.c:

static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
        u8 rndis_mode, dma_addr_t dma_addr, u32 len)
{
...
	if (unlikely(dma_addr & 0x1) || (len < 32) || (len > packet_sz))
		return false;
...
	if (dma_addr & 0x2)
		return false;
...
}

In this case, usb request will be handled in PIO mode which renders dma mapping
operations unnecessary.

This patch adds an api to allow dma code to indicate incompatibility with usb
request. Gadget musb driver call this api, if available, before dma mappings to
avoid any unnecessary mapping operations.

Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Mian Yousaf Kaukab authored and Felipe Balbi committed Feb 1, 2011
1 parent c65bfa6 commit 5f5761c
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 0 deletions.
3 changes: 3 additions & 0 deletions drivers/usb/musb/musb_dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ struct dma_controller {
dma_addr_t dma_addr,
u32 length);
int (*channel_abort)(struct dma_channel *);
int (*is_compatible)(struct dma_channel *channel,
u16 maxpacket,
void *buf, u32 length);
};

/* called after channel_program(), may indicate a fault */
Expand Down
14 changes: 14 additions & 0 deletions drivers/usb/musb/musb_gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,25 @@
static inline void map_dma_buffer(struct musb_request *request,
struct musb *musb, struct musb_ep *musb_ep)
{
int compatible = true;
struct dma_controller *dma = musb->dma_controller;

request->map_state = UN_MAPPED;

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

/* Check if DMA engine can handle this request.
* DMA code must reject the USB request explicitly.
* Default behaviour is to map the request.
*/
if (dma->is_compatible)
compatible = dma->is_compatible(musb_ep->dma,
musb_ep->packet_sz, request->request.buf,
request->request.length);
if (!compatible)
return;

if (request->request.dma == DMA_ADDR_INVALID) {
request->request.dma = dma_map_single(
musb->controller,
Expand Down

0 comments on commit 5f5761c

Please sign in to comment.