[PATCH] ehci: Param to skip BIOS handoff negotiation

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

 



The background here:

The ExoPC tablet (intel pinetrail) with recent kernels is reliably
hanging for ~90 seconds on boot.  I tracked this down to the
pci_write_config_byte() call in the ehci quirk handler that tries to
write the "BIOS handoff" semaphore.  It doesn't look like it's
failing: the rest of the handoff process completes successfully after
it returns.

Beyond discovering that it's a little timing-sensitive (the hang is
reliable in an unpatched 2.6.38, was sporadic on earlier MeeGo
kernels, and happens only about 25% of the time or so if I add a
msleep(1) immediately before the call) I couldn't find any magic to
fix it.  The #if'd out SMI enable immediately above seemed promising,
but was ineffective.

So I hacked in a "ehci_force_handoff" parameter to turn the handoff
process off and treat it as it already does on failure.  The fact that
the code seems prepared to handle this tells me (maybe) that this
isn't too likely to wreck things.  It seems to work great to restore
boot times on the ExoPC, and testing on two other pinetrail netbooks
didn't show anything problems.

Ideas?
Andy

>From ac6fef59e15bd0b4e5823fb870453af73a701cdc Mon Sep 17 00:00:00 2001
From: Andy Ross <andy.ross@xxxxxxxxxxxxx>
Date: Fri, 6 May 2011 14:45:47 -0700
Subject: [PATCH] ehci: Param to skip BIOS handoff negotiation

The pegatron lucid tablets sporadically hang at boot for 90+ seconds
in the pci_write_config_byte() call that writes the BIOS handoff
semaphore.  As the code appears to have been written to reset the flag
even if the negotiation fails, provide a boot parameter
("ehci_force_handoff=1") that skips negotiation entirely.

Signed-off-by: Andy Ross <andy.ross@xxxxxxxxxxxxx>
---
 drivers/usb/host/pci-quirks.c |   22 ++++++++++++++++++----
 1 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 4c502c8..39b0e3e 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -52,6 +52,15 @@
 #define EHCI_USBLEGCTLSTS	4		/* legacy control/status */
 #define EHCI_USBLEGCTLSTS_SOOE	(1 << 13)	/* SMI on ownership change */

+/* Force the BIOS handoff, skipping the negotiation step */
+static int ehci_force_handoff;
+static int __init parse_ehci_force_handoff(char *s)
+{
+	ehci_force_handoff = s[0] == '1' && !s[1];
+	return 0;
+}
+early_param("ehci_force_handoff", parse_ehci_force_handoff);
+

 /*
  * Make sure the controller is completely inactive, unable to
@@ -270,14 +279,17 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
 				 * set for any other reason than forcing a BIOS
 				 * handoff..
 				 */
-				pci_write_config_byte(pdev, offset + 3, 1);
+				if (!ehci_force_handoff)
+					pci_write_config_byte(pdev,
+							      offset + 3, 1);
 			}

 			/* if boot firmware now owns EHCI, spin till
 			 * it hands it over.
 			 */
 			msec = 1000;
-			while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
+			while (!ehci_force_handoff &&
+			       (cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
 				tried_handoff = 1;
 				msleep(10);
 				msec -= 10;
@@ -288,8 +300,10 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
 				/* well, possibly buggy BIOS... try to shut
 				 * it down, and hope nothing goes too wrong
 				 */
-				dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
-						" (BIOS bug?) %08x\n", cap);
+				if (!ehci_force_handoff)
+					dev_warn(&pdev->dev,
+						 "EHCI: BIOS handoff failed"
+						 " (BIOS bug?) %08x\n", cap);
 				pci_write_config_byte(pdev, offset + 2, 0);
 			}

-- 
1.7.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