/** Reset the XHCI host controller. @param Xhc The XHCI Instance. @param Timeout Time to wait before abort (in microsecond, us). @retval EFI_SUCCESS The XHCI host controller is reset. @return Others Failed to reset the XHCI before Timeout. **/ EFI_STATUS XhcResetHC ( IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Timeout ) { EFI_STATUS Status; Status = EFI_SUCCESS; DEBUG ((EFI_D_INFO, "XhcResetHC!\n")); // // Host can only be reset when it is halt. If not so, halt it // if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) { Status = XhcHaltHC (Xhc, Timeout); if (EFI_ERROR (Status)) { return Status; } } if ((Xhc->DebugCapSupOffset == 0xFFFFFFFF) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) == 0)) { XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET); Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout); } return Status; }
/** Set the XHCI host controller to run. @param Xhc The XHCI Instance. @param Timeout Time to wait before abort (in millisecond, ms). @return EFI_SUCCESS The XHCI host controller is running. @return EFI_TIMEOUT Failed to set the XHCI to run before Timeout. **/ EFI_STATUS XhcRunHC ( IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Timeout ) { EFI_STATUS Status; XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN); Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, FALSE, Timeout); return Status; }
/** Reset the XHCI host controller. @param Xhc The XHCI Instance. @param Timeout Time to wait before abort (in millisecond, ms). @retval EFI_SUCCESS The XHCI host controller is reset. @return Others Failed to reset the XHCI before Timeout. **/ EFI_STATUS XhcResetHC ( IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Timeout ) { EFI_STATUS Status; DEBUG ((EFI_D_INFO, "XhcResetHC!\n")); // // Host can only be reset when it is halt. If not so, halt it // if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) { Status = XhcHaltHC (Xhc, Timeout); if (EFI_ERROR (Status)) { return Status; } } XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET); Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout); return Status; }
/** Reset the XHCI host controller. @param Xhc The XHCI Instance. @param Timeout Time to wait before abort (in millisecond, ms). @retval EFI_SUCCESS The XHCI host controller is reset. @return Others Failed to reset the XHCI before Timeout. **/ EFI_STATUS XhcResetHC ( IN USB_XHCI_INSTANCE *Xhc, IN UINT32 Timeout ) { EFI_STATUS Status; Status = EFI_SUCCESS; DEBUG ((EFI_D_INFO, "XhcResetHC!\n")); // // Host can only be reset when it is halt. If not so, halt it // if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) { Status = XhcHaltHC (Xhc, Timeout); if (EFI_ERROR (Status)) { return Status; } } if ((Xhc->DebugCapSupOffset == 0xFFFFFFFF) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) == 0)) { XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET); // // Some XHCI host controllers require to have extra 1ms delay before accessing any MMIO register during reset. // Otherwise there may have the timeout case happened. // The below is a workaround to solve such problem. // gBS->Stall (XHC_1_MILLISECOND); Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout); } return Status; }