summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorljin6 <ljin6@6f19259b-4bc3-4df7-8a09-765794883524>2006-07-18 04:13:40 +0000
committerljin6 <ljin6@6f19259b-4bc3-4df7-8a09-765794883524>2006-07-18 04:13:40 +0000
commit562d28495df348923812281161e64bc9514e15e6 (patch)
tree121f4f3c37c23b23a4dabe21cf4fc46c78a0c5b3
parent4b9fc76f7bba0d847d36cb2070a2d3305ae87acc (diff)
downloadedk2-platforms-562d28495df348923812281161e64bc9514e15e6.tar.xz
Add DevicePathUtilities DevicePathToText DevciePathFromText USB2HostController protocols
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1037 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--EdkModulePkg/Bus/Pci/Ehci/Dxe/ComponentName.c189
-rw-r--r--EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c2821
-rw-r--r--EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.h2689
-rw-r--r--EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.msa87
-rw-r--r--EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciMem.c761
-rw-r--r--EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c1539
-rw-r--r--EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciSched.c3072
-rw-r--r--EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.msa3
-rw-r--r--EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c148
-rw-r--r--EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.c1577
-rw-r--r--EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.h1733
-rw-r--r--EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c2
-rw-r--r--EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.msa5
-rw-r--r--EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c2578
-rw-r--r--EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.h913
-rw-r--r--EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c190
-rw-r--r--EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.c18
-rw-r--r--EdkModulePkg/EdkModulePkg.spd2
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c107
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h422
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa109
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c2434
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c1526
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c421
-rw-r--r--EdkNt32Pkg/Nt32.fpd159
-rw-r--r--MdePkg/Include/Guid/PcAnsi.h10
-rw-r--r--MdePkg/Include/IndustryStandard/Usb.h3
-rw-r--r--MdePkg/Include/Protocol/DevicePathFromText.h4
-rw-r--r--MdePkg/Include/Protocol/Usb2HostController.h22
-rw-r--r--MdePkg/Include/Uefi/UefiSpec.h30
30 files changed, 22377 insertions, 1197 deletions
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/ComponentName.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/ComponentName.c
new file mode 100644
index 0000000000..e0d2010cd4
--- /dev/null
+++ b/EdkModulePkg/Bus/Pci/Ehci/Dxe/ComponentName.c
@@ -0,0 +1,189 @@
+/*++
+
+Copyright 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+
+#include "Ehci.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+EhciComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+EhciComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle, OPTIONAL
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+//
+// EFI Component Name Protocol
+//
+EFI_COMPONENT_NAME_PROTOCOL gEhciComponentName = {
+ EhciComponentNameGetDriverName,
+ EhciComponentNameGetControllerName,
+ "eng"
+};
+
+static EFI_UNICODE_STRING_TABLE mEhciDriverNameTable[] = {
+ { "eng", L"UEFI Usb Ehci Driver" },
+ { NULL , NULL }
+};
+
+EFI_STATUS
+EFIAPI
+EhciComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ DriverName - A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return LookupUnicodeString (
+ Language,
+ gEhciComponentName.SupportedLanguages,
+ mEhciDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+EhciComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle, OPTIONAL
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ ControllerName - A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language
+ specified by Language from the point of view of the
+ driver specified by This.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the user readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ EFI_STATUS Status;
+ USB2_HC_DEV *EhciDev;
+ EFI_USB2_HC_PROTOCOL *Usb2Hc;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Get the device context
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUsb2HcProtocolGuid,
+ (VOID **) &Usb2Hc,
+ gEhciDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ EhciDev = USB2_HC_DEV_FROM_THIS (Usb2Hc);
+
+ return LookupUnicodeString (
+ Language,
+ gEhciComponentName.SupportedLanguages,
+ EhciDev->ControllerNameTable,
+ ControllerName
+ );
+
+}
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c
new file mode 100644
index 0000000000..e7d359ee24
--- /dev/null
+++ b/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c
@@ -0,0 +1,2821 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Ehci.c
+
+Abstract:
+
+
+Revision History
+--*/
+
+
+#include "Ehci.h"
+
+UINTN gEHCDebugLevel = EFI_D_INFO;
+UINTN gEHCErrorLevel = EFI_D_ERROR;
+
+//
+// Prototypes
+// Driver model protocol interface
+//
+
+EFI_STATUS
+EFIAPI
+EhciDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+EhciDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+EFIAPI
+EhciDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// Ehci protocol interface
+//
+EFI_STATUS
+EFIAPI
+EhciGetCapability (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ OUT UINT8 *MaxSpeed,
+ OUT UINT8 *PortNumber,
+ OUT UINT8 *Is64BitCapable
+ );
+
+EFI_STATUS
+EFIAPI
+EhciReset (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT16 Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+EhciGetState (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ OUT EFI_USB_HC_STATE *State
+ );
+
+EFI_STATUS
+EFIAPI
+EhciSetState (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN EFI_USB_HC_STATE State
+ );
+
+EFI_STATUS
+EFIAPI
+EhciControlTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ );
+
+EFI_STATUS
+EFIAPI
+EhciBulkTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ );
+
+EFI_STATUS
+EFIAPI
+EhciAsyncInterruptTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaxiumPacketLength,
+ IN BOOLEAN IsNewTransfer,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN PollingInterval,
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
+ IN VOID *Context OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+EhciSyncInterruptTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ );
+
+EFI_STATUS
+EFIAPI
+EhciIsochronousTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ );
+
+EFI_STATUS
+EFIAPI
+EhciAsyncIsochronousTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
+ IN VOID *Context
+ );
+
+EFI_STATUS
+EFIAPI
+EhciGetRootHubPortStatus (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus
+ );
+
+EFI_STATUS
+EFIAPI
+EhciSetRootHubPortFeature (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ );
+
+EFI_STATUS
+EFIAPI
+EhciClearRootHubPortFeature (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ );
+
+//
+// Ehci Driver Global Variables
+//
+EFI_DRIVER_BINDING_PROTOCOL gEhciDriverBinding = {
+ EhciDriverBindingSupported,
+ EhciDriverBindingStart,
+ EhciDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+UINT32 mUsbCapabilityLen;
+UINT32 mDeviceSpeed[16];
+
+EFI_STATUS
+EFIAPI
+EhciDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Test to see if this driver supports ControllerHandle. Any ControllerHandle
+ that has Usb2HcProtocol installed will be supported.
+
+ Arguments:
+
+ This - Protocol instance pointer.
+ Controlle - Handle of device to test
+ RemainingDevicePath - Not used
+
+ Returns:
+
+ EFI_SUCCESS This driver supports this device.
+ EFI_UNSUPPORTED This driver does not support this device.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ USB_CLASSC UsbClassCReg;
+
+
+ //
+ // Test whether there is PCI IO Protocol attached on the controller handle.
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ goto exit;
+ }
+
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ CLASSC,
+ sizeof (USB_CLASSC) / sizeof (UINT8),
+ &UsbClassCReg
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ Status = EFI_UNSUPPORTED;
+ goto exit;
+ }
+
+ //
+ // Test whether the controller belongs to Ehci type
+ //
+ if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
+ (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
+ (UsbClassCReg.PI != PCI_CLASSC_PI_EHCI)
+ ) {
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ Status = EFI_UNSUPPORTED;
+ goto exit;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+EhciDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Starting the Usb EHCI Driver
+
+ Arguments:
+
+ This - Protocol instance pointer.
+ Controller - Handle of device to test
+ RemainingDevicePath - Not used
+
+ Returns:
+
+ EFI_SUCCESS supports this device.
+ EFI_UNSUPPORTED do not support this device.
+ EFI_DEVICE_ERROR cannot be started due to device Error
+ EFI_OUT_OF_RESOURCES cannot allocate resources
+
+--*/
+{
+ EFI_STATUS Status;
+ USB2_HC_DEV *HcDev;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 MaxSpeed;
+ UINT8 PortNumber;
+ UINT8 Is64BitCapable;
+
+ //
+ // Open the PciIo Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+
+ //
+ // Enable the USB Host Controller
+ //
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationEnable,
+ EFI_PCI_DEVICE_ENABLE,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto close_pciio_protocol;
+ }
+
+ //
+ // Allocate memory for EHC private data structure
+ //
+ HcDev = AllocateZeroPool (sizeof (USB2_HC_DEV));
+ if (NULL == HcDev) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto close_pciio_protocol;
+ }
+
+ //
+ // Init EFI_USB2_HC_PROTOCOL interface and private data structure
+ //
+ HcDev->Usb2Hc.GetCapability = EhciGetCapability;
+ HcDev->Usb2Hc.Reset = EhciReset;
+ HcDev->Usb2Hc.GetState = EhciGetState;
+ HcDev->Usb2Hc.SetState = EhciSetState;
+ HcDev->Usb2Hc.ControlTransfer = EhciControlTransfer;
+ HcDev->Usb2Hc.BulkTransfer = EhciBulkTransfer;
+ HcDev->Usb2Hc.AsyncInterruptTransfer = EhciAsyncInterruptTransfer;
+ HcDev->Usb2Hc.SyncInterruptTransfer = EhciSyncInterruptTransfer;
+ HcDev->Usb2Hc.IsochronousTransfer = EhciIsochronousTransfer;
+ HcDev->Usb2Hc.AsyncIsochronousTransfer = EhciAsyncIsochronousTransfer;
+ HcDev->Usb2Hc.GetRootHubPortStatus = EhciGetRootHubPortStatus;
+ HcDev->Usb2Hc.SetRootHubPortFeature = EhciSetRootHubPortFeature;
+ HcDev->Usb2Hc.ClearRootHubPortFeature = EhciClearRootHubPortFeature;
+ HcDev->Usb2Hc.MajorRevision = 0x1;
+ HcDev->Usb2Hc.MinorRevision = 0x1;
+
+ HcDev->AsyncRequestList = NULL;
+ HcDev->ControllerNameTable = NULL;
+ HcDev->Signature = USB2_HC_DEV_SIGNATURE;
+ HcDev->PciIo = PciIo;
+
+ //
+ // Install USB2_HC_PROTOCOL
+ //
+ Status = gBS->InstallProtocolInterface (
+ &Controller,
+ &gEfiUsb2HcProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &HcDev->Usb2Hc
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto free_pool;
+ }
+
+ //
+ // Get Capability Register Length
+ //
+ Status = GetCapabilityLen (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto uninstall_usb2hc_protocol;
+ }
+
+ //
+ // 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;
+ }
+
+ //
+ // Create AsyncRequest Polling Timer
+ //
+ Status = CreatePollingTimer (HcDev, AsyncRequestMoniter);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto deinit_memory_management;
+ }
+
+ //
+ // 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 = AddUnicodeString (
+ "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_memory_management:
+ 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,
+ (VOID **) &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);
+
+ //
+ // Deinit Ehci pool memory management
+ //
+ DeinitialMemoryManagement (HcDev);
+
+ //
+ // Denint Unicode String Table
+ //
+ FreeUnicodeStringTable (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)) {
+ 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)) {
+ mDeviceSpeed[PortNumber] = IsHighSpeedDevice (This, PortNumber) ? USB_PORT_STAT_HIGH_SPEED : 0;
+ }
+ PortStatus->PortStatus |= mDeviceSpeed[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, "WaitForEhcNotHalt TimeOut\n"));
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+ }
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg |= PORTSC_PR;
+ //
+ // Set one to PortReset bit must also set zero to PortEnable bit
+ //
+ PortStatusControlReg &= ~PORTSC_PED;
+ break;
+
+ case EfiUsbPortPower:
+
+ //
+ // No support, no operation
+ //
+ goto exit;
+
+ case EfiUsbPortOwner:
+
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg |= PORTSC_PO;
+ break;
+
+ default:
+
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ PortStatusControlAddr,
+ PortStatusControlReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+EhciClearRootHubPortFeature (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ )
+/*++
+
+ Routine Description:
+
+ Clears a feature for the specified root hub port.
+
+ Arguments:
+
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ PortNumber - Specifies the root hub port whose feature
+ is requested to be cleared.
+ PortFeature - Indicates the feature selector associated with the
+ feature clear request.
+
+ Returns:
+
+ EFI_SUCCESS
+ The feature specified by PortFeature was cleared 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:
+
+ //
+ // Clear PORT_ENABLE feature means disable port.
+ //
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg &= ~PORTSC_PED;
+ break;
+
+ case EfiUsbPortSuspend:
+
+ //
+ // A write of zero to this bit is ignored by the host controller.
+ // The host controller will unconditionally set this bit to a zero when:
+ // 1. software sets the Forct Port Resume bit to a zero from a one.
+ // 2. software sets the Port Reset bit to a one frome a zero.
+ //
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg &= ~PORTSC_FPR;
+ break;
+
+ case EfiUsbPortReset:
+
+ //
+ // Clear PORT_RESET means clear the reset signal.
+ //
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg &= ~PORTSC_PR;
+ break;
+
+ case EfiUsbPortPower:
+
+ //
+ // No support, no operation
+ //
+ goto exit;
+
+ case EfiUsbPortOwner:
+
+ //
+ // Clear port owner means this port owned by EHC
+ //
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg &= ~PORTSC_PO;
+ break;
+
+ case EfiUsbPortConnectChange:
+
+ //
+ // Clear connect status change
+ //
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg |= PORTSC_CSC;
+ break;
+
+ case EfiUsbPortEnableChange:
+
+ //
+ // Clear enable status change
+ //
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg |= PORTSC_PEDC;
+ break;
+
+ case EfiUsbPortSuspendChange:
+
+ //
+ // No related bit, no operation
+ //
+ goto exit;
+
+ case EfiUsbPortOverCurrentChange:
+
+ //
+ // Clear PortOverCurrent change
+ //
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg |= PORTSC_OCC;
+ break;
+
+ case EfiUsbPortResetChange:
+
+ //
+ // No related bit, no operation
+ //
+ goto exit;
+
+ default:
+
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ PortStatusControlAddr,
+ PortStatusControlReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+EhciControlTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Submits control transfer to a target USB device.
+
+ Arguments:
+
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ DeviceSpeed - Indicates target device speed.
+ MaximumPacketLength - Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+ Request - A pointer to the USB device request that will be sent
+ to the USB device.
+ TransferDirection - Specifies the data direction for the transfer.
+ There are three values available, DataIn, DataOut
+ and NoData.
+ Data - A pointer to the buffer of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - Indicates the size, in bytes, of the data buffer
+ specified by Data.
+ TimeOut - Indicates the maximum time, in microseconds,
+ which the transfer is allowed to complete.
+ Translator - A pointr to the transaction translator data.
+ TransferResult - A pointer to the detailed result information generated
+ by this control transfer.
+
+ Returns:
+
+ EFI_SUCCESS
+ The control transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The control transfer could not be completed due to a lack of resources.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The control transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The control transfer failed due to host controller or device error.
+ Caller should check TranferResult for detailed error information.
+
+--*/
+{
+ EFI_STATUS Status;
+ USB2_HC_DEV *HcDev;
+ UINT8 PktId;
+ EHCI_QH_ENTITY *QhPtr;
+ EHCI_QTD_ENTITY *ControlQtdsPtr;
+ UINT8 *DataCursor;
+ VOID *DataMap;
+ UINT8 *RequestCursor;
+ VOID *RequestMap;
+
+ QhPtr = NULL;
+ ControlQtdsPtr = NULL;
+ DataCursor = NULL;
+ DataMap = NULL;
+ RequestCursor = NULL;
+ RequestMap = NULL;
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+
+ //
+ // Parameters Checking
+ //
+ if (TransferDirection != EfiUsbDataIn &&
+ TransferDirection != EfiUsbDataOut &&
+ TransferDirection != EfiUsbNoData
+ ) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (EfiUsbNoData == TransferDirection) {
+ if (NULL != Data || 0 != *DataLength) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+ } else {
+ if (NULL == Data || 0 == *DataLength) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+ }
+
+ if (Request == NULL || TransferResult == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (EFI_USB_SPEED_LOW == DeviceSpeed) {
+ if (MaximumPacketLength != 8) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+ } else if (MaximumPacketLength != 8 &&
+ MaximumPacketLength != 16 &&
+ MaximumPacketLength != 32 &&
+ MaximumPacketLength != 64
+ ) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ //
+ // If errors exist that cause host controller halt,
+ // then return EFI_DEVICE_ERROR.
+ //
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
+ ClearEhcAllStatus (HcDev);
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ //
+ // Map the Request for bus master access.
+ // BusMasterRead means cpu write
+ //
+ Status = MapRequestBuffer (
+ HcDev,
+ Request,
+ &RequestCursor,
+ &RequestMap
+ );
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ //
+ // Map the source data buffer for bus master access.
+ //
+ Status = MapDataBuffer (
+ HcDev,
+ TransferDirection,
+ Data,
+ DataLength,
+ &PktId,
+ &DataCursor,
+ &DataMap
+ );
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+ goto unmap_request;
+ }
+
+ //
+ // Create and init control Qh
+ //
+ Status = CreateControlQh (
+ HcDev,
+ DeviceAddress,
+ DeviceSpeed,
+ MaximumPacketLength,
+ Translator,
+ &QhPtr
+ );
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto unmap_data;
+ }
+
+ //
+ // Create and init control Qtds
+ //
+ Status = CreateControlQtds (
+ HcDev,
+ PktId,
+ RequestCursor,
+ DataCursor,
+ *DataLength,
+ Translator,
+ &ControlQtdsPtr
+ );
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto destory_qh;
+ }
+
+ //
+ // Link Qtds to Qh
+ //
+ LinkQtdToQh (QhPtr, ControlQtdsPtr);
+
+ ClearEhcAllStatus (HcDev);
+
+ //
+ // Link Qh and Qtds to Async Schedule List
+ //
+ Status = LinkQhToAsyncList (HcDev, QhPtr);
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+ goto destory_qtds;
+ }
+
+ //
+ // Poll Qh-Qtds execution and get result.
+ // detail status is returned
+ //
+ Status = ExecuteTransfer (
+ HcDev,
+ TRUE,
+ QhPtr,
+ DataLength,
+ 0,
+ TimeOut,
+ TransferResult
+ );
+ if (EFI_ERROR (Status)) {
+ goto destory_qtds;
+ }
+
+ //
+ // If has errors that cause host controller halt,
+ // then return EFI_DEVICE_ERROR directly.
+ //
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
+ *TransferResult |= EFI_USB_ERR_SYSTEM;
+ }
+
+ ClearEhcAllStatus (HcDev);
+
+destory_qtds:
+ UnlinkQhFromAsyncList (HcDev, QhPtr);
+ DestoryQtds (HcDev, ControlQtdsPtr);
+destory_qh:
+ DestoryQh (HcDev, QhPtr);
+unmap_data:
+ HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);
+unmap_request:
+ HcDev->PciIo->Unmap (HcDev->PciIo, RequestMap);
+exit:
+ HcDev->PciIo->Flush (HcDev->PciIo);
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+EhciBulkTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Submits bulk transfer to a bulk endpoint of a USB device.
+
+ Arguments:
+
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - The combination of an endpoint number and an
+ endpoint direction of the target USB device.
+ Each endpoint address supports data transfer in
+ one direction except the control endpoint
+ (whose default endpoint address is 0).
+ It is the caller's responsibility to make sure that
+ the EndPointAddress represents a bulk endpoint.
+ DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
+ and EFI_USB_SPEED_HIGH.
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+ DataBuffersNumber - Number of data buffers prepared for the transfer.
+ Data - Array of pointers to the buffers of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - When input, indicates the size, in bytes, of the data buffer
+ specified by Data. When output, indicates the actually
+ transferred data size.
+ DataToggle - A pointer to the data toggle value. On input, it indicates
+ the initial data toggle value the bulk transfer should adopt;
+ on output, it is updated to indicate the data toggle value
+ of the subsequent bulk transfer.
+ Translator - A pointr to the transaction translator data.
+ TimeOut - Indicates the maximum time, in microseconds, which the
+ transfer is allowed to complete.
+ TransferResult - A pointer to the detailed result information of the
+ bulk transfer.
+
+ Returns:
+
+ EFI_SUCCESS
+ The bulk transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The bulk transfer could not be submitted due to lack of resource.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The bulk transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The bulk transfer failed due to host controller or device error.
+ Caller should check TranferResult for detailed error information.
+
+--*/
+{
+ EFI_STATUS Status;
+ USB2_HC_DEV *HcDev;
+ UINT8 PktId;
+ EHCI_QH_ENTITY *QhPtr;
+ EHCI_QTD_ENTITY *BulkQtdsPtr;
+ UINT8 *DataCursor;
+ VOID *DataMap;
+ EFI_USB_DATA_DIRECTION TransferDirection;
+
+ QhPtr = NULL;
+ BulkQtdsPtr = NULL;
+ DataCursor = NULL;
+ DataMap = NULL;
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+
+ //
+ // Parameters Checking
+ //
+ if (NULL == DataLength ||
+ NULL == Data ||
+ NULL == Data[0] ||
+ NULL == TransferResult
+ ) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (*DataLength == 0) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (1 != *DataToggle && 0 != *DataToggle) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (EFI_USB_SPEED_LOW == DeviceSpeed) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (EFI_USB_SPEED_FULL == DeviceSpeed) {
+ if (MaximumPacketLength > 64) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+ }
+
+ if (EFI_USB_SPEED_HIGH == DeviceSpeed) {
+ if (MaximumPacketLength > 512) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+ }
+
+ //
+ // if has errors that cause host controller halt,
+ // then return EFI_DEVICE_ERROR directly.
+ //
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
+ ClearEhcAllStatus (HcDev);
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = ClearEhcAllStatus (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ //
+ // construct QH and TD data structures,
+ // and link them together
+ //
+ if (EndPointAddress & 0x80) {
+ TransferDirection = EfiUsbDataIn;
+ } else {
+ TransferDirection = EfiUsbDataOut;
+ }
+
+ Status = MapDataBuffer (
+ HcDev,
+ TransferDirection,
+ Data[0],
+ DataLength,
+ &PktId,
+ &DataCursor,
+ &DataMap
+ );
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ //
+ // Create and init Bulk Qh
+ //
+ Status = CreateBulkQh (
+ HcDev,
+ DeviceAddress,
+ EndPointAddress,
+ DeviceSpeed,
+ *DataToggle,
+ MaximumPacketLength,
+ Translator,
+ &QhPtr
+ );
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto unmap_data;
+ }
+
+ //
+ // Create and init Bulk Qtds
+ //
+ Status = CreateBulkOrInterruptQtds (
+ HcDev,
+ PktId,
+ DataCursor,
+ *DataLength,
+ Translator,
+ &BulkQtdsPtr
+ );
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto destory_qh;
+ }
+
+ //
+ // Link Qtds to Qh
+ //
+ LinkQtdToQh (QhPtr, BulkQtdsPtr);
+
+ ClearEhcAllStatus (HcDev);
+
+ //
+ // Link Qh and qtds to Async Schedule List
+ //
+ Status = LinkQhToAsyncList (HcDev, QhPtr);
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+ goto destory_qtds;
+ }
+
+ //
+ // Poll QH-TDs execution and get result.
+ // detail status is returned
+ //
+ Status = ExecuteTransfer (
+ HcDev,
+ FALSE,
+ QhPtr,
+ DataLength,
+ DataToggle,
+ TimeOut,
+ TransferResult
+ );
+ if (EFI_ERROR (Status)) {
+ goto destory_qtds;
+ }
+
+ //
+ // if has errors that cause host controller halt,
+ // then return EFI_DEVICE_ERROR directly.
+ //
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
+ *TransferResult |= EFI_USB_ERR_SYSTEM;
+ }
+
+ ClearEhcAllStatus (HcDev);
+
+destory_qtds:
+ UnlinkQhFromAsyncList (HcDev, QhPtr);
+ DestoryQtds (HcDev, BulkQtdsPtr);
+destory_qh:
+ DestoryQh (HcDev, QhPtr);
+unmap_data:
+ HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);
+exit:
+ HcDev->PciIo->Flush (HcDev->PciIo);
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+EhciAsyncInterruptTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN BOOLEAN IsNewTransfer,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN PollingInterval,
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
+ IN VOID *Context OPTIONAL
+ )
+/*++
+
+ Routine Description:
+
+ Submits an asynchronous interrupt transfer to an
+ interrupt endpoint of a USB device.
+
+ Arguments:
+
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - The combination of an endpoint number and an endpoint
+ direction of the target USB device. Each endpoint address
+ supports data transfer in one direction except the
+ control endpoint (whose default endpoint address is 0).
+ It is the caller's responsibility to make sure that
+ the EndPointAddress represents an interrupt endpoint.
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+ IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
+ the host and the target interrupt endpoint.
+ If FALSE, the specified asynchronous interrupt pipe
+ is canceled.
+ DataToggle - A pointer to the data toggle value. On input, it is valid
+ when IsNewTransfer is TRUE, and it indicates the initial
+ data toggle value the asynchronous interrupt transfer
+ should adopt.
+ On output, it is valid when IsNewTransfer is FALSE,
+ and it is updated to indicate the data toggle value of
+ the subsequent asynchronous interrupt transfer.
+ PollingInterval - Indicates the interval, in milliseconds, that the
+ asynchronous interrupt transfer is polled.
+ This parameter is required when IsNewTransfer is TRUE.
+ DataLength - Indicates the length of data to be received at the
+ rate specified by PollingInterval from the target
+ asynchronous interrupt endpoint. This parameter
+ is only required when IsNewTransfer is TRUE.
+ Translator - A pointr to the transaction translator data.
+ CallBackFunction - The Callback function.This function is called at the
+ rate specified by PollingInterval.This parameter is
+ only required when IsNewTransfer is TRUE.
+ Context - The context that is passed to the CallBackFunction.
+ - This is an optional parameter and may be NULL.
+
+ Returns:
+
+ EFI_SUCCESS
+ The asynchronous interrupt transfer request has been successfully
+ submitted or canceled.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_OUT_OF_RESOURCES
+ The request could not be completed due to a lack of resources.
+ EFI_DEVICE_ERROR
+ Can't read register
+
+--*/
+{
+ EFI_STATUS Status;
+ USB2_HC_DEV *HcDev;
+ UINT8 PktId;
+ EHCI_QH_ENTITY *QhPtr;
+ EHCI_QTD_ENTITY *InterruptQtdsPtr;
+ UINT8 *DataPtr;
+ UINT8 *DataCursor;
+ VOID *DataMap;
+ UINTN MappedLength;
+ EHCI_ASYNC_REQUEST *AsyncRequestPtr;
+ EFI_TPL OldTpl;
+
+ QhPtr = NULL;
+ InterruptQtdsPtr = NULL;
+ DataPtr = NULL;
+ DataCursor = NULL;
+ DataMap = NULL;
+ AsyncRequestPtr = NULL;
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+
+ //
+ // Parameters Checking
+ //
+ if (!IsDataInTransfer (EndPointAddress)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (IsNewTransfer) {
+ if (0 == DataLength) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (*DataToggle != 1 && *DataToggle != 0) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (PollingInterval > 255 || PollingInterval < 1) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+ }
+
+ //
+ // if has errors that cause host controller halt,
+ // then return EFI_DEVICE_ERROR directly.
+ //
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
+ ClearEhcAllStatus (HcDev);
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = ClearEhcAllStatus (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ //
+ // Delete Async interrupt transfer request
+ //
+ if (!IsNewTransfer) {
+
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ Status = DeleteAsyncRequestTransfer (
+ HcDev,
+ DeviceAddress,
+ EndPointAddress,
+ DataToggle
+ );
+
+ gBS->RestoreTPL (OldTpl);
+
+ goto exit;
+ }
+
+ Status = EhciAllocatePool (
+ HcDev,
+ (UINT8 **) &AsyncRequestPtr,
+ sizeof (EHCI_ASYNC_REQUEST)
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+
+ Status = EhciAllocatePool (HcDev, &DataPtr, DataLength);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto free_request;
+ }
+
+ MappedLength = DataLength;
+ Status = MapDataBuffer (
+ HcDev,
+ EfiUsbDataIn,
+ DataPtr,
+ &MappedLength,
+ &PktId,
+ &DataCursor,
+ &DataMap
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto free_data;
+ }
+
+ //
+ // Create and init Interrupt Qh
+ //
+ Status = CreateInterruptQh (
+ HcDev,
+ DeviceAddress,
+ EndPointAddress,
+ DeviceSpeed,
+ *DataToggle,
+ MaximumPacketLength,
+ PollingInterval,
+ Translator,
+ &QhPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto unmap_data;
+ }
+
+ //
+ // Create and init Interrupt Qtds
+ //
+ Status = CreateBulkOrInterruptQtds (
+ HcDev,
+ PktId,
+ DataCursor,
+ MappedLength,
+ Translator,
+ &InterruptQtdsPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto destory_qh;
+ }
+
+ //
+ // Link Qtds to Qh
+ //
+ LinkQtdToQh (QhPtr, InterruptQtdsPtr);
+
+ //
+ // Init AsyncRequest Entry
+ //
+ AsyncRequestPtr->Context = Context;
+ AsyncRequestPtr->CallBackFunc = CallBackFunction;
+ AsyncRequestPtr->TransferType = ASYNC_INTERRUPT_TRANSFER;
+ AsyncRequestPtr->QhPtr = QhPtr;
+ AsyncRequestPtr->Prev = NULL;
+ AsyncRequestPtr->Next = NULL;
+
+ if (NULL == HcDev->AsyncRequestList) {
+ Status = StartPollingTimer (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ CleanUpAllAsyncRequestTransfer (HcDev);
+ goto exit;
+ }
+ }
+
+ //
+ // Link Entry to AsyncRequest List
+ //
+ LinkToAsyncReqeust (HcDev, AsyncRequestPtr);
+
+ ClearEhcAllStatus (HcDev);
+
+ Status = DisablePeriodicSchedule (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_TIMEOUT;
+ goto exit;
+ }
+
+ //
+ // Link Qh and Qtds to Periodic Schedule List
+ //
+ LinkQhToPeriodicList (HcDev, QhPtr);
+
+ Status = EnablePeriodicSchedule (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_TIMEOUT;
+ goto exit;
+ }
+
+ if (IsEhcHalted (HcDev)) {
+ Status = StartScheduleExecution (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+ }
+
+ HcDev->PciIo->Flush (HcDev->PciIo);
+ goto exit;
+
+destory_qh:
+ DestoryQh (HcDev, QhPtr);
+free_data:
+ EhciFreePool (HcDev, DataPtr, DataLength);
+free_request:
+ EhciFreePool (
+ HcDev,
+ (UINT8 *) AsyncRequestPtr,
+ sizeof (EHCI_ASYNC_REQUEST)
+ );
+unmap_data:
+ HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);
+exit:
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+EhciSyncInterruptTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Submits synchronous interrupt transfer to an interrupt endpoint
+ of a USB device.
+
+ Arguments:
+
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - The combination of an endpoint number and an endpoint
+ direction of the target USB device. Each endpoint
+ address supports data transfer in one direction
+ except the control endpoint (whose default
+ endpoint address is 0). It is the caller's responsibility
+ to make sure that the EndPointAddress represents
+ an interrupt endpoint.
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+ Data - A pointer to the buffer of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - On input, the size, in bytes, of the data buffer specified
+ by Data. On output, the number of bytes transferred.
+ DataToggle - A pointer to the data toggle value. On input, it indicates
+ the initial data toggle value the synchronous interrupt
+ transfer should adopt;
+ on output, it is updated to indicate the data toggle value
+ of the subsequent synchronous interrupt transfer.
+ TimeOut - Indicates the maximum time, in microseconds, which the
+ transfer is allowed to complete.
+ Translator - A pointr to the transaction translator data.
+ TransferResult - A pointer to the detailed result information from
+ the synchronous interrupt transfer.
+
+ Returns:
+
+ EFI_SUCCESS
+ The synchronous interrupt transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The synchronous interrupt transfer could not be submitted due
+ to lack of resource.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The synchronous interrupt transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The synchronous interrupt transfer failed due to host controller
+ or device error. Caller should check TranferResult for detailed
+ error information.
+
+--*/
+{
+ EFI_STATUS Status;
+ USB2_HC_DEV *HcDev;
+ UINT8 PktId;
+ EHCI_QH_ENTITY *QhPtr;
+ EHCI_QTD_ENTITY *InterruptQtdsPtr;
+ UINT8 *DataCursor;
+ VOID *DataMap;
+
+ QhPtr = NULL;
+ InterruptQtdsPtr = NULL;
+ DataCursor = NULL;
+ DataMap = NULL;
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+
+ //
+ // Parameters Checking
+ //
+ if (DataLength == NULL ||
+ Data == NULL ||
+ TransferResult == NULL
+ ) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (!IsDataInTransfer (EndPointAddress)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (0 == *DataLength) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (*DataToggle != 1 && *DataToggle != 0) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (EFI_USB_SPEED_LOW == DeviceSpeed && 8 != MaximumPacketLength) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (EFI_USB_SPEED_FULL == DeviceSpeed && MaximumPacketLength > 64) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ if (EFI_USB_SPEED_HIGH == DeviceSpeed && MaximumPacketLength > 3072) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ //
+ // if has errors that cause host controller halt,
+ // then return EFI_DEVICE_ERROR directly.
+ //
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
+ ClearEhcAllStatus (HcDev);
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = ClearEhcAllStatus (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = MapDataBuffer (
+ HcDev,
+ EfiUsbDataIn,
+ Data,
+ DataLength,
+ &PktId,
+ &DataCursor,
+ &DataMap
+ );
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ //
+ // Create and init Interrupt Qh
+ //
+ Status = CreateInterruptQh (
+ HcDev,
+ DeviceAddress,
+ EndPointAddress,
+ DeviceSpeed,
+ *DataToggle,
+ MaximumPacketLength,
+ 0,
+ Translator,
+ &QhPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto unmap_data;
+ }
+
+ //
+ // Create and init Interrupt Qtds
+ //
+ Status = CreateBulkOrInterruptQtds (
+ HcDev,
+ PktId,
+ DataCursor,
+ *DataLength,
+ Translator,
+ &InterruptQtdsPtr
+ );
+ if (EFI_ERROR (Status)) {
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto destory_qh;
+ }
+
+ //
+ // Link Qtds to Qh
+ //
+ LinkQtdToQh (QhPtr, InterruptQtdsPtr);
+
+ ClearEhcAllStatus (HcDev);
+
+ Status = DisablePeriodicSchedule (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_TIMEOUT;
+ goto exit;
+ }
+
+ //
+ // Link Qh and Qtds to Periodic Schedule List
+ //
+ LinkQhToPeriodicList (HcDev, QhPtr);
+
+ Status = EnablePeriodicSchedule (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_TIMEOUT;
+ goto exit;
+ }
+
+ if (IsEhcHalted (HcDev)) {
+ Status = StartScheduleExecution (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+ }
+
+ //
+ // Poll QH-TDs execution and get result.
+ // detail status is returned
+ //
+ Status = ExecuteTransfer (
+ HcDev,
+ FALSE,
+ QhPtr,
+ DataLength,
+ DataToggle,
+ TimeOut,
+ TransferResult
+ );
+ if (EFI_ERROR (Status)) {
+ goto destory_qtds;
+ }
+
+ //
+ // if has errors that cause host controller halt,
+ // then return EFI_DEVICE_ERROR directly.
+ //
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
+ *TransferResult |= EFI_USB_ERR_SYSTEM;
+ }
+
+ ClearEhcAllStatus (HcDev);
+
+destory_qtds:
+ UnlinkQhFromPeriodicList (HcDev, QhPtr, 0);
+ DestoryQtds (HcDev, InterruptQtdsPtr);
+destory_qh:
+ DestoryQh (HcDev, QhPtr);
+unmap_data:
+ HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);
+exit:
+ HcDev->PciIo->Flush (HcDev->PciIo);
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+EhciIsochronousTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Submits isochronous transfer to a target USB device.
+
+ Arguments:
+
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - End point address
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+ DataBuffersNumber - Number of data buffers prepared for the transfer.
+ Data - Array of pointers to the buffers of data that will be
+ transmitted to USB device or received from USB device.
+ DataLength - Indicates the size, in bytes, of the data buffer
+ specified by Data.
+ Translator - A pointr to the transaction translator data.
+ TransferResult - A pointer to the detailed result information generated
+ by this control transfer.
+
+ Returns:
+
+ EFI_UNSUPPORTED
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+EhciAsyncIsochronousTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
+ IN VOID *Context
+ )
+/*++
+
+ Routine Description:
+
+ Submits Async isochronous transfer to a target USB device.
+
+ Arguments:
+
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - End point address
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+ DataBuffersNumber - Number of data buffers prepared for the transfer.
+ Data - Array of pointers to the buffers of data that will be transmitted
+ to USB device or received from USB device.
+ Translator - A pointr to the transaction translator data.
+ IsochronousCallBack - When the transfer complete, the call back function will be called
+ Context - Pass to the call back function as parameter
+
+ Returns:
+
+ EFI_UNSUPPORTED
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.h b/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.h
new file mode 100644
index 0000000000..a5fa2be394
--- /dev/null
+++ b/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.h
@@ -0,0 +1,2689 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Ehci.h
+
+Abstract:
+
+
+Revision History
+--*/
+
+#ifndef _EHCI_H
+#define _EHCI_H
+
+//
+// Universal Host Controller Interface data structures and defines
+//
+#include <IndustryStandard/pci22.h>
+
+#ifdef EFI_DEBUG
+extern UINTN gEHCDebugLevel;
+extern UINTN gEHCErrorLevel;
+#endif
+
+#define STALL_1_MACRO_SECOND 1
+#define STALL_1_MILLI_SECOND 1000 * STALL_1_MACRO_SECOND
+#define STALL_1_SECOND 1000 * STALL_1_MILLI_SECOND
+
+#define SETUP_PACKET_PID_CODE 0x02
+#define INPUT_PACKET_PID_CODE 0x01
+#define OUTPUT_PACKET_PID_CODE 0x0
+
+#define ITD_SELECT_TYPE 0x0
+#define QH_SELECT_TYPE 0x01
+#define SITD_SELECT_TYPE 0x02
+#define FSTN_SELECT_TYPE 0x03
+
+#define EHCI_SET_PORT_RESET_RECOVERY_TIME 50 * STALL_1_MILLI_SECOND
+#define EHCI_CLEAR_PORT_RESET_RECOVERY_TIME STALL_1_MILLI_SECOND
+#define EHCI_GENERIC_TIMEOUT 50 * STALL_1_MILLI_SECOND
+#define EHCI_GENERIC_RECOVERY_TIME 50 * STALL_1_MACRO_SECOND
+#define EHCI_SYNC_REQUEST_POLLING_TIME 50 * STALL_1_MACRO_SECOND
+#define EHCI_ASYNC_REQUEST_POLLING_TIME 50 * STALL_1_MILLI_SECOND
+
+#define USB_BAR_INDEX 0 /* how many bytes away from USB_BASE to 0x10 */
+
+#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 1
+
+#define EHCI_MIN_PACKET_SIZE 8
+#define EHCI_MAX_PACKET_SIZE 1024
+#define EHCI_MAX_FRAME_LIST_LENGTH 1024
+#define EHCI_BLOCK_SIZE_WITH_TT 64
+#define EHCI_BLOCK_SIZE 512
+#define EHCI_MAX_QTD_CAPACITY (EFI_PAGE_SIZE * 5)
+
+#define NAK_COUNT_RELOAD 3
+#define QTD_ERROR_COUNTER 1
+#define HIGH_BANDWIDTH_PIPE_MULTIPLIER 1
+
+#define QTD_STATUS_ACTIVE 0x80
+#define QTD_STATUS_HALTED 0x40
+#define QTD_STATUS_BUFFER_ERR 0x20
+#define QTD_STATUS_BABBLE_ERR 0x10
+#define QTD_STATUS_TRANSACTION_ERR 0x08
+#define QTD_STATUS_DO_STOP_SPLIT 0x02
+#define QTD_STATUS_DO_START_SPLIT 0
+#define QTD_STATUS_DO_PING 0x01
+#define QTD_STATUS_DO_OUT 0
+
+#define DATA0 0
+#define DATA1 1
+
+#define MICRO_FRAME_0_CHANNEL 0x01
+#define MICRO_FRAME_1_CHANNEL 0x02
+#define MICRO_FRAME_2_CHANNEL 0x04
+#define MICRO_FRAME_3_CHANNEL 0x08
+#define MICRO_FRAME_4_CHANNEL 0x10
+#define MICRO_FRAME_5_CHANNEL 0x20
+#define MICRO_FRAME_6_CHANNEL 0x40
+#define MICRO_FRAME_7_CHANNEL 0x80
+
+#define CONTROL_TRANSFER 0x01
+#define BULK_TRANSFER 0x02
+#define SYNC_INTERRUPT_TRANSFER 0x04
+#define ASYNC_INTERRUPT_TRANSFER 0x08
+#define SYNC_ISOCHRONOUS_TRANSFER 0x10
+#define ASYNC_ISOCHRONOUS_TRANSFER 0x20
+
+
+//
+// Enhanced Host Controller Registers definitions
+//
+extern UINT32 mUsbCapabilityLen;
+extern EFI_DRIVER_BINDING_PROTOCOL gEhciDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gEhciComponentName;
+
+#define USBCMD 0x0 /* Command Register Offset 00-03h */
+#define USBCMD_RS 0x01 /* Run / Stop */
+#define USBCMD_HCRESET 0x02 /* Host controller reset */
+#define USBCMD_FLS_512 0x04 /* 512 elements (2048bytes) in Frame List */
+#define USBCMD_FLS_256 0x08 /* 256 elements (1024bytes) in Frame List */
+#define USBCMD_PSE 0x10 /* Periodic schedule enable */
+#define USBCMD_ASE 0x20 /* Asynchronous schedule enable */
+#define USBCMD_IAAD 0x40 /* Interrupt on async advance doorbell */
+
+#define USBSTS 0x04 /* Statue Register Offset 04-07h */
+#define USBSTS_HSE 0x10 /* Host system error */
+#define USBSTS_IAA 0x20 /* Interrupt on async advance */
+#define USBSTS_HCH 0x1000 /* Host controller halted */
+#define USBSTS_PSS 0x4000 /* Periodic schedule status */
+#define USBSTS_ASS 0x8000 /* Asynchronous schedule status */
+
+#define USBINTR 0x08 /* Command Register Offset 08-0bh */
+
+#define FRINDEX 0x0c /* Frame Index Offset 0c-0fh */
+
+#define CTRLDSSGMENT 0x10 /* 4G Segment Selector Offset 10-13h */
+
+#define PERIODICLISTBASE 0x14 /* Frame List Base Address Offset 14-17h */
+
+#define ASYNCLISTADDR 0x18 /* Next Asynchronous List Address Offset 18-1bh */
+
+#define CONFIGFLAG 0x40 /* Configured Flag Register Offset 40-43h */
+#define CONFIGFLAG_CF 0x01 /* Configure Flag */
+
+#define PORTSC 0x44 /* Port Status/Control Offset 44-47h */
+#define PORTSC_CCS 0x01 /* Current Connect Status*/
+#define PORTSC_CSC 0x02 /* Connect Status Change */
+#define PORTSC_PED 0x04 /* Port Enable / Disable */
+#define PORTSC_PEDC 0x08 /* Port Enable / Disable Change */
+#define PORTSC_OCA 0x10 /* Over current Active */
+#define PORTSC_OCC 0x20 /* Over current Change */
+#define PORTSC_FPR 0x40 /* Force Port Resume */
+#define PORTSC_SUSP 0x80 /* Port Suspend State */
+#define PORTSC_PR 0x100 /* Port Reset */
+#define PORTSC_LS_KSTATE 0x400 /* Line Status K-state */
+#define PORTSC_LS_JSTATE 0x800 /* Line Status J-state */
+#define PORTSC_PP 0x1000 /* Port Power */
+#define PORTSC_PO 0x2000 /* Port Owner */
+
+#define CAPLENGTH 0 /* Capability Register Length 00h */
+
+#define HCIVERSION 0x02 /* Interface Version Number 02-03h */
+
+#define HCSPARAMS 0x04 /* Structural Parameters 04-07h */
+#define HCSP_NPORTS 0x0f /* Number of physical downstream ports on host controller */
+
+#define HCCPARAMS 0x08 /* Capability Parameters 08-0bh */
+#define HCCP_64BIT 0x01 /* 64-bit Addressing Capability */
+#define HCCP_PFLF 0x02 /* Programmable Frame List Flag */
+#define HCCP_EECP 0xff00 /* EHCI Extemded Capabilities Pointer */
+
+#define HCSPPORTROUTE 0x0c /* Companion Port Route Description 60b */
+
+#define CLASSC 0x09 /* Class Code 09-0bh */
+
+#define USBBASE 0x10 /* Base Address to Memory-mapped Host Controller Register Space 10-13h */
+
+#define SBRN 0x60 /* Serial Bus Release Number 60h */
+
+#define FLADJ 0x61 /* Frame Length Adjustment Register 61h */
+
+#define PORTWAKECAP 0x62 /* Port wake capablilities register(OPIONAL) 61-62h */
+
+//
+// PCI Configuration Registers
+//
+#define EHCI_PCI_CLASSC 0x09
+#define EHCI_PCI_MEMORY_BASE 0x10
+
+//
+// Memory Offset Registers
+//
+#define EHCI_MEMORY_CAPLENGTH 0x0
+#define EHCI_MEMORY_CONFIGFLAG 0x40
+
+//
+// USB Base Class Code,Sub-Class Code and Programming Interface
+//
+#define PCI_CLASSC_PI_EHCI 0x20
+
+#define SETUP_PACKET_ID 0x2D
+#define INPUT_PACKET_ID 0x69
+#define OUTPUT_PACKET_ID 0xE1
+#define ERROR_PACKET_ID 0x55
+
+#define bit(a) 1 << (a)
+
+#define GET_0B_TO_31B(Addr) (((UINTN) Addr) & (0xffffffff))
+#define GET_32B_TO_63B(Addr) ((((UINTN) Addr) >> 32) & (0xffffffff))
+
+
+//
+// Ehci Data and Ctrl Structures
+//
+#pragma pack(1)
+
+typedef struct {
+ UINT8 PI;
+ UINT8 SubClassCode;
+ UINT8 BaseCode;
+} USB_CLASSC;
+
+typedef struct {
+ UINT32 NextQtdTerminate : 1;
+ UINT32 Rsvd1 : 4;
+ UINT32 NextQtdPointer : 27;
+
+ UINT32 AltNextQtdTerminate : 1;
+ UINT32 Rsvd2 : 4;
+ UINT32 AltNextQtdPointer : 27;
+
+ UINT32 Status : 8;
+ UINT32 PidCode : 2;
+ UINT32 ErrorCount : 2;
+ UINT32 CurrentPage : 3;
+ UINT32 InterruptOnComplete : 1;
+ UINT32 TotalBytes : 15;
+ UINT32 DataToggle : 1;
+
+ UINT32 CurrentOffset : 12;
+ UINT32 BufferPointer0 : 20;
+
+ UINT32 Rsvd3 : 12;
+ UINT32 BufferPointer1 : 20;
+
+ UINT32 Rsvd4 : 12;
+ UINT32 BufferPointer2 : 20;
+
+ UINT32 Rsvd5 : 12;
+ UINT32 BufferPointer3 : 20;
+
+ UINT32 Rsvd6 : 12;
+ UINT32 BufferPointer4 : 20;
+
+ UINT32 ExtBufferPointer0;
+ UINT32 ExtBufferPointer1;
+ UINT32 ExtBufferPointer2;
+ UINT32 ExtBufferPointer3;
+ UINT32 ExtBufferPointer4;
+} EHCI_QTD_HW;
+
+typedef struct {
+ UINT32 QhTerminate : 1;
+ UINT32 SelectType : 2;
+ UINT32 Rsvd1 : 2;
+ UINT32 QhHorizontalPointer : 27;
+
+ UINT32 DeviceAddr : 7;
+ UINT32 Inactive : 1;
+ UINT32 EndpointNum : 4;
+ UINT32 EndpointSpeed : 2;
+ UINT32 DataToggleControl : 1;
+ UINT32 HeadReclamationFlag : 1;
+ UINT32 MaxPacketLen : 11;
+ UINT32 ControlEndpointFlag : 1;
+ UINT32 NakCountReload : 4;
+
+ UINT32 InerruptScheduleMask : 8;
+ UINT32 SplitComletionMask : 8;
+ UINT32 HubAddr : 7;
+ UINT32 PortNum : 7;
+ UINT32 Multiplier : 2;
+
+ UINT32 Rsvd2 : 5;
+ UINT32 CurrentQtdPointer : 27;
+
+ UINT32 NextQtdTerminate : 1;
+ UINT32 Rsvd3 : 4;
+ UINT32 NextQtdPointer : 27;
+
+ UINT32 AltNextQtdTerminate : 1;
+ UINT32 NakCount : 4;
+ UINT32 AltNextQtdPointer : 27;
+
+ UINT32 Status : 8;
+ UINT32 PidCode : 2;
+ UINT32 ErrorCount : 2;
+ UINT32 CurrentPage : 3;
+ UINT32 InterruptOnComplete : 1;
+ UINT32 TotalBytes : 15;
+ UINT32 DataToggle : 1;
+
+ UINT32 CurrentOffset : 12;
+ UINT32 BufferPointer0 : 20;
+
+ UINT32 CompleteSplitMask : 8;
+ UINT32 Rsvd4 : 4;
+ UINT32 BufferPointer1 : 20;
+
+ UINT32 FrameTag : 5;
+ UINT32 SplitBytes : 7;
+ UINT32 BufferPointer2 : 20;
+
+ UINT32 Rsvd5 : 12;
+ UINT32 BufferPointer3 : 20;
+
+ UINT32 Rsvd6 : 12;
+ UINT32 BufferPointer4 : 20;
+
+ UINT32 ExtBufferPointer0;
+ UINT32 ExtBufferPointer1;
+ UINT32 ExtBufferPointer2;
+ UINT32 ExtBufferPointer3;
+ UINT32 ExtBufferPointer4;
+} EHCI_QH_HW;
+
+typedef struct {
+ UINT32 LinkTerminate : 1;
+ UINT32 SelectType : 2;
+ UINT32 Rsvd : 2;
+ UINT32 LinkPointer : 27;
+} FRAME_LIST_ENTRY;
+
+#pragma pack()
+
+typedef struct _EHCI_QTD_ENTITY EHCI_QTD_ENTITY;
+typedef struct _EHCI_QH_ENTITY EHCI_QH_ENTITY;
+typedef struct _EHCI_ASYNC_REQUEST EHCI_ASYNC_REQUEST;
+
+typedef struct _EHCI_QTD_ENTITY {
+ EHCI_QTD_HW Qtd;
+ UINT32 TotalBytes;
+ UINT32 StaticTotalBytes;
+ UINT32 StaticCurrentOffset;
+ EHCI_QTD_ENTITY *Prev;
+ EHCI_QTD_ENTITY *Next;
+ EHCI_QTD_ENTITY *AltNext;
+ EHCI_QH_ENTITY *SelfQh;
+} EHCI_QTD_ENTITY;
+
+typedef struct _EHCI_QH_ENTITY {
+ EHCI_QH_HW Qh;
+ EHCI_QH_ENTITY *Next;
+ EHCI_QH_ENTITY *Prev;
+ EHCI_QTD_ENTITY *FirstQtdPtr;
+ EHCI_QTD_ENTITY *LastQtdPtr;
+ EHCI_QTD_ENTITY *AltQtdPtr;
+ UINTN Interval;
+ UINT8 TransferType;
+} EHCI_QH_ENTITY;
+
+#define GET_QH_ENTITY_ADDR(a) ((EHCI_QH_ENTITY *) a)
+#define GET_QTD_ENTITY_ADDR(a) ((EHCI_QTD_ENTITY *) a)
+
+
+//
+// Ehci Managment Structures
+//
+#define USB2_HC_DEV_FROM_THIS(a) CR (a, USB2_HC_DEV, Usb2Hc, USB2_HC_DEV_SIGNATURE)
+
+#define USB2_HC_DEV_SIGNATURE EFI_SIGNATURE_32 ('e', 'h', 'c', 'i')
+
+typedef struct _LIST_HEAD {
+ struct _LIST_HEAD *pre;
+ struct _LIST_HEAD *next;
+} LIST_HEAD;
+
+typedef struct _EHCI_ASYNC_REQUEST {
+ UINT8 TransferType;
+ EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunc;
+ VOID *Context;
+ EHCI_ASYNC_REQUEST *Prev;
+ EHCI_ASYNC_REQUEST *Next;
+ EHCI_QH_ENTITY *QhPtr;
+} EHCI_ASYNC_REQUEST;
+
+typedef struct _MEMORY_MANAGE_HEADER {
+ UINT8 *BitArrayPtr;
+ UINTN BitArraySizeInBytes;
+ UINT8 *MemoryBlockPtr;
+ UINTN MemoryBlockSizeInBytes;
+ VOID *Mapping;
+ struct _MEMORY_MANAGE_HEADER *Next;
+} MEMORY_MANAGE_HEADER;
+
+typedef struct _USB2_HC_DEV {
+ UINTN Signature;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_USB2_HC_PROTOCOL Usb2Hc;
+ UINTN PeriodicFrameListLength;
+ VOID *PeriodicFrameListBuffer;
+ VOID *PeriodicFrameListMap;
+ VOID *AsyncList;
+ EHCI_ASYNC_REQUEST *AsyncRequestList;
+ EFI_EVENT AsyncRequestEvent;
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+ MEMORY_MANAGE_HEADER *MemoryHeader;
+ UINT8 Is64BitCapable;
+ UINT32 High32BitAddr;
+} USB2_HC_DEV;
+
+
+//
+// Internal Functions Declaration
+//
+
+//
+// EhciMem Functions
+//
+EFI_STATUS
+CreateMemoryBlock (
+ IN USB2_HC_DEV *HcDev,
+ OUT MEMORY_MANAGE_HEADER **MemoryHeader,
+ IN UINTN MemoryBlockSizeInPages
+ )
+/*++
+
+Routine Description:
+
+ Use PciIo->AllocateBuffer to allocate common buffer for the memory block,
+ and use PciIo->Map to map the common buffer for Bus Master Read/Write.
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ MemoryHeader - MEMORY_MANAGE_HEADER to output
+ MemoryBlockSizeInPages - MemoryBlockSizeInPages
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Fail for no resources
+ EFI_UNSUPPORTED Unsupported currently
+
+--*/
+;
+
+EFI_STATUS
+FreeMemoryHeader (
+ IN USB2_HC_DEV *HcDev,
+ IN MEMORY_MANAGE_HEADER *MemoryHeader
+ )
+/*++
+
+Routine Description:
+
+ Free Memory Header
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ MemoryHeader - MemoryHeader to be freed
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_INVALID_PARAMETER Parameter is error
+
+--*/
+;
+
+VOID
+InsertMemoryHeaderToList (
+ IN MEMORY_MANAGE_HEADER *MemoryHeader,
+ IN MEMORY_MANAGE_HEADER *NewMemoryHeader
+ )
+/*++
+
+Routine Description:
+
+ Insert Memory Header To List
+
+Arguments:
+
+ MemoryHeader - MEMORY_MANAGE_HEADER
+ NewMemoryHeader - MEMORY_MANAGE_HEADER
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+EFI_STATUS
+AllocMemInMemoryBlock (
+ IN MEMORY_MANAGE_HEADER *MemoryHeader,
+ OUT VOID **Pool,
+ IN UINTN NumberOfMemoryUnit
+ )
+/*++
+
+Routine Description:
+
+ Alloc Memory In MemoryBlock
+
+Arguments:
+
+ MemoryHeader - MEMORY_MANAGE_HEADER
+ Pool - Place to store pointer to memory
+ NumberOfMemoryUnit - Number Of Memory Unit
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_NOT_FOUND Can't find the free memory
+
+--*/
+;
+
+BOOLEAN
+IsMemoryBlockEmptied (
+ IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr
+ )
+/*++
+
+Routine Description:
+
+ Is Memory Block Emptied
+
+Arguments:
+
+ MemoryHeaderPtr - MEMORY_MANAGE_HEADER
+
+Returns:
+
+ TRUE Empty
+ FALSE Not Empty
+
+--*/
+;
+
+VOID
+DelinkMemoryBlock (
+ IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,
+ IN MEMORY_MANAGE_HEADER *NeedFreeMemoryHeader
+ )
+/*++
+
+Routine Description:
+
+ Delink Memory Block
+
+Arguments:
+
+ FirstMemoryHeader - MEMORY_MANAGE_HEADER
+ NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+EFI_STATUS
+InitialMemoryManagement (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Initialize Memory Management
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+DeinitialMemoryManagement (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Deinitialize Memory Management
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+EhciAllocatePool (
+ IN USB2_HC_DEV *HcDev,
+ OUT UINT8 **Pool,
+ IN UINTN AllocSize
+ )
+/*++
+
+Routine Description:
+
+ Ehci Allocate Pool
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Pool - Place to store pointer to the memory buffer
+ AllocSize - Alloc Size
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+VOID
+EhciFreePool (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 *Pool,
+ IN UINTN AllocSize
+ )
+/*++
+
+Routine Description:
+
+ Uhci Free Pool
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+ Pool - Pool to free
+ AllocSize - Pool size
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+//
+// EhciReg Functions
+//
+EFI_STATUS
+ReadEhcCapabiltiyReg (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 CapabiltiyRegAddr,
+ IN OUT UINT32 *Data
+ )
+/*++
+
+Routine Description:
+
+ Read Ehc Capabitlity register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ CapabiltiyRegAddr - Ehc Capability register address
+ Data - A pointer to data read from register
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+ReadEhcOperationalReg (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 OperationalRegAddr,
+ IN OUT UINT32 *Data
+ )
+/*++
+
+Routine Description:
+
+ Read Ehc Operation register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ OperationalRegAddr - Ehc Operation register address
+ Data - A pointer to data read from register
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+WriteEhcOperationalReg (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 OperationalRegAddr,
+ IN UINT32 Data
+ )
+/*++
+
+Routine Description:
+
+ Write Ehc Operation register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ OperationalRegAddr - Ehc Operation register address
+ Data - 32bit write to register
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+SetEhcDoorbell (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Set Ehc door bell bit
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+SetFrameListLen (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Set the length of Frame List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Length - the required length of frame list
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_INVALID_PARAMETER Invalid parameter
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+BOOLEAN
+IsFrameListProgrammable (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether frame list is programmable
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Programmable
+ FALSE Unprogrammable
+
+--*/
+;
+
+BOOLEAN
+IsPeriodicScheduleEnabled (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether periodic schedule is enabled
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Enabled
+ FALSE Disabled
+
+--*/
+;
+
+BOOLEAN
+IsAsyncScheduleEnabled (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether asynchronous schedule is enabled
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Enabled
+ FALSE Disabled
+
+--*/
+;
+
+BOOLEAN
+IsEhcPortEnabled (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 PortNum
+ )
+/*++
+
+Routine Description:
+
+ Whether port is enabled
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Enabled
+ FALSE Disabled
+
+--*/
+;
+
+BOOLEAN
+IsEhcReseted (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether Ehc is halted
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Reseted
+ FALSE Unreseted
+
+--*/
+;
+
+BOOLEAN
+IsEhcHalted (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether Ehc is halted
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Halted
+ FALSE Not halted
+
+--*/
+;
+
+BOOLEAN
+IsEhcSysError (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether Ehc is system error
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE System error
+ FALSE No system error
+
+--*/
+;
+
+BOOLEAN
+IsHighSpeedDevice (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 PortNum
+ )
+/*++
+
+Routine Description:
+
+ Whether high speed device attached
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE High speed
+ FALSE Full speed
+
+--*/
+;
+
+EFI_STATUS
+WaitForEhcReset (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ wait for Ehc reset or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+;
+
+EFI_STATUS
+WaitForEhcHalt (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ wait for Ehc halt or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+;
+
+EFI_STATUS
+WaitForEhcNotHalt (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ wait for Ehc not halt or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+;
+
+EFI_STATUS
+WaitForEhcDoorbell (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for periodic schedule disable or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+;
+
+EFI_STATUS
+WaitForAsyncScheduleEnable (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for Ehc asynchronous schedule enable or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+;
+
+EFI_STATUS
+WaitForAsyncScheduleDisable (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for Ehc asynchronous schedule disable or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+;
+
+EFI_STATUS
+WaitForPeriodicScheduleEnable (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for Ehc periodic schedule enable or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+;
+
+EFI_STATUS
+WaitForPeriodicScheduleDisable (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for periodic schedule disable or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+;
+
+EFI_STATUS
+GetCapabilityLen (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Get the length of capability register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+SetFrameListBaseAddr (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 FrameBuffer
+ )
+/*++
+
+Routine Description:
+
+ Set base address of frame list first entry
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ FrameBuffer - base address of first entry of frame list
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+SetAsyncListAddr (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Set address of first Async schedule Qh
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to first Qh in the Async schedule
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+SetCtrlDataStructSeg (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Set address of first Async schedule Qh
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to first Qh in the Async schedule
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+SetPortRoutingEhc (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Set Ehc port routing bit
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+EnablePeriodicSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Enable periodic schedule
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+DisablePeriodicSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Disable periodic schedule
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+EnableAsynchronousSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Enable asynchrounous schedule
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+DisableAsynchronousSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Disable asynchrounous schedule
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+StartScheduleExecution (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Start Ehc schedule execution
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+ResetEhc (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Reset Ehc
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+ClearEhcAllStatus (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Clear Ehc all status bits
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+//
+// EhciSched Functions
+//
+EFI_STATUS
+InitialPeriodicFrameList (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Initialize Periodic Schedule Frame List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Length - Frame List Length
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+VOID
+DeinitialPeriodicFrameList (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Deinitialize Periodic Schedule Frame List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+EFI_STATUS
+CreatePollingTimer (
+ IN USB2_HC_DEV *HcDev,
+ IN EFI_EVENT_NOTIFY NotifyFunction
+ )
+/*++
+
+Routine Description:
+
+ Create Async Request Polling Timer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ NotifyFunction - Timer Notify Function
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+DestoryPollingTimer (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Destory Async Request Polling Timer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+StartPollingTimer (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Start Async Request Polling Timer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+StopPollingTimer (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Stop Async Request Polling Timer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+CreateQh (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DeviceAddr,
+ IN UINT8 Endpoint,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaxPacketLen,
+ OUT EHCI_QH_ENTITY **QhPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qh Structure and Pre-Initialize
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DeviceAddr - Address of Device
+ Endpoint - Endpoint Number
+ DeviceSpeed - Device Speed
+ MaxPacketLen - Max Length of one Packet
+ QhPtrPtr - A pointer of pointer to Qh for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+CreateControlQh (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DeviceAddr,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaxPacketLen,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT EHCI_QH_ENTITY **QhPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qh for Control Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DeviceAddr - Address of Device
+ DeviceSpeed - Device Speed
+ MaxPacketLen - Max Length of one Packet
+ Translator - Translator Transaction for SplitX
+ QhPtrPtr - A pointer of pointer to Qh for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+CreateBulkQh (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DeviceAddr,
+ IN UINT8 EndPointAddr,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 DataToggle,
+ IN UINTN MaxPacketLen,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT EHCI_QH_ENTITY **QhPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qh for Bulk Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DeviceAddr - Address of Device
+ EndPointAddr - Address of Endpoint
+ DeviceSpeed - Device Speed
+ MaxPacketLen - Max Length of one Packet
+ Translator - Translator Transaction for SplitX
+ QhPtrPtr - A pointer of pointer to Qh for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+CreateInterruptQh (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DeviceAddr,
+ IN UINT8 EndPointAddr,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 DataToggle,
+ IN UINTN MaxPacketLen,
+ IN UINTN Interval,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT EHCI_QH_ENTITY **QhPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qh for Control Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DeviceAddr - Address of Device
+ EndPointAddr - Address of Endpoint
+ DeviceSpeed - Device Speed
+ MaxPacketLen - Max Length of one Packet
+ Interval - value of interval
+ Translator - Translator Transaction for SplitX
+ QhPtrPtr - A pointer of pointer to Qh for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+VOID
+DestoryQh (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Destory Qh Structure
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to Qh
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+EFI_STATUS
+CreateQtd (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 *DataPtr,
+ IN UINTN DataLen,
+ IN UINT8 PktId,
+ IN UINT8 Toggle,
+ IN UINT8 QtdStatus,
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qtd Structure and Pre-Initialize it
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DataPtr - A pointer to user data buffer to transfer
+ DataLen - Length of user data to transfer
+ PktId - Packet Identification of this Qtd
+ Toggle - Data Toggle of this Qtd
+ QtdStatus - Default value of status of this Qtd
+ QtdPtrPtr - A pointer of pointer to Qtd for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+;
+
+EFI_STATUS
+CreateSetupQtd (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 *DevReqPtr,
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qtd Structure for Setup
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DevReqPtr - A pointer to Device Request Data
+ QtdPtrPtr - A pointer of pointer to Qtd for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+;
+
+EFI_STATUS
+CreateDataQtd (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 *DataPtr,
+ IN UINTN DataLen,
+ IN UINT8 PktId,
+ IN UINT8 Toggle,
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qtd Structure for data
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DataPtr - A pointer to user data buffer to transfer
+ DataLen - Length of user data to transfer
+ PktId - Packet Identification of this Qtd
+ Toggle - Data Toggle of this Qtd
+ QtdPtrPtr - A pointer of pointer to Qtd for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+;
+
+EFI_STATUS
+CreateStatusQtd (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 PktId,
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qtd Structure for status
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ PktId - Packet Identification of this Qtd
+ QtdPtrPtr - A pointer of pointer to Qtd for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+;
+
+EFI_STATUS
+CreateAltQtd (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 PktId,
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qtd Structure for Alternative
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ PktId - Packet Identification of this Qtd
+ QtdPtrPtr - A pointer of pointer to Qtd for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+;
+
+EFI_STATUS
+CreateControlQtds (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DataPktId,
+ IN UINT8 *RequestCursor,
+ IN UINT8 *DataCursor,
+ IN UINTN DataLen,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT EHCI_QTD_ENTITY **ControlQtdsHead
+ )
+/*++
+
+Routine Description:
+
+ Create Qtds list for Control Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DataPktId - Packet Identification of Data Qtds
+ RequestCursor - A pointer to request structure buffer to transfer
+ DataCursor - A pointer to user data buffer to transfer
+ DataLen - Length of user data to transfer
+ ControlQtdsHead - A pointer of pointer to first Qtd for control tranfer for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+CreateBulkOrInterruptQtds (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 PktId,
+ IN UINT8 *DataCursor,
+ IN UINTN DataLen,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT EHCI_QTD_ENTITY **QtdsHead
+ )
+/*++
+
+Routine Description:
+
+ Create Qtds list for Bulk or Interrupt Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ PktId - Packet Identification of Qtds
+ DataCursor - A pointer to user data buffer to transfer
+ DataLen - Length of user data to transfer
+ DataToggle - Data Toggle to start
+ Translator - Translator Transaction for SplitX
+ QtdsHead - A pointer of pointer to first Qtd for control tranfer for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+VOID
+DestoryQtds (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QTD_ENTITY *FirstQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Destory all Qtds in the list
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ FirstQtdPtr - A pointer to first Qtd in the list
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+VOID
+LinkQtdToQtd (
+ IN EHCI_QTD_ENTITY *PreQtdPtr,
+ IN EHCI_QTD_ENTITY *QtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Link Qtds together
+
+Arguments:
+
+ PreQtdPtr - A pointer to pre Qtd
+ QtdPtr - A pointer to next Qtd
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+VOID
+LinkQtdsToAltQtd (
+ IN EHCI_QTD_ENTITY *FirstQtdPtr,
+ IN EHCI_QTD_ENTITY *AltQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Link AlterQtds together
+
+Arguments:
+
+ FirstQtdPtr - A pointer to first Qtd in the list
+ AltQtdPtr - A pointer to alternative Qtd
+
+Returns:
+ VOID
+
+--*/
+;
+
+VOID
+LinkQtdToQh (
+ IN EHCI_QH_ENTITY *QhPtr,
+ IN EHCI_QTD_ENTITY *QtdEntryPtr
+ )
+/*++
+
+Routine Description:
+
+ Link Qtds list to Qh
+
+Arguments:
+
+ QhPtr - A pointer to Qh
+ QtdPtr - A pointer to first Qtd in the list
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+EFI_STATUS
+LinkQhToAsyncList (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Link Qh to Async Schedule List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to Qh
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+UnlinkQhFromAsyncList (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Unlink Qh from Async Schedule List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to Qh
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+VOID
+LinkQhToPeriodicList (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Link Qh to Periodic Schedule List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to Qh
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+VOID
+UnlinkQhFromPeriodicList (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr,
+ IN UINTN Interval
+ )
+/*++
+
+Routine Description:
+
+ Unlink Qh from Periodic Schedule List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to Qh
+ Interval - Interval of this periodic transfer
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+VOID
+LinkToAsyncReqeust (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr
+ )
+/*++
+
+Routine Description:
+
+ Llink AsyncRequest Entry to Async Request List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ AsyncRequestPtr - A pointer to Async Request Entry
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+VOID
+UnlinkFromAsyncReqeust (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr
+ )
+/*++
+
+Routine Description:
+
+ Unlink AsyncRequest Entry from Async Request List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ AsyncRequestPtr - A pointer to Async Request Entry
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+UINTN
+GetNumberOfQtd (
+ IN EHCI_QTD_ENTITY *FirstQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Number of Qtds in the list
+
+Arguments:
+
+ FirstQtdPtr - A pointer to first Qtd in the list
+
+Returns:
+
+ Number of Qtds in the list
+
+--*/
+;
+
+UINTN
+GetNumberOfTransaction (
+ IN UINTN SizeOfData,
+ IN UINTN SizeOfTransaction
+ )
+/*++
+
+Routine Description:
+
+ Number of Transactions in one Qtd
+
+Arguments:
+
+ SizeOfData - Size of one Qtd
+ SizeOfTransaction - Size of one Transaction
+
+Returns:
+
+ Number of Transactions in this Qtd
+
+--*/
+;
+
+UINTN
+GetCapacityOfQtd (
+ IN UINT8 *BufferCursor
+ )
+/*++
+
+Routine Description:
+
+ Get Capacity of Qtd
+
+Arguments:
+
+ BufferCursor - BufferCursor of the Qtd
+
+Returns:
+
+ Capacity of Qtd
+
+--*/
+;
+
+UINTN
+GetApproxiOfInterval (
+ IN UINTN Interval
+ )
+/*++
+
+Routine Description:
+
+ Get the approximate value in the 2 index sequence
+
+Arguments:
+
+ Interval - the value of interval
+
+Returns:
+
+ approximate value of interval in the 2 index sequence
+
+--*/
+;
+
+EHCI_QTD_HW *
+GetQtdNextPointer (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Get Qtd next pointer field
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ A pointer to next hardware Qtd structure
+
+--*/
+;
+
+BOOLEAN
+IsQtdStatusActive (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Whether Qtd status is active or not
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ TRUE Active
+ FALSE Inactive
+
+--*/
+;
+
+BOOLEAN
+IsQtdStatusHalted (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Whether Qtd status is halted or not
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ TRUE Halted
+ FALSE Not halted
+
+--*/
+;
+
+BOOLEAN
+IsQtdStatusBufferError (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Whether Qtd status is buffer error or not
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ TRUE Buffer error
+ FALSE No buffer error
+
+--*/
+;
+
+BOOLEAN
+IsQtdStatusBabbleError (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Whether Qtd status is babble error or not
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ TRUE Babble error
+ FALSE No babble error
+
+--*/
+;
+
+BOOLEAN
+IsQtdStatusTransactionError (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Whether Qtd status is transaction error or not
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ TRUE Transaction error
+ FALSE No transaction error
+
+--*/
+;
+
+BOOLEAN
+IsDataInTransfer (
+ IN UINT8 EndPointAddress
+ )
+/*++
+
+Routine Description:
+
+ Whether is a DataIn direction transfer
+
+Arguments:
+
+ EndPointAddress - address of the endpoint
+
+Returns:
+
+ TRUE DataIn
+ FALSE DataOut
+
+--*/
+;
+
+EFI_STATUS
+MapDataBuffer (
+ IN USB2_HC_DEV *HcDev,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ OUT UINT8 *PktId,
+ OUT UINT8 **DataCursor,
+ OUT VOID **DataMap
+ )
+/*++
+
+Routine Description:
+
+ Map address of user data buffer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ TransferDirection - direction of transfer
+ Data - A pointer to user data buffer
+ DataLength - length of user data
+ PktId - Packte Identificaion
+ DataCursor - mapped address to return
+ DataMap - identificaion of this mapping to return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+EFI_STATUS
+MapRequestBuffer (
+ IN USB2_HC_DEV *HcDev,
+ IN OUT VOID *Request,
+ OUT UINT8 **RequestCursor,
+ OUT VOID **RequestMap
+ )
+/*++
+
+Routine Description:
+
+ Map address of request structure buffer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Request - A pointer to request structure
+ RequestCursor - Mapped address of request structure to return
+ RequestMap - Identificaion of this mapping to return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+VOID
+SetQtdBufferPointer (
+ IN EHCI_QTD_HW *QtdHwPtr,
+ IN VOID *DataPtr,
+ IN UINTN DataLen
+ )
+/*++
+
+Routine Description:
+
+ Set data buffer pointers in Qtd
+
+Arguments:
+
+ QtdHwPtr - A pointer to Qtd hardware structure
+ DataPtr - A pointer to user data buffer
+ DataLen - Length of the user data buffer
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+EHCI_QTD_HW *
+GetQtdAlternateNextPointer (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Get Qtd alternate next pointer field
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ A pointer to hardware alternate Qtd
+
+--*/
+;
+
+VOID
+ZeroOutQhOverlay (
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Zero out the fields in Qh structure
+
+Arguments:
+
+ QhPtr - A pointer to Qh structure
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+VOID
+UpdateAsyncRequestTransfer (
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr,
+ IN UINT32 TransferResult,
+ IN UINTN ErrTDPos
+ )
+/*++
+
+Routine Description:
+
+ Update asynchronous request transfer
+
+Arguments:
+
+ AsyncRequestPtr - A pointer to async request
+ TransferResult - transfer result
+ ErrQtdPos - postion of error Qtd
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+
+EFI_STATUS
+DeleteAsyncRequestTransfer (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ OUT UINT8 *DataToggle
+ )
+/*++
+
+Routine Description:
+
+ Delete all asynchronous request transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DeviceAddress - address of usb device
+ EndPointAddress - address of endpoint
+ DataToggle - stored data toggle
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+VOID
+CleanUpAllAsyncRequestTransfer (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Clean up all asynchronous request transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+ VOID
+
+--*/
+;
+
+EFI_STATUS
+ExecuteTransfer (
+ IN USB2_HC_DEV *HcDev,
+ IN BOOLEAN IsControl,
+ IN EHCI_QH_ENTITY *QhPtr,
+ IN OUT UINTN *ActualLen,
+ OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+Routine Description:
+
+ Execute Bulk or SyncInterrupt Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ IsControl - Is control transfer or not
+ QhPtr - A pointer to Qh
+ ActualLen - Actual transfered Len
+ DataToggle - Data Toggle
+ TimeOut - TimeOut threshold
+ TransferResult - Transfer result
+
+Returns:
+
+ EFI_SUCCESS Sucess
+ EFI_DEVICE_ERROR Error
+
+--*/
+;
+
+BOOLEAN
+CheckQtdsTransferResult (
+ IN BOOLEAN IsControl,
+ IN EHCI_QH_ENTITY *QhPtr,
+ OUT UINT32 *Result,
+ OUT UINTN *ErrQtdPos,
+ OUT UINTN *ActualLen
+ )
+/*++
+
+Routine Description:
+
+ Check transfer result of Qtds
+
+Arguments:
+
+ IsControl - Is control transfer or not
+ QhPtr - A pointer to Qh
+ Result - Transfer result
+ ErrQtdPos - Error TD Position
+ ActualLen - Actual Transfer Size
+
+Returns:
+
+ TRUE Qtds finished
+ FALSE Not finish
+
+--*/
+;
+
+EFI_STATUS
+AsyncRequestMoniter (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Interrupt transfer periodic check handler
+
+Arguments:
+
+ Event - Interrupt event
+ Context - Pointer to USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.msa b/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.msa
new file mode 100644
index 0000000000..a44b5a4a75
--- /dev/null
+++ b/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.msa
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+ <MsaHeader>
+ <ModuleName>Ehci</ModuleName>
+ <ModuleType>UEFI_DRIVER</ModuleType>
+ <GuidValue>BDFE430E-8F2A-4db0-9991-6F856594777E</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Component description file for Ehci module</Abstract>
+ <Description>This module provides USB2 Host Controller Protocol implementation for Enhanced Host Controller Interface</Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
+ <License>All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>Ehci</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverModelLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>Ehci.c</Filename>
+ <Filename>EhciMem.c</Filename>
+ <Filename>EhciReg.c</Filename>
+ <Filename>EhciSched.c</Filename>
+ <Filename>ComponentName.c</Filename>
+ <Filename>Ehci.h</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="TO_START">
+ <ProtocolCName>gEfiPciIoProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiUsb2HcProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
+ <Extern>
+ <DriverBinding>gEhciDriverBinding</DriverBinding>
+ </Extern>
+ <Extern>
+ <ComponentName>gEhciComponentName</ComponentName>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea> \ No newline at end of file
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciMem.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciMem.c
new file mode 100644
index 0000000000..2f35f77848
--- /dev/null
+++ b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciMem.c
@@ -0,0 +1,761 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EhciMem.c
+
+Abstract:
+
+
+Revision History
+--*/
+
+#include "Ehci.h"
+
+
+EFI_STATUS
+CreateMemoryBlock (
+ IN USB2_HC_DEV *HcDev,
+ OUT MEMORY_MANAGE_HEADER **MemoryHeader,
+ IN UINTN MemoryBlockSizeInPages
+ )
+/*++
+
+Routine Description:
+
+ Use PciIo->AllocateBuffer to allocate common buffer for the memory block,
+ and use PciIo->Map to map the common buffer for Bus Master Read/Write.
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ MemoryHeader - MEMORY_MANAGE_HEADER to output
+ MemoryBlockSizeInPages - MemoryBlockSizeInPages
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Fail for no resources
+ EFI_UNSUPPORTED Unsupported currently
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *CommonBuffer;
+ EFI_PHYSICAL_ADDRESS MappedAddress;
+ UINTN MemoryBlockSizeInBytes;
+ VOID *Mapping;
+
+ //
+ // Allocate memory for MemoryHeader
+ //
+ *MemoryHeader = AllocateZeroPool (sizeof (MEMORY_MANAGE_HEADER));
+ if (*MemoryHeader == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ (*MemoryHeader)->Next = NULL;
+
+ //
+ // set Memory block size
+ //
+ (*MemoryHeader)->MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);
+
+ //
+ // each bit in Bit Array will manage 32 bytes memory in memory block
+ //
+ (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / 32) / 8;
+
+ //
+ // Allocate memory for BitArray
+ //
+ (*MemoryHeader)->BitArrayPtr = AllocateZeroPool ((*MemoryHeader)->BitArraySizeInBytes);
+ if ((*MemoryHeader)->BitArrayPtr == NULL) {
+ gBS->FreePool (*MemoryHeader);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Memory Block uses MemoryBlockSizeInPages pages,
+ // and it is allocated as common buffer use.
+ //
+ Status = HcDev->PciIo->AllocateBuffer (
+ HcDev->PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ MemoryBlockSizeInPages,
+ &CommonBuffer,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool ((*MemoryHeader)->BitArrayPtr);
+ gBS->FreePool (*MemoryHeader);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);
+ Status = HcDev->PciIo->Map (
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ CommonBuffer,
+ &MemoryBlockSizeInBytes,
+ &MappedAddress,
+ &Mapping
+ );
+ //
+ // If returned Mapped size is less than the size
+ // we request,do not support.
+ //
+ if (EFI_ERROR (Status) || (MemoryBlockSizeInBytes != EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages))) {
+ HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);
+ gBS->FreePool ((*MemoryHeader)->BitArrayPtr);
+ gBS->FreePool (*MemoryHeader);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Data structure involved by host controller
+ // should be restricted into the same 4G
+ //
+ if (HcDev->Is64BitCapable != 0) {
+ if (HcDev->High32BitAddr != GET_32B_TO_63B (MappedAddress)) {
+ HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);
+ HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);
+ gBS->FreePool ((*MemoryHeader)->BitArrayPtr);
+ gBS->FreePool (*MemoryHeader);
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Set Memory block initial address
+ //
+ (*MemoryHeader)->MemoryBlockPtr = (UINT8 *) ((UINTN) MappedAddress);
+ (*MemoryHeader)->Mapping = Mapping;
+
+ ZeroMem (
+ (*MemoryHeader)->MemoryBlockPtr,
+ EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages)
+ );
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FreeMemoryHeader (
+ IN USB2_HC_DEV *HcDev,
+ IN MEMORY_MANAGE_HEADER *MemoryHeader
+ )
+/*++
+
+Routine Description:
+
+ Free Memory Header
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ MemoryHeader - MemoryHeader to be freed
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_INVALID_PARAMETER Parameter is error
+
+--*/
+{
+ if ((MemoryHeader == NULL) || (HcDev == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // unmap the common buffer used by the memory block
+ //
+ HcDev->PciIo->Unmap (HcDev->PciIo, MemoryHeader->Mapping);
+
+ //
+ // free common buffer
+ //
+ HcDev->PciIo->FreeBuffer (
+ HcDev->PciIo,
+ EFI_SIZE_TO_PAGES (MemoryHeader->MemoryBlockSizeInBytes),
+ MemoryHeader->MemoryBlockPtr
+ );
+ //
+ // free bit array
+ //
+ gBS->FreePool (MemoryHeader->BitArrayPtr);
+ //
+ // free memory header
+ //
+ gBS->FreePool (MemoryHeader);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EhciAllocatePool (
+ IN USB2_HC_DEV *HcDev,
+ OUT UINT8 **Pool,
+ IN UINTN AllocSize
+ )
+/*++
+
+Routine Description:
+
+ Ehci Allocate Pool
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Pool - Place to store pointer to the memory buffer
+ AllocSize - Alloc Size
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ MEMORY_MANAGE_HEADER *MemoryHeader;
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;
+ MEMORY_MANAGE_HEADER *NewMemoryHeader;
+ UINTN RealAllocSize;
+ UINTN MemoryBlockSizeInPages;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ *Pool = NULL;
+
+ MemoryHeader = HcDev->MemoryHeader;
+ ASSERT (MemoryHeader != NULL);
+
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);
+
+ //
+ // allocate unit is 32 bytes (align on 32 byte)
+ //
+ if (AllocSize & 0x1F) {
+ RealAllocSize = (AllocSize / 32 + 1) * 32;
+ } else {
+ RealAllocSize = AllocSize;
+ }
+
+ //
+ // There may be linked MemoryHeaders.
+ // To allocate a free pool in Memory blocks,
+ // must search in the MemoryHeader link list
+ // until enough free pool is found.
+ //
+ Status = EFI_NOT_FOUND;
+ for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
+
+ Status = AllocMemInMemoryBlock (
+ TempHeaderPtr,
+ Pool,
+ RealAllocSize / 32
+ );
+ if (!EFI_ERROR (Status)) {
+ ZeroMem (*Pool, AllocSize);
+ gBS->RestoreTPL (OldTpl);
+ return EFI_SUCCESS;
+ }
+ }
+
+ gBS->RestoreTPL (OldTpl);
+
+ //
+ // There is no enough memory,
+ // Create a new Memory Block
+ //
+
+ //
+ // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,
+ // just allocate a large enough memory block.
+ //
+ if (RealAllocSize > EFI_PAGES_TO_SIZE (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES)) {
+ MemoryBlockSizeInPages = EFI_SIZE_TO_PAGES (RealAllocSize) + 1;
+ } else {
+ MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
+ }
+
+ Status = CreateMemoryBlock (HcDev, &NewMemoryHeader, MemoryBlockSizeInPages);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);
+
+ //
+ // Link the new Memory Block to the Memory Header list
+ //
+ InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);
+
+ Status = AllocMemInMemoryBlock (
+ NewMemoryHeader,
+ Pool,
+ RealAllocSize / 32
+ );
+ if (!EFI_ERROR (Status)) {
+ ZeroMem (*Pool, AllocSize);
+ }
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+VOID
+EhciFreePool (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 *Pool,
+ IN UINTN AllocSize
+ )
+/*++
+
+Routine Description:
+
+ Uhci Free Pool
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+ Pool - Pool to free
+ AllocSize - Pool size
+
+Returns:
+
+ VOID
+
+--*/
+{
+ MEMORY_MANAGE_HEADER *MemoryHeader;
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;
+ UINTN StartBytePos;
+ UINTN Index;
+ UINT8 StartBitPos;
+ UINT8 Index2;
+ UINTN Count;
+ UINTN RealAllocSize;
+ EFI_TPL OldTpl;
+
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);
+
+ MemoryHeader = HcDev->MemoryHeader;
+
+ //
+ // allocate unit is 32 byte (align on 32 byte)
+ //
+ if (AllocSize & 0x1F) {
+ RealAllocSize = (AllocSize / 32 + 1) * 32;
+ } else {
+ RealAllocSize = AllocSize;
+ }
+
+ //
+ // scan the memory header linked list for
+ // the asigned memory to free.
+ //
+ for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
+
+ if ((Pool >= TempHeaderPtr->MemoryBlockPtr) &&
+ ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr + TempHeaderPtr->MemoryBlockSizeInBytes))
+ ) {
+ //
+ // Pool is in the Memory Block area,
+ // find the start byte and bit in the bit array
+ //
+ StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8;
+ StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) & 0x7);
+
+ //
+ // reset associated bits in bit arry
+ //
+ for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {
+ TempHeaderPtr->BitArrayPtr[Index] ^= (UINT8) (bit (Index2));
+ Index2++;
+ if (Index2 == 8) {
+ Index += 1;
+ Index2 = 0;
+ }
+ }
+ //
+ // break the loop
+ //
+ break;
+ }
+ }
+
+ //
+ // Release emptied memory blocks (only if the memory block is not
+ // the first one in the memory header list
+ //
+ for (TempHeaderPtr = MemoryHeader->Next; TempHeaderPtr != NULL;) {
+
+ ASSERT (MemoryHeader->Next != NULL);
+
+ if (IsMemoryBlockEmptied (TempHeaderPtr)) {
+
+ DelinkMemoryBlock (MemoryHeader, TempHeaderPtr);
+ //
+ // when the TempHeaderPtr is freed in FreeMemoryHeader(),
+ // the TempHeaderPtr is pointing to nonsense content.
+ //
+ gBS->RestoreTPL (OldTpl);
+ FreeMemoryHeader (HcDev, TempHeaderPtr);
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);
+ //
+ // reset the TempHeaderPtr, continue search for
+ // another empty memory block.
+ //
+ TempHeaderPtr = MemoryHeader->Next;
+ continue;
+ }
+
+ TempHeaderPtr = TempHeaderPtr->Next;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+}
+
+VOID
+InsertMemoryHeaderToList (
+ IN MEMORY_MANAGE_HEADER *MemoryHeader,
+ IN MEMORY_MANAGE_HEADER *NewMemoryHeader
+ )
+/*++
+
+Routine Description:
+
+ Insert Memory Header To List
+
+Arguments:
+
+ MemoryHeader - MEMORY_MANAGE_HEADER
+ NewMemoryHeader - MEMORY_MANAGE_HEADER
+
+Returns:
+
+ VOID
+
+--*/
+{
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;
+
+ for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
+ if (TempHeaderPtr->Next == NULL) {
+ TempHeaderPtr->Next = NewMemoryHeader;
+ break;
+ }
+ }
+}
+
+EFI_STATUS
+AllocMemInMemoryBlock (
+ IN MEMORY_MANAGE_HEADER *MemoryHeader,
+ OUT VOID **Pool,
+ IN UINTN NumberOfMemoryUnit
+ )
+/*++
+
+Routine Description:
+
+ Alloc Memory In MemoryBlock
+
+Arguments:
+
+ MemoryHeader - MEMORY_MANAGE_HEADER
+ Pool - Place to store pointer to memory
+ NumberOfMemoryUnit - Number Of Memory Unit
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_NOT_FOUND Can't find the free memory
+
+--*/
+{
+ UINTN TempBytePos;
+ UINTN FoundBytePos;
+ UINT8 Index;
+ UINT8 FoundBitPos;
+ UINT8 ByteValue;
+ UINT8 BitValue;
+ UINTN NumberOfZeros;
+ UINTN Count;
+
+ FoundBytePos = 0;
+ FoundBitPos = 0;
+ ByteValue = MemoryHeader->BitArrayPtr[0];
+ NumberOfZeros = 0;
+ Index = 0;
+
+ for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {
+
+ //
+ // Pop out BitValue from a byte in TempBytePos.
+ //
+ BitValue = (UINT8) (ByteValue & 0x1);
+
+ //
+ // right shift the byte
+ //
+ ByteValue /= 2;
+
+ if (BitValue == 0) {
+ //
+ // Found a free bit, the NumberOfZeros only record the number
+ // of those consecutive zeros
+ //
+ NumberOfZeros++;
+ //
+ // Found enough consecutive free space, break the loop
+ //
+ if (NumberOfZeros >= NumberOfMemoryUnit) {
+ break;
+ }
+ } else {
+ //
+ // Encountering a '1', meant the bit is ocupied.
+ //
+ if (NumberOfZeros >= NumberOfMemoryUnit) {
+ //
+ // Found enough consecutive free space,break the loop
+ //
+ break;
+ } else {
+ //
+ // the NumberOfZeros only record the number of those consecutive zeros,
+ // so reset the NumberOfZeros to 0 when encountering '1' before finding
+ // enough consecutive '0's
+ //
+ NumberOfZeros = 0;
+ //
+ // reset the (FoundBytePos,FoundBitPos) to the position of '1'
+ //
+ FoundBytePos = TempBytePos;
+ FoundBitPos = Index;
+ }
+ }
+
+ //
+ // step forward a bit
+ //
+ Index++;
+ if (Index == 8) {
+ //
+ // step forward a byte, getting the byte value,
+ // and reset the bit pos.
+ //
+ TempBytePos += 1;
+ ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];
+ Index = 0;
+ }
+ }
+
+ if (NumberOfZeros < NumberOfMemoryUnit) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Found enough free space.
+ //
+
+ //
+ // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:
+ // 1)(FoundBytePos,FoundBitPos) record the position
+ // of the last '1' before the consecutive '0's, it must
+ // be adjusted to the start position of the consecutive '0's.
+ // 2)the start address of the consecutive '0's is just the start of
+ // the bitarray. so no need to adjust the values of
+ // (FoundBytePos,FoundBitPos).
+ //
+ if ((MemoryHeader->BitArrayPtr[FoundBytePos] & bit (FoundBitPos)) != 0) {
+ FoundBitPos += 1;
+ }
+
+ //
+ // Have the (FoundBytePos,FoundBitPos) make sense.
+ //
+ if (FoundBitPos > 7) {
+ FoundBytePos += 1;
+ FoundBitPos -= 8;
+ }
+
+ //
+ // Set the memory as allocated
+ //
+ for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) {
+
+ MemoryHeader->BitArrayPtr[TempBytePos] |= bit (Index);
+ Index++;
+ if (Index == 8) {
+ TempBytePos += 1;
+ Index = 0;
+ }
+ }
+
+ *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * 32;
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+IsMemoryBlockEmptied (
+ IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr
+ )
+/*++
+
+Routine Description:
+
+ Is Memory Block Emptied
+
+Arguments:
+
+ MemoryHeaderPtr - MEMORY_MANAGE_HEADER
+
+Returns:
+
+ TRUE Empty
+ FALSE Not Empty
+
+--*/
+{
+ UINTN Index;
+
+ for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {
+ if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+VOID
+DelinkMemoryBlock (
+ IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,
+ IN MEMORY_MANAGE_HEADER *NeedFreeMemoryHeader
+ )
+/*++
+
+Routine Description:
+
+ Delink Memory Block
+
+Arguments:
+
+ FirstMemoryHeader - MEMORY_MANAGE_HEADER
+ NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER
+
+Returns:
+
+ VOID
+
+--*/
+{
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;
+
+ if ((FirstMemoryHeader == NULL) || (NeedFreeMemoryHeader == NULL)) {
+ return ;
+ }
+
+ for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
+
+ if (TempHeaderPtr->Next == NeedFreeMemoryHeader) {
+ //
+ // Link the before and after
+ //
+ TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;
+ break;
+ }
+ }
+}
+
+EFI_STATUS
+InitialMemoryManagement (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Initialize Memory Management
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ MEMORY_MANAGE_HEADER *MemoryHeader;
+ UINTN MemPages;
+
+ MemPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
+ Status = CreateMemoryBlock (HcDev, &MemoryHeader, MemPages);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+
+ HcDev->MemoryHeader = MemoryHeader;
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+DeinitialMemoryManagement (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Deinitialize Memory Management
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;
+
+ for (TempHeaderPtr = HcDev->MemoryHeader->Next; TempHeaderPtr != NULL;) {
+
+ DelinkMemoryBlock (HcDev->MemoryHeader, TempHeaderPtr);
+ //
+ // when the TempHeaderPtr is freed in FreeMemoryHeader(),
+ // the TempHeaderPtr is pointing to nonsense content.
+ //
+ FreeMemoryHeader (HcDev, TempHeaderPtr);
+ //
+ // reset the TempHeaderPtr,continue free another memory block.
+ //
+ TempHeaderPtr = HcDev->MemoryHeader->Next;
+ }
+
+ FreeMemoryHeader (HcDev, HcDev->MemoryHeader);
+
+ return EFI_SUCCESS;
+}
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c
new file mode 100644
index 0000000000..9ce816ecc9
--- /dev/null
+++ b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciReg.c
@@ -0,0 +1,1539 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Ehchlp.c
+
+Abstract:
+
+
+Revision History
+--*/
+
+#include "Ehci.h"
+
+
+EFI_STATUS
+ReadEhcCapabiltiyReg (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 CapabiltiyRegAddr,
+ IN OUT UINT32 *Data
+ )
+/*++
+
+Routine Description:
+
+ Read Ehc Capabitlity register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ CapabiltiyRegAddr - Ehc Capability register address
+ Data - A pointer to data read from register
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ return HcDev->PciIo->Mem.Read (
+ HcDev->PciIo,
+ EfiPciIoWidthUint32,
+ USB_BAR_INDEX,
+ (UINT64) CapabiltiyRegAddr,
+ 1,
+ Data
+ );
+}
+
+EFI_STATUS
+ReadEhcOperationalReg (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 OperationalRegAddr,
+ IN OUT UINT32 *Data
+ )
+/*++
+
+Routine Description:
+
+ Read Ehc Operation register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ OperationalRegAddr - Ehc Operation register address
+ Data - A pointer to data read from register
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ ASSERT (mUsbCapabilityLen);
+ return HcDev->PciIo->Mem.Read (
+ HcDev->PciIo,
+ EfiPciIoWidthUint32,
+ USB_BAR_INDEX,
+ (UINT64) (OperationalRegAddr + mUsbCapabilityLen),
+ 1,
+ Data
+ );
+}
+
+EFI_STATUS
+WriteEhcOperationalReg (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 OperationalRegAddr,
+ IN UINT32 Data
+ )
+/*++
+
+Routine Description:
+
+ Write Ehc Operation register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ OperationalRegAddr - Ehc Operation register address
+ Data - 32bit write to register
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ ASSERT (mUsbCapabilityLen);
+ return HcDev->PciIo->Mem.Write (
+ HcDev->PciIo,
+ EfiPciIoWidthUint32,
+ USB_BAR_INDEX,
+ (UINT64) (OperationalRegAddr + mUsbCapabilityLen),
+ 1,
+ &Data
+ );
+}
+
+EFI_STATUS
+GetCapabilityLen (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Get the length of capability register
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 CapabilityLenAddr;
+
+ CapabilityLenAddr = CAPLENGTH;
+
+ Status = ReadEhcCapabiltiyReg (
+ HcDev,
+ CapabilityLenAddr,
+ &mUsbCapabilityLen
+ );
+ mUsbCapabilityLen = (UINT8) mUsbCapabilityLen;
+
+ return Status;
+}
+
+EFI_STATUS
+SetFrameListLen (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Set the length of Frame List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Length - the required length of frame list
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_INVALID_PARAMETER Invalid parameter
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+
+ UsbCommandAddr = USBCMD;
+
+ if (256 != Length && 512 != Length) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ &UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ if (256 == Length) {
+ UsbCommandReg |= USBCMD_FLS_256;
+ } else {
+ UsbCommandReg |= USBCMD_FLS_512;
+ }
+
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+SetFrameListBaseAddr (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT32 FrameBuffer
+ )
+/*++
+
+Routine Description:
+
+ Set base address of frame list first entry
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ FrameBuffer - base address of first entry of frame list
+
+Returns:
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 PeriodicListBaseAddr;
+ UINT32 PeriodicListBaseReg;
+
+ Status = EFI_SUCCESS;
+ PeriodicListBaseAddr = PERIODICLISTBASE;
+ PeriodicListBaseReg = FrameBuffer & 0xfffff000;
+
+ if (IsEhcHalted (HcDev)) {
+
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ PeriodicListBaseAddr,
+ PeriodicListBaseReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+SetAsyncListAddr (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Set address of first Async schedule Qh
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to first Qh in the Async schedule
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 AsyncListAddr;
+ UINT32 AsyncListReg;
+
+ AsyncListAddr = ASYNCLISTADDR;
+ AsyncListReg = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh));
+
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ AsyncListAddr,
+ AsyncListReg
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+SetCtrlDataStructSeg (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Set register of control and data structure segment
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 CtrlDsSegmentAddr;
+ UINT32 CtrlDsSegmentReg;
+
+ CtrlDsSegmentAddr = CTRLDSSGMENT;
+ CtrlDsSegmentReg = HcDev->High32BitAddr;
+
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ CtrlDsSegmentAddr,
+ CtrlDsSegmentReg
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+SetPortRoutingEhc (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Set Ehc port routing bit
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 ConfigFlagAddr;
+ UINT32 ConfigFlagReg;
+
+ ConfigFlagAddr = CONFIGFLAG;
+
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ ConfigFlagAddr,
+ &ConfigFlagReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ ConfigFlagReg |= CONFIGFLAG_CF;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ ConfigFlagAddr,
+ ConfigFlagReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+SetEhcDoorbell (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Set Ehc door bell bit
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+
+ UsbCommandAddr = USBCMD;
+
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ &UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ UsbCommandReg |= USBCMD_IAAD;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+ClearEhcAllStatus (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Clear Ehc all status bits
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ UINT32 UsbStatusAddr;
+
+ UsbStatusAddr = USBSTS;
+
+ return WriteEhcOperationalReg (
+ HcDev,
+ UsbStatusAddr,
+ 0x003F
+ );
+}
+
+EFI_STATUS
+EnablePeriodicSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Enable periodic schedule
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+
+ UsbCommandAddr = USBCMD;
+
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ &UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ UsbCommandReg |= USBCMD_PSE;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+DisablePeriodicSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Disable periodic schedule
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+
+ UsbCommandAddr = USBCMD;
+
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ &UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ UsbCommandReg &= ~USBCMD_PSE;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EnableAsynchronousSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Enable asynchrounous schedule
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+
+ UsbCommandAddr = USBCMD;
+
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ &UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ UsbCommandReg |= USBCMD_ASE;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+DisableAsynchronousSchedule (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Disable asynchrounous schedule
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+
+ UsbCommandAddr = USBCMD;
+
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ &UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ UsbCommandReg &= ~USBCMD_ASE;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+ResetEhc (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Reset Ehc
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+
+ UsbCommandAddr = USBCMD;
+
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ &UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ UsbCommandReg |= USBCMD_HCRESET;
+ Status = WriteEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+StartScheduleExecution (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Start Ehc schedule execution
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+
+ UsbCommandAddr = USBCMD;
+
+ 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;
+ }
+
+exit:
+ return Status;
+}
+
+BOOLEAN
+IsFrameListProgrammable (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether frame list is programmable
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Programmable
+ FALSE Unprogrammable
+
+--*/
+{
+ BOOLEAN Value;
+ UINT32 HcCapParamsAddr;
+ UINT32 HcCapParamsReg;
+
+ HcCapParamsAddr = HCCPARAMS;
+
+ ReadEhcOperationalReg (
+ HcDev,
+ HcCapParamsAddr,
+ &HcCapParamsReg
+ );
+
+ if (HcCapParamsReg & HCCP_PFLF) {
+ Value = TRUE;
+ } else {
+ Value = FALSE;
+ }
+
+ return Value;
+}
+
+BOOLEAN
+IsPeriodicScheduleEnabled (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether periodic schedule is enabled
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Enabled
+ FALSE Disabled
+
+--*/
+{
+ BOOLEAN Value;
+ UINT32 UsbStatusAddr;
+ UINT32 UsbStatusReg;
+
+ UsbStatusAddr = USBSTS;
+
+ ReadEhcOperationalReg (
+ HcDev,
+ UsbStatusAddr,
+ &UsbStatusReg
+ );
+
+ if (UsbStatusReg & USBSTS_PSS) {
+ Value = TRUE;
+ } else {
+ Value = FALSE;
+ }
+
+ return Value;
+}
+
+BOOLEAN
+IsAsyncScheduleEnabled (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether asynchronous schedule is enabled
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Enabled
+ FALSE Disabled
+
+--*/
+{
+ BOOLEAN Value;
+ UINT32 UsbStatusAddr;
+ UINT32 UsbStatusReg;
+
+ UsbStatusAddr = USBSTS;
+
+ ReadEhcOperationalReg (
+ HcDev,
+ UsbStatusAddr,
+ &UsbStatusReg
+ );
+
+ if (UsbStatusReg & USBSTS_ASS) {
+ Value = TRUE;
+ } else {
+ Value = FALSE;
+ }
+
+ return Value;
+}
+
+BOOLEAN
+IsEhcPortEnabled (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 PortNum
+ )
+/*++
+
+Routine Description:
+
+ Whether port is enabled
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Enabled
+ FALSE Disabled
+
+--*/
+{
+ UINT32 PortStatusControlAddr;
+ UINT32 PortStatusControlReg;
+
+ PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));
+
+ ReadEhcOperationalReg (
+ HcDev,
+ PortStatusControlAddr,
+ &PortStatusControlReg
+ );
+
+ return ((PortStatusControlReg & PORTSC_PED) ? TRUE : FALSE);
+}
+
+BOOLEAN
+IsEhcReseted (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether Ehc is reseted
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Reseted
+ FALSE Unreseted
+
+--*/
+{
+ BOOLEAN Value;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+
+ UsbCommandAddr = USBCMD;
+
+ ReadEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ &UsbCommandReg
+ );
+
+ if (UsbCommandReg & USBCMD_HCRESET) {
+ Value = FALSE;
+ } else {
+ Value = TRUE;
+ }
+
+ return Value;
+}
+
+BOOLEAN
+IsEhcHalted (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether Ehc is halted
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE Halted
+ FALSE Not halted
+
+--*/
+{
+ BOOLEAN Value;
+ UINT32 UsbStatusAddr;
+ UINT32 UsbStatusReg;
+
+ UsbStatusAddr = USBSTS;
+
+ ReadEhcOperationalReg (
+ HcDev,
+ UsbStatusAddr,
+ &UsbStatusReg
+ );
+
+ if (UsbStatusReg & USBSTS_HCH) {
+ Value = TRUE;
+ } else {
+ Value = FALSE;
+ }
+
+ return Value;
+}
+
+BOOLEAN
+IsEhcSysError (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Whether Ehc is system error
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE System error
+ FALSE No system error
+
+--*/
+{
+ BOOLEAN Value;
+ UINT32 UsbStatusAddr;
+ UINT32 UsbStatusReg;
+
+ UsbStatusAddr = USBSTS;
+
+ ReadEhcOperationalReg (
+ HcDev,
+ UsbStatusAddr,
+ &UsbStatusReg
+ );
+
+ if (UsbStatusReg & USBSTS_HSE) {
+ Value = TRUE;
+ } else {
+ Value = FALSE;
+ }
+
+ return Value;
+}
+
+BOOLEAN
+IsHighSpeedDevice (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 PortNum
+ )
+/*++
+
+Routine Description:
+
+ Whether high speed device attached
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ TRUE High speed
+ FALSE Full speed
+
+--*/
+{
+ USB2_HC_DEV *HcDev;
+ UINT32 PortStatusControlAddr;
+ UINT32 PortStatusControlReg;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+ PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));
+
+ //
+ // Set port reset bit
+ //
+ ReadEhcOperationalReg (
+ HcDev,
+ PortStatusControlAddr,
+ &PortStatusControlReg
+ );
+ //
+ // Make sure Host Controller not halt before reset it
+ //
+ if (IsEhcHalted (HcDev)) {
+ StartScheduleExecution (HcDev);
+ WaitForEhcNotHalt (HcDev, EHCI_GENERIC_TIMEOUT);
+ }
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg |= PORTSC_PR;
+ //
+ // Set one to PortReset bit must also set zero to PortEnable bit
+ //
+ PortStatusControlReg &= ~PORTSC_PED;
+ WriteEhcOperationalReg (
+ HcDev,
+ PortStatusControlAddr,
+ PortStatusControlReg
+ );
+
+ //
+ // Set Port reset recovery time
+ //
+ gBS->Stall (EHCI_SET_PORT_RESET_RECOVERY_TIME);
+
+ //
+ // Clear port reset bit
+ //
+ ReadEhcOperationalReg (
+ HcDev,
+ PortStatusControlAddr,
+ &PortStatusControlReg
+ );
+ PortStatusControlReg &= 0xffffffd5;
+ PortStatusControlReg &= ~PORTSC_PR;
+ WriteEhcOperationalReg (
+ HcDev,
+ PortStatusControlAddr,
+ PortStatusControlReg
+ );
+
+ //
+ // Clear port reset recovery time
+ //
+ gBS->Stall (EHCI_CLEAR_PORT_RESET_RECOVERY_TIME);
+
+ return (IsEhcPortEnabled (HcDev, PortNum) ? TRUE : FALSE);
+}
+
+EFI_STATUS
+WaitForEhcReset (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ wait for Ehc reset or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Delay;
+
+ //
+ // Timeout is in US unit
+ //
+ Delay = (Timeout / 50) + 1;
+ do {
+
+ if (IsEhcReseted (HcDev)) {
+ Status = EFI_SUCCESS;
+ goto exit;
+ }
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);
+
+ } while (Delay--);
+
+ Status = EFI_TIMEOUT;
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+WaitForEhcHalt (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ wait for Ehc halt or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Delay;
+
+ //
+ // Timeout is in US unit
+ //
+ Delay = (Timeout / 50) + 1;
+ do {
+
+ if (IsEhcHalted (HcDev)) {
+ Status = EFI_SUCCESS;
+ goto exit;
+ }
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);
+
+ } while (Delay--);
+
+ Status = EFI_TIMEOUT;
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+WaitForEhcNotHalt (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ wait for Ehc not halt or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Delay;
+
+ //
+ // Timeout is in US unit
+ //
+ Delay = (Timeout / 50) + 1;
+ do {
+
+ if (!IsEhcHalted (HcDev)) {
+ Status = EFI_SUCCESS;
+ goto exit;
+ }
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);
+
+ } while (Delay--);
+
+ Status = EFI_TIMEOUT;
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+WaitForAsyncScheduleEnable (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for Ehc asynchronous schedule enable or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Delay;
+
+ //
+ // Timeout is in US unit
+ //
+ Delay = (Timeout / 50) + 1;
+ do {
+
+ if (IsAsyncScheduleEnabled (HcDev)) {
+ Status = EFI_SUCCESS;
+ goto exit;
+ }
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);
+
+ } while (Delay--);
+
+ Status = EFI_TIMEOUT;
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+WaitForAsyncScheduleDisable (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for Ehc asynchronous schedule disable or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Delay;
+
+ //
+ // Timeout is in US unit
+ //
+ Delay = (Timeout / 50) + 1;
+ do {
+
+ if (!IsAsyncScheduleEnabled (HcDev)) {
+ Status = EFI_SUCCESS;
+ goto exit;
+ }
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);
+
+ } while (Delay--);
+
+ Status = EFI_TIMEOUT;
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+WaitForPeriodicScheduleEnable (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for Ehc periodic schedule enable or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Delay;
+
+ //
+ // Timeout is in US unit
+ //
+ Delay = (Timeout / 50) + 1;
+ do {
+
+ if (IsPeriodicScheduleEnabled (HcDev)) {
+ Status = EFI_SUCCESS;
+ goto exit;
+ }
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);
+
+ } while (Delay--);
+
+ Status = EFI_TIMEOUT;
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+WaitForPeriodicScheduleDisable (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for periodic schedule disable or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Delay;
+
+ //
+ // Timeout is in US unit
+ //
+ Delay = (Timeout / 50) + 1;
+ do {
+
+ if (!IsPeriodicScheduleEnabled (HcDev)) {
+ Status = EFI_SUCCESS;
+ goto exit;
+ }
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);
+
+ } while (Delay--);
+
+ Status = EFI_TIMEOUT;
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+WaitForEhcDoorbell (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Timeout
+ )
+/*++
+
+Routine Description:
+
+ Wait for periodic schedule disable or timeout
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Timeout - timeout threshold
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_TIMEOUT Timeout
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 UsbCommandAddr;
+ UINT32 UsbCommandReg;
+ UINTN Delay;
+
+ UsbCommandAddr = USBCMD;
+ Delay = (Timeout / 50) + 1;
+
+ do {
+ Status = ReadEhcOperationalReg (
+ HcDev,
+ UsbCommandAddr,
+ &UsbCommandReg
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+ if (!(UsbCommandReg & USBCMD_IAAD)) {
+ break;
+ }
+
+ } while (--Delay);
+
+ if (0 == Delay) {
+ Status = EFI_TIMEOUT;
+ }
+
+exit:
+ return Status;
+}
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciSched.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciSched.c
new file mode 100644
index 0000000000..3dc1ff74af
--- /dev/null
+++ b/EdkModulePkg/Bus/Pci/Ehci/Dxe/EhciSched.c
@@ -0,0 +1,3072 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EhciSched.c
+
+Abstract:
+
+
+Revision History
+--*/
+
+#include "Ehci.h"
+
+EFI_STATUS
+InitialPeriodicFrameList (
+ IN USB2_HC_DEV *HcDev,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Initialize Periodic Schedule Frame List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Length - Frame List Length
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *CommonBuffer;
+ EFI_PHYSICAL_ADDRESS FrameBuffer;
+ VOID *Map;
+ UINTN BufferSizeInPages;
+ UINTN BufferSizeInBytes;
+ UINTN FrameIndex;
+ FRAME_LIST_ENTRY *FrameEntryPtr;
+
+ //
+ // The Frame List is a common buffer that will be
+ // accessed by both the cpu and the usb bus master
+ // at the same time.
+ // The Frame List ocupies 4K bytes,
+ // and must be aligned on 4-Kbyte boundaries.
+ //
+ if (EHCI_MAX_FRAME_LIST_LENGTH != Length && IsFrameListProgrammable (HcDev)) {
+ Status = SetFrameListLen (HcDev, Length);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+ }
+
+ BufferSizeInBytes = EFI_PAGE_SIZE;
+ BufferSizeInPages = EFI_SIZE_TO_PAGES (BufferSizeInBytes);
+ Status = HcDev->PciIo->AllocateBuffer (
+ HcDev->PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ BufferSizeInPages,
+ &CommonBuffer,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((gEHCErrorLevel, "PciIo->AllocateBuffer Failed\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+
+ Status = HcDev->PciIo->Map (
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ CommonBuffer,
+ &BufferSizeInBytes,
+ &FrameBuffer,
+ &Map
+ );
+ if (EFI_ERROR (Status) || (BufferSizeInBytes != EFI_PAGE_SIZE)) {
+ DEBUG ((gEHCErrorLevel, "PciIo->MapBuffer Failed\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto free_buffer;
+ }
+
+ //
+ // Put high 32bit into CtrlDataStructSeg reg
+ // when 64bit addressing range capability
+ //
+ if (HcDev->Is64BitCapable != 0) {
+ HcDev->High32BitAddr = (UINT32) GET_32B_TO_63B (FrameBuffer);
+
+ Status = SetCtrlDataStructSeg (HcDev);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((gEHCErrorLevel, "SetCtrlDataStructSeg Failed\n"));
+ Status = EFI_DEVICE_ERROR;
+ goto unmap_buffer;
+ }
+ }
+
+ //
+ // Tell the Host Controller where the Frame List lies,
+ // by set the Frame List Base Address Register.
+ //
+ Status = SetFrameListBaseAddr (HcDev, (UINT32) FrameBuffer);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto unmap_buffer;
+ }
+
+ HcDev->PeriodicFrameListLength = Length;
+ HcDev->PeriodicFrameListBuffer = (VOID *) ((UINTN) FrameBuffer);
+ HcDev->PeriodicFrameListMap = Map;
+
+ //
+ // Init Frame List Array fields
+ //
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;
+ for (FrameIndex = 0; FrameIndex < HcDev->PeriodicFrameListLength; FrameIndex++) {
+ FrameEntryPtr->LinkPointer = 0;
+ FrameEntryPtr->Rsvd = 0;
+ FrameEntryPtr->SelectType = 0;
+ FrameEntryPtr->LinkTerminate = TRUE;
+ FrameEntryPtr++;
+ }
+
+ goto exit;
+
+unmap_buffer:
+ HcDev->PciIo->Unmap (HcDev->PciIo, Map);
+free_buffer:
+ HcDev->PciIo->FreeBuffer (HcDev->PciIo, BufferSizeInPages, CommonBuffer);
+exit:
+ return Status;
+}
+
+VOID
+DeinitialPeriodicFrameList (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Deinitialize Periodic Schedule Frame List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ VOID
+
+--*/
+{
+ HcDev->PciIo->Unmap (HcDev->PciIo, HcDev->PeriodicFrameListMap);
+ HcDev->PciIo->FreeBuffer (HcDev->PciIo, EFI_SIZE_TO_PAGES (EFI_PAGE_SIZE), HcDev->PeriodicFrameListBuffer);
+ return ;
+}
+
+EFI_STATUS
+CreatePollingTimer (
+ IN USB2_HC_DEV *HcDev,
+ IN EFI_EVENT_NOTIFY NotifyFunction
+ )
+/*++
+
+Routine Description:
+
+ Create Async Request Polling Timer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ NotifyFunction - Timer Notify Function
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ return gBS->CreateEvent (
+ EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_NOTIFY,
+ NotifyFunction,
+ HcDev,
+ &HcDev->AsyncRequestEvent
+ );
+}
+
+EFI_STATUS
+DestoryPollingTimer (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Destory Async Request Polling Timer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ return gBS->CloseEvent (HcDev->AsyncRequestEvent);
+}
+
+EFI_STATUS
+StartPollingTimer (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Start Async Request Polling Timer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ return gBS->SetTimer (
+ HcDev->AsyncRequestEvent,
+ TimerPeriodic,
+ EHCI_ASYNC_REQUEST_POLLING_TIME
+ );
+}
+
+EFI_STATUS
+StopPollingTimer (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Stop Async Request Polling Timer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ return gBS->SetTimer (
+ HcDev->AsyncRequestEvent,
+ TimerCancel,
+ EHCI_ASYNC_REQUEST_POLLING_TIME
+ );
+}
+
+EFI_STATUS
+CreateQh (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DeviceAddr,
+ IN UINT8 Endpoint,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaxPacketLen,
+ OUT EHCI_QH_ENTITY **QhPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qh Structure and Pre-Initialize
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DeviceAddr - Address of Device
+ Endpoint - Endpoint Number
+ DeviceSpeed - Device Speed
+ MaxPacketLen - Max Length of one Packet
+ QhPtrPtr - A pointer of pointer to Qh for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ EFI_STATUS Status;
+ EHCI_QH_HW *QhHwPtr;
+
+ ASSERT (HcDev);
+ ASSERT (QhPtrPtr);
+
+ *QhPtrPtr = NULL;
+
+ //
+ // Allocate memory for Qh structure
+ //
+ Status = EhciAllocatePool (
+ HcDev,
+ (UINT8 **) QhPtrPtr,
+ sizeof (EHCI_QH_ENTITY)
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+ //
+ // Init fields in Qh
+ //
+ gBS->SetMem (*QhPtrPtr, sizeof (EHCI_QH_ENTITY), 0);
+
+ //
+ // Software field
+ //
+ (*QhPtrPtr)->Next = NULL;
+ (*QhPtrPtr)->Prev = NULL;
+ (*QhPtrPtr)->FirstQtdPtr = NULL;
+ (*QhPtrPtr)->AltQtdPtr = NULL;
+ (*QhPtrPtr)->LastQtdPtr = NULL;
+
+ //
+ // Hardware field
+ //
+ QhHwPtr = &((*QhPtrPtr)->Qh);
+ QhHwPtr->QhHorizontalPointer = 0;
+ QhHwPtr->SelectType = 0;
+ QhHwPtr->MaxPacketLen = (UINT32) MaxPacketLen;
+ QhHwPtr->EndpointSpeed = (DeviceSpeed & 0x3);
+ QhHwPtr->EndpointNum = (Endpoint & 0x0f);
+ QhHwPtr->DeviceAddr = (DeviceAddr & 0x7f);
+ QhHwPtr->Multiplier = HIGH_BANDWIDTH_PIPE_MULTIPLIER;
+ QhHwPtr->Rsvd1 = 0;
+ QhHwPtr->Rsvd2 = 0;
+ QhHwPtr->Rsvd3 = 0;
+ QhHwPtr->Rsvd4 = 0;
+ QhHwPtr->Rsvd5 = 0;
+ QhHwPtr->Rsvd6 = 0;
+
+exit:
+ return Status;
+}
+
+VOID
+DestoryQh (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Destory Qh Structure
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to Qh
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ ASSERT (HcDev);
+ ASSERT (QhPtr);
+
+ EhciFreePool (HcDev, (UINT8 *) QhPtr, sizeof (EHCI_QH_ENTITY));
+ return ;
+}
+
+EFI_STATUS
+CreateControlQh (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DeviceAddr,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaxPacketLen,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT EHCI_QH_ENTITY **QhPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qh for Control Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DeviceAddr - Address of Device
+ DeviceSpeed - Device Speed
+ MaxPacketLen - Max Length of one Packet
+ Translator - Translator Transaction for SplitX
+ QhPtrPtr - A pointer of pointer to Qh for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Create and init Control Qh
+ //
+ Status = CreateQh (
+ HcDev,
+ DeviceAddr,
+ 0,
+ DeviceSpeed,
+ MaxPacketLen,
+ QhPtrPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+ //
+ // Software field
+ //
+ (*QhPtrPtr)->Next = (*QhPtrPtr);
+ (*QhPtrPtr)->Prev = (*QhPtrPtr);
+ (*QhPtrPtr)->TransferType = CONTROL_TRANSFER;
+
+ //
+ // Hardware field
+ //
+ // Control Transfer use DataToggleControl
+ //
+ (*QhPtrPtr)->Qh.DataToggleControl = TRUE;
+ (*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);
+ (*QhPtrPtr)->Qh.SelectType = QH_SELECT_TYPE;
+ (*QhPtrPtr)->Qh.QhTerminate = FALSE;
+ (*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE;
+ (*QhPtrPtr)->Qh.NakCountReload = NAK_COUNT_RELOAD;
+ if (NULL != Translator) {
+ (*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;
+ (*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;
+ (*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+CreateBulkQh (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DeviceAddr,
+ IN UINT8 EndPointAddr,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 DataToggle,
+ IN UINTN MaxPacketLen,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT EHCI_QH_ENTITY **QhPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qh for Bulk Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DeviceAddr - Address of Device
+ EndPointAddr - Address of Endpoint
+ DeviceSpeed - Device Speed
+ MaxPacketLen - Max Length of one Packet
+ Translator - Translator Transaction for SplitX
+ QhPtrPtr - A pointer of pointer to Qh for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Create and init Bulk Qh
+ //
+ Status = CreateQh (
+ HcDev,
+ DeviceAddr,
+ EndPointAddr,
+ DeviceSpeed,
+ MaxPacketLen,
+ QhPtrPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+
+ //
+ // Software fields
+ //
+ (*QhPtrPtr)->Next = (*QhPtrPtr);
+ (*QhPtrPtr)->Prev = (*QhPtrPtr);
+ (*QhPtrPtr)->TransferType = BULK_TRANSFER;
+
+ //
+ // Hardware fields
+ //
+ // BulkTransfer don't use DataToggleControl
+ //
+ (*QhPtrPtr)->Qh.DataToggleControl = FALSE;
+ (*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);
+ (*QhPtrPtr)->Qh.SelectType = QH_SELECT_TYPE;
+ (*QhPtrPtr)->Qh.QhTerminate = FALSE;
+ (*QhPtrPtr)->Qh.NakCountReload = NAK_COUNT_RELOAD;
+ (*QhPtrPtr)->Qh.DataToggle = DataToggle;
+ if (NULL != Translator) {
+ (*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;
+ (*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;
+ (*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+CreateInterruptQh (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DeviceAddr,
+ IN UINT8 EndPointAddr,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 DataToggle,
+ IN UINTN MaxPacketLen,
+ IN UINTN Interval,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT EHCI_QH_ENTITY **QhPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qh for Control Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DeviceAddr - Address of Device
+ EndPointAddr - Address of Endpoint
+ DeviceSpeed - Device Speed
+ MaxPacketLen - Max Length of one Packet
+ Interval - value of interval
+ Translator - Translator Transaction for SplitX
+ QhPtrPtr - A pointer of pointer to Qh for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Create and init InterruptQh
+ //
+ Status = CreateQh (
+ HcDev,
+ DeviceAddr,
+ EndPointAddr,
+ DeviceSpeed,
+ MaxPacketLen,
+ QhPtrPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+
+ //
+ // Software fields
+ //
+ if (Interval == 0) {
+ (*QhPtrPtr)->TransferType = SYNC_INTERRUPT_TRANSFER;
+ } else {
+ (*QhPtrPtr)->TransferType = ASYNC_INTERRUPT_TRANSFER;
+ }
+ (*QhPtrPtr)->Interval = GetApproxiOfInterval (Interval);
+
+ //
+ // Hardware fields
+ //
+ // InterruptTranfer don't use DataToggleControl
+ //
+ (*QhPtrPtr)->Qh.DataToggleControl = FALSE;
+ (*QhPtrPtr)->Qh.QhHorizontalPointer = 0;
+ (*QhPtrPtr)->Qh.QhTerminate = TRUE;
+ (*QhPtrPtr)->Qh.NakCountReload = 0;
+ (*QhPtrPtr)->Qh.InerruptScheduleMask = MICRO_FRAME_0_CHANNEL;
+ (*QhPtrPtr)->Qh.SplitComletionMask = (MICRO_FRAME_2_CHANNEL | MICRO_FRAME_3_CHANNEL | MICRO_FRAME_4_CHANNEL);
+ (*QhPtrPtr)->Qh.DataToggle = DataToggle;
+ if (NULL != Translator) {
+ (*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;
+ (*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;
+ (*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+CreateQtd (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 *DataPtr,
+ IN UINTN DataLen,
+ IN UINT8 PktId,
+ IN UINT8 Toggle,
+ IN UINT8 QtdStatus,
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qtd Structure and Pre-Initialize it
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DataPtr - A pointer to user data buffer to transfer
+ DataLen - Length of user data to transfer
+ PktId - Packet Identification of this Qtd
+ Toggle - Data Toggle of this Qtd
+ QtdStatus - Default value of status of this Qtd
+ QtdPtrPtr - A pointer of pointer to Qtd for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ EFI_STATUS Status;
+ EHCI_QTD_HW *QtdHwPtr;
+
+ ASSERT (HcDev);
+ ASSERT (QtdPtrPtr);
+
+ //
+ // Create memory for Qtd structure
+ //
+ Status = EhciAllocatePool (
+ HcDev,
+ (UINT8 **) QtdPtrPtr,
+ sizeof (EHCI_QTD_ENTITY)
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+ //
+ // Init fields in Qtd
+ //
+ gBS->SetMem (*QtdPtrPtr, sizeof (EHCI_QTD_ENTITY), 0);
+
+ //
+ // Software field
+ //
+ (*QtdPtrPtr)->TotalBytes = (UINT32) DataLen;
+ (*QtdPtrPtr)->StaticTotalBytes = (UINT32) DataLen;
+ (*QtdPtrPtr)->Prev = NULL;
+ (*QtdPtrPtr)->Next = NULL;
+
+ //
+ // Hardware field
+ //
+ QtdHwPtr = &((*QtdPtrPtr)->Qtd);
+ QtdHwPtr->NextQtdPointer = 0;
+ QtdHwPtr->NextQtdTerminate = TRUE;
+ QtdHwPtr->AltNextQtdPointer = 0;
+ QtdHwPtr->AltNextQtdTerminate = TRUE;
+ QtdHwPtr->DataToggle = Toggle;
+ QtdHwPtr->TotalBytes = (UINT32) DataLen;
+ QtdHwPtr->CurrentPage = 0;
+ QtdHwPtr->ErrorCount = QTD_ERROR_COUNTER;
+ QtdHwPtr->Status = QtdStatus;
+ QtdHwPtr->Rsvd1 = 0;
+ QtdHwPtr->Rsvd2 = 0;
+ QtdHwPtr->Rsvd3 = 0;
+ QtdHwPtr->Rsvd4 = 0;
+ QtdHwPtr->Rsvd5 = 0;
+ QtdHwPtr->Rsvd6 = 0;
+
+ //
+ // Set PacketID [Setup/Data/Status]
+ //
+ switch (PktId) {
+ case SETUP_PACKET_ID:
+ QtdHwPtr->PidCode = SETUP_PACKET_PID_CODE;
+ break;
+
+ case INPUT_PACKET_ID:
+ QtdHwPtr->PidCode = INPUT_PACKET_PID_CODE;
+ break;
+
+ case OUTPUT_PACKET_ID:
+ QtdHwPtr->PidCode = OUTPUT_PACKET_PID_CODE;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ //
+ // Set Data Buffer Pointers
+ //
+ if (NULL != DataPtr) {
+ SetQtdBufferPointer (
+ QtdHwPtr,
+ DataPtr,
+ DataLen
+ );
+ (*QtdPtrPtr)->StaticCurrentOffset = QtdHwPtr->CurrentOffset;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+CreateSetupQtd (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 *DevReqPtr,
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qtd Structure for Setup
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DevReqPtr - A pointer to Device Request Data
+ QtdPtrPtr - A pointer of pointer to Qtd for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ return CreateQtd (
+ HcDev,
+ DevReqPtr,
+ sizeof (EFI_USB_DEVICE_REQUEST),
+ SETUP_PACKET_ID,
+ DATA0,
+ QTD_STATUS_ACTIVE,
+ QtdPtrPtr
+ );
+}
+
+EFI_STATUS
+CreateDataQtd (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 *DataPtr,
+ IN UINTN DataLen,
+ IN UINT8 PktId,
+ IN UINT8 Toggle,
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qtd Structure for data
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DataPtr - A pointer to user data buffer to transfer
+ DataLen - Length of user data to transfer
+ PktId - Packet Identification of this Qtd
+ Toggle - Data Toggle of this Qtd
+ QtdPtrPtr - A pointer of pointer to Qtd for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ return CreateQtd (
+ HcDev,
+ DataPtr,
+ DataLen,
+ PktId,
+ Toggle,
+ QTD_STATUS_ACTIVE,
+ QtdPtrPtr
+ );
+}
+
+EFI_STATUS
+CreateAltQtd (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 PktId,
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qtd Structure for Alternative
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ PktId - Packet Identification of this Qtd
+ QtdPtrPtr - A pointer of pointer to Qtd for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ return CreateQtd (
+ HcDev,
+ NULL,
+ 0,
+ PktId,
+ 0,
+ QTD_STATUS_ACTIVE,
+ QtdPtrPtr
+ );
+}
+
+EFI_STATUS
+CreateStatusQtd (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 PktId,
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr
+ )
+/*++
+
+Routine Description:
+
+ Create Qtd Structure for status
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ PktId - Packet Identification of this Qtd
+ QtdPtrPtr - A pointer of pointer to Qtd for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ return CreateQtd (
+ HcDev,
+ NULL,
+ 0,
+ PktId,
+ DATA1,
+ QTD_STATUS_ACTIVE,
+ QtdPtrPtr
+ );
+}
+
+EFI_STATUS
+CreateControlQtds (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DataPktId,
+ IN UINT8 *RequestCursor,
+ IN UINT8 *DataCursor,
+ IN UINTN DataLen,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT EHCI_QTD_ENTITY **ControlQtdsHead
+ )
+/*++
+
+Routine Description:
+
+ Create Qtds list for Control Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DataPktId - Packet Identification of Data Qtds
+ RequestCursor - A pointer to request structure buffer to transfer
+ DataCursor - A pointer to user data buffer to transfer
+ DataLen - Length of user data to transfer
+ ControlQtdsHead - A pointer of pointer to first Qtd for control tranfer for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ EFI_STATUS Status;
+ EHCI_QTD_ENTITY *QtdPtr;
+ EHCI_QTD_ENTITY *PreQtdPtr;
+ EHCI_QTD_ENTITY *SetupQtdPtr;
+ EHCI_QTD_ENTITY *FirstDataQtdPtr;
+ EHCI_QTD_ENTITY *LastDataQtdPtr;
+ EHCI_QTD_ENTITY *StatusQtdPtr;
+ UINT8 DataToggle;
+ UINT8 StatusPktId;
+ UINTN CapacityOfQtd;
+ UINTN SizePerQtd;
+ UINTN DataCount;
+ UINTN Xnum;
+
+ QtdPtr = NULL;
+ PreQtdPtr = NULL;
+ SetupQtdPtr = NULL;
+ FirstDataQtdPtr = NULL;
+ LastDataQtdPtr = NULL;
+ StatusQtdPtr = NULL;
+ CapacityOfQtd = 0;
+
+ //
+ // Setup Stage of Control Transfer
+ //
+ Status = CreateSetupQtd (
+ HcDev,
+ RequestCursor,
+ &SetupQtdPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+
+ //
+ // Data Stage of Control Transfer
+ //
+ DataToggle = 1;
+ DataCount = DataLen;
+
+ //
+ // Create Qtd structure and link together
+ //
+ while (DataCount > 0) {
+ //
+ // PktSize is the data load size that each Qtd.
+ //
+ CapacityOfQtd = GetCapacityOfQtd (DataCursor);
+ SizePerQtd = DataCount;
+ if (DataCount > CapacityOfQtd) {
+ SizePerQtd = CapacityOfQtd;
+ }
+
+ Status = CreateDataQtd (
+ HcDev,
+ DataCursor,
+ SizePerQtd,
+ DataPktId,
+ DataToggle,
+ &QtdPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ if (NULL == FirstDataQtdPtr) {
+ goto destory_setup_qtd;
+ } else {
+ goto destory_qtds;
+ }
+ }
+
+ if (NULL == FirstDataQtdPtr) {
+ FirstDataQtdPtr = QtdPtr;
+ } else {
+ LinkQtdToQtd (PreQtdPtr, QtdPtr);
+ }
+
+ //
+ // Reverse Data Toggle or not determined by parity of transactions of one qtd
+ //
+ Xnum = Translator ? GetNumberOfTransaction (SizePerQtd, EHCI_BLOCK_SIZE_WITH_TT) : GetNumberOfTransaction (SizePerQtd, EHCI_BLOCK_SIZE);
+ if (Xnum % 2 != 0) {
+ DataToggle ^= 1;
+ }
+
+ PreQtdPtr = QtdPtr;
+ DataCursor += SizePerQtd;
+ DataCount -= SizePerQtd;
+ }
+
+ LastDataQtdPtr = QtdPtr;
+
+ //
+ // Status Stage of Control Transfer
+ //
+ if (OUTPUT_PACKET_ID == DataPktId) {
+ StatusPktId = INPUT_PACKET_ID;
+ } else {
+ StatusPktId = OUTPUT_PACKET_ID;
+ }
+
+ Status = CreateStatusQtd (
+ HcDev,
+ StatusPktId,
+ &StatusQtdPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto destory_qtds;
+ }
+
+ //
+ // Link setup Qtd -> data Qtds -> status Qtd
+ //
+ if (FirstDataQtdPtr != NULL) {
+ LinkQtdToQtd (SetupQtdPtr, FirstDataQtdPtr);
+ LinkQtdToQtd (LastDataQtdPtr, StatusQtdPtr);
+ } else {
+ LinkQtdToQtd (SetupQtdPtr, StatusQtdPtr);
+ }
+
+ *ControlQtdsHead = SetupQtdPtr;
+
+ goto exit;
+
+destory_qtds:
+ DestoryQtds (HcDev, FirstDataQtdPtr);
+destory_setup_qtd:
+ DestoryQtds (HcDev, SetupQtdPtr);
+exit:
+ return Status;
+}
+
+EFI_STATUS
+CreateBulkOrInterruptQtds (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 PktId,
+ IN UINT8 *DataCursor,
+ IN UINTN DataLen,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT EHCI_QTD_ENTITY **QtdsHead
+ )
+/*++
+
+Routine Description:
+
+ Create Qtds list for Bulk or Interrupt Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ PktId - Packet Identification of Qtds
+ DataCursor - A pointer to user data buffer to transfer
+ DataLen - Length of user data to transfer
+ DataToggle - Data Toggle to start
+ Translator - Translator Transaction for SplitX
+ QtdsHead - A pointer of pointer to first Qtd for control tranfer for return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ EFI_STATUS Status;
+ EHCI_QTD_ENTITY *QtdPtr;
+ EHCI_QTD_ENTITY *PreQtdPtr;
+ EHCI_QTD_ENTITY *FirstQtdPtr;
+ EHCI_QTD_ENTITY *AltQtdPtr;
+ UINTN DataCount;
+ UINTN CapacityOfQtd;
+ UINTN SizePerQtd;
+
+ Status = EFI_SUCCESS;
+ QtdPtr = NULL;
+ PreQtdPtr = NULL;
+ FirstQtdPtr = NULL;
+ AltQtdPtr = NULL;
+ CapacityOfQtd = 0;
+
+ DataCount = DataLen;
+ while (DataCount > 0) {
+
+ CapacityOfQtd = GetCapacityOfQtd (DataCursor);
+ SizePerQtd = DataCount;
+ if (DataCount > CapacityOfQtd) {
+ SizePerQtd = CapacityOfQtd;
+ }
+
+ Status = CreateDataQtd (
+ HcDev,
+ DataCursor,
+ SizePerQtd,
+ PktId,
+ 0,
+ &QtdPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ if (NULL == FirstQtdPtr) {
+ goto exit;
+ } else {
+ goto destory_qtds;
+ }
+ }
+
+ if (NULL == FirstQtdPtr) {
+ FirstQtdPtr = QtdPtr;
+ } else {
+ LinkQtdToQtd (PreQtdPtr, QtdPtr);
+ }
+
+ PreQtdPtr = QtdPtr;
+ DataCursor += SizePerQtd;
+ DataCount -= SizePerQtd;
+ }
+
+ //
+ // Set Alternate Qtd
+ //
+ if (INPUT_PACKET_ID == PktId && 1 < GetNumberOfQtd (FirstQtdPtr)) {
+ Status = CreateAltQtd (
+ HcDev,
+ PktId,
+ &AltQtdPtr
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto destory_qtds;
+ }
+
+ LinkQtdsToAltQtd (FirstQtdPtr, AltQtdPtr);
+ }
+
+ *QtdsHead = FirstQtdPtr;
+ goto exit;
+
+destory_qtds:
+ DestoryQtds (HcDev, FirstQtdPtr);
+exit:
+ return Status;
+}
+
+VOID
+DestoryQtds (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QTD_ENTITY *FirstQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Destory all Qtds in the list
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ FirstQtdPtr - A pointer to first Qtd in the list
+
+Returns:
+
+ VOID
+
+--*/
+{
+ EHCI_QTD_ENTITY *PrevQtd;
+ EHCI_QTD_ENTITY *NextQtd;
+
+ if (!FirstQtdPtr) {
+ goto exit;
+ }
+
+ PrevQtd = FirstQtdPtr;
+
+ //
+ // Delete all the Qtds.
+ //
+ do {
+ NextQtd = PrevQtd->Next;
+ EhciFreePool (HcDev, (UINT8 *) PrevQtd, sizeof (EHCI_QTD_ENTITY));
+ PrevQtd = NextQtd;
+ } while (NULL != PrevQtd);
+
+exit:
+ return ;
+}
+
+UINTN
+GetNumberOfQtd (
+ IN EHCI_QTD_ENTITY *FirstQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Number of Qtds in the list
+
+Arguments:
+
+ FirstQtdPtr - A pointer to first Qtd in the list
+
+Returns:
+
+ Number of Qtds in the list
+
+--*/
+{
+ UINTN Count;
+ EHCI_QTD_ENTITY *QtdPtr;
+ Count = 0;
+ QtdPtr = FirstQtdPtr;
+
+ ;
+
+ while (NULL != QtdPtr) {
+ Count++;
+ QtdPtr = QtdPtr->Next;
+ }
+
+ return Count;
+}
+
+UINTN
+GetNumberOfTransaction (
+ IN UINTN SizeOfData,
+ IN UINTN SizeOfTransaction
+ )
+/*++
+
+Routine Description:
+
+ Number of Transactions in one Qtd
+
+Arguments:
+
+ SizeOfData - Size of one Qtd
+ SizeOfTransaction - Size of one Transaction
+
+Returns:
+
+ Number of Transactions in this Qtd
+
+--*/
+{
+
+ return ((SizeOfData & (SizeOfTransaction - 1)) ? SizeOfData / SizeOfTransaction + 1 : SizeOfData / SizeOfTransaction);
+
+}
+
+UINTN
+GetCapacityOfQtd (
+ IN UINT8 *BufferCursor
+ )
+/*++
+
+Routine Description:
+
+ Get Size of First Qtd
+
+Arguments:
+
+ BufferCursor - BufferCursor of the Qtd
+
+Returns:
+
+ Size of First Qtd
+
+--*/
+{
+
+ return (EHCI_MAX_QTD_CAPACITY - (EHCI_BLOCK_SIZE * GetNumberOfTransaction (EFI_PAGE_MASK & GET_0B_TO_31B (BufferCursor), EHCI_BLOCK_SIZE)));
+
+}
+
+UINTN
+GetApproxiOfInterval (
+ IN UINTN Interval
+ )
+/*++
+
+Routine Description:
+
+ Get the approximate value in the 2 index sequence
+
+Arguments:
+
+ Interval - the value of interval
+
+Returns:
+
+ approximate value of interval in the 2 index sequence
+
+--*/
+{
+ UINTN Orignate;
+ UINTN Approxi;
+
+ Orignate = Interval;
+ Approxi = 1;
+
+ while (Orignate != 1 && Orignate != 0) {
+ Orignate = Orignate >> 1;
+ Approxi = Approxi << 1;
+ }
+
+ if (Interval & (Approxi >> 1)) {
+ Approxi = Approxi << 1;
+ }
+
+ return Approxi;
+}
+
+EHCI_QTD_HW *
+GetQtdAlternateNextPointer (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Get Qtd alternate next pointer field
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ A pointer to hardware alternate Qtd
+
+--*/
+{
+ EHCI_QTD_HW *Value;
+
+ Value = NULL;
+
+ if (!HwQtdPtr->AltNextQtdTerminate) {
+ Value = (EHCI_QTD_HW *) GET_0B_TO_31B (HwQtdPtr->AltNextQtdPointer << 5);
+ }
+
+ return Value;
+}
+
+EHCI_QTD_HW *
+GetQtdNextPointer (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Get Qtd next pointer field
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ A pointer to next hardware Qtd structure
+
+--*/
+{
+ EHCI_QTD_HW *Value;
+
+ Value = NULL;
+
+ if (!HwQtdPtr->NextQtdTerminate) {
+ Value = (EHCI_QTD_HW *) GET_0B_TO_31B (HwQtdPtr->NextQtdPointer << 5);
+ }
+
+ return Value;
+}
+
+VOID LinkQtdToQtd (
+ IN EHCI_QTD_ENTITY * PreQtdPtr,
+ IN EHCI_QTD_ENTITY * QtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Link Qtds together
+
+Arguments:
+
+ PreQtdPtr - A pointer to pre Qtd
+ QtdPtr - A pointer to next Qtd
+
+Returns:
+
+ VOID
+
+--*/
+{
+ EHCI_QTD_HW *QtdHwPtr;
+
+ ASSERT(PreQtdPtr);
+ ASSERT(QtdPtr);
+
+ //
+ // Software link
+ //
+ PreQtdPtr->Next = QtdPtr;
+ QtdPtr->Prev = PreQtdPtr;
+
+ //
+ // Hardware link
+ //
+ QtdHwPtr = &(QtdPtr->Qtd);
+ PreQtdPtr->Qtd.NextQtdPointer = (UINT32) (GET_0B_TO_31B(QtdHwPtr) >> 5);
+ PreQtdPtr->Qtd.NextQtdTerminate = FALSE;
+
+ return ;
+}
+
+
+VOID LinkQtdsToAltQtd (
+ IN EHCI_QTD_ENTITY * FirstQtdPtr,
+ IN EHCI_QTD_ENTITY * AltQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Link AlterQtds together
+
+Arguments:
+
+ FirstQtdPtr - A pointer to first Qtd in the list
+ AltQtdPtr - A pointer to alternative Qtd
+
+Returns:
+
+ VOID
+
+--*/
+{
+ EHCI_QTD_ENTITY *QtdPtr;
+ EHCI_QTD_HW *AltQtdHwPtr;
+
+ ASSERT(FirstQtdPtr);
+ ASSERT(AltQtdPtr);
+
+ AltQtdHwPtr = &(AltQtdPtr->Qtd);
+ QtdPtr = FirstQtdPtr;
+
+ while (NULL != QtdPtr) {
+ //
+ // Software link
+ //
+ QtdPtr->AltNext = AltQtdPtr;
+ //
+ // Hardware link
+ //
+ QtdPtr->Qtd.AltNextQtdPointer = (UINT32) (GET_0B_TO_31B(AltQtdHwPtr) >> 5);
+ QtdPtr->Qtd.AltNextQtdTerminate = FALSE;
+ QtdPtr = QtdPtr->Next;
+ }
+
+ return ;
+}
+
+VOID
+LinkQtdToQh (
+ IN EHCI_QH_ENTITY *QhPtr,
+ IN EHCI_QTD_ENTITY *QtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Link Qtds list to Qh
+
+Arguments:
+
+ QhPtr - A pointer to Qh
+ QtdPtr - A pointer to first Qtd in the list
+
+Returns:
+
+ VOID
+
+--*/
+{
+ EHCI_QTD_ENTITY *Cursor;
+ EHCI_QTD_HW *QtdHwPtr;
+
+ ASSERT (QhPtr);
+ ASSERT (QtdPtr);
+
+ QhPtr->FirstQtdPtr = QtdPtr;
+ if (NULL != QtdPtr->AltNext) {
+ QhPtr->AltQtdPtr = QtdPtr->AltNext;
+ }
+
+ Cursor = QtdPtr;
+ while (NULL != Cursor) {
+ Cursor->SelfQh = QhPtr;
+ if (NULL == Cursor->Next) {
+ QhPtr->LastQtdPtr = Cursor;
+ }
+
+ Cursor = Cursor->Next;
+ }
+
+ QtdHwPtr = &(QtdPtr->Qtd);
+ QhPtr->Qh.NextQtdPointer = (UINT32) (GET_0B_TO_31B (QtdHwPtr) >> 5);
+ QhPtr->Qh.NextQtdTerminate = FALSE;
+
+ return ;
+}
+
+EFI_STATUS
+LinkQhToAsyncList (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Link Qh to Async Schedule List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to Qh
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+
+ ASSERT (HcDev);
+ ASSERT (QhPtr);
+
+ QhPtr->Qh.HeadReclamationFlag = TRUE;
+
+ Status = SetAsyncListAddr (HcDev, QhPtr);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ if (!IsAsyncScheduleEnabled (HcDev)) {
+
+ Status = EnableAsynchronousSchedule (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = WaitForAsyncScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((gEHCDebugLevel, "WaitForAsyncScheduleEnable TimeOut"));
+ Status = EFI_TIMEOUT;
+ goto exit;
+ }
+
+ if (IsEhcHalted (HcDev)) {
+ Status = StartScheduleExecution (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+UnlinkQhFromAsyncList (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Unlink Qh from Async Schedule List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to Qh
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ ASSERT (HcDev);
+ ASSERT (QhPtr);
+
+ if (QhPtr == QhPtr->Next) {
+
+ Status = DisableAsynchronousSchedule (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = WaitForAsyncScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((gEHCErrorLevel, "WaitForAsyncScheduleDisable TimeOut\n"));
+ Status = EFI_TIMEOUT;
+ goto exit;
+ }
+
+ }
+
+exit:
+ return Status;
+}
+
+VOID
+LinkQhToPeriodicList (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Link Qh to Periodic Schedule List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to Qh
+
+Returns:
+
+ VOID
+
+--*/
+{
+ FRAME_LIST_ENTRY *FrameEntryPtr;
+ EHCI_QH_ENTITY *FindQhPtr;
+ EHCI_QH_HW *FindQhHwPtr;
+ UINTN FrameIndex;
+
+ ASSERT (HcDev);
+ ASSERT (QhPtr);
+
+ FindQhPtr = NULL;
+ FindQhHwPtr = NULL;
+ FrameIndex = 0;
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;
+
+ QhPtr->Qh.HeadReclamationFlag = FALSE;
+
+ if (QhPtr->TransferType == ASYNC_INTERRUPT_TRANSFER) {
+
+ //
+ // AsyncInterruptTransfer Qh
+ //
+
+ //
+ // Link to Frame[0] List
+ //
+ if (!FrameEntryPtr->LinkTerminate) {
+ //
+ // Not Null FrameList
+ //
+ FindQhHwPtr = (EHCI_QH_HW *) GET_0B_TO_31B (FrameEntryPtr->LinkPointer << 5);
+ FindQhPtr = (EHCI_QH_ENTITY *) GET_QH_ENTITY_ADDR (FindQhHwPtr);
+ //
+ // FindQh is Left/Right to Qh
+ //
+ while ((NULL != FindQhPtr->Next) && (FindQhPtr->Interval > QhPtr->Interval)) {
+ FindQhPtr = FindQhPtr->Next;
+ }
+
+ if (FindQhPtr->Interval == QhPtr->Interval) {
+ //
+ // Link Qh after FindQh
+ //
+ if (NULL != FindQhPtr->Next) {
+ FindQhPtr->Next->Prev = QhPtr;
+ QhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(FindQhPtr->Next->Qh) >> 5);
+ QhPtr->Qh.SelectType = QH_SELECT_TYPE;
+ QhPtr->Qh.QhTerminate = FALSE;
+ }
+
+ FindQhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);
+ FindQhPtr->Qh.SelectType = QH_SELECT_TYPE;
+ FindQhPtr->Qh.QhTerminate = FALSE;
+
+ QhPtr->Prev = FindQhPtr;
+ QhPtr->Next = FindQhPtr->Next;
+ FindQhPtr->Next = QhPtr;
+ } else if (FindQhPtr->Interval < QhPtr->Interval) {
+ //
+ // Link Qh before FindQh
+ //
+ if (NULL == FindQhPtr->Prev) {
+ //
+ // Qh is the First one in Frame[0] List
+ //
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;
+ FrameEntryPtr->LinkTerminate = FALSE;
+ } else {
+ //
+ // Qh is not the First one in Frame[0] List
+ //
+ FindQhPtr->Prev->Next = QhPtr;
+ FindQhPtr->Prev->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);
+ FindQhPtr->Prev->Qh.SelectType = QH_SELECT_TYPE;
+ FindQhPtr->Prev->Qh.QhTerminate = FALSE;
+ }
+
+ QhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(FindQhPtr->Qh) >> 5);
+ QhPtr->Qh.SelectType = QH_SELECT_TYPE;
+ QhPtr->Qh.QhTerminate = FALSE;
+
+ QhPtr->Next = FindQhPtr;
+ QhPtr->Prev = FindQhPtr->Prev;
+ FindQhPtr->Prev = QhPtr;
+ } else {
+ //
+ // Link Qh after FindQh, Qh is the Last one
+ //
+ FindQhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);
+ FindQhPtr->Prev->Qh.SelectType = QH_SELECT_TYPE;
+ FindQhPtr->Qh.QhTerminate = FALSE;
+
+ QhPtr->Prev = FindQhPtr;
+ QhPtr->Next = NULL;
+ FindQhPtr->Next = QhPtr;
+ }
+ } else {
+ //
+ // Null FrameList
+ //
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;
+ FrameEntryPtr->LinkTerminate = FALSE;
+ }
+ //
+ // Other Frame[X]
+ //
+ if (NULL == QhPtr->Prev) {
+ //
+ // Qh is the First one in Frame[0] List
+ //
+ FrameIndex += QhPtr->Interval;
+ while (FrameIndex < HcDev->PeriodicFrameListLength) {
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) (FrameEntryPtr + QhPtr->Interval);
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;
+ FrameEntryPtr->LinkTerminate = FALSE;
+ FrameIndex += QhPtr->Interval;
+ }
+ } else if (QhPtr->Interval < QhPtr->Prev->Interval) {
+ //
+ // Qh is not the First one in Frame[0] List, and Prev.interval > Qh.interval
+ //
+ FrameIndex += QhPtr->Interval;
+ while (FrameIndex < HcDev->PeriodicFrameListLength) {
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) (FrameEntryPtr + QhPtr->Interval);
+ if ((FrameIndex % QhPtr->Prev->Interval) != 0) {
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;
+ FrameEntryPtr->LinkTerminate = FALSE;
+ }
+
+ FrameIndex += QhPtr->Interval;
+ }
+ }
+ } else {
+
+ //
+ // SyncInterruptTransfer Qh
+ //
+
+ if (!FrameEntryPtr->LinkTerminate) {
+ //
+ // Not Null FrameList
+ //
+ FindQhHwPtr = (EHCI_QH_HW *) GET_0B_TO_31B (FrameEntryPtr->LinkPointer << 5);
+ FindQhPtr = (EHCI_QH_ENTITY *) GET_QH_ENTITY_ADDR (FindQhHwPtr);
+ //
+ // FindQh is Last Qh in the Asynchronous List, Link Qh after FindQh
+ //
+ while (NULL != FindQhPtr->Next) {
+ FindQhPtr = FindQhPtr->Next;
+ }
+
+ FindQhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);
+ FindQhPtr->Qh.SelectType = QH_SELECT_TYPE;
+ FindQhPtr->Qh.QhTerminate = FALSE;
+
+ FindQhPtr->Next = QhPtr;
+ QhPtr->Prev = FindQhPtr;
+ } else {
+ //
+ // Null FrameList
+ //
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;
+ FrameEntryPtr->LinkTerminate = FALSE;
+ }
+ }
+
+ return ;
+}
+
+VOID
+UnlinkQhFromPeriodicList (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_QH_ENTITY *QhPtr,
+ IN UINTN Interval
+ )
+/*++
+
+Routine Description:
+
+ Unlink Qh from Periodic Schedule List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ QhPtr - A pointer to Qh
+ Interval - Interval of this periodic transfer
+
+Returns:
+
+ VOID
+
+--*/
+{
+ FRAME_LIST_ENTRY *FrameEntryPtr;
+ UINTN FrameIndex;
+
+ FrameIndex = 0;
+
+ ASSERT (HcDev);
+ ASSERT (QhPtr);
+
+ FrameIndex = 0;
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;
+
+ if (QhPtr->TransferType == ASYNC_INTERRUPT_TRANSFER) {
+
+ //
+ // AsyncInterruptTransfer Qh
+ //
+
+ if (NULL == QhPtr->Prev) {
+ //
+ // Qh is the First one on Frame[0] List
+ //
+ if (NULL == QhPtr->Next) {
+ //
+ // Only one on Frame[0] List
+ //
+ while (FrameIndex < HcDev->PeriodicFrameListLength) {
+ FrameEntryPtr->LinkPointer = 0;
+ FrameEntryPtr->SelectType = 0;
+ FrameEntryPtr->LinkTerminate = TRUE;
+ FrameEntryPtr += Interval;
+ FrameIndex += Interval;
+ }
+ } else {
+ while (FrameIndex < HcDev->PeriodicFrameListLength) {
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Next->Qh) >> 5);
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;
+ FrameEntryPtr->LinkTerminate = FALSE;
+ FrameEntryPtr += Interval;
+ FrameIndex += Interval;
+ }
+ }
+ } else {
+
+ //
+ // Not First one on Frame[0] List
+ //
+ if (NULL == QhPtr->Next) {
+ //
+ // Qh is the Last one on Frame[0] List
+ //
+ QhPtr->Prev->Qh.QhHorizontalPointer = 0;
+ QhPtr->Prev->Qh.SelectType = 0;
+ QhPtr->Prev->Qh.QhTerminate = TRUE;
+ } else {
+ QhPtr->Prev->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Next->Qh) >> 5);
+ QhPtr->Prev->Qh.SelectType = QH_SELECT_TYPE;
+ QhPtr->Prev->Qh.QhTerminate = FALSE;
+ }
+
+ if (Interval == QhPtr->Prev->Interval) {
+ //
+ // Interval is the same as Prev
+ // Not involed Frame[X]
+ //
+ } else {
+ //
+ // Other Frame[X]
+ //
+ while (FrameIndex < HcDev->PeriodicFrameListLength) {
+ if ((FrameIndex % QhPtr->Prev->Interval) != 0) {
+ FrameEntryPtr->LinkPointer = QhPtr->Prev->Qh.QhHorizontalPointer;
+ FrameEntryPtr->SelectType = QhPtr->Prev->Qh.SelectType;
+ FrameEntryPtr->LinkTerminate = QhPtr->Prev->Qh.QhTerminate;
+ }
+ FrameEntryPtr += Interval;
+ FrameIndex += Interval;
+ }
+ }
+ }
+
+ if (NULL != QhPtr->Next) {
+ QhPtr->Next->Prev = QhPtr->Prev;
+ }
+
+ if (NULL != QhPtr->Prev) {
+ QhPtr->Prev->Next = QhPtr->Next;
+ }
+ } else {
+ //
+ // SyncInterruptTransfer Qh
+ //
+ if (NULL == QhPtr->Prev) {
+ //
+ // Qh is the only one Qh on Frame[0] List
+ //
+ FrameEntryPtr->LinkPointer = 0;
+ FrameEntryPtr->SelectType = 0;
+ FrameEntryPtr->LinkTerminate = TRUE;
+ } else {
+ QhPtr->Prev->Qh.QhHorizontalPointer = 0;
+ QhPtr->Prev->Qh.SelectType = 0;
+ QhPtr->Prev->Qh.QhTerminate = TRUE;
+ }
+
+ if (NULL != QhPtr->Prev) {
+ QhPtr->Prev->Next = NULL;
+ }
+ }
+
+ return ;
+}
+
+VOID
+LinkToAsyncReqeust (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr
+ )
+/*++
+
+Routine Description:
+
+ Llink AsyncRequest Entry to Async Request List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ AsyncRequestPtr - A pointer to Async Request Entry
+
+Returns:
+
+ VOID
+
+--*/
+{
+ EHCI_ASYNC_REQUEST *CurrentPtr;
+
+ CurrentPtr = HcDev->AsyncRequestList;
+ HcDev->AsyncRequestList = AsyncRequestPtr;
+ AsyncRequestPtr->Prev = NULL;
+ AsyncRequestPtr->Next = CurrentPtr;
+
+ if (NULL != CurrentPtr) {
+ CurrentPtr->Prev = AsyncRequestPtr;
+ }
+
+ return ;
+}
+
+VOID
+UnlinkFromAsyncReqeust (
+ IN USB2_HC_DEV *HcDev,
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr
+ )
+/*++
+
+Routine Description:
+
+ Unlink AsyncRequest Entry from Async Request List
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ AsyncRequestPtr - A pointer to Async Request Entry
+
+Returns:
+
+ VOID
+
+--*/
+{
+ if (NULL == AsyncRequestPtr->Prev) {
+ HcDev->AsyncRequestList = AsyncRequestPtr->Next;
+ if (NULL != AsyncRequestPtr->Next) {
+ AsyncRequestPtr->Next->Prev = NULL;
+ }
+ } else {
+ AsyncRequestPtr->Prev->Next = AsyncRequestPtr->Next;
+ if (NULL != AsyncRequestPtr->Next) {
+ AsyncRequestPtr->Next->Prev = AsyncRequestPtr->Prev;
+ }
+ }
+
+ return ;
+}
+
+VOID
+SetQtdBufferPointer (
+ IN EHCI_QTD_HW *QtdHwPtr,
+ IN VOID *DataPtr,
+ IN UINTN DataLen
+ )
+/*++
+
+Routine Description:
+
+ Set data buffer pointers in Qtd
+
+Arguments:
+
+ QtdHwPtr - A pointer to Qtd hardware structure
+ DataPtr - A pointer to user data buffer
+ DataLen - Length of the user data buffer
+
+Returns:
+
+ VOID
+
+--*/
+{
+ UINTN RemainLen;
+
+ RemainLen = DataLen;
+ ASSERT (QtdHwPtr);
+
+ //
+ // Set BufferPointer0, ExtBufferPointer0 and Offset
+ //
+ QtdHwPtr->BufferPointer0 = (UINT32) (GET_0B_TO_31B (DataPtr) >> 12);
+ QtdHwPtr->CurrentOffset = (UINT32) (GET_0B_TO_31B (DataPtr) & EFI_PAGE_MASK);
+ QtdHwPtr->ExtBufferPointer0 = (UINT32) GET_32B_TO_63B (DataPtr);
+
+ //
+ // Set BufferPointer1 and ExtBufferPointer1
+ //
+ RemainLen = RemainLen > (EFI_PAGE_SIZE - QtdHwPtr->CurrentOffset) ? (RemainLen - (EFI_PAGE_SIZE - QtdHwPtr->CurrentOffset)) : 0;
+ if (RemainLen == 0) {
+ goto exit;
+ }
+
+ QtdHwPtr->BufferPointer1 = QtdHwPtr->BufferPointer0 + 1;
+ QtdHwPtr->ExtBufferPointer1 = QtdHwPtr->ExtBufferPointer0;
+
+ //
+ // Set BufferPointer2 and ExtBufferPointer2
+ //
+ RemainLen = RemainLen > EFI_PAGE_SIZE ? (RemainLen - EFI_PAGE_SIZE) : 0;
+ if (RemainLen == 0) {
+ goto exit;
+ }
+
+ QtdHwPtr->BufferPointer2 = QtdHwPtr->BufferPointer1 + 1;
+ QtdHwPtr->ExtBufferPointer2 = QtdHwPtr->ExtBufferPointer0;
+
+ //
+ // Set BufferPointer3 and ExtBufferPointer3
+ //
+ RemainLen = RemainLen > EFI_PAGE_SIZE ? (RemainLen - EFI_PAGE_SIZE) : 0;
+ if (RemainLen == 0) {
+ goto exit;
+ }
+
+ QtdHwPtr->BufferPointer3 = QtdHwPtr->BufferPointer2 + 1;
+ QtdHwPtr->ExtBufferPointer3 = QtdHwPtr->ExtBufferPointer0;
+
+ //
+ // Set BufferPointer4 and ExtBufferPointer4
+ //
+ RemainLen = RemainLen > EFI_PAGE_SIZE ? (RemainLen - EFI_PAGE_SIZE) : 0;
+ if (RemainLen == 0) {
+ goto exit;
+ }
+
+ QtdHwPtr->BufferPointer4 = QtdHwPtr->BufferPointer3 + 1;
+ QtdHwPtr->ExtBufferPointer4 = QtdHwPtr->ExtBufferPointer0;
+
+exit:
+ return ;
+}
+
+BOOLEAN
+IsQtdStatusActive (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Whether Qtd status is active or not
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ TRUE Active
+ FALSE Inactive
+
+--*/
+{
+ UINT8 QtdStatus;
+ BOOLEAN Value;
+
+ QtdStatus = (UINT8) (HwQtdPtr->Status);
+ Value = (BOOLEAN) (QtdStatus & QTD_STATUS_ACTIVE);
+
+ return Value;
+}
+
+BOOLEAN
+IsQtdStatusHalted (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Whether Qtd status is halted or not
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ TRUE Halted
+ FALSE Not halted
+
+--*/
+{
+ UINT8 QtdStatus;
+ BOOLEAN Value;
+
+ QtdStatus = (UINT8) (HwQtdPtr->Status);
+ Value = (BOOLEAN) (QtdStatus & QTD_STATUS_HALTED);
+
+ return Value;
+}
+
+BOOLEAN
+IsQtdStatusBufferError (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Whether Qtd status is buffer error or not
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ TRUE Buffer error
+ FALSE No buffer error
+
+--*/
+{
+ UINT8 QtdStatus;
+ BOOLEAN Value;
+
+ QtdStatus = (UINT8) (HwQtdPtr->Status);
+ Value = (BOOLEAN) (QtdStatus & QTD_STATUS_BUFFER_ERR);
+
+ return Value;
+}
+
+BOOLEAN
+IsQtdStatusBabbleError (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Whether Qtd status is babble error or not
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ TRUE Babble error
+ FALSE No babble error
+
+--*/
+{
+ UINT8 QtdStatus;
+ BOOLEAN Value;
+
+ QtdStatus = (UINT8) (HwQtdPtr->Status);
+ Value = (BOOLEAN) (QtdStatus & QTD_STATUS_BABBLE_ERR);
+
+ return Value;
+}
+
+BOOLEAN
+IsQtdStatusTransactionError (
+ IN EHCI_QTD_HW *HwQtdPtr
+ )
+/*++
+
+Routine Description:
+
+ Whether Qtd status is transaction error or not
+
+Arguments:
+
+ HwQtdPtr - A pointer to hardware Qtd structure
+
+Returns:
+
+ TRUE Transaction error
+ FALSE No transaction error
+
+--*/
+{
+ UINT8 QtdStatus;
+ BOOLEAN Value;
+
+ QtdStatus = (UINT8) (HwQtdPtr->Status);
+ Value = (BOOLEAN) (QtdStatus & QTD_STATUS_TRANSACTION_ERR);
+
+ return Value;
+}
+
+BOOLEAN
+IsDataInTransfer (
+ IN UINT8 EndPointAddress
+ )
+/*++
+
+Routine Description:
+
+ Whether is a DataIn direction transfer
+
+Arguments:
+
+ EndPointAddress - address of the endpoint
+
+Returns:
+
+ TRUE DataIn
+ FALSE DataOut
+
+--*/
+{
+ BOOLEAN Value;
+
+ if (EndPointAddress & 0x80) {
+ Value = TRUE;
+ } else {
+ Value = FALSE;
+ }
+
+ return Value;
+}
+
+EFI_STATUS
+MapDataBuffer (
+ IN USB2_HC_DEV *HcDev,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN VOID *Data,
+ IN OUT UINTN *DataLength,
+ OUT UINT8 *PktId,
+ OUT UINT8 **DataCursor,
+ OUT VOID **DataMap
+ )
+/*++
+
+Routine Description:
+
+ Map address of user data buffer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ TransferDirection - direction of transfer
+ Data - A pointer to user data buffer
+ DataLength - length of user data
+ PktId - Packte Identificaion
+ DataCursor - mapped address to return
+ DataMap - identificaion of this mapping to return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS TempPhysicalAddr;
+
+ Status = EFI_SUCCESS;
+
+ switch (TransferDirection) {
+
+ case EfiUsbDataIn:
+
+ *PktId = INPUT_PACKET_ID;
+ //
+ // BusMasterWrite means cpu read
+ //
+ Status = HcDev->PciIo->Map (
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterWrite,
+ Data,
+ DataLength,
+ &TempPhysicalAddr,
+ DataMap
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((gEHCDebugLevel, "MapDataBuffer Failed\n"));
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ *DataCursor = (UINT8 *) ((UINTN) TempPhysicalAddr);
+ break;
+
+ case EfiUsbDataOut:
+
+ *PktId = OUTPUT_PACKET_ID;
+ //
+ // BusMasterRead means cpu write
+ //
+ Status = HcDev->PciIo->Map (
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ Data,
+ DataLength,
+ &TempPhysicalAddr,
+ DataMap
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ *DataCursor = (UINT8 *) ((UINTN) TempPhysicalAddr);
+ break;
+
+ case EfiUsbNoData:
+
+ *PktId = OUTPUT_PACKET_ID;
+ Data = NULL;
+ *DataLength = 0;
+ *DataCursor = NULL;
+ *DataMap = NULL;
+ break;
+
+ default:
+
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+MapRequestBuffer (
+ IN USB2_HC_DEV *HcDev,
+ IN OUT VOID *Request,
+ OUT UINT8 **RequestCursor,
+ OUT VOID **RequestMap
+ )
+/*++
+
+Routine Description:
+
+ Map address of request structure buffer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ Request - A pointer to request structure
+ RequestCursor - Mapped address of request structure to return
+ RequestMap - Identificaion of this mapping to return
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN RequestLen;
+ EFI_PHYSICAL_ADDRESS TempPhysicalAddr;
+
+ RequestLen = sizeof (EFI_USB_DEVICE_REQUEST);
+ Status = HcDev->PciIo->Map (
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ (UINT8 *) Request,
+ (UINTN *) &RequestLen,
+ &TempPhysicalAddr,
+ RequestMap
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ *RequestCursor = (UINT8 *) ((UINTN) TempPhysicalAddr);
+
+exit:
+ return Status;
+}
+
+EFI_STATUS
+DeleteAsyncRequestTransfer (
+ IN USB2_HC_DEV *HcDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ OUT UINT8 *DataToggle
+ )
+/*++
+
+Routine Description:
+
+ Delete all asynchronous request transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ DeviceAddress - address of usb device
+ EndPointAddress - address of endpoint
+ DataToggle - stored data toggle
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ EHCI_ASYNC_REQUEST *AsyncRequestPtr;
+ EHCI_ASYNC_REQUEST *MatchPtr;
+ EHCI_QH_HW *QhHwPtr;
+ UINT8 EndPointNum;
+
+ if (NULL == HcDev->AsyncRequestList) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ MatchPtr = NULL;
+ QhHwPtr = NULL;
+ EndPointNum = EndPointAddress & 0x0f;
+ AsyncRequestPtr = HcDev->AsyncRequestList;
+
+ //
+ // Find QH of AsyncRequest by DeviceAddress and EndPointNum
+ //
+ do {
+
+ QhHwPtr = &(AsyncRequestPtr->QhPtr->Qh);
+ if (QhHwPtr->DeviceAddr == DeviceAddress && QhHwPtr->EndpointNum == EndPointNum) {
+ MatchPtr = AsyncRequestPtr;
+ break;
+ }
+
+ AsyncRequestPtr = AsyncRequestPtr->Next;
+
+ } while (NULL != AsyncRequestPtr);
+
+ if (NULL == MatchPtr) {
+ Status = EFI_INVALID_PARAMETER;
+ goto exit;
+ }
+
+ Status = DisablePeriodicSchedule (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleDisable TimeOut\n"));
+ Status = EFI_TIMEOUT;
+ goto exit;
+ }
+
+ *DataToggle = (UINT8) MatchPtr->QhPtr->Qh.DataToggle;
+ UnlinkQhFromPeriodicList (HcDev, MatchPtr->QhPtr, MatchPtr->QhPtr->Interval);
+ UnlinkFromAsyncReqeust (HcDev, MatchPtr);
+
+ if (NULL == HcDev->AsyncRequestList) {
+
+ Status = StopPollingTimer (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ } else {
+
+ Status = EnablePeriodicSchedule (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+
+ Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleEnable TimeOut\n"));
+ Status = EFI_TIMEOUT;
+ goto exit;
+ }
+
+ if (IsEhcHalted (HcDev)) {
+ Status = StartScheduleExecution (HcDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit;
+ }
+ }
+
+ }
+
+ DestoryQtds (HcDev, MatchPtr->QhPtr->FirstQtdPtr);
+ DestoryQh (HcDev, MatchPtr->QhPtr);
+ EhciFreePool (HcDev, (UINT8 *) MatchPtr, sizeof (EHCI_ASYNC_REQUEST));
+
+exit:
+ return Status;
+}
+
+VOID
+CleanUpAllAsyncRequestTransfer (
+ IN USB2_HC_DEV *HcDev
+ )
+/*++
+
+Routine Description:
+
+ Clean up all asynchronous request transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+
+Returns:
+
+ VOID
+
+--*/
+{
+ EHCI_ASYNC_REQUEST *AsyncRequestPtr;
+ EHCI_ASYNC_REQUEST *FreePtr;
+
+ AsyncRequestPtr = NULL;
+ FreePtr = NULL;
+
+ StopPollingTimer (HcDev);
+
+ AsyncRequestPtr = HcDev->AsyncRequestList;
+ while (NULL != AsyncRequestPtr) {
+
+ FreePtr = AsyncRequestPtr;
+ AsyncRequestPtr = AsyncRequestPtr->Next;
+ UnlinkFromAsyncReqeust (HcDev, FreePtr);
+ UnlinkQhFromPeriodicList (HcDev, FreePtr->QhPtr, FreePtr->QhPtr->Interval);
+ DestoryQtds (HcDev, FreePtr->QhPtr->FirstQtdPtr);
+ DestoryQh (HcDev, FreePtr->QhPtr);
+ EhciFreePool (HcDev, (UINT8 *) FreePtr, sizeof (EHCI_ASYNC_REQUEST));
+
+ }
+
+ return ;
+}
+
+VOID
+ZeroOutQhOverlay (
+ IN EHCI_QH_ENTITY *QhPtr
+ )
+/*++
+
+Routine Description:
+
+ Zero out the fields in Qh structure
+
+Arguments:
+
+ QhPtr - A pointer to Qh structure
+
+Returns:
+
+ VOID
+
+--*/
+{
+ QhPtr->Qh.CurrentQtdPointer = 0;
+ QhPtr->Qh.AltNextQtdPointer = 0;
+ QhPtr->Qh.NakCount = 0;
+ QhPtr->Qh.AltNextQtdTerminate = 0;
+ QhPtr->Qh.TotalBytes = 0;
+ QhPtr->Qh.InterruptOnComplete = 0;
+ QhPtr->Qh.CurrentPage = 0;
+ QhPtr->Qh.ErrorCount = 0;
+ QhPtr->Qh.PidCode = 0;
+ QhPtr->Qh.Status = 0;
+ QhPtr->Qh.BufferPointer0 = 0;
+ QhPtr->Qh.CurrentOffset = 0;
+ QhPtr->Qh.BufferPointer1 = 0;
+ QhPtr->Qh.CompleteSplitMask = 0;
+ QhPtr->Qh.BufferPointer2 = 0;
+ QhPtr->Qh.SplitBytes = 0;
+ QhPtr->Qh.FrameTag = 0;
+ QhPtr->Qh.BufferPointer3 = 0;
+ QhPtr->Qh.BufferPointer4 = 0;
+ QhPtr->Qh.ExtBufferPointer0 = 0;
+ QhPtr->Qh.ExtBufferPointer1 = 0;
+ QhPtr->Qh.ExtBufferPointer2 = 0;
+ QhPtr->Qh.ExtBufferPointer3 = 0;
+ QhPtr->Qh.ExtBufferPointer4 = 0;
+}
+
+VOID
+UpdateAsyncRequestTransfer (
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr,
+ IN UINT32 TransferResult,
+ IN UINTN ErrQtdPos
+ )
+/*++
+
+Routine Description:
+
+ Update asynchronous request transfer
+
+Arguments:
+
+ AsyncRequestPtr - A pointer to async request
+ TransferResult - transfer result
+ ErrQtdPos - postion of error Qtd
+
+Returns:
+
+ VOID
+
+--*/
+{
+ EHCI_QTD_ENTITY *QtdPtr;
+
+ QtdPtr = NULL;
+
+ if (EFI_USB_NOERROR == TransferResult) {
+
+ //
+ // Update Qh for next trigger
+ //
+
+ QtdPtr = AsyncRequestPtr->QhPtr->FirstQtdPtr;
+
+ //
+ // Update fields in Qh
+ //
+
+ //
+ // Get DataToggle from Overlay in Qh
+ //
+ // ZeroOut Overlay in Qh except DataToggle, HostController will update this field
+ //
+ ZeroOutQhOverlay (AsyncRequestPtr->QhPtr);
+ AsyncRequestPtr->QhPtr->Qh.NextQtdPointer = (UINT32) (GET_0B_TO_31B (&(QtdPtr->Qtd)) >> 5);
+ AsyncRequestPtr->QhPtr->Qh.NextQtdTerminate = FALSE;
+
+ //
+ // Update fields in Qtd
+ //
+ while (NULL != QtdPtr) {
+ QtdPtr->Qtd.TotalBytes = QtdPtr->StaticTotalBytes;
+ QtdPtr->Qtd.CurrentOffset = QtdPtr->StaticCurrentOffset;
+ QtdPtr->Qtd.CurrentPage = 0;
+ QtdPtr->Qtd.ErrorCount = QTD_ERROR_COUNTER;
+ QtdPtr->Qtd.Status = QTD_STATUS_ACTIVE;
+
+ QtdPtr->TotalBytes = QtdPtr->StaticTotalBytes;
+ QtdPtr = QtdPtr->Next;
+ }
+ }
+
+ return ;
+}
+
+BOOLEAN
+CheckQtdsTransferResult (
+ IN BOOLEAN IsControl,
+ IN EHCI_QH_ENTITY *QhPtr,
+ OUT UINT32 *Result,
+ OUT UINTN *ErrQtdPos,
+ OUT UINTN *ActualLen
+ )
+/*++
+
+Routine Description:
+
+ Check transfer result of Qtds
+
+Arguments:
+
+ IsControl - Is control transfer or not
+ QhPtr - A pointer to Qh
+ Result - Transfer result
+ ErrQtdPos - Error TD Position
+ ActualLen - Actual Transfer Size
+
+Returns:
+
+ TRUE Qtds finished
+ FALSE Not finish
+
+--*/
+{
+ UINTN ActualLenPerQtd;
+ EHCI_QTD_ENTITY *QtdPtr;
+ EHCI_QTD_HW *QtdHwPtr;
+ BOOLEAN Value;
+
+ ASSERT (QhPtr);
+ ASSERT (Result);
+ ASSERT (ErrQtdPos);
+ ASSERT (ActualLen);
+
+ Value = TRUE;
+ QtdPtr = QhPtr->FirstQtdPtr;
+ QtdHwPtr = &(QtdPtr->Qtd);
+
+ while (NULL != QtdHwPtr) {
+
+ if (IsQtdStatusActive (QtdHwPtr)) {
+ *Result |= EFI_USB_ERR_NOTEXECUTE;
+ }
+
+ if (IsQtdStatusHalted (QtdHwPtr)) {
+ *Result |= EFI_USB_ERR_STALL;
+ }
+
+ if (IsQtdStatusBufferError (QtdHwPtr)) {
+ *Result |= EFI_USB_ERR_BUFFER;
+ }
+
+ if (IsQtdStatusBabbleError (QtdHwPtr)) {
+ *Result |= EFI_USB_ERR_BABBLE;
+ }
+
+ if (IsQtdStatusTransactionError (QtdHwPtr)) {
+ *Result |= EFI_USB_ERR_TIMEOUT;
+ }
+
+ ActualLenPerQtd = QtdPtr->TotalBytes - QtdHwPtr->TotalBytes;
+ QtdPtr->TotalBytes = QtdHwPtr->TotalBytes;
+ //
+ // Accumulate actual transferred data length in each DataQtd.
+ //
+ if (SETUP_PACKET_PID_CODE != QtdHwPtr->PidCode) {
+ *ActualLen += ActualLenPerQtd;
+ }
+
+ if (*Result) {
+ Value = FALSE;
+ break;
+ }
+
+ if ((!IsControl) && (QtdPtr->TotalBytes > 0)) {
+ //
+ // Did something, but isn't full workload
+ //
+ break;
+ }
+
+ (*ErrQtdPos)++;
+ QtdHwPtr = GetQtdNextPointer (QtdHwPtr);
+ QtdPtr = (EHCI_QTD_ENTITY *) GET_QTD_ENTITY_ADDR (QtdHwPtr);
+
+ }
+
+ return Value;
+}
+
+EFI_STATUS
+ExecuteTransfer (
+ IN USB2_HC_DEV *HcDev,
+ IN BOOLEAN IsControl,
+ IN EHCI_QH_ENTITY *QhPtr,
+ IN OUT UINTN *ActualLen,
+ OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+Routine Description:
+
+ Execute Bulk or SyncInterrupt Transfer
+
+Arguments:
+
+ HcDev - USB2_HC_DEV
+ IsControl - Is control transfer or not
+ QhPtr - A pointer to Qh
+ ActualLen - Actual transfered Len
+ DataToggle - Data Toggle
+ TimeOut - TimeOut threshold
+ TransferResult - Transfer result
+
+Returns:
+
+ EFI_SUCCESS Sucess
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN ErrQtdPos;
+ UINTN Delay;
+ UINTN RequireLen;
+ BOOLEAN Finished;
+
+ Status = EFI_SUCCESS;
+ ErrQtdPos = 0;
+ *TransferResult = EFI_USB_NOERROR;
+ RequireLen = *ActualLen;
+ *ActualLen = 0;
+ Finished = FALSE;
+
+ Delay = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;
+
+ do {
+ *TransferResult = 0;
+ Finished = CheckQtdsTransferResult (
+ IsControl,
+ QhPtr,
+ TransferResult,
+ &ErrQtdPos,
+ ActualLen
+ );
+ if (Finished) {
+ break;
+ }
+ //
+ // Qtd is inactive, which means bulk or interrupt transfer's end.
+ //
+ if (!(*TransferResult & EFI_USB_ERR_NOTEXECUTE)) {
+ break;
+ }
+
+ gBS->Stall (EHCI_SYNC_REQUEST_POLLING_TIME);
+
+ } while (--Delay);
+
+ if (EFI_USB_NOERROR != *TransferResult) {
+ if (0 == Delay) {
+ Status = EFI_TIMEOUT;
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+
+ //
+ // Special for Bulk and Interrupt Transfer
+ //
+ *DataToggle = (UINT8) QhPtr->Qh.DataToggle;
+
+ return Status;
+}
+
+EFI_STATUS
+AsyncRequestMoniter (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+Routine Description:
+
+ Interrupt transfer periodic check handler
+
+Arguments:
+ Event - Interrupt event
+ Context - Pointer to USB2_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+ USB2_HC_DEV *HcDev;
+ EHCI_ASYNC_REQUEST *AsyncRequestPtr;
+ EHCI_QTD_HW *QtdHwPtr;
+ UINTN ErrQtdPos;
+ UINTN ActualLen;
+ UINT32 TransferResult;
+ UINT8 *ReceiveBuffer;
+ UINT8 *ProcessBuffer;
+
+ Status = EFI_SUCCESS;
+ QtdHwPtr = NULL;
+ ReceiveBuffer = NULL;
+ ProcessBuffer = NULL;
+ HcDev = (USB2_HC_DEV *) Context;
+ AsyncRequestPtr = HcDev->AsyncRequestList;
+
+ while (NULL != AsyncRequestPtr) {
+
+ TransferResult = 0;
+ ErrQtdPos = 0;
+ ActualLen = 0;
+
+ CheckQtdsTransferResult (
+ FALSE,
+ AsyncRequestPtr->QhPtr,
+ &TransferResult,
+ &ErrQtdPos,
+ &ActualLen
+ );
+
+ if ((TransferResult & EFI_USB_ERR_NAK) || (TransferResult & EFI_USB_ERR_NOTEXECUTE)) {
+ AsyncRequestPtr = AsyncRequestPtr->Next;
+ continue;
+ }
+ //
+ // Allocate memory for EHC private data structure
+ //
+ ProcessBuffer = AllocateZeroPool (ActualLen);
+ if (NULL == ProcessBuffer) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto exit;
+ }
+
+ QtdHwPtr = &(AsyncRequestPtr->QhPtr->FirstQtdPtr->Qtd);
+ ReceiveBuffer = (UINT8 *) GET_0B_TO_31B ((QtdHwPtr->BufferPointer0 << 12) | AsyncRequestPtr->QhPtr->FirstQtdPtr->StaticCurrentOffset);
+ CopyMem (
+ ProcessBuffer,
+ ReceiveBuffer,
+ ActualLen
+ );
+
+ UpdateAsyncRequestTransfer (AsyncRequestPtr, TransferResult, ErrQtdPos);
+
+ if (EFI_USB_NOERROR == TransferResult) {
+
+ if (AsyncRequestPtr->CallBackFunc != NULL) {
+ (AsyncRequestPtr->CallBackFunc) (ProcessBuffer, ActualLen, AsyncRequestPtr->Context, TransferResult);
+ }
+
+ } else {
+
+ //
+ // leave error recovery to its related device driver. A common case of
+ // the error recovery is to re-submit the interrupt transfer.
+ // When an interrupt transfer is re-submitted, its position in the linked
+ // list is changed. It is inserted to the head of the linked list, while
+ // this function scans the whole list from head to tail. Thus, the
+ // re-submitted interrupt transfer's callback function will not be called
+ // again in this round.
+ //
+ if (AsyncRequestPtr->CallBackFunc != NULL) {
+ (AsyncRequestPtr->CallBackFunc) (NULL, 0, AsyncRequestPtr->Context, TransferResult);
+ }
+
+ }
+
+ if (NULL != ProcessBuffer) {
+ gBS->FreePool (ProcessBuffer);
+ }
+
+ AsyncRequestPtr = AsyncRequestPtr->Next;
+
+ }
+
+exit:
+ return Status;
+}
+
diff --git a/EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.msa b/EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.msa
index 66a41d9319..3d24744f12 100644
--- a/EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.msa
+++ b/EdkModulePkg/Bus/Pci/Uhci/Dxe/Uhci.msa
@@ -71,6 +71,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
<Protocol Usage="BY_START">
<ProtocolCName>gEfiUsbHcProtocolGuid</ProtocolCName>
</Protocol>
+ <Protocol Usage="BY_START">
+ <ProtocolCName>gEfiUsb2HcProtocolGuid</ProtocolCName>
+ </Protocol>
</Protocols>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
diff --git a/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c b/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
index 62d58eed78..74ddc6bb12 100644
--- a/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
+++ b/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
@@ -49,13 +49,13 @@ Returns:
// Perform 16bit Read in PCI IO Space
//
return PciIo->Io.Read (
- PciIo,
- EfiPciIoWidthUint16,
- USB_BAR_INDEX,
- (UINT64) PortOffset,
- 1,
- Data
- );
+ PciIo,
+ EfiPciIoWidthUint16,
+ USB_BAR_INDEX,
+ (UINT64) PortOffset,
+ 1,
+ Data
+ );
}
EFI_STATUS
@@ -86,13 +86,13 @@ Returns:
// Perform 32bit Read in PCI IO Space
//
return PciIo->Io.Read (
- PciIo,
- EfiPciIoWidthUint32,
- USB_BAR_INDEX,
- (UINT64) PortOffset,
- 1,
- Data
- );
+ PciIo,
+ EfiPciIoWidthUint32,
+ USB_BAR_INDEX,
+ (UINT64) PortOffset,
+ 1,
+ Data
+ );
}
EFI_STATUS
@@ -123,13 +123,13 @@ Returns:
// Perform 16bit Write in PCI IO Space
//
return PciIo->Io.Write (
- PciIo,
- EfiPciIoWidthUint16,
- USB_BAR_INDEX,
- (UINT64) PortOffset,
- 1,
- &Data
- );
+ PciIo,
+ EfiPciIoWidthUint16,
+ USB_BAR_INDEX,
+ (UINT64) PortOffset,
+ 1,
+ &Data
+ );
}
EFI_STATUS
@@ -160,13 +160,13 @@ Returns:
// Perform 32bit Write in PCI IO Space
//
return PciIo->Io.Write (
- PciIo,
- EfiPciIoWidthUint32,
- USB_BAR_INDEX,
- (UINT64) PortOffset,
- 1,
- &Data
- );
+ PciIo,
+ EfiPciIoWidthUint32,
+ USB_BAR_INDEX,
+ (UINT64) PortOffset,
+ 1,
+ &Data
+ );
}
//
// USB register-base helper functions
@@ -657,10 +657,10 @@ Returns:
EFI_STATUS Status;
Status = ReadUHCCommandReg (
- HcDev->PciIo,
- (UINT32) (USBCMD),
- &CommandContent
- );
+ HcDev->PciIo,
+ (UINT32) (USBCMD),
+ &CommandContent
+ );
if ((CommandContent & USBCMD_MAXP) != USBCMD_MAXP) {
CommandContent |= USBCMD_MAXP;
@@ -715,25 +715,25 @@ Returns:
BufferSizeInBytes = 4096;
BufferSizeInPages = EFI_SIZE_TO_PAGES (BufferSizeInBytes);
Status = HcDev->PciIo->AllocateBuffer (
- HcDev->PciIo,
- AllocateAnyPages,
- EfiBootServicesData,
- BufferSizeInPages,
- &CommonBuffer,
- 0
- );
+ HcDev->PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ BufferSizeInPages,
+ &CommonBuffer,
+ 0
+ );
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
Status = HcDev->PciIo->Map (
- HcDev->PciIo,
- EfiPciIoOperationBusMasterCommonBuffer,
- CommonBuffer,
- &BufferSizeInBytes,
- &MappedAddress,
- &Mapping
- );
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ CommonBuffer,
+ &BufferSizeInBytes,
+ &MappedAddress,
+ &Mapping
+ );
if (EFI_ERROR (Status) || (BufferSizeInBytes != 4096)) {
HcDev->PciIo->FreeBuffer (HcDev->PciIo, BufferSizeInPages, CommonBuffer);
return EFI_UNSUPPORTED;
@@ -3589,13 +3589,13 @@ Returns:
// and it is allocated as common buffer use.
//
Status = HcDev->PciIo->AllocateBuffer (
- HcDev->PciIo,
- AllocateAnyPages,
- EfiBootServicesData,
- MemoryBlockSizeInPages,
- &CommonBuffer,
- 0
- );
+ HcDev->PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ MemoryBlockSizeInPages,
+ &CommonBuffer,
+ 0
+ );
if (EFI_ERROR (Status)) {
gBS->FreePool ((*MemoryHeader)->BitArrayPtr);
gBS->FreePool (*MemoryHeader);
@@ -3604,13 +3604,13 @@ Returns:
MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);
Status = HcDev->PciIo->Map (
- HcDev->PciIo,
- EfiPciIoOperationBusMasterCommonBuffer,
- CommonBuffer,
- &MemoryBlockSizeInBytes,
- &MappedAddress,
- &Mapping
- );
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ CommonBuffer,
+ &MemoryBlockSizeInBytes,
+ &MappedAddress,
+ &Mapping
+ );
//
// if returned Mapped size is less than the size we request,do not support.
//
@@ -3741,10 +3741,10 @@ Returns:
TempHeaderPtr = TempHeaderPtr->Next) {
Status = AllocMemInMemoryBlock (
- TempHeaderPtr,
- (VOID **) Pool,
- RealAllocSize / 32
- );
+ TempHeaderPtr,
+ (VOID **) Pool,
+ RealAllocSize / 32
+ );
if (!EFI_ERROR (Status)) {
ZeroMem (*Pool, AllocSize);
return EFI_SUCCESS;
@@ -3777,10 +3777,10 @@ Returns:
InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);
Status = AllocMemInMemoryBlock (
- NewMemoryHeader,
- (VOID **) Pool,
- RealAllocSize / 32
- );
+ NewMemoryHeader,
+ (VOID **) Pool,
+ RealAllocSize / 32
+ );
if (!EFI_ERROR (Status)) {
ZeroMem (*Pool, AllocSize);
@@ -4226,12 +4226,12 @@ TurnOffUSBEmulation (
//
Command = 0;
PciIo->Pci.Write (
- PciIo,
- EfiPciIoWidthUint16,
- USB_EMULATION,
- 1,
- &Command
- );
+ PciIo,
+ EfiPciIoWidthUint16,
+ USB_EMULATION,
+ 1,
+ &Command
+ );
return ;
}
diff --git a/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.c b/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.c
index 1eba8bed5b..14f8bf2790 100644
--- a/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.c
+++ b/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.c
@@ -28,13 +28,6 @@ Revision History
EFI_STATUS
EFIAPI
-UHCIDriverEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-EFI_STATUS
-EFIAPI
UHCIDriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
@@ -119,7 +112,7 @@ UHCIAsyncInterruptTransfer (
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN BOOLEAN IsSlowDevice,
- IN UINT8 MaxiumPacketLength,
+ IN UINT8 MaximumPacketLength,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle,
IN UINTN PollingInterval, OPTIONAL
@@ -200,6 +193,161 @@ UHCIClearRootHubPortFeature (
);
//
+// UEFI 2.0 Protocol
+//
+
+EFI_STATUS
+EFIAPI
+UHCI2GetCapability(
+ IN EFI_USB2_HC_PROTOCOL * This,
+ OUT UINT8 *MaxSpeed,
+ OUT UINT8 *PortNumber,
+ OUT UINT8 *Is64BitCapable
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2Reset (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT16 Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2GetState (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ OUT EFI_USB_HC_STATE * State
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2SetState (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN EFI_USB_HC_STATE State
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2ControlTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN 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,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2BulkTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2AsyncInterruptTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN BOOLEAN IsNewTransfer,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN PollingInterval, OPTIONAL
+ IN UINTN DataLength, OPTIONAL
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction, OPTIONAL
+ IN VOID *Context OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2SyncInterruptTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2IsochronousTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2AsyncIsochronousTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
+ IN VOID *Context OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2GetRootHubPortStatus (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS * PortStatus
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2SetRootHubPortFeature (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ );
+
+EFI_STATUS
+EFIAPI
+UHCI2ClearRootHubPortFeature (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ );
+
+//
// Asynchronous interrupt transfer monitor function
//
VOID
@@ -236,7 +384,7 @@ UHCIDriverBindingSupported (
Arguments:
This - Protocol instance pointer.
- Controller, - Handle of device to test
+ Controller - Handle of device to test
RemainingDevicePath - Not used
Returns:
@@ -289,20 +437,20 @@ UHCIDriverBindingSupported (
(UsbClassCReg.PI != PCI_CLASSC_PI_UHCI)) {
gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
return EFI_UNSUPPORTED;
}
gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
return EFI_SUCCESS;
}
@@ -351,6 +499,7 @@ UHCIDriverBindingStart (
if (EFI_ERROR (Status)) {
return Status;
}
+
//
// Turn off USB emulation
//
@@ -367,11 +516,11 @@ UHCIDriverBindingStart (
);
if (EFI_ERROR (Status)) {
gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
return EFI_UNSUPPORTED;
}
@@ -381,14 +530,14 @@ UHCIDriverBindingStart (
HcDev = AllocateZeroPool (sizeof (USB_HC_DEV));
if (HcDev == NULL) {
gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
return EFI_OUT_OF_RESOURCES;
}
-
+
//
// init EFI_USB_HC_PROTOCOL protocol interface and install the protocol
//
@@ -410,6 +559,27 @@ UHCIDriverBindingStart (
HcDev->UsbHc.MinorRevision = 0x1;
//
+ //
+ // init EFI_USB2_HC_PROTOCOL protocol interface and install the protocol
+ //
+ HcDev->Usb2Hc.GetCapability = UHCI2GetCapability;
+ HcDev->Usb2Hc.Reset = UHCI2Reset;
+ HcDev->Usb2Hc.GetState = UHCI2GetState;
+ HcDev->Usb2Hc.SetState = UHCI2SetState;
+ HcDev->Usb2Hc.ControlTransfer = UHCI2ControlTransfer;
+ HcDev->Usb2Hc.BulkTransfer = UHCI2BulkTransfer;
+ HcDev->Usb2Hc.AsyncInterruptTransfer = UHCI2AsyncInterruptTransfer;
+ HcDev->Usb2Hc.SyncInterruptTransfer = UHCI2SyncInterruptTransfer;
+ HcDev->Usb2Hc.IsochronousTransfer = UHCI2IsochronousTransfer;
+ HcDev->Usb2Hc.AsyncIsochronousTransfer = UHCI2AsyncIsochronousTransfer;
+ HcDev->Usb2Hc.GetRootHubPortStatus = UHCI2GetRootHubPortStatus;
+ HcDev->Usb2Hc.SetRootHubPortFeature = UHCI2SetRootHubPortFeature;
+ HcDev->Usb2Hc.ClearRootHubPortFeature = UHCI2ClearRootHubPortFeature;
+
+ HcDev->Usb2Hc.MajorRevision = 0x1;
+ HcDev->Usb2Hc.MinorRevision = 0x1;
+
+ //
// Init UHCI private data structures
//
HcDev->Signature = USB_HC_DEV_SIGNATURE;
@@ -428,14 +598,14 @@ UHCIDriverBindingStart (
}
gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
return EFI_OUT_OF_RESOURCES;
}
-
+
//
// Init interrupt list head in the HcDev structure.
//
@@ -460,11 +630,11 @@ UHCIDriverBindingStart (
}
gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
return EFI_UNSUPPORTED;
}
@@ -486,11 +656,11 @@ UHCIDriverBindingStart (
}
gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
return EFI_UNSUPPORTED;
}
@@ -518,7 +688,7 @@ UHCIDriverBindingStart (
);
return Status;
}
-
+
//
// Install Host Controller Protocol
//
@@ -538,17 +708,46 @@ UHCIDriverBindingStart (
}
gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return Status;
+ }
+
+ //
+ // Install USB2.0 Host Controller Protocol
+ //
+ Status = gBS->InstallProtocolInterface (
+ &Controller,
+ &gEfiUsb2HcProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &HcDev->Usb2Hc
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->CloseEvent (HcDev->InterruptTransTimer);
+ FreeFrameListEntry (HcDev);
+ DelMemoryManagement (HcDev);
+
+ if (HcDev != NULL) {
+ gBS->FreePool (HcDev);
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
return Status;
}
//
// component name protocol.
//
+
HcDev->ControllerNameTable = NULL;
AddUnicodeString (
"eng",
@@ -582,12 +781,17 @@ UnInstallUHCInterface (
HcDev = USB_HC_DEV_FROM_THIS (This);
gBS->UninstallProtocolInterface (
- Controller,
- &gEfiUsbHcProtocolGuid,
- &HcDev->UsbHc
- );
-
- //
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ &HcDev->UsbHc
+ );
+
+ gBS->UninstallProtocolInterface (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ &HcDev->Usb2Hc
+ );
+ //
// first stop USB Host Controller
//
This->SetState (This, EfiUsbHcStateHalt);
@@ -659,12 +863,31 @@ UHCIDriverBindingStop (
--*/
{
EFI_USB_HC_PROTOCOL *UsbHc;
+ EFI_USB2_HC_PROTOCOL *Usb2Hc;
EFI_STATUS OpenStatus;
OpenStatus = gBS->OpenProtocol (
Controller,
&gEfiUsbHcProtocolGuid,
- (VOID **) &UsbHc,
+ (VOID **)&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;
+ }
+
+ OpenStatus = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ (VOID **) &Usb2Hc,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
@@ -684,11 +907,11 @@ UHCIDriverBindingStop (
UnInstallUHCInterface (Controller, UsbHc);
gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
return EFI_SUCCESS;
@@ -753,20 +976,20 @@ UHCIReset (
// set the Global Reset bit in the command register
//
Status = ReadUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- &Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ &Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
Command |= USBCMD_GRESET;
Status = WriteUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -782,10 +1005,10 @@ UHCIReset (
//
Command &= ~USBCMD_GRESET;
Status = WriteUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -801,20 +1024,20 @@ UHCIReset (
// set Host Controller Reset bit to 1
//
Status = ReadUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- &Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ &Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
Command |= USBCMD_HCRESET;
Status = WriteUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -905,20 +1128,20 @@ UHCIGetState (
StatusRegAddr = (UINT32) (USBSTS);
Status = ReadUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- &UhcCommand
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ &UhcCommand
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
Status = ReadUHCCommandReg (
- HcDev->PciIo,
- StatusRegAddr,
- &UhcStatus
- );
+ HcDev->PciIo,
+ StatusRegAddr,
+ &UhcStatus
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -990,10 +1213,10 @@ UHCISetState (
}
Status = ReadUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- &Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ &Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -1001,10 +1224,10 @@ UHCISetState (
Command &= ~USBCMD_RS;
Status = WriteUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -1033,20 +1256,20 @@ UHCISetState (
// Set Run/Stop bit to 1.
//
Status = ReadUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- &Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ &Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
Command |= USBCMD_RS | USBCMD_MAXP;
Status = WriteUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -1055,10 +1278,10 @@ UHCISetState (
case EfiUsbHcStateSuspend:
Status = ReadUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- &Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ &Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -1115,20 +1338,20 @@ UHCISetState (
// Set Enter Global Suspend Mode bit to 1.
//
Status = ReadUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- &Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ &Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
Command |= USBCMD_EGSM;
Status = WriteUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -1185,10 +1408,10 @@ UHCIGetRootHubPortNumber (
for (Index = 0; Index < 2; Index++) {
PSAddr = (UINT32) (USBPORTSC1 + Index * 2);
Status = ReadRootPortReg (
- HcDev->PciIo,
- PSAddr,
- &RHPortControl
- );
+ HcDev->PciIo,
+ PSAddr,
+ &RHPortControl
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -1261,10 +1484,10 @@ UHCIGetRootHubPortStatus (
PortStatus->PortChangeStatus = 0;
Status = ReadRootPortReg (
- HcDev->PciIo,
- PSAddr,
- &RHPortStatus
- );
+ HcDev->PciIo,
+ PSAddr,
+ &RHPortStatus
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
@@ -1307,6 +1530,10 @@ UHCIGetRootHubPortStatus (
PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
}
//
+ // CHC will always return one in this bit
+ //
+ PortStatus->PortStatus |= USB_PORT_STAT_OWNER;
+ //
// Fill Port Status Change bits
//
@@ -1393,10 +1620,10 @@ UHCISetRootHubPortFeature (
case EfiUsbPortSuspend:
Status = ReadUHCCommandReg (
- HcDev->PciIo,
- CommandRegAddr,
- &Command
- );
+ HcDev->PciIo,
+ CommandRegAddr,
+ &Command
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -1487,10 +1714,10 @@ UHCIClearRootHubPortFeature (
PSAddr = (UINT32) (USBPORTSC1 + PortNumber * 2);
Status = ReadRootPortReg (
- HcDev->PciIo,
- PSAddr,
- &RHPortControl
- );
+ HcDev->PciIo,
+ PSAddr,
+ &RHPortControl
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -1733,13 +1960,13 @@ UHCIControlTransfer (
// BusMasterWrite means cpu read
//
Status = HcDev->PciIo->Map (
- HcDev->PciIo,
- EfiPciIoOperationBusMasterWrite,
- PtrDataSource,
- &DataLen,
- &TempPtr,
- &Mapping
- );
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterWrite,
+ PtrDataSource,
+ &DataLen,
+ &TempPtr,
+ &Mapping
+ );
if (EFI_ERROR (Status)) {
return Status;
}
@@ -1757,13 +1984,13 @@ UHCIControlTransfer (
// BusMasterRead means cpu write
//
Status = HcDev->PciIo->Map (
- HcDev->PciIo,
- EfiPciIoOperationBusMasterRead,
- PtrDataSource,
- &DataLen,
- &TempPtr,
- &Mapping
- );
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ PtrDataSource,
+ &DataLen,
+ &TempPtr,
+ &Mapping
+ );
if (EFI_ERROR (Status)) {
return Status;
}
@@ -1809,13 +2036,13 @@ UHCIControlTransfer (
//
RequestLen = sizeof (EFI_USB_DEVICE_REQUEST);
Status = HcDev->PciIo->Map (
- HcDev->PciIo,
- EfiPciIoOperationBusMasterRead,
- (UINT8 *) Request,
- &RequestLen,
- &TempPtr,
- &RequestMapping
- );
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ (UINT8 *) Request,
+ &RequestLen,
+ &TempPtr,
+ &RequestMapping
+ );
if (EFI_ERROR (Status)) {
HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);
@@ -1829,14 +2056,14 @@ UHCIControlTransfer (
// generate Setup Stage TD
//
Status = GenSetupStageTD (
- HcDev,
- DeviceAddress,
- 0,
- IsSlowDevice,
- (UINT8 *) RequestMappedAddress,
- sizeof (EFI_USB_DEVICE_REQUEST),
- &PtrSetupTD
- );
+ HcDev,
+ DeviceAddress,
+ 0,
+ IsSlowDevice,
+ (UINT8 *) RequestMappedAddress,
+ sizeof (EFI_USB_DEVICE_REQUEST),
+ &PtrSetupTD
+ );
if (EFI_ERROR (Status)) {
HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);
@@ -1864,16 +2091,16 @@ UHCIControlTransfer (
}
Status = GenDataTD (
- HcDev,
- DeviceAddress,
- 0,
- Ptr,
- PktSize,
- PktID,
- DataToggle,
- IsSlowDevice,
- &PtrTD
- );
+ HcDev,
+ DeviceAddress,
+ 0,
+ Ptr,
+ PktSize,
+ PktID,
+ DataToggle,
+ IsSlowDevice,
+ &PtrTD
+ );
if (EFI_ERROR (Status)) {
//
@@ -1920,13 +2147,13 @@ UHCIControlTransfer (
// create Status Stage TD structure
//
Status = CreateStatusTD (
- HcDev,
- DeviceAddress,
- 0,
- PktID,
- IsSlowDevice,
- &PtrStatusTD
- );
+ HcDev,
+ DeviceAddress,
+ 0,
+ PktID,
+ IsSlowDevice,
+ &PtrStatusTD
+ );
if (EFI_ERROR (Status)) {
HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);
@@ -2009,13 +2236,13 @@ UHCIControlTransfer (
}
Status = ExecuteControlTransfer (
- HcDev,
- PtrFirstDataTD,
- LoadFrameListIndex,
- DataLength,
- TimeOut,
- TransferResult
- );
+ HcDev,
+ PtrFirstDataTD,
+ LoadFrameListIndex,
+ DataLength,
+ TimeOut,
+ TransferResult
+ );
for (Index = 0; Index < 500; Index++) {
DelLinkSingleQH (
@@ -2060,13 +2287,13 @@ UHCIControlTransfer (
// detail status is returned
//
Status = ExecuteControlTransfer (
- HcDev,
- PtrStatusTD,
- LoadFrameListIndex,
- DataLength,
- TimeOut,
- TransferResult
- );
+ HcDev,
+ PtrStatusTD,
+ LoadFrameListIndex,
+ DataLength,
+ TimeOut,
+ TransferResult
+ );
//
// Delete Control Transfer QH-TDs structure
@@ -2123,13 +2350,13 @@ UHCIControlTransfer (
// detail status is returned
//
Status = ExecuteControlTransfer (
- HcDev,
- PtrSetupTD,
- LoadFrameListIndex,
- DataLength,
- TimeOut,
- TransferResult
- );
+ HcDev,
+ PtrSetupTD,
+ LoadFrameListIndex,
+ DataLength,
+ TimeOut,
+ TransferResult
+ );
//
// Remove Control Transfer QH-TDs structure from the frame list
// and update the pointers in the Frame List
@@ -2354,13 +2581,13 @@ UHCIBulkTransfer (
// BusMasterWrite means cpu read
//
Status = HcDev->PciIo->Map (
- HcDev->PciIo,
- EfiPciIoOperationBusMasterWrite,
- PtrDataSource,
- &DataLen,
- &TempPtr,
- &Mapping
- );
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterWrite,
+ PtrDataSource,
+ &DataLen,
+ &TempPtr,
+ &Mapping
+ );
if (EFI_ERROR (Status)) {
return Status;
}
@@ -2377,13 +2604,13 @@ UHCIBulkTransfer (
// BusMasterRead means cpu write
//
Status = HcDev->PciIo->Map (
- HcDev->PciIo,
- EfiPciIoOperationBusMasterRead,
- PtrDataSource,
- &DataLen,
- &TempPtr,
- &Mapping
- );
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ PtrDataSource,
+ &DataLen,
+ &TempPtr,
+ &Mapping
+ );
if (EFI_ERROR (Status)) {
return Status;
}
@@ -2422,16 +2649,16 @@ UHCIBulkTransfer (
}
Status = GenDataTD (
- HcDev,
- DeviceAddress,
- EndPointAddress,
- Ptr,
- PktSize,
- PktID,
- *DataToggle,
- FALSE,
- &PtrTD
- );
+ HcDev,
+ DeviceAddress,
+ EndPointAddress,
+ Ptr,
+ PktSize,
+ PktID,
+ *DataToggle,
+ FALSE,
+ &PtrTD
+ );
if (EFI_ERROR (Status)) {
HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);
@@ -2526,14 +2753,14 @@ UHCIBulkTransfer (
// of the last successful TD
//
Status = ExecBulkorSyncInterruptTransfer (
- HcDev,
- PtrFirstTD,
- LoadFrameListIndex,
- DataLength,
- DataToggle,
- TimeOut,
- TransferResult
- );
+ HcDev,
+ PtrFirstTD,
+ LoadFrameListIndex,
+ DataLength,
+ DataToggle,
+ TimeOut,
+ TransferResult
+ );
//
// Delete Bulk transfer QH-TD structure
@@ -2587,7 +2814,7 @@ UHCIAsyncInterruptTransfer (
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
IN BOOLEAN IsSlowDevice,
- IN UINT8 MaxiumPacketLength,
+ IN UINT8 MaximumPacketLength,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle,
IN UINTN PollingInterval, OPTIONAL
@@ -2618,7 +2845,7 @@ UHCIAsyncInterruptTransfer (
IsSlowDevice Indicates whether the target device is slow device
or full-speed device.
- MaxiumPacketLength Indicates the maximum packet size the target endpoint
+ MaximumPacketLength Indicates the maximum packet size the target endpoint
is capable of sending or receiving.
IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between
@@ -2715,11 +2942,11 @@ UHCIAsyncInterruptTransfer (
OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
Status = DeleteAsyncINTQHTDs (
- HcDev,
- DeviceAddress,
- EndPointAddress,
- DataToggle
- );
+ HcDev,
+ DeviceAddress,
+ EndPointAddress,
+ DataToggle
+ );
gBS->RestoreTPL (OldTpl);
@@ -2764,13 +2991,13 @@ UHCIAsyncInterruptTransfer (
// BusMasterWrite means cpu read
//
Status = HcDev->PciIo->Map (
- HcDev->PciIo,
- EfiPciIoOperationBusMasterWrite,
- Ptr,
- &DataLen,
- &TempPtr,
- &Mapping
- );
+ HcDev->PciIo,
+ EfiPciIoOperationBusMasterWrite,
+ Ptr,
+ &DataLen,
+ &TempPtr,
+ &Mapping
+ );
if (EFI_ERROR (Status)) {
gBS->FreePool (Ptr);
return Status;
@@ -2788,21 +3015,21 @@ UHCIAsyncInterruptTransfer (
//
PktSize = (UINT8) DataLen;
- if (DataLen > MaxiumPacketLength) {
- PktSize = MaxiumPacketLength;
+ if (DataLen > MaximumPacketLength) {
+ PktSize = MaximumPacketLength;
}
Status = GenDataTD (
- HcDev,
- DeviceAddress,
- EndPointAddress,
- MappedPtr,
- PktSize,
- PktID,
- CurrentDataToggle,
- IsSlowDevice,
- &PtrTD
- );
+ HcDev,
+ DeviceAddress,
+ EndPointAddress,
+ MappedPtr,
+ PktSize,
+ PktID,
+ CurrentDataToggle,
+ IsSlowDevice,
+ &PtrTD
+ );
if (EFI_ERROR (Status)) {
gBS->FreePool (Ptr);
HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);
@@ -3084,6 +3311,10 @@ UHCISyncInterruptTransfer (
return EFI_INVALID_PARAMETER;
}
+ if (TransferResult == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
ClearStatusReg (HcDev->PciIo, StatusReg);
//
@@ -3357,6 +3588,830 @@ UHCIAsyncIsochronousTransfer (
return EFI_UNSUPPORTED;
}
+//
+// UEFI 2.0 Protocol
+//
+EFI_STATUS
+EFIAPI
+UHCI2GetCapability(
+ IN EFI_USB2_HC_PROTOCOL * This,
+ OUT UINT8 *MaxSpeed,
+ OUT UINT8 *PortNumber,
+ OUT UINT8 *Is64BitCapable
+ )
+/*++
+
+ Routine Description:
+ Retrieves capabilities of USB host controller according to UEFI 2.0 spec.
+
+ Arguments:
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
+
+ MaxSpeed - A pointer to the max speed USB host controller supports.
+
+ PortNumber - A pointer to the number of root hub ports.
+
+ Is64BitCapable - A pointer to an integer to show whether USB host controller
+ supports 64-bit memory addressing.
+ Returns:
+ EFI_SUCCESS
+ The host controller capabilities 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.
+
+--*/
+{
+ USB_HC_DEV *HcDev;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+
+ if ((NULL == MaxSpeed)
+ ||(NULL == PortNumber)
+ || (NULL == Is64BitCapable))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *MaxSpeed = EFI_USB_SPEED_FULL;
+ *Is64BitCapable = (UINT8)FALSE;
+ return UHCIGetRootHubPortNumber(&HcDev->UsbHc, PortNumber);
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2Reset (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT16 Attributes
+ )
+/*++
+
+ Routine Description:
+ Provides software reset for the USB host controller according to UEFI 2.0 spec.
+
+ 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.
+
+ Returns:
+ EFI_SUCCESS
+ The reset operation succeeded.
+ EFI_INVALID_PARAMETER
+ Attributes is not valid.
+ EFI_UNSUPPORTED
+ 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.
+ EFI_DEVICE_ERROR
+ An error was encountered while attempting to perform
+ the reset operation.
+--*/
+{
+ USB_HC_DEV *HcDev;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+
+ if (Attributes==EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG || Attributes==EFI_USB_HC_RESET_HOST_WITH_DEBUG)
+ return EFI_UNSUPPORTED;
+
+ return UHCIReset(
+ &HcDev->UsbHc,
+ Attributes
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2GetState (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ OUT EFI_USB_HC_STATE * State
+ )
+/*++
+
+ Routine Description:
+ Retrieves current state of the USB host controller according to UEFI 2.0 spec.
+
+ 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;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+ return UHCIGetState(
+ &HcDev->UsbHc,
+ State
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2SetState (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN EFI_USB_HC_STATE State
+ )
+/*++
+
+ Routine Description:
+ Sets the USB host controller to a specific state according to UEFI 2.0 spec.
+
+ 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;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+ return UHCISetState(
+ &HcDev->UsbHc,
+ State
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2ControlTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN EFI_USB_DEVICE_REQUEST * Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+ Submits control transfer to a target USB device accroding to UEFI 2.0 spec..
+
+ Arguments:
+
+ This - A pointer to the EFI_USB_HC_PROTOCOL instance.
+
+ DeviceAddress -Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+
+ DeviceSpeed - Indicates transfer speed of device.
+
+ MaximumPacketLength - Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+
+ Request - A pointer to the USB device request that will be sent
+ to the USB device.
+
+ TransferDirection - Specifies the data direction for the transfer.
+ There are three values available, DataIn, DataOut
+ and NoData.
+
+ Data -A pointer to the buffer of data that will be transmitted
+ to USB device or received from USB device.
+
+ DataLength - Indicates the size, in bytes, of the data buffer
+ specified by Data.
+
+ TimeOut - Indicates the maximum time, in microseconds,
+ which the transfer is allowed to complete.
+
+ TransferResult - A pointer to the detailed result information generated
+ by this control transfer.
+
+ Returns:
+ EFI_SUCCESS
+ The control transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The control transfer could not be completed due to a lack of resources.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The control transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The control transfer failed due to host controller or device error.
+ Caller should check TranferResult for detailed error information.
+
+--*/
+{
+ USB_HC_DEV *HcDev;
+ BOOLEAN IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+
+ return UHCIControlTransfer(
+ &HcDev->UsbHc,
+ DeviceAddress,
+ IsSlowDevice,
+ (UINT8) MaximumPacketLength,
+ Request,
+ TransferDirection,
+ Data,
+ DataLength,
+ TimeOut,
+ TransferResult
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2BulkTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+ Submits bulk transfer to a bulk endpoint of a USB device according to UEFI 2.0 spec.
+
+ Arguments:
+
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+
+ DeviceAddress Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+
+ EndPointAddress The combination of an endpoint number and an
+ endpoint direction of the target USB device.
+ Each endpoint address supports data transfer in
+ one direction except the control endpoint
+ (whose default endpoint address is 0).
+ It is the caller's responsibility to make sure that
+ the EndPointAddress represents a bulk endpoint.
+
+ DeviceSpeed Indicates device speed. The supported values are EFI_USB_SPEED_FULL
+ and EFI_USB_SPEED_HIGH.
+
+ MaximumPacketLength Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+
+ DataBuffersNumber Number of data buffers prepared for the transfer.
+
+ Data Array of pointers to the buffers of data that will be transmitted
+ to USB device or received from USB device.
+
+ DataLength When input, indicates the size, in bytes, of the data buffer
+ specified by Data. When output, indicates the actually
+ transferred data size.
+
+ DataToggle A pointer to the data toggle value. On input, it indicates
+ the initial data toggle value the bulk transfer should adopt;
+ on output, it is updated to indicate the data toggle value
+ of the subsequent bulk transfer.
+
+ Translator A pointr to the transaction translator data.
+
+ TimeOut Indicates the maximum time, in microseconds, which the
+ transfer is allowed to complete.
+
+ TransferResult A pointer to the detailed result information of the
+ bulk transfer.
+
+ Returns:
+ EFI_SUCCESS
+ The bulk transfer was completed successfully.
+
+ EFI_OUT_OF_RESOURCES
+ The bulk transfer could not be submitted due to lack of resource.
+
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+
+ EFI_TIMEOUT
+ The bulk transfer failed due to timeout.
+
+ EFI_DEVICE_ERROR
+ The bulk transfer failed due to host controller or device error.
+ Caller should check TranferResult for detailed error information.
+
+--*/
+{
+ USB_HC_DEV *HcDev;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+
+ if( Data == NULL || DeviceSpeed==EFI_USB_SPEED_LOW)
+ return EFI_INVALID_PARAMETER;
+ /* For full-speed bulk transfers only the data pointed by Data[0] shall be used */
+
+ return UHCIBulkTransfer (
+ &HcDev->UsbHc,
+ DeviceAddress,
+ EndPointAddress,
+ (UINT8) MaximumPacketLength,
+ *Data,
+ DataLength,
+ DataToggle,
+ TimeOut,
+ TransferResult
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2AsyncInterruptTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN BOOLEAN IsNewTransfer,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN PollingInterval,
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
+ IN VOID *Context
+ )
+/*++
+
+ Routine Description:
+ Submits an asynchronous interrupt transfer to an
+ interrupt endpoint of a USB device according to UEFI 2.0 spec.
+
+ Arguments:
+
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+
+ DeviceAddress Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+
+ EndPointAddress The combination of an endpoint number and an endpoint
+ direction of the target USB device. Each endpoint address
+ supports data transfer in one direction except the
+ control endpoint (whose default endpoint address is 0).
+ It is the caller's responsibility to make sure that
+ the EndPointAddress represents an interrupt endpoint.
+
+ DeviceSpeed Indicates device speed.
+
+ MaximumPacketLength Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+
+ IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between
+ the host and the target interrupt endpoint.
+ If FALSE, the specified asynchronous interrupt pipe
+ is canceled.
+
+ DataToggle A pointer to the data toggle value. On input, it is valid
+ when IsNewTransfer is TRUE, and it indicates the initial
+ data toggle value the asynchronous interrupt transfer
+ should adopt.
+ On output, it is valid when IsNewTransfer is FALSE,
+ and it is updated to indicate the data toggle value of
+ the subsequent asynchronous interrupt transfer.
+
+ PollingInterval Indicates the interval, in milliseconds, that the
+ asynchronous interrupt transfer is polled.
+ This parameter is required when IsNewTransfer is TRUE.
+
+ DataLength Indicates the length of data to be received at the
+ rate specified by PollingInterval from the target
+ asynchronous interrupt endpoint. This parameter
+ is only required when IsNewTransfer is TRUE.
+
+ Translator A pointr to the transaction translator data.
+
+ CallBackFunction The Callback function.This function is called at the
+ rate specified by PollingInterval.This parameter is
+ only required when IsNewTransfer is TRUE.
+
+ Context The context that is passed to the CallBackFunction.
+ This is an optional parameter and may be NULL.
+
+ Returns:
+
+ EFI_SUCCESS
+ The asynchronous interrupt transfer request has been successfully
+ submitted or canceled.
+
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+
+ EFI_OUT_OF_RESOURCES
+ The request could not be completed due to a lack of resources.
+
+ EFI_DEVICE_ERROR
+ Can't read register
+--*/
+{
+ USB_HC_DEV *HcDev;
+ BOOLEAN IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+ return UHCIAsyncInterruptTransfer(
+ &HcDev->UsbHc,
+ DeviceAddress,
+ EndPointAddress,
+ IsSlowDevice,
+ (UINT8) MaximumPacketLength,
+ IsNewTransfer,
+ DataToggle,
+ PollingInterval,
+ DataLength,
+ CallBackFunction,
+ Context
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2SyncInterruptTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+ Submits synchronous interrupt transfer to an interrupt endpoint
+ of a USB device according to UEFI 2.0 spec.
+
+ Arguments:
+
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+
+ DeviceAddress Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+
+ EndPointAddress The combination of an endpoint number and an endpoint
+ direction of the target USB device. Each endpoint
+ address supports data transfer in one direction
+ except the control endpoint (whose default
+ endpoint address is 0). It is the caller's responsibility
+ to make sure that the EndPointAddress represents
+ an interrupt endpoint.
+
+ DeviceSpeed Indicates device speed.
+
+ MaximumPacketLength Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+
+ Data A pointer to the buffer of data that will be transmitted
+ to USB device or received from USB device.
+
+ DataLength On input, the size, in bytes, of the data buffer specified
+ by Data. On output, the number of bytes transferred.
+
+ DataToggle A pointer to the data toggle value. On input, it indicates
+ the initial data toggle value the synchronous interrupt
+ transfer should adopt;
+ on output, it is updated to indicate the data toggle value
+ of the subsequent synchronous interrupt transfer.
+
+ TimeOut Indicates the maximum time, in microseconds, which the
+ transfer is allowed to complete.
+ Translator A pointr to the transaction translator data.
+ TransferResult A pointer to the detailed result information from
+ the synchronous interrupt transfer.
+
+ Returns:
+ EFI_SUCCESS
+ The synchronous interrupt transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The synchronous interrupt transfer could not be submitted due
+ to lack of resource.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The synchronous interrupt transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The synchronous interrupt transfer failed due to host controller
+ or device error. Caller should check TranferResult for detailed
+ error information.
+--*/
+{
+ USB_HC_DEV *HcDev;
+ BOOLEAN IsSlowDevice;
+
+ if(DeviceSpeed==EFI_USB_SPEED_HIGH)
+ return EFI_INVALID_PARAMETER;
+
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+
+ return UHCISyncInterruptTransfer(
+ &HcDev->UsbHc,
+ DeviceAddress,
+ EndPointAddress,
+ IsSlowDevice,
+ (UINT8) MaximumPacketLength,
+ Data,
+ DataLength,
+ DataToggle,
+ TimeOut,
+ TransferResult
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2IsochronousTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.
+
+ Arguments:
+
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+
+ DeviceAddress Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+
+ EndPointAddress End point address
+
+ DeviceSpeed Indicates device speed.
+
+ MaximumPacketLength Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+
+ DataBuffersNumber Number of data buffers prepared for the transfer.
+
+ Data Array of pointers to the buffers of data that will be
+ transmitted to USB device or received from USB device.
+
+ DataLength Indicates the size, in bytes, of the data buffer
+ specified by Data.
+
+ Translator A pointr to the transaction translator data.
+
+ TransferResult A pointer to the detailed result information generated
+ by this control transfer.
+ Returns:
+
+ EFI_UNSUPPORTED
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2AsyncIsochronousTransfer (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
+ IN VOID *Context
+ )
+/*++
+
+ Routine Description:
+
+ Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.
+
+ Arguments:
+
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+
+ DeviceAddress Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+
+ EndPointAddress End point address
+
+ DeviceSpeed Indicates device speed.
+
+ MaximumPacketLength Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+
+ DataBuffersNumber Number of data buffers prepared for the transfer.
+
+ Data Array of pointers to the buffers of data that will be transmitted
+ to USB device or received from USB device.
+
+ Translator A pointr to the transaction translator data.
+
+ IsochronousCallBack When the transfer complete, the call back function will be called
+
+ Context Pass to the call back function as parameter
+
+ Returns:
+
+ EFI_UNSUPPORTED
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2GetRootHubPortStatus (
+ 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 according to UEFI 2.0 spec.
+
+ 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
+--*/
+{
+ USB_HC_DEV *HcDev;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+
+ return UHCIGetRootHubPortStatus(
+ &HcDev->UsbHc,
+ PortNumber,
+ PortStatus
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2SetRootHubPortFeature (
+ 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 according to UEFI 2.0 spec.
+
+ 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
+--*/
+{
+ USB_HC_DEV *HcDev;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+ return UHCISetRootHubPortFeature(
+ &HcDev->UsbHc,
+ PortNumber,
+ PortFeature
+ );
+}
+
+EFI_STATUS
+EFIAPI
+UHCI2ClearRootHubPortFeature (
+ IN EFI_USB2_HC_PROTOCOL * This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ )
+/*++
+
+ Routine Description:
+ Clears a feature for the specified root hub port according to Uefi 2.0 spec.
+
+ Arguments:
+
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+
+ PortNumber Specifies the root hub port whose feature
+ is requested to be cleared.
+
+ PortFeature Indicates the feature selector associated with the
+ feature clear request.
+
+ Returns:
+ EFI_SUCCESS
+ The feature specified by PortFeature was cleared 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
+--*/
+{
+ USB_HC_DEV *HcDev;
+
+ HcDev = USB2_HC_DEV_FROM_THIS (This);
+ return UHCIClearRootHubPortFeature(
+ &HcDev->UsbHc,
+ PortNumber,
+ PortFeature
+ );
+}
+
VOID
EFIAPI
MonitorInterruptTrans (
diff --git a/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.h b/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.h
index d6f841bf40..c5ae155f90 100644
--- a/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.h
+++ b/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhci.h
@@ -28,7 +28,7 @@ Revision History
#include <IndustryStandard/pci22.h>
-#define EFI_D_UHCI EFI_D_INFO
+#define EFI_D_UHCI EFI_D_INFO
//
// stall time
@@ -45,21 +45,20 @@ Revision History
//
// 50 ms
//
-#define INTERRUPT_POLLING_TIME 50 * 1000 * 10
+#define INTERRUPT_POLLING_TIME 50 * 1000 * 10
//
// UHCI IO Space Address Register Register locates at
// offset 20 ~ 23h of PCI Configuration Space (UHCI spec, Revision 1.1),
// so, its BAR Index is 4.
//
-#define USB_BAR_INDEX 4
+#define USB_BAR_INDEX 4
//
// One memory block uses 1 page (common buffer for QH,TD use.)
//
#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 1
-
#define bit(a) 1 << (a)
//
@@ -82,13 +81,13 @@ extern UINT16 USBBaseAddr;
#define USBCMD_MAXP bit (7) /* Max Packet (0 = 32, 1 = 64) */
/* Status register */
-#define USBSTS 2 /* Status Register Offset 02-03h */
-#define USBSTS_USBINT bit (0) /* Interrupt due to IOC */
-#define USBSTS_ERROR bit (1) /* Interrupt due to error */
-#define USBSTS_RD bit (2) /* Resume Detect */
-#define USBSTS_HSE bit (3) /* Host System Error*/
-#define USBSTS_HCPE bit (4) /* Host Controller Process Error*/
-#define USBSTS_HCH bit (5) /* HC Halted */
+#define USBSTS 2 /* Status Register Offset 02-03h */
+#define USBSTS_USBINT bit (0) /* Interrupt due to IOC */
+#define USBSTS_ERROR bit (1) /* Interrupt due to error */
+#define USBSTS_RD bit (2) /* Resume Detect */
+#define USBSTS_HSE bit (3) /* Host System Error*/
+#define USBSTS_HCPE bit (4) /* Host Controller Process Error*/
+#define USBSTS_HCH bit (5) /* HC Halted */
/* Interrupt enable register */
#define USBINTR 4 /* Interrupt Enable Register 04-05h */
@@ -98,13 +97,13 @@ extern UINT16 USBBaseAddr;
#define USBINTR_SP bit (3) /* Short packet interrupt enable */
/* Frame Number Register Offset 06-08h */
-#define USBFRNUM 6
+#define USBFRNUM 6
/* Frame List Base Address Register Offset 08-0Bh */
-#define USBFLBASEADD 8
+#define USBFLBASEADD 8
/* Start of Frame Modify Register Offset 0Ch */
-#define USBSOF 0x0c
+#define USBSOF 0x0c
/* USB port status and control registers */
#define USBPORTSC1 0x10 /*Port 1 offset 10-11h */
@@ -126,16 +125,16 @@ extern UINT16 USBBaseAddr;
//
// Class Code Register offset
//
-#define CLASSC 0x09
+#define CLASSC 0x09
//
// USB IO Space Base Address Register offset
//
-#define USBBASE 0x20
+#define USBBASE 0x20
//
// USB legacy Support
//
-#define USB_EMULATION 0xc0
+#define USB_EMULATION 0xc0
//
// USB Base Class Code,Sub-Class Code and Programming Interface.
@@ -224,6 +223,7 @@ typedef struct {
//
//////////////////////////////////////////////////////////////////////////
#define USB_HC_DEV_FROM_THIS(a) CR (a, USB_HC_DEV, UsbHc, USB_HC_DEV_SIGNATURE)
+#define USB2_HC_DEV_FROM_THIS(a) CR (a, USB_HC_DEV, Usb2Hc, USB_HC_DEV_SIGNATURE)
#define USB_HC_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'h', 'c', 'i')
#define INTERRUPT_LIST_SIGNATURE EFI_SIGNATURE_32 ('i', 'n', 't', 's')
@@ -267,6 +267,7 @@ typedef struct _MEMORY_MANAGE_HEADER {
typedef struct {
UINTN Signature;
EFI_USB_HC_PROTOCOL UsbHc;
+ EFI_USB2_HC_PROTOCOL Usb2Hc;
EFI_PCI_IO_PROTOCOL *PciIo;
//
@@ -289,196 +290,683 @@ WriteUHCCommandReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 CmdAddrOffset,
IN UINT16 UsbCmd
- );
+ )
+/*++
+
+Routine Description:
+
+ Write UHCI Command Register
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ CmdAddrOffset - Command address offset
+ UsbCmd - Data to write
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
EFI_STATUS
ReadUHCCommandReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 CmdAddrOffset,
IN OUT UINT16 *Data
- );
+ )
+/*++
+
+Routine Description:
+
+ Read UHCI Command Register
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ CmdAddrOffset - Command address offset
+ Data - Data to return
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
EFI_STATUS
WriteUHCStatusReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 StatusAddrOffset,
IN UINT16 UsbSts
- );
+ )
+/*++
+
+Routine Description:
+
+ Write UHCI Staus Register
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ StatusAddrOffset - Status address offset
+ UsbSts - Data to write
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
EFI_STATUS
ReadUHCStatusReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 StatusAddrOffset,
IN OUT UINT16 *Data
- );
+ )
+/*++
+
+Routine Description:
+
+ Read UHCI Staus Register
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ StatusAddrOffset - Status address offset
+ UsbSts - Data to return
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
EFI_STATUS
ClearStatusReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 StatusAddrOffset
- );
+ )
+/*++
+
+Routine Description:
+
+ Clear the content of UHC's Status Register
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ StatusAddrOffset - Status address offset
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
EFI_STATUS
ReadUHCFrameNumberReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 FrameNumAddrOffset,
IN OUT UINT16 *Data
- );
+ )
+/*++
+
+Routine Description:
+
+ Read from UHC's Frame Number Register
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ FrameNumAddrOffset - Frame number register offset
+ Data - Data to return
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
EFI_STATUS
WriteUHCFrameListBaseReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 FlBaseAddrOffset,
IN UINT32 UsbFrameListBaseAddr
- );
+ )
+/*++
+
+Routine Description:
+
+ Write to UHC's Frame List Base Register
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ FlBaseAddrOffset - Frame Base address register
+ UsbFrameListBaseAddr - Address to write
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
EFI_STATUS
ReadRootPortReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 PortAddrOffset,
IN OUT UINT16 *Data
- );
+ )
+/*++
+
+Routine Description:
+
+ Read from UHC's Root Port Register
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ PortAddrOffset - Port Addrress Offset,
+ Data - Data to return
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
EFI_STATUS
WriteRootPortReg (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 PortAddrOffset,
IN UINT16 ControlBits
- );
+ )
+/*++
+
+Routine Description:
+
+ Write to UHC's Root Port Register
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ PortAddrOffset - Port Addrress Offset,
+ ControlBits - Data to write
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
EFI_STATUS
WaitForUHCHalt (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 StatusRegAddr,
IN UINTN Timeout
- );
+ )
+/*++
+
+Routine Description:
+
+ Wait until UHCI halt or timeout
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ StatusRegAddr - Status Register Address
+ Timeout - Time out value in us
+
+Returns:
+
+ EFI_DEVICE_ERROR - Unable to read the status register
+ EFI_TIMEOUT - Time out
+ EFI_SUCCESS - Success
+
+--*/
+;
BOOLEAN
IsStatusOK (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 StatusRegAddr
- );
+ )
+/*++
+
+Routine Description:
+
+ Judge whether the host controller operates well
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ StatusRegAddr - Status register address
+
+Returns:
+
+ TRUE - Status is good
+ FALSE - Status is bad
+
+--*/
+;
BOOLEAN
IsHostSysOrProcessErr (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 StatusRegAddr
- );
+ )
+/*++
-//
-// This routine programs the USB frame number register. We assume that the
-// HC schedule execution is stopped.
-//
-EFI_STATUS
-SetFrameNumberReg (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 FRNUMAddr,
- IN UINT16 Index
- );
+Routine Description:
+
+ Judge the status is HostSys,ProcessErr error or good
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ StatusRegAddr - Status register address
+
+Returns:
+
+ TRUE - Status is good
+ FALSE - Status is bad
+
+--*/
+;
UINT16
GetCurrentFrameNumber (
IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 FRNUMAddr
- );
+ IN UINT32 FrameNumAddrOffset
+ )
+/*++
+
+Routine Description:
+
+ Get Current Frame Number
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ FrameNumAddrOffset - FrameNum register AddrOffset
+
+Returns:
+
+ Frame number
+
+--*/
+;
EFI_STATUS
SetFrameListBaseAddress (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 FLBASEADDRReg,
IN UINT32 Addr
- );
+ )
+/*++
+
+Routine Description:
+
+ Set FrameListBase Address
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ FlBaseAddrReg - FrameListBase register
+ Addr - Address to set
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
UINT32
GetFrameListBaseAddress (
IN EFI_PCI_IO_PROTOCOL *PciIo,
IN UINT32 FLBAddr
- );
+ )
+/*++
+
+Routine Description:
+
+ Get Current Frame Number
+
+Arguments:
+
+ PciIo - EFI_PCI_IO_PROTOCOL
+ FrameNumAddrOffset - FrameNum register AddrOffset
+
+Returns:
+
+ Frame number
+
+--*/
+;
EFI_STATUS
CreateFrameList (
IN USB_HC_DEV *HcDev,
IN UINT32 FLBASEADDRReg
- );
+ )
+/*++
+
+Routine Description:
+
+ CreateFrameList
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+ FlBaseAddrReg - Frame List register
+
+Returns:
+
+ EFI_OUT_OF_RESOURCES - Can't allocate memory resources
+ EFI_UNSUPPORTED - Map memory fail
+ EFI_SUCCESS - Success
+
+--*/
+;
EFI_STATUS
FreeFrameListEntry (
IN USB_HC_DEV *UhcDev
- );
+ )
+/*++
+
+Routine Description:
+
+ Free FrameList buffer
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS - success
+
+--*/
+;
VOID
InitFrameList (
IN USB_HC_DEV *HcDev
- );
+ )
+/*++
+
+Routine Description:
+
+ Initialize FrameList
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+Returns:
+ VOID
+
+--*/
+;
EFI_STATUS
CreateQH (
IN USB_HC_DEV *HcDev,
OUT QH_STRUCT **pptrQH
- );
+ )
+/*++
+
+Routine Description:
+
+ CreateQH
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+ pptrQH - QH_STRUCT content to return
+Returns:
+
+ EFI_SUCCESS - Success
+ EFI_OUT_OF_RESOURCES - Can't allocate memory
+
+--*/
+;
VOID
SetQHHorizontalLinkPtr (
IN QH_STRUCT *ptrQH,
IN VOID *ptrNext
- );
+ )
+/*++
+
+Routine Description:
+
+ Set QH Horizontal Link Pointer
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+ ptrNext - Data to write
-VOID *
+Returns:
+
+ VOID
+
+--*/
+;
+
+VOID *
GetQHHorizontalLinkPtr (
IN QH_STRUCT *ptrQH
- );
+ )
+/*++
+
+Routine Description:
+
+ Get QH Horizontal Link Pointer
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+
+
+Returns:
+
+ Data to return
+
+--*/
+;
VOID
SetQHHorizontalQHorTDSelect (
IN QH_STRUCT *ptrQH,
IN BOOLEAN bQH
- );
+ )
+/*++
+
+Routine Description:
+
+ Set QH Horizontal QH or TD
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+ bQH - TRUE is QH FALSE is TD
+
+Returns:
+ VOID
+
+--*/
+;
VOID
SetQHHorizontalValidorInvalid (
IN QH_STRUCT *ptrQH,
IN BOOLEAN bValid
- );
+ )
+/*++
+
+Routine Description:
+
+ Set QH Horizontal Valid or Invalid
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+ bValid - TRUE is Valid FALSE is Invalid
+
+Returns:
+ VOID
+
+--*/
+;
VOID
SetQHVerticalLinkPtr (
IN QH_STRUCT *ptrQH,
IN VOID *ptrNext
- );
+ )
+/*++
+
+Routine Description:
-VOID *
+ Set QH Vertical Link Pointer
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+ ptrNext - Data to write
+Returns:
+
+ VOID
+
+--*/
+;
+
+VOID *
GetQHVerticalLinkPtr (
IN QH_STRUCT *ptrQH
- );
+ )
+/*++
+
+Routine Description:
+
+ Get QH Vertical Link Pointer
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+
+Returns:
+
+ Data to return
+
+--*/
+;
VOID
SetQHVerticalQHorTDSelect (
IN QH_STRUCT *ptrQH,
IN BOOLEAN bQH
- );
+ )
+/*++
+
+Routine Description:
+
+ Set QH Vertical QH or TD
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+ bQH - TRUE is QH FALSE is TD
+
+Returns:
+
+ VOID
+
+--*/
+;
BOOLEAN
IsQHHorizontalQHSelect (
IN QH_STRUCT *ptrQH
- );
+ )
+/*++
+
+Routine Description:
+
+ Is QH Horizontal QH Select
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+
+Returns:
+
+ TRUE - QH
+ FALSE - TD
+
+--*/
+;
VOID
SetQHVerticalValidorInvalid (
IN QH_STRUCT *ptrQH,
IN BOOLEAN bValid
- );
+ )
+/*++
+
+Routine Description:
+
+ Set QH Vertical Valid or Invalid
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+ IsValid - TRUE is valid FALSE is invalid
+
+Returns:
+
+ VOID
+
+--*/
+;
BOOLEAN
GetQHVerticalValidorInvalid (
IN QH_STRUCT *ptrQH
- );
+ )
+/*++
+
+Routine Description:
+
+ Get QH Vertical Valid or Invalid
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+
+Returns:
+
+ TRUE - Valid
+ FALSE - Invalid
+
+--*/
+;
EFI_STATUS
AllocateTDStruct (
IN USB_HC_DEV *HcDev,
OUT TD_STRUCT **ppTDStruct
- );
+ )
/*++
Routine Description:
@@ -494,12 +982,13 @@ Returns:
EFI_SUCCESS
--*/
+;
EFI_STATUS
CreateTD (
IN USB_HC_DEV *HcDev,
OUT TD_STRUCT **pptrTD
- );
+ )
/*++
Routine Description:
@@ -517,6 +1006,7 @@ Returns:
EFI_SUCCESS - Success
--*/
+;
EFI_STATUS
@@ -528,7 +1018,7 @@ GenSetupStageTD (
IN UINT8 *pDevReq,
IN UINT8 RequestLen,
OUT TD_STRUCT **ppTD
- );
+ )
/*++
Routine Description:
@@ -550,6 +1040,7 @@ Returns:
EFI_SUCCESS - Success
--*/
+;
EFI_STATUS
GenDataTD (
@@ -562,7 +1053,7 @@ GenDataTD (
IN UINT8 Toggle,
IN BOOLEAN bSlow,
OUT TD_STRUCT **ppTD
- );
+ )
/*++
Routine Description:
@@ -586,6 +1077,7 @@ Returns:
EFI_SUCCESS - Success
--*/
+;
EFI_STATUS
CreateStatusTD (
@@ -595,7 +1087,7 @@ CreateStatusTD (
IN UINT8 PktID,
IN BOOLEAN bSlow,
OUT TD_STRUCT **ppTD
- );
+ )
/*++
Routine Description:
@@ -617,237 +1109,918 @@ Returns:
EFI_SUCCESS - Success
--*/
+;
VOID
SetTDLinkPtrValidorInvalid (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bValid
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD Link Pointer Valid or Invalid
+
+Arguments:
+
+ ptrTDStruct - TD_STRUCT
+ bValid - TRUE is valid FALSE is invalid
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDLinkPtrQHorTDSelect (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bQH
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD Link Pointer QH or TD Select
+
+Arguments:
+
+ ptrTDStruct - TD_STRUCT
+ bQH - TRUE is QH FALSE is TD
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDLinkPtrDepthorBreadth (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bDepth
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD Link Pointer depth or bread priority
+
+Arguments:
+
+ ptrTDStruct - TD_STRUCT
+ bDepth - TRUE is Depth FALSE is Breadth
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDLinkPtr (
IN TD_STRUCT *ptrTDStruct,
IN VOID *ptrNext
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD Link Pointer
+
+Arguments:
-VOID *
+ ptrTDStruct - TD_STRUCT
+ ptrNext - Pointer to set
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+VOID *
GetTDLinkPtr (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Get TD Link Pointer
+
+Arguments:
+
+ ptrTDStruct - TD_STRUCT
+
+Returns:
+
+ Pointer to get
+
+--*/
+;
VOID
EnableorDisableTDShortPacket (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bEnable
- );
+ )
+/*++
+
+Routine Description:
+
+ Enable or Disable TD ShortPacket
+
+Arguments:
+
+ ptrTDStruct - TD_STRUCT
+ bEnable - TRUE is Enanble FALSE is Disable
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDControlErrorCounter (
IN TD_STRUCT *ptrTDStruct,
IN UINT8 nMaxErrors
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD Control ErrorCounter
+
+Arguments:
+
+ ptrTDStruct - TD_STRUCT
+ nMaxErrors - Error counter number
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDLoworFullSpeedDevice (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bLowSpeedDevice
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD status low speed or full speed
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+ bLowSpeedDevice - Show low speed or full speed
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDControlIsochronousorNot (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bIsochronous
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD status Isochronous or not
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+ IsIsochronous - Show Isochronous or not
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetorClearTDControlIOC (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bSet
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD status IOC IsSet
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+ IsSet - Show IOC set or not
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDStatusActiveorInactive (
IN TD_STRUCT *ptrTDStruct,
IN BOOLEAN bActive
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD status active or not
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+ IsActive - Active or not
+
+Returns:
+
+ VOID
+
+--*/
+;
UINT16
SetTDTokenMaxLength (
IN TD_STRUCT *ptrTDStruct,
IN UINT16 nMaxLen
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD Token maxlength
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+ MaximumLength - Maximum length of TD Token
+
+Returns:
+
+ Real maximum length set to TD Token
+
+--*/
+;
VOID
SetTDTokenDataToggle1 (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD Token data toggle1
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDTokenDataToggle0 (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD Token data toggle0
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ VOID
+
+--*/
+;
UINT8
GetTDTokenDataToggle (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Get TD Token data toggle
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ data toggle value
+
+--*/
+;
VOID
SetTDTokenEndPoint (
IN TD_STRUCT *ptrTDStruct,
IN UINTN nEndPoint
- );
+ )
+/*++
+
+Routine Description:
+
+ Set Data Token endpoint number
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+ EndPoint - End point number
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDTokenDeviceAddress (
IN TD_STRUCT *ptrTDStruct,
IN UINTN nDevAddr
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD Token device address
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+ DeviceAddress - Device address
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDTokenPacketID (
IN TD_STRUCT *ptrTDStruct,
IN UINT8 nPID
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD Token packet ID
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+ PID - Packet ID
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetTDDataBuffer (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Set TD data buffer
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ VOID
+
+--*/
+;
BOOLEAN
IsTDStatusActive (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Indicate whether TD status active or not
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ TRUE - Active
+ FALSE - Inactive
+
+--*/
+;
BOOLEAN
IsTDStatusStalled (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Indicate whether TD status stalled or not
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ TRUE - Stalled
+ FALSE - not stalled
+
+--*/
+;
BOOLEAN
IsTDStatusBufferError (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Indicate whether TD status buffer error or not
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ TRUE - Buffer error
+ FALSE - No error
+
+--*/
+;
BOOLEAN
IsTDStatusBabbleError (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Indicate whether TD status babble error or not
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ TRUE - Babble error
+ FALSE - No error
+
+--*/
+;
BOOLEAN
IsTDStatusNAKReceived (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Indicate whether TD status NAK received
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ TRUE - NAK received
+ FALSE - NAK not received
+
+--*/
+;
BOOLEAN
IsTDStatusCRCTimeOutError (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Indicate whether TD status CRC timeout error or not
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ TRUE - CRC timeout error
+ FALSE - CRC timeout no error
+
+--*/
+;
BOOLEAN
IsTDStatusBitStuffError (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Indicate whether TD status bit stuff error or not
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ TRUE - Bit stuff error
+ FALSE - Bit stuff no error
+
+--*/
+;
UINT16
GetTDStatusActualLength (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Get TD status length
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ Return Td status length
+
+--*/
+;
UINT16
GetTDTokenMaxLength (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Get TD Token maximum length
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ Return TD token maximum length
+
+--*/
+;
UINT8
GetTDTokenEndPoint (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Get TD Token endpoint number
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ Return TD Token endpoint number
+
+--*/
+;
UINT8
GetTDTokenDeviceAddress (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Get TD Token device address
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ Return TD Token device address
+
+--*/
+;
UINT8
GetTDTokenPacketID (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Get TD Token packet ID
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ Return TD Token packet ID
-UINT8 *
+--*/
+;
+
+UINT8 *
GetTDDataBuffer (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Get the point to TD data buffer
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ Return a point to TD data buffer
+
+--*/
+;
BOOLEAN
GetTDLinkPtrValidorInvalid (
IN TD_STRUCT *ptrTDStruct
- );
+ )
+/*++
+
+Routine Description:
+
+ Get TD LinkPtr valid or not
+
+Arguments:
+
+ ptrTDStruct - A point to TD_STRUCT
+
+Returns:
+
+ TRUE - Invalid
+ FALSE - Valid
+
+--*/
+;
UINTN
CountTDsNumber (
IN TD_STRUCT *ptrFirstTD
- );
+ )
+/*++
+
+Routine Description:
+
+ Get the number of TDs
+
+Arguments:
+
+ PtrFirstTD - A point to the first TD_STRUCT
+
+Returns:
+
+ Return the number of TDs
+
+--*/
+;
VOID
LinkTDToQH (
IN QH_STRUCT *ptrQH,
IN TD_STRUCT *ptrTD
- );
+ )
+/*++
+
+Routine Description:
+
+ Link TD To QH
+
+Arguments:
+
+ PtrQH - QH_STRUCT
+ PtrTD - TD_STRUCT
+Returns:
+
+ VOID
+
+--*/
+;
VOID
LinkTDToTD (
IN TD_STRUCT *ptrPreTD,
IN TD_STRUCT *ptrTD
- );
+ )
+/*++
+
+Routine Description:
+
+ Link TD To TD
+
+Arguments:
+
+ ptrPreTD - Previous TD_STRUCT to be linked
+ PtrTD - TD_STRUCT to link
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetorClearCurFrameListTerminate (
IN FRAMELIST_ENTRY *pCurEntry,
IN BOOLEAN bSet
- );
+ )
+/*++
+
+Routine Description:
+
+ Set or clear current framelist terminate
+
+Arguments:
+
+ pCurEntry - A point to FRAMELIST_ENTITY
+ IsSet - TRUE to empty the frame and indicate the Pointer field is valid
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
SetCurFrameListQHorTD (
IN FRAMELIST_ENTRY *pCurEntry,
IN BOOLEAN bQH
- );
+ )
+/*++
+
+Routine Description:
+
+ Set current framelist QH or TD
+
+Arguments:
+
+ pCurEntry - A point to FRAMELIST_ENTITY
+ IsQH - TRUE to set QH and FALSE to set TD
+
+Returns:
+
+ VOID
+
+--*/
+;
BOOLEAN
GetCurFrameListTerminate (
IN FRAMELIST_ENTRY *pCurEntry
- );
+ )
+/*++
+
+Routine Description:
+
+ Get current framelist terminate
+
+Arguments:
+
+ pCurEntry - A point to FRAMELIST_ENTITY
+
+Returns:
+
+ TRUE - Terminate
+ FALSE - Not terminate
+
+--*/
+;
VOID
SetCurFrameListPointer (
IN FRAMELIST_ENTRY *pCurEntry,
IN UINT8 *ptr
- );
+ )
+/*++
-VOID *
+Routine Description:
+
+ Set current framelist pointer
+
+Arguments:
+
+ pCurEntry - A point to FRAMELIST_ENTITY
+ ptr - A point to FrameListPtr point to
+
+Returns:
+
+ VOID
+
+--*/
+;
+
+VOID *
GetCurFrameListPointer (
IN FRAMELIST_ENTRY *pCurEntry
- );
+ )
+/*++
+
+Routine Description:
+
+ Get current framelist pointer
+
+Arguments:
+
+ pCurEntry - A point to FRAMELIST_ENTITY
+
+Returns:
+
+ A point FrameListPtr point to
+
+--*/
+;
VOID
LinkQHToFrameList (
IN FRAMELIST_ENTRY *pEntry,
IN UINT16 FrameListIndex,
IN QH_STRUCT *ptrQH
- );
+ )
/*++
Routine Description:
@@ -864,14 +2037,7 @@ Returns:
VOID
--*/
-VOID
-DeleteQHTDs (
- IN FRAMELIST_ENTRY *pEntry,
- IN QH_STRUCT *ptrQH,
- IN TD_STRUCT *ptrFirstTD,
- IN UINT16 FrameListIndex,
- IN BOOLEAN SearchOther
- );
+;
VOID
DelLinkSingleQH (
@@ -880,13 +2046,50 @@ DelLinkSingleQH (
IN UINT16 FrameListIndex,
IN BOOLEAN SearchOther,
IN BOOLEAN Delete
- );
+ )
+/*++
+
+Routine Description:
+
+ Unlink from frame list and delete single QH
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+ PtrQH - QH_STRUCT
+ FrameListIndex - Frame List Index
+ SearchOther - Search Other QH
+ Delete - TRUE is to delete the QH
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
DeleteQueuedTDs (
IN USB_HC_DEV *HcDev,
IN TD_STRUCT *ptrFirstTD
- );
+ )
+/*++
+
+Routine Description:
+
+ Delete Queued TDs
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+ PtrFirstTD - TD link list head
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
InsertQHTDToINTList (
@@ -902,10 +2105,12 @@ InsertQHTDToINTList (
IN UINT8 *DataBuffer,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
IN VOID *Context
- );
+ )
/*++
Routine Description:
+
Insert QH and TD To Interrupt List
+
Arguments:
HcDev - USB_HC_DEV
@@ -920,11 +2125,14 @@ Arguments:
DataBuffer - Data buffer
CallBackFunction- CallBackFunction after interrupt transfeer
Context - CallBackFunction Context passed as function parameter
+
Returns:
+
EFI_SUCCESS - Sucess
EFI_INVALID_PARAMETER - Paremeter is error
--*/
+;
EFI_STATUS
DeleteAsyncINTQHTDs (
@@ -932,11 +2140,12 @@ DeleteAsyncINTQHTDs (
IN UINT8 DeviceAddress,
IN UINT8 EndPointAddress,
OUT UINT8 *DataToggle
- );
+ )
/*++
Routine Description:
Delete Async INT QH and TDs
+
Arguments:
HcDev - USB_HC_DEV
@@ -945,10 +2154,13 @@ Arguments:
DataToggle - Data Toggle
Returns:
+
EFI_SUCCESS - Sucess
EFI_INVALID_PARAMETER - Paremeter is error
--*/
+;
+
BOOLEAN
CheckTDsResults (
IN TD_STRUCT *ptrTD,
@@ -956,7 +2168,7 @@ CheckTDsResults (
OUT UINT32 *Result,
OUT UINTN *ErrTDPos,
OUT UINTN *ActualTransferSize
- );
+ )
/*++
Routine Description:
@@ -977,6 +2189,8 @@ Returns:
FALSE - Fail
--*/
+;
+
VOID
ExecuteAsyncINTTDs (
IN USB_HC_DEV *HcDev,
@@ -984,7 +2198,7 @@ ExecuteAsyncINTTDs (
OUT UINT32 *Result,
OUT UINTN *ErrTDPos,
OUT UINTN *ActualLen
- ) ;
+ )
/*++
Routine Description:
@@ -1004,12 +2218,14 @@ Returns:
VOID
--*/
+;
+
VOID
UpdateAsyncINTQHTDs (
IN INTERRUPT_LIST *ptrList,
IN UINT32 Result,
IN UINT32 ErrTDPos
- );
+ )
/*++
Routine Description:
@@ -1027,16 +2243,19 @@ Returns:
VOID
--*/
+;
+
VOID
ReleaseInterruptList (
IN USB_HC_DEV *HcDev,
IN LIST_ENTRY *ListHead
- );
+ )
/*++
Routine Description:
Release Interrupt List
+
Arguments:
HcDev - USB_HC_DEV
@@ -1047,6 +2266,8 @@ Returns:
VOID
--*/
+;
+
EFI_STATUS
ExecuteControlTransfer (
IN USB_HC_DEV *HcDev,
@@ -1055,7 +2276,7 @@ ExecuteControlTransfer (
OUT UINTN *ActualLen,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
- );
+ )
/*++
Routine Description:
@@ -1077,6 +2298,8 @@ Returns:
--*/
+;
+
EFI_STATUS
ExecBulkorSyncInterruptTransfer (
IN USB_HC_DEV *HcDev,
@@ -1086,7 +2309,7 @@ ExecBulkorSyncInterruptTransfer (
OUT UINT8 *DataToggle,
IN UINTN TimeOut,
OUT UINT32 *TransferResult
- );
+ )
/*++
Routine Description:
@@ -1107,81 +2330,311 @@ Returns:
EFI_SUCCESS - Sucess
EFI_DEVICE_ERROR - Error
--*/
+;
EFI_STATUS
InitializeMemoryManagement (
IN USB_HC_DEV *HcDev
- );
+ )
+/*++
+
+Routine Description:
+
+ Initialize Memory Management
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS - Success
+
+--*/
+;
EFI_STATUS
CreateMemoryBlock (
IN USB_HC_DEV *HcDev,
IN MEMORY_MANAGE_HEADER **MemoryHeader,
IN UINTN MemoryBlockSizeInPages
- );
+ )
+/*++
+
+Routine Description:
+
+ Use PciIo->AllocateBuffer to allocate common buffer for the memory block,
+ and use PciIo->Map to map the common buffer for Bus Master Read/Write.
+
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+ MemoryHeader - MEMORY_MANAGE_HEADER to output
+ MemoryBlockSizeInPages - MemoryBlockSizeInPages
+
+Returns:
+
+ EFI_SUCCESS - Success
+ EFI_OUT_OF_RESOURCES - Out of resources
+ EFI_UNSUPPORTED - Unsupported
+
+--*/
+;
EFI_STATUS
FreeMemoryHeader (
IN USB_HC_DEV *HcDev,
IN MEMORY_MANAGE_HEADER *MemoryHeader
- );
+ )
+/*++
+
+Routine Description:
+
+ Free Memory Header
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+ MemoryHeader - MemoryHeader to be freed
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Parameter is error
+ EFI_SUCCESS - Success
+
+--*/
+;
EFI_STATUS
UhciAllocatePool (
IN USB_HC_DEV *UhcDev,
IN UINT8 **Pool,
IN UINTN AllocSize
- );
+ )
+/*++
+
+Routine Description:
+
+ Uhci Allocate Pool
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+ Pool - Place to store pointer to the memory buffer
+ AllocSize - Alloc Size
+
+Returns:
+
+ EFI_SUCCESS - Success
+
+--*/
+;
VOID
UhciFreePool (
IN USB_HC_DEV *HcDev,
IN UINT8 *Pool,
IN UINTN AllocSize
- );
+ )
+/*++
+
+Routine Description:
+
+ Uhci Free Pool
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+ Pool - Pool to free
+ AllocSize - Pool size
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
InsertMemoryHeaderToList (
IN MEMORY_MANAGE_HEADER *MemoryHeader,
IN MEMORY_MANAGE_HEADER *NewMemoryHeader
- );
+ )
+/*++
+
+Routine Description:
+
+ Insert Memory Header To List
+
+Arguments:
+
+ MemoryHeader - MEMORY_MANAGE_HEADER
+ NewMemoryHeader - MEMORY_MANAGE_HEADER
+
+Returns:
+
+ VOID
+
+--*/
+;
EFI_STATUS
AllocMemInMemoryBlock (
IN MEMORY_MANAGE_HEADER *MemoryHeader,
IN VOID **Pool,
IN UINTN NumberOfMemoryUnit
- );
+ )
+/*++
+
+Routine Description:
+
+ Alloc Memory In MemoryBlock
+
+Arguments:
+
+ MemoryHeader - MEMORY_MANAGE_HEADER
+ Pool - Place to store pointer to memory
+ NumberOfMemoryUnit - Number Of Memory Unit
+
+Returns:
+
+ EFI_NOT_FOUND - Can't find the free memory
+ EFI_SUCCESS - Success
+
+--*/
+;
BOOLEAN
IsMemoryBlockEmptied (
IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr
- );
+ )
+/*++
+
+/*++
+
+Routine Description:
+
+ Is Memory Block Emptied
+
+Arguments:
+
+ MemoryHeaderPtr - MEMORY_MANAGE_HEADER
+
+Returns:
+
+ TRUE - Empty
+ FALSE - Not Empty
+
+--*/
+;
VOID
DelinkMemoryBlock (
IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,
IN MEMORY_MANAGE_HEADER *FreeMemoryHeader
- );
+ )
+/*++
+
+Routine Description:
+
+ Delink Memory Block
+
+Arguments:
+
+ FirstMemoryHeader - MEMORY_MANAGE_HEADER
+ NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER
+
+Returns:
+
+ VOID
+
+--*/
+;
EFI_STATUS
DelMemoryManagement (
IN USB_HC_DEV *HcDev
- );
+ )
+/*++
+
+Routine Description:
+
+ Delete Memory Management
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+
+Returns:
+
+ EFI_SUCCESS - Success
+
+--*/
+;
VOID
EnableMaxPacketSize (
IN USB_HC_DEV *HcDev
- );
+ )
+/*++
+
+Routine Description:
+
+ Enable Max Packet Size
+
+Arguments:
+
+ HcDev - USB_HC_DEV
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
CleanUsbTransactions (
IN USB_HC_DEV *HcDev
- );
+ )
+/*++
+
+Routine Description:
+
+ Clean USB Transactions
+
+Arguments:
+
+ HcDev - A point to USB_HC_DEV
+
+Returns:
+
+ VOID
+
+--*/
+;
VOID
TurnOffUSBEmulation (
IN EFI_PCI_IO_PROTOCOL *PciIo
- );
+ )
+/*++
+
+Routine Description:
+
+ Set current framelist QH or TD
+
+Arguments:
+
+ pCurEntry - A point to FRAMELIST_ENTITY
+ IsQH - TRUE to set QH and FALSE to set TD
+
+Returns:
+
+ VOID
+
+--*/
+;
#endif
diff --git a/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c b/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c
index 0aa0507c2a..8cd6b8e6f6 100644
--- a/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c
+++ b/EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c
@@ -710,7 +710,7 @@ BotDataPhase (
BufferPtr = (UINT8 *) DataBuffer;
TransferredSize = 0;
MaxRetry = 10;
- PackageNum = 15;
+ PackageNum = 128;
//
// retrieve the the max packet length of the given endpoint
diff --git a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.msa b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.msa
index 54a79ecd9a..d7101dce0e 100644
--- a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.msa
+++ b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/UsbBus.msa
@@ -83,7 +83,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
<Protocol Usage="BY_START">
<ProtocolCName>gEfiUsbIoProtocolGuid</ProtocolCName>
</Protocol>
- <Protocol Usage="TO_START">
+ <Protocol Usage="SOMETIMES_CONSUMED">
+ <ProtocolCName>gEfiUsb2HcProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="SOMETIMES_CONSUMED">
<ProtocolCName>gEfiUsbHcProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="TO_START">
diff --git a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
index f4ac69e13f..1d1f44d638 100644
--- a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
+++ b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
@@ -23,10 +23,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "usbbus.h"
-//#ifdef EFI_DEBUG
-UINTN gUSBDebugLevel = EFI_D_ERROR;
+UINTN gUSBDebugLevel = EFI_D_INFO;
UINTN gUSBErrorLevel = EFI_D_ERROR;
-//#endif
+
//
// The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER
// structure in the UsbBusDriverControllerDriverStop(). Then we can
@@ -121,17 +120,52 @@ UsbDeviceConfiguration (
//
STATIC
VOID
-EFIAPI
-UsbEnumeration (
+RootHubEnumeration (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+STATIC
+VOID
+HubEnumeration (
IN EFI_EVENT Event,
IN VOID *Context
);
+STATIC
+EFI_STATUS
+UsbSetTransactionTranslator (
+ IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
+ IN UINT8 ParentPort,
+ IN OUT USB_IO_DEVICE *Device
+ );
+
+STATIC
+EFI_STATUS
+UsbUnsetTransactionTranslator (
+ USB_IO_DEVICE *Device
+ );
+
+STATIC
+EFI_STATUS
+IdentifyDeviceSpeed (
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ USB_IO_DEVICE *NewDevice,
+ UINT8 Index
+ );
+
+STATIC
+EFI_STATUS
+ReleasePortToCHC (
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ UINT8 PortNum
+ );
+
EFI_STATUS
ResetRootPort (
- IN EFI_USB_HC_PROTOCOL *UsbHCInterface,
- IN UINT8 PortNum,
- IN UINT8 RetryTimes
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 PortNum,
+ IN UINT8 RetryTimes
);
EFI_STATUS
@@ -140,12 +174,6 @@ ResetHubPort (
IN UINT8 PortIndex
);
-EFI_STATUS
-ClearRootPortConnectionChangeStatus (
- IN UINT8 PortNum,
- IN EFI_USB_HC_PROTOCOL *UsbHCInterface
- );
-
STATIC
EFI_STATUS
ParentPortReset (
@@ -162,6 +190,18 @@ UINT8
UsbAllocateAddress (
IN UINT8 *AddressPool
)
+/*++
+
+ Routine Description:
+ Allocate address for usb device
+
+ Arguments:
+ AddressPool - Pool of usb device address
+
+ Returns:
+ Usb device address
+
+--*/
{
UINT8 ByteIndex;
UINT8 BitIndex;
@@ -188,6 +228,19 @@ UsbFreeAddress (
IN UINT8 DevAddress,
IN UINT8 *AddressPool
)
+/*++
+
+ Routine Description:
+ Free address for usb device
+
+ Arguments:
+ DevAddress - Usb device address
+ AddressPool - Pool of usb device address
+
+ Returns:
+ VOID
+
+--*/
{
UINT8 WhichByte;
UINT8 WhichBit;
@@ -215,8 +268,8 @@ UsbBusControllerDriverSupported (
Arguments:
This - Protocol instance pointer.
- Controller - Handle of device to test
- RemainingDevicePath - Not used
+ Controller - Handle of device to test
+ RemainingDevicePath - Device Path Protocol instance pointer
Returns:
EFI_SUCCESS - This driver supports this device.
@@ -224,30 +277,103 @@ UsbBusControllerDriverSupported (
--*/
{
- EFI_STATUS OpenStatus;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_USB2_HC_PROTOCOL *Usb2Hc;
+ EFI_USB_HC_PROTOCOL *UsbHc;
+ EFI_DEV_PATH_PTR Node;
//
+ // Check Device Path
+ //
+ if (RemainingDevicePath != NULL) {
+ Node.DevPath = RemainingDevicePath;
+ if (Node.DevPath->Type != MESSAGING_DEVICE_PATH ||
+ Node.DevPath->SubType != MSG_USB_DP ||
+ DevicePathNodeLength(Node.DevPath) != sizeof(USB_DEVICE_PATH)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ //
// Check whether USB Host Controller Protocol is already
// installed on this handle. If it is installed, we can start
// USB Bus Driver now.
//
- OpenStatus = gBS->OpenProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- NULL,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- );
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ (VOID **) &Usb2Hc,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ (VOID **) &UsbHc,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
- if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {
- return EFI_UNSUPPORTED;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return EFI_SUCCESS;
}
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
- return OpenStatus;
+ return EFI_SUCCESS;
}
-
EFI_STATUS
EFIAPI
UsbBusControllerDriverStart (
@@ -270,11 +396,8 @@ UsbBusControllerDriverStart (
Returns:
EFI_SUCCESS - This driver supports this device.
- EFI_UNSUPPORTED - This driver does not support this device.
EFI_DEVICE_ERROR - This driver cannot be started due to device
- Error
EFI_OUT_OF_RESOURCES- Can't allocate memory resources
- EFI_ALREADY_STARTED - This driver has been started
--*/
{
@@ -283,7 +406,9 @@ UsbBusControllerDriverStart (
USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
USB_IO_DEVICE *RootHub;
USB_IO_CONTROLLER_DEVICE *RootHubController;
- EFI_USB_HC_PROTOCOL *UsbHCInterface;
+ UINT8 MaxSpeed;
+ UINT8 PortNumber;
+ UINT8 Is64BitCapable;
//
// Allocate USB_BUS_CONTROLLER_DEVICE structure
@@ -311,54 +436,56 @@ UsbBusControllerDriverStart (
if (EFI_ERROR (OpenStatus)) {
gBS->FreePool (UsbBusDev);
- return EFI_UNSUPPORTED;
+ return OpenStatus;
}
//
// Locate the Host Controller Interface
//
OpenStatus = gBS->OpenProtocol (
Controller,
- &gEfiUsbHcProtocolGuid,
- (VOID **) &UsbHCInterface,
+ &gEfiUsb2HcProtocolGuid,
+ (VOID **) &(UsbBusDev->Usb2HCInterface),
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
+ if (EFI_ERROR (OpenStatus)) {
- if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {
-
- //
- // Report Status Code here since we will reset the host controller
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,
- UsbBusDev->DevicePath
- );
+ UsbBusDev->Hc2ProtocolSupported = FALSE;
+ OpenStatus = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ (VOID **) &(UsbBusDev->UsbHCInterface),
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (OpenStatus)) {
+ //
+ // Report Status Code here since we will reset the host controller
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,
+ UsbBusDev->DevicePath
+ );
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- gBS->FreePool (UsbBusDev);
- return EFI_UNSUPPORTED;
- }
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ gBS->FreePool (UsbBusDev);
+ return OpenStatus;
+ }
- if (OpenStatus == EFI_ALREADY_STARTED) {
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- gBS->FreePool (UsbBusDev);
- return EFI_ALREADY_STARTED;
+ DEBUG ((gUSBDebugLevel, "UsbHcProtocol Opened.\n"));
+ } else {
+ DEBUG ((gUSBDebugLevel, "Usb2HcProtocol Opened.\n"));
+ UsbBusDev->Hc2ProtocolSupported = TRUE;
}
- UsbBusDev->UsbHCInterface = UsbHCInterface;
-
//
// Attach EFI_USB_BUS_PROTOCOL to controller handle,
// for locate UsbBusDev later
@@ -378,12 +505,22 @@ UsbBusControllerDriverStart (
This->DriverBindingHandle,
Controller
);
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ } else {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+
gBS->FreePool (UsbBusDev);
return Status;
}
@@ -404,12 +541,22 @@ UsbBusControllerDriverStart (
This->DriverBindingHandle,
Controller
);
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ } else {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+
gBS->FreePool (UsbBusDev);
return EFI_OUT_OF_RESOURCES;
}
@@ -435,28 +582,41 @@ UsbBusControllerDriverStart (
This->DriverBindingHandle,
Controller
);
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ } else {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
gBS->FreePool (UsbBusDev);
gBS->FreePool (RootHub);
return EFI_OUT_OF_RESOURCES;
}
- UsbHCInterface->GetRootHubPortNumber (
- UsbHCInterface,
- &RootHubController->DownstreamPorts
- );
- RootHubController->UsbDevice = RootHub;
- RootHubController->IsUsbHub = TRUE;
- RootHubController->DevicePath = UsbBusDev->DevicePath;
- RootHubController->HostController = Controller;
+ UsbVirtualHcGetCapability (
+ UsbBusDev,
+ &MaxSpeed,
+ &PortNumber,
+ &Is64BitCapable
+ );
+ RootHubController->DownstreamPorts = PortNumber;
+ RootHubController->UsbDevice = RootHub;
+ RootHubController->IsUsbHub = TRUE;
+ RootHubController->DevicePath = UsbBusDev->DevicePath;
+ RootHubController->HostController = Controller;
- RootHub->NumOfControllers = 1;
- RootHub->UsbController[0] = RootHubController;
+ RootHub->NumOfControllers = 1;
+ RootHub->UsbController[0] = RootHubController;
+ RootHub->DeviceSpeed = MaxSpeed;
//
// Report Status Code here since we will reset the host controller
@@ -470,10 +630,10 @@ UsbBusControllerDriverStart (
//
// Reset USB Host Controller
//
- UsbHCInterface->Reset (
- UsbHCInterface,
- EFI_USB_HC_RESET_GLOBAL
- );
+ UsbVirtualHcReset (
+ UsbBusDev,
+ EFI_USB_HC_RESET_GLOBAL
+ );
//
// Report Status Code while we are going to bring up the Host Controller
@@ -488,10 +648,10 @@ UsbBusControllerDriverStart (
//
// Start USB Host Controller
//
- UsbHCInterface->SetState (
- UsbHCInterface,
- EfiUsbHcStateOperational
- );
+ UsbVirtualHcSetState (
+ UsbBusDev,
+ EfiUsbHcStateOperational
+ );
//
// Create a timer to query root ports periodically
@@ -499,7 +659,7 @@ UsbBusControllerDriverStart (
Status = gBS->CreateEvent (
EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
EFI_TPL_CALLBACK,
- UsbEnumeration,
+ RootHubEnumeration,
RootHubController,
&RootHubController->HubNotify
);
@@ -517,17 +677,26 @@ UsbBusControllerDriverStart (
Controller
);
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ } else {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
gBS->FreePool (RootHubController);
gBS->FreePool (RootHub);
gBS->FreePool (UsbBusDev);
- return EFI_UNSUPPORTED;
+ return EFI_OUT_OF_RESOURCES;
}
//
@@ -556,22 +725,32 @@ UsbBusControllerDriverStart (
Controller
);
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ } else {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
gBS->CloseEvent (RootHubController->HubNotify);
gBS->FreePool (RootHubController);
gBS->FreePool (RootHub);
gBS->FreePool (UsbBusDev);
- return EFI_UNSUPPORTED;
+ return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
+
//
// Stop the bus controller
//
@@ -608,7 +787,6 @@ UsbBusControllerDriverStop (
USB_BUS_CONTROLLER_DEVICE *UsbBusController;
EFI_USB_BUS_PROTOCOL *UsbIdentifier;
UINT8 Index2;
- EFI_USB_HC_PROTOCOL *UsbHCInterface;
USB_IO_CONTROLLER_DEVICE *UsbController;
USB_IO_DEVICE *UsbIoDevice;
USB_IO_CONTROLLER_DEVICE *HubController;
@@ -678,7 +856,6 @@ UsbBusControllerDriverStop (
//
// Stop USB Host Controller
//
- UsbHCInterface = UsbBusController->UsbHCInterface;
//
// Report Status Code here since we will reset the host controller
@@ -689,10 +866,10 @@ UsbBusControllerDriverStop (
EFI_IO_BUS_USB | EFI_IOB_PC_RESET
);
- UsbHCInterface->SetState (
- UsbHCInterface,
- EfiUsbHcStateHalt
- );
+ UsbVirtualHcSetState (
+ UsbBusController,
+ EfiUsbHcStateHalt
+ );
//
// Deconfiguration all its devices
@@ -725,12 +902,21 @@ UsbBusControllerDriverStop (
// Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL
// Opened by this Controller
//
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
+ if (UsbBusController->Hc2ProtocolSupported) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ } else {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
gBS->CloseProtocol (
Controller,
@@ -786,6 +972,13 @@ UsbDeviceConfiguration (
USB_IO_CONTROLLER_DEVICE *UsbIoController;
UsbBusDev = UsbIoDevice->BusController;
+
+ UsbSetTransactionTranslator (
+ ParentHubController,
+ ParentPort,
+ UsbIoDevice
+ );
+
//
// Since a USB device must have at least on interface,
// so create this instance first
@@ -807,6 +1000,8 @@ UsbDeviceConfiguration (
//
UsbIo = &FirstController->UsbIo;
+ ParentPortReset (FirstController, FALSE, 0);
+
//
// First retrieve the 1st 8 bytes of
// in order to get the MaxPacketSize for Endpoint 0
@@ -815,7 +1010,7 @@ UsbDeviceConfiguration (
UsbIoDevice->DeviceDescriptor.MaxPacketSize0 = 8;
- ParentPortReset (FirstController, FALSE, Index);
+ gBS->Stall (100 * 1000);
Result = UsbGetDescriptor (
UsbIo,
@@ -826,7 +1021,8 @@ UsbDeviceConfiguration (
&Status
);
if (!EFI_ERROR (Result)) {
- DEBUG ((gUSBDebugLevel,
+ DEBUG (
+ (gUSBDebugLevel,
"Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
UsbIoDevice->DeviceDescriptor.MaxPacketSize0)
);
@@ -875,6 +1071,11 @@ UsbDeviceConfiguration (
UsbIoDevice->DeviceAddress = DevAddress;
//
+ // SetAddress Complete Time by Spec, Max 50ms
+ //
+ gBS->Stall (10 * 1000);
+
+ //
// Get the whole device descriptor
//
Result = UsbGetDescriptor (
@@ -1049,7 +1250,6 @@ UsbDeviceConfiguration (
//
// USB Device DeConfiguration
//
-
EFI_STATUS
UsbDeviceDeConfiguration (
IN USB_IO_DEVICE *UsbIoDevice
@@ -1074,8 +1274,6 @@ UsbDeviceDeConfiguration (
UINT8 Index;
EFI_USB_IO_PROTOCOL *UsbIo;
- DEBUG ((gUSBDebugLevel, "Enter Usb Device Deconfiguration\n"));
-
//
// Double check UsbIoDevice exists
//
@@ -1083,6 +1281,8 @@ UsbDeviceDeConfiguration (
return EFI_SUCCESS;
}
+ UsbUnsetTransactionTranslator (UsbIoDevice);
+
for (index = 0; index < UsbIoDevice->NumOfControllers; index++) {
//
// Check if it is a hub, if so, de configuration all its
@@ -1143,13 +1343,21 @@ UsbDeviceDeConfiguration (
//
// remove child handle reference to the USB_HC_PROTOCOL
//
- gBS->CloseProtocol (
- UsbController->HostController,
- &gEfiUsbHcProtocolGuid,
- gUsbBusDriverBinding.DriverBindingHandle,
- UsbController->Handle
- );
-
+ if (UsbIoDevice->BusController->Hc2ProtocolSupported) {
+ gBS->CloseProtocol (
+ UsbController->HostController,
+ &gEfiUsb2HcProtocolGuid,
+ gUsbBusDriverBinding.DriverBindingHandle,
+ UsbController->Handle
+ );
+ } else {
+ gBS->CloseProtocol (
+ UsbController->HostController,
+ &gEfiUsbHcProtocolGuid,
+ gUsbBusDriverBinding.DriverBindingHandle,
+ UsbController->Handle
+ );
+ }
//
// Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
// installed on this handle
@@ -1314,30 +1522,31 @@ OnHubInterruptComplete (
STATIC
VOID
EFIAPI
-UsbEnumeration (
+RootHubEnumeration (
IN EFI_EVENT Event,
IN VOID *Context
)
/*++
Routine Description:
- This is USB enumerator
+
+ This is USB RootHub enumerator
Arguments:
+
Event - Indicating which event is signaled
Context - actually it is a USB_IO_DEVICE
Returns:
- EFI_SUCCESS
- Others
-
+
+ VOID
+
--*/
{
USB_IO_CONTROLLER_DEVICE *HubController;
EFI_USB_PORT_STATUS HubPortStatus;
EFI_STATUS Status;
UINT8 Index;
- EFI_USB_HC_PROTOCOL *UsbHCInterface;
USB_IO_DEVICE *UsbIoDev;
USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
EFI_HANDLE HostController;
@@ -1346,476 +1555,561 @@ UsbEnumeration (
USB_IO_CONTROLLER_DEVICE *NewController;
UINT8 Index2;
EFI_USB_IO_PROTOCOL *UsbIo;
- UINT8 StatusChangePort;
HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
HostController = HubController->HostController;
UsbBusDev = HubController->UsbDevice->BusController;
- if (HubController->UsbDevice->DeviceAddress == 1) {
+ //
+ // Root hub has the address 1
+ //
+ UsbIoDev = HubController->UsbDevice;
+
+ for (Index = 0; Index < HubController->DownstreamPorts; Index++) {
+
+ UsbVirtualHcGetRootHubPortStatus (
+ UsbBusDev,
+ Index,
+ (EFI_USB_PORT_STATUS *) &HubPortStatus
+ );
+
+ if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {
+ continue;
+ }
//
- // Root hub has the address 1
+ // Clear root hub status change status
//
- UsbIoDev = HubController->UsbDevice;
- UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;
-
- for (Index = 0; Index < HubController->DownstreamPorts; Index++) {
- UsbHCInterface->GetRootHubPortStatus (
- UsbHCInterface,
- Index,
- (EFI_USB_PORT_STATUS *) &HubPortStatus
- );
+ UsbVirtualHcClearRootHubPortFeature (
+ UsbBusDev,
+ Index,
+ EfiUsbPortConnectChange
+ );
- if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {
- continue;
- }
+ gBS->Stall (100 * 1000);
+
+ UsbVirtualHcGetRootHubPortStatus (
+ UsbBusDev,
+ Index,
+ (EFI_USB_PORT_STATUS *) &HubPortStatus
+ );
+
+ if (IsPortConnect (HubPortStatus.PortStatus)) {
+
//
- // Clear root hub status change status
+ // There is something connected to this port
//
- ClearRootPortConnectionChangeStatus (
- Index,
- UsbHCInterface
+ DEBUG ((gUSBDebugLevel, "Something connected to Root Hub at Port0x%x\n", Index));
+
+ ReportUsbStatusCode (
+ UsbBusDev,
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG
);
+ //
+ // if there is something physically detached, but still logically
+ // attached...
+ //
+ OldUsbIoDevice = HubController->Children[Index];
- gBS->Stall (100 * 1000);
+ if (NULL != OldUsbIoDevice) {
+ UsbDeviceDeConfiguration (OldUsbIoDevice);
+ HubController->Children[Index] = NULL;
+ }
- UsbHCInterface->GetRootHubPortStatus (
- UsbHCInterface,
- Index,
- (EFI_USB_PORT_STATUS *) &HubPortStatus
- );
+ NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));
+ if (NewDevice == NULL) {
+ return ;
+ }
+ //
+ // Initialize some fields by copying data from
+ // its parents
+ //
+ NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;
+ NewDevice->BusController = UsbIoDev->BusController;
- if (IsPortConnect (HubPortStatus.PortStatus)) {
-
- //
- // There is something connected to this port
- //
- DEBUG ((gUSBDebugLevel, "Something attached from Root Hub in 0x%x\n", Index));
+ //
+ // Process of identify device speed
+ //
+ Status = IdentifyDeviceSpeed (
+ UsbBusDev,
+ NewDevice,
+ Index
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (NewDevice);
+ continue;
+ }
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_PROGRESS_CODE,
- EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG
- );
+ //
+ // Configure that device
+ //
+ Status = UsbDeviceConfiguration (
+ HubController,
+ HostController,
+ Index,
+ NewDevice
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (NewDevice);
+ return ;
+ }
+ //
+ // Add this device to the usb bus tree
+ //
+ HubController->Children[Index] = NewDevice;
+
+ for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {
//
- // if there is something physically detached, but still logically
- // attached...
+ // If this device is hub, add to the hub index
//
- OldUsbIoDevice = HubController->Children[Index];
+ NewController = NewDevice->UsbController[Index2];
- if (NULL != OldUsbIoDevice) {
- UsbDeviceDeConfiguration (OldUsbIoDevice);
- HubController->Children[Index] = NULL;
- }
-
- NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));
- if (NewDevice == NULL) {
- return ;
- }
+ Status = gBS->ConnectController (
+ NewController->Handle,
+ NULL,
+ NULL,
+ TRUE
+ );
//
- // Initialize some fields by copying data from
- // its parents
+ // If connect success, we need to disconnect when
+ // stop the controller, otherwise we need not call
+ // gBS->DisconnectController ()
+ // This is used by those usb devices we don't plan
+ // to support. We can allocate
+ // controller handles for them, but we don't have
+ // device drivers to manage them.
//
- NewDevice->IsSlowDevice = IsPortLowSpeedDeviceAttached (HubPortStatus.PortStatus);
+ NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));
- DEBUG ((gUSBDebugLevel, "DeviceSpeed 0x%x\n", NewDevice->IsSlowDevice));
+ if (IsHub (NewController)) {
- NewDevice->BusController = UsbIoDev->BusController;
+ NewController->IsUsbHub = TRUE;
- //
- // Configure that device
- //
- Status = UsbDeviceConfiguration (
- HubController,
- HostController,
- Index,
- NewDevice
- );
- if (EFI_ERROR (Status)) {
- gBS->FreePool (NewDevice);
- return ;
- }
- //
- // Add this device to the usb bus tree
- //
- HubController->Children[Index] = NewDevice;
-
- for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {
//
- // If this device is hub, add to the hub index
+ // Configure Hub Controller
//
- NewController = NewDevice->UsbController[Index2];
-
- Status = gBS->ConnectController (
- NewController->Handle,
- NULL,
- NULL,
- TRUE
- );
+ Status = DoHubConfig (NewController);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
//
- // If connect success, we need to disconnect when
- // stop the controller, otherwise we need not call
- // gBS->DisconnectController ()
- // This is used by those usb devices we don't plan
- // to support. We can allocate
- // controller handles for them, but we don't have
- // device drivers to manage them.
+ // Create an event to do hub enumeration
//
- NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));
-
- if (IsHub (NewController)) {
-
- NewController->IsUsbHub = TRUE;
-
- //
- // Configure Hub Controller
- //
- Status = DoHubConfig (NewController);
- if (EFI_ERROR (Status)) {
- continue;
- }
- //
- // Create an event to do hub enumeration
- //
- gBS->CreateEvent (
- EFI_EVENT_NOTIFY_SIGNAL,
- EFI_TPL_CALLBACK,
- UsbEnumeration,
- NewController,
- &NewController->HubNotify
- );
+ gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK,
+ HubEnumeration,
+ NewController,
+ &NewController->HubNotify
+ );
- //
- // Add request to do query hub status
- // change endpoint
- // Hub ports < 7
- //
- UsbIo = &NewController->UsbIo;
- UsbIo->UsbAsyncInterruptTransfer (
- UsbIo,
- NewController->HubEndpointAddress,
- TRUE,
- 100,
- 1,
- OnHubInterruptComplete,
- NewController
- );
+ //
+ // Add request to do query hub status
+ // change endpoint
+ // Hub ports < 7
+ //
+ UsbIo = &NewController->UsbIo;
+ UsbIo->UsbAsyncInterruptTransfer (
+ UsbIo,
+ NewController->HubEndpointAddress,
+ TRUE,
+ 100,
+ 1,
+ OnHubInterruptComplete,
+ NewController
+ );
- }
}
- } else {
- //
- // Something disconnected from USB root hub
- //
- DEBUG ((gUSBDebugLevel, "Something deteached from Root Hub\n"));
+ }
+ } else {
+ //
+ // Something disconnected from USB root hub
+ //
+ DEBUG ((gUSBDebugLevel, "Something disconnected from Root Hub at Port0x%x\n", Index));
- OldUsbIoDevice = HubController->Children[Index];
+ OldUsbIoDevice = HubController->Children[Index];
- UsbDeviceDeConfiguration (OldUsbIoDevice);
+ UsbDeviceDeConfiguration (OldUsbIoDevice);
- HubController->Children[Index] = NULL;
+ HubController->Children[Index] = NULL;
- UsbHCInterface->ClearRootHubPortFeature (
- UsbHCInterface,
- Index,
- EfiUsbPortEnableChange
- );
+ UsbVirtualHcClearRootHubPortFeature (
+ UsbBusDev,
+ Index,
+ EfiUsbPortEnableChange
+ );
+ }
+ }
- UsbHCInterface->GetRootHubPortStatus (
- UsbHCInterface,
- Index,
- (EFI_USB_PORT_STATUS *) &HubPortStatus
- );
+ return ;
+}
+//
+// USB Root Hub Enumerator
+//
+STATIC
+VOID
+EFIAPI
+HubEnumeration (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
- }
- }
+ Routine Description:
+
+ This is Usb Hub enumerator
- return ;
- } else {
+ Arguments:
+
+ Event - Indicating which event is signaled
+ Context - actually it is a USB_IO_DEVICE
+
+ Returns:
+
+ VOID
+
+--*/
+{
+ USB_IO_CONTROLLER_DEVICE *HubController;
+ EFI_USB_PORT_STATUS HubPortStatus;
+ EFI_STATUS Status;
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
+ EFI_HANDLE HostController;
+ USB_IO_DEVICE *OldUsbIoDevice;
+ USB_IO_DEVICE *NewDevice;
+ USB_IO_CONTROLLER_DEVICE *NewController;
+ UINT8 Index2;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ UINT8 StatusChangePort;
+ UINT8 Number;
+
+ HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
+ HostController = HubController->HostController;
+ UsbBusDev = HubController->UsbDevice->BusController;
+
+ //
+ // Event from Hub, Get the hub controller handle
+ //
+ //
+ // Get the status change endpoint
+ //
+ StatusChangePort = HubController->StatusChangePort;
+
+ //
+ // Clear HubController Status Change Bit
+ //
+ HubController->StatusChangePort = 0;
+
+ if (StatusChangePort == 0) {
//
- // Event from Hub, Get the hub controller handle
+ // Hub changes, we don't handle here
//
+ return ;
+ }
+ //
+ // Check which event took place at that port
+ //
+ UsbIo = &HubController->UsbIo;
+ Status = HubGetPortStatus (
+ UsbIo,
+ StatusChangePort,
+ (UINT32 *) &HubPortStatus
+ );
+
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+ //
+ // Clear some change status
+ //
+ if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {
//
- // Get the status change endpoint
+ // Clear Hub port enable change
//
- StatusChangePort = HubController->StatusChangePort;
+ DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));
+ HubClearPortFeature (
+ UsbIo,
+ StatusChangePort,
+ EfiUsbPortEnableChange
+ );
+
+ HubGetPortStatus (
+ UsbIo,
+ StatusChangePort,
+ (UINT32 *) &HubPortStatus
+ );
+ }
+ if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {
//
- // Clear HubController Status Change Bit
+ // Clear Hub reset change
//
- HubController->StatusChangePort = 0;
+ DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));
+ HubClearPortFeature (
+ UsbIo,
+ StatusChangePort,
+ EfiUsbPortResetChange
+ );
- if (StatusChangePort == 0) {
- //
- // Hub changes, we don't handle here
- //
- return ;
- }
+ HubGetPortStatus (
+ UsbIo,
+ StatusChangePort,
+ (UINT32 *) &HubPortStatus
+ );
+ }
+
+ if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {
//
- // Check which event took place at that port
+ // Clear Hub overcurrent change
//
- UsbIo = &HubController->UsbIo;
- Status = HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
- );
+ DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));
+ HubClearPortFeature (
+ UsbIo,
+ StatusChangePort,
+ EfiUsbPortOverCurrentChange
+ );
- if (EFI_ERROR (Status)) {
- return ;
- }
+ HubGetPortStatus (
+ UsbIo,
+ StatusChangePort,
+ (UINT32 *) &HubPortStatus
+ );
+ }
+
+ if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {
//
- // Clear some change status
+ // First clear port connection change
//
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {
- //
- // Clear Hub port enable change
- //
- DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));
- HubClearPortFeature (
- UsbIo,
- StatusChangePort,
- EfiUsbPortEnableChange
- );
+ DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));
+ HubClearPortFeature (
+ UsbIo,
+ StatusChangePort,
+ EfiUsbPortConnectChange
+ );
- HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
+ HubGetPortStatus (
+ UsbIo,
+ StatusChangePort,
+ (UINT32 *) &HubPortStatus
+ );
+
+ if (IsPortConnect (HubPortStatus.PortStatus)) {
+
+ DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));
+
+ ReportUsbStatusCode (
+ UsbBusDev,
+ EFI_PROGRESS_CODE,
+ EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG
);
- }
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {
//
- // Clear Hub reset change
+ // if there is something physically detached, but still logically
+ // attached...
//
- DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));
- HubClearPortFeature (
- UsbIo,
- StatusChangePort,
- EfiUsbPortResetChange
- );
+ OldUsbIoDevice = HubController->Children[StatusChangePort - 1];
- HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
- );
- }
+ if (NULL != OldUsbIoDevice) {
+ UsbDeviceDeConfiguration (OldUsbIoDevice);
+ HubController->Children[StatusChangePort - 1] = NULL;
+ }
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {
+ NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));
+ if (NewDevice == NULL) {
+ return ;
+ }
//
- // Clear Hub overcurrent change
+ // Initialize some fields
//
- DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));
- HubClearPortFeature (
- UsbIo,
- StatusChangePort,
- EfiUsbPortOverCurrentChange
- );
+ NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;
+ NewDevice->BusController = HubController->UsbDevice->BusController;
- HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
- );
- }
-
- if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {
//
- // First clear port connection change
+ // There is something connected to this port,
+ // reset that port
+ //
+ // Disable the enable bit in port status
//
- DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));
HubClearPortFeature (
UsbIo,
StatusChangePort,
- EfiUsbPortConnectChange
- );
-
- HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
+ EfiUsbPortEnable
);
- if (IsPortConnect (HubPortStatus.PortStatus)) {
-
- DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));
+ gBS->Stall (50 * 1000);
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_PROGRESS_CODE,
- EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG
+ //
+ // Wait for bit change
+ //
+ Number = 10;
+ do {
+ HubGetPortStatus (
+ UsbIo,
+ StatusChangePort,
+ (UINT32 *) &HubPortStatus
);
+ gBS->Stall (10 * 1000);
+ Number -= 1;
+ } while ((HubPortStatus.PortStatus & USB_PORT_STAT_ENABLE) == 1 && Number > 0);
+ if (Number == 0) {
//
- // if there is something physically detached, but still logically
- // attached...
+ // Cannot disable port, return error
//
- OldUsbIoDevice = HubController->Children[StatusChangePort - 1];
-
- if (NULL != OldUsbIoDevice) {
- UsbDeviceDeConfiguration (OldUsbIoDevice);
- HubController->Children[StatusChangePort - 1] = NULL;
- }
+ DEBUG ((gUSBErrorLevel, "Disable Port Failed\n"));
+ gBS->FreePool (NewDevice);
+ return ;
+ }
- NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));
- if (NewDevice == NULL) {
- return ;
- }
+ HubSetPortFeature (
+ UsbIo,
+ StatusChangePort,
+ EfiUsbPortReset
+ );
- ResetHubPort (HubController, StatusChangePort);
+ gBS->Stall (50 * 1000);
+ //
+ // Wait for port reset complete
+ //
+ Number = 10;
+ do {
HubGetPortStatus (
UsbIo,
StatusChangePort,
(UINT32 *) &HubPortStatus
);
+ gBS->Stall (10 * 1000);
+ Number -= 1;
+ } while ((HubPortStatus.PortStatus & USB_PORT_STAT_RESET) == 1 && Number > 0);
+ if (Number == 0) {
//
- // Initialize some fields
+ // Cannot reset port, return error
//
- NewDevice->IsSlowDevice = IsPortLowSpeedDeviceAttached (HubPortStatus.PortStatus);
+ DEBUG ((gUSBErrorLevel, "Reset Port Failed\n"));
+ gBS->FreePool (NewDevice);
+ return ;
+ }
+ //
+ // Check high speed or full speed device
+ //
+ if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {
+ DEBUG ((gUSBDebugLevel, "Low Speed Device Attached to Hub\n"));
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;
+ } else if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {
+ DEBUG ((gUSBDebugLevel, "High Speed Device Attached to Hub\n"));
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;
+ } else {
+ DEBUG ((gUSBDebugLevel, "Full Speed Device Attached to Hub\n"));
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;
+ }
+ //
+ // Configure that device
+ //
+ Status = UsbDeviceConfiguration (
+ HubController,
+ HostController,
+ (UINT8) (StatusChangePort - 1),
+ NewDevice
+ );
- NewDevice->BusController = HubController->UsbDevice->BusController;
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (NewDevice);
+ return ;
+ }
+ //
+ // Add this device to the usb bus tree
+ // StatusChangePort is begin from 1,
+ //
+ HubController->Children[StatusChangePort - 1] = NewDevice;
+ for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {
//
- // Configure that device
+ // If this device is hub, add to the hub index
//
- Status = UsbDeviceConfiguration (
- HubController,
- HostController,
- (UINT8) (StatusChangePort - 1),
- NewDevice
- );
+ NewController = NewDevice->UsbController[Index2];
- if (EFI_ERROR (Status)) {
- gBS->FreePool (NewDevice);
- return ;
- }
//
- // Add this device to the usb bus tree
- // StatusChangePort is begin from 1,
+ // Connect the controller to the driver image
//
- HubController->Children[StatusChangePort - 1] = NewDevice;
+ Status = gBS->ConnectController (
+ NewController->Handle,
+ NULL,
+ NULL,
+ TRUE
+ );
+ //
+ // If connect success, we need to disconnect when
+ // stop the controller, otherwise we need not call
+ // gBS->DisconnectController ()
+ // This is used by those usb devices we don't plan
+ // to support. We can allocate
+ // controller handles for them, but we don't have
+ // device drivers to manage them.
+ //
+ NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));
- for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {
- //
- // If this device is hub, add to the hub index
- //
- NewController = NewDevice->UsbController[Index2];
+ //
+ // If this device is hub, add to the hub index
+ //
+ if (IsHub (NewController)) {
+
+ NewController->IsUsbHub = TRUE;
//
- // Connect the controller to the driver image
+ // Configure Hub
//
- Status = gBS->ConnectController (
- NewController->Handle,
- NULL,
- NULL,
- TRUE
- );
+ Status = DoHubConfig (NewController);
+
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
//
- // If connect success, we need to disconnect when
- // stop the controller, otherwise we need not call
- // gBS->DisconnectController ()
- // This is used by those usb devices we don't plan
- // to support. We can allocate
- // controller handles for them, but we don't have
- // device drivers to manage them.
+ // Create an event to do hub enumeration
//
- NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));
+ gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK,
+ HubEnumeration,
+ NewController,
+ &NewController->HubNotify
+ );
//
- // If this device is hub, add to the hub index
+ // Add request to do query hub status
+ // change endpoint
//
- if (IsHub (NewController)) {
-
- NewController->IsUsbHub = TRUE;
-
- //
- // Configure Hub
- //
- Status = DoHubConfig (NewController);
-
- if (EFI_ERROR (Status)) {
- continue;
- }
- //
- // Create an event to do hub enumeration
- //
- gBS->CreateEvent (
- EFI_EVENT_NOTIFY_SIGNAL,
- EFI_TPL_CALLBACK,
- UsbEnumeration,
- NewController,
- &NewController->HubNotify
+ UsbIo = &NewController->UsbIo;
+ UsbIo->UsbAsyncInterruptTransfer (
+ UsbIo,
+ NewController->HubEndpointAddress, // Hub endpoint address
+ TRUE,
+ 100,
+ 1, // Hub ports < 7
+ OnHubInterruptComplete,
+ NewController
);
-
- //
- // Add request to do query hub status
- // change endpoint
- //
- UsbIo = &NewController->UsbIo;
- UsbIo->UsbAsyncInterruptTransfer (
- UsbIo,
- NewController->HubEndpointAddress, // Hub endpoint address
- TRUE,
- 100,
- 1, // Hub ports < 7
- OnHubInterruptComplete,
- NewController
- );
- }
}
- } else {
- //
- // Something disconnected from USB hub
- //
- DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));
-
- OldUsbIoDevice = HubController->Children[StatusChangePort - 1];
+ }
+ } else {
+ //
+ // Something disconnected from USB hub
+ //
+ DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));
- UsbDeviceDeConfiguration (OldUsbIoDevice);
+ OldUsbIoDevice = HubController->Children[StatusChangePort - 1];
- HubController->Children[StatusChangePort - 1] = NULL;
+ UsbDeviceDeConfiguration (OldUsbIoDevice);
- }
+ HubController->Children[StatusChangePort - 1] = NULL;
- return ;
}
return ;
}
-}
-//
-// Clear port connection change status over a given root hub port
-//
-EFI_STATUS
-ClearRootPortConnectionChangeStatus (
- UINT8 PortNum,
- EFI_USB_HC_PROTOCOL *UsbHCInterface
- )
-/*++
- Routine Description:
- Clear port connection change status over a given root hub port
-
- Arguments:
- PortNum - The given port.
- UsbHCInterface - The EFI_USB_HC_PROTOCOL instance.
-
- Returns:
- EFI_SUCCESS
-
---*/
-{
- EFI_STATUS Status;
- Status = UsbHCInterface->ClearRootHubPortFeature (
- UsbHCInterface,
- PortNum,
- EfiUsbPortConnectChange
- );
- return Status;
+ return ;
}
STATIC
@@ -1877,6 +2171,7 @@ InitUsbIoController (
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
EFI_USB_HC_PROTOCOL *UsbHcProtocol;
+ EFI_USB2_HC_PROTOCOL *Usb2HcProtocol;
//
// Build the child device path for each new USB_IO device
@@ -1908,14 +2203,25 @@ InitUsbIoController (
return Status;
}
- Status = gBS->OpenProtocol (
- UsbIoController->HostController,
- &gEfiUsbHcProtocolGuid,
- (VOID **) &UsbHcProtocol,
- gUsbBusDriverBinding.DriverBindingHandle,
- UsbIoController->Handle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
+ if (UsbIoController->UsbDevice->BusController->Hc2ProtocolSupported) {
+ Status = gBS->OpenProtocol (
+ UsbIoController->HostController,
+ &gEfiUsb2HcProtocolGuid,
+ (VOID **)&Usb2HcProtocol,
+ gUsbBusDriverBinding.DriverBindingHandle,
+ UsbIoController->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else {
+ Status = gBS->OpenProtocol (
+ UsbIoController->HostController,
+ &gEfiUsbHcProtocolGuid,
+ (VOID **)&UsbHcProtocol,
+ gUsbBusDriverBinding.DriverBindingHandle,
+ UsbIoController->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ }
return Status;
}
@@ -1934,8 +2240,9 @@ ParentPortReset (
Arguments:
UsbIoController - Indicating the Usb Controller Device.
- Reconfigure - Do we need to reconfigure it.
+ ReConfigure - Do we need to reconfigure it.
RetryTimes - Retry Times when failed
+
Returns:
EFI_SUCCESS
EFI_DEVICE_ERROR
@@ -1960,7 +2267,7 @@ ParentPortReset (
if (ParentIoDev->DeviceAddress == 1) {
DEBUG ((gUSBDebugLevel, "Reset from Root Hub 0x%x\n", HubPort));
- ResetRootPort (ParentIoDev->BusController->UsbHCInterface, HubPort, RetryTimes);
+ ResetRootPort (ParentIoDev->BusController, HubPort, RetryTimes);
} else {
DEBUG ((gUSBDebugLevel, "Reset from Hub, Addr 0x%x\n", ParentIoDev->DeviceAddress));
ResetHubPort (ParentController, HubPort + 1);
@@ -2036,9 +2343,9 @@ UsbPortReset (
EFI_STATUS
ResetRootPort (
- IN EFI_USB_HC_PROTOCOL *UsbHCInterface,
- IN UINT8 PortNum,
- IN UINT8 RetryTimes
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 PortNum,
+ IN UINT8 RetryTimes
)
/*++
@@ -2046,25 +2353,27 @@ ResetRootPort (
Reset Root Hub port.
Arguments:
- UsbHCInterface - The EFI_USB_HC_PROTOCOL instance.
- PortNum - The given port to be reset.
- RetryTimes - RetryTimes when failed
+ UsbBusDev - Bus controller of the device.
+ PortNum - The given port to be reset.
+ RetryTimes - RetryTimes when failed
+
Returns:
- N/A
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
--*/
{
- EFI_STATUS Status;
+ EFI_STATUS Status;
+ EFI_USB_PORT_STATUS PortStatus;
//
// reset root port
//
- Status = UsbHCInterface->SetRootHubPortFeature (
- UsbHCInterface,
- PortNum,
- EfiUsbPortReset
- );
-
+ Status = UsbVirtualHcSetRootHubPortFeature (
+ UsbBusDev,
+ PortNum,
+ EfiUsbPortReset
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
@@ -2074,46 +2383,56 @@ ResetRootPort (
//
// clear reset root port
//
- Status = UsbHCInterface->ClearRootHubPortFeature (
- UsbHCInterface,
- PortNum,
- EfiUsbPortReset
- );
-
+ Status = UsbVirtualHcClearRootHubPortFeature (
+ UsbBusDev,
+ PortNum,
+ EfiUsbPortReset
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
gBS->Stall (1000);
- Status = ClearRootPortConnectionChangeStatus (PortNum, UsbHCInterface);
-
+ Status = UsbVirtualHcClearRootHubPortFeature (
+ UsbBusDev,
+ PortNum,
+ EfiUsbPortConnectChange
+ );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
- //
- // Set port enable
- //
- Status = UsbHCInterface->SetRootHubPortFeature (
- UsbHCInterface,
- PortNum,
- EfiUsbPortEnable
- );
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
+
+ UsbVirtualHcGetRootHubPortStatus (
+ UsbBusDev,
+ PortNum,
+ &PortStatus
+ );
+ if (PortStatus.PortStatus & USB_PORT_STAT_OWNER) {
+ //
+ // Set port enable
+ //
+ Status = UsbVirtualHcSetRootHubPortFeature (
+ UsbBusDev,
+ PortNum,
+ EfiUsbPortEnable
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = UsbVirtualHcClearRootHubPortFeature (
+ UsbBusDev,
+ PortNum,
+ EfiUsbPortEnableChange
+ );
}
- Status = UsbHCInterface->ClearRootHubPortFeature (
- UsbHCInterface,
- PortNum,
- EfiUsbPortEnableChange
- );
gBS->Stall ((1 + RetryTimes) * 50 * 1000);
return EFI_SUCCESS;
}
-
EFI_STATUS
ResetHubPort (
IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
@@ -2202,10 +2521,6 @@ ResetHubPort (
return EFI_SUCCESS;
}
-
-
-
-
STATIC
EFI_STATUS
ReportUsbStatusCode (
@@ -2236,7 +2551,6 @@ Routine Description:
);
}
-
EFI_STATUS
IsDeviceDisconnected (
IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
@@ -2264,7 +2578,6 @@ IsDeviceDisconnected (
EFI_STATUS Status;
EFI_USB_IO_PROTOCOL *UsbIo;
EFI_USB_PORT_STATUS PortStatus;
- EFI_USB_HC_PROTOCOL *UsbHCInterface;
ParentController = UsbIoController->Parent;
ParentIoDev = ParentController->UsbDevice;
@@ -2275,12 +2588,11 @@ IsDeviceDisconnected (
//
// Connected to the root hub
//
- UsbHCInterface = ParentIoDev->BusController->UsbHCInterface;
- Status = UsbHCInterface->GetRootHubPortStatus (
- UsbHCInterface,
- HubPort,
- &PortStatus
- );
+ UsbVirtualHcGetRootHubPortStatus (
+ ParentIoDev->BusController,
+ HubPort,
+ &PortStatus
+ );
} else {
UsbIo = &UsbIoController->UsbIo;
@@ -2303,3 +2615,1135 @@ IsDeviceDisconnected (
return EFI_SUCCESS;
}
+
+STATIC
+EFI_STATUS
+UsbSetTransactionTranslator (
+ IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
+ IN UINT8 ParentPort,
+ IN OUT USB_IO_DEVICE *Device
+ )
+/*++
+
+ Routine Description:
+
+ Set Transaction Translator parameter
+
+ Arguments:
+
+ ParentHubController - Controller structure of the parent Hub device
+ ParentPort - Number of parent port
+ Device - Structure of the device
+
+ Returns:
+
+ EFI_SUCCESS Success
+ EFI_OUT_OF_RESOURCES Cannot allocate resources
+
+--*/
+{
+ USB_IO_CONTROLLER_DEVICE *AncestorHubController;
+
+ AncestorHubController = ParentHubController;
+ Device->Translator = NULL;
+
+ if (EFI_USB_SPEED_HIGH == Device->DeviceSpeed) {
+ return EFI_SUCCESS;
+ }
+
+ do {
+ if (EFI_USB_SPEED_HIGH == AncestorHubController->UsbDevice->DeviceSpeed) {
+ break;
+ }
+
+ if (NULL == AncestorHubController->Parent) {
+ return EFI_SUCCESS;
+ }
+
+ AncestorHubController = AncestorHubController->Parent;
+ } while (1);
+
+ Device->Translator = AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR));
+ if (NULL == Device->Translator) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Device->Translator->TranslatorHubAddress = AncestorHubController->UsbDevice->DeviceAddress;
+ Device->Translator->TranslatorPortNumber = ParentPort;
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+UsbUnsetTransactionTranslator (
+ USB_IO_DEVICE *Device
+ )
+/*++
+
+ Routine Description:
+
+ Unset Transaction Translator parameter
+
+ Arguments:
+
+ Device - Structure of the device
+
+ Returns:
+
+ EFI_SUCCESS Success
+
+--*/
+{
+ if (Device->Translator) {
+ gBS->FreePool (Device->Translator);
+ Device->Translator = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+IdentifyDeviceSpeed (
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ USB_IO_DEVICE *NewDevice,
+ UINT8 Index
+ )
+/*++
+
+ Routine Description:
+
+ Identify speed of USB device
+
+ Arguments:
+
+ UsbBusDev - UsbBus controller structure of the device
+ NewDevice - Devcie controller structure
+ Index - Number of the port
+
+ Returns:
+
+ EFI_SUCCESS Success
+ EFI_NOT_FOUND Device release to CHC or can't be found
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_USB_PORT_STATUS HubPortStatus;
+
+ UsbVirtualHcGetRootHubPortStatus (
+ UsbBusDev,
+ Index,
+ (EFI_USB_PORT_STATUS *) &HubPortStatus
+ );
+
+ //
+ // Check device device
+ //
+ if (!(HubPortStatus.PortStatus & USB_PORT_STAT_OWNER)) {
+ //
+ // EHC Port Owner
+ //
+ if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {
+ DEBUG ((gUSBDebugLevel, "High Speed Device attached to EHC\n"));
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;
+ } else {
+ Status = ReleasePortToCHC (UsbBusDev, Index);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((gUSBErrorLevel, "Fail to release port to CHC\n"));
+ } else {
+ DEBUG ((gUSBDebugLevel, "Success to release port to CHC\n"));
+ }
+ return EFI_DEVICE_ERROR;
+ }
+ } else {
+ //
+ // CHC Port Owner
+ //
+ if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {
+ DEBUG ((gUSBDebugLevel, "Low Speed Device attached to CHC\n"));
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;
+ } else {
+ DEBUG ((gUSBDebugLevel, "FULL Speed Device attached to CHC\n"));
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+ReleasePortToCHC (
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ UINT8 PortNum
+ )
+/*++
+
+ Routine Description:
+
+ Set bit to release the port owner to CHC
+
+ Arguments:
+
+ UsbBusDev - UsbBus controller structure of the device
+ PortNum - Number of the port
+
+ Returns:
+
+ EFI_SUCCESS Success
+ EFI_DEVICE_ERROR Fail
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = UsbVirtualHcSetRootHubPortFeature (
+ UsbBusDev,
+ PortNum,
+ EfiUsbPortOwner
+ );
+
+ gBS->Stall (100 * 1000);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcGetCapability (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ OUT UINT8 *MaxSpeed,
+ OUT UINT8 *PortNumber,
+ OUT UINT8 *Is64BitCapable
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to Retrieves the capablility of root hub ports
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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
+ The 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;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->GetCapability (
+ UsbBusDev->Usb2HCInterface,
+ MaxSpeed,
+ PortNumber,
+ Is64BitCapable
+ );
+ } else {
+ Status = UsbBusDev->UsbHCInterface->GetRootHubPortNumber (
+ UsbBusDev->UsbHCInterface,
+ PortNumber
+ );
+ *MaxSpeed = EFI_USB_SPEED_FULL;
+ *Is64BitCapable = (UINT8) FALSE;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcReset (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT16 Attributes
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to provides software reset for the USB host controller
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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 // Hc2 and Hc
+ #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
+ #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
+ #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
+
+ 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;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->Reset (
+ UsbBusDev->Usb2HCInterface,
+ EFI_USB_HC_RESET_GLOBAL
+ );
+ } else {
+ Status = UsbBusDev->UsbHCInterface->Reset (
+ UsbBusDev->UsbHCInterface,
+ EFI_USB_HC_RESET_GLOBAL
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcGetState (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ OUT EFI_USB_HC_STATE *State
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to retrieves current state of the USB host controller
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->GetState (
+ UsbBusDev->Usb2HCInterface,
+ State
+ );
+ } else {
+ Status = UsbBusDev->UsbHCInterface->GetState (
+ UsbBusDev->UsbHCInterface,
+ State
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcSetState (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN EFI_USB_HC_STATE State
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to sets the USB host controller to a specific state
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->SetState (
+ UsbBusDev->Usb2HCInterface,
+ State
+ );
+ } else {
+ Status = UsbBusDev->UsbHCInterface->SetState (
+ UsbBusDev->UsbHCInterface,
+ State
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcGetRootHubPortStatus (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to retrieves the current status of a USB root hub port
+ both for Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->GetRootHubPortStatus (
+ UsbBusDev->Usb2HCInterface,
+ PortNumber,
+ PortStatus
+ );
+ } else {
+ Status = UsbBusDev->UsbHCInterface->GetRootHubPortStatus (
+ UsbBusDev->UsbHCInterface,
+ PortNumber,
+ PortStatus
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcSetRootHubPortFeature (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ )
+/*++
+
+ Routine Description:
+ Virual interface to sets a feature for the specified root hub port
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->SetRootHubPortFeature (
+ UsbBusDev->Usb2HCInterface,
+ PortNumber,
+ PortFeature
+ );
+ } else {
+ Status = UsbBusDev->UsbHCInterface->SetRootHubPortFeature (
+ UsbBusDev->UsbHCInterface,
+ PortNumber,
+ PortFeature
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcClearRootHubPortFeature (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to clears a feature for the specified root hub port
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ PortNumber - Specifies the root hub port whose feature
+ is requested to be cleared.
+ PortFeature - Indicates the feature selector associated with the
+ feature clear request.
+
+ Returns:
+
+ EFI_SUCCESS
+ The feature specified by PortFeature was cleared 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;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->ClearRootHubPortFeature (
+ UsbBusDev->Usb2HCInterface,
+ PortNumber,
+ PortFeature
+ );
+ } else {
+ Status = UsbBusDev->UsbHCInterface->ClearRootHubPortFeature (
+ UsbBusDev->UsbHCInterface,
+ PortNumber,
+ PortFeature
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcControlTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to submits control transfer to a target USB device
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ DeviceSpeed - Indicates target device speed.
+ MaximumPacketLength - Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+ Request - A pointer to the USB device request that will be sent
+ to the USB device.
+ TransferDirection - Specifies the data direction for the transfer.
+ There are three values available, DataIn, DataOut
+ and NoData.
+ Data - A pointer to the buffer of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - Indicates the size, in bytes, of the data buffer
+ specified by Data.
+ TimeOut - Indicates the maximum time, in microseconds,
+ which the transfer is allowed to complete.
+ Translator - A pointr to the transaction translator data.
+ TransferResult - A pointer to the detailed result information generated
+ by this control transfer.
+
+ Returns:
+
+ EFI_SUCCESS
+ The control transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The control transfer could not be completed due to a lack of resources.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The control transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The control transfer failed due to host controller or device error.
+ Caller should check TranferResult for detailed error information.
+
+--*/
+{
+ EFI_STATUS Status;
+ BOOLEAN IsSlowDevice;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->ControlTransfer (
+ UsbBusDev->Usb2HCInterface,
+ DeviceAddress,
+ DeviceSpeed,
+ MaximumPacketLength,
+ Request,
+ TransferDirection,
+ Data,
+ DataLength,
+ TimeOut,
+ Translator,
+ TransferResult
+ );
+ } else {
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
+ Status = UsbBusDev->UsbHCInterface->ControlTransfer (
+ UsbBusDev->UsbHCInterface,
+ DeviceAddress,
+ IsSlowDevice,
+ (UINT8) MaximumPacketLength,
+ Request,
+ TransferDirection,
+ Data,
+ DataLength,
+ TimeOut,
+ TransferResult
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcBulkTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
+ both for Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - The combination of an endpoint number and an
+ endpoint direction of the target USB device.
+ Each endpoint address supports data transfer in
+ one direction except the control endpoint
+ (whose default endpoint address is 0).
+ It is the caller's responsibility to make sure that
+ the EndPointAddress represents a bulk endpoint.
+ DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
+ and EFI_USB_SPEED_HIGH.
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+ DataBuffersNumber - Number of data buffers prepared for the transfer.
+ Data - Array of pointers to the buffers of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - When input, indicates the size, in bytes, of the data buffer
+ specified by Data. When output, indicates the actually
+ transferred data size.
+ DataToggle - A pointer to the data toggle value. On input, it indicates
+ the initial data toggle value the bulk transfer should adopt;
+ on output, it is updated to indicate the data toggle value
+ of the subsequent bulk transfer.
+ Translator - A pointr to the transaction translator data.
+ TimeOut - Indicates the maximum time, in microseconds, which the
+ transfer is allowed to complete.
+ TransferResult - A pointer to the detailed result information of the
+ bulk transfer.
+
+ Returns:
+
+ EFI_SUCCESS
+ The bulk transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The bulk transfer could not be submitted due to lack of resource.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The bulk transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The bulk transfer failed due to host controller or device error.
+ Caller should check TranferResult for detailed error information.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->BulkTransfer (
+ UsbBusDev->Usb2HCInterface,
+ DeviceAddress,
+ EndPointAddress,
+ DeviceSpeed,
+ MaximumPacketLength,
+ DataBuffersNumber,
+ Data,
+ DataLength,
+ DataToggle,
+ TimeOut,
+ Translator,
+ TransferResult
+ );
+ } else {
+ Status = UsbBusDev->UsbHCInterface->BulkTransfer (
+ UsbBusDev->UsbHCInterface,
+ DeviceAddress,
+ EndPointAddress,
+ (UINT8) MaximumPacketLength,
+ *Data,
+ DataLength,
+ DataToggle,
+ TimeOut,
+ TransferResult
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcAsyncInterruptTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE * UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN BOOLEAN IsNewTransfer,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN PollingInterval,
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
+ IN VOID *Context OPTIONAL
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to submits an asynchronous interrupt transfer to an
+ interrupt endpoint of a USB device for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - The combination of an endpoint number and an endpoint
+ direction of the target USB device. Each endpoint address
+ supports data transfer in one direction except the
+ control endpoint (whose default endpoint address is 0).
+ It is the caller's responsibility to make sure that
+ the EndPointAddress represents an interrupt endpoint.
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+ IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
+ the host and the target interrupt endpoint.
+ If FALSE, the specified asynchronous interrupt pipe
+ is canceled.
+ DataToggle - A pointer to the data toggle value. On input, it is valid
+ when IsNewTransfer is TRUE, and it indicates the initial
+ data toggle value the asynchronous interrupt transfer
+ should adopt.
+ On output, it is valid when IsNewTransfer is FALSE,
+ and it is updated to indicate the data toggle value of
+ the subsequent asynchronous interrupt transfer.
+ PollingInterval - Indicates the interval, in milliseconds, that the
+ asynchronous interrupt transfer is polled.
+ This parameter is required when IsNewTransfer is TRUE.
+ DataLength - Indicates the length of data to be received at the
+ rate specified by PollingInterval from the target
+ asynchronous interrupt endpoint. This parameter
+ is only required when IsNewTransfer is TRUE.
+ Translator - A pointr to the transaction translator data.
+ CallBackFunction - The Callback function.This function is called at the
+ rate specified by PollingInterval.This parameter is
+ only required when IsNewTransfer is TRUE.
+ Context - The context that is passed to the CallBackFunction.
+ - This is an optional parameter and may be NULL.
+
+ Returns:
+
+ EFI_SUCCESS
+ The asynchronous interrupt transfer request has been successfully
+ submitted or canceled.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_OUT_OF_RESOURCES
+ The request could not be completed due to a lack of resources.
+ EFI_DEVICE_ERROR
+ Can't read register
+
+--*/
+{
+ EFI_STATUS Status;
+ BOOLEAN IsSlowDevice;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->AsyncInterruptTransfer (
+ UsbBusDev->Usb2HCInterface,
+ DeviceAddress,
+ EndPointAddress,
+ DeviceSpeed,
+ MaximumPacketLength,
+ IsNewTransfer,
+ DataToggle,
+ PollingInterval,
+ DataLength,
+ Translator,
+ CallBackFunction,
+ Context
+ );
+ } else {
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
+ Status = UsbBusDev->UsbHCInterface->AsyncInterruptTransfer (
+ UsbBusDev->UsbHCInterface,
+ DeviceAddress,
+ EndPointAddress,
+ IsSlowDevice,
+ (UINT8) MaximumPacketLength,
+ IsNewTransfer,
+ DataToggle,
+ PollingInterval,
+ DataLength,
+ CallBackFunction,
+ Context
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcSyncInterruptTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
+ of a USB device for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - The combination of an endpoint number and an endpoint
+ direction of the target USB device. Each endpoint
+ address supports data transfer in one direction
+ except the control endpoint (whose default
+ endpoint address is 0). It is the caller's responsibility
+ to make sure that the EndPointAddress represents
+ an interrupt endpoint.
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+ Data - A pointer to the buffer of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - On input, the size, in bytes, of the data buffer specified
+ by Data. On output, the number of bytes transferred.
+ DataToggle - A pointer to the data toggle value. On input, it indicates
+ the initial data toggle value the synchronous interrupt
+ transfer should adopt;
+ on output, it is updated to indicate the data toggle value
+ of the subsequent synchronous interrupt transfer.
+ TimeOut - Indicates the maximum time, in microseconds, which the
+ transfer is allowed to complete.
+ Translator - A pointr to the transaction translator data.
+ TransferResult - A pointer to the detailed result information from
+ the synchronous interrupt transfer.
+
+ Returns:
+
+ EFI_SUCCESS
+ The synchronous interrupt transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The synchronous interrupt transfer could not be submitted due
+ to lack of resource.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The synchronous interrupt transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The synchronous interrupt transfer failed due to host controller
+ or device error. Caller should check TranferResult for detailed
+ error information.
+
+--*/
+{
+ EFI_STATUS Status;
+ BOOLEAN IsSlowDevice;
+
+ Status = EFI_SUCCESS;
+
+ if (UsbBusDev->Hc2ProtocolSupported) {
+ Status = UsbBusDev->Usb2HCInterface->SyncInterruptTransfer (
+ UsbBusDev->Usb2HCInterface,
+ DeviceAddress,
+ EndPointAddress,
+ DeviceSpeed,
+ MaximumPacketLength,
+ Data,
+ DataLength,
+ DataToggle,
+ TimeOut,
+ Translator,
+ TransferResult
+ );
+ } else {
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;
+ Status = UsbBusDev->UsbHCInterface->SyncInterruptTransfer (
+ UsbBusDev->UsbHCInterface,
+ DeviceAddress,
+ EndPointAddress,
+ IsSlowDevice,
+ (UINT8) MaximumPacketLength,
+ Data,
+ DataLength,
+ DataToggle,
+ TimeOut,
+ TransferResult
+ );
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcIsochronousTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to submits isochronous transfer to a target USB device
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - End point address
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+ DataBuffersNumber - Number of data buffers prepared for the transfer.
+ Data - Array of pointers to the buffers of data that will be
+ transmitted to USB device or received from USB device.
+ DataLength - Indicates the size, in bytes, of the data buffer
+ specified by Data.
+ Translator - A pointr to the transaction translator data.
+ TransferResult - A pointer to the detailed result information generated
+ by this control transfer.
+
+ Returns:
+
+ EFI_UNSUPPORTED
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcAsyncIsochronousTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
+ IN VOID *Context
+ )
+/*++
+
+ Routine Description:
+
+ Vitual interface to submits Async isochronous transfer to a target USB device
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - End point address
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+ DataBuffersNumber - Number of data buffers prepared for the transfer.
+ Data - Array of pointers to the buffers of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - Indicates the size, in bytes, of the data buffer
+ specified by Data.
+ Translator - A pointr to the transaction translator data.
+ IsochronousCallBack - When the transfer complete, the call back function will be called
+ Context - Pass to the call back function as parameter
+
+ Returns:
+
+ EFI_UNSUPPORTED
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.h b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.h
index 036f4dfe50..47f0fd804f 100644
--- a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.h
+++ b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.h
@@ -30,13 +30,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "hub.h"
#include "usbutil.h"
-//#ifdef EFI_DEBUG
extern UINTN gUSBDebugLevel;
extern UINTN gUSBErrorLevel;
-//#endif
-#define MICROSECOND 10000
-#define ONESECOND (1000 * MICROSECOND)
+#define MICROSECOND 10000
+#define ONESECOND (1000 * MICROSECOND)
#define BUSPOLLING_PERIOD ONESECOND
//
// We define some maximun value here
@@ -120,21 +118,23 @@ typedef struct usb_io_controller_device {
struct _usb_bus_controller_device;
typedef struct usb_io_device {
- UINT8 DeviceAddress;
- BOOLEAN IsConfigured;
- BOOLEAN IsSlowDevice;
- EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor;
- LIST_ENTRY ConfigDescListHead;
- CONFIG_DESC_LIST_ENTRY *ActiveConfig;
- UINT16 LangID[USB_MAXLANID];
+ UINT8 DeviceAddress;
+ BOOLEAN IsConfigured;
+ BOOLEAN IsSlowDevice;
+ UINT8 DeviceSpeed;
+ EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator;
+ EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor;
+ LIST_ENTRY ConfigDescListHead;
+ CONFIG_DESC_LIST_ENTRY *ActiveConfig;
+ UINT16 LangID[USB_MAXLANID];
- struct _usb_bus_controller_device *BusController;
+ struct _usb_bus_controller_device *BusController;
//
// Track the controller handle
//
- UINT8 NumOfControllers;
- USB_IO_CONTROLLER_DEVICE *UsbController[USB_MAXCONTROLLERS];
+ UINT8 NumOfControllers;
+ USB_IO_CONTROLLER_DEVICE *UsbController[USB_MAXCONTROLLERS];
} USB_IO_DEVICE;
@@ -154,10 +154,12 @@ typedef struct _usb_bus_controller_device {
UINTN Signature;
EFI_USB_BUS_PROTOCOL BusIdentify;
+ EFI_USB2_HC_PROTOCOL *Usb2HCInterface;
EFI_USB_HC_PROTOCOL *UsbHCInterface;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
UINT8 AddressPool[16];
USB_IO_DEVICE *Root;
+ BOOLEAN Hc2ProtocolSupported;
} USB_BUS_CONTROLLER_DEVICE;
#define USB_BUS_CONTROLLER_DEVICE_FROM_THIS(a) \
@@ -177,28 +179,99 @@ extern EFI_GUID gUSBBusDriverGuid;
BOOLEAN
IsHub (
IN USB_IO_CONTROLLER_DEVICE *Dev
- );
+ )
+/*++
+
+ Routine Description:
+ Tell if a usb controller is a hub controller.
+
+ Arguments:
+ Dev - UsbIoController device structure.
+
+ Returns:
+ TRUE/FALSE
+--*/
+;
EFI_STATUS
UsbGetStringtable (
IN USB_IO_DEVICE *UsbIoDevice
- );
+ )
+/*++
+
+ Routine Description:
+ Get the string table stored in a usb device.
+
+ Arguments:
+ Dev - UsbIoController device structure.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_UNSUPPORTED
+ EFI_OUT_OF_RESOURCES
+
+--*/
+;
EFI_STATUS
UsbGetAllConfigurations (
IN USB_IO_DEVICE *UsbIoDevice
- );
+ )
+/*++
+
+ Routine Description:
+ This function is to parse all the configuration descriptor.
+
+ Arguments:
+ UsbIoDevice - USB_IO_DEVICE device structure.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+ EFI_OUT_OF_RESOURCES
+
+--*/
+;
EFI_STATUS
UsbSetConfiguration (
IN USB_IO_DEVICE *Dev,
IN UINTN ConfigurationValue
- );
+ )
+/*++
+
+ Routine Description:
+ Set the device to a configuration value.
+
+ Arguments:
+ UsbIoDev - USB_IO_DEVICE to be set configuration
+ ConfigrationValue - The configuration value to be set to that device
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+
+--*/
+;
EFI_STATUS
UsbSetDefaultConfiguration (
IN USB_IO_DEVICE *Dev
- );
+ )
+/*++
+
+ Routine Description:
+ Set the device to a default configuration value.
+
+ Arguments:
+ UsbIoDev - USB_IO_DEVICE to be set configuration
+
+ Returns
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+
+--*/
+;
//
// Device Deconfiguration functions
@@ -206,56 +279,834 @@ UsbSetDefaultConfiguration (
VOID
UsbDestroyAllConfiguration (
IN USB_IO_DEVICE *UsbIoDevice
- );
+ )
+/*++
+
+ Routine Description:
+ Delete all configuration data when device is not used.
+
+ Arguments:
+ UsbIoDevice - USB_IO_DEVICE to be set configuration
+
+ Returns:
+ VOID
+
+--*/
+;
EFI_STATUS
DoHubConfig (
IN USB_IO_CONTROLLER_DEVICE *HubIoDevice
- );
+ )
+/*++
+
+ Routine Description:
+ Configure the hub
+
+ Arguments:
+ HubController - Indicating the hub controller device that
+ will be configured
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+
+--*/
+
+;
VOID
GetDeviceEndPointMaxPacketLength (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT8 EndpointAddr,
- OUT UINT8 *MaxPacketLength
- );
+ OUT UINTN *MaxPacketLength
+ )
+/*++
+
+ Routine Description:
+ Get the Max Packet Length of the speified Endpoint.
+
+ Arguments:
+ UsbIo - Given Usb Controller device.
+ EndpointAddr - Given Endpoint address.
+ MaxPacketLength - The max packet length of that endpoint
+
+ Returns:
+ N/A
+
+--*/
+;
VOID
GetDataToggleBit (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT8 EndpointAddr,
OUT UINT8 *DataToggle
- );
+ )
+/*++
+
+ Routine Description:
+ Get the datatoggle of a specified endpoint.
+
+ Arguments:
+ UsbIo - Given Usb Controller device.
+ EndpointAddr - Given Endpoint address.
+ DataToggle - The current data toggle of that endpoint
+
+ Returns:
+ VOID
+
+--*/
+;
VOID
SetDataToggleBit (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT8 EndpointAddr,
IN UINT8 DataToggle
- );
+ )
+/*++
+
+ Routine Description:
+ Set the datatoggle of a specified endpoint
+
+ Arguments:
+ UsbIo - Given Usb Controller device.
+ EndpointAddr - Given Endpoint address.
+ DataToggle - The current data toggle of that endpoint to be set
+
+ Returns:
+ VOID
+
+--*/
+;
-INTERFACE_DESC_LIST_ENTRY *
+INTERFACE_DESC_LIST_ENTRY *
FindInterfaceListEntry (
IN EFI_USB_IO_PROTOCOL *This
- );
+ )
+/*++
+
+ Routine Description:
+ Find Interface ListEntry.
-ENDPOINT_DESC_LIST_ENTRY *
+ Arguments:
+ This - EFI_USB_IO_PROTOCOL
+
+ Returns:
+ INTERFACE_DESC_LIST_ENTRY pointer
+
+--*/
+;
+
+ENDPOINT_DESC_LIST_ENTRY *
FindEndPointListEntry (
IN EFI_USB_IO_PROTOCOL *This,
IN UINT8 EndPointAddress
- );
+ )
+/*++
+
+ Routine Description:
+ Find EndPoint ListEntry.
+ Arguments:
+ This - EFI_USB_IO_PROTOCOL
+ EndpointAddr - Endpoint address.
+
+ Returns:
+ ENDPOINT_DESC_LIST_ENTRY pointer
+
+--*/
+;
EFI_STATUS
IsDeviceDisconnected (
IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
IN OUT BOOLEAN *Disconnected
- );
+ )
+/*++
+
+ Routine Description:
+ Reset if the device is disconencted or not
+
+ Arguments:
+ UsbIoController - Indicating the Usb Controller Device.
+ Disconnected - Indicate whether the device is disconencted or not
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+
+--*/
+;
EFI_STATUS
UsbDeviceDeConfiguration (
IN USB_IO_DEVICE *UsbIoDevice
- );
+ )
+/*++
+
+ Routine Description:
+ Remove Device, Device Handles, Uninstall Protocols.
+
+ Arguments:
+ UsbIoDevice - The device to be deconfigured.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+
+--*/
+;
+EFI_STATUS
+EFIAPI
+UsbVirtualHcGetCapability (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ OUT UINT8 *MaxSpeed,
+ OUT UINT8 *PortNumber,
+ OUT UINT8 *Is64BitCapable
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to Retrieves the capablility of root hub ports
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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
+ The 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
+EFIAPI
+UsbVirtualHcReset (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT16 Attributes
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to provides software reset for the USB host controller
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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 // Hc2 and Hc
+ #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
+ #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
+ #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
+
+ 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
+EFIAPI
+UsbVirtualHcGetState (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ OUT EFI_USB_HC_STATE *State
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to retrieves current state of the USB host controller
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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
+EFIAPI
+UsbVirtualHcSetState (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN EFI_USB_HC_STATE State
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to sets the USB host controller to a specific state
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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
+EFIAPI
+UsbVirtualHcGetRootHubPortStatus (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to retrieves the current status of a USB root hub port
+ both for Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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
+EFIAPI
+UsbVirtualHcSetRootHubPortFeature (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ )
+/*++
+
+ Routine Description:
+ Virual interface to sets a feature for the specified root hub port
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ 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
+EFIAPI
+UsbVirtualHcClearRootHubPortFeature (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to clears a feature for the specified root hub port
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ PortNumber - Specifies the root hub port whose feature
+ is requested to be cleared.
+ PortFeature - Indicates the feature selector associated with the
+ feature clear request.
+
+ Returns:
+
+ EFI_SUCCESS
+ The feature specified by PortFeature was cleared 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
+EFIAPI
+UsbVirtualHcControlTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to submits control transfer to a target USB device
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ DeviceSpeed - Indicates target device speed.
+ MaximumPacketLength - Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+ Request - A pointer to the USB device request that will be sent
+ to the USB device.
+ TransferDirection - Specifies the data direction for the transfer.
+ There are three values available, DataIn, DataOut
+ and NoData.
+ Data - A pointer to the buffer of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - Indicates the size, in bytes, of the data buffer
+ specified by Data.
+ TimeOut - Indicates the maximum time, in microseconds,
+ which the transfer is allowed to complete.
+ Translator - A pointr to the transaction translator data.
+ TransferResult - A pointer to the detailed result information generated
+ by this control transfer.
+
+ Returns:
+
+ EFI_SUCCESS
+ The control transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The control transfer could not be completed due to a lack of resources.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The control transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The control transfer failed due to host controller or device error.
+ Caller should check TranferResult for detailed error information.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcBulkTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
+ both for Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - The combination of an endpoint number and an
+ endpoint direction of the target USB device.
+ Each endpoint address supports data transfer in
+ one direction except the control endpoint
+ (whose default endpoint address is 0).
+ It is the caller's responsibility to make sure that
+ the EndPointAddress represents a bulk endpoint.
+ DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
+ and EFI_USB_SPEED_HIGH.
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+ DataBuffersNumber - Number of data buffers prepared for the transfer.
+ Data - Array of pointers to the buffers of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - When input, indicates the size, in bytes, of the data buffer
+ specified by Data. When output, indicates the actually
+ transferred data size.
+ DataToggle - A pointer to the data toggle value. On input, it indicates
+ the initial data toggle value the bulk transfer should adopt;
+ on output, it is updated to indicate the data toggle value
+ of the subsequent bulk transfer.
+ Translator - A pointr to the transaction translator data.
+ TimeOut - Indicates the maximum time, in microseconds, which the
+ transfer is allowed to complete.
+ TransferResult - A pointer to the detailed result information of the
+ bulk transfer.
+
+ Returns:
+
+ EFI_SUCCESS
+ The bulk transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The bulk transfer could not be submitted due to lack of resource.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The bulk transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The bulk transfer failed due to host controller or device error.
+ Caller should check TranferResult for detailed error information.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcAsyncInterruptTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE * UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN BOOLEAN IsNewTransfer,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN PollingInterval,
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
+ IN VOID *Context OPTIONAL
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to submits an asynchronous interrupt transfer to an
+ interrupt endpoint of a USB device for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - The combination of an endpoint number and an endpoint
+ direction of the target USB device. Each endpoint address
+ supports data transfer in one direction except the
+ control endpoint (whose default endpoint address is 0).
+ It is the caller's responsibility to make sure that
+ the EndPointAddress represents an interrupt endpoint.
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+ IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
+ the host and the target interrupt endpoint.
+ If FALSE, the specified asynchronous interrupt pipe
+ is canceled.
+ DataToggle - A pointer to the data toggle value. On input, it is valid
+ when IsNewTransfer is TRUE, and it indicates the initial
+ data toggle value the asynchronous interrupt transfer
+ should adopt.
+ On output, it is valid when IsNewTransfer is FALSE,
+ and it is updated to indicate the data toggle value of
+ the subsequent asynchronous interrupt transfer.
+ PollingInterval - Indicates the interval, in milliseconds, that the
+ asynchronous interrupt transfer is polled.
+ This parameter is required when IsNewTransfer is TRUE.
+ DataLength - Indicates the length of data to be received at the
+ rate specified by PollingInterval from the target
+ asynchronous interrupt endpoint. This parameter
+ is only required when IsNewTransfer is TRUE.
+ Translator - A pointr to the transaction translator data.
+ CallBackFunction - The Callback function.This function is called at the
+ rate specified by PollingInterval.This parameter is
+ only required when IsNewTransfer is TRUE.
+ Context - The context that is passed to the CallBackFunction.
+ - This is an optional parameter and may be NULL.
+
+ Returns:
+
+ EFI_SUCCESS
+ The asynchronous interrupt transfer request has been successfully
+ submitted or canceled.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_OUT_OF_RESOURCES
+ The request could not be completed due to a lack of resources.
+ EFI_DEVICE_ERROR
+ Can't read register
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcSyncInterruptTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
+ of a USB device for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - The combination of an endpoint number and an endpoint
+ direction of the target USB device. Each endpoint
+ address supports data transfer in one direction
+ except the control endpoint (whose default
+ endpoint address is 0). It is the caller's responsibility
+ to make sure that the EndPointAddress represents
+ an interrupt endpoint.
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint
+ is capable of sending or receiving.
+ Data - A pointer to the buffer of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - On input, the size, in bytes, of the data buffer specified
+ by Data. On output, the number of bytes transferred.
+ DataToggle - A pointer to the data toggle value. On input, it indicates
+ the initial data toggle value the synchronous interrupt
+ transfer should adopt;
+ on output, it is updated to indicate the data toggle value
+ of the subsequent synchronous interrupt transfer.
+ TimeOut - Indicates the maximum time, in microseconds, which the
+ transfer is allowed to complete.
+ Translator - A pointr to the transaction translator data.
+ TransferResult - A pointer to the detailed result information from
+ the synchronous interrupt transfer.
+
+ Returns:
+
+ EFI_SUCCESS
+ The synchronous interrupt transfer was completed successfully.
+ EFI_OUT_OF_RESOURCES
+ The synchronous interrupt transfer could not be submitted due
+ to lack of resource.
+ EFI_INVALID_PARAMETER
+ Some parameters are invalid.
+ EFI_TIMEOUT
+ The synchronous interrupt transfer failed due to timeout.
+ EFI_DEVICE_ERROR
+ The synchronous interrupt transfer failed due to host controller
+ or device error. Caller should check TranferResult for detailed
+ error information.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcIsochronousTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+/*++
+
+ Routine Description:
+
+ Virtual interface to submits isochronous transfer to a target USB device
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - End point address
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+ DataBuffersNumber - Number of data buffers prepared for the transfer.
+ Data - Array of pointers to the buffers of data that will be
+ transmitted to USB device or received from USB device.
+ DataLength - Indicates the size, in bytes, of the data buffer
+ specified by Data.
+ Translator - A pointr to the transaction translator data.
+ TransferResult - A pointer to the detailed result information generated
+ by this control transfer.
+
+ Returns:
+
+ EFI_UNSUPPORTED
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+UsbVirtualHcAsyncIsochronousTransfer (
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
+ IN VOID *Context
+ )
+/*++
+
+ Routine Description:
+
+ Vitual interface to submits Async isochronous transfer to a target USB device
+ for both Hc2 and Hc protocol.
+
+ Arguments:
+
+ UsbBusDev - A pointer to bus controller of the device.
+ DeviceAddress - Represents the address of the target device on the USB,
+ which is assigned during USB enumeration.
+ EndPointAddress - End point address
+ DeviceSpeed - Indicates device speed.
+ MaximumPacketLength - Indicates the maximum packet size that the
+ default control transfer endpoint is capable of
+ sending or receiving.
+ DataBuffersNumber - Number of data buffers prepared for the transfer.
+ Data - Array of pointers to the buffers of data that will be transmitted
+ to USB device or received from USB device.
+ DataLength - Indicates the size, in bytes, of the data buffer
+ specified by Data.
+ Translator - A pointr to the transaction translator data.
+ IsochronousCallBack - When the transfer complete, the call back function will be called
+ Context - Pass to the call back function as parameter
+
+ Returns:
+
+ EFI_UNSUPPORTED
+
+--*/
+;
#endif
diff --git a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c
index bd87c5ca2e..eb563b8e8b 100644
--- a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c
+++ b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbio.c
@@ -233,9 +233,9 @@ UsbControlTransfer (
--*/
{
USB_IO_CONTROLLER_DEVICE *UsbIoController;
- EFI_USB_HC_PROTOCOL *UsbHCInterface;
+
EFI_STATUS RetStatus;
- USB_IO_DEVICE *UsbIoDevice;
+ USB_IO_DEVICE *UsbIoDev;
UINT8 MaxPacketLength;
UINT32 TransferResult;
BOOLEAN Disconnected;
@@ -251,9 +251,9 @@ UsbControlTransfer (
// to perform other parameters checking
//
UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
- UsbIoDevice = UsbIoController->UsbDevice;
- UsbHCInterface = UsbIoDevice->BusController->UsbHCInterface;
- MaxPacketLength = UsbIoDevice->DeviceDescriptor.MaxPacketSize0;
+ UsbIoDev = UsbIoController->UsbDevice;
+
+ MaxPacketLength = UsbIoDev->DeviceDescriptor.MaxPacketSize0;
if (Request->Request == USB_DEV_CLEAR_FEATURE &&
@@ -268,24 +268,23 @@ UsbControlTransfer (
return EFI_DEVICE_ERROR;
}
}
-
-
-
//
// using HostController's ControlTransfer to complete the request
//
- RetStatus = UsbHCInterface->ControlTransfer (
- UsbHCInterface,
- UsbIoDevice->DeviceAddress,
- UsbIoDevice->IsSlowDevice,
- MaxPacketLength,
- Request,
- Direction,
- Data,
- &DataLength,
- (UINTN) Timeout,
- &TransferResult
- );
+ RetStatus = UsbVirtualHcControlTransfer (
+ UsbIoDev->BusController,
+ UsbIoDev->DeviceAddress,
+ UsbIoDev->DeviceSpeed,
+ MaxPacketLength,
+ Request,
+ Direction,
+ Data,
+ &DataLength,
+ (UINTN) Timeout,
+ UsbIoDev->Translator,
+ &TransferResult
+ );
+
*Status = TransferResult;
if (Request->Request == USB_DEV_CLEAR_FEATURE &&
@@ -346,18 +345,19 @@ UsbBulkTransfer (
--*/
{
USB_IO_DEVICE *UsbIoDev;
- UINT8 MaxPacketLength;
+ UINTN MaxPacketLength;
UINT8 DataToggle;
UINT8 OldToggle;
EFI_STATUS RetStatus;
- EFI_USB_HC_PROTOCOL *UsbHCInterface;
+
USB_IO_CONTROLLER_DEVICE *UsbIoController;
ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;
UINT32 TransferResult;
-
- UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
- UsbIoDev = UsbIoController->UsbDevice;
- UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;
+ UINT8 DataBuffersNumber;
+
+ DataBuffersNumber = 1;
+ UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
+ UsbIoDev = UsbIoController->UsbDevice;
//
// Parameters Checking
@@ -408,17 +408,20 @@ UsbBulkTransfer (
//
// using HostController's BulkTransfer to complete the request
//
- RetStatus = UsbHCInterface->BulkTransfer (
- UsbHCInterface,
- UsbIoDev->DeviceAddress,
- DeviceEndpoint,
- MaxPacketLength,
- Data,
- DataLength,
- &DataToggle,
- Timeout,
- &TransferResult
- );
+ RetStatus = UsbVirtualHcBulkTransfer (
+ UsbIoDev->BusController,
+ UsbIoDev->DeviceAddress,
+ DeviceEndpoint,
+ UsbIoDev->DeviceSpeed,
+ MaxPacketLength,
+ DataBuffersNumber,
+ &Data,
+ DataLength,
+ &DataToggle,
+ Timeout,
+ UsbIoDev->Translator,
+ &TransferResult
+ );
if (OldToggle != DataToggle) {
//
@@ -474,14 +477,13 @@ UsbSyncInterruptTransfer (
--*/
{
- USB_IO_DEVICE *UsbIoDev;
- UINT8 MaxPacketLength;
- UINT8 DataToggle;
- UINT8 OldToggle;
- EFI_STATUS RetStatus;
- EFI_USB_HC_PROTOCOL *UsbHCInterface;
- USB_IO_CONTROLLER_DEVICE *UsbIoController;
- ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;
+ USB_IO_DEVICE *UsbIoDev;
+ UINTN MaxPacketLength;
+ UINT8 DataToggle;
+ UINT8 OldToggle;
+ EFI_STATUS RetStatus;
+ USB_IO_CONTROLLER_DEVICE *UsbIoController;
+ ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;
//
// Parameters Checking
@@ -517,8 +519,6 @@ UsbSyncInterruptTransfer (
//
UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
UsbIoDev = UsbIoController->UsbDevice;
- UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;
-
GetDeviceEndPointMaxPacketLength (
This,
DeviceEndpoint,
@@ -535,18 +535,19 @@ UsbSyncInterruptTransfer (
//
// using HostController's SyncInterruptTransfer to complete the request
//
- RetStatus = UsbHCInterface->SyncInterruptTransfer (
- UsbHCInterface,
- UsbIoDev->DeviceAddress,
- DeviceEndpoint,
- UsbIoDev->IsSlowDevice,
- MaxPacketLength,
- Data,
- DataLength,
- &DataToggle,
- Timeout,
- Status
- );
+ RetStatus = UsbVirtualHcSyncInterruptTransfer (
+ UsbIoDev->BusController,
+ UsbIoDev->DeviceAddress,
+ DeviceEndpoint,
+ UsbIoDev->DeviceSpeed,
+ MaxPacketLength,
+ Data,
+ DataLength,
+ &DataToggle,
+ Timeout,
+ UsbIoDev->Translator,
+ Status
+ );
if (OldToggle != DataToggle) {
//
@@ -590,7 +591,7 @@ UsbAsyncInterruptTransfer (
the transfer is to be executed.
DataLength - Specifies the length, in bytes, of the data to be
received from the USB device.
- InterruptCallback - The Callback function. This function is called if
+ InterruptCallBack - The Callback function. This function is called if
the asynchronous interrupt transfer is completed.
Context - Passed to InterruptCallback
Returns:
@@ -600,13 +601,12 @@ UsbAsyncInterruptTransfer (
--*/
{
- USB_IO_DEVICE *UsbIoDev;
- UINT8 MaxPacketLength;
- UINT8 DataToggle;
- EFI_USB_HC_PROTOCOL *UsbHCInterface;
- EFI_STATUS RetStatus;
- USB_IO_CONTROLLER_DEVICE *UsbIoController;
- ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;
+ USB_IO_DEVICE *UsbIoDev;
+ UINTN MaxPacketLength;
+ UINT8 DataToggle;
+ EFI_STATUS RetStatus;
+ USB_IO_CONTROLLER_DEVICE *UsbIoController;
+ ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;
//
// Check endpoint
@@ -634,25 +634,25 @@ UsbAsyncInterruptTransfer (
UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
UsbIoDev = UsbIoController->UsbDevice;
- UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;
if (!IsNewTransfer) {
//
// Delete this transfer
//
- UsbHCInterface->AsyncInterruptTransfer (
- UsbHCInterface,
- UsbIoDev->DeviceAddress,
- DeviceEndpoint,
- UsbIoDev->IsSlowDevice,
- 0,
- FALSE,
- &DataToggle,
- PollingInterval,
- DataLength,
- NULL,
- NULL
- );
+ UsbVirtualHcAsyncInterruptTransfer (
+ UsbIoDev->BusController,
+ UsbIoDev->DeviceAddress,
+ DeviceEndpoint,
+ UsbIoDev->DeviceSpeed,
+ 0,
+ FALSE,
+ &DataToggle,
+ PollingInterval,
+ DataLength,
+ UsbIoDev->Translator,
+ NULL,
+ NULL
+ );
//
// We need to store the toggle value
@@ -678,19 +678,20 @@ UsbAsyncInterruptTransfer (
&DataToggle
);
- RetStatus = UsbHCInterface->AsyncInterruptTransfer (
- UsbHCInterface,
- UsbIoDev->DeviceAddress,
- DeviceEndpoint,
- UsbIoDev->IsSlowDevice,
- MaxPacketLength,
- TRUE,
- &DataToggle,
- PollingInterval,
- DataLength,
- InterruptCallBack,
- Context
- );
+ RetStatus = UsbVirtualHcAsyncInterruptTransfer (
+ UsbIoDev->BusController,
+ UsbIoDev->DeviceAddress,
+ DeviceEndpoint,
+ UsbIoDev->DeviceSpeed,
+ MaxPacketLength,
+ TRUE,
+ &DataToggle,
+ PollingInterval,
+ DataLength,
+ UsbIoDev->Translator,
+ InterruptCallBack,
+ Context
+ );
return RetStatus;
}
@@ -1070,6 +1071,7 @@ UsbGetStringDescriptor (
EFI_SUCCESS
EFI_NOT_FOUND
EFI_OUT_OF_RESOURCES
+ EFI_UNSUPPORTED
--*/
{
diff --git a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.c b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.c
index 07eb5805e9..e3380856bf 100644
--- a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.c
+++ b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbutil.c
@@ -35,10 +35,10 @@ IsPortConnect (
Tell if there is a device connected to that port according to
the Port Status.
- Parameters:
+ Arguments:
PortStatus - The status value of that port.
- Return Value:
+ Returns:
TRUE
FALSE
@@ -280,7 +280,6 @@ IsPortResetChange (
}
}
-
BOOLEAN
IsPortSuspendChange (
IN UINT16 PortChangeStatus
@@ -309,8 +308,7 @@ IsPortSuspendChange (
}
}
-
-INTERFACE_DESC_LIST_ENTRY*
+INTERFACE_DESC_LIST_ENTRY *
FindInterfaceListEntry (
IN EFI_USB_IO_PROTOCOL *This
)
@@ -329,7 +327,7 @@ FindInterfaceListEntry (
{
USB_IO_CONTROLLER_DEVICE *UsbIoController;
USB_IO_DEVICE *UsbIoDev;
- LIST_ENTRY *InterfaceListHead;
+ LIST_ENTRY *InterfaceListHead;
INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;
UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
@@ -367,8 +365,8 @@ FindEndPointListEntry (
Find EndPoint ListEntry.
Arguments:
- This - EFI_USB_IO_PROTOCOL
- EndpointAddr - Endpoint address.
+ This - EFI_USB_IO_PROTOCOL
+ EndPointAddress - Endpoint address.
Returns:
ENDPOINT_DESC_LIST_ENTRY pointer
@@ -471,7 +469,7 @@ VOID
GetDeviceEndPointMaxPacketLength (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT8 EndpointAddr,
- OUT UINT8 *MaxPacketLength
+ OUT UINTN *MaxPacketLength
)
/*++
@@ -498,7 +496,7 @@ GetDeviceEndPointMaxPacketLength (
return ;
}
- *MaxPacketLength = (UINT8) (EndpointListEntry->EndpointDescriptor.MaxPacketSize);
+ *MaxPacketLength = (UINTN) (EndpointListEntry->EndpointDescriptor.MaxPacketSize);
return ;
}
diff --git a/EdkModulePkg/EdkModulePkg.spd b/EdkModulePkg/EdkModulePkg.spd
index b6efc6934f..6c7da5bd22 100644
--- a/EdkModulePkg/EdkModulePkg.spd
+++ b/EdkModulePkg/EdkModulePkg.spd
@@ -394,6 +394,7 @@
<Filename>Bus/Pci/IdeBus/Dxe/idebus.msa</Filename>
<Filename>Bus/Pci/PciBus/Dxe/PciBus.msa</Filename>
<Filename>Bus/Pci/Uhci/Dxe/Uhci.msa</Filename>
+ <Filename>Bus/Pci/Ehci/Dxe/Ehci.msa</Filename>
<Filename>Bus/Pci/Undi/RuntimeDxe/Undi.msa</Filename>
<Filename>Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa</Filename>
<Filename>Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa</Filename>
@@ -440,6 +441,7 @@
<Filename>Universal/Console/Terminal/Dxe/Terminal.msa</Filename>
<Filename>Universal/DataHub/DataHub/Dxe/DataHub.msa</Filename>
<Filename>Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.msa</Filename>
+ <Filename>Universal/DevicePath/Dxe/DevicePath.msa</Filename>
<Filename>Universal/Debugger/Debugport/Dxe/DebugPort.msa</Filename>
<Filename>Universal/DebugSupport/Dxe/DebugSupport.msa</Filename>
<Filename>Universal/Disk/DiskIo/Dxe/DiskIo.msa</Filename>
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c
new file mode 100644
index 0000000000..79741a4615
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.c
@@ -0,0 +1,107 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DevicePathDriver.c
+
+Abstract:
+
+ Device Path Driver to produce DevPathUtilities Protocol, DevPathFromText Protocol
+ and DevPathToText Protocol.
+
+--*/
+
+#include <Uefi/UefiSpec.h>
+#include <Protocol/DevicePath.h>
+#include "DevicePath.h"
+
+DEVICE_PATH_DRIVER_PRIVATE_DATA mPrivateData;
+
+EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid = DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL;
+EFI_GUID mEfiDevicePathMessagingSASGuid = DEVICE_PATH_MESSAGING_SAS;
+
+STATIC EFI_DEVICE_PATH_UTILITIES_PROTOCOL mDevicePathUtilitiesProtocol = {
+ GetDevicePathSize,
+ DuplicateDevicePath,
+ AppendDevicePath,
+ AppendDeviceNode,
+ AppendDevicePathInstance,
+ GetNextDevicePathInstance,
+ IsDevicePathMultiInstance,
+ CreateDeviceNode
+};
+
+STATIC EFI_DEVICE_PATH_TO_TEXT_PROTOCOL mDevicePathToTextProtocol = {
+ ConvertDeviceNodeToText,
+ ConvertDevicePathToText
+};
+
+STATIC EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL mDevicePathFromTextProtocol = {
+ ConvertTextToDeviceNode,
+ ConvertTextToDevicePath
+};
+
+EFI_STATUS
+EFIAPI
+DevicePathEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+ Routine Description:
+ Entry point for EFI drivers.
+
+ Arguments:
+ ImageHandle - EFI_HANDLE
+ SystemTable - EFI_SYSTEM_TABLE
+
+ Returns:
+ EFI_SUCCESS
+ others
+
+--*/
+{
+ EFI_STATUS Status;
+
+ mPrivateData.Signature = DEVICE_PATH_DRIVER_SIGNATURE;
+
+ mPrivateData.DevicePathUtilities.GetDevicePathSize = GetDevicePathSize;
+ mPrivateData.DevicePathUtilities.DuplicateDevicePath = DuplicateDevicePath;
+ mPrivateData.DevicePathUtilities.AppendDevicePath = AppendDevicePath;
+ mPrivateData.DevicePathUtilities.AppendDeviceNode = AppendDeviceNode;
+ mPrivateData.DevicePathUtilities.AppendDevicePathInstance = AppendDevicePathInstance;
+ mPrivateData.DevicePathUtilities.GetNextDevicePathInstance = GetNextDevicePathInstance;
+ mPrivateData.DevicePathUtilities.IsDevicePathMultiInstance = IsDevicePathMultiInstance;
+ mPrivateData.DevicePathUtilities.CreateDeviceNode = CreateDeviceNode;
+
+ mPrivateData.DevicePathToText.ConvertDeviceNodeToText = ConvertDeviceNodeToText;
+ mPrivateData.DevicePathToText.ConvertDevicePathToText = ConvertDevicePathToText;
+
+ mPrivateData.DevicePathFromText.ConvertTextToDeviceNode = ConvertTextToDeviceNode;
+ mPrivateData.DevicePathFromText.ConvertTextToDevicePath = ConvertTextToDevicePath;
+
+ mPrivateData.Handle = NULL;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mPrivateData.Handle,
+ &gEfiDevicePathUtilitiesProtocolGuid,
+ &mPrivateData.DevicePathUtilities,
+ &gEfiDevicePathToTextProtocolGuid,
+ &mPrivateData.DevicePathToText,
+ &gEfiDevicePathFromTextProtocolGuid,
+ &mPrivateData.DevicePathFromText,
+ NULL
+ );
+
+ return Status;
+}
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h
new file mode 100644
index 0000000000..aa333453ea
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.h
@@ -0,0 +1,422 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DevicePathDriver.h
+
+Abstract:
+ Definition for Device Path Utilities driver
+
+--*/
+
+#ifndef _DEVICE_PATH_DRIVER_H
+#define _DEVICE_PATH_DRIVER_H
+
+extern EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid;
+extern EFI_GUID mEfiDevicePathMessagingSASGuid;
+
+#define DEVICE_PATH_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('D', 'P', 'D', 'V')
+
+typedef struct {
+
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ //
+ // Produced protocols
+ //
+ EFI_DEVICE_PATH_UTILITIES_PROTOCOL DevicePathUtilities;
+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL DevicePathFromText;
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL DevicePathToText;
+
+} DEVICE_PATH_DRIVER_PRIVATE_DATA;
+
+#define MAX_CHAR 480
+
+#define MIN_ALIGNMENT_SIZE sizeof(UINTN)
+#define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
+
+#define IS_COMMA(a) ((a) == L',')
+#define IS_HYPHEN(a) ((a) == L'-')
+#define IS_DOT(a) ((a) == L'.')
+#define IS_LEFT_PARENTH(a) ((a) == L'(')
+#define IS_RIGHT_PARENTH(a) ((a) == L')')
+#define IS_SLASH(a) ((a) == L'/')
+#define IS_NULL(a) ((a) == L'\0')
+
+#define DEVICE_NODE_END 1
+#define DEVICE_PATH_INSTANCE_END 2
+#define DEVICE_PATH_END 3
+
+#define SetDevicePathInstanceEndNode(a) { \
+ (a)->Type = END_DEVICE_PATH_TYPE; \
+ (a)->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; \
+ (a)->Length[0] = sizeof (EFI_DEVICE_PATH_PROTOCOL); \
+ (a)->Length[1] = 0; \
+ }
+
+//
+// Private Data structure
+//
+typedef struct {
+ CHAR16 *Str;
+ UINTN Len;
+ UINTN MaxLen;
+} POOL_PRINT;
+
+typedef struct {
+ UINT8 Type;
+ UINT8 SubType;
+ VOID (*Function) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+} DEVICE_PATH_TO_TEXT_TABLE;
+
+typedef struct {
+ CHAR16 *DevicePathNodeText;
+ EFI_DEVICE_PATH_PROTOCOL * (*Function) (CHAR16 *);
+} DEVICE_PATH_FROM_TEXT_TABLE;
+
+typedef struct {
+ BOOLEAN ClassExist;
+ UINT8 Class;
+ BOOLEAN SubClassExist;
+ UINT8 SubClass;
+} USB_CLASS_TEXT;
+
+#define USB_CLASS_AUDIO 1
+#define USB_CLASS_CDCCONTROL 2
+#define USB_CLASS_HID 3
+#define USB_CLASS_IMAGE 6
+#define USB_CLASS_PRINTER 7
+#define USB_CLASS_MASS_STORAGE 8
+#define USB_CLASS_HUB 9
+#define USB_CLASS_CDCDATA 10
+#define USB_CLASS_SMART_CARD 11
+#define USB_CLASS_VIDEO 14
+#define USB_CLASS_DIAGNOSTIC 220
+#define USB_CLASS_WIRELESS 224
+
+#define USB_CLASS_RESERVE 254
+#define USB_SUBCLASS_FW_UPDATE 1
+#define USB_SUBCLASS_IRDA_BRIDGE 2
+#define USB_SUBCLASS_TEST 3
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MEDIA_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 HID;
+ UINT32 UID;
+ UINT32 CID;
+ CHAR8 HidUidCidStr[3];
+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 NetworkProtocol;
+ UINT16 LoginOption;
+ UINT16 Reserved;
+ UINT16 TargetPortalGroupTag;
+ UINT64 Lun;
+ CHAR16 iSCSITargetName[1];
+} ISCSI_DEVICE_PATH_WITH_NAME;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEVICE_PATH_WITH_DATA;
+
+CHAR16 *
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+/*++
+
+ Routine Description:
+ Convert a device node to its text representation.
+
+ Arguments:
+ DeviceNode - Points to the device node to be converted.
+ DisplayOnly - If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ Returns:
+ A pointer - a pointer to the allocated text representation of the device node.
+ NULL - if DeviceNode is NULL or there was insufficient memory.
+
+--*/
+;
+
+CHAR16 *
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+/*++
+
+ Routine Description:
+ Convert a device path to its text representation.
+
+ Arguments:
+ DeviceNode - Points to the device path to be converted.
+ DisplayOnly - If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ Returns:
+ A pointer - a pointer to the allocated text representation of the device path.
+ NULL - if DeviceNode is NULL or there was insufficient memory.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ )
+/*++
+
+ Routine Description:
+ Convert text to the binary representation of a device node.
+
+ Arguments:
+ TextDeviceNode - TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ Returns:
+ A pointer - Pointer to the EFI device node.
+ NULL - if TextDeviceNode is NULL or there was insufficient memory.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ )
+/*++
+
+ Routine Description:
+ Convert text to the binary representation of a device path.
+
+ Arguments:
+ TextDevicePath - TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ Returns:
+ A pointer - Pointer to the allocated device path.
+ NULL - if TextDeviceNode is NULL or there was insufficient memory.
+
+--*/
+;
+
+UINTN
+GetDevicePathSize (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Returns the size of the device path, in bytes.
+
+ Arguments:
+ DevicePath - Points to the start of the EFI device path.
+
+ Returns:
+ Size - Size of the specified device path, in bytes, including the end-of-path tag.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Create a duplicate of the specified path.
+
+ Arguments:
+ DevicePath - Points to the source EFI device path.
+
+ Returns:
+ Pointer - A pointer to the duplicate device path.
+ NULL - Insufficient memory.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2
+ )
+/*++
+
+ Routine Description:
+ Create a new path by appending the second device path to the first.
+
+ Arguments:
+ Src1 - Points to the first device path. If NULL, then it is ignored.
+ Src2 - Points to the second device path. If NULL, then it is ignored.
+
+ Returns:
+ Pointer - A pointer to the newly created device path.
+ NULL - Memory could not be allocated
+ or either DevicePath or DeviceNode is NULL.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDeviceNode (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
+ )
+/*++
+
+ Routine Description:
+ Creates a new path by appending the device node to the device path.
+
+ Arguments:
+ DevicePath - Points to the device path.
+ DeviceNode - Points to the device node.
+
+ Returns:
+ Pointer - A pointer to the allocated device node.
+ NULL - Memory could not be allocated
+ or either DevicePath or DeviceNode is NULL.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ )
+/*++
+
+ Routine Description:
+ Creates a new path by appending the specified device path instance to the specified device path.
+
+ Arguments:
+ DevicePath - Points to the device path. If NULL, then ignored.
+ DevicePathInstance - Points to the device path instance.
+
+ Returns:
+ Pointer - A pointer to the newly created device path
+ NULL - Memory could not be allocated or DevicePathInstance is NULL.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance,
+ OUT UINTN *DevicePathInstanceSize
+ )
+/*++
+
+ Routine Description:
+ Creates a copy of the current device path instance and returns a pointer to the next device path instance.
+
+ Arguments:
+ DevicePathInstance - On input, this holds the pointer to the current device path
+ instance. On output, this holds the pointer to the next
+ device path instance or NULL if there are no more device
+ path instances in the device path.
+ DevicePathInstanceSize - On output, this holds the size of the device path instance,
+ in bytes or zero, if DevicePathInstance is zero.
+
+ Returns:
+ Pointer - A pointer to the copy of the current device path instance.
+ NULL - DevicePathInstace was NULL on entry or there was insufficient memory.
+
+--*/
+;
+
+BOOLEAN
+IsDevicePathMultiInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Returns whether a device path is multi-instance.
+
+ Arguments:
+ DevicePath - Points to the device path. If NULL, then ignored.
+
+ Returns:
+ TRUE - The device path has more than one instance
+ FALSE - The device path is empty or contains only a single instance.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ )
+/*++
+
+ Routine Description:
+ Creates a device node
+
+ Arguments:
+ NodeType - NodeType is the device node type (EFI_DEVICE_PATH.Type) for
+ the new device node.
+ NodeSubType - NodeSubType is the device node sub-type
+ EFI_DEVICE_PATH.SubType) for the new device node.
+ NodeLength - NodeLength is the length of the device node
+ (EFI_DEVICE_PATH.Length) for the new device node.
+
+ Returns:
+ Pointer - A pointer to the newly created device node.
+ NULL - NodeLength is less than
+ the size of the header or there was insufficient memory.
+
+--*/
+;
+
+#endif
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa
new file mode 100644
index 0000000000..20dd59848f
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePath.msa
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">
+
+ <MsaHeader>
+ <ModuleName>DevicePath</ModuleName>
+ <ModuleType>DXE_DRIVER</ModuleType>
+ <GuidValue>9B680FCE-AD6B-4F3A-B60B-F59899003443</GuidValue>
+ <Version>1.0</Version>
+ <Abstract>Component description file for Device Path Driver.</Abstract>
+ <Description>This driver is for DevicePathUtilities, DevicePahtToText and DevicePathFromText</Description>
+ <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>
+ <License>All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
+ </MsaHeader>
+ <ModuleDefinitions>
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
+ <BinaryModule>false</BinaryModule>
+ <OutputFileBasename>DevicePath</OutputFileBasename>
+ </ModuleDefinitions>
+ <LibraryClassDefinitions>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>DebugLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>PrintLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiDriverEntryPoint</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>BaseMemoryLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>MemoryAllocationLib</Keyword>
+ </LibraryClass>
+ <LibraryClass Usage="ALWAYS_CONSUMED">
+ <Keyword>UefiBootServicesTableLib</Keyword>
+ </LibraryClass>
+ </LibraryClassDefinitions>
+ <SourceFiles>
+ <Filename>DevicePath.c</Filename>
+ <Filename>DevicePath.h</Filename>
+ <Filename>DevicePathFromText.c</Filename>
+ <Filename>DevicePathToText.c</Filename>
+ <Filename>DevicePathUtilities.c</Filename>
+ </SourceFiles>
+ <PackageDependencies>
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Package PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>
+ </PackageDependencies>
+ <Protocols>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiDebugPortProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_CONSUMED">
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_PRODUCED">
+ <ProtocolCName>gEfiDevicePathUtilitiesProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_PRODUCED">
+ <ProtocolCName>gEfiDevicePathFromTextProtocolGuid</ProtocolCName>
+ </Protocol>
+ <Protocol Usage="ALWAYS_PRODUCED">
+ <ProtocolCName>gEfiDevicePathToTextProtocolGuid</ProtocolCName>
+ </Protocol>
+ </Protocols>
+ <Guids>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiPcAnsiGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiVT100PlusGuid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiVT100Guid</GuidCName>
+ </GuidCNames>
+ <GuidCNames Usage="ALWAYS_CONSUMED">
+ <GuidCName>gEfiVTUTF8Guid</GuidCName>
+ </GuidCNames>
+ </Guids>
+ <Externs>
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
+ <Specification>EDK_RELEASE_VERSION 0x00090000</Specification>
+ <Extern>
+ <ModuleEntryPoint>DevicePathEntryPoint</ModuleEntryPoint>
+ </Extern>
+ </Externs>
+</ModuleSurfaceArea>
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c
new file mode 100644
index 0000000000..e0864da6f0
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathFromText.c
@@ -0,0 +1,2434 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DevicePathFromText.c
+
+Abstract:
+
+ DevicePathFromText protocol as defined in the UEFI 2.0 specification.
+
+--*/
+
+#include <protocol/DevicePathFromText.h>
+#include "DevicePath.h"
+
+CHAR16 *
+StrDuplicate (
+ IN CONST CHAR16 *Src
+ )
+/*++
+
+ Routine Description:
+ Duplicate a string
+
+ Arguments:
+ Src - Source string
+
+ Returns:
+ Duplicated string
+
+--*/
+{
+ UINTN Length;
+ CHAR16 *ReturnStr;
+
+ Length = StrLen ((CHAR16 *) Src);
+
+ ReturnStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), (VOID *) Src);
+
+ return ReturnStr;
+}
+
+CHAR16 *
+GetParamByNodeName (
+ IN CHAR16 *Str,
+ IN CHAR16 *NodeName
+ )
+/*++
+
+ Routine Description:
+ Get parameter in a pair of parentheses follow the given node name.
+ For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1".
+
+ Arguments:
+ Str - Device Path Text
+ NodeName - Name of the node
+
+ Returns:
+ Parameter text for the node
+
+--*/
+{
+ CHAR16 *ParamStr;
+ CHAR16 *StrPointer;
+ UINTN NodeNameLength;
+ UINTN ParameterLength;
+
+ //
+ // Check whether the node name matchs
+ //
+ NodeNameLength = StrLen (NodeName);
+ if (CompareMem (Str, NodeName, NodeNameLength * sizeof (CHAR16)) != 0) {
+ return NULL;
+ }
+
+ ParamStr = Str + NodeNameLength;
+ if (!IS_LEFT_PARENTH (*ParamStr)) {
+ return NULL;
+ }
+
+ //
+ // Skip the found '(' and find first occurrence of ')'
+ //
+ ParamStr++;
+ ParameterLength = 0;
+ StrPointer = ParamStr;
+ while (!IS_NULL (*StrPointer)) {
+ if (IS_RIGHT_PARENTH (*StrPointer)) {
+ break;
+ }
+ StrPointer++;
+ ParameterLength++;
+ }
+ if (IS_NULL (*StrPointer)) {
+ //
+ // ')' not found
+ //
+ return NULL;
+ }
+
+ ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr);
+ if (ParamStr == NULL) {
+ return NULL;
+ }
+ //
+ // Terminate the parameter string
+ //
+ ParamStr[ParameterLength] = L'\0';
+
+ return ParamStr;
+}
+
+CHAR16 *
+SplitStr (
+ IN OUT CHAR16 **List,
+ IN CHAR16 Separator
+ )
+/*++
+
+ Routine Description:
+ Get current sub-string from a string list, before return
+ the list header is moved to next sub-string. The sub-string is separated
+ by the specified character. For example, the separator is ',', the string
+ list is "2,0,3", it returns "2", the remain list move to "2,3"
+
+ Arguments:
+ List - A string list separated by the specified separator
+ Separator - The separator character
+
+ Returns:
+ pointer - The current sub-string
+
+--*/
+{
+ CHAR16 *Str;
+ CHAR16 *ReturnStr;
+
+ Str = *List;
+ ReturnStr = Str;
+
+ if (IS_NULL (*Str)) {
+ return ReturnStr;
+ }
+
+ //
+ // Find first occurrence of the separator
+ //
+ while (!IS_NULL (*Str)) {
+ if (*Str == Separator) {
+ break;
+ }
+ Str++;
+ }
+
+ if (*Str == Separator) {
+ //
+ // Find a sub-string, terminate it
+ //
+ *Str = L'\0';
+ Str++;
+ }
+
+ //
+ // Move to next sub-string
+ //
+ *List = Str;
+
+ return ReturnStr;
+}
+
+CHAR16 *
+GetNextParamStr (
+ IN OUT CHAR16 **List
+ )
+{
+ //
+ // The separator is comma
+ //
+ return SplitStr (List, L',');
+}
+
+CHAR16 *
+GetNextDeviceNodeStr (
+ IN OUT CHAR16 **DevicePath,
+ OUT BOOLEAN *IsInstanceEnd
+ )
+/*++
+
+ Routine Description:
+ Get one device node from entire device path text.
+
+ Arguments:
+ Str - The entire device path text string
+ IsInstanceEnd - This node is the end of a device path instance
+
+ Returns:
+ a pointer - A device node text
+ NULL - No more device node available
+
+--*/
+{
+ CHAR16 *Str;
+ CHAR16 *ReturnStr;
+ UINTN ParenthesesStack;
+
+ Str = *DevicePath;
+ if (IS_NULL (*Str)) {
+ return NULL;
+ }
+
+ //
+ // Skip the leading '/', '(', ')' and ','
+ //
+ while (!IS_NULL (*Str)) {
+ if (!IS_SLASH (*Str) &&
+ !IS_COMMA (*Str) &&
+ !IS_LEFT_PARENTH (*Str) &&
+ !IS_RIGHT_PARENTH (*Str)) {
+ break;
+ }
+ Str++;
+ }
+
+ ReturnStr = Str;
+
+ //
+ // Scan for the separator of this device node, '/' or ','
+ //
+ ParenthesesStack = 0;
+ while (!IS_NULL (*Str)) {
+ if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) {
+ break;
+ }
+
+ if (IS_LEFT_PARENTH (*Str)) {
+ ParenthesesStack++;
+ } else if (IS_RIGHT_PARENTH (*Str)) {
+ ParenthesesStack--;
+ }
+
+ Str++;
+ }
+
+ if (ParenthesesStack != 0) {
+ //
+ // The '(' doesn't pair with ')', invalid device path text
+ //
+ return NULL;
+ }
+
+ if (IS_COMMA (*Str)) {
+ *IsInstanceEnd = TRUE;
+ *Str = L'\0';
+ Str++;
+ } else {
+ *IsInstanceEnd = FALSE;
+ if (!IS_NULL (*Str)) {
+ *Str = L'\0';
+ Str++;
+ }
+ }
+
+ *DevicePath = Str;
+
+ return ReturnStr;
+}
+
+BOOLEAN
+IsHexDigit (
+ OUT UINT8 *Digit,
+ IN CHAR16 Char
+ )
+/*++
+
+ Routine Description:
+ Determines if a Unicode character is a hexadecimal digit.
+ The test is case insensitive.
+
+ Arguments:
+ Digit - Pointer to byte that receives the value of the hex character.
+ Char - Unicode character to test.
+
+ Returns:
+ TRUE - If the character is a hexadecimal digit.
+ FALSE - Otherwise.
+
+--*/
+{
+ if ((Char >= L'0') && (Char <= L'9')) {
+ *Digit = (UINT8) (Char - L'0');
+ return TRUE;
+ }
+
+ if ((Char >= L'A') && (Char <= L'F')) {
+ *Digit = (UINT8) (Char - L'A' + 0x0A);
+ return TRUE;
+ }
+
+ if ((Char >= L'a') && (Char <= L'f')) {
+ *Digit = (UINT8) (Char - L'a' + 0x0A);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+CHAR16
+NibbleToHexChar (
+ IN UINT8 Nibble
+ )
+/*++
+
+ Routine Description:
+ Converts the low nibble of a byte to hex unicode character.
+
+ Arguments:
+ Nibble - lower nibble of a byte.
+
+ Returns:
+ Hex unicode character.
+
+--*/
+{
+ Nibble &= 0x0F;
+ if (Nibble <= 0x9) {
+ return (CHAR16)(Nibble + L'0');
+ }
+
+ return (CHAR16)(Nibble - 0xA + L'A');
+}
+
+EFI_STATUS
+HexStringToBuf (
+ IN OUT UINT8 *Buf,
+ IN OUT UINTN *Len,
+ IN CHAR16 *Str,
+ OUT UINTN *ConvertedStrLen OPTIONAL
+ )
+/*++
+
+ Routine Description:
+ Converts Unicode string to binary buffer.
+ The conversion may be partial.
+ The first character in the string that is not hex digit stops the conversion.
+ At a minimum, any blob of data could be represented as a hex string.
+
+ Arguments:
+ Buf - Pointer to buffer that receives the data.
+ Len - Length in bytes of the buffer to hold converted data.
+ If routine return with EFI_SUCCESS, containing length of converted data.
+ If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
+ Str - String to be converted from.
+ ConvertedStrLen - Length of the Hex String consumed.
+
+ Returns:
+ EFI_SUCCESS: Routine Success.
+ EFI_BUFFER_TOO_SMALL: The buffer is too small to hold converted data.
+ EFI_
+
+--*/
+{
+ UINTN HexCnt;
+ UINTN Idx;
+ UINTN BufferLength;
+ UINT8 Digit;
+ UINT8 Byte;
+
+ //
+ // Find out how many hex characters the string has.
+ //
+ for (Idx = 0, HexCnt = 0; IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++);
+
+ if (HexCnt == 0) {
+ *Len = 0;
+ return EFI_SUCCESS;
+ }
+ //
+ // Two Unicode characters make up 1 buffer byte. Round up.
+ //
+ BufferLength = (HexCnt + 1) / 2;
+
+ //
+ // Test if buffer is passed enough.
+ //
+ if (BufferLength > (*Len)) {
+ *Len = BufferLength;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Len = BufferLength;
+
+ for (Idx = 0; Idx < HexCnt; Idx++) {
+
+ IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]);
+
+ //
+ // For odd charaters, write the lower nibble for each buffer byte,
+ // and for even characters, the upper nibble.
+ //
+ if ((Idx & 1) == 0) {
+ Byte = Digit;
+ } else {
+ Byte = Buf[Idx / 2];
+ Byte &= 0x0F;
+ Byte |= Digit << 4;
+ }
+
+ Buf[Idx / 2] = Byte;
+ }
+
+ if (ConvertedStrLen != NULL) {
+ *ConvertedStrLen = HexCnt;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+BufToHexString (
+ IN OUT CHAR16 *Str,
+ IN OUT UINTN *HexStringBufferLength,
+ IN UINT8 *Buf,
+ IN UINTN Len
+ )
+/*++
+
+ Routine Description:
+ Converts binary buffer to Unicode string.
+ At a minimum, any blob of data could be represented as a hex string.
+
+ Arguments:
+ Str - Pointer to the string.
+ HexStringBufferLength - Length in bytes of buffer to hold the hex string. Includes tailing '\0' character.
+ If routine return with EFI_SUCCESS, containing length of hex string buffer.
+ If routine return with EFI_BUFFER_TOO_SMALL, containg length of hex string buffer desired.
+ Buf - Buffer to be converted from.
+ Len - Length in bytes of the buffer to be converted.
+
+ Returns:
+ EFI_SUCCESS: Routine success.
+ EFI_BUFFER_TOO_SMALL: The hex string buffer is too small.
+
+--*/
+{
+ UINTN Idx;
+ UINT8 Byte;
+ UINTN StrLen;
+
+ //
+ // Make sure string is either passed or allocate enough.
+ // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer.
+ // Plus the Unicode termination character.
+ //
+ StrLen = Len * 2;
+ if (StrLen > ((*HexStringBufferLength) - 1)) {
+ *HexStringBufferLength = StrLen + 1;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *HexStringBufferLength = StrLen + 1;
+ //
+ // Ends the string.
+ //
+ Str[StrLen] = L'\0';
+
+ for (Idx = 0; Idx < Len; Idx++) {
+
+ Byte = Buf[Idx];
+ Str[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte);
+ Str[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4));
+ }
+
+ return EFI_SUCCESS;
+}
+
+CHAR16 *
+TrimHexStr (
+ IN CHAR16 *Str
+ )
+/*++
+
+ Routine Description:
+ Skip the leading white space and '0x' or '0X' of a hex string
+
+ Arguments:
+ Str - The hex string
+
+ Returns:
+
+--*/
+{
+ //
+ // skip preceeding white space
+ //
+ while (*Str && *Str == ' ') {
+ Str += 1;
+ }
+ //
+ // skip preceeding zeros
+ //
+ while (*Str && *Str == '0') {
+ Str += 1;
+ }
+ //
+ // skip preceeding white space
+ //
+ if (*Str && (*Str == 'x' || *Str == 'X')) {
+ Str += 1;
+ }
+
+ return Str;
+}
+
+UINTN
+Xtoi (
+ IN CHAR16 *Str
+ )
+/*++
+
+Routine Description:
+
+ Convert hex string to uint
+
+Arguments:
+
+ Str - The string
+
+Returns:
+
+--*/
+{
+ UINTN Rvalue;
+ UINTN Length;
+
+ ASSERT (Str != NULL);
+
+ //
+ // convert hex digits
+ //
+ Rvalue = 0;
+ Length = sizeof (UINTN);
+ HexStringToBuf ((UINT8 *) &Rvalue, &Length, TrimHexStr (Str), NULL);
+
+ return Rvalue;
+}
+
+VOID
+Xtoi64 (
+ IN CHAR16 *Str,
+ IN UINT64 *Data
+ )
+/*++
+
+Routine Description:
+
+ Convert hex string to 64 bit data.
+
+Arguments:
+
+ Str - The string
+
+Returns:
+
+--*/
+{
+ UINTN Length;
+
+ Length = sizeof (UINT64);
+ HexStringToBuf ((UINT8 *) Data, &Length, TrimHexStr (Str), NULL);
+}
+
+UINTN
+Atoi (
+ IN CHAR16 *str
+ )
+/*++
+
+Routine Description:
+
+ Convert decimal string to uint
+
+Arguments:
+
+ Str - The string
+
+Returns:
+
+--*/
+{
+ UINTN Rvalue;
+ CHAR16 Char;
+ UINTN High;
+ UINTN Low;
+
+ ASSERT (str != NULL);
+
+ High = (UINTN) -1 / 10;
+ Low = (UINTN) -1 % 10;
+ //
+ // skip preceeding white space
+ //
+ while (*str && *str == ' ') {
+ str += 1;
+ }
+ //
+ // convert digits
+ //
+ Rvalue = 0;
+ Char = *(str++);
+ while (Char) {
+ if (Char >= '0' && Char <= '9') {
+ if (Rvalue > High || Rvalue == High && Char - '0' > (INTN) Low) {
+ return (UINTN) -1;
+ }
+
+ Rvalue = (Rvalue * 10) + Char - '0';
+ } else {
+ break;
+ }
+
+ Char = *(str++);
+ }
+
+ return Rvalue;
+}
+
+EFI_STATUS
+StrToBuf (
+ OUT UINT8 *Buf,
+ IN UINTN BufferLength,
+ IN CHAR16 *Str
+ )
+{
+ UINTN Index;
+ UINTN StrLength;
+ UINT8 Digit;
+ UINT8 Byte;
+
+ //
+ // Two hex char make up one byte
+ //
+ StrLength = BufferLength * sizeof (CHAR16);
+
+ for(Index = 0; Index < StrLength; Index++, Str++) {
+
+ IsHexDigit (&Digit, *Str);
+
+ //
+ // For odd charaters, write the upper nibble for each buffer byte,
+ // and for even characters, the lower nibble.
+ //
+ if ((Index & 1) == 0) {
+ Byte = Digit << 4;
+ } else {
+ Byte = Buf[Index / 2];
+ Byte &= 0xF0;
+ Byte |= Digit;
+ }
+
+ Buf[Index / 2] = Byte;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+StrToGuid (
+ IN CHAR16 *Str,
+ OUT EFI_GUID *Guid
+ )
+{
+ UINTN BufferLength;
+ UINTN ConvertedStrLen;
+ EFI_STATUS Status;
+
+ BufferLength = sizeof (Guid->Data1);
+ Status = HexStringToBuf ((UINT8 *) &Guid->Data1, &BufferLength, Str, &ConvertedStrLen);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Str += ConvertedStrLen;
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ BufferLength = sizeof (Guid->Data2);
+ Status = HexStringToBuf ((UINT8 *) &Guid->Data2, &BufferLength, Str, &ConvertedStrLen);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Str += ConvertedStrLen;
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ BufferLength = sizeof (Guid->Data3);
+ Status = HexStringToBuf ((UINT8 *) &Guid->Data3, &BufferLength, Str, &ConvertedStrLen);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Str += ConvertedStrLen;
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ StrToBuf (&Guid->Data4[0], 2, Str);
+ //
+ // Skip 2 byte hex chars
+ //
+ Str += 2 * 2;
+
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ StrToBuf (&Guid->Data4[2], 6, Str);
+
+ return EFI_SUCCESS;
+}
+
+VOID
+StrToIPv4Addr (
+ IN OUT CHAR16 **Str,
+ OUT EFI_IPv4_ADDRESS *IPv4Addr
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < 4; Index++) {
+ IPv4Addr->Addr[Index] = (UINT8) Atoi (SplitStr (Str, L'.'));
+ }
+}
+
+VOID
+StrToIPv6Addr (
+ IN OUT CHAR16 **Str,
+ OUT EFI_IPv6_ADDRESS *IPv6Addr
+ )
+{
+ UINTN Index;
+ UINT16 Data;
+
+ for (Index = 0; Index < 8; Index++) {
+ Data = (UINT16) Xtoi (SplitStr (Str, L':'));
+ IPv6Addr->Addr[Index * 2] = (UINT8) (Data >> 8);
+ IPv6Addr->Addr[Index * 2 + 1] = (UINT8) (Data & 0xff);
+ }
+}
+
+VOID
+StrToAscii (
+ IN CHAR16 *Str,
+ IN OUT CHAR8 **AsciiStr
+ )
+{
+ CHAR8 *Dest;
+
+ Dest = *AsciiStr;
+ while (!IS_NULL (*Str)) {
+ *(Dest++) = (CHAR8) *(Str++);
+ }
+ *Dest = 0;
+
+ //
+ // Return the string next to it
+ //
+ *AsciiStr = Dest + 1;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPci (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionStr;
+ CHAR16 *DeviceStr;
+ PCI_DEVICE_PATH *Pci;
+
+ FunctionStr = GetNextParamStr (&TextDeviceNode);
+ DeviceStr = GetNextParamStr (&TextDeviceNode);
+ Pci = (PCI_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCI_DP,
+ sizeof (PCI_DEVICE_PATH)
+ );
+
+ Pci->Function = (UINT8) Xtoi (FunctionStr);
+ Pci->Device = (UINT8) Xtoi (DeviceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pci;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcCard (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionNumberStr;
+ PCCARD_DEVICE_PATH *Pccard;
+
+ FunctionNumberStr = GetNextParamStr (&TextDeviceNode);
+ Pccard = (PCCARD_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCCARD_DP,
+ sizeof (PCCARD_DEVICE_PATH)
+ );
+
+ Pccard->FunctionNumber = (UINT8) Xtoi (FunctionNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pccard;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMemoryMapped (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddressStr;
+ CHAR16 *EndingAddressStr;
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ StartingAddressStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddressStr = GetNextParamStr (&TextDeviceNode);
+ MemMap = (MEMMAP_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ sizeof (MEMMAP_DEVICE_PATH)
+ );
+
+ MemMap->MemoryType = 0;
+
+ Xtoi64 (StartingAddressStr, &MemMap->StartingAddress);
+ Xtoi64 (EndingAddressStr, &MemMap->EndingAddress);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MemMap;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextVendor (
+ IN CHAR16 *TextDeviceNode,
+ IN UINT8 Type,
+ IN UINT8 SubType
+ )
+{
+ CHAR16 *GuidStr;
+ CHAR16 *DataStr;
+ UINTN Length;
+ VENDOR_DEVICE_PATH *Vendor;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+
+ DataStr = GetNextParamStr (&TextDeviceNode);
+ Length = StrLen (DataStr);
+ //
+ // Two hex characters make up 1 buffer byte
+ //
+ Length = (Length + 1) / 2;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ Type,
+ SubType,
+ sizeof (VENDOR_DEVICE_PATH) + (UINT16) Length
+ );
+
+ StrToGuid (GuidStr, &Vendor->Guid);
+ StrToBuf (((UINT8 *) Vendor) + sizeof (VENDOR_DEVICE_PATH), Length, DataStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenHw (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP
+ );
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCtrl (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *ControllerStr;
+ CONTROLLER_DEVICE_PATH *Controller;
+
+ ControllerStr = GetNextParamStr (&TextDeviceNode);
+ Controller = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_CONTROLLER_DP,
+ sizeof (CONTROLLER_DEVICE_PATH)
+ );
+ Controller->ControllerNumber = (UINT32) Xtoi (ControllerStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Controller;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ if ((HIDStr[0] == L'P') && (HIDStr[1] == L'N') && (HIDStr[2] == L'P')) {
+ HIDStr += 3;
+ }
+
+ Acpi->HID = EISA_PNP_ID (Xtoi (HIDStr));
+ Acpi->UID = (UINT32) Xtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextAcpi (
+ IN CHAR16 *TextDeviceNode,
+ IN UINT32 Hid
+ )
+{
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ Acpi->HID = Hid;
+ Acpi->UID = (UINT32) Xtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPciRoot (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a0341d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFloppy (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x060441d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextKeyboard (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x030141d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSerial (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x050141d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextParallelPort (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x040141d0);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiEx (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDStr;
+ CHAR16 *HIDSTRStr;
+ CHAR16 *CIDSTRStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *AcpiExt;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ HIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ CIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ Length = sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) +
+ (UINT16) StrLen (HIDSTRStr) + 1 +
+ (UINT16) StrLen (UIDSTRStr) + 1 +
+ (UINT16) StrLen (CIDSTRStr) + 1;
+ AcpiExt = (ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ if ((HIDStr[0] == L'P') && (HIDStr[1] == L'N') && (HIDStr[2] == L'P')) {
+ HIDStr += 3;
+ AcpiExt->HID = EISA_PNP_ID (Xtoi (HIDStr));
+ } else {
+ AcpiExt->HID = (UINT32) Xtoi (HIDStr);
+ }
+
+ AcpiExt->UID = (UINT32) Xtoi (UIDStr);
+ AcpiExt->CID = (UINT32) Xtoi (CIDStr);
+
+ AsciiStr = AcpiExt->HidUidCidStr;
+ StrToAscii (HIDSTRStr, &AsciiStr);
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ StrToAscii (CIDSTRStr, &AsciiStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiExt;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiExp (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *AcpiExt;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ Length = sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + (UINT16) StrLen (UIDSTRStr) + 3;
+ AcpiExt = (ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ if ((HIDStr[0] == L'P') && (HIDStr[1] == L'N') && (HIDStr[2] == L'P')) {
+ HIDStr += 3;
+ AcpiExt->HID = EISA_PNP_ID (Xtoi (HIDStr));
+ } else {
+ AcpiExt->HID = (UINT32) Xtoi (HIDStr);
+ }
+
+ AcpiExt->UID = 0;
+ AcpiExt->CID = (UINT32) Xtoi (CIDStr);
+
+ AsciiStr = AcpiExt->HidUidCidStr;
+ //
+ // HID string is NULL
+ //
+ *AsciiStr = 0;
+ //
+ // Convert UID string
+ //
+ AsciiStr++;
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ //
+ // CID string is NULL
+ //
+ *AsciiStr = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiExt;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAta (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PrimarySecondaryStr;
+ CHAR16 *SlaveMasterStr;
+ CHAR16 *LunStr;
+ ATAPI_DEVICE_PATH *Atapi;
+
+ Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ATAPI_DP,
+ sizeof (ATAPI_DEVICE_PATH)
+ );
+
+ PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode);
+ SlaveMasterStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+
+ Atapi->PrimarySecondary = (StrCmp (PrimarySecondaryStr, L"Primary") == 0) ? (UINT8) 0 : (UINT8) 1;
+ Atapi->SlaveMaster = (StrCmp (SlaveMasterStr, L"Master") == 0) ? (UINT8) 0 : (UINT8) 1;
+ Atapi->Lun = (UINT16) Xtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Atapi;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextScsi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PunStr;
+ CHAR16 *LunStr;
+ SCSI_DEVICE_PATH *Scsi;
+
+ PunStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Scsi = (SCSI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SCSI_DP,
+ sizeof (SCSI_DEVICE_PATH)
+ );
+
+ Scsi->Pun = (UINT16) Xtoi (PunStr);
+ Scsi->Lun = (UINT16) Xtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Scsi;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibre (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *WWNStr;
+ CHAR16 *LunStr;
+ FIBRECHANNEL_DEVICE_PATH *Fibre;
+
+ WWNStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Fibre = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_FIBRECHANNEL_DP,
+ sizeof (FIBRECHANNEL_DEVICE_PATH)
+ );
+
+ Fibre->Reserved = 0;
+ Xtoi64 (WWNStr, &Fibre->WWN);
+ Xtoi64 (LunStr, &Fibre->Lun);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Fibre;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromText1394 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ F1394_DEVICE_PATH *F1394;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ F1394 = (F1394_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_1394_DP,
+ sizeof (F1394_DEVICE_PATH)
+ );
+
+ F1394->Reserved = 0;
+ Xtoi64 (GuidStr, &F1394->Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) F1394;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsb (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PortStr;
+ CHAR16 *InterfaceStr;
+ USB_DEVICE_PATH *Usb;
+
+ PortStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceStr = GetNextParamStr (&TextDeviceNode);
+ Usb = (USB_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_DP,
+ sizeof (USB_DEVICE_PATH)
+ );
+
+ Usb->ParentPortNumber = (UINT8) Xtoi (PortStr);
+ Usb->InterfaceNumber = (UINT8) Xtoi (InterfaceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Usb;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextI2O (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TIDStr;
+ I2O_DEVICE_PATH *I2O;
+
+ TIDStr = GetNextParamStr (&TextDeviceNode);
+ I2O = (I2O_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_I2O_DP,
+ sizeof (I2O_DEVICE_PATH)
+ );
+
+ I2O->Tid = (UINT32) Xtoi (TIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) I2O;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextInfiniband (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FlagsStr;
+ CHAR16 *GuidStr;
+ CHAR16 *SidStr;
+ CHAR16 *TidStr;
+ CHAR16 *DidStr;
+ EFI_GUID PortGid;
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ FlagsStr = GetNextParamStr (&TextDeviceNode);
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ SidStr = GetNextParamStr (&TextDeviceNode);
+ TidStr = GetNextParamStr (&TextDeviceNode);
+ DidStr = GetNextParamStr (&TextDeviceNode);
+ InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_INFINIBAND_DP,
+ sizeof (INFINIBAND_DEVICE_PATH)
+ );
+
+ InfiniBand->ResourceFlags = (UINT32) Xtoi (FlagsStr);
+ StrToGuid (GuidStr, &PortGid);
+ CopyMem (InfiniBand->PortGid, &PortGid, sizeof (EFI_GUID));
+ Xtoi64 (SidStr, &InfiniBand->ServiceId);
+ Xtoi64 (TidStr, &InfiniBand->TargetPortId);
+ Xtoi64 (DidStr, &InfiniBand->DeviceId);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMsg (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP
+ );
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenPcAnsi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ Vendor->Guid = gEfiPcAnsiGuid;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ Vendor->Guid = gEfiVT100Guid;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100Plus (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ Vendor->Guid = gEfiVT100PlusGuid;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenUtf8 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ Vendor->Guid = gEfiVTUTF8Guid;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUartFlowCtrl (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *ValueStr;
+ UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
+
+ ValueStr = GetNextParamStr (&TextDeviceNode);
+ UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (UART_FLOW_CONTROL_DEVICE_PATH)
+ );
+
+ UartFlowControl->Guid = mEfiDevicePathMessagingUartFlowControlGuid;
+ if (StrCmp (ValueStr, L"XonXoff") == 0) {
+ UartFlowControl->FlowControlMap = 2;
+ } else if (StrCmp (ValueStr, L"Hardware") == 0) {
+ UartFlowControl->FlowControlMap = 1;
+ } else {
+ UartFlowControl->FlowControlMap = 0;
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSAS (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *LunStr;
+ CHAR16 *RTPStr;
+ CHAR16 *SASSATAStr;
+ CHAR16 *LocationStr;
+ CHAR16 *ConnectStr;
+ CHAR16 *DriveBayStr;
+ CHAR16 *ReservedStr;
+ UINT16 Info;
+ SAS_DEVICE_PATH *Sas;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ RTPStr = GetNextParamStr (&TextDeviceNode);
+ SASSATAStr = GetNextParamStr (&TextDeviceNode);
+ LocationStr = GetNextParamStr (&TextDeviceNode);
+ ConnectStr = GetNextParamStr (&TextDeviceNode);
+ DriveBayStr = GetNextParamStr (&TextDeviceNode);
+ ReservedStr = GetNextParamStr (&TextDeviceNode);
+ Info = 0x0000;
+ Sas = (SAS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (SAS_DEVICE_PATH)
+ );
+
+ Sas->Guid = mEfiDevicePathMessagingSASGuid;
+ Xtoi64 (AddressStr, &Sas->SasAddress);
+ Xtoi64 (LunStr, &Sas->Lun);
+ Sas->RelativeTargetPort = (UINT16) Xtoi (RTPStr);
+ if (StrCmp (SASSATAStr, L"NoTopology") == 0)
+ ;
+ else {
+ if (StrCmp (DriveBayStr, L"0") == 0) {
+ Info |= 0x0001;
+ } else {
+ Info |= 0x0002;
+ Info |= (Xtoi (DriveBayStr) << 8);
+ }
+
+ if (StrCmp (SASSATAStr, L"SATA") == 0) {
+ Info |= 0x0010;
+ }
+
+ if (StrCmp (LocationStr, L"External") == 0) {
+ Info |= 0x0020;
+ }
+
+ if (StrCmp (ConnectStr, L"Expanded") == 0) {
+ Info |= 0x0040;
+ }
+ }
+
+ Sas->DeviceTopology = Info;
+ Sas->Reserved = (UINT32) Xtoi (ReservedStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sas;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextDebugPort (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEFINED_MESSAGING_DEVICE_PATH *Vend;
+
+ Vend = (VENDOR_DEFINED_MESSAGING_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEFINED_MESSAGING_DEVICE_PATH)
+ );
+
+ Vend->Guid = gEfiDebugPortProtocolGuid;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vend;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMAC (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *IfTypeStr;
+ UINTN Length;
+ MAC_ADDR_DEVICE_PATH *MAC;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ IfTypeStr = GetNextParamStr (&TextDeviceNode);
+ MAC = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_MAC_ADDR_DP,
+ sizeof (MAC_ADDR_DEVICE_PATH)
+ );
+
+ MAC->IfType = (UINT8) Xtoi (IfTypeStr);
+
+ Length = sizeof (EFI_MAC_ADDRESS);
+ StrToBuf (&MAC->MacAddress.Addr[0], Length, AddressStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MAC;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv4 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ IPv4_DEVICE_PATH *IPv4;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ IPv4 = (IPv4_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv4_DP,
+ sizeof (IPv4_DEVICE_PATH)
+ );
+
+ StrToIPv4Addr (&RemoteIPStr, &IPv4->RemoteIpAddress);
+ IPv4->Protocol = (StrCmp (ProtocolStr, L"UDP") == 0) ? (UINT16) 0 : (UINT16) 1;
+ if (StrCmp (TypeStr, L"Static") == 0) {
+ IPv4->StaticIpAddress = TRUE;
+ } else {
+ IPv4->StaticIpAddress = FALSE;
+ }
+
+ StrToIPv4Addr (&LocalIPStr, &IPv4->LocalIpAddress);
+
+ IPv4->LocalPort = 0;
+ IPv4->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv4;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv6 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ IPv6_DEVICE_PATH *IPv6;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ IPv6 = (IPv6_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv6_DP,
+ sizeof (IPv6_DEVICE_PATH)
+ );
+
+ StrToIPv6Addr (&RemoteIPStr, &IPv6->RemoteIpAddress);
+ IPv6->Protocol = (StrCmp (ProtocolStr, L"UDP") == 0) ? (UINT16) 0 : (UINT16) 1;
+ if (StrCmp (TypeStr, L"Static") == 0) {
+ IPv6->StaticIpAddress = TRUE;
+ } else {
+ IPv6->StaticIpAddress = FALSE;
+ }
+
+ StrToIPv6Addr (&LocalIPStr, &IPv6->LocalIpAddress);
+
+ IPv6->LocalPort = 0;
+ IPv6->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv6;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUart (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *BaudStr;
+ CHAR16 *DataBitsStr;
+ CHAR16 *ParityStr;
+ CHAR16 *StopBitsStr;
+ UART_DEVICE_PATH *Uart;
+
+ BaudStr = GetNextParamStr (&TextDeviceNode);
+ DataBitsStr = GetNextParamStr (&TextDeviceNode);
+ ParityStr = GetNextParamStr (&TextDeviceNode);
+ StopBitsStr = GetNextParamStr (&TextDeviceNode);
+ Uart = (UART_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_UART_DP,
+ sizeof (UART_DEVICE_PATH)
+ );
+
+ Uart->BaudRate = (StrCmp (BaudStr, L"DEFAULT") == 0) ? 115200 : Atoi (BaudStr);
+ Uart->DataBits = (StrCmp (DataBitsStr, L"DEFAULT") == 0) ? (UINT8) 8 : (UINT8) Atoi (DataBitsStr);
+ switch (*ParityStr) {
+ case L'D':
+ Uart->Parity = 0;
+ break;
+
+ case L'N':
+ Uart->Parity = 1;
+ break;
+
+ case L'E':
+ Uart->Parity = 2;
+ break;
+
+ case L'O':
+ Uart->Parity = 3;
+ break;
+
+ case L'M':
+ Uart->Parity = 4;
+ break;
+
+ case L'S':
+ Uart->Parity = 5;
+
+ default:
+ Uart->Parity = 0xff;
+ }
+
+ if (StrCmp (StopBitsStr, L"D") == 0) {
+ Uart->StopBits = (UINT8) 0;
+ } else if (StrCmp (StopBitsStr, L"1") == 0) {
+ Uart->StopBits = (UINT8) 1;
+ } else if (StrCmp (StopBitsStr, L"1.5") == 0) {
+ Uart->StopBits = (UINT8) 2;
+ } else if (StrCmp (StopBitsStr, L"2") == 0) {
+ Uart->StopBits = (UINT8) 3;
+ } else {
+ Uart->StopBits = 0xff;
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Uart;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextUsbClass (
+ IN CHAR16 *TextDeviceNode,
+ IN USB_CLASS_TEXT *UsbClassText
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *ClassStr;
+ CHAR16 *SubClassStr;
+ CHAR16 *ProtocolStr;
+ USB_CLASS_DEVICE_PATH *UsbClass;
+
+ UsbClass = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_CLASS_DP,
+ sizeof (USB_CLASS_DEVICE_PATH)
+ );
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ if (UsbClassText->ClassExist) {
+ ClassStr = GetNextParamStr (&TextDeviceNode);
+ UsbClass->DeviceClass = (UINT8) Xtoi (ClassStr);
+ } else {
+ UsbClass->DeviceClass = UsbClassText->Class;
+ }
+ if (UsbClassText->SubClassExist) {
+ SubClassStr = GetNextParamStr (&TextDeviceNode);
+ UsbClass->DeviceSubClass = (UINT8) Xtoi (SubClassStr);
+ } else {
+ UsbClass->DeviceSubClass = UsbClassText->SubClass;
+ }
+
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+
+ UsbClass->VendorId = (UINT16) Xtoi (VIDStr);
+ UsbClass->ProductId = (UINT16) Xtoi (PIDStr);
+ UsbClass->DeviceProtocol = (UINT8) Xtoi (ProtocolStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass;
+}
+
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbClass (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = TRUE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbAudio (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_AUDIO;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCControl (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_CDCCONTROL;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHID (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_HID;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbImage (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_IMAGE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbPrinter (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_PRINTER;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbMassStorage (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_MASS_STORAGE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHub (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_HUB;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCData (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_CDCDATA;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbSmartCard (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_SMART_CARD;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbVideo (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_VIDEO;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDiagnostic (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_DIAGNOSTIC;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWireless (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_WIRELESS;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDeviceFirmwareUpdate (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_FW_UPDATE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbIrdaBridge (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_IRDA_BRIDGE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbTestAndMeasurement (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_TEST;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWwid (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *InterfaceNumStr;
+ USB_WWID_DEVICE_PATH *UsbWwid;
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceNumStr = GetNextParamStr (&TextDeviceNode);
+ UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_WWID_DP,
+ sizeof (USB_WWID_DEVICE_PATH)
+ );
+
+ UsbWwid->VendorId = (UINT16) Xtoi (VIDStr);
+ UsbWwid->ProductId = (UINT16) Xtoi (PIDStr);
+ UsbWwid->InterfaceNumber = (UINT16) Xtoi (InterfaceNumStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUnit (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *LunStr;
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_DEVICE_LOGICAL_UNIT_DP,
+ sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH)
+ );
+
+ LogicalUnit->Lun = (UINT8) Xtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextiSCSI (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ UINT16 Options;
+ CHAR16 *NameStr;
+ CHAR16 *PortalGroupStr;
+ CHAR16 *LunStr;
+ CHAR16 *HeaderDigestStr;
+ CHAR16 *DataDigestStr;
+ CHAR16 *AuthenticationStr;
+ CHAR16 *ProtocolStr;
+ ISCSI_DEVICE_PATH_WITH_NAME *iSCSI;
+
+ NameStr = GetNextParamStr (&TextDeviceNode);
+ PortalGroupStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ HeaderDigestStr = GetNextParamStr (&TextDeviceNode);
+ DataDigestStr = GetNextParamStr (&TextDeviceNode);
+ AuthenticationStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ iSCSI = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ISCSI_DP,
+ sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + (UINT16) (StrLen (NameStr) * 2)
+ );
+
+ StrCpy (iSCSI->iSCSITargetName, NameStr);
+ iSCSI->TargetPortalGroupTag = (UINT16) Xtoi (PortalGroupStr);
+ Xtoi64 (LunStr, &iSCSI->Lun);
+
+ Options = 0x0000;
+ if (StrCmp (HeaderDigestStr, L"CRC32C") == 0) {
+ Options |= 0x0002;
+ }
+
+ if (StrCmp (DataDigestStr, L"CRC32C") == 0) {
+ Options |= 0x0008;
+ }
+
+ if (StrCmp (AuthenticationStr, L"None") == 0) {
+ Options |= 0x0800;
+ }
+
+ if (StrCmp (AuthenticationStr, L"CHAP_UNI") == 0) {
+ Options |= 0x1000;
+ }
+
+ iSCSI->LoginOption = (UINT16) Options;
+
+ iSCSI->NetworkProtocol = (UINT16) StrCmp (ProtocolStr, L"TCP");
+ iSCSI->Reserved = (UINT16) 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) iSCSI;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHD (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PartitionStr;
+ CHAR16 *TypeStr;
+ CHAR16 *SignatureStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ UINT32 Signature32;
+ EFI_GUID SignatureGuid;
+ HARDDRIVE_DEVICE_PATH *Hd;
+
+ PartitionStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ SignatureStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ Hd = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_HARDDRIVE_DP,
+ sizeof (HARDDRIVE_DEVICE_PATH)
+ );
+
+ Hd->PartitionNumber = (UINT32) Atoi (PartitionStr);
+
+ ZeroMem (Hd->Signature, 16);
+ Hd->MBRType = (UINT8) 0;
+
+ if (StrCmp (TypeStr, L"None") == 0) {
+ Hd->SignatureType = (UINT8) 0;
+ } else if (StrCmp (TypeStr, L"MBR") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_MBR;
+ Hd->MBRType = 0x01;
+
+ Signature32 = (UINT32) Xtoi (SignatureStr);
+ CopyMem (Hd->Signature, &Signature32, sizeof (UINT32));
+ } else if (StrCmp (TypeStr, L"GUID") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_GUID;
+ Hd->MBRType = 0x02;
+
+ StrToGuid (SignatureStr, &SignatureGuid);
+ CopyMem (Hd->Signature, &SignatureGuid, sizeof (EFI_GUID));
+ } else {
+ Hd->SignatureType = 0xff;
+
+ }
+
+ Xtoi64 (StartStr, &Hd->PartitionStart);
+ Xtoi64 (SizeStr, &Hd->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Hd;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCDROM (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *EntryStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ CDROM_DEVICE_PATH *CDROM;
+
+ EntryStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ CDROM = (CDROM_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_CDROM_DP,
+ sizeof (CDROM_DEVICE_PATH)
+ );
+
+ CDROM->BootEntry = (UINT32) Xtoi (EntryStr);
+ Xtoi64 (StartStr, &CDROM->PartitionStart);
+ Xtoi64 (SizeStr, &CDROM->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) CDROM;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMEDIA (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MEDIA_DEVICE_PATH,
+ MEDIA_VENDOR_DP
+ );
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFilePath (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ FILEPATH_DEVICE_PATH *File;
+
+ File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+ sizeof (FILEPATH_DEVICE_PATH) + (UINT16) (StrLen (TextDeviceNode) * 2)
+ );
+
+ StrCpy (File->PathName, TextDeviceNode);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) File;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMedia (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_PROTOCOL_DEVICE_PATH *Media;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ Media = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PROTOCOL_DP,
+ sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &Media->Protocol);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Media;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBBS (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TypeStr;
+ CHAR16 *IdStr;
+ CHAR16 *FlagsStr;
+ UINT8 *AsciiStr;
+ BBS_BBS_DEVICE_PATH *Bbs;
+
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ IdStr = GetNextParamStr (&TextDeviceNode);
+ FlagsStr = GetNextParamStr (&TextDeviceNode);
+ Bbs = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode (
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ sizeof (BBS_BBS_DEVICE_PATH) + (UINT16) (StrLen (IdStr))
+ );
+
+ if (StrCmp (TypeStr, L"Floppy") == 0) {
+ Bbs->DeviceType = BBS_TYPE_FLOPPY;
+ } else if (StrCmp (TypeStr, L"HD") == 0) {
+ Bbs->DeviceType = BBS_TYPE_HARDDRIVE;
+ } else if (StrCmp (TypeStr, L"CDROM") == 0) {
+ Bbs->DeviceType = BBS_TYPE_CDROM;
+ } else if (StrCmp (TypeStr, L"PCMCIA") == 0) {
+ Bbs->DeviceType = BBS_TYPE_PCMCIA;
+ } else if (StrCmp (TypeStr, L"USB") == 0) {
+ Bbs->DeviceType = BBS_TYPE_USB;
+ } else if (StrCmp (TypeStr, L"Network") == 0) {
+ Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK;
+ } else {
+ Bbs->DeviceType = BBS_TYPE_UNKNOWN;
+ }
+
+ AsciiStr = Bbs->String;
+ StrToAscii (IdStr, &AsciiStr);
+
+ Bbs->StatusFlag = (UINT16) Xtoi (FlagsStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Bbs;
+}
+
+DEVICE_PATH_FROM_TEXT_TABLE DevPathFromTextTable[] = {
+ L"Pci",
+ DevPathFromTextPci,
+ L"PcCard",
+ DevPathFromTextPcCard,
+ L"MemoryMapped",
+ DevPathFromTextMemoryMapped,
+ L"VenHw",
+ DevPathFromTextVenHw,
+ L"Ctrl",
+ DevPathFromTextCtrl,
+ L"Acpi",
+ DevPathFromTextAcpi,
+ L"PciRoot",
+ DevPathFromTextPciRoot,
+ L"Floppy",
+ DevPathFromTextFloppy,
+ L"Keyboard",
+ DevPathFromTextKeyboard,
+ L"Serial",
+ DevPathFromTextSerial,
+ L"ParallelPort",
+ DevPathFromTextParallelPort,
+ L"AcpiEx",
+ DevPathFromTextAcpiEx,
+ L"AcpiExp",
+ DevPathFromTextAcpiExp,
+ L"Ata",
+ DevPathFromTextAta,
+ L"Scsi",
+ DevPathFromTextScsi,
+ L"Fibre",
+ DevPathFromTextFibre,
+ L"I1394",
+ DevPathFromText1394,
+ L"USB",
+ DevPathFromTextUsb,
+ L"I2O",
+ DevPathFromTextI2O,
+ L"Infiniband",
+ DevPathFromTextInfiniband,
+ L"VenMsg",
+ DevPathFromTextVenMsg,
+ L"VenPcAnsi",
+ DevPathFromTextVenPcAnsi,
+ L"VenVt100",
+ DevPathFromTextVenVt100,
+ L"VenVt100Plus",
+ DevPathFromTextVenVt100Plus,
+ L"VenUtf8",
+ DevPathFromTextVenUtf8,
+ L"UartFlowCtrl",
+ DevPathFromTextUartFlowCtrl,
+ L"SAS",
+ DevPathFromTextSAS,
+ L"DebugPort",
+ DevPathFromTextDebugPort,
+ L"MAC",
+ DevPathFromTextMAC,
+ L"IPv4",
+ DevPathFromTextIPv4,
+ L"IPv6",
+ DevPathFromTextIPv6,
+ L"Uart",
+ DevPathFromTextUart,
+ L"UsbClass",
+ DevPathFromTextUsbClass,
+ L"UsbAudio",
+ DevPathFromTextUsbAudio,
+ L"UsbCDCControl",
+ DevPathFromTextUsbCDCControl,
+ L"UsbHID",
+ DevPathFromTextUsbHID,
+ L"UsbImage",
+ DevPathFromTextUsbImage,
+ L"UsbPrinter",
+ DevPathFromTextUsbPrinter,
+ L"UsbMassStorage",
+ DevPathFromTextUsbMassStorage,
+ L"UsbHub",
+ DevPathFromTextUsbHub,
+ L"UsbCDCData",
+ DevPathFromTextUsbCDCData,
+ L"UsbSmartCard",
+ DevPathFromTextUsbSmartCard,
+ L"UsbVideo",
+ DevPathFromTextUsbVideo,
+ L"UsbDiagnostic",
+ DevPathFromTextUsbDiagnostic,
+ L"UsbWireless",
+ DevPathFromTextUsbWireless,
+ L"UsbDeviceFirmwareUpdate",
+ DevPathFromTextUsbDeviceFirmwareUpdate,
+ L"UsbIrdaBridge",
+ DevPathFromTextUsbIrdaBridge,
+ L"UsbTestAndMeasurement",
+ DevPathFromTextUsbTestAndMeasurement,
+ L"UsbWwid",
+ DevPathFromTextUsbWwid,
+ L"Unit",
+ DevPathFromTextUnit,
+ L"iSCSI",
+ DevPathFromTextiSCSI,
+ L"HD",
+ DevPathFromTextHD,
+ L"CDROM",
+ DevPathFromTextCDROM,
+ L"VenMEDIA",
+ DevPathFromTextVenMEDIA,
+ L"Media",
+ DevPathFromTextMedia,
+ L"BBS",
+ DevPathFromTextBBS,
+ NULL,
+ NULL
+};
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ )
+/*++
+
+ Routine Description:
+ Convert text to the binary representation of a device node.
+
+ Arguments:
+ TextDeviceNode - TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ Returns:
+ A pointer - Pointer to the EFI device node.
+ NULL - If TextDeviceNode is NULL or there was insufficient memory or text unsupported.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL * (*DumpNode) (CHAR16 *);
+ CHAR16 *ParamStr;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ CHAR16 *DeviceNodeStr;
+ UINTN Index;
+
+ if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) {
+ return NULL;
+ }
+
+ ParamStr = NULL;
+ DumpNode = NULL;
+ DeviceNodeStr = StrDuplicate (TextDeviceNode);
+
+ for (Index = 0; DevPathFromTextTable[Index].Function; Index++) {
+ ParamStr = GetParamByNodeName (DeviceNodeStr, DevPathFromTextTable[Index].DevicePathNodeText);
+ if (ParamStr != NULL) {
+ DumpNode = DevPathFromTextTable[Index].Function;
+ break;
+ }
+ }
+
+ if (DumpNode == NULL) {
+ //
+ // A file path
+ //
+ DumpNode = DevPathFromTextFilePath;
+ DeviceNode = DumpNode (DeviceNodeStr);
+ } else {
+ DeviceNode = DumpNode (ParamStr);
+ gBS->FreePool (ParamStr);
+ }
+
+ gBS->FreePool (DeviceNodeStr);
+
+ return DeviceNode;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ )
+/*++
+
+ Routine Description:
+ Convert text to the binary representation of a device path.
+
+ Arguments:
+ TextDevicePath - TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ Returns:
+ A pointer - Pointer to the allocated device path.
+ NULL - If TextDeviceNode is NULL or there was insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL * (*DumpNode) (CHAR16 *);
+ CHAR16 *ParamStr;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ UINTN Index;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ CHAR16 *DevicePathStr;
+ CHAR16 *Str;
+ CHAR16 *DeviceNodeStr;
+ UINT8 IsInstanceEnd;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
+ return NULL;
+ }
+
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ SetDevicePathEndNode (DevicePath);
+
+ ParamStr = NULL;
+ DeviceNodeStr = NULL;
+ DevicePathStr = StrDuplicate (TextDevicePath);
+
+ Str = DevicePathStr;
+ while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
+ DumpNode = NULL;
+ for (Index = 0; DevPathFromTextTable[Index].Function; Index++) {
+ ParamStr = GetParamByNodeName (DeviceNodeStr, DevPathFromTextTable[Index].DevicePathNodeText);
+ if (ParamStr != NULL) {
+ DumpNode = DevPathFromTextTable[Index].Function;
+ break;
+ }
+ }
+
+ if (DumpNode == NULL) {
+ //
+ // A file path
+ //
+ DumpNode = DevPathFromTextFilePath;
+ DeviceNode = DumpNode (DeviceNodeStr);
+ } else {
+ DeviceNode = DumpNode (ParamStr);
+ gBS->FreePool (ParamStr);
+ }
+
+ NewDevicePath = AppendDeviceNode (DevicePath, DeviceNode);
+ gBS->FreePool (DevicePath);
+ gBS->FreePool (DeviceNode);
+ DevicePath = NewDevicePath;
+
+ if (IsInstanceEnd) {
+ DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ SetDevicePathInstanceEndNode (DeviceNode);
+
+ NewDevicePath = AppendDeviceNode (DevicePath, DeviceNode);
+ gBS->FreePool (DevicePath);
+ gBS->FreePool (DeviceNode);
+ DevicePath = NewDevicePath;
+ }
+ }
+
+ gBS->FreePool (DevicePathStr);
+ return DevicePath;
+}
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c
new file mode 100644
index 0000000000..64fd5658fd
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathToText.c
@@ -0,0 +1,1526 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DevicePathToText.c
+
+Abstract:
+
+ DevicePathToText protocol as defined in the UEFI 2.0 specification.
+
+--*/
+
+#include <protocol/DevicePathToText.h>
+#include "DevicePath.h"
+
+EFI_DEVICE_PATH_PROTOCOL *
+UnpackDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ )
+/*++
+
+ Routine Description:
+ Function unpacks a device path data structure so that all the nodes of a device path
+ are naturally aligned.
+
+ Arguments:
+ DevPath - A pointer to a device path data structure
+
+ Returns:
+ If the memory for the device path is successfully allocated, then a pointer to the
+ new device path is returned. Otherwise, NULL is returned.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Src;
+ EFI_DEVICE_PATH_PROTOCOL *Dest;
+ EFI_DEVICE_PATH_PROTOCOL *NewPath;
+ UINTN Size;
+
+ if (DevPath == NULL) {
+ return NULL;
+ }
+ //
+ // Walk device path and round sizes to valid boundries
+ //
+ Src = DevPath;
+ Size = 0;
+ for (;;) {
+ Size += DevicePathNodeLength (Src);
+ Size += ALIGN_SIZE (Size);
+
+ if (IsDevicePathEnd (Src)) {
+ break;
+ }
+
+ Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);
+ }
+ //
+ // Allocate space for the unpacked path
+ //
+ NewPath = AllocateZeroPool (Size);
+ if (NewPath != NULL) {
+
+ ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);
+
+ //
+ // Copy each node
+ //
+ Src = DevPath;
+ Dest = NewPath;
+ for (;;) {
+ Size = DevicePathNodeLength (Src);
+ CopyMem (Dest, Src, Size);
+ Size += ALIGN_SIZE (Size);
+ SetDevicePathNodeLength (Dest, Size);
+ Dest->Type |= EFI_DP_TYPE_UNPACKED;
+ Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);
+
+ if (IsDevicePathEnd (Src)) {
+ break;
+ }
+
+ Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);
+ }
+ }
+
+ return NewPath;
+}
+
+VOID *
+ReallocatePool (
+ IN VOID *OldPool,
+ IN UINTN OldSize,
+ IN UINTN NewSize
+ )
+/*++
+
+ Routine Description:
+ Adjusts the size of a previously allocated buffer.
+
+ Arguments:
+ OldPool - A pointer to the buffer whose size is being adjusted.
+ OldSize - The size of the current buffer.
+ NewSize - The size of the new buffer.
+
+ Returns:
+ EFI_SUCEESS - The requested number of bytes were allocated.
+ EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.
+ EFI_INVALID_PARAMETER - The buffer was invalid.
+
+--*/
+{
+ VOID *NewPool;
+
+ NewPool = NULL;
+ if (NewSize) {
+ NewPool = AllocateZeroPool (NewSize);
+ }
+
+ if (OldPool) {
+ if (NewPool) {
+ CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
+ }
+
+ gBS->FreePool (OldPool);
+ }
+
+ return NewPool;
+}
+
+CHAR16 *
+CatPrint (
+ IN OUT POOL_PRINT *Str,
+ IN CHAR16 *Fmt,
+ ...
+ )
+/*++
+
+ Routine Description:
+ Concatenates a formatted unicode string to allocated pool.
+ The caller must free the resulting buffer.
+
+ Arguments:
+ Str - Tracks the allocated pool, size in use, and
+ amount of pool allocated.
+ Fmt - The format string
+
+ Returns:
+ Allocated buffer with the formatted string printed in it.
+ The caller must free the allocated buffer. The buffer
+ allocation is not packed.
+
+--*/
+{
+ UINT16 *AppendStr;
+ VA_LIST Args;
+ UINTN Size;
+
+ AppendStr = AllocateZeroPool (0x1000);
+ if (AppendStr == NULL) {
+ return Str->Str;
+ }
+
+ VA_START (Args, Fmt);
+ UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);
+ VA_END (Args);
+ if (NULL == Str->Str) {
+ Size = StrSize (AppendStr);
+ Str->Str = AllocateZeroPool (Size);
+ ASSERT (Str->Str != NULL);
+ } else {
+ Size = StrSize (AppendStr) + StrSize (Str->Str) - sizeof (UINT16);
+ Str->Str = ReallocatePool (
+ Str->Str,
+ StrSize (Str->Str),
+ Size
+ );
+ ASSERT (Str->Str != NULL);
+ }
+
+ Str->MaxLen = MAX_CHAR * sizeof (UINT16);
+ if (Size < Str->MaxLen) {
+ StrCat (Str->Str, AppendStr);
+ Str->Len = Size - sizeof (UINT16);
+ }
+
+ gBS->FreePool (AppendStr);
+ return Str->Str;
+}
+
+VOID
+DevPathToTextPci (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ PCI_DEVICE_PATH *Pci;
+
+ Pci = DevPath;
+ CatPrint (Str, L"Pci(%x,%x)", Pci->Function, Pci->Device);
+}
+
+VOID
+DevPathToTextPccard (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ PCCARD_DEVICE_PATH *Pccard;
+
+ Pccard = DevPath;
+ CatPrint (Str, L"PcCard(%x)", Pccard->FunctionNumber);
+}
+
+VOID
+DevPathToTextMemMap (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ MemMap = DevPath;
+ CatPrint (
+ Str,
+ L"MemoryMapped(%lx,%lx)",
+ MemMap->StartingAddress,
+ MemMap->EndingAddress
+ );
+}
+
+VOID
+DevPathToTextVendor (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+ CHAR16 *Type;
+ UINTN Index;
+ UINT32 FlowControlMap;
+ UINT16 Info;
+
+ Vendor = (VENDOR_DEVICE_PATH *) DevPath;
+ switch (DevicePathType (&Vendor->Header)) {
+ case HARDWARE_DEVICE_PATH:
+ Type = L"Hw";
+ break;
+
+ case MESSAGING_DEVICE_PATH:
+ Type = L"Msg";
+ if (AllowShortcuts) {
+ if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
+ CatPrint (Str, L"VenPcAnsi()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
+ CatPrint (Str, L"VenVt100()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
+ CatPrint (Str, L"VenVt100Plus()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
+ CatPrint (Str, L"VenUft8()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingUartFlowControlGuid)) {
+ FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
+ switch (FlowControlMap & 0x00000003) {
+ case 0:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"None");
+ break;
+
+ case 1:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");
+ break;
+
+ case 2:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");
+ break;
+
+ default:
+ break;
+ }
+
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingSASGuid)) {
+ CatPrint (
+ Str,
+ L"SAS(%lx,%lx,%x,",
+ ((SAS_DEVICE_PATH *) Vendor)->SasAddress,
+ ((SAS_DEVICE_PATH *) Vendor)->Lun,
+ ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort
+ );
+ Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
+ if ((Info & 0x0f) == 0) {
+ CatPrint (Str, L"NoTopology,0,0,0,");
+ } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {
+ CatPrint (
+ Str,
+ L"%s,%s,%s,",
+ (Info & (0x1 << 4)) ? L"SATA" : L"SAS",
+ (Info & (0x1 << 5)) ? L"External" : L"Internal",
+ (Info & (0x1 << 6)) ? L"Expanded" : L"Direct"
+ );
+ if ((Info & 0x0f) == 1) {
+ CatPrint (Str, L"0,");
+ } else {
+ CatPrint (Str, L"%x,", (Info >> 8) & 0xff);
+ }
+ } else {
+ CatPrint (Str, L"0,0,0,0,");
+ }
+
+ CatPrint (Str, L"%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
+ CatPrint (Str, L"DebugPort()");
+ return ;
+ } else {
+ return ;
+ //
+ // reserved
+ //
+ }
+ }
+ break;
+
+ case MEDIA_DEVICE_PATH:
+ Type = L"Media";
+ break;
+
+ default:
+ Type = L"?";
+ break;
+ }
+
+ CatPrint (Str, L"Ven%s(%g,", Type, &Vendor->Guid);
+ for (Index = 0; Index < DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH); Index++) {
+ CatPrint (Str, L"%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
+ }
+
+ CatPrint (Str, L")");
+}
+
+VOID
+DevPathToTextController (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CONTROLLER_DEVICE_PATH *Controller;
+
+ Controller = DevPath;
+ CatPrint (
+ Str,
+ L"Ctrl(%x)",
+ (UINT16 *)Controller->ControllerNumber
+ );
+}
+
+VOID
+DevPathToTextAcpi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ Acpi = DevPath;
+ if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ if (AllowShortcuts) {
+ switch (EISA_ID_TO_NUM (Acpi->HID)) {
+ case 0x0a03:
+ CatPrint (Str, L"PciRoot(%x)", Acpi->UID);
+ break;
+
+ case 0x0604:
+ CatPrint (Str, L"Floppy(%x)", Acpi->UID);
+ break;
+
+ case 0x0301:
+ CatPrint (Str, L"Keyboard(%x)", Acpi->UID);
+ break;
+
+ case 0x0501:
+ CatPrint (Str, L"Serial(%x)", Acpi->UID);
+ break;
+
+ case 0x0401:
+ CatPrint (Str, L"ParallelPort(%x)", Acpi->UID);
+ break;
+
+ default:
+ break;
+ }
+
+ return ;
+ }
+
+ CatPrint (Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
+ } else {
+ CatPrint (Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);
+ }
+}
+
+#define NextStrA(a) ((UINT8 *) (((UINT8 *) (a)) + AsciiStrLen (a) + 1))
+
+VOID
+DevPathToTextExtAcpi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *AcpiExt;
+
+ AcpiExt = DevPath;
+
+ if (AllowShortcuts) {
+ if ((*(AcpiExt->HidUidCidStr) == '\0') &&
+ (*(NextStrA (NextStrA (AcpiExt->HidUidCidStr))) == '\0') &&
+ (AcpiExt->UID == 0)
+ ) {
+ if ((AcpiExt->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ CatPrint (
+ Str,
+ L"AcpiExp(PNP%04x,%x,%a)",
+ EISA_ID_TO_NUM (AcpiExt->HID),
+ AcpiExt->CID,
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ } else {
+ CatPrint (
+ Str,
+ L"AcpiExp(%08x,%x,%a)",
+ AcpiExt->HID,
+ AcpiExt->CID,
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ }
+ }
+ return ;
+ }
+
+ if ((AcpiExt->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ CatPrint (
+ Str,
+ L"AcpiEx(PNP%04x,%x,%x,%a,%a,%a)",
+ EISA_ID_TO_NUM (AcpiExt->HID),
+ AcpiExt->CID,
+ AcpiExt->UID,
+ AcpiExt->HidUidCidStr,
+ NextStrA (NextStrA (AcpiExt->HidUidCidStr)),
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ } else {
+ CatPrint (
+ Str,
+ L"AcpiEx(%08x,%x,%x,%a,%a,%a)",
+ AcpiExt->HID,
+ AcpiExt->CID,
+ AcpiExt->UID,
+ AcpiExt->HidUidCidStr,
+ NextStrA (NextStrA (AcpiExt->HidUidCidStr)),
+ NextStrA (AcpiExt->HidUidCidStr)
+ );
+ }
+}
+
+VOID
+DevPathToTextAtapi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ATAPI_DEVICE_PATH *Atapi;
+
+ Atapi = DevPath;
+
+ if (DisplayOnly) {
+ CatPrint (Str, L"Ata(%x)", Atapi->Lun);
+ } else {
+ CatPrint (
+ Str,
+ L"Ata(%s,%s,%x)",
+ Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
+ Atapi->SlaveMaster ? L"Slave" : L"Master",
+ Atapi->Lun
+ );
+ }
+}
+
+VOID
+DevPathToTextScsi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ SCSI_DEVICE_PATH *Scsi;
+
+ Scsi = DevPath;
+ CatPrint (Str, L"Scsi(%x,%x)", Scsi->Pun, Scsi->Lun);
+}
+
+VOID
+DevPathToTextFibre (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ FIBRECHANNEL_DEVICE_PATH *Fibre;
+
+ Fibre = DevPath;
+ CatPrint (Str, L"Fibre(%lx,%lx)", Fibre->WWN, Fibre->Lun);
+}
+
+VOID
+DevPathToText1394 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ F1394_DEVICE_PATH *F1394;
+
+ F1394 = DevPath;
+ CatPrint (Str, L"I1394(%lx)", F1394->Guid);
+}
+
+VOID
+DevPathToTextUsb (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_DEVICE_PATH *Usb;
+
+ Usb = DevPath;
+ CatPrint (Str, L"USB(%x,%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
+}
+
+VOID
+DevPathToTextUsbWWID (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_WWID_DEVICE_PATH *UsbWWId;
+
+ UsbWWId = DevPath;
+ CatPrint (
+ Str,
+ L"UsbWwid(%x,%x,%x,\"WWID\")",
+ UsbWWId->VendorId,
+ UsbWWId->ProductId,
+ UsbWWId->InterfaceNumber
+ );
+}
+
+VOID
+DevPathToTextLogicalUnit (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+ LogicalUnit = DevPath;
+ CatPrint (Str, L"Unit(%x)", LogicalUnit->Lun);
+}
+
+VOID
+DevPathToTextUsbClass (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_CLASS_DEVICE_PATH *UsbClass;
+
+ UsbClass = DevPath;
+
+ if (AllowShortcuts == TRUE) {
+ switch (UsbClass->DeviceClass) {
+ case 1:
+ CatPrint (
+ Str,
+ L"UsbAudio(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 2:
+ CatPrint (
+ Str,
+ L"UsbCDCControl(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 3:
+ CatPrint (
+ Str,
+ L"UsbHID(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 6:
+ CatPrint (
+ Str,
+ L"UsbImage(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 7:
+ CatPrint (
+ Str,
+ L"UsbPrinter(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 8:
+ CatPrint (
+ Str,
+ L"UsbMassStorage(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 9:
+ CatPrint (
+ Str,
+ L"UsbHub(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 10:
+ CatPrint (
+ Str,
+ L"UsbCDCData(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 11:
+ CatPrint (
+ Str,
+ L"UsbSmartCard(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 14:
+ CatPrint (
+ Str,
+ L"UsbVideo(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 220:
+ CatPrint (
+ Str,
+ L"UsbDiagnostic(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 224:
+ CatPrint (
+ Str,
+ L"UsbWireless(%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ break;
+
+ case 254:
+ if (UsbClass->DeviceSubClass == 1) {
+ CatPrint (
+ Str,
+ L"UsbDeviceFirmwareUpdate(%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ } else if (UsbClass->DeviceSubClass == 2) {
+ CatPrint (
+ Str,
+ L"UsbIrdaBridge(%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ } else if (UsbClass->DeviceSubClass == 3) {
+ CatPrint (
+ Str,
+ L"UsbTestAndMeasurement(%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"UsbClass(%x,%x,%x,%x,%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceClass,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+}
+
+VOID
+DevPathToTextI2O (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ I2O_DEVICE_PATH *I2O;
+
+ I2O = DevPath;
+ CatPrint (Str, L"I2O(%x)", I2O->Tid);
+}
+
+VOID
+DevPathToTextMacAddr (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MAC_ADDR_DEVICE_PATH *MAC;
+ UINTN HwAddressSize;
+ UINTN Index;
+
+ MAC = DevPath;
+
+ HwAddressSize = sizeof (EFI_MAC_ADDRESS);
+ if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
+ HwAddressSize = 6;
+ }
+
+ CatPrint (Str, L"MAC(");
+
+ for (Index = 0; Index < HwAddressSize; Index++) {
+ CatPrint (Str, L"%02x", MAC->MacAddress.Addr[Index]);
+ }
+
+ CatPrint (Str, L",%x)", MAC->IfType);
+}
+
+VOID
+DevPathToTextIPv4 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ IPv4_DEVICE_PATH *IP;
+
+ IP = DevPath;
+ if (DisplayOnly == TRUE) {
+ CatPrint (
+ Str,
+ L"IPv4(%d.%d.%d.%d)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3]
+ );
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"IPv4(%d.%d.%d.%d,%s,%s,%d.%d.%d.%d)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3],
+ IP->Protocol ? L"TCP" : L"UDP",
+ (IP->StaticIpAddress == TRUE) ? L"Static" : L"DHCP",
+ IP->LocalIpAddress.Addr[0],
+ IP->LocalIpAddress.Addr[1],
+ IP->LocalIpAddress.Addr[2],
+ IP->LocalIpAddress.Addr[3]
+ );
+}
+
+VOID
+DevPathToTextIPv6 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ IPv6_DEVICE_PATH *IP;
+
+ IP = DevPath;
+ if (DisplayOnly == TRUE) {
+ CatPrint (
+ Str,
+ L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3],
+ IP->RemoteIpAddress.Addr[4],
+ IP->RemoteIpAddress.Addr[5],
+ IP->RemoteIpAddress.Addr[6],
+ IP->RemoteIpAddress.Addr[7],
+ IP->RemoteIpAddress.Addr[8],
+ IP->RemoteIpAddress.Addr[9],
+ IP->RemoteIpAddress.Addr[10],
+ IP->RemoteIpAddress.Addr[11],
+ IP->RemoteIpAddress.Addr[12],
+ IP->RemoteIpAddress.Addr[13],
+ IP->RemoteIpAddress.Addr[14],
+ IP->RemoteIpAddress.Addr[15]
+ );
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x,%s,%s,%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
+ IP->RemoteIpAddress.Addr[0],
+ IP->RemoteIpAddress.Addr[1],
+ IP->RemoteIpAddress.Addr[2],
+ IP->RemoteIpAddress.Addr[3],
+ IP->RemoteIpAddress.Addr[4],
+ IP->RemoteIpAddress.Addr[5],
+ IP->RemoteIpAddress.Addr[6],
+ IP->RemoteIpAddress.Addr[7],
+ IP->RemoteIpAddress.Addr[8],
+ IP->RemoteIpAddress.Addr[9],
+ IP->RemoteIpAddress.Addr[10],
+ IP->RemoteIpAddress.Addr[11],
+ IP->RemoteIpAddress.Addr[12],
+ IP->RemoteIpAddress.Addr[13],
+ IP->RemoteIpAddress.Addr[14],
+ IP->RemoteIpAddress.Addr[15],
+ IP->Protocol ? L"TCP" : L"UDP",
+ (IP->StaticIpAddress == TRUE) ? L"Static" : L"DHCP",
+ IP->LocalIpAddress.Addr[0],
+ IP->LocalIpAddress.Addr[1],
+ IP->LocalIpAddress.Addr[2],
+ IP->LocalIpAddress.Addr[3],
+ IP->LocalIpAddress.Addr[4],
+ IP->LocalIpAddress.Addr[5],
+ IP->LocalIpAddress.Addr[6],
+ IP->LocalIpAddress.Addr[7],
+ IP->LocalIpAddress.Addr[8],
+ IP->LocalIpAddress.Addr[9],
+ IP->LocalIpAddress.Addr[10],
+ IP->LocalIpAddress.Addr[11],
+ IP->LocalIpAddress.Addr[12],
+ IP->LocalIpAddress.Addr[13],
+ IP->LocalIpAddress.Addr[14],
+ IP->LocalIpAddress.Addr[15]
+ );
+}
+
+VOID
+DevPathToTextInfiniBand (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ InfiniBand = DevPath;
+ CatPrint (
+ Str,
+ L"Infiniband(%x,%g,%lx,%lx,%lx)",
+ InfiniBand->ResourceFlags,
+ InfiniBand->PortGid,
+ InfiniBand->ServiceId,
+ InfiniBand->TargetPortId,
+ InfiniBand->DeviceId
+ );
+}
+
+VOID
+DevPathToTextUart (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ UART_DEVICE_PATH *Uart;
+ CHAR8 Parity;
+
+ Uart = DevPath;
+ switch (Uart->Parity) {
+ case 0:
+ Parity = 'D';
+ break;
+
+ case 1:
+ Parity = 'N';
+ break;
+
+ case 2:
+ Parity = 'E';
+ break;
+
+ case 3:
+ Parity = 'O';
+ break;
+
+ case 4:
+ Parity = 'M';
+ break;
+
+ case 5:
+ Parity = 'S';
+ break;
+
+ default:
+ Parity = 'x';
+ break;
+ }
+
+ if (Uart->BaudRate == 0) {
+ CatPrint (Str, L"Uart(DEFAULT,");
+ } else {
+ CatPrint (Str, L"Uart(%ld,", Uart->BaudRate);
+ }
+
+ if (Uart->DataBits == 0) {
+ CatPrint (Str, L"DEFAULT,");
+ } else {
+ CatPrint (Str, L"%d,", Uart->DataBits);
+ }
+
+ CatPrint (Str, L"%c,", Parity);
+
+ switch (Uart->StopBits) {
+ case 0:
+ CatPrint (Str, L"D)");
+ break;
+
+ case 1:
+ CatPrint (Str, L"1)");
+ break;
+
+ case 2:
+ CatPrint (Str, L"1.5)");
+ break;
+
+ case 3:
+ CatPrint (Str, L"2)");
+ break;
+
+ default:
+ CatPrint (Str, L"x)");
+ break;
+ }
+}
+
+VOID
+DevPathToTextiSCSI (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ISCSI_DEVICE_PATH_WITH_NAME *iSCSI;
+ UINT16 Options;
+
+ iSCSI = DevPath;
+ CatPrint (
+ Str,
+ L"iSCSI(%s,%x,%lx,",
+ iSCSI->iSCSITargetName,
+ iSCSI->TargetPortalGroupTag,
+ iSCSI->Lun
+ );
+
+ Options = iSCSI->LoginOption;
+ CatPrint (Str, L"%s,", ((Options >> 1) & 0x0001) ? L"CRC32C" : L"None");
+ CatPrint (Str, L"%s,", ((Options >> 3) & 0x0001) ? L"CRC32C" : L"None");
+ if ((Options >> 11) & 0x0001) {
+ CatPrint (Str, L"%s,", L"None");
+ } else if ((Options >> 12) & 0x0001) {
+ CatPrint (Str, L"%s,", L"CHAP_UNI");
+ } else {
+ CatPrint (Str, L"%s,", L"CHAP_BI");
+
+ }
+
+ CatPrint (Str, L"%s)", (iSCSI->NetworkProtocol == 0) ? L"TCP" : L"reserved");
+}
+
+VOID
+DevPathToTextHardDrive (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ HARDDRIVE_DEVICE_PATH *Hd;
+
+ Hd = DevPath;
+ switch (Hd->SignatureType) {
+ case 0:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,0,",
+ Hd->PartitionNumber,
+ L"None"
+ );
+ break;
+
+ case SIGNATURE_TYPE_MBR:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,%08x,",
+ Hd->PartitionNumber,
+ L"MBR",
+ *((UINT32 *) (&(Hd->Signature[0])))
+ );
+ break;
+
+ case SIGNATURE_TYPE_GUID:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,%g,",
+ Hd->PartitionNumber,
+ L"GUID",
+ (EFI_GUID *) &(Hd->Signature[0])
+ );
+ break;
+
+ default:
+ break;
+ }
+
+ CatPrint (Str, L"%lx,%lx)", Hd->PartitionStart, Hd->PartitionSize);
+}
+
+VOID
+DevPathToTextCDROM (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CDROM_DEVICE_PATH *Cd;
+
+ Cd = DevPath;
+ if (DisplayOnly == TRUE) {
+ CatPrint (Str, L"CDROM(%x)", Cd->BootEntry);
+ return ;
+ }
+
+ CatPrint (Str, L"CDROM(%x,%lx,%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);
+}
+
+VOID
+DevPathToTextFilePath (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ FILEPATH_DEVICE_PATH *Fp;
+
+ Fp = DevPath;
+ CatPrint (Str, L"%s", Fp->PathName);
+}
+
+VOID
+DevPathToTextMediaProtocol (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
+
+ MediaProt = DevPath;
+ CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);
+}
+
+VOID
+DevPathToTextBBS (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ BBS_BBS_DEVICE_PATH *Bbs;
+ CHAR16 *Type;
+
+ Bbs = DevPath;
+ switch (Bbs->DeviceType) {
+ case BBS_TYPE_FLOPPY:
+ Type = L"Floppy";
+ break;
+
+ case BBS_TYPE_HARDDRIVE:
+ Type = L"HD";
+ break;
+
+ case BBS_TYPE_CDROM:
+ Type = L"CDROM";
+ break;
+
+ case BBS_TYPE_PCMCIA:
+ Type = L"PCMCIA";
+ break;
+
+ case BBS_TYPE_USB:
+ Type = L"USB";
+ break;
+
+ case BBS_TYPE_EMBEDDED_NETWORK:
+ Type = L"Network";
+ break;
+
+ default:
+ Type = L"?";
+ break;
+ }
+
+ CatPrint (Str, L"BBS(%s,%a", Type, Bbs->String);
+
+ if (DisplayOnly == TRUE) {
+ CatPrint (Str, L")");
+ return ;
+ }
+
+ CatPrint (Str, L",%x)", Bbs->StatusFlag);
+}
+
+VOID
+DevPathToTextEndInstance (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CatPrint (Str, L",");
+}
+
+VOID
+DevPathToTextNodeUnknown (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CatPrint (Str, L"?");
+}
+
+DEVICE_PATH_TO_TEXT_TABLE DevPathToTextTable[] = {
+ HARDWARE_DEVICE_PATH,
+ HW_PCI_DP,
+ DevPathToTextPci,
+ HARDWARE_DEVICE_PATH,
+ HW_PCCARD_DP,
+ DevPathToTextPccard,
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ DevPathToTextMemMap,
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ DevPathToTextVendor,
+ HARDWARE_DEVICE_PATH,
+ HW_CONTROLLER_DP,
+ DevPathToTextController,
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ DevPathToTextAcpi,
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ DevPathToTextExtAcpi,
+ MESSAGING_DEVICE_PATH,
+ MSG_ATAPI_DP,
+ DevPathToTextAtapi,
+ MESSAGING_DEVICE_PATH,
+ MSG_SCSI_DP,
+ DevPathToTextScsi,
+ MESSAGING_DEVICE_PATH,
+ MSG_FIBRECHANNEL_DP,
+ DevPathToTextFibre,
+ MESSAGING_DEVICE_PATH,
+ MSG_1394_DP,
+ DevPathToText1394,
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_DP,
+ DevPathToTextUsb,
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_WWID_DP,
+ DevPathToTextUsbWWID,
+ MESSAGING_DEVICE_PATH,
+ MSG_DEVICE_LOGICAL_UNIT_DP,
+ DevPathToTextLogicalUnit,
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_CLASS_DP,
+ DevPathToTextUsbClass,
+ MESSAGING_DEVICE_PATH,
+ MSG_I2O_DP,
+ DevPathToTextI2O,
+ MESSAGING_DEVICE_PATH,
+ MSG_MAC_ADDR_DP,
+ DevPathToTextMacAddr,
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv4_DP,
+ DevPathToTextIPv4,
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv6_DP,
+ DevPathToTextIPv6,
+ MESSAGING_DEVICE_PATH,
+ MSG_INFINIBAND_DP,
+ DevPathToTextInfiniBand,
+ MESSAGING_DEVICE_PATH,
+ MSG_UART_DP,
+ DevPathToTextUart,
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ DevPathToTextVendor,
+ MESSAGING_DEVICE_PATH,
+ MSG_ISCSI_DP,
+ DevPathToTextiSCSI,
+ MEDIA_DEVICE_PATH,
+ MEDIA_HARDDRIVE_DP,
+ DevPathToTextHardDrive,
+ MEDIA_DEVICE_PATH,
+ MEDIA_CDROM_DP,
+ DevPathToTextCDROM,
+ MEDIA_DEVICE_PATH,
+ MEDIA_VENDOR_DP,
+ DevPathToTextVendor,
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+ DevPathToTextFilePath,
+ MEDIA_DEVICE_PATH,
+ MEDIA_PROTOCOL_DP,
+ DevPathToTextMediaProtocol,
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+ DevPathToTextFilePath,
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ DevPathToTextBBS,
+ END_DEVICE_PATH_TYPE,
+ END_INSTANCE_DEVICE_PATH_SUBTYPE,
+ DevPathToTextEndInstance,
+ 0,
+ 0,
+ NULL
+};
+
+CHAR16 *
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+/*++
+
+ Routine Description:
+ Convert a device node to its text representation.
+
+ Arguments:
+ DeviceNode - Points to the device node to be converted.
+ DisplayOnly - If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ Returns:
+ A pointer - a pointer to the allocated text representation of the device node.
+ NULL - if DeviceNode is NULL or there was insufficient memory.
+
+--*/
+{
+ POOL_PRINT Str;
+ UINTN Index;
+ UINTN NewSize;
+ VOID (*DumpNode)(POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+
+ if (DeviceNode == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (&Str, sizeof (Str));
+
+ //
+ // Process the device path node
+ //
+ DumpNode = NULL;
+ for (Index = 0; DevPathToTextTable[Index].Function != NULL; Index++) {
+ if (DevicePathType (DeviceNode) == DevPathToTextTable[Index].Type &&
+ DevicePathSubType (DeviceNode) == DevPathToTextTable[Index].SubType
+ ) {
+ DumpNode = DevPathToTextTable[Index].Function;
+ break;
+ }
+ }
+ //
+ // If not found, use a generic function
+ //
+ if (DumpNode == NULL) {
+ DumpNode = DevPathToTextNodeUnknown;
+ }
+
+ //
+ // Print this node
+ //
+ DumpNode (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);
+
+ //
+ // Shrink pool used for string allocation
+ //
+ NewSize = (Str.Len + 1) * sizeof (CHAR16);
+ Str.Str = ReallocatePool (Str.Str, NewSize, NewSize);
+ ASSERT (Str.Str != NULL);
+ Str.Str[Str.Len] = 0;
+ return Str.Str;
+}
+
+CHAR16 *
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+/*++
+
+ Routine Description:
+ Convert a device path to its text representation.
+
+ Arguments:
+ DeviceNode - Points to the device path to be converted.
+ DisplayOnly - If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ Returns:
+ A pointer - a pointer to the allocated text representation of the device path.
+ NULL - if DeviceNode is NULL or there was insufficient memory.
+
+--*/
+{
+ POOL_PRINT Str;
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
+ EFI_DEVICE_PATH_PROTOCOL *UnpackDevPath;
+ UINTN Index;
+ UINTN NewSize;
+ VOID (*DumpNode) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (&Str, sizeof (Str));
+
+ //
+ // Unpacked the device path
+ //
+ UnpackDevPath = UnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath);
+ ASSERT (UnpackDevPath != NULL);
+
+ //
+ // Process each device path node
+ //
+ DevPathNode = UnpackDevPath;
+ while (!IsDevicePathEnd (DevPathNode)) {
+ //
+ // Find the handler to dump this device path node
+ //
+ DumpNode = NULL;
+ for (Index = 0; DevPathToTextTable[Index].Function; Index += 1) {
+
+ if (DevicePathType (DevPathNode) == DevPathToTextTable[Index].Type &&
+ DevicePathSubType (DevPathNode) == DevPathToTextTable[Index].SubType
+ ) {
+ DumpNode = DevPathToTextTable[Index].Function;
+ break;
+ }
+ }
+ //
+ // If not found, use a generic function
+ //
+ if (!DumpNode) {
+ DumpNode = DevPathToTextNodeUnknown;
+ }
+ //
+ // Put a path seperator in if needed
+ //
+ if (Str.Len && DumpNode != DevPathToTextEndInstance) {
+ if (*(Str.Str + Str.Len / sizeof (CHAR16) - 1) != L',') {
+ CatPrint (&Str, L"/");
+ }
+ }
+ //
+ // Print this node of the device path
+ //
+ DumpNode (&Str, DevPathNode, DisplayOnly, AllowShortcuts);
+
+ //
+ // Next device path node
+ //
+ DevPathNode = NextDevicePathNode (DevPathNode);
+ }
+ //
+ // Shrink pool used for string allocation
+ //
+ gBS->FreePool (UnpackDevPath);
+
+ NewSize = (Str.Len + 1) * sizeof (CHAR16);
+ Str.Str = ReallocatePool (Str.Str, NewSize, NewSize);
+ ASSERT (Str.Str != NULL);
+ Str.Str[Str.Len] = 0;
+ return Str.Str;
+}
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c
new file mode 100644
index 0000000000..2b54c76832
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c
@@ -0,0 +1,421 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DevicePathUtilities.c
+
+Abstract:
+
+ Implementation file for Device Path Utilities Protocol
+
+--*/
+
+#include <protocol/DevicePathUtilities.h>
+#include <protocol/DevicePath.h>
+#include "DevicePath.h"
+
+UINTN
+GetDevicePathSize (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Returns the size of the device path, in bytes.
+
+ Arguments:
+ DevicePath - Points to the start of the EFI device path.
+
+ Returns:
+ Size - Size of the specified device path, in bytes, including the end-of-path tag.
+
+--*/
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Start;
+
+ if (DevicePath == NULL) {
+ return 0;
+ }
+
+ //
+ // Search for the end of the device path structure
+ //
+ Start = (EFI_DEVICE_PATH_PROTOCOL *) DevicePath;
+ while (!IsDevicePathEnd (DevicePath)) {
+ DevicePath = NextDevicePathNode (DevicePath);
+ }
+
+ //
+ // Compute the size and add back in the size of the end device path structure
+ //
+ return ((UINTN) DevicePath - (UINTN) Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Create a duplicate of the specified path.
+
+ Arguments:
+ DevicePath - Points to the source EFI device path.
+
+ Returns:
+ Pointer - A pointer to the duplicate device path.
+ NULL - Insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN Size;
+
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ //
+ // Compute the size
+ //
+ Size = GetDevicePathSize (DevicePath);
+ if (Size == 0) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for duplicate device path
+ //
+ NewDevicePath = AllocateCopyPool (Size, (VOID *) DevicePath);
+
+ return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2
+ )
+/*++
+
+ Routine Description:
+ Create a new path by appending the second device path to the first.
+
+ Arguments:
+ Src1 - Points to the first device path. If NULL, then it is ignored.
+ Src2 - Points to the second device path. If NULL, then it is ignored.
+
+ Returns:
+ Pointer - A pointer to the newly created device path.
+ NULL - Memory could not be allocated
+ or either DevicePath or DeviceNode is NULL.
+
+--*/
+{
+ UINTN Size;
+ UINTN Size1;
+ UINTN Size2;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath;
+
+ //
+ // If there's only 1 path, just duplicate it
+ //
+ if (Src1 == NULL) {
+ ASSERT (!IsDevicePathUnpacked (Src2));
+ return DuplicateDevicePath (Src2);
+ }
+
+ if (Src2 == NULL) {
+ ASSERT (!IsDevicePathUnpacked (Src1));
+ return DuplicateDevicePath (Src1);
+ }
+
+ //
+ // Allocate space for the combined device path. It only has one end node of
+ // length EFI_DEVICE_PATH_PROTOCOL
+ //
+ Size1 = GetDevicePathSize (Src1);
+ Size2 = GetDevicePathSize (Src2);
+ Size = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+ NewDevicePath = AllocateCopyPool (Size, (VOID *) Src1);
+
+ if (NewDevicePath != NULL) {
+ //
+ // Over write Src1 EndNode and do the copy
+ //
+ SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL)));
+ CopyMem (SecondDevicePath, (VOID *) Src2, Size2);
+ }
+
+ return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDeviceNode (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
+ )
+/*++
+
+ Routine Description:
+ Creates a new path by appending the device node to the device path.
+
+ Arguments:
+ DevicePath - Points to the device path.
+ DeviceNode - Points to the device node.
+
+ Returns:
+ Pointer - A pointer to the allocated device node.
+ NULL - Memory could not be allocated
+ or either DevicePath or DeviceNode is NULL.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Temp;
+ EFI_DEVICE_PATH_PROTOCOL *NextNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN NodeLength;
+
+ if ((DevicePath == NULL) || (DeviceNode == NULL)) {
+ return NULL;
+ }
+
+ //
+ // Build a Node that has a terminator on it
+ //
+ NodeLength = DevicePathNodeLength (DeviceNode);
+
+ Temp = AllocateCopyPool (NodeLength + sizeof (EFI_DEVICE_PATH_PROTOCOL), (VOID *) DeviceNode);
+ if (Temp == NULL) {
+ return NULL;
+ }
+
+ //
+ // Add and end device path node to convert Node to device path
+ //
+ NextNode = NextDevicePathNode (Temp);
+ SetDevicePathEndNode (NextNode);
+
+ //
+ // Append device paths
+ //
+ NewDevicePath = AppendDevicePath (DevicePath, Temp);
+ gBS->FreePool (Temp);
+ return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ )
+/*++
+
+ Routine Description:
+ Creates a new path by appending the specified device path instance to the specified device path.
+
+ Arguments:
+ DevicePath - Points to the device path. If NULL, then ignored.
+ DevicePathInstance - Points to the device path instance.
+
+ Returns:
+ Pointer - A pointer to the newly created device path
+ NULL - Memory could not be allocated or DevicePathInstance is NULL.
+
+--*/
+{
+ UINT8 *Ptr;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ UINTN SrcSize;
+ UINTN InstanceSize;
+
+ if (DevicePathInstance == NULL) {
+ return NULL;
+ }
+
+ if (DevicePath == NULL) {
+ return DuplicateDevicePath (DevicePathInstance);
+ }
+
+ SrcSize = GetDevicePathSize (DevicePath);
+ InstanceSize = GetDevicePathSize (DevicePathInstance);
+
+ Ptr = AllocateCopyPool (SrcSize + InstanceSize, (VOID *) DevicePath);
+ if (Ptr != NULL) {
+
+ DevPath = (EFI_DEVICE_PATH_PROTOCOL *) (Ptr + (SrcSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)));
+ //
+ // Convert the End to an End Instance, since we are
+ // appending another instacne after this one its a good
+ // idea.
+ //
+ DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+ DevPath = NextDevicePathNode (DevPath);
+ CopyMem (DevPath, (VOID *) DevicePathInstance, InstanceSize);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance,
+ OUT UINTN *DevicePathInstanceSize
+ )
+/*++
+
+ Routine Description:
+ Creates a copy of the current device path instance and returns a pointer to the next device path instance.
+
+ Arguments:
+ DevicePathInstance - On input, this holds the pointer to the current device path
+ instance. On output, this holds the pointer to the next
+ device path instance or NULL if there are no more device
+ path instances in the device path.
+ DevicePathInstanceSize - On output, this holds the size of the device path instance,
+ in bytes or zero, if DevicePathInstance is zero.
+
+ Returns:
+ Pointer - A pointer to the copy of the current device path instance.
+ NULL - DevicePathInstace was NULL on entry or there was insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ EFI_DEVICE_PATH_PROTOCOL *ReturnValue;
+ UINT8 Temp;
+
+ if (*DevicePathInstance == NULL) {
+ if (DevicePathInstanceSize != NULL) {
+ *DevicePathInstanceSize = 0;
+ }
+
+ return NULL;
+ }
+
+ //
+ // Find the end of the device path instance
+ //
+ DevPath = *DevicePathInstance;
+ while (!IsDevicePathEndType (DevPath)) {
+ DevPath = NextDevicePathNode (DevPath);
+ }
+
+ //
+ // Compute the size of the device path instance
+ //
+ if (DevicePathInstanceSize != NULL) {
+ *DevicePathInstanceSize = ((UINTN) DevPath - (UINTN) (*DevicePathInstance)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+ }
+
+ //
+ // Make a copy and return the device path instance
+ //
+ Temp = DevPath->SubType;
+ DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ ReturnValue = DuplicateDevicePath (*DevicePathInstance);
+ DevPath->SubType = Temp;
+
+ //
+ // If DevPath is the end of an entire device path, then another instance
+ // does not follow, so *DevicePath is set to NULL.
+ //
+ if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
+ *DevicePathInstance = NULL;
+ } else {
+ *DevicePathInstance = NextDevicePathNode (DevPath);
+ }
+
+ return ReturnValue;
+}
+
+BOOLEAN
+IsDevicePathMultiInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Returns whether a device path is multi-instance.
+
+ Arguments:
+ DevicePath - Points to the device path. If NULL, then ignored.
+
+ Returns:
+ TRUE - The device path has more than one instance
+ FALSE - The device path is empty or contains only a single instance.
+
+--*/
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Node;
+
+ if (DevicePath == NULL) {
+ return FALSE;
+ }
+
+ Node = DevicePath;
+ while (!IsDevicePathEnd (Node)) {
+ if (EfiIsDevicePathEndInstance (Node)) {
+ return TRUE;
+ }
+
+ Node = NextDevicePathNode (Node);
+ }
+
+ return FALSE;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ )
+/*++
+
+ Routine Description:
+ Creates a device node
+
+ Arguments:
+ NodeType - NodeType is the device node type (EFI_DEVICE_PATH.Type) for
+ the new device node.
+ NodeSubType - NodeSubType is the device node sub-type
+ EFI_DEVICE_PATH.SubType) for the new device node.
+ NodeLength - NodeLength is the length of the device node
+ (EFI_DEVICE_PATH.Length) for the new device node.
+
+ Returns:
+ Pointer - A pointer to the newly created device node.
+ NULL - NodeLength is less than
+ the size of the header or there was insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return NULL;
+ }
+
+ Node = (EFI_DEVICE_PATH_PROTOCOL *) AllocateZeroPool ((UINTN) NodeLength);
+ if (Node != NULL) {
+ Node->Type = NodeType;
+ Node->SubType = NodeSubType;
+ SetDevicePathNodeLength (Node, NodeLength);
+ }
+
+ return Node;
+}
diff --git a/EdkNt32Pkg/Nt32.fpd b/EdkNt32Pkg/Nt32.fpd
index 50b6c855b6..62a0f6116b 100644
--- a/EdkNt32Pkg/Nt32.fpd
+++ b/EdkNt32Pkg/Nt32.fpd
@@ -3473,6 +3473,73 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<FfsFormatKey>BS_DRIVER</FfsFormatKey>
</ModuleSaBuildOptions>
</ModuleSA>
+ <ModuleSA SupArchList="IA32" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674" ModuleGuid="9B680FCE-AD6B-4F3A-B60B-F59899003443">
+ <Libraries>
+ <Instance ModuleGuid="ff5c7a2c-ab7a-4366-8616-11c6e53247b6" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="f1bbe03d-2f28-4dee-bec7-d98d7a30c36a" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="3a004ba5-efe0-4a61-9f1a-267a46ae5ba9" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="331deb15-454b-48d8-9b74-70d01f3f3556" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="3ddc3b12-99ea-4364-b315-6310a2050be5" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="a86fbfca-0183-4eeb-aa8a-762e3b7da1f3" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ </Libraries>
+ <PcdBuildDefinition>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdMaximumUnicodeStringLength</C_Name>
+ <Token>0x00000001</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>1000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdMaximumAsciiStringLength</C_Name>
+ <Token>0x00000002</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>1000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdDebugPropertyMask</C_Name>
+ <Token>0x00000005</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT8</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>0x0f</Value>
+ </PcdData>
+ <PcdData ItemType="PATCHABLE_IN_MODULE">
+ <C_Name>PcdDebugPrintErrorLevel</C_Name>
+ <Token>0x00000006</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>0x80000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdReportStatusCodePropertyMask</C_Name>
+ <Token>0x00000007</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT8</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>0x07</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdDebugClearMemoryValue</C_Name>
+ <Token>0x00000008</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT8</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>0xAF</Value>
+ </PcdData>
+ </PcdBuildDefinition>
+ <ModuleSaBuildOptions>
+ <FvBinding>FV_RECOVERY</FvBinding>
+ <FfsFormatKey>BS_DRIVER</FfsFormatKey>
+ </ModuleSaBuildOptions>
+ </ModuleSA>
<ModuleSA SupArchList="IA32" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674" ModuleGuid="6B38F7B4-AD98-40e9-9093-ACA2B5A253C4">
<Libraries>
<Instance ModuleGuid="ff5c7a2c-ab7a-4366-8616-11c6e53247b6" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
@@ -4579,6 +4646,98 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
<FfsFormatKey>BS_DRIVER</FfsFormatKey>
</ModuleSaBuildOptions>
</ModuleSA>
+ <ModuleSA SupArchList="IA32" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674" ModuleGuid="BDFE430E-8F2A-4db0-9991-6F856594777E">
+ <Libraries>
+ <Instance ModuleGuid="ff5c7a2c-ab7a-4366-8616-11c6e53247b6" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="f1bbe03d-2f28-4dee-bec7-d98d7a30c36a" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="3a004ba5-efe0-4a61-9f1a-267a46ae5ba9" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="331deb15-454b-48d8-9b74-70d01f3f3556" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="52af22ae-9901-4484-8cdc-622dd5838b09" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="3ddc3b12-99ea-4364-b315-6310a2050be5" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="50bcb105-6634-441d-b403-659110a03ad2" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>
+ <Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ <Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
+ </Libraries>
+ <PcdBuildDefinition>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdMaximumUnicodeStringLength</C_Name>
+ <Token>0x00000001</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>1000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdMaximumAsciiStringLength</C_Name>
+ <Token>0x00000002</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>1000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdSpinLockTimeout</C_Name>
+ <Token>0x00000004</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>10000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdMaximumLinkedListLength</C_Name>
+ <Token>0x00000003</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>1000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdReportStatusCodePropertyMask</C_Name>
+ <Token>0x00000007</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT8</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>0x07</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdDebugPropertyMask</C_Name>
+ <Token>0x00000005</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT8</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>0x0f</Value>
+ </PcdData>
+ <PcdData ItemType="PATCHABLE_IN_MODULE">
+ <C_Name>PcdDebugPrintErrorLevel</C_Name>
+ <Token>0x00000006</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT32</DatumType>
+ <MaxDatumSize>4</MaxDatumSize>
+ <Value>0x80000000</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdDebugClearMemoryValue</C_Name>
+ <Token>0x00000008</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT8</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>0xAF</Value>
+ </PcdData>
+ <PcdData ItemType="FIXED_AT_BUILD">
+ <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>
+ <Token>0x00000009</Token>
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>
+ <DatumType>UINT8</DatumType>
+ <MaxDatumSize>1</MaxDatumSize>
+ <Value>0</Value>
+ </PcdData>
+ </PcdBuildDefinition>
+ <ModuleSaBuildOptions>
+ <FvBinding>FV_MAIN</FvBinding>
+ <FfsFormatKey>BS_DRIVER</FfsFormatKey>
+ </ModuleSaBuildOptions>
+ </ModuleSA>
<ModuleSA SupArchList="IA32" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674" ModuleGuid="0167CCC4-D0F7-4f21-A3EF-9E64B7CDCE8B">
<Libraries>
<Instance ModuleGuid="ff5c7a2c-ab7a-4366-8616-11c6e53247b6" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
diff --git a/MdePkg/Include/Guid/PcAnsi.h b/MdePkg/Include/Guid/PcAnsi.h
index c9b74ab03e..afbfc73bab 100644
--- a/MdePkg/Include/Guid/PcAnsi.h
+++ b/MdePkg/Include/Guid/PcAnsi.h
@@ -40,6 +40,16 @@
0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88 } \
}
+#define EFI_UART_DEVICE_PATH_GUID \
+ { \
+ 0x37499a9d, 0x542f, 0x4c89, {0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 } \
+ }
+
+#define EFI_SAS_DEVICE_PATH_GUID \
+ { \
+ 0xb4dd87d4, 0x8b00, 0xd911, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \
+ }
+
extern EFI_GUID gEfiPcAnsiGuid;
extern EFI_GUID gEfiVT100Guid;
extern EFI_GUID gEfiVT100PlusGuid;
diff --git a/MdePkg/Include/IndustryStandard/Usb.h b/MdePkg/Include/IndustryStandard/Usb.h
index dca7351ff1..d3328a5461 100644
--- a/MdePkg/Include/IndustryStandard/Usb.h
+++ b/MdePkg/Include/IndustryStandard/Usb.h
@@ -255,6 +255,8 @@ typedef struct {
#define USB_PORT_STAT_RESET 0x0010
#define USB_PORT_STAT_POWER 0x0100
#define USB_PORT_STAT_LOW_SPEED 0x0200
+#define USB_PORT_STAT_HIGH_SPEED 0x0400
+#define USB_PORT_STAT_OWNER 0x0800
#define USB_PORT_STAT_C_CONNECTION 0x0001
#define USB_PORT_STAT_C_ENABLE 0x0002
@@ -270,6 +272,7 @@ typedef enum {
EfiUsbPortSuspend = 2,
EfiUsbPortReset = 4,
EfiUsbPortPower = 8,
+ EfiUsbPortOwner = 13,
EfiUsbPortConnectChange = 16,
EfiUsbPortEnableChange = 17,
EfiUsbPortSuspendChange = 18,
diff --git a/MdePkg/Include/Protocol/DevicePathFromText.h b/MdePkg/Include/Protocol/DevicePathFromText.h
index a3a6c431ca..0d1ce3208a 100644
--- a/MdePkg/Include/Protocol/DevicePathFromText.h
+++ b/MdePkg/Include/Protocol/DevicePathFromText.h
@@ -64,8 +64,8 @@ EFI_DEVICE_PATH_PROTOCOL*
;
typedef struct {
- EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertDeviceNodeFromText;
- EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertDevicePathFromText;
+ EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode;
+ EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath;
} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;
extern EFI_GUID gEfiDevicePathFromTextProtocolGuid;
diff --git a/MdePkg/Include/Protocol/Usb2HostController.h b/MdePkg/Include/Protocol/Usb2HostController.h
index 5326d5b623..2a9d02da07 100644
--- a/MdePkg/Include/Protocol/Usb2HostController.h
+++ b/MdePkg/Include/Protocol/Usb2HostController.h
@@ -269,6 +269,7 @@ EFI_STATUS
IN OUT UINT8 *DataToggle,
IN UINTN PollingInterval OPTIONAL,
IN UINTN DataLength OPTIONAL,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator OPTIONAL,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction OPTIONAL,
IN VOID *Context OPTIONAL
)
@@ -305,16 +306,17 @@ EFI_STATUS
typedef
EFI_STATUS
(EFIAPI *EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER) (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN OUT VOID *Data,
- IN OUT UINTN *DataLength,
- IN OUT UINT8 *DataToggle,
- IN UINTN TimeOut,
- OUT UINT32 *TransferResult
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
)
;
diff --git a/MdePkg/Include/Uefi/UefiSpec.h b/MdePkg/Include/Uefi/UefiSpec.h
index 9993cd44e7..3410ad2821 100644
--- a/MdePkg/Include/Uefi/UefiSpec.h
+++ b/MdePkg/Include/Uefi/UefiSpec.h
@@ -1839,11 +1839,7 @@ typedef struct {
#define HW_CONTROLLER_DP 0x05
typedef struct {
EFI_DEVICE_PATH_PROTOCOL Header;
-#if EDK_RELEASE_VERSION >= 0x00020000
UINT32 ControllerNumber;
-#else
- UINT32 Controller;
-#endif
} CONTROLLER_DEVICE_PATH;
//
@@ -1945,6 +1941,7 @@ typedef struct {
UINT8 DeviceProtocol;
} USB_CLASS_DEVICE_PATH;
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
#define MSG_USB_WWID_DP 0x10
typedef struct {
EFI_DEVICE_PATH_PROTOCOL Header;
@@ -1957,8 +1954,9 @@ typedef struct {
#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11
typedef struct {
EFI_DEVICE_PATH_PROTOCOL Header;
- UINT8 LUN;
+ UINT8 Lun;
} DEVICE_LOGICAL_UNIT_DEVICE_PATH;
+#endif
#define MSG_I2O_DP 0x06
typedef struct {
@@ -2030,8 +2028,27 @@ typedef struct {
#define DEVICE_PATH_MESSAGING_VT_100 EFI_VT_100_GUID
#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID
#define DEVICE_PATH_MESSAGING_VT_UTF8 EFI_VT_UTF8_GUID
-#define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+
+#define DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL EFI_UART_DEVICE_PATH_GUID
+#define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT32 FlowControlMap;
+} UART_FLOW_CONTROL_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT32 Reserved;
+ UINT64 SasAddress;
+ UINT64 Lun;
+ UINT16 DeviceTopology;
+ UINT16 RelativeTargetPort;
+} SAS_DEVICE_PATH;
#define MSG_ISCSI_DP 0x13
typedef struct {
@@ -2053,6 +2070,7 @@ typedef struct {
#define ISCSI_LOGIN_OPTION_CHAP_BI 0x0000
#define ISCSI_LOGIN_OPTION_CHAP_UNI 0x2000
+#endif
//
// Media Device Path