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