usb: musb: unmap the DMA buffer when switching to PIO mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux