📄 uhci.c
字号:
gBS->FreePool(HcDev);
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_OUT_OF_RESOURCES ;
}
//
// Init interrupt list head in the HcDev structure.
//
InitializeListHead (&(HcDev->InterruptListHead)) ;
//
// Create timer for interrupt transfer result polling
//
Status = gBS->CreateEvent (
EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
EFI_TPL_NOTIFY,
MonitorInterruptTrans,
HcDev,
&HcDev->InterruptTransTimer
) ;
if (EFI_ERROR(Status)) {
FreeFrameListEntry(HcDev);
gBS->UninstallProtocolInterface(
Controller,
&gEfiUsbHcProtocolGuid,
&HcDev->UsbHc
) ;
if(HcDev != NULL) {
gBS->FreePool(HcDev);
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_UNSUPPORTED;
}
//
// Here set interrupt transfer polling timer in 50ms unit.
//
Status = gBS->SetTimer(HcDev->InterruptTransTimer, TimerPeriodic, 50*1000*10);
if (EFI_ERROR(Status)) {
gBS->CloseEvent(HcDev->InterruptTransTimer);
FreeFrameListEntry(HcDev);
gBS->UninstallProtocolInterface(
Controller,
&gEfiUsbHcProtocolGuid,
&HcDev->UsbHc
) ;
if(HcDev != NULL) {
gBS->FreePool(HcDev);
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_UNSUPPORTED;
}
//
// QH,TD structures must in common buffer that will be
// accessed by both cpu and usb bus master at the same time.
// so, there must has memory management for QH,TD structures.
//
Status = InitializeMemoryManagement (HcDev);
if (EFI_ERROR(Status)) {
gBS->SetTimer(HcDev->InterruptTransTimer,TimerCancel, 0) ;
gBS->CloseEvent(HcDev->InterruptTransTimer);
FreeFrameListEntry(HcDev);
gBS->UninstallProtocolInterface(
Controller,
&gEfiUsbHcProtocolGuid,
&HcDev->UsbHc
) ;
if(HcDev != NULL) {
gBS->FreePool(HcDev);
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
}
//
// component name protocol.
//
HcDev->ControllerNameTable = NULL;
EfiLibAddUnicodeString (
"eng",
gUhciComponentName.SupportedLanguages,
&HcDev->ControllerNameTable,
L"Usb Universal Host Controller"
);
return EFI_SUCCESS ;
}
EFI_STATUS
UnInstallUHCInterface(
IN EFI_HANDLE Controller,
IN EFI_USB_HC_PROTOCOL *This
)
{
USB_HC_DEV *HcDev ;
HcDev = USB_HC_DEV_FROM_THIS(This) ;
gBS->UninstallProtocolInterface(
Controller,
&gEfiUsbHcProtocolGuid,
&HcDev->UsbHc
) ;
//
// first stop USB Host Controller
//
This->SetState (This,EfiUsbHcStateHalt);
//
// Delete interrupt transfer polling timer
//
gBS->SetTimer(HcDev->InterruptTransTimer,TimerCancel, 0) ;
gBS->CloseEvent(HcDev->InterruptTransTimer) ;
//
// Delete all the asynchronous interrupt transfers in the interrupt list
// and free associated memory
//
ReleaseInterruptList(HcDev,&(HcDev->InterruptListHead)) ;
//
// free Frame List Entry.
//
FreeFrameListEntry(HcDev);
//
// Free common buffer allocated for QH,TD structures
//
DelMemoryManagement (HcDev);
if (HcDev->ControllerNameTable) {
EfiLibFreeUnicodeStringTable (HcDev->ControllerNameTable);
}
//
// Disable the USB Host Controller
//
HcDev->PciIo->Attributes (
HcDev->PciIo,
EfiPciIoAttributeOperationDisable,
EFI_PCI_DEVICE_ENABLE,
NULL
);
gBS->FreePool(HcDev) ;
return EFI_SUCCESS ;
}
EFI_STATUS
UHCIDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
EFI_USB_HC_PROTOCOL *UsbHc;
EFI_STATUS OpenStatus;
OpenStatus = gBS->OpenProtocol(
Controller,
&gEfiUsbHcProtocolGuid,
&UsbHc,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
//
// Test whether the Controller handler passed in is a valid
// Usb controller handle that should be supported, if not,
// return the error status directly
//
if (EFI_ERROR (OpenStatus)) {
return OpenStatus;
}
//
// free all the controller related memory and uninstall UHCI Protocol.
//
UnInstallUHCInterface(Controller,UsbHc);
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_SUCCESS;
}
EFI_STATUS
UHCIReset(
IN EFI_USB_HC_PROTOCOL *This,
IN UINT16 Attributes
)
/*++
Routine Description:
Provides software reset for the USB host controller.
Arguments:
This A pointer to the EFI_USB_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
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.
Returns:
EFI_SUCCESS
The reset operation succeeded.
EFI_INVALID_PARAMETER
Attributes is not valid.
EFI_DEVICE_ERROR
An error was encountered while attempting to perform
the reset operation.
--*/
{
BOOLEAN Match;
USB_HC_DEV *HcDev;
UINT32 CommandRegAddr;
UINT32 FlBaseAddrReg;
UINT16 Command;
Match = FALSE;
HcDev = USB_HC_DEV_FROM_THIS(This);
CommandRegAddr = (UINT32)(USBCMD);
FlBaseAddrReg = (UINT32)(USBFLBASEADD);
if ((Attributes & EFI_USB_HC_RESET_GLOBAL) != 0) {
Match = TRUE;
//
// set the Global Reset bit in the command register
//
Command = ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr);
Command |= USBCMD_GRESET;
WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr,Command);
//
// wait 20ms to let reset complete
// (the UHCI spec asks for a minimum of 10ms to let reset complete)
//
gBS->Stall(20000);
//
// Clear the Global Reset bit to zero.
//
Command &= ~USBCMD_GRESET;
WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr,Command);
gBS->Stall(10000);
}
if ((Attributes & EFI_USB_HC_RESET_HOST_CONTROLLER) != 0) {
Match = TRUE;
//
// set Host Controller Reset bit to 1
//
Command = ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr);
Command |= USBCMD_HCRESET;
WriteUHCCommandReg(HcDev->PciIo,CommandRegAddr,Command);
//
// this bit will be reset by Host Controller when reset is completed.
//
gBS->Stall(10000); // wait 10ms to let reset complete
}
if (!Match) {
return EFI_INVALID_PARAMETER;
}
//
// Delete all old transactions on the USB bus
//
CleanUsbTransactions (HcDev);
//
// Initialize Universal Host Controller's Frame List Data Structure
//
InitFrameList (HcDev);
//
// Reset may cause Frame List Base Address Register reset to zero,
// so set the original value back again.
//
SetFrameListBaseAddress(
HcDev->PciIo,
FlBaseAddrReg,
(UINT32)((UINTN)HcDev->FrameListEntry)
);
return EFI_SUCCESS;
}
EFI_STATUS
UHCIGetState (
IN EFI_USB_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_USB_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.
--*/
{
USB_HC_DEV *HcDev;
UINT32 CommandRegAddr;
UINT32 StatusRegAddr;
UINT16 UhcCommand;
UINT16 UhcStatus;
if (State == NULL) {
return EFI_INVALID_PARAMETER;
}
HcDev = USB_HC_DEV_FROM_THIS(This);
CommandRegAddr = (UINT32)(USBCMD);
StatusRegAddr = (UINT32)(USBSTS);
UhcCommand = ReadUHCCommandReg(HcDev->PciIo,CommandRegAddr);
UhcStatus = ReadUHCCommandReg(HcDev->PciIo,StatusRegAddr);
if (UhcCommand & USBCMD_EGSM) {
*State = EfiUsbHcStateSuspend;
return EFI_SUCCESS;
}
if ((UhcStatus & USBSTS_HCH) == 0) {
*State = EfiUsbHcStateOperational;
} else {
*State = EfiUsbHcStateHalt;
}
return EFI_SUCCESS;
}
EFI_STATUS
UHCISetState (
IN EFI_USB_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_USB_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.
--*/
{
USB_HC_DEV *HcDev;
UINT32 CommandRegAddr;
UINT32 StatusRegAddr;
UINT16 Command;
EFI_USB_HC_STATE CurrentState;
EFI_STATUS Status;
HcDev = USB_HC_DEV_FROM_THIS(This) ;
CommandRegAddr = (UINT32)(USBCMD);
StatusRegAddr = (UINT32)(USBSTS);
Status = UHCIGetState (This,&CurrentState);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -