ehci.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,436 行 · 第 1/5 页
C
2,436 行
//
// Create and Init Perodic Frame List
//
Status = EhciGetCapability (
&HcDev->Usb2Hc,
&MaxSpeed,
&PortNumber,
&Is64BitCapable
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto uninstall_usb2hc_protocol;
}
HcDev->Is64BitCapable = Is64BitCapable;
//
// Create and Init Perodic Frame List
//
Status = InitialPeriodicFrameList (
HcDev,
EHCI_MAX_FRAME_LIST_LENGTH
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto uninstall_usb2hc_protocol;
}
//
// Init memory pool management
//
Status = InitialMemoryManagement (HcDev);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto deinit_perodic_frame_list;
}
Status = CreateNULLQH (HcDev);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto deinit_perodic_frame_list;
}
//
// Create AsyncRequest Polling Timer
//
Status = CreatePollingTimer (HcDev, AsyncRequestMoniter);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto deinit_null_qh;
}
//
// Default Maxximum Interrupt Interval is 8,
// it means that 8 micro frame = 1ms
//
//
// Start the Host Controller
//
if (IsEhcHalted (HcDev)) {
Status = StartScheduleExecution (HcDev);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto deinit_timer;
}
}
//
// Set all ports routing to EHC
//
Status = SetPortRoutingEhc (HcDev);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto deinit_timer;
}
//
// Component name protocol
//
Status = EfiLibAddUnicodeString (
"eng",
gEhciComponentName.SupportedLanguages,
&HcDev->ControllerNameTable,
L"Usb Enhanced Host Controller"
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto deinit_timer;
}
goto exit;
//
// Error handle process
//
deinit_timer:
DestoryPollingTimer (HcDev);
deinit_null_qh:
DestroyNULLQH(HcDev);
DeinitialMemoryManagement (HcDev);
deinit_perodic_frame_list:
DeinitialPeriodicFrameList (HcDev);
uninstall_usb2hc_protocol:
gBS->UninstallProtocolInterface (
Controller,
&gEfiUsb2HcProtocolGuid,
&HcDev->Usb2Hc
);
free_pool:
gBS->FreePool (HcDev);
close_pciio_protocol:
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
exit:
return Status;
}
EFI_STATUS
EFIAPI
EhciDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Stop this driver on ControllerHandle. Support stoping any child handles
created by this driver.
Arguments:
This - Protocol instance pointer.
Controller - Handle of device to stop driver on
NumberOfChildren - Number of Children in the ChildHandleBuffer
ChildHandleBuffer - List of handles for the children we need to stop.
Returns:
EFI_SUCCESS Success
EFI_DEVICE_ERROR Fail
--*/
{
EFI_STATUS Status;
EFI_USB2_HC_PROTOCOL *Usb2Hc;
USB2_HC_DEV *HcDev;
//
// Test whether the Controller handler passed in is a valid
// Usb controller handle that should be supported, if not,
// return the error status directly
//
Status = gBS->OpenProtocol (
Controller,
&gEfiUsb2HcProtocolGuid,
&Usb2Hc,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
HcDev = USB2_HC_DEV_FROM_THIS (Usb2Hc);
//
// free all the controller related memory and uninstall UHCI Protocol.
//
Status = gBS->UninstallProtocolInterface (
Controller,
&gEfiUsb2HcProtocolGuid,
Usb2Hc
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
//
// Set Host Controller state as halt
//
Status = Usb2Hc->SetState (
Usb2Hc,
EfiUsbHcStateHalt
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
//
// Stop AsyncRequest Polling Timer
//
Status = StopPollingTimer (HcDev);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
//
// Destroy Asynchronous Request Event
//
DestoryPollingTimer (HcDev);
//
// Destroy Perodic Frame List
//
DeinitialPeriodicFrameList (HcDev);
//
// Destroy NULLQH
//
DestroyNULLQH (HcDev);
//
// Deinit Ehci pool memory management
//
DeinitialMemoryManagement (HcDev);
//
// Denint Unicode String Table
//
EfiLibFreeUnicodeStringTable (HcDev->ControllerNameTable);
//
// Disable the USB Host Controller
//
Status = HcDev->PciIo->Attributes (
HcDev->PciIo,
EfiPciIoAttributeOperationDisable,
EFI_PCI_DEVICE_ENABLE,
NULL
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
gBS->FreePool (HcDev);
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
exit:
return Status;
}
EFI_STATUS
EFIAPI
EhciGetCapability (
IN EFI_USB2_HC_PROTOCOL *This,
OUT UINT8 *MaxSpeed,
OUT UINT8 *PortNumber,
OUT UINT8 *Is64BitCapable
)
/*++
Routine Description:
Retrieves the capablility of root hub ports.
Arguments:
This - A pointer to the EFI_USB_HC_PROTOCOL instance.
MaxSpeed - A pointer to the number of the host controller.
PortNumber - A pointer to the number of the root hub ports.
Is64BitCapable - A pointer to the flag for whether controller supports
64-bit memory addressing.
Returns:
EFI_SUCCESS host controller capability were retrieved successfully.
EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the capabilities.
--*/
{
EFI_STATUS Status;
USB2_HC_DEV *HcDev;
UINT32 HcStructParamsAddr;
UINT32 HcStructParamsReg;
UINT32 HcCapParamsAddr;
UINT32 HcCapParamsReg;
if (MaxSpeed == NULL || PortNumber == NULL || Is64BitCapable == NULL) {
Status = EFI_INVALID_PARAMETER;
goto exit;
}
HcStructParamsAddr = HCSPARAMS;
HcCapParamsAddr = HCCPARAMS;
HcDev = USB2_HC_DEV_FROM_THIS (This);
Status = ReadEhcCapabiltiyReg (
HcDev,
HcStructParamsAddr,
&HcStructParamsReg
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
Status = ReadEhcCapabiltiyReg (
HcDev,
HcCapParamsAddr,
&HcCapParamsReg
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
*MaxSpeed = EFI_USB_SPEED_HIGH;
*PortNumber = (UINT8) (HcStructParamsReg & HCSP_NPORTS);
*Is64BitCapable = (UINT8) (HcCapParamsReg & HCCP_64BIT);
exit:
return Status;
}
EFI_STATUS
EFIAPI
EhciReset (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT16 Attributes
)
/*++
Routine Description:
Provides software reset for the USB host controller.
Arguments:
This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
Attributes - A bit mask of the reset operation to perform.
See below for a list of the supported bit mask values.
#define EFI_USB_HC_RESET_GLOBAL 0x0001
#define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002
#define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004
#define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008
EFI_USB_HC_RESET_GLOBAL
If this bit is set, a global reset signal will be sent to the USB bus.
This resets all of the USB bus logic, including the USB host
controller hardware and all the devices attached on the USB bus.
EFI_USB_HC_RESET_HOST_CONTROLLER
If this bit is set, the USB host controller hardware will be reset.
No reset signal will be sent to the USB bus.
EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
If this bit is set, a global reset signal will be sent to the USB bus.
This resets all of the USB bus logic, including the USB host
controller hardware and all the devices attached on the USB bus.
If this is an EHCI controller and the debug port has configured, then
this is will still reset the host controller.
EFI_USB_HC_RESET_HOST_WITH_DEBUG
If this bit is set, the USB host controller hardware will be reset.
If this is an EHCI controller and the debug port has been configured,
then this will still reset the host controller.
Returns:
EFI_SUCCESS
The reset operation succeeded.
EFI_INVALID_PARAMETER
Attributes is not valid.
EFI_UNSUPPOURTED
The type of reset specified by Attributes is not currently supported by
the host controller hardware.
EFI_ACCESS_DENIED
Reset operation is rejected due to the debug port being configured and
active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
perform reset operation for this host controller.
EFI_DEVICE_ERROR
An error was encountered while attempting to perform
the reset operation.
--*/
{
EFI_STATUS Status;
USB2_HC_DEV *HcDev;
UINTN FrameIndex;
FRAME_LIST_ENTRY *FrameEntryPtr;
HcDev = USB2_HC_DEV_FROM_THIS (This);
switch (Attributes) {
case EFI_USB_HC_RESET_GLOBAL:
//
// Same behavior as Host Controller Reset
//
case EFI_USB_HC_RESET_HOST_CONTROLLER:
//
// Host Controller must be Halt when Reset it
//
if (IsEhcHalted (HcDev)) {
Status = ResetEhc (HcDev);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
//
// Set to zero by Host Controller when reset process completes
//
Status = WaitForEhcReset (HcDev, EHCI_GENERIC_TIMEOUT);
if (EFI_ERROR (Status)) {
Status = EFI_TIMEOUT;
goto exit;
}
} else {
Status = EFI_DEVICE_ERROR;
goto exit;
}
//
// only asynchronous interrupt transfers are always alive on the bus, need to cleanup
//
CleanUpAllAsyncRequestTransfer (HcDev);
Status = ClearEhcAllStatus (HcDev);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
//
// Set appropriate 4G Segment Selector
//
Status = SetCtrlDataStructSeg (HcDev);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
//
// Init Perodic List Base Addr and Frame List
//
Status = SetFrameListBaseAddr (
HcDev,
(UINT32) GET_0B_TO_31B (HcDev->PeriodicFrameListBuffer)
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;
for (FrameIndex = 0; FrameIndex < HcDev->PeriodicFrameListLength; FrameIndex++) {
FrameEntryPtr->LinkTerminate = TRUE;
FrameEntryPtr++;
}
//
// Start the Host Controller
//
if (IsEhcHalted (HcDev)) {
Status = StartScheduleExecution (HcDev);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
}
//
// Set all ports routing to EHC
//
Status = SetPortRoutingEhc (HcDev);
if (EFI_ERROR (Status)) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?