\r
The XHCI register operation routines.\r
\r
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
**/\r
UINT8\r
XhcReadCapReg8 (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset\r
)\r
{\r
- UINT8 Data;\r
- EFI_STATUS Status;\r
+ UINT8 Data;\r
+ EFI_STATUS Status;\r
\r
Status = Xhc->PciIo->Mem.Read (\r
Xhc->PciIo,\r
EfiPciIoWidthUint8,\r
XHC_BAR_INDEX,\r
- (UINT64) Offset,\r
+ (UINT64)Offset,\r
1,\r
&Data\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
+ DEBUG ((DEBUG_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
Data = 0xFF;\r
}\r
\r
**/\r
UINT32\r
XhcReadCapReg (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset\r
)\r
{\r
- UINT32 Data;\r
- EFI_STATUS Status;\r
+ UINT32 Data;\r
+ EFI_STATUS Status;\r
\r
Status = Xhc->PciIo->Mem.Read (\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) Offset,\r
+ (UINT64)Offset,\r
1,\r
&Data\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
+ DEBUG ((DEBUG_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
Data = 0xFFFFFFFF;\r
}\r
\r
**/\r
UINT32\r
XhcReadOpReg (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset\r
)\r
{\r
- UINT32 Data;\r
- EFI_STATUS Status;\r
+ UINT32 Data;\r
+ EFI_STATUS Status;\r
\r
ASSERT (Xhc->CapLength != 0);\r
\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->CapLength + Offset),\r
+ Xhc->CapLength + Offset,\r
1,\r
&Data\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
+ DEBUG ((DEBUG_ERROR, "XhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
Data = 0xFFFFFFFF;\r
}\r
\r
**/\r
VOID\r
XhcWriteOpReg (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT32 Data\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset,\r
+ IN UINT32 Data\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
\r
ASSERT (Xhc->CapLength != 0);\r
\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->CapLength + Offset),\r
- 1,\r
- &Data\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
- }\r
-}\r
-\r
-/**\r
- Write the data to the 2-bytes width XHCI operational register.\r
-\r
- @param Xhc The XHCI Instance.\r
- @param Offset The offset of the 2-bytes width operational register.\r
- @param Data The data to write.\r
-\r
-**/\r
-VOID\r
-XhcWriteOpReg16 (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT16 Data\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- ASSERT (Xhc->CapLength != 0);\r
-\r
- Status = Xhc->PciIo->Mem.Write (\r
- Xhc->PciIo,\r
- EfiPciIoWidthUint16,\r
- XHC_BAR_INDEX,\r
- (UINT64) (Xhc->CapLength + Offset),\r
+ Xhc->CapLength + Offset,\r
1,\r
&Data\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcWriteOpReg16: Pci Io Write error: %r at %d\n", Status, Offset));\r
+ DEBUG ((DEBUG_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
}\r
}\r
\r
-/**\r
- Read XHCI door bell register.\r
-\r
- @param Xhc The XHCI Instance.\r
- @param Offset The offset of the door bell register.\r
-\r
- @return The register content read\r
-\r
-**/\r
-UINT32\r
-XhcReadDoorBellReg (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset\r
- )\r
-{\r
- UINT32 Data;\r
- EFI_STATUS Status;\r
-\r
- ASSERT (Xhc->DBOff != 0);\r
-\r
- Status = Xhc->PciIo->Mem.Read (\r
- Xhc->PciIo,\r
- EfiPciIoWidthUint32,\r
- XHC_BAR_INDEX,\r
- (UINT64) (Xhc->DBOff + Offset),\r
- 1,\r
- &Data\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcReadDoorBellReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
- Data = 0xFFFFFFFF;\r
- }\r
-\r
- return Data;\r
-}\r
-\r
/**\r
Write the data to the XHCI door bell register.\r
\r
**/\r
VOID\r
XhcWriteDoorBellReg (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT32 Data\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset,\r
+ IN UINT32 Data\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
\r
ASSERT (Xhc->DBOff != 0);\r
\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->DBOff + Offset),\r
+ Xhc->DBOff + Offset,\r
1,\r
&Data\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
+ DEBUG ((DEBUG_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
}\r
}\r
\r
**/\r
UINT32\r
XhcReadRuntimeReg (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset\r
)\r
{\r
- UINT32 Data;\r
- EFI_STATUS Status;\r
+ UINT32 Data;\r
+ EFI_STATUS Status;\r
\r
ASSERT (Xhc->RTSOff != 0);\r
\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->RTSOff + Offset),\r
+ Xhc->RTSOff + Offset,\r
1,\r
&Data\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
+ DEBUG ((DEBUG_ERROR, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
Data = 0xFFFFFFFF;\r
}\r
\r
**/\r
VOID\r
XhcWriteRuntimeReg (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT32 Data\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset,\r
+ IN UINT32 Data\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
\r
ASSERT (Xhc->RTSOff != 0);\r
\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->RTSOff + Offset),\r
+ Xhc->RTSOff + Offset,\r
1,\r
&Data\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
+ DEBUG ((DEBUG_ERROR, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
}\r
}\r
\r
**/\r
UINT32\r
XhcReadExtCapReg (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset\r
)\r
{\r
- UINT32 Data;\r
- EFI_STATUS Status;\r
+ UINT32 Data;\r
+ EFI_STATUS Status;\r
\r
ASSERT (Xhc->ExtCapRegBase != 0);\r
\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->ExtCapRegBase + Offset),\r
+ Xhc->ExtCapRegBase + Offset,\r
1,\r
&Data\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
+ DEBUG ((DEBUG_ERROR, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
Data = 0xFFFFFFFF;\r
}\r
\r
**/\r
VOID\r
XhcWriteExtCapReg (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT32 Data\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset,\r
+ IN UINT32 Data\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
\r
ASSERT (Xhc->ExtCapRegBase != 0);\r
\r
Xhc->PciIo,\r
EfiPciIoWidthUint32,\r
XHC_BAR_INDEX,\r
- (UINT64) (Xhc->ExtCapRegBase + Offset),\r
+ Xhc->ExtCapRegBase + Offset,\r
1,\r
&Data\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
+ DEBUG ((DEBUG_ERROR, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
}\r
}\r
\r
-\r
/**\r
Set one bit of the runtime register while keeping other bits.\r
\r
**/\r
VOID\r
XhcSetRuntimeRegBit (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT32 Bit\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset,\r
+ IN UINT32 Bit\r
)\r
{\r
- UINT32 Data;\r
+ UINT32 Data;\r
\r
Data = XhcReadRuntimeReg (Xhc, Offset);\r
Data |= Bit;\r
**/\r
VOID\r
XhcClearRuntimeRegBit (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT32 Bit\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset,\r
+ IN UINT32 Bit\r
)\r
{\r
- UINT32 Data;\r
+ UINT32 Data;\r
\r
Data = XhcReadRuntimeReg (Xhc, Offset);\r
Data &= ~Bit;\r
**/\r
VOID\r
XhcSetOpRegBit (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT32 Bit\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset,\r
+ IN UINT32 Bit\r
)\r
{\r
- UINT32 Data;\r
+ UINT32 Data;\r
\r
Data = XhcReadOpReg (Xhc, Offset);\r
Data |= Bit;\r
XhcWriteOpReg (Xhc, Offset, Data);\r
}\r
\r
-\r
/**\r
Clear one bit of the operational register while keeping other bits.\r
\r
**/\r
VOID\r
XhcClearOpRegBit (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT32 Bit\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset,\r
+ IN UINT32 Bit\r
)\r
{\r
- UINT32 Data;\r
+ UINT32 Data;\r
\r
Data = XhcReadOpReg (Xhc, Offset);\r
Data &= ~Bit;\r
Wait the operation register's bit as specified by Bit\r
to become set (or clear).\r
\r
- @param Xhc The XHCI Instance.\r
- @param Offset The offset of the operation register.\r
- @param Bit The bit of the register to wait for.\r
- @param WaitToSet Wait the bit to set or clear.\r
- @param Timeout The time to wait before abort (in millisecond, ms).\r
+ @param Xhc The XHCI Instance.\r
+ @param Offset The offset of the operation register.\r
+ @param Bit The bit of the register to wait for.\r
+ @param WaitToSet Wait the bit to set or clear.\r
+ @param Timeout The time to wait before abort (in millisecond, ms).\r
\r
- @retval EFI_SUCCESS The bit successfully changed by host controller.\r
- @retval EFI_TIMEOUT The time out occurred.\r
+ @retval EFI_SUCCESS The bit successfully changed by host controller.\r
+ @retval EFI_TIMEOUT The time out occurred.\r
+ @retval EFI_OUT_OF_RESOURCES Memory for the timer event could not be allocated.\r
\r
**/\r
EFI_STATUS\r
XhcWaitOpRegBit (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Offset,\r
- IN UINT32 Bit,\r
- IN BOOLEAN WaitToSet,\r
- IN UINT32 Timeout\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Offset,\r
+ IN UINT32 Bit,\r
+ IN BOOLEAN WaitToSet,\r
+ IN UINT32 Timeout\r
)\r
{\r
- UINT32 Index;\r
- UINTN Loop;\r
+ EFI_STATUS Status;\r
+ EFI_EVENT TimeoutEvent;\r
+\r
+ TimeoutEvent = NULL;\r
+\r
+ if (Timeout == 0) {\r
+ return EFI_TIMEOUT;\r
+ }\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_TIMER,\r
+ TPL_CALLBACK,\r
+ NULL,\r
+ NULL,\r
+ &TimeoutEvent\r
+ );\r
\r
- Loop = (Timeout * XHC_1_MILLISECOND / XHC_POLL_DELAY) + 1;\r
+ if (EFI_ERROR (Status)) {\r
+ goto DONE;\r
+ }\r
+\r
+ Status = gBS->SetTimer (\r
+ TimeoutEvent,\r
+ TimerRelative,\r
+ EFI_TIMER_PERIOD_MILLISECONDS (Timeout)\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto DONE;\r
+ }\r
\r
- for (Index = 0; Index < Loop; Index++) {\r
+ do {\r
if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) == WaitToSet) {\r
- return EFI_SUCCESS;\r
+ Status = EFI_SUCCESS;\r
+ goto DONE;\r
}\r
\r
- gBS->Stall (XHC_POLL_DELAY);\r
+ gBS->Stall (XHC_1_MICROSECOND);\r
+ } while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent)));\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+DONE:\r
+ if (TimeoutEvent != NULL) {\r
+ gBS->CloseEvent (TimeoutEvent);\r
}\r
\r
- return EFI_TIMEOUT;\r
+ return Status;\r
}\r
\r
/**\r
**/\r
VOID\r
XhcSetBiosOwnership (\r
- IN USB_XHCI_INSTANCE *Xhc\r
+ IN USB_XHCI_INSTANCE *Xhc\r
)\r
{\r
- UINT32 Buffer;\r
+ UINT32 Buffer;\r
+\r
+ if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
+ return;\r
+ }\r
\r
- DEBUG ((EFI_D_INFO, "XhcSetBiosOwnership: called to set BIOS ownership\n"));\r
+ DEBUG ((DEBUG_INFO, "XhcSetBiosOwnership: called to set BIOS ownership\n"));\r
\r
Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
Buffer = ((Buffer & (~USBLEGSP_OS_SEMAPHORE)) | USBLEGSP_BIOS_SEMAPHORE);\r
**/\r
VOID\r
XhcClearBiosOwnership (\r
- IN USB_XHCI_INSTANCE *Xhc\r
+ IN USB_XHCI_INSTANCE *Xhc\r
)\r
{\r
- UINT32 Buffer;\r
+ UINT32 Buffer;\r
\r
- DEBUG ((EFI_D_INFO, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));\r
+ if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
+ return;\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));\r
\r
Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
Buffer = ((Buffer & (~USBLEGSP_BIOS_SEMAPHORE)) | USBLEGSP_OS_SEMAPHORE);\r
**/\r
UINT32\r
XhcGetCapabilityAddr (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT8 CapId\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT8 CapId\r
)\r
{\r
- UINT32 ExtCapOffset;\r
- UINT8 NextExtCapReg;\r
- UINT32 Data;\r
+ UINT32 ExtCapOffset;\r
+ UINT8 NextExtCapReg;\r
+ UINT32 Data;\r
\r
ExtCapOffset = 0;\r
\r
if ((Data & 0xFF) == CapId) {\r
return ExtCapOffset;\r
}\r
+\r
//\r
// If not, then traverse all of the ext capability registers till finding out it.\r
//\r
ExtCapOffset += (NextExtCapReg << 2);\r
} while (NextExtCapReg != 0);\r
\r
- return 0;\r
+ return 0xFFFFFFFF;\r
}\r
\r
/**\r
**/\r
BOOLEAN\r
XhcIsHalt (\r
- IN USB_XHCI_INSTANCE *Xhc\r
+ IN USB_XHCI_INSTANCE *Xhc\r
)\r
{\r
return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT);\r
}\r
\r
-\r
/**\r
Whether system error occurred.\r
\r
**/\r
BOOLEAN\r
XhcIsSysError (\r
- IN USB_XHCI_INSTANCE *Xhc\r
+ IN USB_XHCI_INSTANCE *Xhc\r
)\r
{\r
return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE);\r
}\r
\r
+/**\r
+ Set USBCMD Host System Error Enable(HSEE) Bit if PCICMD SERR# Enable Bit is set.\r
+\r
+ The USBCMD HSEE Bit will be reset to default 0 by USBCMD Host Controller Reset(HCRST).\r
+ This function is to set USBCMD HSEE Bit if PCICMD SERR# Enable Bit is set.\r
+\r
+ @param Xhc The XHCI Instance.\r
+\r
+**/\r
+VOID\r
+XhcSetHsee (\r
+ IN USB_XHCI_INSTANCE *Xhc\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT16 XhciCmd;\r
+\r
+ PciIo = Xhc->PciIo;\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ PCI_COMMAND_OFFSET,\r
+ sizeof (XhciCmd) / sizeof (UINT16),\r
+ &XhciCmd\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ if ((XhciCmd & EFI_PCI_COMMAND_SERR) != 0) {\r
+ XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_HSEE);\r
+ }\r
+ }\r
+}\r
+\r
/**\r
Reset the XHCI host controller.\r
\r
**/\r
EFI_STATUS\r
XhcResetHC (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Timeout\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Timeout\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
\r
Status = EFI_SUCCESS;\r
\r
- DEBUG ((EFI_D_INFO, "XhcResetHC!\n"));\r
+ DEBUG ((DEBUG_INFO, "XhcResetHC!\n"));\r
//\r
// Host can only be reset when it is halt. If not so, halt it\r
//\r
}\r
}\r
\r
- if (((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) ||\r
- ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) == 0)) {\r
+ if ((Xhc->DebugCapSupOffset == 0xFFFFFFFF) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) ||\r
+ ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) == 0))\r
+ {\r
XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
+ //\r
+ // Some XHCI host controllers require to have extra 1ms delay before accessing any MMIO register during reset.\r
+ // Otherwise there may have the timeout case happened.\r
+ // The below is a workaround to solve such problem.\r
+ //\r
+ gBS->Stall (XHC_1_MILLISECOND);\r
Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // The USBCMD HSEE Bit will be reset to default 0 by USBCMD HCRST.\r
+ // Set USBCMD HSEE Bit if PCICMD SERR# Enable Bit is set.\r
+ //\r
+ XhcSetHsee (Xhc);\r
+ }\r
}\r
\r
return Status;\r
}\r
\r
-\r
/**\r
Halt the XHCI host controller.\r
\r
**/\r
EFI_STATUS\r
XhcHaltHC (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Timeout\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Timeout\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
\r
XhcClearOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, TRUE, Timeout);\r
return Status;\r
}\r
\r
-\r
/**\r
Set the XHCI host controller to run.\r
\r
**/\r
EFI_STATUS\r
XhcRunHC (\r
- IN USB_XHCI_INSTANCE *Xhc,\r
- IN UINT32 Timeout\r
+ IN USB_XHCI_INSTANCE *Xhc,\r
+ IN UINT32 Timeout\r
)\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
\r
XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, FALSE, Timeout);\r
return Status;\r
}\r
-\r