]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[xhci] Forcibly disable SMIs if BIOS fails to release ownership
authorMichael Brown <mcb30@ipxe.org>
Mon, 16 Mar 2015 20:32:33 +0000 (20:32 +0000)
committerMichael Brown <mcb30@ipxe.org>
Mon, 16 Mar 2015 20:38:48 +0000 (20:38 +0000)
If the BIOS fails to gracefully release ownership of the xHCI
controller, we can forcibly claim it by disabling all SMIs via the
USB legacy support control/status register.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/usb/xhci.c

index 34290774a93d83539d3e2157d7807c2e8d48e3ed..6306e158058d13a6c16ba18538cc51a3c2573dcf 100644 (file)
@@ -556,16 +556,15 @@ static void xhci_legacy_init ( struct xhci_device *xhci ) {
  * Claim ownership from BIOS
  *
  * @v xhci             xHCI device
- * @ret rc             Return status code
  */
-static int xhci_legacy_claim ( struct xhci_device *xhci ) {
+static void xhci_legacy_claim ( struct xhci_device *xhci ) {
        uint32_t ctlsts;
        uint8_t bios;
        unsigned int i;
 
        /* Do nothing unless legacy support capability is present */
        if ( ! xhci->legacy )
-               return 0;
+               return;
 
        /* Claim ownership */
        writeb ( XHCI_USBLEGSUP_OS_OWNED,
@@ -585,16 +584,19 @@ static int xhci_legacy_claim ( struct xhci_device *xhci ) {
                                DBGC ( xhci, "XHCI %p warning: BIOS retained "
                                       "SMIs: %08x\n", xhci, ctlsts );
                        }
-                       return 0;
+                       return;
                }
 
                /* Delay */
                mdelay ( 1 );
        }
 
-       DBGC ( xhci, "XHCI %p timed out waiting for BIOS to release "
-              "ownership\n", xhci );
-       return -ETIMEDOUT;
+       /* BIOS did not release ownership.  Claim it forcibly by
+        * disabling all SMIs.
+        */
+       DBGC ( xhci, "XHCI %p could not claim ownership from BIOS: forcibly "
+              "disabling SMIs\n", xhci );
+       writel ( 0, xhci->cap + xhci->legacy + XHCI_USBLEGSUP_CTLSTS );
 }
 
 /**
@@ -3105,8 +3107,7 @@ static int xhci_probe ( struct pci_device *pci ) {
 
        /* Initialise USB legacy support and claim ownership */
        xhci_legacy_init ( xhci );
-       if ( ( rc = xhci_legacy_claim ( xhci ) ) != 0 )
-               goto err_legacy_claim;
+       xhci_legacy_claim ( xhci );
 
        /* Fix Intel PCH-specific quirks, if applicable */
        if ( pci->id->driver_data & XHCI_PCH )
@@ -3148,7 +3149,6 @@ static int xhci_probe ( struct pci_device *pci ) {
        if ( pci->id->driver_data & XHCI_PCH )
                xhci_pch_undo ( xhci, pci );
        xhci_legacy_release ( xhci );
- err_legacy_claim:
        iounmap ( xhci->regs );
  err_ioremap:
        free ( xhci );