From: Hema HK <hemahk@xxxxxx> Buffer is mapped to dma when dma channel is allocated. Buffer needs to be unmapped when fallback to cpu mode if dma channel_program fails. Signed-off-by: Hema HK <hemahk@xxxxxx> Cc: Felipe Balbi <felipe.balbi@xxxxxxxxx> --- Index: linux-2.6/drivers/usb/musb/musb_gadget.c =================================================================== --- linux-2.6.orig/drivers/usb/musb/musb_gadget.c +++ linux-2.6/drivers/usb/musb/musb_gadget.c @@ -120,22 +120,24 @@ __acquires(ep->musb->lock) ep->busy = 1; spin_unlock(&musb->lock); if (is_dma_capable()) { - if (req->mapped) { - dma_unmap_single(musb->controller, - req->request.dma, - req->request.length, - req->tx - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); - req->request.dma = DMA_ADDR_INVALID; - req->mapped = 0; - } else if (req->request.dma != DMA_ADDR_INVALID) - dma_sync_single_for_cpu(musb->controller, - req->request.dma, - req->request.length, - req->tx - ? DMA_TO_DEVICE - : DMA_FROM_DEVICE); + if (req->request.dma != DMA_ADDR_INVALID) { + if (req->mapped) { + dma_unmap_single(musb->controller, + req->request.dma, + req->request.length, + req->tx + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + req->request.dma = DMA_ADDR_INVALID; + req->mapped = 0; + } else if (req->request.dma != DMA_ADDR_INVALID) + dma_sync_single_for_cpu(musb->controller, + req->request.dma, + req->request.length, + req->tx + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + } } if (request->status == 0) DBG(5, "%s done request %p, %d/%d\n", @@ -393,6 +395,29 @@ static void txstate(struct musb *musb, s #endif if (!use_dma) { + /* unmap the dma buffer back to cpu if dma channel + *programming fails + */ + if (is_dma_capable()) { + if (req->mapped) { + dma_unmap_single(musb->controller, + req->request.dma, + req->request.length, + req->tx + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + req->request.dma = DMA_ADDR_INVALID; + req->mapped = 0; + } else if (req->request.dma != DMA_ADDR_INVALID) { + dma_sync_single_for_cpu(musb->controller, + req->request.dma, + req->request.length, + req->tx + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + } + } + musb_write_fifo(musb_ep->hw_ep, fifo_count, (u8 *) (request->buf + request->actual)); request->actual += fifo_count; @@ -711,7 +736,31 @@ static void rxstate(struct musb *musb, s return; } #endif - + /* unmap the dma buffer back to cpu if dma channel + * programming fails. This buffer is mapped if the channel + * allocation is successful + */ + if (is_dma_capable()) { + if (req->mapped) { + dma_unmap_single(musb->controller, + req->request.dma, + req->request.length, + req->tx + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + req->request.dma = DMA_ADDR_INVALID; + req->mapped = 0; + } else if (req->request.dma != + DMA_ADDR_INVALID) { + dma_sync_single_for_cpu( + musb->controller, + req->request.dma, + req->request.length, + req->tx + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + } + } musb_read_fifo(musb_ep->hw_ep, fifo_count, (u8 *) (request->buf + request->actual)); request->actual += fifo_count; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html