ehci.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 2,436 行 · 第 1/5 页
C
2,436 行
Status = EFI_DEVICE_ERROR;
goto exit;
}
break;
case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:
Status = EFI_UNSUPPORTED;
break;
case EFI_USB_HC_RESET_HOST_WITH_DEBUG:
Status = EFI_UNSUPPORTED;
break;
default:
Status = EFI_INVALID_PARAMETER;
}
exit:
return Status;
}
EFI_STATUS
EFIAPI
EhciGetState (
IN EFI_USB2_HC_PROTOCOL *This,
OUT EFI_USB_HC_STATE *State
)
/*++
Routine Description:
Retrieves current state of the USB host controller.
Arguments:
This A pointer to the EFI_USB2_HC_PROTOCOL instance.
State A pointer to the EFI_USB_HC_STATE data structure that
indicates current state of the USB host controller.
Type EFI_USB_HC_STATE is defined below.
typedef enum {
EfiUsbHcStateHalt,
EfiUsbHcStateOperational,
EfiUsbHcStateSuspend,
EfiUsbHcStateMaximum
} EFI_USB_HC_STATE;
Returns:
EFI_SUCCESS
The state information of the host controller was returned in State.
EFI_INVALID_PARAMETER
State is NULL.
EFI_DEVICE_ERROR
An error was encountered while attempting to retrieve the
host controller's current state.
--*/
{
EFI_STATUS Status;
USB2_HC_DEV *HcDev;
UINT32 UsbStatusAddr;
UINT32 UsbStatusReg;
if (State == NULL) {
Status = EFI_INVALID_PARAMETER;
goto exit;
}
UsbStatusAddr = USBSTS;
HcDev = USB2_HC_DEV_FROM_THIS (This);
Status = ReadEhcOperationalReg (
HcDev,
UsbStatusAddr,
&UsbStatusReg
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
if (UsbStatusReg & USBSTS_HCH) {
*State = EfiUsbHcStateHalt;
} else {
*State = EfiUsbHcStateOperational;
}
exit:
return Status;
}
EFI_STATUS
EFIAPI
EhciSetState (
IN EFI_USB2_HC_PROTOCOL *This,
IN EFI_USB_HC_STATE State
)
/*++
Routine Description:
Sets the USB host controller to a specific state.
Arguments:
This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
State - Indicates the state of the host controller that will be set.
Returns:
EFI_SUCCESS
The USB host controller was successfully placed in the state
specified by State.
EFI_INVALID_PARAMETER
State is invalid.
EFI_DEVICE_ERROR
Failed to set the state specified by State due to device error.
--*/
{
EFI_STATUS Status;
USB2_HC_DEV *HcDev;
UINT32 UsbCommandAddr;
UINT32 UsbCommandReg;
EFI_USB_HC_STATE CurrentState;
UsbCommandAddr = USBCMD;
HcDev = USB2_HC_DEV_FROM_THIS (This);
Status = EhciGetState (This, &CurrentState);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
switch (State) {
case EfiUsbHcStateHalt:
if (EfiUsbHcStateHalt == CurrentState) {
Status = EFI_SUCCESS;
goto exit;
} else if (EfiUsbHcStateOperational == CurrentState) {
Status = ReadEhcOperationalReg (
HcDev,
UsbCommandAddr,
&UsbCommandReg
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
UsbCommandReg &= ~USBCMD_RS;
Status = WriteEhcOperationalReg (
HcDev,
UsbCommandAddr,
UsbCommandReg
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
//
// Ensure the HC is in halt status after send the stop command
//
Status = WaitForEhcHalt (HcDev, EHCI_GENERIC_TIMEOUT);
if (EFI_ERROR (Status)) {
Status = EFI_TIMEOUT;
goto exit;
}
}
break;
case EfiUsbHcStateOperational:
if (IsEhcSysError (HcDev)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
if (EfiUsbHcStateOperational == CurrentState) {
Status = EFI_SUCCESS;
goto exit;
} else if (EfiUsbHcStateHalt == CurrentState) {
//
// Set Host Controller Run
//
Status = ReadEhcOperationalReg (
HcDev,
UsbCommandAddr,
&UsbCommandReg
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
UsbCommandReg |= USBCMD_RS;
Status = WriteEhcOperationalReg (
HcDev,
UsbCommandAddr,
UsbCommandReg
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
}
break;
case EfiUsbHcStateSuspend:
Status = EFI_UNSUPPORTED;
break;
default:
Status = EFI_INVALID_PARAMETER;
}
exit:
return Status;
}
EFI_STATUS
EFIAPI
EhciGetRootHubPortStatus (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 PortNumber,
OUT EFI_USB_PORT_STATUS *PortStatus
)
/*++
Routine Description:
Retrieves the current status of a USB root hub port.
Arguments:
This - A pointer to the EFI_USB2_HC_PROTOCOL.
PortNumber - Specifies the root hub port from which the status
is to be retrieved. This value is zero-based. For example,
if a root hub has two ports, then the first port is numbered 0,
and the second port is numbered 1.
PortStatus - A pointer to the current port status bits and
port status change bits.
Returns:
EFI_SUCCESS The status of the USB root hub port specified
by PortNumber was returned in PortStatus.
EFI_INVALID_PARAMETER PortNumber is invalid.
EFI_DEVICE_ERROR Can't read register
--*/
{
EFI_STATUS Status;
USB2_HC_DEV *HcDev;
UINT32 PortStatusControlAddr;
UINT32 PortStatusControlReg;
UINT8 MaxSpeed;
UINT8 TotalPortNumber;
UINT8 Is64BitCapable;
if (PortStatus == NULL) {
Status = EFI_INVALID_PARAMETER;
goto exit;
}
EhciGetCapability (
This,
&MaxSpeed,
&TotalPortNumber,
&Is64BitCapable
);
if (PortNumber >= TotalPortNumber) {
Status = EFI_INVALID_PARAMETER;
goto exit;
}
HcDev = USB2_HC_DEV_FROM_THIS (This);
PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));
//
// Clear port status
//
PortStatus->PortStatus = 0;
PortStatus->PortChangeStatus = 0;
Status = ReadEhcOperationalReg (
HcDev,
PortStatusControlAddr,
&PortStatusControlReg
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
//
// Fill Port Status bits
//
//
// Current Connect Status
//
if (PORTSC_CCS & PortStatusControlReg) {
PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
}
//
// Port Enabled/Disabled
//
if (PORTSC_PED & PortStatusControlReg) {
PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
}
//
// Port Suspend
//
if (PORTSC_SUSP & PortStatusControlReg) {
PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
}
//
// Over-current Active
//
if (PORTSC_OCA & PortStatusControlReg) {
PortStatus->PortStatus |= USB_PORT_STAT_OVERCURRENT;
}
//
// Port Reset
//
if (PORTSC_PR & PortStatusControlReg) {
PortStatus->PortStatus |= USB_PORT_STAT_RESET;
}
//
// Port Power
//
if (PORTSC_PP & PortStatusControlReg) {
PortStatus->PortStatus |= USB_PORT_STAT_POWER;
}
//
// Port Owner
//
if (PORTSC_PO & PortStatusControlReg) {
PortStatus->PortStatus |= USB_PORT_STAT_OWNER;
}
//
// Identify device speed
//
if (PORTSC_LS_KSTATE & PortStatusControlReg) {
//
// Low Speed Device Attached
//
PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
} else {
//
// Not Low Speed Device Attached
//
if ((PORTSC_CCS & PortStatusControlReg) && (PORTSC_CSC & PortStatusControlReg)) {
HcDev->DeviceSpeed[PortNumber] = IsHighSpeedDevice (This, PortNumber) ? USB_PORT_STAT_HIGH_SPEED : 0;
}
PortStatus->PortStatus |= HcDev->DeviceSpeed[PortNumber];
}
//
// Fill Port Status Change bits
//
//
// Connect Status Change
//
if (PORTSC_CSC & PortStatusControlReg) {
PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
}
//
// Port Enabled/Disabled Change
//
if (PORTSC_PEDC & PortStatusControlReg) {
PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
}
//
// Port Over Current Change
//
if (PORTSC_OCC & PortStatusControlReg) {
PortStatus->PortChangeStatus |= USB_PORT_STAT_C_OVERCURRENT;
}
exit:
return Status;
}
EFI_STATUS
EFIAPI
EhciSetRootHubPortFeature (
IN EFI_USB2_HC_PROTOCOL *This,
IN UINT8 PortNumber,
IN EFI_USB_PORT_FEATURE PortFeature
)
/*++
Routine Description:
Sets a feature for the specified root hub port.
Arguments:
This - A pointer to the EFI_USB2_HC_PROTOCOL.
PortNumber - Specifies the root hub port whose feature
is requested to be set.
PortFeature - Indicates the feature selector associated
with the feature set request.
Returns:
EFI_SUCCESS
The feature specified by PortFeature was set for the
USB root hub port specified by PortNumber.
EFI_INVALID_PARAMETER
PortNumber is invalid or PortFeature is invalid.
EFI_DEVICE_ERROR
Can't read register
--*/
{
EFI_STATUS Status;
USB2_HC_DEV *HcDev;
UINT32 PortStatusControlAddr;
UINT32 PortStatusControlReg;
UINT8 MaxSpeed;
UINT8 TotalPortNumber;
UINT8 Is64BitCapable;
EhciGetCapability (
This,
&MaxSpeed,
&TotalPortNumber,
&Is64BitCapable
);
if (PortNumber >= TotalPortNumber) {
Status = EFI_INVALID_PARAMETER;
goto exit;
}
HcDev = USB2_HC_DEV_FROM_THIS (This);
PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));
Status = ReadEhcOperationalReg (
HcDev,
PortStatusControlAddr,
&PortStatusControlReg
);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
switch (PortFeature) {
case EfiUsbPortEnable:
//
// Sofeware can't set this bit, Port can only be enable by the Host Controller
// as a part of the reset and enable
//
PortStatusControlReg &= 0xffffffd5;
PortStatusControlReg |= PORTSC_PED;
break;
case EfiUsbPortSuspend:
PortStatusControlReg &= 0xffffffd5;
PortStatusControlReg |= PORTSC_SUSP;
break;
case EfiUsbPortReset:
//
// Make sure Host Controller not halt before reset it
//
if (IsEhcHalted (HcDev)) {
Status = StartScheduleExecution (HcDev);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto exit;
}
Status = WaitForEhcNotHalt (HcDev, EHCI_GENERIC_TIMEOUT);
if (EFI_ERROR (Status)) {
DEBUG ((gEHCDebugLevel, "EHCI: WaitForEhcNotHalt TimeOut\n"));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?