📄 uhci.c
字号:
/*++
Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
This software and associated documentation (if any) is furnished
under a license and may only be used or copied in accordance
with the terms of the license. Except as permitted by such
license, no part of this software or documentation may be
reproduced, stored in a retrieval system, or transmitted in any
form or by any means without the express written consent of
Intel Corporation.
Module Name:
Uhci.c
Abstract:
Revision History
--*/
#include "Efi.h"
#include "EfiDriverLib.h"
#include "uhci.h"
//
// Prototypes
// Driver model protocol interface
//
EFI_STATUS
UHCIDriverEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
EFI_STATUS
UHCIDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
UHCIDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
EFI_STATUS
UHCIDriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
//
// UHCI interface functions
//
EFI_STATUS
UHCIReset(
IN EFI_USB_HC_PROTOCOL *This,
IN UINT16 Attributes
);
EFI_STATUS
UHCIGetState (
IN EFI_USB_HC_PROTOCOL *This,
OUT EFI_USB_HC_STATE *State
);
EFI_STATUS
UHCISetState (
IN EFI_USB_HC_PROTOCOL *This,
IN EFI_USB_HC_STATE State
);
EFI_STATUS
UHCIControlTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaximumPacketLength,
IN EFI_USB_DEVICE_REQUEST *Request,
IN EFI_USB_DATA_DIRECTION TransferDirection,
IN OUT VOID *Data OPTIONAL,
IN OUT UINTN *DataLength OPTIONAL,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
);
EFI_STATUS
UHCIBulkTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 MaximumPacketLength,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
);
EFI_STATUS
UHCIAsyncInterruptTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaxiumPacketLength,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle OPTIONAL,
IN UINTN PollingInterval OPTIONAL,
IN UINTN DataLength OPTIONAL,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction OPTIONAL,
IN VOID *Context OPTIONAL
);
EFI_STATUS
UHCISyncInterruptTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN BOOLEAN IsSlowDevice,
IN UINT8 MaximumPacketLength,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
);
EFI_STATUS
UHCIIsochronousTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 MaximumPacketLength,
IN OUT VOID *Data,
IN OUT UINTN DataLength,
OUT UINT32 *TransferResult
);
EFI_STATUS
UHCIAsyncIsochronousTransfer (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN UINT8 MaximumPacketLength,
IN OUT VOID *Data,
IN UINTN DataLength,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
IN VOID *Context OPTIONAL
);
EFI_STATUS
UHCIGetRootHubPortNumber (
IN EFI_USB_HC_PROTOCOL *This,
OUT UINT8 *PortNumber
);
EFI_STATUS
UHCIGetRootHubPortStatus (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 PortNumber,
OUT EFI_USB_PORT_STATUS *PortStatus
);
EFI_STATUS
UHCISetRootHubPortFeature (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 PortNumber,
IN EFI_USB_PORT_FEATURE PortFeature
);
EFI_STATUS
UHCIClearRootHubPortFeature (
IN EFI_USB_HC_PROTOCOL *This,
IN UINT8 PortNumber,
IN EFI_USB_PORT_FEATURE PortFeature
);
//
// Asynchronous interrupt transfer monitor function
//
VOID
MonitorInterruptTrans(
IN EFI_EVENT Event,
IN VOID *Context
);
//
// UHCI Driver Global Variables
//
EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding = {
UHCIDriverBindingSupported,
UHCIDriverBindingStart,
UHCIDriverBindingStop,
0x10,
NULL,
NULL
};
EFI_DRIVER_ENTRY_POINT(UHCIDriverEntryPoint)
EFI_STATUS
UHCIDriverEntryPoint(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
return EfiLibInstallAllDriverProtocols (
ImageHandle,
SystemTable,
&gUhciDriverBinding,
ImageHandle,
&gUhciComponentName,
NULL,
NULL
);
}
EFI_STATUS
UHCIDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
EFI_STATUS OpenStatus;
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
USB_CLASSC UsbClassCReg;
//
// Test whether there is PCI IO Protocol attached on the controller handle.
//
OpenStatus = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
&PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (OpenStatus)) {
return OpenStatus;
}
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8,
CLASSC,sizeof(USB_CLASSC) / sizeof(UINT8),
&UsbClassCReg
);
if (EFI_ERROR(Status)) {
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_UNSUPPORTED;
}
//
// Test whether the controller belongs to UHCI type
//
if ((UsbClassCReg.BaseCode != PCI_CLASSC_BASE_CLASS_SERIAL)
|| (UsbClassCReg.SubClassCode != PCI_CLASSC_SUBCLASS_SERIAL_USB)
|| (UsbClassCReg.PI != PCI_CLASSC_PI_UHCI)) {
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_UNSUPPORTED;
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_SUCCESS;
}
EFI_STATUS
UHCIDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
EFI_STATUS Status;
UINTN FlBaseAddrReg;
EFI_PCI_IO_PROTOCOL *PciIo;
USB_HC_DEV *HcDev;
HcDev = NULL;
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
&PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Turn off USB emulation
//
TurnOffUSBEmulation (PciIo);
//
// Enable the USB Host Controller
//
Status = PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationEnable,
EFI_PCI_DEVICE_ENABLE,
NULL
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_UNSUPPORTED;
}
EnableUhc (PciIo);
//
// allocate memory for UHC private data structure
//
Status = gBS->AllocatePool(
EfiBootServicesData,
sizeof(USB_HC_DEV),
&HcDev
);
if(EFI_ERROR(Status)) {
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return EFI_OUT_OF_RESOURCES;
}
EfiZeroMem(HcDev,sizeof(USB_HC_DEV));
//
// init EFI_USB_HC_PROTOCOL protocol interface and install the protocol
//
HcDev->UsbHc.Reset = UHCIReset;
HcDev->UsbHc.GetState = UHCIGetState;
HcDev->UsbHc.SetState = UHCISetState;
HcDev->UsbHc.ControlTransfer = UHCIControlTransfer;
HcDev->UsbHc.BulkTransfer = UHCIBulkTransfer;
HcDev->UsbHc.AsyncInterruptTransfer = UHCIAsyncInterruptTransfer;
HcDev->UsbHc.SyncInterruptTransfer = UHCISyncInterruptTransfer;
HcDev->UsbHc.IsochronousTransfer = UHCIIsochronousTransfer;
HcDev->UsbHc.AsyncIsochronousTransfer = UHCIAsyncIsochronousTransfer;
HcDev->UsbHc.GetRootHubPortNumber = UHCIGetRootHubPortNumber;
HcDev->UsbHc.GetRootHubPortStatus = UHCIGetRootHubPortStatus;
HcDev->UsbHc.SetRootHubPortFeature = UHCISetRootHubPortFeature;
HcDev->UsbHc.ClearRootHubPortFeature = UHCIClearRootHubPortFeature;
HcDev->UsbHc.MajorRevision = 0x1; // indicate usb1.1
HcDev->UsbHc.MinorRevision = 0x1; //
//
// Install Host Controller Protocol
//
Status = gBS->InstallProtocolInterface (
&Controller,
&gEfiUsbHcProtocolGuid,
EFI_NATIVE_INTERFACE,
&HcDev->UsbHc
);
if (EFI_ERROR(Status)) {
if(HcDev != NULL) {
gBS->FreePool(HcDev);
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
}
//
// Init UHCI private data structures
//
HcDev->Signature = USB_HC_DEV_SIGNATURE;
HcDev->PciIo = PciIo;
FlBaseAddrReg = USBFLBASEADD;
//
// Allocate and Init Host Controller's Frame List Entry
//
Status = CreateFrameList (HcDev,(UINT32)FlBaseAddrReg);
if (EFI_ERROR(Status)) {
gBS->UninstallProtocolInterface(
Controller,
&gEfiUsbHcProtocolGuid,
&HcDev->UsbHc
) ;
if(HcDev != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -