This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM4378: Linux USB Host driver issue on AM4378

Part Number: AM4378

Tool/software: Linux

Hi champs,

Some problems here are faced with AM4378 USB Host driver (usbdwc3 with chip revision: 5533240a) when disconnecting an USB Storage (pendrive) on a custom design

When using Linux Kernel version 4.1.18 with Xenoami support and extracting the USB Storage while is writing some times the following error is seen :

<4>[  246.157546] xhci-hcd xhci-hcd.0.auto: xHCI host not responding to stop endpoint command.
<4>[  246.166860] xhci-hcd xhci-hcd.0.auto: Assuming host is dying, halting host.
<4>[  246.200068] xhci-hcd xhci-hcd.0.auto: Host not halted after 16000 microseconds.
<4>[  246.208164] xhci-hcd xhci-hcd.0.auto: Non-responsive xHCI host is not halting.
<4>[  246.216111] xhci-hcd xhci-hcd.0.auto: Completing active URBs anyway.
<3>[  246.223177] xhci-hcd xhci-hcd.0.auto: HC died; cleaning up

and other times a kernel panic pops up :

2000/01/11,07:11:05 any kern.info kernel: [  389.957554] usb 1-1: new high-speed USB device number 4 using xhci-hcd
[  390.100234] Alignment trap: not handling instruction e1932f9f at [<c025ccb0>]
2000/01/11,07:11:05 any kern.info kernel: [  390.099019] usb 1-1: New USB device found, idVendor=8564, idProduct=1000
2000/01/11,07:11:05 any kern.info kernel: [  390.099040] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
2000/01/11,07:11:05 any kern.[  390.129792] Unhandled fault: alignment exception (0x011) at 0x00312d51
[  390.141195] pgd = c0004000
[  390.144189] [00312d51] *pgd=00000000

When updating only the usb part (driver/usb/) to 4.1.37, the kernel panics seem solved, but the "USB xHCI Port Disable Feature Does not work" (issue 896 for another micro http://www.ti.com/lit/er/sprz429j/sprz429j.pdf) seems to happen still.

After forums review the following patch issued by that Felipe Balbi <balbi@ti.com> has been found :
https://patchwork.kernel.org/patch/9439257/
https://patchwork.kernel.org/patch/5655271/

A patch has been made manually (attached) and solve the problem, but we want to make sure that patch works ok in all contexts

QUESTIONS : Is there an easy way to reproduce the failure to make sure that patch is working ok?

This is an important question since if it occurs once then it needs a reboot to attach again the USB storage and this should be avoided

Thanks

Best regards,

Guillaume

5488.071-usbdwc3-brokenport.patch.txt
Patch adapted manually from ti-kernel-4.4 to solve the problem described in the link
https://lkml.org/lkml/2015/1/12/587. Our revision is less than DWC3_REVISION_300A
--- linux-4.1.18-base/drivers/usb/dwc3/core.h	2017-01-16 15:45:18.362726000 +0100
+++ linux-4.1.18/drivers/usb/dwc3/core.h	2017-01-16 15:47:28.082726000 +0100
@@ -784,6 +784,8 @@
 #define DWC3_REVISION_260A	0x5533260a
 #define DWC3_REVISION_270A	0x5533270a
 #define DWC3_REVISION_280A	0x5533280a
+#define DWC3_REVISION_290A	0x5533290a
+#define DWC3_REVISION_300A	0x5533300a	
 
 /*
  * NOTICE: we're using bit 31 as a "is usb 3.1" flag. This is really
--- linux-4.1.18-base/drivers/usb/dwc3/host.c	2017-01-16 15:45:18.362726000 +0100
+++ linux-4.1.18/drivers/usb/dwc3/host.c	2017-01-16 15:46:57.146726000 +0100
@@ -51,6 +51,19 @@
 
 	pdata.usb3_lpm_capable = dwc->usb3_lpm_capable;
 
+	/**
+	 * WORKAROUND: dwc3 revisions <=3.00a have a limitation
+	 * where Port Disable command doesn't work.
+	 *
+	 * The suggested workaround is that we avoid Port Disable
+	 * completely.
+	 *
+	 * This following flag tells XHCI to do just that.
+	 */
+	dev_info(dwc->dev, "dwc3 revision: %x\n", dwc->revision);
+	if (dwc->revision <= DWC3_REVISION_300A)
+		pdata.quirk_port_broken_pe = true;
+
 	ret = platform_device_add_data(xhci, &pdata, sizeof(pdata));
 	if (ret) {
 		dev_err(dwc->dev, "couldn't add platform data to xHCI device\n");
--- linux-4.1.18-base/drivers/usb/host/xhci.h	2017-01-16 15:45:18.370726000 +0100
+++ linux-4.1.18/drivers/usb/host/xhci.h	2017-01-16 15:49:05.794726000 +0100
@@ -1572,6 +1572,8 @@
 #define XHCI_SPURIOUS_WAKEUP	(1 << 18)
 /* For controllers with a broken beyond repair streams implementation */
 #define XHCI_BROKEN_STREAMS	(1 << 19)
+/* For controller with a broken Port Disable implementation */
+#define XHCI_BROKEN_PORT_PE	(1 << 21)
 #define XHCI_PME_STUCK_QUIRK	(1 << 20)
 #define XHCI_SSIC_PORT_UNUSED	(1 << 22)
 #define XHCI_NO_64BIT_SUPPORT	(1 << 23)
--- linux-4.1.18-base/drivers/usb/host/xhci-hub.c	2017-01-16 15:45:18.370726000 +0100
+++ linux-4.1.18/drivers/usb/host/xhci-hub.c	2017-01-16 15:50:05.369016000 +0100
@@ -348,6 +348,13 @@
 		return;
 	}
 
+	if (xhci->quirks & XHCI_BROKEN_PORT_PE) {
+		xhci_dbg(xhci, "Broken Port Enabled/Disabled, ignoring "
+				"port disable request.\n");
+		return;
+	}
+
+
 	/* Write 1 to disable the port */
 	writel(port_status | PORT_PE, addr);
 	port_status = readl(addr);
--- linux-4.1.18-base/drivers/usb/host/xhci-plat.c	2017-01-16 15:45:18.370726000 +0100
+++ linux-4.1.18/drivers/usb/host/xhci-plat.c	2017-01-16 15:48:21.198726000 +0100
@@ -150,6 +150,9 @@
 	if ((node && of_property_read_bool(node, "usb3-lpm-capable")) ||
 			(pdata && pdata->usb3_lpm_capable))
 		xhci->quirks |= XHCI_LPM_SUPPORT;
+
+	if (pdata && pdata->quirk_port_broken_pe)
+		xhci->quirks |= XHCI_BROKEN_PORT_PE;
 	/*
 	 * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset)
 	 * is called by usb_add_hcd().
--- linux-4.1.18-base/include/linux/usb/xhci_pdriver.h	2017-01-16 15:45:20.302726000 +0100
+++ linux-4.1.18/include/linux/usb/xhci_pdriver.h	2017-01-16 15:52:58.905016000 +0100
@@ -18,10 +18,12 @@
  *
  * @usb3_lpm_capable:	determines if this xhci platform supports USB3
  *			LPM capability
+ * @quirk_port_broken_pe: If true, XHCI will not use Port Disable. 
  *
  */
 struct usb_xhci_pdata {
 	unsigned	usb3_lpm_capable:1;
+	unsigned    quirk_port_broken_pe:1;
 };
 
 #endif /* __USB_CORE_XHCI_PDRIVER_H */

  • Hi Guillaume,

    I've notified the USB expert. Feedback will be posted here.

    Best Regards,
    Yordan
  • Guillaume,

    The symptom matches to an issue we observed which has been fixed in the newer Processor SDK kernel. The issue was solved with multiple kernel patches which fixed several kernel bugs, so it is difficult to identify the patch set which solves this particular issue. It is recommended to migrate to the latest Processor SDK kernel to ensure the issue is addressed.

  • Hello Bin,

    Thanks. Understood but here it is not an option update to the latest SDK. Xenomai is used and the last patch version is for the kernel 4.1.18.

    Could you share any validation procedure or use case testing that could be put in place in order to validate that the patching which has been integrated solve the issue in any conditions?

    Thank you

    BR,
    Guillaume
  • Guillaume,

    In general in Linux we use the same test case which triggers the issue to validate the fix. There is nothing magic.

    By the way, I have to correct my statement in my first post. Looking at the patches in the link you provided, it seems the issue the customer has is different from the one I mentioned which is fixed in the latest SDK. The patches show the customer's issue is hardware related, but the one I mentioned is purely software bug of dma-mask handling in the driver.

  • Hello Bin,

    Since finally the patch I mentioned is not linked to the latest SDK fixes, could you give more details about the patch I mentioned in my first post ? Ie

    . Is it known from TI side? 

    . What HW issue is it related to?

    . Do you have an easy way to reproduce this HW issue  in order to validate the patch which is now used?

    Thank you

    BR,

    Guillaume