[PATCH Resend v3] usb: musb: do not use dma for control transfers

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

 



The Inventra DMA engine used with the MUSB controller in many
SoCs cannot use DMA for control transfers on EP0, but can use
DMA for all other transfers.

The USB core maps urbs for DMA if hcd->self.uses_dma is true.
(hcd->self.uses_dma is true for MUSB as well).

Split the uses_dma flag into two - one that says if the
controller needs to use PIO for control transfers, and
another which says if the controller uses DMA (for all
other transfers).

Also, populate this flag for all MUSB by default.

(Tested on OMAP3 and OMAP4 boards, with EHCI and MUSB HCDs
simultaneously in use).

Signed-off-by: Maulik Mankad <x0082077@xxxxxx>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@xxxxxx>
Signed-off-by: Anand Gadiyar <gadiyar@xxxxxx>
Cc: Oliver Neukum <oliver@xxxxxxxxxx>
Cc: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
Cc: Praveena NADAHALLY <praveen.nadahally@xxxxxxxxxxxxxx>
Cc: Felipe Balbi <balbi@xxxxxx>
Cc: Ajay Kumar Gupta <ajay.gupta@xxxxxx>
---
Resending this patch - it seems to have been lost along the way

v3: Simplified version, tested again with MUSB+EHCI
- Added Sign-offs for Santosh and Maulik, who wrote
the initial version on which I based my patch.

- I've populated the uses_pio_for_control flag for all
MUSB HCDs. Even though some DMA engines used with MUSB may
be able to carry out control transfers using DMA, there may
not be much to be gained. If someone disagrees, I'll respin
the patch to populate this flag for the Inventra engine alone.

 drivers/usb/core/hcd.c         |    2 ++
 drivers/usb/musb/musb_core.c   |    3 +++
 drivers/usb/musb/musb_gadget.c |    4 ++++
 include/linux/usb.h            |    4 ++++
 4 files changed, 13 insertions(+)

Index: mainline/drivers/usb/core/hcd.c
===================================================================
--- mainline.orig/drivers/usb/core/hcd.c
+++ mainline/drivers/usb/core/hcd.c
@@ -1330,6 +1330,8 @@ static int map_urb_for_dma(struct usb_hc
 	 */
 
 	if (usb_endpoint_xfer_control(&urb->ep->desc)) {
+		if (hcd->self.uses_pio_for_control)
+			return ret;
 		if (hcd->self.uses_dma) {
 			urb->setup_dma = dma_map_single(
 					hcd->self.controller,
Index: mainline/include/linux/usb.h
===================================================================
--- mainline.orig/include/linux/usb.h
+++ mainline/include/linux/usb.h
@@ -313,6 +313,10 @@ struct usb_bus {
 	int busnum;			/* Bus number (in order of reg) */
 	const char *bus_name;		/* stable id (PCI slot_name etc) */
 	u8 uses_dma;			/* Does the host controller use DMA? */
+	u8 uses_pio_for_control;	/*
+					 * Does the host controller use PIO
+					 * for control transfers?
+					 */
 	u8 otg_port;			/* 0, or number of OTG/HNP port */
 	unsigned is_b_host:1;		/* true during some HNP roleswitches */
 	unsigned b_hnp_enable:1;	/* OTG: did A-Host enable HNP? */
Index: mainline/drivers/usb/musb/musb_core.c
===================================================================
--- mainline.orig/drivers/usb/musb/musb_core.c
+++ mainline/drivers/usb/musb/musb_core.c
@@ -2116,12 +2116,15 @@ bad_config:
 	 * Otherwise, wait till the gadget driver hooks up.
 	 */
 	if (!is_otg_enabled(musb) && is_host_enabled(musb)) {
+		struct usb_hcd	*hcd = musb_to_hcd(musb);
+
 		MUSB_HST_MODE(musb);
 		musb->xceiv->default_a = 1;
 		musb->xceiv->state = OTG_STATE_A_IDLE;
 
 		status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
 
+		hcd->self.uses_pio_for_control = 1;
 		DBG(1, "%s mode, status %d, devctl %02x %c\n",
 			"HOST", status,
 			musb_readb(musb->mregs, MUSB_DEVCTL),
Index: mainline/drivers/usb/musb/musb_gadget.c
===================================================================
--- mainline.orig/drivers/usb/musb/musb_gadget.c
+++ mainline/drivers/usb/musb/musb_gadget.c
@@ -1789,6 +1789,8 @@ int usb_gadget_probe_driver(struct usb_g
 		spin_unlock_irqrestore(&musb->lock, flags);
 
 		if (is_otg_enabled(musb)) {
+			struct usb_hcd	*hcd = musb_to_hcd(musb);
+
 			DBG(3, "OTG startup...\n");
 
 			/* REVISIT:  funcall to other code, which also
@@ -1803,6 +1805,8 @@ int usb_gadget_probe_driver(struct usb_g
 				musb->gadget_driver = NULL;
 				musb->g.dev.driver = NULL;
 				spin_unlock_irqrestore(&musb->lock, flags);
+			} else {
+				hcd->self.uses_pio_for_control = 1;
 			}
 		}
 	}
--
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