--- /dev/null
+/*++\r
+\r
+Copyright 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ ComponentName.c\r
+\r
+Abstract:\r
+\r
+--*/\r
+\r
+#include "Ehci.h"\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+EhciComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle, OPTIONAL\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ );\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL gEhciComponentName = {\r
+ EhciComponentNameGetDriverName,\r
+ EhciComponentNameGetControllerName,\r
+ "eng"\r
+};\r
+\r
+static EFI_UNICODE_STRING_TABLE mEhciDriverNameTable[] = {\r
+ { "eng", L"UEFI Usb Ehci Driver" },\r
+ { NULL , NULL }\r
+};\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciComponentNameGetDriverName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **DriverName\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.\r
+\r
+ Arguments:\r
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ Language - A pointer to a three character ISO 639-2 language identifier.\r
+ This is the language of the driver name that that the caller \r
+ is requesting, and it must match one of the languages specified\r
+ in SupportedLanguages. The number of languages supported by a \r
+ driver is up to the driver writer.\r
+ DriverName - A pointer to the Unicode string to return. This Unicode string\r
+ is the name of the driver specified by This in the language \r
+ specified by Language.\r
+\r
+ Returns:\r
+ EFI_SUCCESS - The Unicode string for the Driver specified by This\r
+ and the language specified by Language was returned \r
+ in DriverName.\r
+ EFI_INVALID_PARAMETER - Language is NULL.\r
+ EFI_INVALID_PARAMETER - DriverName is NULL.\r
+ EFI_UNSUPPORTED - The driver specified by This does not support the \r
+ language specified by Language.\r
+\r
+--*/\r
+{\r
+ return LookupUnicodeString (\r
+ Language,\r
+ gEhciComponentName.SupportedLanguages,\r
+ mEhciDriverNameTable,\r
+ DriverName\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciComponentNameGetControllerName (\r
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,\r
+ IN EFI_HANDLE ControllerHandle,\r
+ IN EFI_HANDLE ChildHandle, OPTIONAL\r
+ IN CHAR8 *Language,\r
+ OUT CHAR16 **ControllerName\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Retrieves a Unicode string that is the user readable name of the controller\r
+ that is being managed by an EFI Driver.\r
+\r
+ Arguments:\r
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.\r
+ ControllerHandle - The handle of a controller that the driver specified by \r
+ This is managing. This handle specifies the controller \r
+ whose name is to be returned.\r
+ ChildHandle - The handle of the child controller to retrieve the name \r
+ of. This is an optional parameter that may be NULL. It \r
+ will be NULL for device drivers. It will also be NULL \r
+ for a bus drivers that wish to retrieve the name of the \r
+ bus controller. It will not be NULL for a bus driver \r
+ that wishes to retrieve the name of a child controller.\r
+ Language - A pointer to a three character ISO 639-2 language \r
+ identifier. This is the language of the controller name \r
+ that that the caller is requesting, and it must match one\r
+ of the languages specified in SupportedLanguages. The \r
+ number of languages supported by a driver is up to the \r
+ driver writer.\r
+ ControllerName - A pointer to the Unicode string to return. This Unicode\r
+ string is the name of the controller specified by \r
+ ControllerHandle and ChildHandle in the language \r
+ specified by Language from the point of view of the \r
+ driver specified by This. \r
+\r
+ Returns:\r
+ EFI_SUCCESS - The Unicode string for the user readable name in the \r
+ language specified by Language for the driver \r
+ specified by This was returned in DriverName.\r
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid \r
+ EFI_HANDLE.\r
+ EFI_INVALID_PARAMETER - Language is NULL.\r
+ EFI_INVALID_PARAMETER - ControllerName is NULL.\r
+ EFI_UNSUPPORTED - The driver specified by This is not currently \r
+ managing the controller specified by \r
+ ControllerHandle and ChildHandle.\r
+ EFI_UNSUPPORTED - The driver specified by This does not support the \r
+ language specified by Language.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *EhciDev;\r
+ EFI_USB2_HC_PROTOCOL *Usb2Hc;\r
+\r
+ //\r
+ // This is a device driver, so ChildHandle must be NULL.\r
+ //\r
+ if (ChildHandle != NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // Get the device context\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ ControllerHandle,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ (VOID **) &Usb2Hc,\r
+ gEhciDriverBinding.DriverBindingHandle,\r
+ ControllerHandle,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ EhciDev = USB2_HC_DEV_FROM_THIS (Usb2Hc);\r
+\r
+ return LookupUnicodeString (\r
+ Language,\r
+ gEhciComponentName.SupportedLanguages,\r
+ EhciDev->ControllerNameTable,\r
+ ControllerName\r
+ );\r
+\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ Ehci.c\r
+ \r
+Abstract: \r
+ \r
+\r
+Revision History\r
+--*/\r
+\r
+\r
+#include "Ehci.h"\r
+\r
+UINTN gEHCDebugLevel = EFI_D_INFO;\r
+UINTN gEHCErrorLevel = EFI_D_ERROR;\r
+\r
+//\r
+// Prototypes\r
+// Driver model protocol interface\r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ );\r
+\r
+//\r
+// Ehci protocol interface\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetCapability (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ OUT UINT8 *MaxSpeed,\r
+ OUT UINT8 *PortNumber,\r
+ OUT UINT8 *Is64BitCapable\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciReset (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT16 Attributes\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetState (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ OUT EFI_USB_HC_STATE *State\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSetState (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN EFI_USB_HC_STATE State\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciControlTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN EFI_USB_DEVICE_REQUEST *Request,\r
+ IN EFI_USB_DATA_DIRECTION TransferDirection,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciBulkTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciAsyncInterruptTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaxiumPacketLength,\r
+ IN BOOLEAN IsNewTransfer,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN PollingInterval,\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,\r
+ IN VOID *Context OPTIONAL\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSyncInterruptTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciIsochronousTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciAsyncIsochronousTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,\r
+ IN VOID *Context\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetRootHubPortStatus (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 PortNumber,\r
+ OUT EFI_USB_PORT_STATUS *PortStatus\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSetRootHubPortFeature (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciClearRootHubPortFeature (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ );\r
+\r
+//\r
+// Ehci Driver Global Variables\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gEhciDriverBinding = {\r
+ EhciDriverBindingSupported,\r
+ EhciDriverBindingStart,\r
+ EhciDriverBindingStop,\r
+ 0x10,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
+UINT32 mUsbCapabilityLen;\r
+UINT32 mDeviceSpeed[16];\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingSupported (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ \r
+ Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
+ that has Usb2HcProtocol installed will be supported.\r
+\r
+ Arguments:\r
+ \r
+ This - Protocol instance pointer.\r
+ Controlle - Handle of device to test\r
+ RemainingDevicePath - Not used\r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS This driver supports this device.\r
+ EFI_UNSUPPORTED This driver does not support this device.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ USB_CLASSC UsbClassCReg;\r
+\r
+ \r
+ //\r
+ // Test whether there is PCI IO Protocol attached on the controller handle.\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto exit;\r
+ }\r
+\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ CLASSC,\r
+ sizeof (USB_CLASSC) / sizeof (UINT8),\r
+ &UsbClassCReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ Status = EFI_UNSUPPORTED;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Test whether the controller belongs to Ehci type\r
+ //\r
+ if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||\r
+ (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||\r
+ (UsbClassCReg.PI != PCI_CLASSC_PI_EHCI)\r
+ ) {\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+ Status = EFI_UNSUPPORTED;\r
+ goto exit;\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingStart (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ \r
+ Starting the Usb EHCI Driver\r
+\r
+ Arguments:\r
+ \r
+ This - Protocol instance pointer.\r
+ Controller - Handle of device to test\r
+ RemainingDevicePath - Not used\r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS supports this device.\r
+ EFI_UNSUPPORTED do not support this device.\r
+ EFI_DEVICE_ERROR cannot be started due to device Error\r
+ EFI_OUT_OF_RESOURCES cannot allocate resources\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT8 MaxSpeed;\r
+ UINT8 PortNumber;\r
+ UINT8 Is64BitCapable;\r
+ \r
+ //\r
+ // Open the PciIo Protocol\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **) &PciIo,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Enable the USB Host Controller\r
+ //\r
+ Status = PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationEnable,\r
+ EFI_PCI_DEVICE_ENABLE,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto close_pciio_protocol;\r
+ }\r
+ \r
+ //\r
+ // Allocate memory for EHC private data structure\r
+ //\r
+ HcDev = AllocateZeroPool (sizeof (USB2_HC_DEV));\r
+ if (NULL == HcDev) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto close_pciio_protocol;\r
+ }\r
+ \r
+ //\r
+ // Init EFI_USB2_HC_PROTOCOL interface and private data structure\r
+ //\r
+ HcDev->Usb2Hc.GetCapability = EhciGetCapability;\r
+ HcDev->Usb2Hc.Reset = EhciReset;\r
+ HcDev->Usb2Hc.GetState = EhciGetState;\r
+ HcDev->Usb2Hc.SetState = EhciSetState;\r
+ HcDev->Usb2Hc.ControlTransfer = EhciControlTransfer;\r
+ HcDev->Usb2Hc.BulkTransfer = EhciBulkTransfer;\r
+ HcDev->Usb2Hc.AsyncInterruptTransfer = EhciAsyncInterruptTransfer;\r
+ HcDev->Usb2Hc.SyncInterruptTransfer = EhciSyncInterruptTransfer;\r
+ HcDev->Usb2Hc.IsochronousTransfer = EhciIsochronousTransfer;\r
+ HcDev->Usb2Hc.AsyncIsochronousTransfer = EhciAsyncIsochronousTransfer;\r
+ HcDev->Usb2Hc.GetRootHubPortStatus = EhciGetRootHubPortStatus;\r
+ HcDev->Usb2Hc.SetRootHubPortFeature = EhciSetRootHubPortFeature;\r
+ HcDev->Usb2Hc.ClearRootHubPortFeature = EhciClearRootHubPortFeature;\r
+ HcDev->Usb2Hc.MajorRevision = 0x1;\r
+ HcDev->Usb2Hc.MinorRevision = 0x1;\r
+\r
+ HcDev->AsyncRequestList = NULL;\r
+ HcDev->ControllerNameTable = NULL;\r
+ HcDev->Signature = USB2_HC_DEV_SIGNATURE;\r
+ HcDev->PciIo = PciIo;\r
+\r
+ //\r
+ // Install USB2_HC_PROTOCOL\r
+ //\r
+ Status = gBS->InstallProtocolInterface (\r
+ &Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ &HcDev->Usb2Hc\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto free_pool;\r
+ }\r
+ \r
+ //\r
+ // Get Capability Register Length\r
+ //\r
+ Status = GetCapabilityLen (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto uninstall_usb2hc_protocol;\r
+ }\r
+ \r
+ //\r
+ // Create and Init Perodic Frame List\r
+ //\r
+ Status = EhciGetCapability (\r
+ &HcDev->Usb2Hc, \r
+ &MaxSpeed, \r
+ &PortNumber, \r
+ &Is64BitCapable\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto uninstall_usb2hc_protocol;\r
+ }\r
+ HcDev->Is64BitCapable = Is64BitCapable;\r
+ \r
+ //\r
+ // Create and Init Perodic Frame List\r
+ //\r
+ Status = InitialPeriodicFrameList (\r
+ HcDev, \r
+ EHCI_MAX_FRAME_LIST_LENGTH\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto uninstall_usb2hc_protocol;\r
+ }\r
+ \r
+ //\r
+ // Init memory pool management\r
+ //\r
+ Status = InitialMemoryManagement (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto deinit_perodic_frame_list;\r
+ }\r
+ \r
+ //\r
+ // Create AsyncRequest Polling Timer\r
+ //\r
+ Status = CreatePollingTimer (HcDev, AsyncRequestMoniter);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto deinit_memory_management;\r
+ }\r
+ \r
+ //\r
+ // Default Maxximum Interrupt Interval is 8, \r
+ // it means that 8 micro frame = 1ms\r
+ //\r
+ \r
+ //\r
+ // Start the Host Controller\r
+ //\r
+ if (IsEhcHalted (HcDev)) {\r
+ Status = StartScheduleExecution (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto deinit_timer;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Set all ports routing to EHC\r
+ //\r
+ Status = SetPortRoutingEhc (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto deinit_timer;\r
+ }\r
+ \r
+ //\r
+ // Component name protocol\r
+ //\r
+ Status = AddUnicodeString (\r
+ "eng",\r
+ gEhciComponentName.SupportedLanguages,\r
+ &HcDev->ControllerNameTable,\r
+ L"Usb Enhanced Host Controller"\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto deinit_timer;\r
+ }\r
+\r
+ goto exit;\r
+\r
+ //\r
+ // Error handle process\r
+ //\r
+deinit_timer:\r
+ DestoryPollingTimer (HcDev);\r
+deinit_memory_management:\r
+ DeinitialMemoryManagement (HcDev);\r
+deinit_perodic_frame_list:\r
+ DeinitialPeriodicFrameList (HcDev);\r
+uninstall_usb2hc_protocol:\r
+ gBS->UninstallProtocolInterface (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ &HcDev->Usb2Hc\r
+ );\r
+free_pool:\r
+ gBS->FreePool (HcDev);\r
+close_pciio_protocol:\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciDriverBindingStop (\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ \r
+ Stop this driver on ControllerHandle. Support stoping any child handles\r
+ created by this driver.\r
+\r
+ Arguments:\r
+ \r
+ This - Protocol instance pointer.\r
+ Controller - Handle of device to stop driver on\r
+ NumberOfChildren - Number of Children in the ChildHandleBuffer\r
+ ChildHandleBuffer - List of handles for the children we need to stop.\r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_USB2_HC_PROTOCOL *Usb2Hc;\r
+ USB2_HC_DEV *HcDev;\r
+\r
+ //\r
+ // Test whether the Controller handler passed in is a valid\r
+ // Usb controller handle that should be supported, if not,\r
+ // return the error status directly\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ (VOID **) &Usb2Hc,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (Usb2Hc);\r
+\r
+ //\r
+ // free all the controller related memory and uninstall UHCI Protocol.\r
+ //\r
+ Status = gBS->UninstallProtocolInterface (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ Usb2Hc\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Set Host Controller state as halt\r
+ //\r
+ Status = Usb2Hc->SetState (\r
+ Usb2Hc, \r
+ EfiUsbHcStateHalt\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Stop AsyncRequest Polling Timer\r
+ //\r
+ Status = StopPollingTimer (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Destroy Asynchronous Request Event\r
+ //\r
+ DestoryPollingTimer (HcDev);\r
+\r
+ //\r
+ // Destroy Perodic Frame List\r
+ //\r
+ DeinitialPeriodicFrameList (HcDev);\r
+\r
+ //\r
+ // Deinit Ehci pool memory management\r
+ //\r
+ DeinitialMemoryManagement (HcDev);\r
+\r
+ //\r
+ // Denint Unicode String Table\r
+ //\r
+ FreeUnicodeStringTable (HcDev->ControllerNameTable);\r
+\r
+ //\r
+ // Disable the USB Host Controller\r
+ //\r
+ Status = HcDev->PciIo->Attributes (\r
+ HcDev->PciIo,\r
+ EfiPciIoAttributeOperationDisable,\r
+ EFI_PCI_DEVICE_ENABLE,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ gBS->FreePool (HcDev);\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetCapability (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ OUT UINT8 *MaxSpeed,\r
+ OUT UINT8 *PortNumber,\r
+ OUT UINT8 *Is64BitCapable\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Retrieves the capablility of root hub ports.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB_HC_PROTOCOL instance.\r
+ MaxSpeed - A pointer to the number of the host controller.\r
+ PortNumber - A pointer to the number of the root hub ports.\r
+ Is64BitCapable - A pointer to the flag for whether controller supports \r
+ 64-bit memory addressing.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS host controller capability were retrieved successfully.\r
+ EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
+ EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the capabilities. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINT32 HcStructParamsAddr;\r
+ UINT32 HcStructParamsReg;\r
+ UINT32 HcCapParamsAddr;\r
+ UINT32 HcCapParamsReg;\r
+\r
+ if (MaxSpeed == NULL || PortNumber == NULL || Is64BitCapable == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ HcStructParamsAddr = HCSPARAMS;\r
+ HcCapParamsAddr = HCCPARAMS;\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+ Status = ReadEhcCapabiltiyReg (\r
+ HcDev,\r
+ HcStructParamsAddr,\r
+ &HcStructParamsReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = ReadEhcCapabiltiyReg (\r
+ HcDev,\r
+ HcCapParamsAddr,\r
+ &HcCapParamsReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ *MaxSpeed = EFI_USB_SPEED_HIGH;\r
+ *PortNumber = (UINT8) (HcStructParamsReg & HCSP_NPORTS);\r
+ *Is64BitCapable = (UINT8) (HcCapParamsReg & HCCP_64BIT);\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciReset (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT16 Attributes\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Provides software reset for the USB host controller.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance. \r
+ Attributes - A bit mask of the reset operation to perform. \r
+ See below for a list of the supported bit mask values.\r
+ \r
+ #define EFI_USB_HC_RESET_GLOBAL 0x0001\r
+ #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002\r
+ #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004\r
+ #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008\r
+\r
+ EFI_USB_HC_RESET_GLOBAL \r
+ If this bit is set, a global reset signal will be sent to the USB bus.\r
+ This resets all of the USB bus logic, including the USB host \r
+ controller hardware and all the devices attached on the USB bus.\r
+ EFI_USB_HC_RESET_HOST_CONTROLLER \r
+ If this bit is set, the USB host controller hardware will be reset. \r
+ No reset signal will be sent to the USB bus.\r
+ EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG\r
+ If this bit is set, a global reset signal will be sent to the USB bus.\r
+ This resets all of the USB bus logic, including the USB host \r
+ controller hardware and all the devices attached on the USB bus. \r
+ If this is an EHCI controller and the debug port has configured, then \r
+ this is will still reset the host controller.\r
+ EFI_USB_HC_RESET_HOST_WITH_DEBUG\r
+ If this bit is set, the USB host controller hardware will be reset. \r
+ If this is an EHCI controller and the debug port has been configured,\r
+ then this will still reset the host controller.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The reset operation succeeded.\r
+ EFI_INVALID_PARAMETER \r
+ Attributes is not valid.\r
+ EFI_UNSUPPOURTED\r
+ The type of reset specified by Attributes is not currently supported by\r
+ the host controller hardware.\r
+ EFI_ACCESS_DENIED\r
+ Reset operation is rejected due to the debug port being configured and \r
+ active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or \r
+ EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to\r
+ perform reset operation for this host controller.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to perform \r
+ the reset operation.\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINTN FrameIndex;\r
+ FRAME_LIST_ENTRY *FrameEntryPtr;\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+ switch (Attributes) {\r
+\r
+ case EFI_USB_HC_RESET_GLOBAL:\r
+ \r
+ //\r
+ // Same behavior as Host Controller Reset\r
+ //\r
+\r
+ case EFI_USB_HC_RESET_HOST_CONTROLLER:\r
+ \r
+ //\r
+ // Host Controller must be Halt when Reset it\r
+ //\r
+ if (IsEhcHalted (HcDev)) {\r
+ Status = ResetEhc (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ //\r
+ // Set to zero by Host Controller when reset process completes\r
+ //\r
+ Status = WaitForEhcReset (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_TIMEOUT;\r
+ goto exit;\r
+ }\r
+ } else {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ //\r
+ // only asynchronous interrupt transfers are always alive on the bus, need to cleanup\r
+ //\r
+ CleanUpAllAsyncRequestTransfer (HcDev);\r
+ Status = ClearEhcAllStatus (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ //\r
+ // Set appropriate 4G Segment Selector\r
+ //\r
+ Status = SetCtrlDataStructSeg (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ //\r
+ // Init Perodic List Base Addr and Frame List\r
+ //\r
+ Status = SetFrameListBaseAddr (\r
+ HcDev, \r
+ (UINT32) GET_0B_TO_31B (HcDev->PeriodicFrameListBuffer)\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;\r
+ for (FrameIndex = 0; FrameIndex < HcDev->PeriodicFrameListLength; FrameIndex++) {\r
+ FrameEntryPtr->LinkTerminate = TRUE;\r
+ FrameEntryPtr++;\r
+ }\r
+\r
+ //\r
+ // Start the Host Controller\r
+ //\r
+ if (IsEhcHalted (HcDev)) {\r
+ Status = StartScheduleExecution (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Set all ports routing to EHC\r
+ //\r
+ Status = SetPortRoutingEhc (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ break;\r
+\r
+ case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:\r
+ \r
+ Status = EFI_UNSUPPORTED;\r
+ break;\r
+\r
+ case EFI_USB_HC_RESET_HOST_WITH_DEBUG:\r
+ \r
+ Status = EFI_UNSUPPORTED;\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetState (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ OUT EFI_USB_HC_STATE *State\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Retrieves current state of the USB host controller.\r
+ \r
+ Arguments:\r
+ \r
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ State A pointer to the EFI_USB_HC_STATE data structure that \r
+ indicates current state of the USB host controller. \r
+ Type EFI_USB_HC_STATE is defined below.\r
+ \r
+ typedef enum {\r
+ EfiUsbHcStateHalt,\r
+ EfiUsbHcStateOperational,\r
+ EfiUsbHcStateSuspend,\r
+ EfiUsbHcStateMaximum\r
+ } EFI_USB_HC_STATE;\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The state information of the host controller was returned in State.\r
+ EFI_INVALID_PARAMETER \r
+ State is NULL.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to retrieve the \r
+ host controller's current state. \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINT32 UsbStatusAddr;\r
+ UINT32 UsbStatusReg;\r
+\r
+ if (State == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ UsbStatusAddr = USBSTS;\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ &UsbStatusReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ if (UsbStatusReg & USBSTS_HCH) {\r
+ *State = EfiUsbHcStateHalt;\r
+ } else {\r
+ *State = EfiUsbHcStateOperational;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSetState (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN EFI_USB_HC_STATE State\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Sets the USB host controller to a specific state.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ State - Indicates the state of the host controller that will be set.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The USB host controller was successfully placed in the state \r
+ specified by State.\r
+ EFI_INVALID_PARAMETER \r
+ State is invalid.\r
+ EFI_DEVICE_ERROR \r
+ Failed to set the state specified by State due to device error. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+ EFI_USB_HC_STATE CurrentState;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+ Status = EhciGetState (This, &CurrentState);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ switch (State) {\r
+\r
+ case EfiUsbHcStateHalt:\r
+\r
+ if (EfiUsbHcStateHalt == CurrentState) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ } else if (EfiUsbHcStateOperational == CurrentState) {\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg &= ~USBCMD_RS;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ //\r
+ // Ensure the HC is in halt status after send the stop command\r
+ //\r
+ Status = WaitForEhcHalt (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_TIMEOUT;\r
+ goto exit;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case EfiUsbHcStateOperational:\r
+ \r
+ if (IsEhcSysError (HcDev)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ if (EfiUsbHcStateOperational == CurrentState) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ } else if (EfiUsbHcStateHalt == CurrentState) {\r
+ //\r
+ // Set Host Controller Run\r
+ //\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_RS;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case EfiUsbHcStateSuspend:\r
+ \r
+ Status = EFI_UNSUPPORTED;\r
+ break;\r
+\r
+ default:\r
+ \r
+ Status = EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciGetRootHubPortStatus (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 PortNumber,\r
+ OUT EFI_USB_PORT_STATUS *PortStatus\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Retrieves the current status of a USB root hub port.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL.\r
+ PortNumber - Specifies the root hub port from which the status \r
+ is to be retrieved. This value is zero-based. For example, \r
+ if a root hub has two ports, then the first port is numbered 0,\r
+ and the second port is numbered 1.\r
+ PortStatus - A pointer to the current port status bits and \r
+ port status change bits. \r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS The status of the USB root hub port specified \r
+ by PortNumber was returned in PortStatus.\r
+ EFI_INVALID_PARAMETER PortNumber is invalid. \r
+ EFI_DEVICE_ERROR Can't read register \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINT32 PortStatusControlAddr;\r
+ UINT32 PortStatusControlReg;\r
+ UINT8 MaxSpeed;\r
+ UINT8 TotalPortNumber;\r
+ UINT8 Is64BitCapable;\r
+\r
+ if (PortStatus == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ EhciGetCapability (\r
+ This, \r
+ &MaxSpeed, \r
+ &TotalPortNumber, \r
+ &Is64BitCapable\r
+ );\r
+ \r
+ if (PortNumber >= TotalPortNumber) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));\r
+\r
+ //\r
+ // Clear port status\r
+ //\r
+ PortStatus->PortStatus = 0;\r
+ PortStatus->PortChangeStatus = 0;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ &PortStatusControlReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Fill Port Status bits\r
+ //\r
+ \r
+ //\r
+ // Current Connect Status\r
+ //\r
+ if (PORTSC_CCS & PortStatusControlReg) {\r
+ PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;\r
+ }\r
+ //\r
+ // Port Enabled/Disabled\r
+ //\r
+ if (PORTSC_PED & PortStatusControlReg) {\r
+ PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;\r
+ }\r
+ //\r
+ // Port Suspend\r
+ //\r
+ if (PORTSC_SUSP & PortStatusControlReg) {\r
+ PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;\r
+ }\r
+ //\r
+ // Over-current Active\r
+ //\r
+ if (PORTSC_OCA & PortStatusControlReg) {\r
+ PortStatus->PortStatus |= USB_PORT_STAT_OVERCURRENT;\r
+ }\r
+ //\r
+ // Port Reset\r
+ //\r
+ if (PORTSC_PR & PortStatusControlReg) {\r
+ PortStatus->PortStatus |= USB_PORT_STAT_RESET;\r
+ }\r
+ //\r
+ // Port Power\r
+ //\r
+ if (PORTSC_PP & PortStatusControlReg) {\r
+ PortStatus->PortStatus |= USB_PORT_STAT_POWER;\r
+ }\r
+ //\r
+ // Port Owner\r
+ //\r
+ if (PORTSC_PO & PortStatusControlReg) {\r
+ PortStatus->PortStatus |= USB_PORT_STAT_OWNER;\r
+ }\r
+ //\r
+ // Identify device speed\r
+ //\r
+ if (PORTSC_LS_KSTATE & PortStatusControlReg) {\r
+ //\r
+ // Low Speed Device Attached\r
+ //\r
+ PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
+ } else {\r
+ //\r
+ // Not Low Speed Device Attached\r
+ //\r
+ if ((PORTSC_CCS & PortStatusControlReg) && (PORTSC_CSC & PortStatusControlReg)) {\r
+ mDeviceSpeed[PortNumber] = IsHighSpeedDevice (This, PortNumber) ? USB_PORT_STAT_HIGH_SPEED : 0;\r
+ }\r
+ PortStatus->PortStatus |= mDeviceSpeed[PortNumber];\r
+ }\r
+ //\r
+ // Fill Port Status Change bits\r
+ //\r
+ //\r
+ // Connect Status Change\r
+ //\r
+ if (PORTSC_CSC & PortStatusControlReg) {\r
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;\r
+ }\r
+ //\r
+ // Port Enabled/Disabled Change\r
+ //\r
+ if (PORTSC_PEDC & PortStatusControlReg) {\r
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;\r
+ }\r
+ //\r
+ // Port Over Current Change\r
+ //\r
+ if (PORTSC_OCC & PortStatusControlReg) {\r
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_OVERCURRENT;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSetRootHubPortFeature (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Sets a feature for the specified root hub port.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL.\r
+ PortNumber - Specifies the root hub port whose feature \r
+ is requested to be set.\r
+ PortFeature - Indicates the feature selector associated \r
+ with the feature set request. \r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The feature specified by PortFeature was set for the \r
+ USB root hub port specified by PortNumber.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid or PortFeature is invalid.\r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINT32 PortStatusControlAddr;\r
+ UINT32 PortStatusControlReg;\r
+ UINT8 MaxSpeed;\r
+ UINT8 TotalPortNumber;\r
+ UINT8 Is64BitCapable;\r
+\r
+ EhciGetCapability (\r
+ This, \r
+ &MaxSpeed, \r
+ &TotalPortNumber, \r
+ &Is64BitCapable\r
+ );\r
+\r
+ if (PortNumber >= TotalPortNumber) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ &PortStatusControlReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ switch (PortFeature) {\r
+\r
+ case EfiUsbPortEnable:\r
+ \r
+ //\r
+ // Sofeware can't set this bit, Port can only be enable by the Host Controller\r
+ // as a part of the reset and enable\r
+ //\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg |= PORTSC_PED;\r
+ break;\r
+\r
+ case EfiUsbPortSuspend:\r
+ \r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg |= PORTSC_SUSP;\r
+ break;\r
+\r
+ case EfiUsbPortReset:\r
+ \r
+ //\r
+ // Make sure Host Controller not halt before reset it\r
+ //\r
+ if (IsEhcHalted (HcDev)) {\r
+ Status = StartScheduleExecution (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ Status = WaitForEhcNotHalt (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((gEHCDebugLevel, "WaitForEhcNotHalt TimeOut\n"));\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ }\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg |= PORTSC_PR;\r
+ //\r
+ // Set one to PortReset bit must also set zero to PortEnable bit\r
+ //\r
+ PortStatusControlReg &= ~PORTSC_PED;\r
+ break;\r
+\r
+ case EfiUsbPortPower:\r
+ \r
+ //\r
+ // No support, no operation\r
+ //\r
+ goto exit;\r
+\r
+ case EfiUsbPortOwner:\r
+ \r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg |= PORTSC_PO;\r
+ break;\r
+\r
+ default:\r
+ \r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ PortStatusControlReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciClearRootHubPortFeature (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Clears a feature for the specified root hub port.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance. \r
+ PortNumber - Specifies the root hub port whose feature \r
+ is requested to be cleared.\r
+ PortFeature - Indicates the feature selector associated with the \r
+ feature clear request.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The feature specified by PortFeature was cleared for the \r
+ USB root hub port specified by PortNumber.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid or PortFeature is invalid.\r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINT32 PortStatusControlAddr;\r
+ UINT32 PortStatusControlReg;\r
+ UINT8 MaxSpeed;\r
+ UINT8 TotalPortNumber;\r
+ UINT8 Is64BitCapable;\r
+\r
+ EhciGetCapability (\r
+ This, \r
+ &MaxSpeed, \r
+ &TotalPortNumber, \r
+ &Is64BitCapable\r
+ );\r
+\r
+ if (PortNumber >= TotalPortNumber) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ &PortStatusControlReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ switch (PortFeature) {\r
+\r
+ case EfiUsbPortEnable:\r
+ \r
+ //\r
+ // Clear PORT_ENABLE feature means disable port.\r
+ //\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg &= ~PORTSC_PED;\r
+ break;\r
+\r
+ case EfiUsbPortSuspend:\r
+ \r
+ //\r
+ // A write of zero to this bit is ignored by the host controller.\r
+ // The host controller will unconditionally set this bit to a zero when:\r
+ // 1. software sets the Forct Port Resume bit to a zero from a one.\r
+ // 2. software sets the Port Reset bit to a one frome a zero.\r
+ //\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg &= ~PORTSC_FPR;\r
+ break;\r
+\r
+ case EfiUsbPortReset:\r
+ \r
+ //\r
+ // Clear PORT_RESET means clear the reset signal.\r
+ //\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg &= ~PORTSC_PR;\r
+ break;\r
+\r
+ case EfiUsbPortPower:\r
+ \r
+ //\r
+ // No support, no operation\r
+ //\r
+ goto exit;\r
+\r
+ case EfiUsbPortOwner:\r
+ \r
+ //\r
+ // Clear port owner means this port owned by EHC\r
+ //\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg &= ~PORTSC_PO;\r
+ break;\r
+\r
+ case EfiUsbPortConnectChange:\r
+ \r
+ //\r
+ // Clear connect status change\r
+ //\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg |= PORTSC_CSC;\r
+ break;\r
+\r
+ case EfiUsbPortEnableChange:\r
+ \r
+ //\r
+ // Clear enable status change\r
+ //\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg |= PORTSC_PEDC;\r
+ break;\r
+\r
+ case EfiUsbPortSuspendChange:\r
+ \r
+ //\r
+ // No related bit, no operation\r
+ //\r
+ goto exit;\r
+\r
+ case EfiUsbPortOverCurrentChange:\r
+ \r
+ //\r
+ // Clear PortOverCurrent change\r
+ //\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg |= PORTSC_OCC;\r
+ break;\r
+\r
+ case EfiUsbPortResetChange:\r
+ \r
+ //\r
+ // No related bit, no operation\r
+ //\r
+ goto exit;\r
+\r
+ default:\r
+ \r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ PortStatusControlReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciControlTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN EFI_USB_DEVICE_REQUEST *Request,\r
+ IN EFI_USB_DATA_DIRECTION TransferDirection,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Submits control transfer to a target USB device.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ DeviceSpeed - Indicates target device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ Request - A pointer to the USB device request that will be sent \r
+ to the USB device. \r
+ TransferDirection - Specifies the data direction for the transfer.\r
+ There are three values available, DataIn, DataOut \r
+ and NoData.\r
+ Data - A pointer to the buffer of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ TimeOut - Indicates the maximum time, in microseconds, \r
+ which the transfer is allowed to complete.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information generated \r
+ by this control transfer.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The control transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The control transfer could not be completed due to a lack of resources.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The control transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The control transfer failed due to host controller or device error. \r
+ Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINT8 PktId;\r
+ EHCI_QH_ENTITY *QhPtr;\r
+ EHCI_QTD_ENTITY *ControlQtdsPtr;\r
+ UINT8 *DataCursor;\r
+ VOID *DataMap;\r
+ UINT8 *RequestCursor;\r
+ VOID *RequestMap;\r
+\r
+ QhPtr = NULL;\r
+ ControlQtdsPtr = NULL;\r
+ DataCursor = NULL;\r
+ DataMap = NULL;\r
+ RequestCursor = NULL;\r
+ RequestMap = NULL;\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+ //\r
+ // Parameters Checking\r
+ //\r
+ if (TransferDirection != EfiUsbDataIn &&\r
+ TransferDirection != EfiUsbDataOut &&\r
+ TransferDirection != EfiUsbNoData\r
+ ) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (EfiUsbNoData == TransferDirection) {\r
+ if (NULL != Data || 0 != *DataLength) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+ } else {\r
+ if (NULL == Data || 0 == *DataLength) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+ }\r
+\r
+ if (Request == NULL || TransferResult == NULL) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (EFI_USB_SPEED_LOW == DeviceSpeed) {\r
+ if (MaximumPacketLength != 8) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+ } else if (MaximumPacketLength != 8 &&\r
+ MaximumPacketLength != 16 &&\r
+ MaximumPacketLength != 32 &&\r
+ MaximumPacketLength != 64\r
+ ) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // If errors exist that cause host controller halt,\r
+ // then return EFI_DEVICE_ERROR.\r
+ //\r
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+ ClearEhcAllStatus (HcDev);\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Map the Request for bus master access.\r
+ // BusMasterRead means cpu write\r
+ //\r
+ Status = MapRequestBuffer (\r
+ HcDev,\r
+ Request,\r
+ &RequestCursor,\r
+ &RequestMap\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Map the source data buffer for bus master access.\r
+ //\r
+ Status = MapDataBuffer (\r
+ HcDev,\r
+ TransferDirection,\r
+ Data,\r
+ DataLength,\r
+ &PktId,\r
+ &DataCursor,\r
+ &DataMap\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto unmap_request;\r
+ }\r
+ \r
+ //\r
+ // Create and init control Qh\r
+ //\r
+ Status = CreateControlQh (\r
+ HcDev,\r
+ DeviceAddress,\r
+ DeviceSpeed,\r
+ MaximumPacketLength,\r
+ Translator,\r
+ &QhPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto unmap_data;\r
+ }\r
+ \r
+ //\r
+ // Create and init control Qtds\r
+ //\r
+ Status = CreateControlQtds (\r
+ HcDev,\r
+ PktId,\r
+ RequestCursor,\r
+ DataCursor,\r
+ *DataLength,\r
+ Translator,\r
+ &ControlQtdsPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto destory_qh;\r
+ }\r
+ \r
+ //\r
+ // Link Qtds to Qh\r
+ //\r
+ LinkQtdToQh (QhPtr, ControlQtdsPtr);\r
+\r
+ ClearEhcAllStatus (HcDev);\r
+\r
+ //\r
+ // Link Qh and Qtds to Async Schedule List\r
+ //\r
+ Status = LinkQhToAsyncList (HcDev, QhPtr);\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto destory_qtds;\r
+ }\r
+ \r
+ //\r
+ // Poll Qh-Qtds execution and get result.\r
+ // detail status is returned\r
+ //\r
+ Status = ExecuteTransfer (\r
+ HcDev,\r
+ TRUE,\r
+ QhPtr,\r
+ DataLength,\r
+ 0,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto destory_qtds;\r
+ }\r
+ \r
+ //\r
+ // If has errors that cause host controller halt,\r
+ // then return EFI_DEVICE_ERROR directly.\r
+ //\r
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+ *TransferResult |= EFI_USB_ERR_SYSTEM;\r
+ }\r
+\r
+ ClearEhcAllStatus (HcDev);\r
+\r
+destory_qtds:\r
+ UnlinkQhFromAsyncList (HcDev, QhPtr);\r
+ DestoryQtds (HcDev, ControlQtdsPtr);\r
+destory_qh:\r
+ DestoryQh (HcDev, QhPtr);\r
+unmap_data:\r
+ HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);\r
+unmap_request:\r
+ HcDev->PciIo->Unmap (HcDev->PciIo, RequestMap);\r
+exit:\r
+ HcDev->PciIo->Flush (HcDev->PciIo);\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciBulkTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Submits bulk transfer to a bulk endpoint of a USB device.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration. \r
+ EndPointAddress - The combination of an endpoint number and an \r
+ endpoint direction of the target USB device. \r
+ Each endpoint address supports data transfer in \r
+ one direction except the control endpoint \r
+ (whose default endpoint address is 0). \r
+ It is the caller's responsibility to make sure that \r
+ the EndPointAddress represents a bulk endpoint. \r
+ DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL\r
+ and EFI_USB_SPEED_HIGH.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint\r
+ is capable of sending or receiving. \r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be transmitted \r
+ to USB device or received from USB device. \r
+ DataLength - When input, indicates the size, in bytes, of the data buffer\r
+ specified by Data. When output, indicates the actually \r
+ transferred data size. \r
+ DataToggle - A pointer to the data toggle value. On input, it indicates \r
+ the initial data toggle value the bulk transfer should adopt;\r
+ on output, it is updated to indicate the data toggle value \r
+ of the subsequent bulk transfer. \r
+ Translator - A pointr to the transaction translator data. \r
+ TimeOut - Indicates the maximum time, in microseconds, which the \r
+ transfer is allowed to complete. \r
+ TransferResult - A pointer to the detailed result information of the \r
+ bulk transfer.\r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The bulk transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The bulk transfer could not be submitted due to lack of resource.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The bulk transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The bulk transfer failed due to host controller or device error.\r
+ Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINT8 PktId;\r
+ EHCI_QH_ENTITY *QhPtr;\r
+ EHCI_QTD_ENTITY *BulkQtdsPtr;\r
+ UINT8 *DataCursor;\r
+ VOID *DataMap;\r
+ EFI_USB_DATA_DIRECTION TransferDirection;\r
+\r
+ QhPtr = NULL;\r
+ BulkQtdsPtr = NULL;\r
+ DataCursor = NULL;\r
+ DataMap = NULL;\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+ //\r
+ // Parameters Checking\r
+ //\r
+ if (NULL == DataLength ||\r
+ NULL == Data || \r
+ NULL == Data[0] || \r
+ NULL == TransferResult\r
+ ) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (*DataLength == 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (1 != *DataToggle && 0 != *DataToggle) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (EFI_USB_SPEED_LOW == DeviceSpeed) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (EFI_USB_SPEED_FULL == DeviceSpeed) {\r
+ if (MaximumPacketLength > 64) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+ }\r
+\r
+ if (EFI_USB_SPEED_HIGH == DeviceSpeed) {\r
+ if (MaximumPacketLength > 512) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // if has errors that cause host controller halt,\r
+ // then return EFI_DEVICE_ERROR directly.\r
+ //\r
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+ ClearEhcAllStatus (HcDev);\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = ClearEhcAllStatus (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // construct QH and TD data structures,\r
+ // and link them together\r
+ //\r
+ if (EndPointAddress & 0x80) {\r
+ TransferDirection = EfiUsbDataIn;\r
+ } else {\r
+ TransferDirection = EfiUsbDataOut;\r
+ }\r
+\r
+ Status = MapDataBuffer (\r
+ HcDev,\r
+ TransferDirection,\r
+ Data[0],\r
+ DataLength,\r
+ &PktId,\r
+ &DataCursor,\r
+ &DataMap\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Create and init Bulk Qh\r
+ //\r
+ Status = CreateBulkQh (\r
+ HcDev,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DeviceSpeed,\r
+ *DataToggle,\r
+ MaximumPacketLength,\r
+ Translator,\r
+ &QhPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto unmap_data;\r
+ }\r
+ \r
+ //\r
+ // Create and init Bulk Qtds\r
+ //\r
+ Status = CreateBulkOrInterruptQtds (\r
+ HcDev,\r
+ PktId,\r
+ DataCursor,\r
+ *DataLength,\r
+ Translator,\r
+ &BulkQtdsPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto destory_qh;\r
+ }\r
+ \r
+ //\r
+ // Link Qtds to Qh\r
+ //\r
+ LinkQtdToQh (QhPtr, BulkQtdsPtr);\r
+\r
+ ClearEhcAllStatus (HcDev);\r
+\r
+ //\r
+ // Link Qh and qtds to Async Schedule List\r
+ //\r
+ Status = LinkQhToAsyncList (HcDev, QhPtr);\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto destory_qtds;\r
+ }\r
+ \r
+ //\r
+ // Poll QH-TDs execution and get result.\r
+ // detail status is returned\r
+ //\r
+ Status = ExecuteTransfer (\r
+ HcDev,\r
+ FALSE,\r
+ QhPtr,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto destory_qtds;\r
+ }\r
+ \r
+ //\r
+ // if has errors that cause host controller halt,\r
+ // then return EFI_DEVICE_ERROR directly.\r
+ //\r
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+ *TransferResult |= EFI_USB_ERR_SYSTEM;\r
+ }\r
+\r
+ ClearEhcAllStatus (HcDev);\r
+\r
+destory_qtds:\r
+ UnlinkQhFromAsyncList (HcDev, QhPtr);\r
+ DestoryQtds (HcDev, BulkQtdsPtr);\r
+destory_qh:\r
+ DestoryQh (HcDev, QhPtr);\r
+unmap_data:\r
+ HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);\r
+exit:\r
+ HcDev->PciIo->Flush (HcDev->PciIo);\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciAsyncInterruptTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN BOOLEAN IsNewTransfer,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN PollingInterval,\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,\r
+ IN VOID *Context OPTIONAL\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Submits an asynchronous interrupt transfer to an \r
+ interrupt endpoint of a USB device.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration. \r
+ EndPointAddress - The combination of an endpoint number and an endpoint \r
+ direction of the target USB device. Each endpoint address \r
+ supports data transfer in one direction except the \r
+ control endpoint (whose default endpoint address is 0). \r
+ It is the caller's responsibility to make sure that \r
+ the EndPointAddress represents an interrupt endpoint. \r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint\r
+ is capable of sending or receiving. \r
+ IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between\r
+ the host and the target interrupt endpoint. \r
+ If FALSE, the specified asynchronous interrupt pipe \r
+ is canceled. \r
+ DataToggle - A pointer to the data toggle value. On input, it is valid \r
+ when IsNewTransfer is TRUE, and it indicates the initial \r
+ data toggle value the asynchronous interrupt transfer \r
+ should adopt. \r
+ On output, it is valid when IsNewTransfer is FALSE, \r
+ and it is updated to indicate the data toggle value of \r
+ the subsequent asynchronous interrupt transfer. \r
+ PollingInterval - Indicates the interval, in milliseconds, that the \r
+ asynchronous interrupt transfer is polled. \r
+ This parameter is required when IsNewTransfer is TRUE. \r
+ DataLength - Indicates the length of data to be received at the \r
+ rate specified by PollingInterval from the target \r
+ asynchronous interrupt endpoint. This parameter \r
+ is only required when IsNewTransfer is TRUE. \r
+ Translator - A pointr to the transaction translator data.\r
+ CallBackFunction - The Callback function.This function is called at the \r
+ rate specified by PollingInterval.This parameter is \r
+ only required when IsNewTransfer is TRUE. \r
+ Context - The context that is passed to the CallBackFunction.\r
+ - This is an optional parameter and may be NULL.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The asynchronous interrupt transfer request has been successfully \r
+ submitted or canceled.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_OUT_OF_RESOURCES \r
+ The request could not be completed due to a lack of resources. \r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINT8 PktId;\r
+ EHCI_QH_ENTITY *QhPtr;\r
+ EHCI_QTD_ENTITY *InterruptQtdsPtr;\r
+ UINT8 *DataPtr;\r
+ UINT8 *DataCursor;\r
+ VOID *DataMap;\r
+ UINTN MappedLength;\r
+ EHCI_ASYNC_REQUEST *AsyncRequestPtr;\r
+ EFI_TPL OldTpl;\r
+\r
+ QhPtr = NULL;\r
+ InterruptQtdsPtr = NULL;\r
+ DataPtr = NULL;\r
+ DataCursor = NULL;\r
+ DataMap = NULL;\r
+ AsyncRequestPtr = NULL;\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+ //\r
+ // Parameters Checking\r
+ //\r
+ if (!IsDataInTransfer (EndPointAddress)) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (IsNewTransfer) {\r
+ if (0 == DataLength) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (*DataToggle != 1 && *DataToggle != 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (PollingInterval > 255 || PollingInterval < 1) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // if has errors that cause host controller halt,\r
+ // then return EFI_DEVICE_ERROR directly.\r
+ //\r
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+ ClearEhcAllStatus (HcDev);\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = ClearEhcAllStatus (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Delete Async interrupt transfer request\r
+ //\r
+ if (!IsNewTransfer) {\r
+\r
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
+\r
+ Status = DeleteAsyncRequestTransfer (\r
+ HcDev,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DataToggle\r
+ );\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ goto exit;\r
+ }\r
+\r
+ Status = EhciAllocatePool (\r
+ HcDev, \r
+ (UINT8 **) &AsyncRequestPtr, \r
+ sizeof (EHCI_ASYNC_REQUEST)\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+\r
+ Status = EhciAllocatePool (HcDev, &DataPtr, DataLength);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto free_request;\r
+ }\r
+\r
+ MappedLength = DataLength;\r
+ Status = MapDataBuffer (\r
+ HcDev,\r
+ EfiUsbDataIn,\r
+ DataPtr,\r
+ &MappedLength,\r
+ &PktId,\r
+ &DataCursor,\r
+ &DataMap\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto free_data;\r
+ }\r
+ \r
+ //\r
+ // Create and init Interrupt Qh\r
+ //\r
+ Status = CreateInterruptQh (\r
+ HcDev,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DeviceSpeed,\r
+ *DataToggle,\r
+ MaximumPacketLength,\r
+ PollingInterval,\r
+ Translator,\r
+ &QhPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto unmap_data;\r
+ }\r
+ \r
+ //\r
+ // Create and init Interrupt Qtds\r
+ //\r
+ Status = CreateBulkOrInterruptQtds (\r
+ HcDev,\r
+ PktId,\r
+ DataCursor,\r
+ MappedLength,\r
+ Translator,\r
+ &InterruptQtdsPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto destory_qh;\r
+ }\r
+ \r
+ //\r
+ // Link Qtds to Qh\r
+ //\r
+ LinkQtdToQh (QhPtr, InterruptQtdsPtr);\r
+\r
+ //\r
+ // Init AsyncRequest Entry\r
+ //\r
+ AsyncRequestPtr->Context = Context;\r
+ AsyncRequestPtr->CallBackFunc = CallBackFunction;\r
+ AsyncRequestPtr->TransferType = ASYNC_INTERRUPT_TRANSFER;\r
+ AsyncRequestPtr->QhPtr = QhPtr;\r
+ AsyncRequestPtr->Prev = NULL;\r
+ AsyncRequestPtr->Next = NULL;\r
+\r
+ if (NULL == HcDev->AsyncRequestList) {\r
+ Status = StartPollingTimer (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ CleanUpAllAsyncRequestTransfer (HcDev);\r
+ goto exit;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Link Entry to AsyncRequest List\r
+ //\r
+ LinkToAsyncReqeust (HcDev, AsyncRequestPtr);\r
+\r
+ ClearEhcAllStatus (HcDev);\r
+\r
+ Status = DisablePeriodicSchedule (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_TIMEOUT;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Link Qh and Qtds to Periodic Schedule List\r
+ //\r
+ LinkQhToPeriodicList (HcDev, QhPtr);\r
+\r
+ Status = EnablePeriodicSchedule (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_TIMEOUT;\r
+ goto exit;\r
+ }\r
+\r
+ if (IsEhcHalted (HcDev)) {\r
+ Status = StartScheduleExecution (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ }\r
+\r
+ HcDev->PciIo->Flush (HcDev->PciIo);\r
+ goto exit;\r
+\r
+destory_qh:\r
+ DestoryQh (HcDev, QhPtr);\r
+free_data:\r
+ EhciFreePool (HcDev, DataPtr, DataLength);\r
+free_request:\r
+ EhciFreePool (\r
+ HcDev, \r
+ (UINT8 *) AsyncRequestPtr, \r
+ sizeof (EHCI_ASYNC_REQUEST)\r
+ );\r
+unmap_data:\r
+ HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciSyncInterruptTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Submits synchronous interrupt transfer to an interrupt endpoint \r
+ of a USB device.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ DeviceAddress - Represents the address of the target device on the USB, \r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - The combination of an endpoint number and an endpoint \r
+ direction of the target USB device. Each endpoint \r
+ address supports data transfer in one direction \r
+ except the control endpoint (whose default \r
+ endpoint address is 0). It is the caller's responsibility\r
+ to make sure that the EndPointAddress represents \r
+ an interrupt endpoint. \r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint \r
+ is capable of sending or receiving.\r
+ Data - A pointer to the buffer of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - On input, the size, in bytes, of the data buffer specified \r
+ by Data. On output, the number of bytes transferred.\r
+ DataToggle - A pointer to the data toggle value. On input, it indicates\r
+ the initial data toggle value the synchronous interrupt \r
+ transfer should adopt; \r
+ on output, it is updated to indicate the data toggle value \r
+ of the subsequent synchronous interrupt transfer. \r
+ TimeOut - Indicates the maximum time, in microseconds, which the \r
+ transfer is allowed to complete.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information from \r
+ the synchronous interrupt transfer. \r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The synchronous interrupt transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The synchronous interrupt transfer could not be submitted due \r
+ to lack of resource.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The synchronous interrupt transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The synchronous interrupt transfer failed due to host controller \r
+ or device error. Caller should check TranferResult for detailed \r
+ error information. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ UINT8 PktId;\r
+ EHCI_QH_ENTITY *QhPtr;\r
+ EHCI_QTD_ENTITY *InterruptQtdsPtr;\r
+ UINT8 *DataCursor;\r
+ VOID *DataMap;\r
+\r
+ QhPtr = NULL;\r
+ InterruptQtdsPtr = NULL;\r
+ DataCursor = NULL;\r
+ DataMap = NULL;\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+\r
+ //\r
+ // Parameters Checking\r
+ //\r
+ if (DataLength == NULL ||\r
+ Data == NULL || \r
+ TransferResult == NULL\r
+ ) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (!IsDataInTransfer (EndPointAddress)) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (0 == *DataLength) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (*DataToggle != 1 && *DataToggle != 0) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (EFI_USB_SPEED_LOW == DeviceSpeed && 8 != MaximumPacketLength) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (EFI_USB_SPEED_FULL == DeviceSpeed && MaximumPacketLength > 64) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ if (EFI_USB_SPEED_HIGH == DeviceSpeed && MaximumPacketLength > 3072) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // if has errors that cause host controller halt,\r
+ // then return EFI_DEVICE_ERROR directly.\r
+ //\r
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+ ClearEhcAllStatus (HcDev);\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = ClearEhcAllStatus (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = MapDataBuffer (\r
+ HcDev,\r
+ EfiUsbDataIn,\r
+ Data,\r
+ DataLength,\r
+ &PktId,\r
+ &DataCursor,\r
+ &DataMap\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Create and init Interrupt Qh\r
+ //\r
+ Status = CreateInterruptQh (\r
+ HcDev,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DeviceSpeed,\r
+ *DataToggle,\r
+ MaximumPacketLength,\r
+ 0,\r
+ Translator,\r
+ &QhPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto unmap_data;\r
+ }\r
+ \r
+ //\r
+ // Create and init Interrupt Qtds\r
+ //\r
+ Status = CreateBulkOrInterruptQtds (\r
+ HcDev,\r
+ PktId,\r
+ DataCursor,\r
+ *DataLength,\r
+ Translator,\r
+ &InterruptQtdsPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ *TransferResult = EFI_USB_ERR_SYSTEM;\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto destory_qh;\r
+ }\r
+ \r
+ //\r
+ // Link Qtds to Qh\r
+ //\r
+ LinkQtdToQh (QhPtr, InterruptQtdsPtr);\r
+\r
+ ClearEhcAllStatus (HcDev);\r
+\r
+ Status = DisablePeriodicSchedule (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_TIMEOUT;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Link Qh and Qtds to Periodic Schedule List\r
+ //\r
+ LinkQhToPeriodicList (HcDev, QhPtr);\r
+\r
+ Status = EnablePeriodicSchedule (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_TIMEOUT;\r
+ goto exit;\r
+ }\r
+\r
+ if (IsEhcHalted (HcDev)) {\r
+ Status = StartScheduleExecution (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Poll QH-TDs execution and get result.\r
+ // detail status is returned\r
+ //\r
+ Status = ExecuteTransfer (\r
+ HcDev,\r
+ FALSE,\r
+ QhPtr,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto destory_qtds;\r
+ }\r
+ \r
+ //\r
+ // if has errors that cause host controller halt,\r
+ // then return EFI_DEVICE_ERROR directly.\r
+ //\r
+ if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {\r
+ *TransferResult |= EFI_USB_ERR_SYSTEM;\r
+ }\r
+\r
+ ClearEhcAllStatus (HcDev);\r
+\r
+destory_qtds:\r
+ UnlinkQhFromPeriodicList (HcDev, QhPtr, 0);\r
+ DestoryQtds (HcDev, InterruptQtdsPtr);\r
+destory_qh:\r
+ DestoryQh (HcDev, QhPtr);\r
+unmap_data:\r
+ HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);\r
+exit:\r
+ HcDev->PciIo->Flush (HcDev->PciIo);\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciIsochronousTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Submits isochronous transfer to a target USB device.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - End point address\r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be \r
+ transmitted to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information generated \r
+ by this control transfer. \r
+ \r
+ Returns:\r
+ \r
+ EFI_UNSUPPORTED \r
+\r
+--*/\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EhciAsyncIsochronousTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Submits Async isochronous transfer to a target USB device.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - End point address\r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ Translator - A pointr to the transaction translator data.\r
+ IsochronousCallBack - When the transfer complete, the call back function will be called\r
+ Context - Pass to the call back function as parameter\r
+ \r
+ Returns:\r
+ \r
+ EFI_UNSUPPORTED \r
+\r
+--*/\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ Ehci.h\r
+ \r
+Abstract: \r
+ \r
+\r
+Revision History\r
+--*/\r
+\r
+#ifndef _EHCI_H\r
+#define _EHCI_H\r
+\r
+//\r
+// Universal Host Controller Interface data structures and defines\r
+//\r
+#include <IndustryStandard/pci22.h>\r
+\r
+#ifdef EFI_DEBUG\r
+extern UINTN gEHCDebugLevel;\r
+extern UINTN gEHCErrorLevel;\r
+#endif\r
+\r
+#define STALL_1_MACRO_SECOND 1\r
+#define STALL_1_MILLI_SECOND 1000 * STALL_1_MACRO_SECOND\r
+#define STALL_1_SECOND 1000 * STALL_1_MILLI_SECOND\r
+\r
+#define SETUP_PACKET_PID_CODE 0x02\r
+#define INPUT_PACKET_PID_CODE 0x01\r
+#define OUTPUT_PACKET_PID_CODE 0x0\r
+\r
+#define ITD_SELECT_TYPE 0x0\r
+#define QH_SELECT_TYPE 0x01\r
+#define SITD_SELECT_TYPE 0x02\r
+#define FSTN_SELECT_TYPE 0x03\r
+\r
+#define EHCI_SET_PORT_RESET_RECOVERY_TIME 50 * STALL_1_MILLI_SECOND\r
+#define EHCI_CLEAR_PORT_RESET_RECOVERY_TIME STALL_1_MILLI_SECOND\r
+#define EHCI_GENERIC_TIMEOUT 50 * STALL_1_MILLI_SECOND\r
+#define EHCI_GENERIC_RECOVERY_TIME 50 * STALL_1_MACRO_SECOND\r
+#define EHCI_SYNC_REQUEST_POLLING_TIME 50 * STALL_1_MACRO_SECOND\r
+#define EHCI_ASYNC_REQUEST_POLLING_TIME 50 * STALL_1_MILLI_SECOND\r
+\r
+#define USB_BAR_INDEX 0 /* how many bytes away from USB_BASE to 0x10 */\r
+\r
+#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 1\r
+\r
+#define EHCI_MIN_PACKET_SIZE 8\r
+#define EHCI_MAX_PACKET_SIZE 1024\r
+#define EHCI_MAX_FRAME_LIST_LENGTH 1024\r
+#define EHCI_BLOCK_SIZE_WITH_TT 64\r
+#define EHCI_BLOCK_SIZE 512\r
+#define EHCI_MAX_QTD_CAPACITY (EFI_PAGE_SIZE * 5)\r
+\r
+#define NAK_COUNT_RELOAD 3\r
+#define QTD_ERROR_COUNTER 1\r
+#define HIGH_BANDWIDTH_PIPE_MULTIPLIER 1\r
+\r
+#define QTD_STATUS_ACTIVE 0x80\r
+#define QTD_STATUS_HALTED 0x40\r
+#define QTD_STATUS_BUFFER_ERR 0x20\r
+#define QTD_STATUS_BABBLE_ERR 0x10\r
+#define QTD_STATUS_TRANSACTION_ERR 0x08\r
+#define QTD_STATUS_DO_STOP_SPLIT 0x02\r
+#define QTD_STATUS_DO_START_SPLIT 0\r
+#define QTD_STATUS_DO_PING 0x01\r
+#define QTD_STATUS_DO_OUT 0\r
+\r
+#define DATA0 0\r
+#define DATA1 1\r
+\r
+#define MICRO_FRAME_0_CHANNEL 0x01\r
+#define MICRO_FRAME_1_CHANNEL 0x02\r
+#define MICRO_FRAME_2_CHANNEL 0x04\r
+#define MICRO_FRAME_3_CHANNEL 0x08\r
+#define MICRO_FRAME_4_CHANNEL 0x10\r
+#define MICRO_FRAME_5_CHANNEL 0x20\r
+#define MICRO_FRAME_6_CHANNEL 0x40\r
+#define MICRO_FRAME_7_CHANNEL 0x80\r
+\r
+#define CONTROL_TRANSFER 0x01\r
+#define BULK_TRANSFER 0x02\r
+#define SYNC_INTERRUPT_TRANSFER 0x04\r
+#define ASYNC_INTERRUPT_TRANSFER 0x08\r
+#define SYNC_ISOCHRONOUS_TRANSFER 0x10\r
+#define ASYNC_ISOCHRONOUS_TRANSFER 0x20\r
+\r
+\r
+//\r
+// Enhanced Host Controller Registers definitions\r
+//\r
+extern UINT32 mUsbCapabilityLen;\r
+extern EFI_DRIVER_BINDING_PROTOCOL gEhciDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL gEhciComponentName;\r
+\r
+#define USBCMD 0x0 /* Command Register Offset 00-03h */\r
+#define USBCMD_RS 0x01 /* Run / Stop */\r
+#define USBCMD_HCRESET 0x02 /* Host controller reset */\r
+#define USBCMD_FLS_512 0x04 /* 512 elements (2048bytes) in Frame List */\r
+#define USBCMD_FLS_256 0x08 /* 256 elements (1024bytes) in Frame List */\r
+#define USBCMD_PSE 0x10 /* Periodic schedule enable */\r
+#define USBCMD_ASE 0x20 /* Asynchronous schedule enable */\r
+#define USBCMD_IAAD 0x40 /* Interrupt on async advance doorbell */\r
+\r
+#define USBSTS 0x04 /* Statue Register Offset 04-07h */\r
+#define USBSTS_HSE 0x10 /* Host system error */\r
+#define USBSTS_IAA 0x20 /* Interrupt on async advance */\r
+#define USBSTS_HCH 0x1000 /* Host controller halted */\r
+#define USBSTS_PSS 0x4000 /* Periodic schedule status */\r
+#define USBSTS_ASS 0x8000 /* Asynchronous schedule status */\r
+\r
+#define USBINTR 0x08 /* Command Register Offset 08-0bh */\r
+\r
+#define FRINDEX 0x0c /* Frame Index Offset 0c-0fh */\r
+\r
+#define CTRLDSSGMENT 0x10 /* 4G Segment Selector Offset 10-13h */\r
+\r
+#define PERIODICLISTBASE 0x14 /* Frame List Base Address Offset 14-17h */\r
+\r
+#define ASYNCLISTADDR 0x18 /* Next Asynchronous List Address Offset 18-1bh */\r
+\r
+#define CONFIGFLAG 0x40 /* Configured Flag Register Offset 40-43h */\r
+#define CONFIGFLAG_CF 0x01 /* Configure Flag */\r
+\r
+#define PORTSC 0x44 /* Port Status/Control Offset 44-47h */\r
+#define PORTSC_CCS 0x01 /* Current Connect Status*/\r
+#define PORTSC_CSC 0x02 /* Connect Status Change */\r
+#define PORTSC_PED 0x04 /* Port Enable / Disable */\r
+#define PORTSC_PEDC 0x08 /* Port Enable / Disable Change */\r
+#define PORTSC_OCA 0x10 /* Over current Active */\r
+#define PORTSC_OCC 0x20 /* Over current Change */\r
+#define PORTSC_FPR 0x40 /* Force Port Resume */\r
+#define PORTSC_SUSP 0x80 /* Port Suspend State */\r
+#define PORTSC_PR 0x100 /* Port Reset */\r
+#define PORTSC_LS_KSTATE 0x400 /* Line Status K-state */\r
+#define PORTSC_LS_JSTATE 0x800 /* Line Status J-state */\r
+#define PORTSC_PP 0x1000 /* Port Power */\r
+#define PORTSC_PO 0x2000 /* Port Owner */\r
+\r
+#define CAPLENGTH 0 /* Capability Register Length 00h */\r
+\r
+#define HCIVERSION 0x02 /* Interface Version Number 02-03h */\r
+\r
+#define HCSPARAMS 0x04 /* Structural Parameters 04-07h */\r
+#define HCSP_NPORTS 0x0f /* Number of physical downstream ports on host controller */\r
+\r
+#define HCCPARAMS 0x08 /* Capability Parameters 08-0bh */\r
+#define HCCP_64BIT 0x01 /* 64-bit Addressing Capability */\r
+#define HCCP_PFLF 0x02 /* Programmable Frame List Flag */\r
+#define HCCP_EECP 0xff00 /* EHCI Extemded Capabilities Pointer */\r
+\r
+#define HCSPPORTROUTE 0x0c /* Companion Port Route Description 60b */\r
+\r
+#define CLASSC 0x09 /* Class Code 09-0bh */\r
+\r
+#define USBBASE 0x10 /* Base Address to Memory-mapped Host Controller Register Space 10-13h */\r
+\r
+#define SBRN 0x60 /* Serial Bus Release Number 60h */\r
+\r
+#define FLADJ 0x61 /* Frame Length Adjustment Register 61h */\r
+\r
+#define PORTWAKECAP 0x62 /* Port wake capablilities register(OPIONAL) 61-62h */\r
+\r
+//\r
+// PCI Configuration Registers\r
+//\r
+#define EHCI_PCI_CLASSC 0x09\r
+#define EHCI_PCI_MEMORY_BASE 0x10\r
+\r
+//\r
+// Memory Offset Registers\r
+//\r
+#define EHCI_MEMORY_CAPLENGTH 0x0\r
+#define EHCI_MEMORY_CONFIGFLAG 0x40\r
+\r
+//\r
+// USB Base Class Code,Sub-Class Code and Programming Interface\r
+//\r
+#define PCI_CLASSC_PI_EHCI 0x20\r
+\r
+#define SETUP_PACKET_ID 0x2D\r
+#define INPUT_PACKET_ID 0x69\r
+#define OUTPUT_PACKET_ID 0xE1\r
+#define ERROR_PACKET_ID 0x55\r
+\r
+#define bit(a) 1 << (a)\r
+\r
+#define GET_0B_TO_31B(Addr) (((UINTN) Addr) & (0xffffffff))\r
+#define GET_32B_TO_63B(Addr) ((((UINTN) Addr) >> 32) & (0xffffffff))\r
+\r
+\r
+//\r
+// Ehci Data and Ctrl Structures\r
+//\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+ UINT8 PI;\r
+ UINT8 SubClassCode;\r
+ UINT8 BaseCode;\r
+} USB_CLASSC;\r
+\r
+typedef struct {\r
+ UINT32 NextQtdTerminate : 1;\r
+ UINT32 Rsvd1 : 4;\r
+ UINT32 NextQtdPointer : 27;\r
+\r
+ UINT32 AltNextQtdTerminate : 1;\r
+ UINT32 Rsvd2 : 4;\r
+ UINT32 AltNextQtdPointer : 27;\r
+\r
+ UINT32 Status : 8;\r
+ UINT32 PidCode : 2;\r
+ UINT32 ErrorCount : 2;\r
+ UINT32 CurrentPage : 3;\r
+ UINT32 InterruptOnComplete : 1;\r
+ UINT32 TotalBytes : 15;\r
+ UINT32 DataToggle : 1;\r
+\r
+ UINT32 CurrentOffset : 12;\r
+ UINT32 BufferPointer0 : 20;\r
+\r
+ UINT32 Rsvd3 : 12;\r
+ UINT32 BufferPointer1 : 20;\r
+\r
+ UINT32 Rsvd4 : 12;\r
+ UINT32 BufferPointer2 : 20;\r
+\r
+ UINT32 Rsvd5 : 12;\r
+ UINT32 BufferPointer3 : 20;\r
+\r
+ UINT32 Rsvd6 : 12;\r
+ UINT32 BufferPointer4 : 20;\r
+\r
+ UINT32 ExtBufferPointer0;\r
+ UINT32 ExtBufferPointer1;\r
+ UINT32 ExtBufferPointer2;\r
+ UINT32 ExtBufferPointer3;\r
+ UINT32 ExtBufferPointer4;\r
+} EHCI_QTD_HW;\r
+\r
+typedef struct {\r
+ UINT32 QhTerminate : 1;\r
+ UINT32 SelectType : 2;\r
+ UINT32 Rsvd1 : 2;\r
+ UINT32 QhHorizontalPointer : 27;\r
+\r
+ UINT32 DeviceAddr : 7;\r
+ UINT32 Inactive : 1;\r
+ UINT32 EndpointNum : 4;\r
+ UINT32 EndpointSpeed : 2;\r
+ UINT32 DataToggleControl : 1;\r
+ UINT32 HeadReclamationFlag : 1;\r
+ UINT32 MaxPacketLen : 11;\r
+ UINT32 ControlEndpointFlag : 1;\r
+ UINT32 NakCountReload : 4;\r
+\r
+ UINT32 InerruptScheduleMask : 8;\r
+ UINT32 SplitComletionMask : 8;\r
+ UINT32 HubAddr : 7;\r
+ UINT32 PortNum : 7;\r
+ UINT32 Multiplier : 2;\r
+\r
+ UINT32 Rsvd2 : 5;\r
+ UINT32 CurrentQtdPointer : 27;\r
+\r
+ UINT32 NextQtdTerminate : 1;\r
+ UINT32 Rsvd3 : 4;\r
+ UINT32 NextQtdPointer : 27;\r
+\r
+ UINT32 AltNextQtdTerminate : 1;\r
+ UINT32 NakCount : 4;\r
+ UINT32 AltNextQtdPointer : 27;\r
+\r
+ UINT32 Status : 8;\r
+ UINT32 PidCode : 2;\r
+ UINT32 ErrorCount : 2;\r
+ UINT32 CurrentPage : 3;\r
+ UINT32 InterruptOnComplete : 1;\r
+ UINT32 TotalBytes : 15;\r
+ UINT32 DataToggle : 1;\r
+\r
+ UINT32 CurrentOffset : 12;\r
+ UINT32 BufferPointer0 : 20;\r
+\r
+ UINT32 CompleteSplitMask : 8;\r
+ UINT32 Rsvd4 : 4;\r
+ UINT32 BufferPointer1 : 20;\r
+\r
+ UINT32 FrameTag : 5;\r
+ UINT32 SplitBytes : 7;\r
+ UINT32 BufferPointer2 : 20;\r
+\r
+ UINT32 Rsvd5 : 12;\r
+ UINT32 BufferPointer3 : 20;\r
+\r
+ UINT32 Rsvd6 : 12;\r
+ UINT32 BufferPointer4 : 20;\r
+\r
+ UINT32 ExtBufferPointer0;\r
+ UINT32 ExtBufferPointer1;\r
+ UINT32 ExtBufferPointer2;\r
+ UINT32 ExtBufferPointer3;\r
+ UINT32 ExtBufferPointer4;\r
+} EHCI_QH_HW;\r
+\r
+typedef struct {\r
+ UINT32 LinkTerminate : 1;\r
+ UINT32 SelectType : 2;\r
+ UINT32 Rsvd : 2;\r
+ UINT32 LinkPointer : 27;\r
+} FRAME_LIST_ENTRY;\r
+\r
+#pragma pack()\r
+\r
+typedef struct _EHCI_QTD_ENTITY EHCI_QTD_ENTITY;\r
+typedef struct _EHCI_QH_ENTITY EHCI_QH_ENTITY;\r
+typedef struct _EHCI_ASYNC_REQUEST EHCI_ASYNC_REQUEST;\r
+\r
+typedef struct _EHCI_QTD_ENTITY {\r
+ EHCI_QTD_HW Qtd;\r
+ UINT32 TotalBytes;\r
+ UINT32 StaticTotalBytes;\r
+ UINT32 StaticCurrentOffset;\r
+ EHCI_QTD_ENTITY *Prev;\r
+ EHCI_QTD_ENTITY *Next;\r
+ EHCI_QTD_ENTITY *AltNext;\r
+ EHCI_QH_ENTITY *SelfQh;\r
+} EHCI_QTD_ENTITY;\r
+\r
+typedef struct _EHCI_QH_ENTITY {\r
+ EHCI_QH_HW Qh;\r
+ EHCI_QH_ENTITY *Next;\r
+ EHCI_QH_ENTITY *Prev;\r
+ EHCI_QTD_ENTITY *FirstQtdPtr;\r
+ EHCI_QTD_ENTITY *LastQtdPtr;\r
+ EHCI_QTD_ENTITY *AltQtdPtr;\r
+ UINTN Interval;\r
+ UINT8 TransferType;\r
+} EHCI_QH_ENTITY;\r
+\r
+#define GET_QH_ENTITY_ADDR(a) ((EHCI_QH_ENTITY *) a)\r
+#define GET_QTD_ENTITY_ADDR(a) ((EHCI_QTD_ENTITY *) a)\r
+\r
+\r
+//\r
+// Ehci Managment Structures\r
+//\r
+#define USB2_HC_DEV_FROM_THIS(a) CR (a, USB2_HC_DEV, Usb2Hc, USB2_HC_DEV_SIGNATURE)\r
+\r
+#define USB2_HC_DEV_SIGNATURE EFI_SIGNATURE_32 ('e', 'h', 'c', 'i')\r
+\r
+typedef struct _LIST_HEAD {\r
+ struct _LIST_HEAD *pre;\r
+ struct _LIST_HEAD *next;\r
+} LIST_HEAD;\r
+\r
+typedef struct _EHCI_ASYNC_REQUEST {\r
+ UINT8 TransferType;\r
+ EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunc;\r
+ VOID *Context;\r
+ EHCI_ASYNC_REQUEST *Prev;\r
+ EHCI_ASYNC_REQUEST *Next;\r
+ EHCI_QH_ENTITY *QhPtr;\r
+} EHCI_ASYNC_REQUEST;\r
+\r
+typedef struct _MEMORY_MANAGE_HEADER {\r
+ UINT8 *BitArrayPtr;\r
+ UINTN BitArraySizeInBytes;\r
+ UINT8 *MemoryBlockPtr;\r
+ UINTN MemoryBlockSizeInBytes;\r
+ VOID *Mapping;\r
+ struct _MEMORY_MANAGE_HEADER *Next;\r
+} MEMORY_MANAGE_HEADER;\r
+\r
+typedef struct _USB2_HC_DEV {\r
+ UINTN Signature;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_USB2_HC_PROTOCOL Usb2Hc;\r
+ UINTN PeriodicFrameListLength;\r
+ VOID *PeriodicFrameListBuffer;\r
+ VOID *PeriodicFrameListMap;\r
+ VOID *AsyncList;\r
+ EHCI_ASYNC_REQUEST *AsyncRequestList;\r
+ EFI_EVENT AsyncRequestEvent;\r
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;\r
+ MEMORY_MANAGE_HEADER *MemoryHeader;\r
+ UINT8 Is64BitCapable;\r
+ UINT32 High32BitAddr;\r
+} USB2_HC_DEV;\r
+\r
+\r
+//\r
+// Internal Functions Declaration\r
+//\r
+\r
+//\r
+// EhciMem Functions\r
+//\r
+EFI_STATUS\r
+CreateMemoryBlock (\r
+ IN USB2_HC_DEV *HcDev,\r
+ OUT MEMORY_MANAGE_HEADER **MemoryHeader,\r
+ IN UINTN MemoryBlockSizeInPages\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Use PciIo->AllocateBuffer to allocate common buffer for the memory block,\r
+ and use PciIo->Map to map the common buffer for Bus Master Read/Write.\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ MemoryHeader - MEMORY_MANAGE_HEADER to output\r
+ MemoryBlockSizeInPages - MemoryBlockSizeInPages\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Fail for no resources\r
+ EFI_UNSUPPORTED Unsupported currently\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+FreeMemoryHeader (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeader\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Free Memory Header\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ MemoryHeader - MemoryHeader to be freed\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_INVALID_PARAMETER Parameter is error\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+InsertMemoryHeaderToList (\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
+ IN MEMORY_MANAGE_HEADER *NewMemoryHeader\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Insert Memory Header To List\r
+\r
+Arguments:\r
+\r
+ MemoryHeader - MEMORY_MANAGE_HEADER\r
+ NewMemoryHeader - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AllocMemInMemoryBlock (\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
+ OUT VOID **Pool,\r
+ IN UINTN NumberOfMemoryUnit\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Alloc Memory In MemoryBlock\r
+\r
+Arguments:\r
+\r
+ MemoryHeader - MEMORY_MANAGE_HEADER\r
+ Pool - Place to store pointer to memory\r
+ NumberOfMemoryUnit - Number Of Memory Unit\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_NOT_FOUND Can't find the free memory \r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsMemoryBlockEmptied (\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Is Memory Block Emptied\r
+\r
+Arguments:\r
+\r
+ MemoryHeaderPtr - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+ TRUE Empty\r
+ FALSE Not Empty \r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+DelinkMemoryBlock (\r
+ IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,\r
+ IN MEMORY_MANAGE_HEADER *NeedFreeMemoryHeader\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Delink Memory Block\r
+\r
+Arguments:\r
+\r
+ FirstMemoryHeader - MEMORY_MANAGE_HEADER\r
+ NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+InitialMemoryManagement (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize Memory Management\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DeinitialMemoryManagement (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Deinitialize Memory Management\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EhciAllocatePool (\r
+ IN USB2_HC_DEV *HcDev,\r
+ OUT UINT8 **Pool,\r
+ IN UINTN AllocSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Ehci Allocate Pool\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ Pool - Place to store pointer to the memory buffer\r
+ AllocSize - Alloc Size\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+EhciFreePool (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 *Pool,\r
+ IN UINTN AllocSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Uhci Free Pool\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ Pool - Pool to free\r
+ AllocSize - Pool size\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+//\r
+// EhciReg Functions\r
+//\r
+EFI_STATUS\r
+ReadEhcCapabiltiyReg (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 CapabiltiyRegAddr,\r
+ IN OUT UINT32 *Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read Ehc Capabitlity register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ CapabiltiyRegAddr - Ehc Capability register address\r
+ Data - A pointer to data read from register\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ReadEhcOperationalReg (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 OperationalRegAddr,\r
+ IN OUT UINT32 *Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read Ehc Operation register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ OperationalRegAddr - Ehc Operation register address\r
+ Data - A pointer to data read from register\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WriteEhcOperationalReg (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 OperationalRegAddr,\r
+ IN UINT32 Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Write Ehc Operation register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ OperationalRegAddr - Ehc Operation register address\r
+ Data - 32bit write to register\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetEhcDoorbell (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set Ehc door bell bit\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetFrameListLen (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set the length of Frame List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Length - the required length of frame list\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_INVALID_PARAMETER Invalid parameter\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsFrameListProgrammable (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether frame list is programmable\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Programmable\r
+ FALSE Unprogrammable\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsPeriodicScheduleEnabled (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether periodic schedule is enabled\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Enabled\r
+ FALSE Disabled\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsAsyncScheduleEnabled (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether asynchronous schedule is enabled\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Enabled\r
+ FALSE Disabled\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsEhcPortEnabled (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 PortNum\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether port is enabled\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Enabled\r
+ FALSE Disabled\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsEhcReseted (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Ehc is halted\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Reseted\r
+ FALSE Unreseted\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsEhcHalted (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Ehc is halted\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Halted\r
+ FALSE Not halted\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsEhcSysError (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Ehc is system error\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE System error\r
+ FALSE No system error\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsHighSpeedDevice (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 PortNum \r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether high speed device attached\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE High speed\r
+ FALSE Full speed\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForEhcReset (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ wait for Ehc reset or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForEhcHalt (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ wait for Ehc halt or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForEhcNotHalt (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ wait for Ehc not halt or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForEhcDoorbell (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for periodic schedule disable or timeout\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForAsyncScheduleEnable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for Ehc asynchronous schedule enable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForAsyncScheduleDisable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for Ehc asynchronous schedule disable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForPeriodicScheduleEnable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for Ehc periodic schedule enable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+WaitForPeriodicScheduleDisable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for periodic schedule disable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+GetCapabilityLen (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the length of capability register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetFrameListBaseAddr (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 FrameBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set base address of frame list first entry\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ FrameBuffer - base address of first entry of frame list\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetAsyncListAddr (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set address of first Async schedule Qh\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to first Qh in the Async schedule\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetCtrlDataStructSeg (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set address of first Async schedule Qh\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to first Qh in the Async schedule\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+SetPortRoutingEhc (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set Ehc port routing bit\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EnablePeriodicSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Enable periodic schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DisablePeriodicSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Disable periodic schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EnableAsynchronousSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Enable asynchrounous schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DisableAsynchronousSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Disable asynchrounous schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StartScheduleExecution (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start Ehc schedule execution\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ResetEhc (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Reset Ehc\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ClearEhcAllStatus (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Clear Ehc all status bits\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+//\r
+// EhciSched Functions\r
+//\r
+EFI_STATUS\r
+InitialPeriodicFrameList (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize Periodic Schedule Frame List\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ Length - Frame List Length\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+DeinitialPeriodicFrameList (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Deinitialize Periodic Schedule Frame List\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreatePollingTimer (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EFI_EVENT_NOTIFY NotifyFunction\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ NotifyFunction - Timer Notify Function\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+DestoryPollingTimer (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destory Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StartPollingTimer (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+StopPollingTimer (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Stop Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateQh (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DeviceAddr,\r
+ IN UINT8 Endpoint,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaxPacketLen,\r
+ OUT EHCI_QH_ENTITY **QhPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qh Structure and Pre-Initialize\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DeviceAddr - Address of Device\r
+ Endpoint - Endpoint Number\r
+ DeviceSpeed - Device Speed\r
+ MaxPacketLen - Max Length of one Packet\r
+ QhPtrPtr - A pointer of pointer to Qh for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateControlQh (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DeviceAddr,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaxPacketLen,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT EHCI_QH_ENTITY **QhPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qh for Control Transfer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DeviceAddr - Address of Device\r
+ DeviceSpeed - Device Speed\r
+ MaxPacketLen - Max Length of one Packet\r
+ Translator - Translator Transaction for SplitX\r
+ QhPtrPtr - A pointer of pointer to Qh for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateBulkQh (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DeviceAddr,\r
+ IN UINT8 EndPointAddr,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINT8 DataToggle,\r
+ IN UINTN MaxPacketLen,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT EHCI_QH_ENTITY **QhPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qh for Bulk Transfer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DeviceAddr - Address of Device\r
+ EndPointAddr - Address of Endpoint\r
+ DeviceSpeed - Device Speed\r
+ MaxPacketLen - Max Length of one Packet\r
+ Translator - Translator Transaction for SplitX\r
+ QhPtrPtr - A pointer of pointer to Qh for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateInterruptQh (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DeviceAddr,\r
+ IN UINT8 EndPointAddr,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINT8 DataToggle,\r
+ IN UINTN MaxPacketLen,\r
+ IN UINTN Interval,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT EHCI_QH_ENTITY **QhPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qh for Control Transfer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DeviceAddr - Address of Device\r
+ EndPointAddr - Address of Endpoint\r
+ DeviceSpeed - Device Speed\r
+ MaxPacketLen - Max Length of one Packet\r
+ Interval - value of interval\r
+ Translator - Translator Transaction for SplitX\r
+ QhPtrPtr - A pointer of pointer to Qh for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+DestoryQh (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destory Qh Structure \r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to Qh\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateQtd (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 *DataPtr,\r
+ IN UINTN DataLen,\r
+ IN UINT8 PktId,\r
+ IN UINT8 Toggle,\r
+ IN UINT8 QtdStatus,\r
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtd Structure and Pre-Initialize it\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DataPtr - A pointer to user data buffer to transfer\r
+ DataLen - Length of user data to transfer\r
+ PktId - Packet Identification of this Qtd\r
+ Toggle - Data Toggle of this Qtd\r
+ QtdStatus - Default value of status of this Qtd\r
+ QtdPtrPtr - A pointer of pointer to Qtd for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateSetupQtd (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 *DevReqPtr,\r
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtd Structure for Setup \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DevReqPtr - A pointer to Device Request Data\r
+ QtdPtrPtr - A pointer of pointer to Qtd for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateDataQtd (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 *DataPtr,\r
+ IN UINTN DataLen,\r
+ IN UINT8 PktId,\r
+ IN UINT8 Toggle,\r
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtd Structure for data \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DataPtr - A pointer to user data buffer to transfer\r
+ DataLen - Length of user data to transfer\r
+ PktId - Packet Identification of this Qtd\r
+ Toggle - Data Toggle of this Qtd\r
+ QtdPtrPtr - A pointer of pointer to Qtd for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateStatusQtd (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 PktId,\r
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtd Structure for status \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ PktId - Packet Identification of this Qtd\r
+ QtdPtrPtr - A pointer of pointer to Qtd for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateAltQtd (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 PktId,\r
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtd Structure for Alternative \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ PktId - Packet Identification of this Qtd\r
+ QtdPtrPtr - A pointer of pointer to Qtd for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateControlQtds (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DataPktId,\r
+ IN UINT8 *RequestCursor,\r
+ IN UINT8 *DataCursor,\r
+ IN UINTN DataLen,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT EHCI_QTD_ENTITY **ControlQtdsHead\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtds list for Control Transfer \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DataPktId - Packet Identification of Data Qtds\r
+ RequestCursor - A pointer to request structure buffer to transfer\r
+ DataCursor - A pointer to user data buffer to transfer\r
+ DataLen - Length of user data to transfer\r
+ ControlQtdsHead - A pointer of pointer to first Qtd for control tranfer for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateBulkOrInterruptQtds (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 PktId,\r
+ IN UINT8 *DataCursor,\r
+ IN UINTN DataLen,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT EHCI_QTD_ENTITY **QtdsHead\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtds list for Bulk or Interrupt Transfer \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ PktId - Packet Identification of Qtds\r
+ DataCursor - A pointer to user data buffer to transfer\r
+ DataLen - Length of user data to transfer\r
+ DataToggle - Data Toggle to start\r
+ Translator - Translator Transaction for SplitX\r
+ QtdsHead - A pointer of pointer to first Qtd for control tranfer for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+DestoryQtds (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QTD_ENTITY *FirstQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destory all Qtds in the list\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ FirstQtdPtr - A pointer to first Qtd in the list \r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+LinkQtdToQtd (\r
+ IN EHCI_QTD_ENTITY *PreQtdPtr,\r
+ IN EHCI_QTD_ENTITY *QtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link Qtds together\r
+ \r
+Arguments:\r
+\r
+ PreQtdPtr - A pointer to pre Qtd\r
+ QtdPtr - A pointer to next Qtd\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+LinkQtdsToAltQtd (\r
+ IN EHCI_QTD_ENTITY *FirstQtdPtr,\r
+ IN EHCI_QTD_ENTITY *AltQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link AlterQtds together\r
+ \r
+Arguments:\r
+\r
+ FirstQtdPtr - A pointer to first Qtd in the list\r
+ AltQtdPtr - A pointer to alternative Qtd\r
+ \r
+Returns:\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+LinkQtdToQh (\r
+ IN EHCI_QH_ENTITY *QhPtr,\r
+ IN EHCI_QTD_ENTITY *QtdEntryPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link Qtds list to Qh\r
+ \r
+Arguments:\r
+\r
+ QhPtr - A pointer to Qh\r
+ QtdPtr - A pointer to first Qtd in the list\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+LinkQhToAsyncList (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link Qh to Async Schedule List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to Qh\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+UnlinkQhFromAsyncList (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Unlink Qh from Async Schedule List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to Qh\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+LinkQhToPeriodicList (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link Qh to Periodic Schedule List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to Qh\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+UnlinkQhFromPeriodicList (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr,\r
+ IN UINTN Interval\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Unlink Qh from Periodic Schedule List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to Qh\r
+ Interval - Interval of this periodic transfer\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+LinkToAsyncReqeust (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Llink AsyncRequest Entry to Async Request List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ AsyncRequestPtr - A pointer to Async Request Entry\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+UnlinkFromAsyncReqeust (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Unlink AsyncRequest Entry from Async Request List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ AsyncRequestPtr - A pointer to Async Request Entry\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+;\r
+\r
+UINTN\r
+GetNumberOfQtd (\r
+ IN EHCI_QTD_ENTITY *FirstQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Number of Qtds in the list\r
+ \r
+Arguments:\r
+\r
+ FirstQtdPtr - A pointer to first Qtd in the list\r
+ \r
+Returns:\r
+\r
+ Number of Qtds in the list\r
+\r
+--*/\r
+;\r
+\r
+UINTN\r
+GetNumberOfTransaction (\r
+ IN UINTN SizeOfData,\r
+ IN UINTN SizeOfTransaction\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Number of Transactions in one Qtd\r
+ \r
+Arguments:\r
+\r
+ SizeOfData - Size of one Qtd\r
+ SizeOfTransaction - Size of one Transaction\r
+ \r
+Returns:\r
+\r
+ Number of Transactions in this Qtd\r
+\r
+--*/\r
+;\r
+\r
+UINTN\r
+GetCapacityOfQtd (\r
+ IN UINT8 *BufferCursor\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get Capacity of Qtd\r
+ \r
+Arguments:\r
+\r
+ BufferCursor - BufferCursor of the Qtd\r
+ \r
+Returns:\r
+\r
+ Capacity of Qtd\r
+\r
+--*/\r
+;\r
+\r
+UINTN\r
+GetApproxiOfInterval (\r
+ IN UINTN Interval\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the approximate value in the 2 index sequence\r
+ \r
+Arguments:\r
+\r
+ Interval - the value of interval\r
+ \r
+Returns:\r
+\r
+ approximate value of interval in the 2 index sequence\r
+ \r
+--*/\r
+;\r
+\r
+EHCI_QTD_HW *\r
+GetQtdNextPointer (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get Qtd next pointer field\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ A pointer to next hardware Qtd structure\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQtdStatusActive (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Qtd status is active or not\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ TRUE Active\r
+ FALSE Inactive\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQtdStatusHalted (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Qtd status is halted or not\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r\r
+\r
+ TRUE Halted\r
+ FALSE Not halted\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQtdStatusBufferError (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Qtd status is buffer error or not\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ TRUE Buffer error\r
+ FALSE No buffer error\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQtdStatusBabbleError (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Qtd status is babble error or not\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ TRUE Babble error\r
+ FALSE No babble error\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQtdStatusTransactionError (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Qtd status is transaction error or not\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ TRUE Transaction error\r
+ FALSE No transaction error\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsDataInTransfer (\r
+ IN UINT8 EndPointAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether is a DataIn direction transfer\r
+ \r
+Arguments:\r
+\r
+ EndPointAddress - address of the endpoint \r
+ \r
+Returns:\r
+\r
+ TRUE DataIn\r
+ FALSE DataOut\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+MapDataBuffer (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EFI_USB_DATA_DIRECTION TransferDirection,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ OUT UINT8 *PktId,\r
+ OUT UINT8 **DataCursor,\r
+ OUT VOID **DataMap\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Map address of user data buffer\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ TransferDirection - direction of transfer\r
+ Data - A pointer to user data buffer \r
+ DataLength - length of user data\r
+ PktId - Packte Identificaion\r
+ DataCursor - mapped address to return\r
+ DataMap - identificaion of this mapping to return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+MapRequestBuffer (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN OUT VOID *Request,\r
+ OUT UINT8 **RequestCursor,\r
+ OUT VOID **RequestMap\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Map address of request structure buffer\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Request - A pointer to request structure\r
+ RequestCursor - Mapped address of request structure to return\r
+ RequestMap - Identificaion of this mapping to return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+SetQtdBufferPointer (\r
+ IN EHCI_QTD_HW *QtdHwPtr,\r
+ IN VOID *DataPtr,\r
+ IN UINTN DataLen\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set data buffer pointers in Qtd\r
+\r
+Arguments:\r
+\r
+ QtdHwPtr - A pointer to Qtd hardware structure \r
+ DataPtr - A pointer to user data buffer\r
+ DataLen - Length of the user data buffer\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+EHCI_QTD_HW *\r
+GetQtdAlternateNextPointer (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get Qtd alternate next pointer field\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ A pointer to hardware alternate Qtd\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+ZeroOutQhOverlay (\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Zero out the fields in Qh structure\r
+ \r
+Arguments:\r
+\r
+ QhPtr - A pointer to Qh structure\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+UpdateAsyncRequestTransfer (\r
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr,\r
+ IN UINT32 TransferResult,\r
+ IN UINTN ErrTDPos\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Update asynchronous request transfer\r
+ \r
+Arguments:\r
+\r
+ AsyncRequestPtr - A pointer to async request \r
+ TransferResult - transfer result \r
+ ErrQtdPos - postion of error Qtd\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+;\r
+\r
+\r
+EFI_STATUS\r
+DeleteAsyncRequestTransfer (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ OUT UINT8 *DataToggle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Delete all asynchronous request transfer\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DeviceAddress - address of usb device\r
+ EndPointAddress - address of endpoint\r
+ DataToggle - stored data toggle\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+CleanUpAllAsyncRequestTransfer (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Clean up all asynchronous request transfer\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+ VOID\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+ExecuteTransfer (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN BOOLEAN IsControl,\r
+ IN EHCI_QH_ENTITY *QhPtr,\r
+ IN OUT UINTN *ActualLen,\r
+ OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Execute Bulk or SyncInterrupt Transfer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ IsControl - Is control transfer or not\r
+ QhPtr - A pointer to Qh\r
+ ActualLen - Actual transfered Len \r
+ DataToggle - Data Toggle\r
+ TimeOut - TimeOut threshold\r
+ TransferResult - Transfer result\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Sucess\r
+ EFI_DEVICE_ERROR Error\r
+ \r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+CheckQtdsTransferResult (\r
+ IN BOOLEAN IsControl,\r
+ IN EHCI_QH_ENTITY *QhPtr,\r
+ OUT UINT32 *Result,\r
+ OUT UINTN *ErrQtdPos,\r
+ OUT UINTN *ActualLen\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check transfer result of Qtds\r
+\r
+Arguments:\r
+\r
+ IsControl - Is control transfer or not\r
+ QhPtr - A pointer to Qh\r
+ Result - Transfer result\r
+ ErrQtdPos - Error TD Position\r
+ ActualLen - Actual Transfer Size\r
+\r
+Returns:\r
+\r
+ TRUE Qtds finished\r
+ FALSE Not finish\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AsyncRequestMoniter (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ \r
+ Interrupt transfer periodic check handler\r
+ \r
+Arguments:\r
+\r
+ Event - Interrupt event\r
+ Context - Pointer to USB2_HC_DEV\r
+ \r
+Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--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.-->\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+ <MsaHeader>\r
+ <ModuleName>Ehci</ModuleName>\r
+ <ModuleType>UEFI_DRIVER</ModuleType>\r
+ <GuidValue>BDFE430E-8F2A-4db0-9991-6F856594777E</GuidValue>\r
+ <Version>1.0</Version>\r
+ <Abstract>Component description file for Ehci module</Abstract>\r
+ <Description>This module provides USB2 Host Controller Protocol implementation for Enhanced Host Controller Interface</Description>\r
+ <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>\r
+ <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>\r
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
+ </MsaHeader>\r
+ <ModuleDefinitions>\r
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+ <BinaryModule>false</BinaryModule>\r
+ <OutputFileBasename>Ehci</OutputFileBasename>\r
+ </ModuleDefinitions>\r
+ <LibraryClassDefinitions>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>DebugLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiDriverModelLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiDriverEntryPoint</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseMemoryLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>MemoryAllocationLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiBootServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ </LibraryClassDefinitions>\r
+ <SourceFiles>\r
+ <Filename>Ehci.c</Filename>\r
+ <Filename>EhciMem.c</Filename>\r
+ <Filename>EhciReg.c</Filename>\r
+ <Filename>EhciSched.c</Filename>\r
+ <Filename>ComponentName.c</Filename>\r
+ <Filename>Ehci.h</Filename>\r
+ </SourceFiles>\r
+ <PackageDependencies>\r
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ </PackageDependencies>\r
+ <Protocols>\r
+ <Protocol Usage="TO_START">\r
+ <ProtocolCName>gEfiPciIoProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="BY_START">\r
+ <ProtocolCName>gEfiUsb2HcProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ </Protocols>\r
+ <Externs>\r
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+ <Specification>EDK_RELEASE_VERSION 0x00020000</Specification>\r
+ <Extern>\r
+ <DriverBinding>gEhciDriverBinding</DriverBinding>\r
+ </Extern>\r
+ <Extern>\r
+ <ComponentName>gEhciComponentName</ComponentName>\r
+ </Extern>\r
+ </Externs>\r
+</ModuleSurfaceArea>
\ No newline at end of file
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ EhciMem.c\r
+ \r
+Abstract: \r
+ \r
+\r
+Revision History\r
+--*/\r
+\r
+#include "Ehci.h"\r
+\r
+\r
+EFI_STATUS\r
+CreateMemoryBlock (\r
+ IN USB2_HC_DEV *HcDev,\r
+ OUT MEMORY_MANAGE_HEADER **MemoryHeader,\r
+ IN UINTN MemoryBlockSizeInPages\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Use PciIo->AllocateBuffer to allocate common buffer for the memory block,\r
+ and use PciIo->Map to map the common buffer for Bus Master Read/Write.\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ MemoryHeader - MEMORY_MANAGE_HEADER to output\r
+ MemoryBlockSizeInPages - MemoryBlockSizeInPages\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Fail for no resources\r
+ EFI_UNSUPPORTED Unsupported currently\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ VOID *CommonBuffer;\r
+ EFI_PHYSICAL_ADDRESS MappedAddress;\r
+ UINTN MemoryBlockSizeInBytes;\r
+ VOID *Mapping;\r
+\r
+ //\r
+ // Allocate memory for MemoryHeader\r
+ //\r
+ *MemoryHeader = AllocateZeroPool (sizeof (MEMORY_MANAGE_HEADER));\r
+ if (*MemoryHeader == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ (*MemoryHeader)->Next = NULL;\r
+\r
+ //\r
+ // set Memory block size\r
+ //\r
+ (*MemoryHeader)->MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
+\r
+ //\r
+ // each bit in Bit Array will manage 32 bytes memory in memory block\r
+ //\r
+ (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / 32) / 8;\r
+\r
+ //\r
+ // Allocate memory for BitArray\r
+ //\r
+ (*MemoryHeader)->BitArrayPtr = AllocateZeroPool ((*MemoryHeader)->BitArraySizeInBytes);\r
+ if ((*MemoryHeader)->BitArrayPtr == NULL) {\r
+ gBS->FreePool (*MemoryHeader);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ \r
+ //\r
+ // Memory Block uses MemoryBlockSizeInPages pages,\r
+ // and it is allocated as common buffer use.\r
+ //\r
+ Status = HcDev->PciIo->AllocateBuffer (\r
+ HcDev->PciIo,\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ MemoryBlockSizeInPages,\r
+ &CommonBuffer,\r
+ 0\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
+ gBS->FreePool (*MemoryHeader);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
+ Status = HcDev->PciIo->Map (\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterCommonBuffer,\r
+ CommonBuffer,\r
+ &MemoryBlockSizeInBytes,\r
+ &MappedAddress,\r
+ &Mapping\r
+ );\r
+ //\r
+ // If returned Mapped size is less than the size \r
+ // we request,do not support.\r
+ //\r
+ if (EFI_ERROR (Status) || (MemoryBlockSizeInBytes != EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages))) {\r
+ HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);\r
+ gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
+ gBS->FreePool (*MemoryHeader);\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ \r
+ //\r
+ // Data structure involved by host controller \r
+ // should be restricted into the same 4G\r
+ //\r
+ if (HcDev->Is64BitCapable != 0) {\r
+ if (HcDev->High32BitAddr != GET_32B_TO_63B (MappedAddress)) {\r
+ HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
+ HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);\r
+ gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
+ gBS->FreePool (*MemoryHeader);\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Set Memory block initial address\r
+ //\r
+ (*MemoryHeader)->MemoryBlockPtr = (UINT8 *) ((UINTN) MappedAddress);\r
+ (*MemoryHeader)->Mapping = Mapping;\r
+\r
+ ZeroMem (\r
+ (*MemoryHeader)->MemoryBlockPtr,\r
+ EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages)\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+FreeMemoryHeader (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeader\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Free Memory Header\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ MemoryHeader - MemoryHeader to be freed\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_INVALID_PARAMETER Parameter is error\r
+\r
+--*/\r
+{\r
+ if ((MemoryHeader == NULL) || (HcDev == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ //\r
+ // unmap the common buffer used by the memory block\r
+ //\r
+ HcDev->PciIo->Unmap (HcDev->PciIo, MemoryHeader->Mapping);\r
+\r
+ //\r
+ // free common buffer\r
+ //\r
+ HcDev->PciIo->FreeBuffer (\r
+ HcDev->PciIo,\r
+ EFI_SIZE_TO_PAGES (MemoryHeader->MemoryBlockSizeInBytes),\r
+ MemoryHeader->MemoryBlockPtr\r
+ );\r
+ //\r
+ // free bit array\r
+ //\r
+ gBS->FreePool (MemoryHeader->BitArrayPtr);\r
+ //\r
+ // free memory header\r
+ //\r
+ gBS->FreePool (MemoryHeader);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+EhciAllocatePool (\r
+ IN USB2_HC_DEV *HcDev,\r
+ OUT UINT8 **Pool,\r
+ IN UINTN AllocSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Ehci Allocate Pool\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ Pool - Place to store pointer to the memory buffer\r
+ AllocSize - Alloc Size\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+\r
+--*/\r
+{\r
+ MEMORY_MANAGE_HEADER *MemoryHeader;\r
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
+ MEMORY_MANAGE_HEADER *NewMemoryHeader;\r
+ UINTN RealAllocSize;\r
+ UINTN MemoryBlockSizeInPages;\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ *Pool = NULL;\r
+\r
+ MemoryHeader = HcDev->MemoryHeader;\r
+ ASSERT (MemoryHeader != NULL);\r
+\r
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r
+ \r
+ //\r
+ // allocate unit is 32 bytes (align on 32 byte)\r
+ //\r
+ if (AllocSize & 0x1F) {\r
+ RealAllocSize = (AllocSize / 32 + 1) * 32;\r
+ } else {\r
+ RealAllocSize = AllocSize;\r
+ }\r
+ \r
+ //\r
+ // There may be linked MemoryHeaders.\r
+ // To allocate a free pool in Memory blocks,\r
+ // must search in the MemoryHeader link list\r
+ // until enough free pool is found.\r
+ //\r
+ Status = EFI_NOT_FOUND;\r
+ for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
+\r
+ Status = AllocMemInMemoryBlock (\r
+ TempHeaderPtr,\r
+ Pool,\r
+ RealAllocSize / 32\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ ZeroMem (*Pool, AllocSize);\r
+ gBS->RestoreTPL (OldTpl);\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+ \r
+ //\r
+ // There is no enough memory,\r
+ // Create a new Memory Block\r
+ //\r
+ \r
+ //\r
+ // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,\r
+ // just allocate a large enough memory block.\r
+ //\r
+ if (RealAllocSize > EFI_PAGES_TO_SIZE (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES)) {\r
+ MemoryBlockSizeInPages = EFI_SIZE_TO_PAGES (RealAllocSize) + 1;\r
+ } else {\r
+ MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;\r
+ }\r
+\r
+ Status = CreateMemoryBlock (HcDev, &NewMemoryHeader, MemoryBlockSizeInPages);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r\r
+ \r
+ //\r
+ // Link the new Memory Block to the Memory Header list\r
+ //\r
+ InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);\r
+\r
+ Status = AllocMemInMemoryBlock (\r
+ NewMemoryHeader,\r
+ Pool,\r
+ RealAllocSize / 32\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ ZeroMem (*Pool, AllocSize);\r
+ }\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+}\r
+\r
+VOID\r
+EhciFreePool (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 *Pool,\r
+ IN UINTN AllocSize\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Uhci Free Pool\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ Pool - Pool to free\r
+ AllocSize - Pool size\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ MEMORY_MANAGE_HEADER *MemoryHeader;\r
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
+ UINTN StartBytePos;\r
+ UINTN Index;\r
+ UINT8 StartBitPos;\r
+ UINT8 Index2;\r
+ UINTN Count;\r
+ UINTN RealAllocSize;\r
+ EFI_TPL OldTpl;\r
+\r
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r
+\r
+ MemoryHeader = HcDev->MemoryHeader;\r
+\r
+ //\r
+ // allocate unit is 32 byte (align on 32 byte)\r
+ //\r
+ if (AllocSize & 0x1F) {\r
+ RealAllocSize = (AllocSize / 32 + 1) * 32;\r
+ } else {\r
+ RealAllocSize = AllocSize;\r
+ }\r
+ \r
+ //\r
+ // scan the memory header linked list for\r
+ // the asigned memory to free.\r
+ //\r
+ for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
+\r
+ if ((Pool >= TempHeaderPtr->MemoryBlockPtr) &&\r
+ ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr + TempHeaderPtr->MemoryBlockSizeInBytes))\r
+ ) {\r
+ //\r
+ // Pool is in the Memory Block area,\r
+ // find the start byte and bit in the bit array\r
+ //\r
+ StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8;\r
+ StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) & 0x7);\r
+\r
+ //\r
+ // reset associated bits in bit arry\r
+ //\r
+ for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {\r
+ TempHeaderPtr->BitArrayPtr[Index] ^= (UINT8) (bit (Index2));\r
+ Index2++;\r
+ if (Index2 == 8) {\r
+ Index += 1;\r
+ Index2 = 0;\r
+ }\r
+ }\r
+ //\r
+ // break the loop\r
+ //\r
+ break;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Release emptied memory blocks (only if the memory block is not\r
+ // the first one in the memory header list\r
+ //\r
+ for (TempHeaderPtr = MemoryHeader->Next; TempHeaderPtr != NULL;) {\r
+\r
+ ASSERT (MemoryHeader->Next != NULL);\r
+\r
+ if (IsMemoryBlockEmptied (TempHeaderPtr)) {\r
+\r
+ DelinkMemoryBlock (MemoryHeader, TempHeaderPtr);\r
+ //\r
+ // when the TempHeaderPtr is freed in FreeMemoryHeader(),\r
+ // the TempHeaderPtr is pointing to nonsense content.\r
+ //\r
+ gBS->RestoreTPL (OldTpl);\r
+ FreeMemoryHeader (HcDev, TempHeaderPtr);\r
+ OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);\r
+ //\r
+ // reset the TempHeaderPtr, continue search for\r
+ // another empty memory block.\r
+ //\r
+ TempHeaderPtr = MemoryHeader->Next;\r
+ continue;\r
+ }\r
+\r
+ TempHeaderPtr = TempHeaderPtr->Next;\r
+ }\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+}\r
+\r
+VOID\r
+InsertMemoryHeaderToList (\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
+ IN MEMORY_MANAGE_HEADER *NewMemoryHeader\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Insert Memory Header To List\r
+\r
+Arguments:\r
+\r
+ MemoryHeader - MEMORY_MANAGE_HEADER\r
+ NewMemoryHeader - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
+\r
+ for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
+ if (TempHeaderPtr->Next == NULL) {\r
+ TempHeaderPtr->Next = NewMemoryHeader;\r
+ break;\r
+ }\r
+ }\r
+}\r
+\r
+EFI_STATUS\r
+AllocMemInMemoryBlock (\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
+ OUT VOID **Pool,\r
+ IN UINTN NumberOfMemoryUnit\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Alloc Memory In MemoryBlock\r
+\r
+Arguments:\r
+\r
+ MemoryHeader - MEMORY_MANAGE_HEADER\r
+ Pool - Place to store pointer to memory\r
+ NumberOfMemoryUnit - Number Of Memory Unit\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_NOT_FOUND Can't find the free memory \r
+\r
+--*/\r
+{\r
+ UINTN TempBytePos;\r
+ UINTN FoundBytePos;\r
+ UINT8 Index;\r
+ UINT8 FoundBitPos;\r
+ UINT8 ByteValue;\r
+ UINT8 BitValue;\r
+ UINTN NumberOfZeros;\r
+ UINTN Count;\r
+\r
+ FoundBytePos = 0;\r
+ FoundBitPos = 0;\r
+ ByteValue = MemoryHeader->BitArrayPtr[0];\r
+ NumberOfZeros = 0;\r
+ Index = 0;\r
+\r
+ for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {\r
+ \r
+ //\r
+ // Pop out BitValue from a byte in TempBytePos.\r
+ //\r
+ BitValue = (UINT8) (ByteValue & 0x1);\r
+ \r
+ //\r
+ // right shift the byte\r
+ //\r
+ ByteValue /= 2;\r
+\r
+ if (BitValue == 0) {\r
+ //\r
+ // Found a free bit, the NumberOfZeros only record the number\r
+ // of those consecutive zeros\r
+ //\r
+ NumberOfZeros++;\r
+ //\r
+ // Found enough consecutive free space, break the loop\r
+ //\r
+ if (NumberOfZeros >= NumberOfMemoryUnit) {\r
+ break;\r
+ }\r
+ } else {\r
+ //\r
+ // Encountering a '1', meant the bit is ocupied.\r
+ //\r
+ if (NumberOfZeros >= NumberOfMemoryUnit) {\r
+ //\r
+ // Found enough consecutive free space,break the loop\r
+ //\r
+ break;\r
+ } else {\r
+ //\r
+ // the NumberOfZeros only record the number of those consecutive zeros,\r
+ // so reset the NumberOfZeros to 0 when encountering '1' before finding\r
+ // enough consecutive '0's\r
+ //\r
+ NumberOfZeros = 0;\r
+ //\r
+ // reset the (FoundBytePos,FoundBitPos) to the position of '1'\r
+ //\r
+ FoundBytePos = TempBytePos;\r
+ FoundBitPos = Index;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // step forward a bit\r
+ //\r
+ Index++;\r
+ if (Index == 8) {\r
+ //\r
+ // step forward a byte, getting the byte value,\r
+ // and reset the bit pos.\r
+ //\r
+ TempBytePos += 1;\r
+ ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];\r
+ Index = 0;\r
+ }\r
+ }\r
+\r
+ if (NumberOfZeros < NumberOfMemoryUnit) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ \r
+ //\r
+ // Found enough free space.\r
+ //\r
+ \r
+ //\r
+ // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:\r
+ // 1)(FoundBytePos,FoundBitPos) record the position\r
+ // of the last '1' before the consecutive '0's, it must\r
+ // be adjusted to the start position of the consecutive '0's.\r
+ // 2)the start address of the consecutive '0's is just the start of\r
+ // the bitarray. so no need to adjust the values of\r
+ // (FoundBytePos,FoundBitPos).\r
+ //\r
+ if ((MemoryHeader->BitArrayPtr[FoundBytePos] & bit (FoundBitPos)) != 0) {\r
+ FoundBitPos += 1;\r
+ }\r
+ \r
+ //\r
+ // Have the (FoundBytePos,FoundBitPos) make sense.\r
+ //\r
+ if (FoundBitPos > 7) {\r
+ FoundBytePos += 1;\r
+ FoundBitPos -= 8;\r
+ }\r
+ \r
+ //\r
+ // Set the memory as allocated\r
+ //\r
+ for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) {\r
+\r
+ MemoryHeader->BitArrayPtr[TempBytePos] |= bit (Index);\r
+ Index++;\r
+ if (Index == 8) {\r
+ TempBytePos += 1;\r
+ Index = 0;\r
+ }\r
+ }\r
+\r
+ *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * 32;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+BOOLEAN\r
+IsMemoryBlockEmptied (\r
+ IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Is Memory Block Emptied\r
+\r
+Arguments:\r
+\r
+ MemoryHeaderPtr - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+ TRUE Empty\r
+ FALSE Not Empty \r
+\r
+--*/\r
+{\r
+ UINTN Index;\r
+\r
+ for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {\r
+ if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {\r
+ return FALSE;\r
+ }\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+VOID\r
+DelinkMemoryBlock (\r
+ IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,\r
+ IN MEMORY_MANAGE_HEADER *NeedFreeMemoryHeader\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Delink Memory Block\r
+\r
+Arguments:\r
+\r
+ FirstMemoryHeader - MEMORY_MANAGE_HEADER\r
+ NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
+\r
+ if ((FirstMemoryHeader == NULL) || (NeedFreeMemoryHeader == NULL)) {\r
+ return ;\r
+ }\r
+\r
+ for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {\r
+\r
+ if (TempHeaderPtr->Next == NeedFreeMemoryHeader) {\r
+ //\r
+ // Link the before and after\r
+ //\r
+ TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;\r
+ break;\r
+ }\r
+ }\r
+}\r
+\r
+EFI_STATUS\r
+InitialMemoryManagement (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize Memory Management\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ MEMORY_MANAGE_HEADER *MemoryHeader;\r
+ UINTN MemPages;\r
+\r
+ MemPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;\r
+ Status = CreateMemoryBlock (HcDev, &MemoryHeader, MemPages);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+\r
+ HcDev->MemoryHeader = MemoryHeader;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DeinitialMemoryManagement (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Deinitialize Memory Management\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;\r
+\r
+ for (TempHeaderPtr = HcDev->MemoryHeader->Next; TempHeaderPtr != NULL;) {\r
+\r
+ DelinkMemoryBlock (HcDev->MemoryHeader, TempHeaderPtr);\r
+ //\r
+ // when the TempHeaderPtr is freed in FreeMemoryHeader(),\r
+ // the TempHeaderPtr is pointing to nonsense content.\r
+ //\r
+ FreeMemoryHeader (HcDev, TempHeaderPtr);\r
+ //\r
+ // reset the TempHeaderPtr,continue free another memory block.\r
+ //\r
+ TempHeaderPtr = HcDev->MemoryHeader->Next;\r
+ }\r
+\r
+ FreeMemoryHeader (HcDev, HcDev->MemoryHeader);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ Ehchlp.c\r
+ \r
+Abstract: \r
+ \r
+\r
+Revision History\r
+--*/\r
+\r
+#include "Ehci.h"\r
+\r
+\r
+EFI_STATUS\r
+ReadEhcCapabiltiyReg (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 CapabiltiyRegAddr,\r
+ IN OUT UINT32 *Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read Ehc Capabitlity register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ CapabiltiyRegAddr - Ehc Capability register address\r
+ Data - A pointer to data read from register\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ return HcDev->PciIo->Mem.Read (\r
+ HcDev->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ USB_BAR_INDEX,\r
+ (UINT64) CapabiltiyRegAddr,\r
+ 1,\r
+ Data\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+ReadEhcOperationalReg (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 OperationalRegAddr,\r
+ IN OUT UINT32 *Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read Ehc Operation register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ OperationalRegAddr - Ehc Operation register address\r
+ Data - A pointer to data read from register\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ ASSERT (mUsbCapabilityLen);\r
+ return HcDev->PciIo->Mem.Read (\r
+ HcDev->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ USB_BAR_INDEX,\r
+ (UINT64) (OperationalRegAddr + mUsbCapabilityLen),\r
+ 1,\r
+ Data\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+WriteEhcOperationalReg (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 OperationalRegAddr,\r
+ IN UINT32 Data\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Write Ehc Operation register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ OperationalRegAddr - Ehc Operation register address\r
+ Data - 32bit write to register\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ ASSERT (mUsbCapabilityLen);\r
+ return HcDev->PciIo->Mem.Write (\r
+ HcDev->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ USB_BAR_INDEX,\r
+ (UINT64) (OperationalRegAddr + mUsbCapabilityLen),\r
+ 1,\r
+ &Data\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+GetCapabilityLen (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the length of capability register\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 CapabilityLenAddr;\r
+\r
+ CapabilityLenAddr = CAPLENGTH;\r
+\r
+ Status = ReadEhcCapabiltiyReg (\r
+ HcDev,\r
+ CapabilityLenAddr,\r
+ &mUsbCapabilityLen\r
+ );\r
+ mUsbCapabilityLen = (UINT8) mUsbCapabilityLen;\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetFrameListLen (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set the length of Frame List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Length - the required length of frame list\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_INVALID_PARAMETER Invalid parameter\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ if (256 != Length && 512 != Length) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ if (256 == Length) {\r
+ UsbCommandReg |= USBCMD_FLS_256;\r
+ } else {\r
+ UsbCommandReg |= USBCMD_FLS_512;\r
+ }\r
+\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetFrameListBaseAddr (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT32 FrameBuffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set base address of frame list first entry\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ FrameBuffer - base address of first entry of frame list\r
+ \r
+Returns:\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 PeriodicListBaseAddr;\r
+ UINT32 PeriodicListBaseReg;\r
+\r
+ Status = EFI_SUCCESS;\r
+ PeriodicListBaseAddr = PERIODICLISTBASE;\r
+ PeriodicListBaseReg = FrameBuffer & 0xfffff000;\r
+\r
+ if (IsEhcHalted (HcDev)) {\r
+\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ PeriodicListBaseAddr,\r
+ PeriodicListBaseReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetAsyncListAddr (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set address of first Async schedule Qh\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to first Qh in the Async schedule\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 AsyncListAddr;\r
+ UINT32 AsyncListReg;\r
+\r
+ AsyncListAddr = ASYNCLISTADDR;\r
+ AsyncListReg = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh));\r
+\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ AsyncListAddr,\r
+ AsyncListReg\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetCtrlDataStructSeg (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set register of control and data structure segment\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 CtrlDsSegmentAddr;\r
+ UINT32 CtrlDsSegmentReg;\r
+\r
+ CtrlDsSegmentAddr = CTRLDSSGMENT;\r
+ CtrlDsSegmentReg = HcDev->High32BitAddr;\r
+\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ CtrlDsSegmentAddr,\r
+ CtrlDsSegmentReg\r
+ );\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetPortRoutingEhc (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set Ehc port routing bit\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 ConfigFlagAddr;\r
+ UINT32 ConfigFlagReg;\r
+\r
+ ConfigFlagAddr = CONFIGFLAG;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ ConfigFlagAddr,\r
+ &ConfigFlagReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ ConfigFlagReg |= CONFIGFLAG_CF;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ ConfigFlagAddr,\r
+ ConfigFlagReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+SetEhcDoorbell (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set Ehc door bell bit\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_IAAD;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+ClearEhcAllStatus (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Clear Ehc all status bits\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ UINT32 UsbStatusAddr;\r
+\r
+ UsbStatusAddr = USBSTS;\r
+\r
+ return WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ 0x003F\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EnablePeriodicSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Enable periodic schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_PSE;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DisablePeriodicSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Disable periodic schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ UsbCommandReg &= ~USBCMD_PSE;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EnableAsynchronousSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Enable asynchrounous schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_ASE;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DisableAsynchronousSchedule (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Disable asynchrounous schedule\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ UsbCommandReg &= ~USBCMD_ASE;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+ResetEhc (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Reset Ehc\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_HCRESET;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+StartScheduleExecution (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start Ehc schedule execution\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ UsbCommandReg |= USBCMD_RS;\r
+ Status = WriteEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+BOOLEAN\r
+IsFrameListProgrammable (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether frame list is programmable\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Programmable\r
+ FALSE Unprogrammable\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 HcCapParamsAddr;\r
+ UINT32 HcCapParamsReg;\r
+\r
+ HcCapParamsAddr = HCCPARAMS;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ HcCapParamsAddr,\r
+ &HcCapParamsReg\r
+ );\r
+\r
+ if (HcCapParamsReg & HCCP_PFLF) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsPeriodicScheduleEnabled (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether periodic schedule is enabled\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Enabled\r
+ FALSE Disabled\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 UsbStatusAddr;\r
+ UINT32 UsbStatusReg;\r
+\r
+ UsbStatusAddr = USBSTS;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ &UsbStatusReg\r
+ );\r
+\r
+ if (UsbStatusReg & USBSTS_PSS) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsAsyncScheduleEnabled (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether asynchronous schedule is enabled\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Enabled\r
+ FALSE Disabled\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 UsbStatusAddr;\r
+ UINT32 UsbStatusReg;\r
+\r
+ UsbStatusAddr = USBSTS;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ &UsbStatusReg\r
+ );\r
+\r
+ if (UsbStatusReg & USBSTS_ASS) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsEhcPortEnabled (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 PortNum\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether port is enabled\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Enabled\r
+ FALSE Disabled\r
+ \r
+--*/\r
+{\r
+ UINT32 PortStatusControlAddr;\r
+ UINT32 PortStatusControlReg;\r
+\r
+ PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ &PortStatusControlReg\r
+ );\r
+\r
+ return ((PortStatusControlReg & PORTSC_PED) ? TRUE : FALSE);\r
+}\r
+\r
+BOOLEAN\r
+IsEhcReseted (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Ehc is reseted\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Reseted\r
+ FALSE Unreseted\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+\r
+ if (UsbCommandReg & USBCMD_HCRESET) {\r
+ Value = FALSE;\r
+ } else {\r
+ Value = TRUE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsEhcHalted (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Ehc is halted\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE Halted\r
+ FALSE Not halted\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 UsbStatusAddr;\r
+ UINT32 UsbStatusReg;\r
+\r
+ UsbStatusAddr = USBSTS;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ &UsbStatusReg\r
+ );\r
+\r
+ if (UsbStatusReg & USBSTS_HCH) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsEhcSysError (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Ehc is system error\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE System error\r
+ FALSE No system error\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+ UINT32 UsbStatusAddr;\r
+ UINT32 UsbStatusReg;\r
+\r
+ UsbStatusAddr = USBSTS;\r
+\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbStatusAddr,\r
+ &UsbStatusReg\r
+ );\r
+\r
+ if (UsbStatusReg & USBSTS_HSE) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsHighSpeedDevice (\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 PortNum \r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether high speed device attached\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ TRUE High speed\r
+ FALSE Full speed\r
+ \r
+--*/\r
+{\r
+ USB2_HC_DEV *HcDev;\r
+ UINT32 PortStatusControlAddr;\r
+ UINT32 PortStatusControlReg;\r
+ \r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));\r
+\r
+ //\r
+ // Set port reset bit\r
+ //\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ &PortStatusControlReg\r
+ );\r
+ //\r
+ // Make sure Host Controller not halt before reset it\r
+ //\r
+ if (IsEhcHalted (HcDev)) {\r
+ StartScheduleExecution (HcDev);\r
+ WaitForEhcNotHalt (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ }\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg |= PORTSC_PR;\r
+ //\r
+ // Set one to PortReset bit must also set zero to PortEnable bit\r
+ //\r
+ PortStatusControlReg &= ~PORTSC_PED;\r
+ WriteEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ PortStatusControlReg\r
+ );\r
+\r
+ //\r
+ // Set Port reset recovery time\r
+ //\r
+ gBS->Stall (EHCI_SET_PORT_RESET_RECOVERY_TIME);\r
+\r
+ //\r
+ // Clear port reset bit\r
+ //\r
+ ReadEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ &PortStatusControlReg\r
+ );\r
+ PortStatusControlReg &= 0xffffffd5;\r
+ PortStatusControlReg &= ~PORTSC_PR;\r
+ WriteEhcOperationalReg (\r
+ HcDev,\r
+ PortStatusControlAddr,\r
+ PortStatusControlReg\r
+ );\r
+\r
+ //\r
+ // Clear port reset recovery time\r
+ //\r
+ gBS->Stall (EHCI_CLEAR_PORT_RESET_RECOVERY_TIME);\r
+\r
+ return (IsEhcPortEnabled (HcDev, PortNum) ? TRUE : FALSE);\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcReset (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ wait for Ehc reset or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (IsEhcReseted (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcHalt (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ wait for Ehc halt or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (IsEhcHalted (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcNotHalt (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ wait for Ehc not halt or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (!IsEhcHalted (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForAsyncScheduleEnable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for Ehc asynchronous schedule enable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (IsAsyncScheduleEnabled (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForAsyncScheduleDisable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for Ehc asynchronous schedule disable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (!IsAsyncScheduleEnabled (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForPeriodicScheduleEnable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for Ehc periodic schedule enable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (IsPeriodicScheduleEnabled (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForPeriodicScheduleDisable (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for periodic schedule disable or timeout\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Delay;\r
+\r
+ //\r
+ // Timeout is in US unit\r
+ //\r
+ Delay = (Timeout / 50) + 1;\r
+ do {\r
+\r
+ if (!IsPeriodicScheduleEnabled (HcDev)) {\r
+ Status = EFI_SUCCESS;\r
+ goto exit;\r
+ }\r
+ gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
+\r
+ } while (Delay--);\r
+\r
+ Status = EFI_TIMEOUT;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+WaitForEhcDoorbell (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Timeout\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait for periodic schedule disable or timeout\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Timeout - timeout threshold\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_TIMEOUT Timeout\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 UsbCommandAddr;\r
+ UINT32 UsbCommandReg;\r
+ UINTN Delay;\r
+\r
+ UsbCommandAddr = USBCMD;\r
+ Delay = (Timeout / 50) + 1;\r
+ \r
+ do {\r
+ Status = ReadEhcOperationalReg (\r
+ HcDev,\r
+ UsbCommandAddr,\r
+ &UsbCommandReg\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ if (!(UsbCommandReg & USBCMD_IAAD)) {\r
+ break;\r
+ }\r
+ \r
+ } while (--Delay);\r
+\r
+ if (0 == Delay) {\r
+ Status = EFI_TIMEOUT;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ EhciSched.c\r
+ \r
+Abstract: \r
+ \r
+\r
+Revision History\r
+--*/\r
+\r
+#include "Ehci.h"\r
+\r
+EFI_STATUS\r
+InitialPeriodicFrameList (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINTN Length\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize Periodic Schedule Frame List\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ Length - Frame List Length\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ VOID *CommonBuffer;\r
+ EFI_PHYSICAL_ADDRESS FrameBuffer;\r
+ VOID *Map;\r
+ UINTN BufferSizeInPages;\r
+ UINTN BufferSizeInBytes;\r
+ UINTN FrameIndex;\r
+ FRAME_LIST_ENTRY *FrameEntryPtr;\r
+ \r
+ //\r
+ // The Frame List is a common buffer that will be\r
+ // accessed by both the cpu and the usb bus master\r
+ // at the same time.\r
+ // The Frame List ocupies 4K bytes,\r
+ // and must be aligned on 4-Kbyte boundaries.\r
+ //\r
+ if (EHCI_MAX_FRAME_LIST_LENGTH != Length && IsFrameListProgrammable (HcDev)) {\r
+ Status = SetFrameListLen (HcDev, Length);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+ }\r
+\r
+ BufferSizeInBytes = EFI_PAGE_SIZE;\r
+ BufferSizeInPages = EFI_SIZE_TO_PAGES (BufferSizeInBytes);\r
+ Status = HcDev->PciIo->AllocateBuffer (\r
+ HcDev->PciIo,\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ BufferSizeInPages,\r
+ &CommonBuffer,\r
+ 0\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((gEHCErrorLevel, "PciIo->AllocateBuffer Failed\n"));\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+\r
+ Status = HcDev->PciIo->Map (\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterCommonBuffer,\r
+ CommonBuffer,\r
+ &BufferSizeInBytes,\r
+ &FrameBuffer,\r
+ &Map\r
+ );\r
+ if (EFI_ERROR (Status) || (BufferSizeInBytes != EFI_PAGE_SIZE)) {\r
+ DEBUG ((gEHCErrorLevel, "PciIo->MapBuffer Failed\n"));\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto free_buffer;\r
+ }\r
+\r
+ //\r
+ // Put high 32bit into CtrlDataStructSeg reg \r
+ // when 64bit addressing range capability\r
+ //\r
+ if (HcDev->Is64BitCapable != 0) {\r
+ HcDev->High32BitAddr = (UINT32) GET_32B_TO_63B (FrameBuffer);\r
+ \r
+ Status = SetCtrlDataStructSeg (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((gEHCErrorLevel, "SetCtrlDataStructSeg Failed\n"));\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto unmap_buffer;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Tell the Host Controller where the Frame List lies,\r
+ // by set the Frame List Base Address Register.\r
+ //\r
+ Status = SetFrameListBaseAddr (HcDev, (UINT32) FrameBuffer);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto unmap_buffer;\r
+ }\r
+\r
+ HcDev->PeriodicFrameListLength = Length;\r
+ HcDev->PeriodicFrameListBuffer = (VOID *) ((UINTN) FrameBuffer);\r
+ HcDev->PeriodicFrameListMap = Map;\r
+\r
+ //\r
+ // Init Frame List Array fields\r
+ //\r
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;\r
+ for (FrameIndex = 0; FrameIndex < HcDev->PeriodicFrameListLength; FrameIndex++) {\r
+ FrameEntryPtr->LinkPointer = 0;\r
+ FrameEntryPtr->Rsvd = 0;\r
+ FrameEntryPtr->SelectType = 0;\r
+ FrameEntryPtr->LinkTerminate = TRUE;\r
+ FrameEntryPtr++;\r
+ }\r
+\r
+ goto exit;\r
+\r
+unmap_buffer:\r
+ HcDev->PciIo->Unmap (HcDev->PciIo, Map);\r
+free_buffer:\r
+ HcDev->PciIo->FreeBuffer (HcDev->PciIo, BufferSizeInPages, CommonBuffer);\r
+exit:\r
+ return Status;\r
+}\r
+\r
+VOID\r
+DeinitialPeriodicFrameList (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Deinitialize Periodic Schedule Frame List\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+\r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+{\r
+ HcDev->PciIo->Unmap (HcDev->PciIo, HcDev->PeriodicFrameListMap);\r
+ HcDev->PciIo->FreeBuffer (HcDev->PciIo, EFI_SIZE_TO_PAGES (EFI_PAGE_SIZE), HcDev->PeriodicFrameListBuffer);\r
+ return ;\r
+}\r
+\r
+EFI_STATUS\r
+CreatePollingTimer (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EFI_EVENT_NOTIFY NotifyFunction\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ NotifyFunction - Timer Notify Function\r
+ \r
+Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ return gBS->CreateEvent (\r
+ EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,\r
+ EFI_TPL_NOTIFY,\r
+ NotifyFunction,\r
+ HcDev,\r
+ &HcDev->AsyncRequestEvent\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+DestoryPollingTimer (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destory Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ return gBS->CloseEvent (HcDev->AsyncRequestEvent);\r
+}\r
+\r
+EFI_STATUS\r
+StartPollingTimer (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Start Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ return gBS->SetTimer (\r
+ HcDev->AsyncRequestEvent,\r
+ TimerPeriodic,\r
+ EHCI_ASYNC_REQUEST_POLLING_TIME\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+StopPollingTimer (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Stop Async Request Polling Timer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ return gBS->SetTimer (\r
+ HcDev->AsyncRequestEvent,\r
+ TimerCancel,\r
+ EHCI_ASYNC_REQUEST_POLLING_TIME\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+CreateQh (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DeviceAddr,\r
+ IN UINT8 Endpoint,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaxPacketLen,\r
+ OUT EHCI_QH_ENTITY **QhPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qh Structure and Pre-Initialize\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DeviceAddr - Address of Device\r
+ Endpoint - Endpoint Number\r
+ DeviceSpeed - Device Speed\r
+ MaxPacketLen - Max Length of one Packet\r
+ QhPtrPtr - A pointer of pointer to Qh for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EHCI_QH_HW *QhHwPtr;\r
+\r
+ ASSERT (HcDev);\r
+ ASSERT (QhPtrPtr);\r
+\r
+ *QhPtrPtr = NULL;\r
+\r
+ //\r
+ // Allocate memory for Qh structure\r
+ //\r
+ Status = EhciAllocatePool (\r
+ HcDev,\r
+ (UINT8 **) QhPtrPtr,\r
+ sizeof (EHCI_QH_ENTITY)\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+ //\r
+ // Init fields in Qh\r
+ //\r
+ gBS->SetMem (*QhPtrPtr, sizeof (EHCI_QH_ENTITY), 0);\r
+\r
+ //\r
+ // Software field\r
+ //\r
+ (*QhPtrPtr)->Next = NULL;\r
+ (*QhPtrPtr)->Prev = NULL;\r
+ (*QhPtrPtr)->FirstQtdPtr = NULL;\r
+ (*QhPtrPtr)->AltQtdPtr = NULL;\r
+ (*QhPtrPtr)->LastQtdPtr = NULL;\r
+\r
+ //\r
+ // Hardware field\r
+ //\r
+ QhHwPtr = &((*QhPtrPtr)->Qh);\r
+ QhHwPtr->QhHorizontalPointer = 0;\r
+ QhHwPtr->SelectType = 0;\r
+ QhHwPtr->MaxPacketLen = (UINT32) MaxPacketLen;\r
+ QhHwPtr->EndpointSpeed = (DeviceSpeed & 0x3);\r
+ QhHwPtr->EndpointNum = (Endpoint & 0x0f);\r
+ QhHwPtr->DeviceAddr = (DeviceAddr & 0x7f);\r
+ QhHwPtr->Multiplier = HIGH_BANDWIDTH_PIPE_MULTIPLIER;\r
+ QhHwPtr->Rsvd1 = 0;\r
+ QhHwPtr->Rsvd2 = 0;\r
+ QhHwPtr->Rsvd3 = 0;\r
+ QhHwPtr->Rsvd4 = 0;\r
+ QhHwPtr->Rsvd5 = 0;\r
+ QhHwPtr->Rsvd6 = 0;\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+VOID\r
+DestoryQh (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destory Qh Structure \r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to Qh\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ ASSERT (HcDev);\r
+ ASSERT (QhPtr);\r
+\r
+ EhciFreePool (HcDev, (UINT8 *) QhPtr, sizeof (EHCI_QH_ENTITY));\r
+ return ;\r
+}\r
+\r
+EFI_STATUS\r
+CreateControlQh (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DeviceAddr,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaxPacketLen,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT EHCI_QH_ENTITY **QhPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qh for Control Transfer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DeviceAddr - Address of Device\r
+ DeviceSpeed - Device Speed\r
+ MaxPacketLen - Max Length of one Packet\r
+ Translator - Translator Transaction for SplitX\r
+ QhPtrPtr - A pointer of pointer to Qh for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Create and init Control Qh\r
+ //\r
+ Status = CreateQh (\r
+ HcDev,\r
+ DeviceAddr,\r
+ 0,\r
+ DeviceSpeed,\r
+ MaxPacketLen,\r
+ QhPtrPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+ //\r
+ // Software field\r
+ //\r
+ (*QhPtrPtr)->Next = (*QhPtrPtr);\r
+ (*QhPtrPtr)->Prev = (*QhPtrPtr);\r
+ (*QhPtrPtr)->TransferType = CONTROL_TRANSFER;\r
+\r
+ //\r
+ // Hardware field\r
+ //\r
+ // Control Transfer use DataToggleControl\r
+ //\r
+ (*QhPtrPtr)->Qh.DataToggleControl = TRUE;\r
+ (*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);\r
+ (*QhPtrPtr)->Qh.SelectType = QH_SELECT_TYPE;\r
+ (*QhPtrPtr)->Qh.QhTerminate = FALSE;\r
+ (*QhPtrPtr)->Qh.ControlEndpointFlag = TRUE;\r
+ (*QhPtrPtr)->Qh.NakCountReload = NAK_COUNT_RELOAD;\r
+ if (NULL != Translator) {\r
+ (*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;\r
+ (*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;\r
+ (*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CreateBulkQh (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DeviceAddr,\r
+ IN UINT8 EndPointAddr,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINT8 DataToggle,\r
+ IN UINTN MaxPacketLen,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT EHCI_QH_ENTITY **QhPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qh for Bulk Transfer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DeviceAddr - Address of Device\r
+ EndPointAddr - Address of Endpoint\r
+ DeviceSpeed - Device Speed\r
+ MaxPacketLen - Max Length of one Packet\r
+ Translator - Translator Transaction for SplitX\r
+ QhPtrPtr - A pointer of pointer to Qh for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Create and init Bulk Qh\r
+ //\r
+ Status = CreateQh (\r
+ HcDev,\r
+ DeviceAddr,\r
+ EndPointAddr,\r
+ DeviceSpeed,\r
+ MaxPacketLen,\r
+ QhPtrPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Software fields\r
+ //\r
+ (*QhPtrPtr)->Next = (*QhPtrPtr);\r
+ (*QhPtrPtr)->Prev = (*QhPtrPtr);\r
+ (*QhPtrPtr)->TransferType = BULK_TRANSFER;\r
+\r
+ //\r
+ // Hardware fields\r
+ //\r
+ // BulkTransfer don't use DataToggleControl\r
+ //\r
+ (*QhPtrPtr)->Qh.DataToggleControl = FALSE; \r
+ (*QhPtrPtr)->Qh.QhHorizontalPointer = (UINT32) (GET_0B_TO_31B (&((*QhPtrPtr)->Qh)) >> 5);\r
+ (*QhPtrPtr)->Qh.SelectType = QH_SELECT_TYPE;\r
+ (*QhPtrPtr)->Qh.QhTerminate = FALSE;\r
+ (*QhPtrPtr)->Qh.NakCountReload = NAK_COUNT_RELOAD;\r
+ (*QhPtrPtr)->Qh.DataToggle = DataToggle;\r
+ if (NULL != Translator) {\r
+ (*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;\r
+ (*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;\r
+ (*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CreateInterruptQh (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DeviceAddr,\r
+ IN UINT8 EndPointAddr,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINT8 DataToggle,\r
+ IN UINTN MaxPacketLen,\r
+ IN UINTN Interval,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT EHCI_QH_ENTITY **QhPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qh for Control Transfer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DeviceAddr - Address of Device\r
+ EndPointAddr - Address of Endpoint\r
+ DeviceSpeed - Device Speed\r
+ MaxPacketLen - Max Length of one Packet\r
+ Interval - value of interval\r
+ Translator - Translator Transaction for SplitX\r
+ QhPtrPtr - A pointer of pointer to Qh for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ //\r
+ // Create and init InterruptQh\r
+ //\r
+ Status = CreateQh (\r
+ HcDev,\r
+ DeviceAddr,\r
+ EndPointAddr,\r
+ DeviceSpeed,\r
+ MaxPacketLen,\r
+ QhPtrPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Software fields\r
+ //\r
+ if (Interval == 0) {\r
+ (*QhPtrPtr)->TransferType = SYNC_INTERRUPT_TRANSFER;\r
+ } else {\r
+ (*QhPtrPtr)->TransferType = ASYNC_INTERRUPT_TRANSFER;\r
+ }\r
+ (*QhPtrPtr)->Interval = GetApproxiOfInterval (Interval);\r
+\r
+ //\r
+ // Hardware fields\r
+ //\r
+ // InterruptTranfer don't use DataToggleControl\r
+ //\r
+ (*QhPtrPtr)->Qh.DataToggleControl = FALSE;\r
+ (*QhPtrPtr)->Qh.QhHorizontalPointer = 0;\r
+ (*QhPtrPtr)->Qh.QhTerminate = TRUE;\r
+ (*QhPtrPtr)->Qh.NakCountReload = 0;\r
+ (*QhPtrPtr)->Qh.InerruptScheduleMask = MICRO_FRAME_0_CHANNEL;\r
+ (*QhPtrPtr)->Qh.SplitComletionMask = (MICRO_FRAME_2_CHANNEL | MICRO_FRAME_3_CHANNEL | MICRO_FRAME_4_CHANNEL);\r
+ (*QhPtrPtr)->Qh.DataToggle = DataToggle;\r
+ if (NULL != Translator) {\r
+ (*QhPtrPtr)->Qh.PortNum = Translator->TranslatorPortNumber;\r
+ (*QhPtrPtr)->Qh.HubAddr = Translator->TranslatorHubAddress;\r
+ (*QhPtrPtr)->Qh.Status |= QTD_STATUS_DO_START_SPLIT;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CreateQtd (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 *DataPtr,\r
+ IN UINTN DataLen,\r
+ IN UINT8 PktId,\r
+ IN UINT8 Toggle,\r
+ IN UINT8 QtdStatus,\r
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtd Structure and Pre-Initialize it\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DataPtr - A pointer to user data buffer to transfer\r
+ DataLen - Length of user data to transfer\r
+ PktId - Packet Identification of this Qtd\r
+ Toggle - Data Toggle of this Qtd\r
+ QtdStatus - Default value of status of this Qtd\r
+ QtdPtrPtr - A pointer of pointer to Qtd for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EHCI_QTD_HW *QtdHwPtr;\r
+\r
+ ASSERT (HcDev);\r
+ ASSERT (QtdPtrPtr);\r
+\r
+ //\r
+ // Create memory for Qtd structure\r
+ //\r
+ Status = EhciAllocatePool (\r
+ HcDev,\r
+ (UINT8 **) QtdPtrPtr,\r
+ sizeof (EHCI_QTD_ENTITY)\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+ //\r
+ // Init fields in Qtd\r
+ //\r
+ gBS->SetMem (*QtdPtrPtr, sizeof (EHCI_QTD_ENTITY), 0);\r
+\r
+ //\r
+ // Software field\r
+ //\r
+ (*QtdPtrPtr)->TotalBytes = (UINT32) DataLen;\r
+ (*QtdPtrPtr)->StaticTotalBytes = (UINT32) DataLen;\r
+ (*QtdPtrPtr)->Prev = NULL;\r
+ (*QtdPtrPtr)->Next = NULL;\r
+\r
+ //\r
+ // Hardware field\r
+ //\r
+ QtdHwPtr = &((*QtdPtrPtr)->Qtd);\r
+ QtdHwPtr->NextQtdPointer = 0;\r
+ QtdHwPtr->NextQtdTerminate = TRUE;\r
+ QtdHwPtr->AltNextQtdPointer = 0;\r
+ QtdHwPtr->AltNextQtdTerminate = TRUE;\r
+ QtdHwPtr->DataToggle = Toggle;\r
+ QtdHwPtr->TotalBytes = (UINT32) DataLen;\r
+ QtdHwPtr->CurrentPage = 0;\r
+ QtdHwPtr->ErrorCount = QTD_ERROR_COUNTER;\r
+ QtdHwPtr->Status = QtdStatus;\r
+ QtdHwPtr->Rsvd1 = 0;\r
+ QtdHwPtr->Rsvd2 = 0;\r
+ QtdHwPtr->Rsvd3 = 0;\r
+ QtdHwPtr->Rsvd4 = 0;\r
+ QtdHwPtr->Rsvd5 = 0;\r
+ QtdHwPtr->Rsvd6 = 0;\r
+\r
+ //\r
+ // Set PacketID [Setup/Data/Status]\r
+ //\r
+ switch (PktId) {\r
+ case SETUP_PACKET_ID:\r
+ QtdHwPtr->PidCode = SETUP_PACKET_PID_CODE;\r
+ break;\r
+\r
+ case INPUT_PACKET_ID:\r
+ QtdHwPtr->PidCode = INPUT_PACKET_PID_CODE;\r
+ break;\r
+\r
+ case OUTPUT_PACKET_ID:\r
+ QtdHwPtr->PidCode = OUTPUT_PACKET_PID_CODE;\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Set Data Buffer Pointers\r
+ //\r
+ if (NULL != DataPtr) {\r
+ SetQtdBufferPointer (\r
+ QtdHwPtr,\r
+ DataPtr,\r
+ DataLen\r
+ );\r
+ (*QtdPtrPtr)->StaticCurrentOffset = QtdHwPtr->CurrentOffset;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CreateSetupQtd (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 *DevReqPtr,\r
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtd Structure for Setup \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DevReqPtr - A pointer to Device Request Data\r
+ QtdPtrPtr - A pointer of pointer to Qtd for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ return CreateQtd (\r
+ HcDev,\r
+ DevReqPtr,\r
+ sizeof (EFI_USB_DEVICE_REQUEST),\r
+ SETUP_PACKET_ID,\r
+ DATA0,\r
+ QTD_STATUS_ACTIVE,\r
+ QtdPtrPtr\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+CreateDataQtd (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 *DataPtr,\r
+ IN UINTN DataLen,\r
+ IN UINT8 PktId,\r
+ IN UINT8 Toggle,\r
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtd Structure for data \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DataPtr - A pointer to user data buffer to transfer\r
+ DataLen - Length of user data to transfer\r
+ PktId - Packet Identification of this Qtd\r
+ Toggle - Data Toggle of this Qtd\r
+ QtdPtrPtr - A pointer of pointer to Qtd for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ return CreateQtd (\r
+ HcDev,\r
+ DataPtr,\r
+ DataLen,\r
+ PktId,\r
+ Toggle,\r
+ QTD_STATUS_ACTIVE,\r
+ QtdPtrPtr\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+CreateAltQtd (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 PktId,\r
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtd Structure for Alternative \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ PktId - Packet Identification of this Qtd\r
+ QtdPtrPtr - A pointer of pointer to Qtd for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ return CreateQtd (\r
+ HcDev,\r
+ NULL,\r
+ 0,\r
+ PktId,\r
+ 0,\r
+ QTD_STATUS_ACTIVE,\r
+ QtdPtrPtr\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+CreateStatusQtd (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 PktId,\r
+ OUT EHCI_QTD_ENTITY **QtdPtrPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtd Structure for status \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ PktId - Packet Identification of this Qtd\r
+ QtdPtrPtr - A pointer of pointer to Qtd for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ return CreateQtd (\r
+ HcDev,\r
+ NULL,\r
+ 0,\r
+ PktId,\r
+ DATA1,\r
+ QTD_STATUS_ACTIVE,\r
+ QtdPtrPtr\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+CreateControlQtds (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DataPktId,\r
+ IN UINT8 *RequestCursor,\r
+ IN UINT8 *DataCursor,\r
+ IN UINTN DataLen,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT EHCI_QTD_ENTITY **ControlQtdsHead\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtds list for Control Transfer \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DataPktId - Packet Identification of Data Qtds\r
+ RequestCursor - A pointer to request structure buffer to transfer\r
+ DataCursor - A pointer to user data buffer to transfer\r
+ DataLen - Length of user data to transfer\r
+ ControlQtdsHead - A pointer of pointer to first Qtd for control tranfer for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EHCI_QTD_ENTITY *QtdPtr;\r
+ EHCI_QTD_ENTITY *PreQtdPtr;\r
+ EHCI_QTD_ENTITY *SetupQtdPtr;\r
+ EHCI_QTD_ENTITY *FirstDataQtdPtr;\r
+ EHCI_QTD_ENTITY *LastDataQtdPtr;\r
+ EHCI_QTD_ENTITY *StatusQtdPtr;\r
+ UINT8 DataToggle;\r
+ UINT8 StatusPktId;\r
+ UINTN CapacityOfQtd;\r
+ UINTN SizePerQtd;\r
+ UINTN DataCount;\r
+ UINTN Xnum;\r
+ \r
+ QtdPtr = NULL;\r
+ PreQtdPtr = NULL;\r
+ SetupQtdPtr = NULL;\r
+ FirstDataQtdPtr = NULL;\r
+ LastDataQtdPtr = NULL;\r
+ StatusQtdPtr = NULL;\r
+ CapacityOfQtd = 0;\r
+\r
+ //\r
+ // Setup Stage of Control Transfer\r
+ //\r
+ Status = CreateSetupQtd (\r
+ HcDev,\r
+ RequestCursor,\r
+ &SetupQtdPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+ \r
+ //\r
+ // Data Stage of Control Transfer\r
+ //\r
+ DataToggle = 1;\r
+ DataCount = DataLen;\r
+\r
+ //\r
+ // Create Qtd structure and link together\r
+ //\r
+ while (DataCount > 0) {\r
+ //\r
+ // PktSize is the data load size that each Qtd.\r
+ //\r
+ CapacityOfQtd = GetCapacityOfQtd (DataCursor);\r
+ SizePerQtd = DataCount;\r
+ if (DataCount > CapacityOfQtd) {\r
+ SizePerQtd = CapacityOfQtd;\r
+ }\r
+\r
+ Status = CreateDataQtd (\r
+ HcDev,\r
+ DataCursor,\r
+ SizePerQtd,\r
+ DataPktId,\r
+ DataToggle,\r
+ &QtdPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ if (NULL == FirstDataQtdPtr) {\r
+ goto destory_setup_qtd;\r
+ } else {\r
+ goto destory_qtds;\r
+ }\r
+ }\r
+\r
+ if (NULL == FirstDataQtdPtr) {\r
+ FirstDataQtdPtr = QtdPtr;\r
+ } else {\r
+ LinkQtdToQtd (PreQtdPtr, QtdPtr);\r
+ }\r
+\r
+ //\r
+ // Reverse Data Toggle or not determined by parity of transactions of one qtd\r
+ //\r
+ Xnum = Translator ? GetNumberOfTransaction (SizePerQtd, EHCI_BLOCK_SIZE_WITH_TT) : GetNumberOfTransaction (SizePerQtd, EHCI_BLOCK_SIZE);\r
+ if (Xnum % 2 != 0) {\r
+ DataToggle ^= 1;\r
+ }\r
+ \r
+ PreQtdPtr = QtdPtr;\r
+ DataCursor += SizePerQtd;\r
+ DataCount -= SizePerQtd;\r
+ }\r
+\r
+ LastDataQtdPtr = QtdPtr;\r
+\r
+ //\r
+ // Status Stage of Control Transfer\r
+ //\r
+ if (OUTPUT_PACKET_ID == DataPktId) {\r
+ StatusPktId = INPUT_PACKET_ID;\r
+ } else {\r
+ StatusPktId = OUTPUT_PACKET_ID;\r
+ }\r
+\r
+ Status = CreateStatusQtd (\r
+ HcDev,\r
+ StatusPktId,\r
+ &StatusQtdPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto destory_qtds;\r
+ }\r
+ \r
+ //\r
+ // Link setup Qtd -> data Qtds -> status Qtd\r
+ //\r
+ if (FirstDataQtdPtr != NULL) {\r
+ LinkQtdToQtd (SetupQtdPtr, FirstDataQtdPtr);\r
+ LinkQtdToQtd (LastDataQtdPtr, StatusQtdPtr);\r
+ } else {\r
+ LinkQtdToQtd (SetupQtdPtr, StatusQtdPtr);\r
+ }\r
+\r
+ *ControlQtdsHead = SetupQtdPtr;\r
+\r
+ goto exit;\r
+\r
+destory_qtds:\r
+ DestoryQtds (HcDev, FirstDataQtdPtr);\r
+destory_setup_qtd:\r
+ DestoryQtds (HcDev, SetupQtdPtr);\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+CreateBulkOrInterruptQtds (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 PktId,\r
+ IN UINT8 *DataCursor,\r
+ IN UINTN DataLen,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT EHCI_QTD_ENTITY **QtdsHead\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create Qtds list for Bulk or Interrupt Transfer \r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ PktId - Packet Identification of Qtds\r
+ DataCursor - A pointer to user data buffer to transfer\r
+ DataLen - Length of user data to transfer\r
+ DataToggle - Data Toggle to start\r
+ Translator - Translator Transaction for SplitX\r
+ QtdsHead - A pointer of pointer to first Qtd for control tranfer for return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EHCI_QTD_ENTITY *QtdPtr;\r
+ EHCI_QTD_ENTITY *PreQtdPtr;\r
+ EHCI_QTD_ENTITY *FirstQtdPtr;\r
+ EHCI_QTD_ENTITY *AltQtdPtr;\r
+ UINTN DataCount;\r
+ UINTN CapacityOfQtd;\r
+ UINTN SizePerQtd;\r
+\r
+ Status = EFI_SUCCESS;\r
+ QtdPtr = NULL;\r
+ PreQtdPtr = NULL;\r
+ FirstQtdPtr = NULL;\r
+ AltQtdPtr = NULL;\r
+ CapacityOfQtd = 0;\r
+\r
+ DataCount = DataLen;\r
+ while (DataCount > 0) {\r
+\r
+ CapacityOfQtd = GetCapacityOfQtd (DataCursor);\r
+ SizePerQtd = DataCount;\r
+ if (DataCount > CapacityOfQtd) {\r
+ SizePerQtd = CapacityOfQtd;\r
+ }\r
+\r
+ Status = CreateDataQtd (\r
+ HcDev,\r
+ DataCursor,\r
+ SizePerQtd,\r
+ PktId,\r
+ 0,\r
+ &QtdPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ if (NULL == FirstQtdPtr) {\r
+ goto exit;\r
+ } else {\r
+ goto destory_qtds;\r
+ }\r
+ }\r
+\r
+ if (NULL == FirstQtdPtr) {\r
+ FirstQtdPtr = QtdPtr;\r
+ } else {\r
+ LinkQtdToQtd (PreQtdPtr, QtdPtr);\r
+ }\r
+\r
+ PreQtdPtr = QtdPtr;\r
+ DataCursor += SizePerQtd;\r
+ DataCount -= SizePerQtd;\r
+ }\r
+ \r
+ //\r
+ // Set Alternate Qtd\r
+ //\r
+ if (INPUT_PACKET_ID == PktId && 1 < GetNumberOfQtd (FirstQtdPtr)) {\r
+ Status = CreateAltQtd (\r
+ HcDev,\r
+ PktId,\r
+ &AltQtdPtr\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto destory_qtds;\r
+ }\r
+\r
+ LinkQtdsToAltQtd (FirstQtdPtr, AltQtdPtr);\r
+ }\r
+\r
+ *QtdsHead = FirstQtdPtr;\r
+ goto exit;\r
+\r
+destory_qtds:\r
+ DestoryQtds (HcDev, FirstQtdPtr);\r
+exit:\r
+ return Status;\r
+}\r
+\r
+VOID\r
+DestoryQtds (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QTD_ENTITY *FirstQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Destory all Qtds in the list\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ FirstQtdPtr - A pointer to first Qtd in the list \r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ EHCI_QTD_ENTITY *PrevQtd;\r
+ EHCI_QTD_ENTITY *NextQtd;\r
+\r
+ if (!FirstQtdPtr) {\r
+ goto exit;\r
+ }\r
+\r
+ PrevQtd = FirstQtdPtr;\r
+\r
+ //\r
+ // Delete all the Qtds.\r
+ //\r
+ do {\r
+ NextQtd = PrevQtd->Next;\r
+ EhciFreePool (HcDev, (UINT8 *) PrevQtd, sizeof (EHCI_QTD_ENTITY));\r
+ PrevQtd = NextQtd;\r
+ } while (NULL != PrevQtd);\r
+\r
+exit:\r
+ return ;\r
+}\r
+\r
+UINTN\r
+GetNumberOfQtd (\r
+ IN EHCI_QTD_ENTITY *FirstQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Number of Qtds in the list\r
+ \r
+Arguments:\r
+\r
+ FirstQtdPtr - A pointer to first Qtd in the list\r
+ \r
+Returns:\r
+\r
+ Number of Qtds in the list\r
+\r
+--*/\r
+{\r
+ UINTN Count;\r
+ EHCI_QTD_ENTITY *QtdPtr;\r
+ Count = 0;\r
+ QtdPtr = FirstQtdPtr;\r
+\r
+ ;\r
+\r
+ while (NULL != QtdPtr) {\r
+ Count++;\r
+ QtdPtr = QtdPtr->Next;\r
+ }\r
+\r
+ return Count;\r
+}\r
+\r
+UINTN\r
+GetNumberOfTransaction (\r
+ IN UINTN SizeOfData,\r
+ IN UINTN SizeOfTransaction\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Number of Transactions in one Qtd\r
+ \r
+Arguments:\r
+\r
+ SizeOfData - Size of one Qtd\r
+ SizeOfTransaction - Size of one Transaction\r
+ \r
+Returns:\r
+\r
+ Number of Transactions in this Qtd\r
+\r
+--*/\r
+{\r
+\r
+ return ((SizeOfData & (SizeOfTransaction - 1)) ? SizeOfData / SizeOfTransaction + 1 : SizeOfData / SizeOfTransaction);\r
+\r
+}\r
+\r
+UINTN\r
+GetCapacityOfQtd (\r
+ IN UINT8 *BufferCursor\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get Size of First Qtd\r
+ \r
+Arguments:\r
+\r
+ BufferCursor - BufferCursor of the Qtd\r
+ \r
+Returns:\r
+\r
+ Size of First Qtd\r
+\r
+--*/\r
+{\r
+\r
+ return (EHCI_MAX_QTD_CAPACITY - (EHCI_BLOCK_SIZE * GetNumberOfTransaction (EFI_PAGE_MASK & GET_0B_TO_31B (BufferCursor), EHCI_BLOCK_SIZE)));\r
+\r
+}\r
+\r
+UINTN\r
+GetApproxiOfInterval (\r
+ IN UINTN Interval\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the approximate value in the 2 index sequence\r
+ \r
+Arguments:\r
+\r
+ Interval - the value of interval\r
+ \r
+Returns:\r
+\r
+ approximate value of interval in the 2 index sequence\r
+ \r
+--*/\r
+{\r
+ UINTN Orignate;\r
+ UINTN Approxi;\r
+\r
+ Orignate = Interval;\r
+ Approxi = 1;\r
+\r
+ while (Orignate != 1 && Orignate != 0) {\r
+ Orignate = Orignate >> 1;\r
+ Approxi = Approxi << 1;\r
+ }\r
+\r
+ if (Interval & (Approxi >> 1)) {\r
+ Approxi = Approxi << 1;\r
+ }\r
+\r
+ return Approxi;\r
+}\r
+\r
+EHCI_QTD_HW *\r
+GetQtdAlternateNextPointer (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get Qtd alternate next pointer field\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ A pointer to hardware alternate Qtd\r
+ \r
+--*/\r
+{\r
+ EHCI_QTD_HW *Value;\r
+\r
+ Value = NULL;\r
+\r
+ if (!HwQtdPtr->AltNextQtdTerminate) {\r
+ Value = (EHCI_QTD_HW *) GET_0B_TO_31B (HwQtdPtr->AltNextQtdPointer << 5);\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+EHCI_QTD_HW *\r
+GetQtdNextPointer (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get Qtd next pointer field\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ A pointer to next hardware Qtd structure\r
+ \r
+--*/\r
+{\r
+ EHCI_QTD_HW *Value;\r
+\r
+ Value = NULL;\r
+\r
+ if (!HwQtdPtr->NextQtdTerminate) {\r
+ Value = (EHCI_QTD_HW *) GET_0B_TO_31B (HwQtdPtr->NextQtdPointer << 5);\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+VOID LinkQtdToQtd (\r
+ IN EHCI_QTD_ENTITY * PreQtdPtr, \r
+ IN EHCI_QTD_ENTITY * QtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link Qtds together\r
+ \r
+Arguments:\r
+\r
+ PreQtdPtr - A pointer to pre Qtd\r
+ QtdPtr - A pointer to next Qtd\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ EHCI_QTD_HW *QtdHwPtr;\r
+\r
+ ASSERT(PreQtdPtr);\r
+ ASSERT(QtdPtr);\r
+\r
+ //\r
+ // Software link\r
+ //\r
+ PreQtdPtr->Next = QtdPtr;\r
+ QtdPtr->Prev = PreQtdPtr;\r
+\r
+ //\r
+ // Hardware link\r
+ //\r
+ QtdHwPtr = &(QtdPtr->Qtd);\r
+ PreQtdPtr->Qtd.NextQtdPointer = (UINT32) (GET_0B_TO_31B(QtdHwPtr) >> 5);\r
+ PreQtdPtr->Qtd.NextQtdTerminate = FALSE;\r
+\r
+ return ;\r
+}\r
+\r\r
+\r
+VOID LinkQtdsToAltQtd (\r
+ IN EHCI_QTD_ENTITY * FirstQtdPtr, \r
+ IN EHCI_QTD_ENTITY * AltQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link AlterQtds together\r
+ \r
+Arguments:\r
+\r
+ FirstQtdPtr - A pointer to first Qtd in the list\r
+ AltQtdPtr - A pointer to alternative Qtd\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ EHCI_QTD_ENTITY *QtdPtr;\r
+ EHCI_QTD_HW *AltQtdHwPtr;\r
+\r
+ ASSERT(FirstQtdPtr);\r
+ ASSERT(AltQtdPtr);\r
+\r
+ AltQtdHwPtr = &(AltQtdPtr->Qtd);\r
+ QtdPtr = FirstQtdPtr;\r
+ \r
+ while (NULL != QtdPtr) {\r
+ //\r
+ // Software link\r
+ //\r
+ QtdPtr->AltNext = AltQtdPtr;\r
+ //\r
+ // Hardware link\r
+ //\r
+ QtdPtr->Qtd.AltNextQtdPointer = (UINT32) (GET_0B_TO_31B(AltQtdHwPtr) >> 5);\r
+ QtdPtr->Qtd.AltNextQtdTerminate = FALSE;\r
+ QtdPtr = QtdPtr->Next;\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+VOID\r
+LinkQtdToQh (\r
+ IN EHCI_QH_ENTITY *QhPtr,\r
+ IN EHCI_QTD_ENTITY *QtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link Qtds list to Qh\r
+ \r
+Arguments:\r
+\r
+ QhPtr - A pointer to Qh\r
+ QtdPtr - A pointer to first Qtd in the list\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ EHCI_QTD_ENTITY *Cursor;\r
+ EHCI_QTD_HW *QtdHwPtr;\r
+\r
+ ASSERT (QhPtr);\r
+ ASSERT (QtdPtr);\r
+\r
+ QhPtr->FirstQtdPtr = QtdPtr;\r
+ if (NULL != QtdPtr->AltNext) {\r
+ QhPtr->AltQtdPtr = QtdPtr->AltNext;\r
+ }\r
+\r
+ Cursor = QtdPtr;\r
+ while (NULL != Cursor) {\r
+ Cursor->SelfQh = QhPtr;\r
+ if (NULL == Cursor->Next) {\r
+ QhPtr->LastQtdPtr = Cursor;\r
+ }\r
+\r
+ Cursor = Cursor->Next;\r
+ }\r
+\r
+ QtdHwPtr = &(QtdPtr->Qtd);\r
+ QhPtr->Qh.NextQtdPointer = (UINT32) (GET_0B_TO_31B (QtdHwPtr) >> 5);\r
+ QhPtr->Qh.NextQtdTerminate = FALSE;\r
+\r
+ return ;\r
+}\r
+\r
+EFI_STATUS\r
+LinkQhToAsyncList (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link Qh to Async Schedule List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to Qh\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ ASSERT (HcDev);\r
+ ASSERT (QhPtr);\r
+\r
+ QhPtr->Qh.HeadReclamationFlag = TRUE;\r
+\r
+ Status = SetAsyncListAddr (HcDev, QhPtr);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ if (!IsAsyncScheduleEnabled (HcDev)) {\r
+\r
+ Status = EnableAsynchronousSchedule (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = WaitForAsyncScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((gEHCDebugLevel, "WaitForAsyncScheduleEnable TimeOut"));\r
+ Status = EFI_TIMEOUT;\r
+ goto exit;\r
+ }\r
+\r
+ if (IsEhcHalted (HcDev)) {\r
+ Status = StartScheduleExecution (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+UnlinkQhFromAsyncList (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Unlink Qh from Async Schedule List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to Qh\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ ASSERT (HcDev);\r
+ ASSERT (QhPtr);\r
+\r
+ if (QhPtr == QhPtr->Next) {\r
+\r
+ Status = DisableAsynchronousSchedule (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = WaitForAsyncScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((gEHCErrorLevel, "WaitForAsyncScheduleDisable TimeOut\n"));\r
+ Status = EFI_TIMEOUT;\r
+ goto exit;\r
+ }\r
+\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+VOID\r
+LinkQhToPeriodicList (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link Qh to Periodic Schedule List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to Qh\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+{\r
+ FRAME_LIST_ENTRY *FrameEntryPtr;\r
+ EHCI_QH_ENTITY *FindQhPtr;\r
+ EHCI_QH_HW *FindQhHwPtr;\r
+ UINTN FrameIndex;\r
+\r
+ ASSERT (HcDev);\r
+ ASSERT (QhPtr);\r
+\r
+ FindQhPtr = NULL;\r
+ FindQhHwPtr = NULL;\r
+ FrameIndex = 0;\r
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;\r
+\r
+ QhPtr->Qh.HeadReclamationFlag = FALSE;\r
+\r
+ if (QhPtr->TransferType == ASYNC_INTERRUPT_TRANSFER) {\r
+ \r
+ //\r
+ // AsyncInterruptTransfer Qh\r
+ //\r
+ \r
+ //\r
+ // Link to Frame[0] List\r
+ //\r
+ if (!FrameEntryPtr->LinkTerminate) {\r
+ //\r
+ // Not Null FrameList\r
+ //\r
+ FindQhHwPtr = (EHCI_QH_HW *) GET_0B_TO_31B (FrameEntryPtr->LinkPointer << 5);\r
+ FindQhPtr = (EHCI_QH_ENTITY *) GET_QH_ENTITY_ADDR (FindQhHwPtr);\r
+ //\r
+ // FindQh is Left/Right to Qh\r
+ //\r
+ while ((NULL != FindQhPtr->Next) && (FindQhPtr->Interval > QhPtr->Interval)) {\r
+ FindQhPtr = FindQhPtr->Next;\r
+ }\r
+\r
+ if (FindQhPtr->Interval == QhPtr->Interval) {\r
+ //\r
+ // Link Qh after FindQh\r
+ //\r
+ if (NULL != FindQhPtr->Next) {\r
+ FindQhPtr->Next->Prev = QhPtr;\r
+ QhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(FindQhPtr->Next->Qh) >> 5);\r
+ QhPtr->Qh.SelectType = QH_SELECT_TYPE;\r
+ QhPtr->Qh.QhTerminate = FALSE;\r
+ }\r
+\r
+ FindQhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+ FindQhPtr->Qh.SelectType = QH_SELECT_TYPE;\r
+ FindQhPtr->Qh.QhTerminate = FALSE;\r
+\r
+ QhPtr->Prev = FindQhPtr;\r
+ QhPtr->Next = FindQhPtr->Next;\r
+ FindQhPtr->Next = QhPtr;\r
+ } else if (FindQhPtr->Interval < QhPtr->Interval) {\r
+ //\r
+ // Link Qh before FindQh\r
+ //\r
+ if (NULL == FindQhPtr->Prev) {\r
+ //\r
+ // Qh is the First one in Frame[0] List\r
+ //\r
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;\r
+ FrameEntryPtr->LinkTerminate = FALSE;\r
+ } else {\r
+ //\r
+ // Qh is not the First one in Frame[0] List\r
+ //\r
+ FindQhPtr->Prev->Next = QhPtr;\r
+ FindQhPtr->Prev->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+ FindQhPtr->Prev->Qh.SelectType = QH_SELECT_TYPE;\r
+ FindQhPtr->Prev->Qh.QhTerminate = FALSE;\r
+ }\r
+\r
+ QhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(FindQhPtr->Qh) >> 5);\r
+ QhPtr->Qh.SelectType = QH_SELECT_TYPE;\r
+ QhPtr->Qh.QhTerminate = FALSE;\r
+\r
+ QhPtr->Next = FindQhPtr;\r
+ QhPtr->Prev = FindQhPtr->Prev;\r
+ FindQhPtr->Prev = QhPtr;\r
+ } else {\r
+ //\r
+ // Link Qh after FindQh, Qh is the Last one\r
+ //\r
+ FindQhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+ FindQhPtr->Prev->Qh.SelectType = QH_SELECT_TYPE;\r
+ FindQhPtr->Qh.QhTerminate = FALSE;\r
+\r
+ QhPtr->Prev = FindQhPtr;\r
+ QhPtr->Next = NULL;\r
+ FindQhPtr->Next = QhPtr;\r
+ }\r
+ } else {\r
+ //\r
+ // Null FrameList\r
+ //\r
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;\r
+ FrameEntryPtr->LinkTerminate = FALSE;\r
+ }\r
+ //\r
+ // Other Frame[X]\r
+ //\r
+ if (NULL == QhPtr->Prev) {\r
+ //\r
+ // Qh is the First one in Frame[0] List\r
+ //\r
+ FrameIndex += QhPtr->Interval;\r
+ while (FrameIndex < HcDev->PeriodicFrameListLength) {\r
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) (FrameEntryPtr + QhPtr->Interval);\r
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;\r
+ FrameEntryPtr->LinkTerminate = FALSE;\r
+ FrameIndex += QhPtr->Interval;\r
+ }\r
+ } else if (QhPtr->Interval < QhPtr->Prev->Interval) {\r
+ //\r
+ // Qh is not the First one in Frame[0] List, and Prev.interval > Qh.interval\r
+ //\r
+ FrameIndex += QhPtr->Interval;\r
+ while (FrameIndex < HcDev->PeriodicFrameListLength) {\r
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) (FrameEntryPtr + QhPtr->Interval);\r
+ if ((FrameIndex % QhPtr->Prev->Interval) != 0) {\r
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;\r
+ FrameEntryPtr->LinkTerminate = FALSE;\r
+ }\r
+\r
+ FrameIndex += QhPtr->Interval;\r
+ }\r
+ }\r
+ } else {\r
+ \r
+ //\r
+ // SyncInterruptTransfer Qh\r
+ //\r
+ \r
+ if (!FrameEntryPtr->LinkTerminate) {\r
+ //\r
+ // Not Null FrameList\r
+ //\r
+ FindQhHwPtr = (EHCI_QH_HW *) GET_0B_TO_31B (FrameEntryPtr->LinkPointer << 5);\r
+ FindQhPtr = (EHCI_QH_ENTITY *) GET_QH_ENTITY_ADDR (FindQhHwPtr);\r
+ //\r
+ // FindQh is Last Qh in the Asynchronous List, Link Qh after FindQh\r
+ //\r
+ while (NULL != FindQhPtr->Next) {\r
+ FindQhPtr = FindQhPtr->Next;\r
+ }\r
+\r
+ FindQhPtr->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+ FindQhPtr->Qh.SelectType = QH_SELECT_TYPE;\r
+ FindQhPtr->Qh.QhTerminate = FALSE;\r
+\r
+ FindQhPtr->Next = QhPtr;\r
+ QhPtr->Prev = FindQhPtr;\r
+ } else {\r
+ //\r
+ // Null FrameList\r
+ //\r
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh) >> 5);\r
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;\r
+ FrameEntryPtr->LinkTerminate = FALSE;\r
+ }\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+VOID\r
+UnlinkQhFromPeriodicList (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_QH_ENTITY *QhPtr,\r
+ IN UINTN Interval\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Unlink Qh from Periodic Schedule List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ QhPtr - A pointer to Qh\r
+ Interval - Interval of this periodic transfer\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+{\r
+ FRAME_LIST_ENTRY *FrameEntryPtr;\r
+ UINTN FrameIndex;\r
+\r
+ FrameIndex = 0;\r
+\r
+ ASSERT (HcDev);\r
+ ASSERT (QhPtr);\r
+\r
+ FrameIndex = 0;\r
+ FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;\r
+\r
+ if (QhPtr->TransferType == ASYNC_INTERRUPT_TRANSFER) {\r
+ \r
+ //\r
+ // AsyncInterruptTransfer Qh\r
+ //\r
+ \r
+ if (NULL == QhPtr->Prev) {\r
+ //\r
+ // Qh is the First one on Frame[0] List\r
+ //\r
+ if (NULL == QhPtr->Next) {\r
+ //\r
+ // Only one on Frame[0] List\r
+ //\r
+ while (FrameIndex < HcDev->PeriodicFrameListLength) {\r
+ FrameEntryPtr->LinkPointer = 0;\r
+ FrameEntryPtr->SelectType = 0;\r
+ FrameEntryPtr->LinkTerminate = TRUE;\r
+ FrameEntryPtr += Interval;\r
+ FrameIndex += Interval;\r
+ }\r
+ } else {\r
+ while (FrameIndex < HcDev->PeriodicFrameListLength) {\r
+ FrameEntryPtr->LinkPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Next->Qh) >> 5);\r
+ FrameEntryPtr->SelectType = QH_SELECT_TYPE;\r
+ FrameEntryPtr->LinkTerminate = FALSE;\r
+ FrameEntryPtr += Interval;\r
+ FrameIndex += Interval;\r
+ }\r
+ }\r
+ } else {\r
+ \r
+ //\r
+ // Not First one on Frame[0] List\r
+ //\r
+ if (NULL == QhPtr->Next) {\r
+ //\r
+ // Qh is the Last one on Frame[0] List\r
+ //\r
+ QhPtr->Prev->Qh.QhHorizontalPointer = 0;\r
+ QhPtr->Prev->Qh.SelectType = 0;\r
+ QhPtr->Prev->Qh.QhTerminate = TRUE;\r
+ } else {\r
+ QhPtr->Prev->Qh.QhHorizontalPointer = (UINT32) GET_0B_TO_31B (&(QhPtr->Next->Qh) >> 5);\r
+ QhPtr->Prev->Qh.SelectType = QH_SELECT_TYPE;\r
+ QhPtr->Prev->Qh.QhTerminate = FALSE;\r
+ }\r
+\r
+ if (Interval == QhPtr->Prev->Interval) {\r
+ //\r
+ // Interval is the same as Prev\r
+ // Not involed Frame[X]\r
+ //\r
+ } else {\r
+ //\r
+ // Other Frame[X]\r
+ //\r
+ while (FrameIndex < HcDev->PeriodicFrameListLength) {\r
+ if ((FrameIndex % QhPtr->Prev->Interval) != 0) {\r
+ FrameEntryPtr->LinkPointer = QhPtr->Prev->Qh.QhHorizontalPointer;\r
+ FrameEntryPtr->SelectType = QhPtr->Prev->Qh.SelectType;\r
+ FrameEntryPtr->LinkTerminate = QhPtr->Prev->Qh.QhTerminate;\r
+ }\r
+ FrameEntryPtr += Interval;\r
+ FrameIndex += Interval;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (NULL != QhPtr->Next) {\r
+ QhPtr->Next->Prev = QhPtr->Prev;\r
+ }\r
+\r
+ if (NULL != QhPtr->Prev) {\r
+ QhPtr->Prev->Next = QhPtr->Next;\r
+ }\r
+ } else {\r
+ //\r
+ // SyncInterruptTransfer Qh\r
+ //\r
+ if (NULL == QhPtr->Prev) {\r
+ //\r
+ // Qh is the only one Qh on Frame[0] List\r
+ //\r
+ FrameEntryPtr->LinkPointer = 0;\r
+ FrameEntryPtr->SelectType = 0;\r
+ FrameEntryPtr->LinkTerminate = TRUE;\r
+ } else {\r
+ QhPtr->Prev->Qh.QhHorizontalPointer = 0;\r
+ QhPtr->Prev->Qh.SelectType = 0;\r
+ QhPtr->Prev->Qh.QhTerminate = TRUE;\r
+ }\r
+\r
+ if (NULL != QhPtr->Prev) {\r
+ QhPtr->Prev->Next = NULL;\r
+ }\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+VOID\r
+LinkToAsyncReqeust (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Llink AsyncRequest Entry to Async Request List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ AsyncRequestPtr - A pointer to Async Request Entry\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+{\r
+ EHCI_ASYNC_REQUEST *CurrentPtr;\r
+\r
+ CurrentPtr = HcDev->AsyncRequestList;\r
+ HcDev->AsyncRequestList = AsyncRequestPtr;\r
+ AsyncRequestPtr->Prev = NULL;\r
+ AsyncRequestPtr->Next = CurrentPtr;\r
+\r
+ if (NULL != CurrentPtr) {\r
+ CurrentPtr->Prev = AsyncRequestPtr;\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+VOID\r
+UnlinkFromAsyncReqeust (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Unlink AsyncRequest Entry from Async Request List\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ AsyncRequestPtr - A pointer to Async Request Entry\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+{\r
+ if (NULL == AsyncRequestPtr->Prev) {\r
+ HcDev->AsyncRequestList = AsyncRequestPtr->Next;\r
+ if (NULL != AsyncRequestPtr->Next) {\r
+ AsyncRequestPtr->Next->Prev = NULL;\r
+ }\r
+ } else {\r
+ AsyncRequestPtr->Prev->Next = AsyncRequestPtr->Next;\r
+ if (NULL != AsyncRequestPtr->Next) {\r
+ AsyncRequestPtr->Next->Prev = AsyncRequestPtr->Prev;\r
+ }\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+VOID\r
+SetQtdBufferPointer (\r
+ IN EHCI_QTD_HW *QtdHwPtr,\r
+ IN VOID *DataPtr,\r
+ IN UINTN DataLen\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set data buffer pointers in Qtd\r
+\r
+Arguments:\r
+\r
+ QtdHwPtr - A pointer to Qtd hardware structure \r
+ DataPtr - A pointer to user data buffer\r
+ DataLen - Length of the user data buffer\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+{\r
+ UINTN RemainLen;\r
+\r
+ RemainLen = DataLen;\r
+ ASSERT (QtdHwPtr);\r
+\r
+ //\r
+ // Set BufferPointer0, ExtBufferPointer0 and Offset\r
+ //\r
+ QtdHwPtr->BufferPointer0 = (UINT32) (GET_0B_TO_31B (DataPtr) >> 12);\r
+ QtdHwPtr->CurrentOffset = (UINT32) (GET_0B_TO_31B (DataPtr) & EFI_PAGE_MASK);\r
+ QtdHwPtr->ExtBufferPointer0 = (UINT32) GET_32B_TO_63B (DataPtr);\r
+\r
+ //\r
+ // Set BufferPointer1 and ExtBufferPointer1\r
+ //\r
+ RemainLen = RemainLen > (EFI_PAGE_SIZE - QtdHwPtr->CurrentOffset) ? (RemainLen - (EFI_PAGE_SIZE - QtdHwPtr->CurrentOffset)) : 0;\r
+ if (RemainLen == 0) {\r
+ goto exit;\r
+ }\r
+\r
+ QtdHwPtr->BufferPointer1 = QtdHwPtr->BufferPointer0 + 1;\r
+ QtdHwPtr->ExtBufferPointer1 = QtdHwPtr->ExtBufferPointer0;\r
+\r
+ //\r
+ // Set BufferPointer2 and ExtBufferPointer2\r
+ //\r
+ RemainLen = RemainLen > EFI_PAGE_SIZE ? (RemainLen - EFI_PAGE_SIZE) : 0;\r
+ if (RemainLen == 0) {\r
+ goto exit;\r
+ }\r
+\r
+ QtdHwPtr->BufferPointer2 = QtdHwPtr->BufferPointer1 + 1;\r
+ QtdHwPtr->ExtBufferPointer2 = QtdHwPtr->ExtBufferPointer0;\r
+\r
+ //\r
+ // Set BufferPointer3 and ExtBufferPointer3\r
+ //\r
+ RemainLen = RemainLen > EFI_PAGE_SIZE ? (RemainLen - EFI_PAGE_SIZE) : 0;\r
+ if (RemainLen == 0) {\r
+ goto exit;\r
+ }\r
+\r
+ QtdHwPtr->BufferPointer3 = QtdHwPtr->BufferPointer2 + 1;\r
+ QtdHwPtr->ExtBufferPointer3 = QtdHwPtr->ExtBufferPointer0;\r
+\r
+ //\r
+ // Set BufferPointer4 and ExtBufferPointer4\r
+ //\r
+ RemainLen = RemainLen > EFI_PAGE_SIZE ? (RemainLen - EFI_PAGE_SIZE) : 0;\r
+ if (RemainLen == 0) {\r
+ goto exit;\r
+ }\r
+\r
+ QtdHwPtr->BufferPointer4 = QtdHwPtr->BufferPointer3 + 1;\r
+ QtdHwPtr->ExtBufferPointer4 = QtdHwPtr->ExtBufferPointer0;\r
+\r
+exit:\r
+ return ;\r
+}\r
+\r
+BOOLEAN\r
+IsQtdStatusActive (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Qtd status is active or not\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ TRUE Active\r
+ FALSE Inactive\r
+ \r
+--*/\r
+{\r
+ UINT8 QtdStatus;\r
+ BOOLEAN Value;\r
+\r
+ QtdStatus = (UINT8) (HwQtdPtr->Status);\r
+ Value = (BOOLEAN) (QtdStatus & QTD_STATUS_ACTIVE);\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsQtdStatusHalted (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Qtd status is halted or not\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ TRUE Halted\r
+ FALSE Not halted\r
+ \r
+--*/\r
+{\r
+ UINT8 QtdStatus;\r
+ BOOLEAN Value;\r
+\r
+ QtdStatus = (UINT8) (HwQtdPtr->Status);\r
+ Value = (BOOLEAN) (QtdStatus & QTD_STATUS_HALTED);\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsQtdStatusBufferError (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Qtd status is buffer error or not\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ TRUE Buffer error\r
+ FALSE No buffer error\r
+ \r
+--*/\r
+{\r
+ UINT8 QtdStatus;\r
+ BOOLEAN Value;\r
+\r
+ QtdStatus = (UINT8) (HwQtdPtr->Status);\r
+ Value = (BOOLEAN) (QtdStatus & QTD_STATUS_BUFFER_ERR);\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsQtdStatusBabbleError (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Qtd status is babble error or not\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ TRUE Babble error\r
+ FALSE No babble error\r
+ \r
+--*/\r
+{\r
+ UINT8 QtdStatus;\r
+ BOOLEAN Value;\r
+\r
+ QtdStatus = (UINT8) (HwQtdPtr->Status);\r
+ Value = (BOOLEAN) (QtdStatus & QTD_STATUS_BABBLE_ERR);\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsQtdStatusTransactionError (\r
+ IN EHCI_QTD_HW *HwQtdPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether Qtd status is transaction error or not\r
+ \r
+Arguments:\r
+\r
+ HwQtdPtr - A pointer to hardware Qtd structure\r
+ \r
+Returns:\r
+\r
+ TRUE Transaction error\r
+ FALSE No transaction error\r
+ \r
+--*/\r
+{\r
+ UINT8 QtdStatus;\r
+ BOOLEAN Value;\r
+\r
+ QtdStatus = (UINT8) (HwQtdPtr->Status);\r
+ Value = (BOOLEAN) (QtdStatus & QTD_STATUS_TRANSACTION_ERR);\r
+\r
+ return Value;\r
+}\r
+\r
+BOOLEAN\r
+IsDataInTransfer (\r
+ IN UINT8 EndPointAddress\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Whether is a DataIn direction transfer\r
+ \r
+Arguments:\r
+\r
+ EndPointAddress - address of the endpoint \r
+ \r
+Returns:\r
+\r
+ TRUE DataIn\r
+ FALSE DataOut\r
+ \r
+--*/\r
+{\r
+ BOOLEAN Value;\r
+\r
+ if (EndPointAddress & 0x80) {\r
+ Value = TRUE;\r
+ } else {\r
+ Value = FALSE;\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+EFI_STATUS\r
+MapDataBuffer (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN EFI_USB_DATA_DIRECTION TransferDirection,\r
+ IN VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ OUT UINT8 *PktId,\r
+ OUT UINT8 **DataCursor,\r
+ OUT VOID **DataMap\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Map address of user data buffer\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ TransferDirection - direction of transfer\r
+ Data - A pointer to user data buffer \r
+ DataLength - length of user data\r
+ PktId - Packte Identificaion\r
+ DataCursor - mapped address to return\r
+ DataMap - identificaion of this mapping to return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_PHYSICAL_ADDRESS TempPhysicalAddr;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ switch (TransferDirection) {\r
+\r
+ case EfiUsbDataIn:\r
+\r
+ *PktId = INPUT_PACKET_ID;\r
+ //\r
+ // BusMasterWrite means cpu read\r
+ //\r
+ Status = HcDev->PciIo->Map (\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterWrite,\r
+ Data,\r
+ DataLength,\r
+ &TempPhysicalAddr,\r
+ DataMap\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((gEHCDebugLevel, "MapDataBuffer Failed\n"));\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ *DataCursor = (UINT8 *) ((UINTN) TempPhysicalAddr);\r
+ break;\r
+\r
+ case EfiUsbDataOut:\r
+\r
+ *PktId = OUTPUT_PACKET_ID;\r
+ //\r
+ // BusMasterRead means cpu write\r
+ //\r
+ Status = HcDev->PciIo->Map (\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterRead,\r
+ Data,\r
+ DataLength,\r
+ &TempPhysicalAddr,\r
+ DataMap\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ *DataCursor = (UINT8 *) ((UINTN) TempPhysicalAddr);\r
+ break;\r
+\r
+ case EfiUsbNoData:\r
+\r
+ *PktId = OUTPUT_PACKET_ID;\r
+ Data = NULL;\r
+ *DataLength = 0;\r
+ *DataCursor = NULL;\r
+ *DataMap = NULL;\r
+ break;\r
+\r
+ default:\r
+ \r
+ Status = EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+MapRequestBuffer (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN OUT VOID *Request,\r
+ OUT UINT8 **RequestCursor,\r
+ OUT VOID **RequestMap\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Map address of request structure buffer\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ Request - A pointer to request structure\r
+ RequestCursor - Mapped address of request structure to return\r
+ RequestMap - Identificaion of this mapping to return\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN RequestLen;\r
+ EFI_PHYSICAL_ADDRESS TempPhysicalAddr;\r
+\r
+ RequestLen = sizeof (EFI_USB_DEVICE_REQUEST);\r
+ Status = HcDev->PciIo->Map (\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterRead,\r
+ (UINT8 *) Request,\r
+ (UINTN *) &RequestLen,\r
+ &TempPhysicalAddr,\r
+ RequestMap\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ *RequestCursor = (UINT8 *) ((UINTN) TempPhysicalAddr);\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+DeleteAsyncRequestTransfer (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ OUT UINT8 *DataToggle\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Delete all asynchronous request transfer\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ DeviceAddress - address of usb device\r
+ EndPointAddress - address of endpoint\r
+ DataToggle - stored data toggle\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EHCI_ASYNC_REQUEST *AsyncRequestPtr;\r
+ EHCI_ASYNC_REQUEST *MatchPtr;\r
+ EHCI_QH_HW *QhHwPtr;\r
+ UINT8 EndPointNum;\r
+\r
+ if (NULL == HcDev->AsyncRequestList) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ MatchPtr = NULL;\r
+ QhHwPtr = NULL;\r
+ EndPointNum = EndPointAddress & 0x0f;\r
+ AsyncRequestPtr = HcDev->AsyncRequestList;\r
+\r
+ //\r
+ // Find QH of AsyncRequest by DeviceAddress and EndPointNum\r
+ //\r
+ do {\r
+\r
+ QhHwPtr = &(AsyncRequestPtr->QhPtr->Qh);\r
+ if (QhHwPtr->DeviceAddr == DeviceAddress && QhHwPtr->EndpointNum == EndPointNum) {\r
+ MatchPtr = AsyncRequestPtr;\r
+ break;\r
+ }\r
+\r
+ AsyncRequestPtr = AsyncRequestPtr->Next;\r
+\r
+ } while (NULL != AsyncRequestPtr);\r
+\r
+ if (NULL == MatchPtr) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto exit;\r
+ }\r
+\r
+ Status = DisablePeriodicSchedule (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleDisable TimeOut\n"));\r
+ Status = EFI_TIMEOUT;\r
+ goto exit;\r
+ }\r
+\r
+ *DataToggle = (UINT8) MatchPtr->QhPtr->Qh.DataToggle;\r
+ UnlinkQhFromPeriodicList (HcDev, MatchPtr->QhPtr, MatchPtr->QhPtr->Interval);\r
+ UnlinkFromAsyncReqeust (HcDev, MatchPtr);\r
+\r
+ if (NULL == HcDev->AsyncRequestList) {\r
+\r
+ Status = StopPollingTimer (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ } else {\r
+\r
+ Status = EnablePeriodicSchedule (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+\r
+ Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((gEHCErrorLevel, "WaitForPeriodicScheduleEnable TimeOut\n"));\r
+ Status = EFI_TIMEOUT;\r
+ goto exit;\r
+ }\r
+\r
+ if (IsEhcHalted (HcDev)) {\r
+ Status = StartScheduleExecution (HcDev);\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto exit;\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ DestoryQtds (HcDev, MatchPtr->QhPtr->FirstQtdPtr);\r
+ DestoryQh (HcDev, MatchPtr->QhPtr);\r
+ EhciFreePool (HcDev, (UINT8 *) MatchPtr, sizeof (EHCI_ASYNC_REQUEST));\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
+VOID\r
+CleanUpAllAsyncRequestTransfer (\r
+ IN USB2_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Clean up all asynchronous request transfer\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV \r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+{\r
+ EHCI_ASYNC_REQUEST *AsyncRequestPtr;\r
+ EHCI_ASYNC_REQUEST *FreePtr;\r
+\r
+ AsyncRequestPtr = NULL;\r
+ FreePtr = NULL;\r
+\r
+ StopPollingTimer (HcDev);\r
+\r
+ AsyncRequestPtr = HcDev->AsyncRequestList;\r
+ while (NULL != AsyncRequestPtr) {\r
+\r
+ FreePtr = AsyncRequestPtr;\r
+ AsyncRequestPtr = AsyncRequestPtr->Next;\r
+ UnlinkFromAsyncReqeust (HcDev, FreePtr);\r
+ UnlinkQhFromPeriodicList (HcDev, FreePtr->QhPtr, FreePtr->QhPtr->Interval);\r
+ DestoryQtds (HcDev, FreePtr->QhPtr->FirstQtdPtr);\r
+ DestoryQh (HcDev, FreePtr->QhPtr);\r
+ EhciFreePool (HcDev, (UINT8 *) FreePtr, sizeof (EHCI_ASYNC_REQUEST));\r
+\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+VOID\r
+ZeroOutQhOverlay (\r
+ IN EHCI_QH_ENTITY *QhPtr\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Zero out the fields in Qh structure\r
+ \r
+Arguments:\r
+\r
+ QhPtr - A pointer to Qh structure\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+{\r
+ QhPtr->Qh.CurrentQtdPointer = 0;\r
+ QhPtr->Qh.AltNextQtdPointer = 0;\r
+ QhPtr->Qh.NakCount = 0;\r
+ QhPtr->Qh.AltNextQtdTerminate = 0;\r
+ QhPtr->Qh.TotalBytes = 0;\r
+ QhPtr->Qh.InterruptOnComplete = 0;\r
+ QhPtr->Qh.CurrentPage = 0;\r
+ QhPtr->Qh.ErrorCount = 0;\r
+ QhPtr->Qh.PidCode = 0;\r
+ QhPtr->Qh.Status = 0;\r
+ QhPtr->Qh.BufferPointer0 = 0;\r
+ QhPtr->Qh.CurrentOffset = 0;\r
+ QhPtr->Qh.BufferPointer1 = 0;\r
+ QhPtr->Qh.CompleteSplitMask = 0;\r
+ QhPtr->Qh.BufferPointer2 = 0;\r
+ QhPtr->Qh.SplitBytes = 0;\r
+ QhPtr->Qh.FrameTag = 0;\r
+ QhPtr->Qh.BufferPointer3 = 0;\r
+ QhPtr->Qh.BufferPointer4 = 0;\r
+ QhPtr->Qh.ExtBufferPointer0 = 0;\r
+ QhPtr->Qh.ExtBufferPointer1 = 0;\r
+ QhPtr->Qh.ExtBufferPointer2 = 0;\r
+ QhPtr->Qh.ExtBufferPointer3 = 0;\r
+ QhPtr->Qh.ExtBufferPointer4 = 0;\r
+}\r
+\r
+VOID\r
+UpdateAsyncRequestTransfer (\r
+ IN EHCI_ASYNC_REQUEST *AsyncRequestPtr,\r
+ IN UINT32 TransferResult,\r
+ IN UINTN ErrQtdPos\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Update asynchronous request transfer\r
+ \r
+Arguments:\r
+\r
+ AsyncRequestPtr - A pointer to async request \r
+ TransferResult - transfer result \r
+ ErrQtdPos - postion of error Qtd\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+{\r
+ EHCI_QTD_ENTITY *QtdPtr;\r
+\r
+ QtdPtr = NULL;\r
+\r
+ if (EFI_USB_NOERROR == TransferResult) {\r
+ \r
+ //\r
+ // Update Qh for next trigger\r
+ //\r
+\r
+ QtdPtr = AsyncRequestPtr->QhPtr->FirstQtdPtr;\r
+\r
+ //\r
+ // Update fields in Qh\r
+ //\r
+\r
+ //\r
+ // Get DataToggle from Overlay in Qh\r
+ //\r
+ // ZeroOut Overlay in Qh except DataToggle, HostController will update this field\r
+ //\r
+ ZeroOutQhOverlay (AsyncRequestPtr->QhPtr);\r
+ AsyncRequestPtr->QhPtr->Qh.NextQtdPointer = (UINT32) (GET_0B_TO_31B (&(QtdPtr->Qtd)) >> 5);\r
+ AsyncRequestPtr->QhPtr->Qh.NextQtdTerminate = FALSE;\r
+\r
+ //\r
+ // Update fields in Qtd\r
+ //\r
+ while (NULL != QtdPtr) {\r
+ QtdPtr->Qtd.TotalBytes = QtdPtr->StaticTotalBytes;\r
+ QtdPtr->Qtd.CurrentOffset = QtdPtr->StaticCurrentOffset;\r
+ QtdPtr->Qtd.CurrentPage = 0;\r
+ QtdPtr->Qtd.ErrorCount = QTD_ERROR_COUNTER;\r
+ QtdPtr->Qtd.Status = QTD_STATUS_ACTIVE;\r
+\r
+ QtdPtr->TotalBytes = QtdPtr->StaticTotalBytes;\r
+ QtdPtr = QtdPtr->Next;\r
+ }\r
+ }\r
+\r
+ return ;\r
+}\r
+\r
+BOOLEAN\r
+CheckQtdsTransferResult (\r
+ IN BOOLEAN IsControl,\r
+ IN EHCI_QH_ENTITY *QhPtr,\r
+ OUT UINT32 *Result,\r
+ OUT UINTN *ErrQtdPos,\r
+ OUT UINTN *ActualLen\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Check transfer result of Qtds\r
+\r
+Arguments:\r
+\r
+ IsControl - Is control transfer or not\r
+ QhPtr - A pointer to Qh\r
+ Result - Transfer result\r
+ ErrQtdPos - Error TD Position\r
+ ActualLen - Actual Transfer Size\r
+\r
+Returns:\r
+\r
+ TRUE Qtds finished\r
+ FALSE Not finish\r
+ \r
+--*/\r
+{\r
+ UINTN ActualLenPerQtd;\r
+ EHCI_QTD_ENTITY *QtdPtr;\r
+ EHCI_QTD_HW *QtdHwPtr;\r
+ BOOLEAN Value;\r
+\r
+ ASSERT (QhPtr);\r
+ ASSERT (Result);\r
+ ASSERT (ErrQtdPos);\r
+ ASSERT (ActualLen);\r
+\r
+ Value = TRUE;\r
+ QtdPtr = QhPtr->FirstQtdPtr;\r
+ QtdHwPtr = &(QtdPtr->Qtd);\r
+\r
+ while (NULL != QtdHwPtr) {\r
+\r
+ if (IsQtdStatusActive (QtdHwPtr)) {\r
+ *Result |= EFI_USB_ERR_NOTEXECUTE;\r
+ }\r
+\r
+ if (IsQtdStatusHalted (QtdHwPtr)) {\r
+ *Result |= EFI_USB_ERR_STALL;\r
+ }\r
+\r
+ if (IsQtdStatusBufferError (QtdHwPtr)) {\r
+ *Result |= EFI_USB_ERR_BUFFER;\r
+ }\r
+\r
+ if (IsQtdStatusBabbleError (QtdHwPtr)) {\r
+ *Result |= EFI_USB_ERR_BABBLE;\r
+ }\r
+\r
+ if (IsQtdStatusTransactionError (QtdHwPtr)) {\r
+ *Result |= EFI_USB_ERR_TIMEOUT;\r
+ }\r
+\r
+ ActualLenPerQtd = QtdPtr->TotalBytes - QtdHwPtr->TotalBytes;\r
+ QtdPtr->TotalBytes = QtdHwPtr->TotalBytes;\r
+ //\r
+ // Accumulate actual transferred data length in each DataQtd.\r\r
+ //\r
+ if (SETUP_PACKET_PID_CODE != QtdHwPtr->PidCode) {\r
+ *ActualLen += ActualLenPerQtd;\r
+ }\r
+\r
+ if (*Result) {\r
+ Value = FALSE;\r
+ break;\r
+ }\r
+\r
+ if ((!IsControl) && (QtdPtr->TotalBytes > 0)) {\r
+ //\r
+ // Did something, but isn't full workload\r
+ //\r
+ break;\r
+ }\r
+\r
+ (*ErrQtdPos)++;\r
+ QtdHwPtr = GetQtdNextPointer (QtdHwPtr);\r
+ QtdPtr = (EHCI_QTD_ENTITY *) GET_QTD_ENTITY_ADDR (QtdHwPtr);\r
+\r
+ }\r
+\r
+ return Value;\r
+}\r
+\r
+EFI_STATUS\r
+ExecuteTransfer (\r
+ IN USB2_HC_DEV *HcDev,\r
+ IN BOOLEAN IsControl,\r
+ IN EHCI_QH_ENTITY *QhPtr,\r
+ IN OUT UINTN *ActualLen,\r
+ OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Execute Bulk or SyncInterrupt Transfer\r
+\r
+Arguments:\r
+\r
+ HcDev - USB2_HC_DEV\r
+ IsControl - Is control transfer or not\r
+ QhPtr - A pointer to Qh\r
+ ActualLen - Actual transfered Len \r
+ DataToggle - Data Toggle\r
+ TimeOut - TimeOut threshold\r
+ TransferResult - Transfer result\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Sucess\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ErrQtdPos;\r
+ UINTN Delay;\r
+ UINTN RequireLen;\r
+ BOOLEAN Finished;\r
+\r
+ Status = EFI_SUCCESS;\r
+ ErrQtdPos = 0;\r
+ *TransferResult = EFI_USB_NOERROR;\r
+ RequireLen = *ActualLen;\r
+ *ActualLen = 0;\r
+ Finished = FALSE;\r
+\r
+ Delay = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;\r
+\r
+ do {\r
+ *TransferResult = 0;\r
+ Finished = CheckQtdsTransferResult (\r
+ IsControl,\r
+ QhPtr,\r
+ TransferResult,\r
+ &ErrQtdPos,\r
+ ActualLen\r
+ );\r
+ if (Finished) {\r
+ break;\r
+ }\r
+ //\r
+ // Qtd is inactive, which means bulk or interrupt transfer's end.\r
+ //\r
+ if (!(*TransferResult & EFI_USB_ERR_NOTEXECUTE)) {\r
+ break;\r
+ }\r
+\r
+ gBS->Stall (EHCI_SYNC_REQUEST_POLLING_TIME);\r
+\r
+ } while (--Delay);\r
+\r
+ if (EFI_USB_NOERROR != *TransferResult) {\r
+ if (0 == Delay) {\r
+ Status = EFI_TIMEOUT;\r
+ } else {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Special for Bulk and Interrupt Transfer\r
+ //\r
+ *DataToggle = (UINT8) QhPtr->Qh.DataToggle;\r
+ \r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+AsyncRequestMoniter (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+Routine Description:\r
+ \r
+ Interrupt transfer periodic check handler\r
+ \r
+Arguments:\r
+ Event - Interrupt event\r
+ Context - Pointer to USB2_HC_DEV\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *HcDev;\r
+ EHCI_ASYNC_REQUEST *AsyncRequestPtr;\r
+ EHCI_QTD_HW *QtdHwPtr;\r
+ UINTN ErrQtdPos;\r
+ UINTN ActualLen;\r
+ UINT32 TransferResult;\r
+ UINT8 *ReceiveBuffer;\r
+ UINT8 *ProcessBuffer;\r
+\r
+ Status = EFI_SUCCESS;\r
+ QtdHwPtr = NULL;\r
+ ReceiveBuffer = NULL;\r
+ ProcessBuffer = NULL;\r
+ HcDev = (USB2_HC_DEV *) Context;\r
+ AsyncRequestPtr = HcDev->AsyncRequestList;\r
+\r
+ while (NULL != AsyncRequestPtr) {\r
+\r
+ TransferResult = 0;\r
+ ErrQtdPos = 0;\r
+ ActualLen = 0;\r
+\r
+ CheckQtdsTransferResult (\r
+ FALSE, \r
+ AsyncRequestPtr->QhPtr, \r
+ &TransferResult, \r
+ &ErrQtdPos, \r
+ &ActualLen\r
+ );\r
+\r
+ if ((TransferResult & EFI_USB_ERR_NAK) || (TransferResult & EFI_USB_ERR_NOTEXECUTE)) {\r
+ AsyncRequestPtr = AsyncRequestPtr->Next;\r
+ continue;\r
+ }\r
+ //\r
+ // Allocate memory for EHC private data structure\r
+ //\r
+ ProcessBuffer = AllocateZeroPool (ActualLen);\r
+ if (NULL == ProcessBuffer) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto exit;\r
+ }\r
+\r
+ QtdHwPtr = &(AsyncRequestPtr->QhPtr->FirstQtdPtr->Qtd);\r
+ ReceiveBuffer = (UINT8 *) GET_0B_TO_31B ((QtdHwPtr->BufferPointer0 << 12) | AsyncRequestPtr->QhPtr->FirstQtdPtr->StaticCurrentOffset);\r
+ CopyMem (\r
+ ProcessBuffer,\r
+ ReceiveBuffer,\r
+ ActualLen\r
+ );\r
+\r
+ UpdateAsyncRequestTransfer (AsyncRequestPtr, TransferResult, ErrQtdPos);\r
+\r
+ if (EFI_USB_NOERROR == TransferResult) {\r
+\r
+ if (AsyncRequestPtr->CallBackFunc != NULL) {\r
+ (AsyncRequestPtr->CallBackFunc) (ProcessBuffer, ActualLen, AsyncRequestPtr->Context, TransferResult);\r
+ }\r
+\r
+ } else {\r
+\r
+ //\r
+ // leave error recovery to its related device driver. A common case of \r
+ // the error recovery is to re-submit the interrupt transfer.\r
+ // When an interrupt transfer is re-submitted, its position in the linked\r
+ // list is changed. It is inserted to the head of the linked list, while\r
+ // this function scans the whole list from head to tail. Thus, the\r
+ // re-submitted interrupt transfer's callback function will not be called\r
+ // again in this round.\r
+ //\r
+ if (AsyncRequestPtr->CallBackFunc != NULL) {\r
+ (AsyncRequestPtr->CallBackFunc) (NULL, 0, AsyncRequestPtr->Context, TransferResult);\r
+ }\r
+\r
+ }\r
+\r
+ if (NULL != ProcessBuffer) {\r
+ gBS->FreePool (ProcessBuffer);\r
+ }\r
+\r
+ AsyncRequestPtr = AsyncRequestPtr->Next;\r
+\r
+ }\r
+\r
+exit:\r
+ return Status;\r
+}\r
+\r
<Protocol Usage="BY_START">\r
<ProtocolCName>gEfiUsbHcProtocolGuid</ProtocolCName>\r
</Protocol>\r
+ <Protocol Usage="BY_START">\r
+ <ProtocolCName>gEfiUsb2HcProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
</Protocols>\r
<Externs>\r
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
// Perform 16bit Read in PCI IO Space\r
//\r
return PciIo->Io.Read (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- USB_BAR_INDEX,\r
- (UINT64) PortOffset,\r
- 1,\r
- Data\r
- );\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ USB_BAR_INDEX,\r
+ (UINT64) PortOffset,\r
+ 1,\r
+ Data\r
+ );\r
}\r
\r
EFI_STATUS\r
// Perform 32bit Read in PCI IO Space\r
//\r
return PciIo->Io.Read (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- USB_BAR_INDEX,\r
- (UINT64) PortOffset,\r
- 1,\r
- Data\r
- );\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ USB_BAR_INDEX,\r
+ (UINT64) PortOffset,\r
+ 1,\r
+ Data\r
+ );\r
}\r
\r
EFI_STATUS\r
// Perform 16bit Write in PCI IO Space\r
//\r
return PciIo->Io.Write (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- USB_BAR_INDEX,\r
- (UINT64) PortOffset,\r
- 1,\r
- &Data\r
- );\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ USB_BAR_INDEX,\r
+ (UINT64) PortOffset,\r
+ 1,\r
+ &Data\r
+ );\r
}\r
\r
EFI_STATUS\r
// Perform 32bit Write in PCI IO Space\r
//\r
return PciIo->Io.Write (\r
- PciIo,\r
- EfiPciIoWidthUint32,\r
- USB_BAR_INDEX,\r
- (UINT64) PortOffset,\r
- 1,\r
- &Data\r
- );\r
+ PciIo,\r
+ EfiPciIoWidthUint32,\r
+ USB_BAR_INDEX,\r
+ (UINT64) PortOffset,\r
+ 1,\r
+ &Data\r
+ );\r
}\r
//\r
// USB register-base helper functions\r
EFI_STATUS Status;\r
\r
Status = ReadUHCCommandReg (\r
- HcDev->PciIo,\r
- (UINT32) (USBCMD),\r
- &CommandContent\r
- );\r
+ HcDev->PciIo,\r
+ (UINT32) (USBCMD),\r
+ &CommandContent\r
+ );\r
\r
if ((CommandContent & USBCMD_MAXP) != USBCMD_MAXP) {\r
CommandContent |= USBCMD_MAXP;\r
BufferSizeInBytes = 4096;\r
BufferSizeInPages = EFI_SIZE_TO_PAGES (BufferSizeInBytes);\r
Status = HcDev->PciIo->AllocateBuffer (\r
- HcDev->PciIo,\r
- AllocateAnyPages,\r
- EfiBootServicesData,\r
- BufferSizeInPages,\r
- &CommonBuffer,\r
- 0\r
- );\r
+ HcDev->PciIo,\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ BufferSizeInPages,\r
+ &CommonBuffer,\r
+ 0\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
Status = HcDev->PciIo->Map (\r
- HcDev->PciIo,\r
- EfiPciIoOperationBusMasterCommonBuffer,\r
- CommonBuffer,\r
- &BufferSizeInBytes,\r
- &MappedAddress,\r
- &Mapping\r
- );\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterCommonBuffer,\r
+ CommonBuffer,\r
+ &BufferSizeInBytes,\r
+ &MappedAddress,\r
+ &Mapping\r
+ );\r
if (EFI_ERROR (Status) || (BufferSizeInBytes != 4096)) {\r
HcDev->PciIo->FreeBuffer (HcDev->PciIo, BufferSizeInPages, CommonBuffer);\r
return EFI_UNSUPPORTED;\r
// and it is allocated as common buffer use.\r
//\r
Status = HcDev->PciIo->AllocateBuffer (\r
- HcDev->PciIo,\r
- AllocateAnyPages,\r
- EfiBootServicesData,\r
- MemoryBlockSizeInPages,\r
- &CommonBuffer,\r
- 0\r
- );\r
+ HcDev->PciIo,\r
+ AllocateAnyPages,\r
+ EfiBootServicesData,\r
+ MemoryBlockSizeInPages,\r
+ &CommonBuffer,\r
+ 0\r
+ );\r
if (EFI_ERROR (Status)) {\r
gBS->FreePool ((*MemoryHeader)->BitArrayPtr);\r
gBS->FreePool (*MemoryHeader);\r
\r
MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);\r
Status = HcDev->PciIo->Map (\r
- HcDev->PciIo,\r
- EfiPciIoOperationBusMasterCommonBuffer,\r
- CommonBuffer,\r
- &MemoryBlockSizeInBytes,\r
- &MappedAddress,\r
- &Mapping\r
- );\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterCommonBuffer,\r
+ CommonBuffer,\r
+ &MemoryBlockSizeInBytes,\r
+ &MappedAddress,\r
+ &Mapping\r
+ );\r
//\r
// if returned Mapped size is less than the size we request,do not support.\r
//\r
TempHeaderPtr = TempHeaderPtr->Next) {\r
\r
Status = AllocMemInMemoryBlock (\r
- TempHeaderPtr,\r
- (VOID **) Pool,\r
- RealAllocSize / 32\r
- );\r
+ TempHeaderPtr,\r
+ (VOID **) Pool,\r
+ RealAllocSize / 32\r
+ );\r
if (!EFI_ERROR (Status)) {\r
ZeroMem (*Pool, AllocSize);\r
return EFI_SUCCESS;\r
InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);\r
\r
Status = AllocMemInMemoryBlock (\r
- NewMemoryHeader,\r
- (VOID **) Pool,\r
- RealAllocSize / 32\r
- );\r
+ NewMemoryHeader,\r
+ (VOID **) Pool,\r
+ RealAllocSize / 32\r
+ );\r
\r
if (!EFI_ERROR (Status)) {\r
ZeroMem (*Pool, AllocSize);\r
//\r
Command = 0;\r
PciIo->Pci.Write (\r
- PciIo,\r
- EfiPciIoWidthUint16,\r
- USB_EMULATION,\r
- 1,\r
- &Command\r
- );\r
+ PciIo,\r
+ EfiPciIoWidthUint16,\r
+ USB_EMULATION,\r
+ 1,\r
+ &Command\r
+ );\r
\r
return ;\r
}\r
// Driver model protocol interface\r
//\r
\r
-EFI_STATUS\r
-EFIAPI\r
-UHCIDriverEntryPoint (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- );\r
-\r
EFI_STATUS\r
EFIAPI\r
UHCIDriverBindingSupported (\r
IN UINT8 DeviceAddress,\r
IN UINT8 EndPointAddress,\r
IN BOOLEAN IsSlowDevice,\r
- IN UINT8 MaxiumPacketLength,\r
+ IN UINT8 MaximumPacketLength,\r
IN BOOLEAN IsNewTransfer,\r
IN OUT UINT8 *DataToggle,\r
IN UINTN PollingInterval, OPTIONAL\r
IN EFI_USB_PORT_FEATURE PortFeature\r
);\r
\r
+//\r
+// UEFI 2.0 Protocol\r
+//\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetCapability(\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ OUT UINT8 *MaxSpeed,\r
+ OUT UINT8 *PortNumber,\r
+ OUT UINT8 *Is64BitCapable\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2Reset (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT16 Attributes\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetState (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ OUT EFI_USB_HC_STATE * State\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SetState (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN EFI_USB_HC_STATE State\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2ControlTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN EFI_USB_DEVICE_REQUEST * Request,\r
+ IN EFI_USB_DATA_DIRECTION TransferDirection,\r
+ IN OUT VOID *Data, OPTIONAL\r
+ IN OUT UINTN *DataLength, OPTIONAL\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2BulkTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2AsyncInterruptTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN BOOLEAN IsNewTransfer,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN PollingInterval, OPTIONAL\r
+ IN UINTN DataLength, OPTIONAL\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction, OPTIONAL\r
+ IN VOID *Context OPTIONAL\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SyncInterruptTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2IsochronousTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2AsyncIsochronousTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,\r
+ IN VOID *Context OPTIONAL\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetRootHubPortStatus (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 PortNumber,\r
+ OUT EFI_USB_PORT_STATUS * PortStatus\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SetRootHubPortFeature (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2ClearRootHubPortFeature (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ );\r
+\r
//\r
// Asynchronous interrupt transfer monitor function\r
//\r
\r
Arguments:\r
This - Protocol instance pointer.\r
- Controller, - Handle of device to test\r
+ Controller - Handle of device to test\r
RemainingDevicePath - Not used\r
\r
Returns:\r
(UsbClassCReg.PI != PCI_CLASSC_PI_UHCI)) {\r
\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
\r
return EFI_UNSUPPORTED;\r
}\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
return EFI_SUCCESS;\r
\r
}\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
//\r
// Turn off USB emulation\r
//\r
);\r
if (EFI_ERROR (Status)) {\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
return EFI_UNSUPPORTED;\r
}\r
\r
HcDev = AllocateZeroPool (sizeof (USB_HC_DEV));\r
if (HcDev == NULL) {\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- \r
+\r
//\r
// init EFI_USB_HC_PROTOCOL protocol interface and install the protocol\r
//\r
HcDev->UsbHc.MajorRevision = 0x1;\r
HcDev->UsbHc.MinorRevision = 0x1;\r
\r
+ //\r
+ //\r
+ // init EFI_USB2_HC_PROTOCOL protocol interface and install the protocol\r
+ //\r
+ HcDev->Usb2Hc.GetCapability = UHCI2GetCapability;\r
+ HcDev->Usb2Hc.Reset = UHCI2Reset;\r
+ HcDev->Usb2Hc.GetState = UHCI2GetState;\r
+ HcDev->Usb2Hc.SetState = UHCI2SetState;\r
+ HcDev->Usb2Hc.ControlTransfer = UHCI2ControlTransfer;\r
+ HcDev->Usb2Hc.BulkTransfer = UHCI2BulkTransfer;\r
+ HcDev->Usb2Hc.AsyncInterruptTransfer = UHCI2AsyncInterruptTransfer;\r
+ HcDev->Usb2Hc.SyncInterruptTransfer = UHCI2SyncInterruptTransfer;\r
+ HcDev->Usb2Hc.IsochronousTransfer = UHCI2IsochronousTransfer;\r
+ HcDev->Usb2Hc.AsyncIsochronousTransfer = UHCI2AsyncIsochronousTransfer;\r
+ HcDev->Usb2Hc.GetRootHubPortStatus = UHCI2GetRootHubPortStatus;\r
+ HcDev->Usb2Hc.SetRootHubPortFeature = UHCI2SetRootHubPortFeature;\r
+ HcDev->Usb2Hc.ClearRootHubPortFeature = UHCI2ClearRootHubPortFeature;\r
+ \r
+ HcDev->Usb2Hc.MajorRevision = 0x1;\r
+ HcDev->Usb2Hc.MinorRevision = 0x1;\r
+ \r
//\r
// Init UHCI private data structures\r
//\r
}\r
\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- \r
+\r
//\r
// Init interrupt list head in the HcDev structure.\r
//\r
}\r
\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
return EFI_UNSUPPORTED;\r
}\r
\r
}\r
\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
return EFI_UNSUPPORTED;\r
}\r
\r
);\r
return Status;\r
}\r
- \r
+\r
//\r
// Install Host Controller Protocol\r
//\r
}\r
\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Install USB2.0 Host Controller Protocol\r
+ //\r
+ Status = gBS->InstallProtocolInterface (\r
+ &Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ &HcDev->Usb2Hc\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->CloseEvent (HcDev->InterruptTransTimer);\r
+ FreeFrameListEntry (HcDev);\r
+ DelMemoryManagement (HcDev);\r
+\r
+ if (HcDev != NULL) {\r
+ gBS->FreePool (HcDev);\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+\r
return Status;\r
}\r
\r
//\r
// component name protocol.\r
//\r
+\r
HcDev->ControllerNameTable = NULL;\r
AddUnicodeString (\r
"eng",\r
HcDev = USB_HC_DEV_FROM_THIS (This);\r
\r
gBS->UninstallProtocolInterface (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- &HcDev->UsbHc\r
- );\r
-\r
- //\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ &HcDev->UsbHc\r
+ );\r
+ \r
+ gBS->UninstallProtocolInterface (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ &HcDev->Usb2Hc\r
+ );\r
+ // \r
// first stop USB Host Controller\r
//\r
This->SetState (This, EfiUsbHcStateHalt);\r
--*/\r
{\r
EFI_USB_HC_PROTOCOL *UsbHc;\r
+ EFI_USB2_HC_PROTOCOL *Usb2Hc;\r
EFI_STATUS OpenStatus;\r
\r
OpenStatus = gBS->OpenProtocol (\r
Controller,\r
&gEfiUsbHcProtocolGuid,\r
- (VOID **) &UsbHc,\r
+ (VOID **)&UsbHc,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
+ //\r
+ // Test whether the Controller handler passed in is a valid\r
+ // Usb controller handle that should be supported, if not,\r
+ // return the error status directly\r
+ //\r
+ if (EFI_ERROR (OpenStatus)) {\r
+ return OpenStatus;\r
+ }\r
+\r
+ OpenStatus = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ (VOID **) &Usb2Hc,\r
This->DriverBindingHandle,\r
Controller,\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
UnInstallUHCInterface (Controller, UsbHc);\r
\r
gBS->CloseProtocol (\r
- Controller,\r
- &gEfiPciIoProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
\r
return EFI_SUCCESS;\r
\r
// set the Global Reset bit in the command register\r
//\r
Status = ReadUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- &Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ &Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
Command |= USBCMD_GRESET;\r
Status = WriteUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
//\r
Command &= ~USBCMD_GRESET;\r
Status = WriteUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
// set Host Controller Reset bit to 1\r
//\r
Status = ReadUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- &Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ &Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
Command |= USBCMD_HCRESET;\r
Status = WriteUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
StatusRegAddr = (UINT32) (USBSTS);\r
\r
Status = ReadUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- &UhcCommand\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ &UhcCommand\r
+ );\r
\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
Status = ReadUHCCommandReg (\r
- HcDev->PciIo,\r
- StatusRegAddr,\r
- &UhcStatus\r
- );\r
+ HcDev->PciIo,\r
+ StatusRegAddr,\r
+ &UhcStatus\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
}\r
\r
Status = ReadUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- &Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ &Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
Command &= ~USBCMD_RS;\r
\r
Status = WriteUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
// Set Run/Stop bit to 1.\r
//\r
Status = ReadUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- &Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ &Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
Command |= USBCMD_RS | USBCMD_MAXP;\r
Status = WriteUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
case EfiUsbHcStateSuspend:\r
Status = ReadUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- &Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ &Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
// Set Enter Global Suspend Mode bit to 1.\r
//\r
Status = ReadUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- &Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ &Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
Command |= USBCMD_EGSM;\r
Status = WriteUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
for (Index = 0; Index < 2; Index++) {\r
PSAddr = (UINT32) (USBPORTSC1 + Index * 2);\r
Status = ReadRootPortReg (\r
- HcDev->PciIo,\r
- PSAddr,\r
- &RHPortControl\r
- );\r
+ HcDev->PciIo,\r
+ PSAddr,\r
+ &RHPortControl\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
PortStatus->PortChangeStatus = 0;\r
\r
Status = ReadRootPortReg (\r
- HcDev->PciIo,\r
- PSAddr,\r
- &RHPortStatus\r
- );\r
+ HcDev->PciIo,\r
+ PSAddr,\r
+ &RHPortStatus\r
+ );\r
\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
}\r
//\r
+ // CHC will always return one in this bit\r
+ //\r
+ PortStatus->PortStatus |= USB_PORT_STAT_OWNER;\r
+ //\r
// Fill Port Status Change bits\r
//\r
\r
\r
case EfiUsbPortSuspend:\r
Status = ReadUHCCommandReg (\r
- HcDev->PciIo,\r
- CommandRegAddr,\r
- &Command\r
- );\r
+ HcDev->PciIo,\r
+ CommandRegAddr,\r
+ &Command\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
PSAddr = (UINT32) (USBPORTSC1 + PortNumber * 2);\r
\r
Status = ReadRootPortReg (\r
- HcDev->PciIo,\r
- PSAddr,\r
- &RHPortControl\r
- );\r
+ HcDev->PciIo,\r
+ PSAddr,\r
+ &RHPortControl\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
// BusMasterWrite means cpu read\r
//\r
Status = HcDev->PciIo->Map (\r
- HcDev->PciIo,\r
- EfiPciIoOperationBusMasterWrite,\r
- PtrDataSource,\r
- &DataLen,\r
- &TempPtr,\r
- &Mapping\r
- );\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterWrite,\r
+ PtrDataSource,\r
+ &DataLen,\r
+ &TempPtr,\r
+ &Mapping\r
+ );\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
// BusMasterRead means cpu write\r
//\r
Status = HcDev->PciIo->Map (\r
- HcDev->PciIo,\r
- EfiPciIoOperationBusMasterRead,\r
- PtrDataSource,\r
- &DataLen,\r
- &TempPtr,\r
- &Mapping\r
- );\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterRead,\r
+ PtrDataSource,\r
+ &DataLen,\r
+ &TempPtr,\r
+ &Mapping\r
+ );\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
//\r
RequestLen = sizeof (EFI_USB_DEVICE_REQUEST);\r
Status = HcDev->PciIo->Map (\r
- HcDev->PciIo,\r
- EfiPciIoOperationBusMasterRead,\r
- (UINT8 *) Request,\r
- &RequestLen,\r
- &TempPtr,\r
- &RequestMapping\r
- );\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterRead,\r
+ (UINT8 *) Request,\r
+ &RequestLen,\r
+ &TempPtr,\r
+ &RequestMapping\r
+ );\r
\r
if (EFI_ERROR (Status)) {\r
HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
// generate Setup Stage TD\r
//\r
Status = GenSetupStageTD (\r
- HcDev,\r
- DeviceAddress,\r
- 0,\r
- IsSlowDevice,\r
- (UINT8 *) RequestMappedAddress,\r
- sizeof (EFI_USB_DEVICE_REQUEST),\r
- &PtrSetupTD\r
- );\r
+ HcDev,\r
+ DeviceAddress,\r
+ 0,\r
+ IsSlowDevice,\r
+ (UINT8 *) RequestMappedAddress,\r
+ sizeof (EFI_USB_DEVICE_REQUEST),\r
+ &PtrSetupTD\r
+ );\r
\r
if (EFI_ERROR (Status)) {\r
HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
}\r
\r
Status = GenDataTD (\r
- HcDev,\r
- DeviceAddress,\r
- 0,\r
- Ptr,\r
- PktSize,\r
- PktID,\r
- DataToggle,\r
- IsSlowDevice,\r
- &PtrTD\r
- );\r
+ HcDev,\r
+ DeviceAddress,\r
+ 0,\r
+ Ptr,\r
+ PktSize,\r
+ PktID,\r
+ DataToggle,\r
+ IsSlowDevice,\r
+ &PtrTD\r
+ );\r
\r
if (EFI_ERROR (Status)) {\r
//\r
// create Status Stage TD structure\r
//\r
Status = CreateStatusTD (\r
- HcDev,\r
- DeviceAddress,\r
- 0,\r
- PktID,\r
- IsSlowDevice,\r
- &PtrStatusTD\r
- );\r
+ HcDev,\r
+ DeviceAddress,\r
+ 0,\r
+ PktID,\r
+ IsSlowDevice,\r
+ &PtrStatusTD\r
+ );\r
\r
if (EFI_ERROR (Status)) {\r
HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
}\r
\r
Status = ExecuteControlTransfer (\r
- HcDev,\r
- PtrFirstDataTD,\r
- LoadFrameListIndex,\r
- DataLength,\r
- TimeOut,\r
- TransferResult\r
- );\r
+ HcDev,\r
+ PtrFirstDataTD,\r
+ LoadFrameListIndex,\r
+ DataLength,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
\r
for (Index = 0; Index < 500; Index++) {\r
DelLinkSingleQH (\r
// detail status is returned\r
//\r
Status = ExecuteControlTransfer (\r
- HcDev,\r
- PtrStatusTD,\r
- LoadFrameListIndex,\r
- DataLength,\r
- TimeOut,\r
- TransferResult\r
- );\r
+ HcDev,\r
+ PtrStatusTD,\r
+ LoadFrameListIndex,\r
+ DataLength,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
\r
//\r
// Delete Control Transfer QH-TDs structure\r
// detail status is returned\r
//\r
Status = ExecuteControlTransfer (\r
- HcDev,\r
- PtrSetupTD,\r
- LoadFrameListIndex,\r
- DataLength,\r
- TimeOut,\r
- TransferResult\r
- );\r
+ HcDev,\r
+ PtrSetupTD,\r
+ LoadFrameListIndex,\r
+ DataLength,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
//\r
// Remove Control Transfer QH-TDs structure from the frame list\r
// and update the pointers in the Frame List\r
// BusMasterWrite means cpu read\r
//\r
Status = HcDev->PciIo->Map (\r
- HcDev->PciIo,\r
- EfiPciIoOperationBusMasterWrite,\r
- PtrDataSource,\r
- &DataLen,\r
- &TempPtr,\r
- &Mapping\r
- );\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterWrite,\r
+ PtrDataSource,\r
+ &DataLen,\r
+ &TempPtr,\r
+ &Mapping\r
+ );\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
// BusMasterRead means cpu write\r
//\r
Status = HcDev->PciIo->Map (\r
- HcDev->PciIo,\r
- EfiPciIoOperationBusMasterRead,\r
- PtrDataSource,\r
- &DataLen,\r
- &TempPtr,\r
- &Mapping\r
- );\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterRead,\r
+ PtrDataSource,\r
+ &DataLen,\r
+ &TempPtr,\r
+ &Mapping\r
+ );\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
}\r
\r
Status = GenDataTD (\r
- HcDev,\r
- DeviceAddress,\r
- EndPointAddress,\r
- Ptr,\r
- PktSize,\r
- PktID,\r
- *DataToggle,\r
- FALSE,\r
- &PtrTD\r
- );\r
+ HcDev,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ Ptr,\r
+ PktSize,\r
+ PktID,\r
+ *DataToggle,\r
+ FALSE,\r
+ &PtrTD\r
+ );\r
\r
if (EFI_ERROR (Status)) {\r
HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
// of the last successful TD\r
//\r
Status = ExecBulkorSyncInterruptTransfer (\r
- HcDev,\r
- PtrFirstTD,\r
- LoadFrameListIndex,\r
- DataLength,\r
- DataToggle,\r
- TimeOut,\r
- TransferResult\r
- );\r
+ HcDev,\r
+ PtrFirstTD,\r
+ LoadFrameListIndex,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
\r
//\r
// Delete Bulk transfer QH-TD structure\r
IN UINT8 DeviceAddress,\r
IN UINT8 EndPointAddress,\r
IN BOOLEAN IsSlowDevice,\r
- IN UINT8 MaxiumPacketLength,\r
+ IN UINT8 MaximumPacketLength,\r
IN BOOLEAN IsNewTransfer,\r
IN OUT UINT8 *DataToggle,\r
IN UINTN PollingInterval, OPTIONAL\r
IsSlowDevice Indicates whether the target device is slow device \r
or full-speed device.\r
\r
- MaxiumPacketLength Indicates the maximum packet size the target endpoint\r
+ MaximumPacketLength Indicates the maximum packet size the target endpoint\r
is capable of sending or receiving.\r
\r
IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between\r
OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);\r
\r
Status = DeleteAsyncINTQHTDs (\r
- HcDev,\r
- DeviceAddress,\r
- EndPointAddress,\r
- DataToggle\r
- );\r
+ HcDev,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DataToggle\r
+ );\r
\r
gBS->RestoreTPL (OldTpl);\r
\r
// BusMasterWrite means cpu read\r
//\r
Status = HcDev->PciIo->Map (\r
- HcDev->PciIo,\r
- EfiPciIoOperationBusMasterWrite,\r
- Ptr,\r
- &DataLen,\r
- &TempPtr,\r
- &Mapping\r
- );\r
+ HcDev->PciIo,\r
+ EfiPciIoOperationBusMasterWrite,\r
+ Ptr,\r
+ &DataLen,\r
+ &TempPtr,\r
+ &Mapping\r
+ );\r
if (EFI_ERROR (Status)) {\r
gBS->FreePool (Ptr);\r
return Status;\r
//\r
\r
PktSize = (UINT8) DataLen;\r
- if (DataLen > MaxiumPacketLength) {\r
- PktSize = MaxiumPacketLength;\r
+ if (DataLen > MaximumPacketLength) {\r
+ PktSize = MaximumPacketLength;\r
}\r
\r
Status = GenDataTD (\r
- HcDev,\r
- DeviceAddress,\r
- EndPointAddress,\r
- MappedPtr,\r
- PktSize,\r
- PktID,\r
- CurrentDataToggle,\r
- IsSlowDevice,\r
- &PtrTD\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (Ptr);\r
+ HcDev,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ MappedPtr,\r
+ PktSize,\r
+ PktID,\r
+ CurrentDataToggle,\r
+ IsSlowDevice,\r
+ &PtrTD\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (Ptr);\r
HcDev->PciIo->Unmap (HcDev->PciIo, Mapping);\r
DeleteQueuedTDs (HcDev, PtrFirstTD);\r
return Status;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ if (TransferResult == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
ClearStatusReg (HcDev->PciIo, StatusReg);\r
\r
//\r
return EFI_UNSUPPORTED;\r
}\r
\r
+//\r
+// UEFI 2.0 Protocol\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetCapability(\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ OUT UINT8 *MaxSpeed,\r
+ OUT UINT8 *PortNumber,\r
+ OUT UINT8 *Is64BitCapable\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Retrieves capabilities of USB host controller according to UEFI 2.0 spec.\r
+\r
+ Arguments:\r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ \r
+ MaxSpeed - A pointer to the max speed USB host controller supports.\r
+ \r
+ PortNumber - A pointer to the number of root hub ports.\r
+ \r
+ Is64BitCapable - A pointer to an integer to show whether USB host controller\r
+ supports 64-bit memory addressing.\r
+ Returns:\r
+ EFI_SUCCESS \r
+ The host controller capabilities were retrieved successfully.\r
+ EFI_INVALID_PARAMETER \r
+ MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to retrieve the capabilities.\r
+ \r
+--*/ \r
+{\r
+ USB_HC_DEV *HcDev;\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ \r
+ if ((NULL == MaxSpeed) \r
+ ||(NULL == PortNumber)\r
+ || (NULL == Is64BitCapable))\r
+ {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ \r
+ *MaxSpeed = EFI_USB_SPEED_FULL;\r
+ *Is64BitCapable = (UINT8)FALSE;\r
+ return UHCIGetRootHubPortNumber(&HcDev->UsbHc, PortNumber);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2Reset (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT16 Attributes\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Provides software reset for the USB host controller according to UEFI 2.0 spec.\r
+\r
+ Arguments:\r
+ This - A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ \r
+ Attributes - A bit mask of the reset operation to perform. \r
+ See below for a list of the supported bit mask values.\r
+ \r
+ #define EFI_USB_HC_RESET_GLOBAL 0x0001\r
+ #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002\r
+ #define EFI_USB_HC_RESET_GLOBAL _WITH_DEBUG 0x0004\r
+ #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008\r
+\r
+ EFI_USB_HC_RESET_GLOBAL \r
+ If this bit is set, a global reset signal will be sent to the USB bus.\r
+ This resets all of the USB bus logic, including the USB host \r
+ controller hardware and all the devices attached on the USB bus.\r
+ EFI_USB_HC_RESET_HOST_CONTROLLER \r
+ If this bit is set, the USB host controller hardware will be reset. \r
+ No reset signal will be sent to the USB bus.\r
+ \r
+ Returns:\r
+ EFI_SUCCESS \r
+ The reset operation succeeded.\r
+ EFI_INVALID_PARAMETER \r
+ Attributes is not valid.\r
+ EFI_UNSUPPORTED\r
+ The type of reset specified by Attributes is not currently supported by the host controller hardware.\r
+ EFI_ACCESS_DENIED\r
+ Reset operation is rejected due to the debug port being configured and active.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to perform \r
+ the reset operation.\r
+--*/\r
+{\r
+ USB_HC_DEV *HcDev;\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ \r
+ if (Attributes==EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG || Attributes==EFI_USB_HC_RESET_HOST_WITH_DEBUG)\r
+ return EFI_UNSUPPORTED;\r
+ \r
+ return UHCIReset(\r
+ &HcDev->UsbHc, \r
+ Attributes\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetState (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ OUT EFI_USB_HC_STATE * State\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Retrieves current state of the USB host controller according to UEFI 2.0 spec.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB_HC_PROTOCOL instance.\r
+ \r
+ State - A pointer to the EFI_USB_HC_STATE data structure that \r
+ indicates current state of the USB host controller. \r
+ Type EFI_USB_HC_STATE is defined below.\r
+ \r
+ typedef enum {\r
+ EfiUsbHcStateHalt,\r
+ EfiUsbHcStateOperational,\r
+ EfiUsbHcStateSuspend,\r
+ EfiUsbHcStateMaximum\r
+ } EFI_USB_HC_STATE;\r
+ \r
+ Returns:\r
+ EFI_SUCCESS \r
+ The state information of the host controller was returned in State.\r
+ EFI_INVALID_PARAMETER \r
+ State is NULL.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to retrieve the \r
+ host controller's current state. \r
+--*/ \r
+{\r
+ USB_HC_DEV *HcDev;\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ return UHCIGetState(\r
+ &HcDev->UsbHc, \r
+ State\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SetState (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN EFI_USB_HC_STATE State\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Sets the USB host controller to a specific state according to UEFI 2.0 spec.\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB_HC_PROTOCOL instance.\r
+\r
+ State - Indicates the state of the host controller that will be set.\r
+ \r
+ Returns:\r
+ EFI_SUCCESS \r
+ The USB host controller was successfully placed in the state \r
+ specified by State.\r
+ EFI_INVALID_PARAMETER \r
+ State is invalid.\r
+ EFI_DEVICE_ERROR \r
+ Failed to set the state specified by State due to device error. \r
+--*/\r
+{\r
+ USB_HC_DEV *HcDev;\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ return UHCISetState(\r
+ &HcDev->UsbHc, \r
+ State\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2ControlTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN EFI_USB_DEVICE_REQUEST * Request,\r
+ IN EFI_USB_DATA_DIRECTION TransferDirection,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Submits control transfer to a target USB device accroding to UEFI 2.0 spec..\r
+ \r
+ Arguments:\r
+ \r
+ This - A pointer to the EFI_USB_HC_PROTOCOL instance.\r
+\r
+ DeviceAddress -Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+\r
+ DeviceSpeed - Indicates transfer speed of device.\r
+ \r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ \r
+ Request - A pointer to the USB device request that will be sent \r
+ to the USB device. \r
+ \r
+ TransferDirection - Specifies the data direction for the transfer.\r
+ There are three values available, DataIn, DataOut \r
+ and NoData.\r
+ \r
+ Data -A pointer to the buffer of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ \r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ \r
+ TimeOut - Indicates the maximum time, in microseconds, \r
+ which the transfer is allowed to complete.\r
+ \r
+ TransferResult - A pointer to the detailed result information generated \r
+ by this control transfer.\r
+ \r
+ Returns:\r
+ EFI_SUCCESS \r
+ The control transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The control transfer could not be completed due to a lack of resources.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The control transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The control transfer failed due to host controller or device error. \r
+ Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+{\r
+ USB_HC_DEV *HcDev;\r
+ BOOLEAN IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ \r
+ return UHCIControlTransfer(\r
+ &HcDev->UsbHc, \r
+ DeviceAddress, \r
+ IsSlowDevice, \r
+ (UINT8) MaximumPacketLength, \r
+ Request, \r
+ TransferDirection, \r
+ Data, \r
+ DataLength,\r
+ TimeOut,\r
+ TransferResult\r
+ ); \r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2BulkTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ ) \r
+/*++\r
+ \r
+ Routine Description:\r
+ Submits bulk transfer to a bulk endpoint of a USB device according to UEFI 2.0 spec.\r
+ \r
+ Arguments:\r
+ \r
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ \r
+ DeviceAddress Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ \r
+ EndPointAddress The combination of an endpoint number and an \r
+ endpoint direction of the target USB device. \r
+ Each endpoint address supports data transfer in \r
+ one direction except the control endpoint \r
+ (whose default endpoint address is 0). \r
+ It is the caller's responsibility to make sure that \r
+ the EndPointAddress represents a bulk endpoint. \r
+ \r
+ DeviceSpeed Indicates device speed. The supported values are EFI_USB_SPEED_FULL\r
+ and EFI_USB_SPEED_HIGH.\r
+ \r
+ MaximumPacketLength Indicates the maximum packet size the target endpoint\r
+ is capable of sending or receiving.\r
+ \r
+ DataBuffersNumber Number of data buffers prepared for the transfer.\r
+ \r
+ Data Array of pointers to the buffers of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ \r
+ DataLength When input, indicates the size, in bytes, of the data buffer\r
+ specified by Data. When output, indicates the actually \r
+ transferred data size.\r
+ \r
+ DataToggle A pointer to the data toggle value. On input, it indicates \r
+ the initial data toggle value the bulk transfer should adopt;\r
+ on output, it is updated to indicate the data toggle value \r
+ of the subsequent bulk transfer. \r
+ \r
+ Translator A pointr to the transaction translator data.\r
+ \r
+ TimeOut Indicates the maximum time, in microseconds, which the \r
+ transfer is allowed to complete.\r
+ \r
+ TransferResult A pointer to the detailed result information of the \r
+ bulk transfer.\r
+\r
+ Returns:\r
+ EFI_SUCCESS \r
+ The bulk transfer was completed successfully.\r
+ \r
+ EFI_OUT_OF_RESOURCES \r
+ The bulk transfer could not be submitted due to lack of resource.\r
+ \r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ \r
+ EFI_TIMEOUT \r
+ The bulk transfer failed due to timeout.\r
+ \r
+ EFI_DEVICE_ERROR \r
+ The bulk transfer failed due to host controller or device error.\r
+ Caller should check TranferResult for detailed error information.\r
+\r
+--*/ \r
+{\r
+ USB_HC_DEV *HcDev;\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ \r
+ if( Data == NULL || DeviceSpeed==EFI_USB_SPEED_LOW)\r
+ return EFI_INVALID_PARAMETER;\r
+ /* For full-speed bulk transfers only the data pointed by Data[0] shall be used */\r
+\r
+ return UHCIBulkTransfer (\r
+ &HcDev->UsbHc, \r
+ DeviceAddress, \r
+ EndPointAddress, \r
+ (UINT8) MaximumPacketLength, \r
+ *Data, \r
+ DataLength, \r
+ DataToggle, \r
+ TimeOut, \r
+ TransferResult\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2AsyncInterruptTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN BOOLEAN IsNewTransfer,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN PollingInterval,\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Submits an asynchronous interrupt transfer to an \r
+ interrupt endpoint of a USB device according to UEFI 2.0 spec.\r
+ \r
+ Arguments:\r
+ \r
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ \r
+ DeviceAddress Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ \r
+ EndPointAddress The combination of an endpoint number and an endpoint \r
+ direction of the target USB device. Each endpoint address \r
+ supports data transfer in one direction except the \r
+ control endpoint (whose default endpoint address is 0). \r
+ It is the caller's responsibility to make sure that \r
+ the EndPointAddress represents an interrupt endpoint.\r
+ \r
+ DeviceSpeed Indicates device speed.\r
+ \r
+ MaximumPacketLength Indicates the maximum packet size the target endpoint\r
+ is capable of sending or receiving.\r
+ \r
+ IsNewTransfer If TRUE, an asynchronous interrupt pipe is built between\r
+ the host and the target interrupt endpoint. \r
+ If FALSE, the specified asynchronous interrupt pipe \r
+ is canceled.\r
+ \r
+ DataToggle A pointer to the data toggle value. On input, it is valid \r
+ when IsNewTransfer is TRUE, and it indicates the initial \r
+ data toggle value the asynchronous interrupt transfer \r
+ should adopt. \r
+ On output, it is valid when IsNewTransfer is FALSE, \r
+ and it is updated to indicate the data toggle value of \r
+ the subsequent asynchronous interrupt transfer.\r
+ \r
+ PollingInterval Indicates the interval, in milliseconds, that the \r
+ asynchronous interrupt transfer is polled. \r
+ This parameter is required when IsNewTransfer is TRUE.\r
+ \r
+ DataLength Indicates the length of data to be received at the \r
+ rate specified by PollingInterval from the target \r
+ asynchronous interrupt endpoint. This parameter \r
+ is only required when IsNewTransfer is TRUE.\r
+ \r
+ Translator A pointr to the transaction translator data.\r
+ \r
+ CallBackFunction The Callback function.This function is called at the \r
+ rate specified by PollingInterval.This parameter is \r
+ only required when IsNewTransfer is TRUE.\r
+ \r
+ Context The context that is passed to the CallBackFunction.\r
+ This is an optional parameter and may be NULL.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The asynchronous interrupt transfer request has been successfully \r
+ submitted or canceled.\r
+ \r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ \r
+ EFI_OUT_OF_RESOURCES \r
+ The request could not be completed due to a lack of resources. \r
+ \r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+--*/ \r
+{\r
+ USB_HC_DEV *HcDev;\r
+ BOOLEAN IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+ \r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ return UHCIAsyncInterruptTransfer(\r
+ &HcDev->UsbHc, \r
+ DeviceAddress, \r
+ EndPointAddress, \r
+ IsSlowDevice, \r
+ (UINT8) MaximumPacketLength, \r
+ IsNewTransfer, \r
+ DataToggle, \r
+ PollingInterval,\r
+ DataLength, \r
+ CallBackFunction,\r
+ Context\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SyncInterruptTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Submits synchronous interrupt transfer to an interrupt endpoint \r
+ of a USB device according to UEFI 2.0 spec.\r
+ \r
+ Arguments:\r
+ \r
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ \r
+ DeviceAddress Represents the address of the target device on the USB, \r
+ which is assigned during USB enumeration.\r
+ \r
+ EndPointAddress The combination of an endpoint number and an endpoint \r
+ direction of the target USB device. Each endpoint \r
+ address supports data transfer in one direction \r
+ except the control endpoint (whose default \r
+ endpoint address is 0). It is the caller's responsibility\r
+ to make sure that the EndPointAddress represents \r
+ an interrupt endpoint. \r
+ \r
+ DeviceSpeed Indicates device speed.\r
+ \r
+ MaximumPacketLength Indicates the maximum packet size the target endpoint \r
+ is capable of sending or receiving.\r
+ \r
+ Data A pointer to the buffer of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ \r
+ DataLength On input, the size, in bytes, of the data buffer specified \r
+ by Data. On output, the number of bytes transferred.\r
+ \r
+ DataToggle A pointer to the data toggle value. On input, it indicates\r
+ the initial data toggle value the synchronous interrupt \r
+ transfer should adopt; \r
+ on output, it is updated to indicate the data toggle value \r
+ of the subsequent synchronous interrupt transfer. \r
+ \r
+ TimeOut Indicates the maximum time, in microseconds, which the \r
+ transfer is allowed to complete.\r
+ Translator A pointr to the transaction translator data.\r
+ TransferResult A pointer to the detailed result information from \r
+ the synchronous interrupt transfer. \r
+\r
+ Returns:\r
+ EFI_SUCCESS \r
+ The synchronous interrupt transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The synchronous interrupt transfer could not be submitted due \r
+ to lack of resource.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The synchronous interrupt transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The synchronous interrupt transfer failed due to host controller \r
+ or device error. Caller should check TranferResult for detailed \r
+ error information. \r
+--*/ \r
+{\r
+ USB_HC_DEV *HcDev;\r
+ BOOLEAN IsSlowDevice;\r
+ \r
+ if(DeviceSpeed==EFI_USB_SPEED_HIGH)\r
+ return EFI_INVALID_PARAMETER;\r
+ \r
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE; \r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ \r
+ return UHCISyncInterruptTransfer(\r
+ &HcDev->UsbHc, \r
+ DeviceAddress, \r
+ EndPointAddress, \r
+ IsSlowDevice, \r
+ (UINT8) MaximumPacketLength, \r
+ Data, \r
+ DataLength, \r
+ DataToggle,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2IsochronousTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.\r
+ \r
+ Arguments:\r
+ \r
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ \r
+ DeviceAddress Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ \r
+ EndPointAddress End point address\r
+ \r
+ DeviceSpeed Indicates device speed.\r
+ \r
+ MaximumPacketLength Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ \r
+ DataBuffersNumber Number of data buffers prepared for the transfer.\r
+ \r
+ Data Array of pointers to the buffers of data that will be \r
+ transmitted to USB device or received from USB device.\r
+ \r
+ DataLength Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ \r
+ Translator A pointr to the transaction translator data.\r
+ \r
+ TransferResult A pointer to the detailed result information generated \r
+ by this control transfer. \r
+ Returns:\r
+ \r
+ EFI_UNSUPPORTED \r
+\r
+--*/ \r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2AsyncIsochronousTransfer (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.\r
+ \r
+ Arguments:\r
+ \r
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ \r
+ DeviceAddress Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+\r
+ EndPointAddress End point address\r
+ \r
+ DeviceSpeed Indicates device speed.\r
+ \r
+ MaximumPacketLength Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ \r
+ DataBuffersNumber Number of data buffers prepared for the transfer.\r
+ \r
+ Data Array of pointers to the buffers of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ \r
+ Translator A pointr to the transaction translator data.\r
+ \r
+ IsochronousCallBack When the transfer complete, the call back function will be called\r
+ \r
+ Context Pass to the call back function as parameter\r
+ \r
+ Returns:\r
+ \r
+ EFI_UNSUPPORTED \r
+\r
+--*/ \r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2GetRootHubPortStatus (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 PortNumber,\r
+ OUT EFI_USB_PORT_STATUS * PortStatus\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.\r
+ \r
+ Arguments:\r
+ \r
+ This A pointer to the EFI_USB2_HC_PROTOCOL.\r
+ \r
+ PortNumber Specifies the root hub port from which the status \r
+ is to be retrieved. This value is zero-based. For example, \r
+ if a root hub has two ports, then the first port is numbered 0,\r
+ and the second port is numbered 1.\r
+ \r
+ PortStatus A pointer to the current port status bits and \r
+ port status change bits. \r
+ \r
+ Returns:\r
+ EFI_SUCCESS \r
+ The status of the USB root hub port specified by PortNumber \r
+ was returned in PortStatus.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid. \r
+ EFI_DEVICE_ERROR - Can't read register \r
+--*/ \r
+{\r
+ USB_HC_DEV *HcDev;\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ \r
+ return UHCIGetRootHubPortStatus(\r
+ &HcDev->UsbHc, \r
+ PortNumber, \r
+ PortStatus\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2SetRootHubPortFeature (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Sets a feature for the specified root hub port according to UEFI 2.0 spec.\r
+ \r
+ Arguments:\r
+ \r
+ This A pointer to the EFI_USB2_HC_PROTOCOL.\r
+ \r
+ PortNumber Specifies the root hub port whose feature \r
+ is requested to be set.\r
+ \r
+ PortFeature Indicates the feature selector associated \r
+ with the feature set request. \r
+ \r
+ Returns:\r
+ EFI_SUCCESS \r
+ The feature specified by PortFeature was set for the \r
+ USB root hub port specified by PortNumber.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid or PortFeature is invalid.\r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+--*/ \r
+{\r
+ USB_HC_DEV *HcDev;\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ return UHCISetRootHubPortFeature(\r
+ &HcDev->UsbHc, \r
+ PortNumber, \r
+ PortFeature\r
+ );\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UHCI2ClearRootHubPortFeature (\r
+ IN EFI_USB2_HC_PROTOCOL * This,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Clears a feature for the specified root hub port according to Uefi 2.0 spec.\r
+ \r
+ Arguments:\r
+ \r
+ This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ \r
+ PortNumber Specifies the root hub port whose feature \r
+ is requested to be cleared.\r
+ \r
+ PortFeature Indicates the feature selector associated with the \r
+ feature clear request.\r
+ \r
+ Returns:\r
+ EFI_SUCCESS \r
+ The feature specified by PortFeature was cleared for the \r
+ USB root hub port specified by PortNumber.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid or PortFeature is invalid.\r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+--*/ \r
+{\r
+ USB_HC_DEV *HcDev;\r
+\r
+ HcDev = USB2_HC_DEV_FROM_THIS (This);\r
+ return UHCIClearRootHubPortFeature(\r
+ &HcDev->UsbHc, \r
+ PortNumber, \r
+ PortFeature\r
+ );\r
+}\r
+\r
VOID\r
EFIAPI\r
MonitorInterruptTrans (\r
\r
#include <IndustryStandard/pci22.h>\r
\r
-#define EFI_D_UHCI EFI_D_INFO\r
+#define EFI_D_UHCI EFI_D_INFO\r
\r
//\r
// stall time\r
//\r
// 50 ms\r
//\r
-#define INTERRUPT_POLLING_TIME 50 * 1000 * 10\r
+#define INTERRUPT_POLLING_TIME 50 * 1000 * 10\r
\r
//\r
// UHCI IO Space Address Register Register locates at\r
// offset 20 ~ 23h of PCI Configuration Space (UHCI spec, Revision 1.1),\r
// so, its BAR Index is 4.\r
//\r
-#define USB_BAR_INDEX 4\r
+#define USB_BAR_INDEX 4\r
\r
//\r
// One memory block uses 1 page (common buffer for QH,TD use.)\r
//\r
#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 1\r
\r
-\r
#define bit(a) 1 << (a)\r
\r
//\r
#define USBCMD_MAXP bit (7) /* Max Packet (0 = 32, 1 = 64) */\r
\r
/* Status register */\r
-#define USBSTS 2 /* Status Register Offset 02-03h */\r
-#define USBSTS_USBINT bit (0) /* Interrupt due to IOC */\r
-#define USBSTS_ERROR bit (1) /* Interrupt due to error */\r
-#define USBSTS_RD bit (2) /* Resume Detect */\r
-#define USBSTS_HSE bit (3) /* Host System Error*/\r
-#define USBSTS_HCPE bit (4) /* Host Controller Process Error*/\r
-#define USBSTS_HCH bit (5) /* HC Halted */\r
+#define USBSTS 2 /* Status Register Offset 02-03h */\r
+#define USBSTS_USBINT bit (0) /* Interrupt due to IOC */\r
+#define USBSTS_ERROR bit (1) /* Interrupt due to error */\r
+#define USBSTS_RD bit (2) /* Resume Detect */\r
+#define USBSTS_HSE bit (3) /* Host System Error*/\r
+#define USBSTS_HCPE bit (4) /* Host Controller Process Error*/\r
+#define USBSTS_HCH bit (5) /* HC Halted */\r
\r
/* Interrupt enable register */\r
#define USBINTR 4 /* Interrupt Enable Register 04-05h */\r
#define USBINTR_SP bit (3) /* Short packet interrupt enable */\r
\r
/* Frame Number Register Offset 06-08h */\r
-#define USBFRNUM 6\r
+#define USBFRNUM 6\r
\r
/* Frame List Base Address Register Offset 08-0Bh */\r
-#define USBFLBASEADD 8\r
+#define USBFLBASEADD 8\r
\r
/* Start of Frame Modify Register Offset 0Ch */\r
-#define USBSOF 0x0c\r
+#define USBSOF 0x0c\r
\r
/* USB port status and control registers */\r
#define USBPORTSC1 0x10 /*Port 1 offset 10-11h */\r
//\r
// Class Code Register offset\r
//\r
-#define CLASSC 0x09\r
+#define CLASSC 0x09\r
//\r
// USB IO Space Base Address Register offset\r
//\r
-#define USBBASE 0x20\r
+#define USBBASE 0x20\r
\r
//\r
// USB legacy Support\r
//\r
-#define USB_EMULATION 0xc0\r
+#define USB_EMULATION 0xc0\r
\r
//\r
// USB Base Class Code,Sub-Class Code and Programming Interface.\r
//\r
//////////////////////////////////////////////////////////////////////////\r
#define USB_HC_DEV_FROM_THIS(a) CR (a, USB_HC_DEV, UsbHc, USB_HC_DEV_SIGNATURE)\r
+#define USB2_HC_DEV_FROM_THIS(a) CR (a, USB_HC_DEV, Usb2Hc, USB_HC_DEV_SIGNATURE)\r
\r
#define USB_HC_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'h', 'c', 'i')\r
#define INTERRUPT_LIST_SIGNATURE EFI_SIGNATURE_32 ('i', 'n', 't', 's')\r
typedef struct {\r
UINTN Signature;\r
EFI_USB_HC_PROTOCOL UsbHc;\r
+ EFI_USB2_HC_PROTOCOL Usb2Hc;\r
EFI_PCI_IO_PROTOCOL *PciIo;\r
\r
//\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 CmdAddrOffset,\r
IN UINT16 UsbCmd\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Write UHCI Command Register\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ CmdAddrOffset - Command address offset\r
+ UsbCmd - Data to write\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
ReadUHCCommandReg (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 CmdAddrOffset,\r
IN OUT UINT16 *Data\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read UHCI Command Register\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ CmdAddrOffset - Command address offset\r
+ Data - Data to return\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
WriteUHCStatusReg (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 StatusAddrOffset,\r
IN UINT16 UsbSts\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Write UHCI Staus Register\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ StatusAddrOffset - Status address offset\r
+ UsbSts - Data to write\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
ReadUHCStatusReg (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 StatusAddrOffset,\r
IN OUT UINT16 *Data\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read UHCI Staus Register\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ StatusAddrOffset - Status address offset\r
+ UsbSts - Data to return\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
ClearStatusReg (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 StatusAddrOffset\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Clear the content of UHC's Status Register\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ StatusAddrOffset - Status address offset\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
ReadUHCFrameNumberReg (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 FrameNumAddrOffset,\r
IN OUT UINT16 *Data\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read from UHC's Frame Number Register\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ FrameNumAddrOffset - Frame number register offset\r
+ Data - Data to return \r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
WriteUHCFrameListBaseReg (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 FlBaseAddrOffset,\r
IN UINT32 UsbFrameListBaseAddr\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Write to UHC's Frame List Base Register\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ FlBaseAddrOffset - Frame Base address register\r
+ UsbFrameListBaseAddr - Address to write\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
ReadRootPortReg (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 PortAddrOffset,\r
IN OUT UINT16 *Data\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Read from UHC's Root Port Register\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ PortAddrOffset - Port Addrress Offset,\r
+ Data - Data to return\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
WriteRootPortReg (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 PortAddrOffset,\r
IN UINT16 ControlBits\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Write to UHC's Root Port Register\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ PortAddrOffset - Port Addrress Offset,\r
+ ControlBits - Data to write\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
WaitForUHCHalt (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 StatusRegAddr,\r
IN UINTN Timeout\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Wait until UHCI halt or timeout\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ StatusRegAddr - Status Register Address\r
+ Timeout - Time out value in us\r
+\r
+Returns:\r
+\r
+ EFI_DEVICE_ERROR - Unable to read the status register\r
+ EFI_TIMEOUT - Time out\r
+ EFI_SUCCESS - Success\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
IsStatusOK (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 StatusRegAddr\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Judge whether the host controller operates well\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ StatusRegAddr - Status register address\r
+\r
+Returns:\r
+\r
+ TRUE - Status is good\r
+ FALSE - Status is bad\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
IsHostSysOrProcessErr (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 StatusRegAddr\r
- );\r
+ )\r
+/*++\r
\r
-//\r
-// This routine programs the USB frame number register. We assume that the\r
-// HC schedule execution is stopped.\r
-//\r
-EFI_STATUS\r
-SetFrameNumberReg (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT32 FRNUMAddr,\r
- IN UINT16 Index\r
- );\r
+Routine Description:\r
+\r
+ Judge the status is HostSys,ProcessErr error or good\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ StatusRegAddr - Status register address\r
+\r
+Returns:\r
+\r
+ TRUE - Status is good\r
+ FALSE - Status is bad\r
+\r
+--*/\r
+;\r
\r
UINT16\r
GetCurrentFrameNumber (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT32 FRNUMAddr\r
- );\r
+ IN UINT32 FrameNumAddrOffset\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get Current Frame Number\r
+\r
+Arguments:\r
+\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ FrameNumAddrOffset - FrameNum register AddrOffset\r
+\r
+Returns:\r
+\r
+ Frame number \r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
SetFrameListBaseAddress (\r
IN EFI_PCI_IO_PROTOCOL *PciIo,\r
IN UINT32 FLBASEADDRReg,\r
IN UINT32 Addr\r
- );\r
-\r
-UINT32\r
-GetFrameListBaseAddress (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT32 FLBAddr\r
- );\r
+ )\r
+/*++\r
\r
-EFI_STATUS\r
-CreateFrameList (\r
- IN USB_HC_DEV *HcDev,\r
- IN UINT32 FLBASEADDRReg\r
- );\r
+Routine Description:\r
\r
-EFI_STATUS\r
-FreeFrameListEntry (\r
- IN USB_HC_DEV *UhcDev\r
- );\r
+ Set FrameListBase Address\r
\r
-VOID\r
-InitFrameList (\r
- IN USB_HC_DEV *HcDev\r
- );\r
+Arguments:\r
\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ FlBaseAddrReg - FrameListBase register\r
+ Addr - Address to set\r
\r
-EFI_STATUS\r
-CreateQH (\r
- IN USB_HC_DEV *HcDev,\r
- OUT QH_STRUCT **pptrQH\r
- );\r
+Returns:\r
\r
-VOID\r
-SetQHHorizontalLinkPtr (\r
- IN QH_STRUCT *ptrQH,\r
- IN VOID *ptrNext\r
- );\r
+ EFI_SUCCESS\r
\r
-VOID *\r
-GetQHHorizontalLinkPtr (\r
- IN QH_STRUCT *ptrQH\r
- );\r
+--*/\r
+;\r
\r
-VOID\r
-SetQHHorizontalQHorTDSelect (\r
- IN QH_STRUCT *ptrQH,\r
- IN BOOLEAN bQH\r
- );\r
+UINT32\r
+GetFrameListBaseAddress (\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN UINT32 FLBAddr\r
+ )\r
+/*++\r
\r
-VOID\r
-SetQHHorizontalValidorInvalid (\r
- IN QH_STRUCT *ptrQH,\r
- IN BOOLEAN bValid\r
- );\r
+Routine Description:\r
\r
-VOID\r
-SetQHVerticalLinkPtr (\r
- IN QH_STRUCT *ptrQH,\r
- IN VOID *ptrNext\r
- );\r
+ Get Current Frame Number\r
\r
-VOID * \r
-GetQHVerticalLinkPtr (\r
- IN QH_STRUCT *ptrQH\r
- );\r
+Arguments:\r
\r
-VOID\r
-SetQHVerticalQHorTDSelect (\r
- IN QH_STRUCT *ptrQH,\r
- IN BOOLEAN bQH\r
- );\r
+ PciIo - EFI_PCI_IO_PROTOCOL\r
+ FrameNumAddrOffset - FrameNum register AddrOffset\r
\r
-BOOLEAN\r
-IsQHHorizontalQHSelect (\r
- IN QH_STRUCT *ptrQH\r
- );\r
+Returns:\r
\r
-VOID\r
-SetQHVerticalValidorInvalid (\r
- IN QH_STRUCT *ptrQH,\r
- IN BOOLEAN bValid\r
- );\r
+ Frame number \r
\r
-BOOLEAN\r
-GetQHVerticalValidorInvalid (\r
- IN QH_STRUCT *ptrQH\r
- );\r
+--*/\r
+;\r
\r
EFI_STATUS\r
-AllocateTDStruct (\r
- IN USB_HC_DEV *HcDev,\r
- OUT TD_STRUCT **ppTDStruct\r
- );\r
+CreateFrameList (\r
+ IN USB_HC_DEV *HcDev,\r
+ IN UINT32 FLBASEADDRReg\r
+ )\r
/*++\r
\r
Routine Description:\r
\r
- Allocate TD Struct\r
+ CreateFrameList\r
\r
Arguments:\r
\r
- HcDev - USB_HC_DEV\r
- ppTDStruct - place to store TD_STRUCT pointer\r
+ HcDev - USB_HC_DEV\r
+ FlBaseAddrReg - Frame List register\r
+\r
Returns:\r
\r
- EFI_SUCCESS\r
+ EFI_OUT_OF_RESOURCES - Can't allocate memory resources\r
+ EFI_UNSUPPORTED - Map memory fail\r
+ EFI_SUCCESS - Success\r
\r
--*/\r
+;\r
\r
EFI_STATUS\r
-CreateTD (\r
- IN USB_HC_DEV *HcDev,\r
- OUT TD_STRUCT **pptrTD\r
- );\r
+FreeFrameListEntry (\r
+ IN USB_HC_DEV *UhcDev\r
+ )\r
/*++\r
\r
Routine Description:\r
\r
- Create TD\r
+ Free FrameList buffer\r
\r
Arguments:\r
\r
- HcDev - USB_HC_DEV\r
- pptrTD - TD_STRUCT pointer to store\r
+ HcDev - USB_HC_DEV\r
\r
Returns:\r
\r
- EFI_OUT_OF_RESOURCES - Can't allocate resources\r
- EFI_SUCCESS - Success\r
+ EFI_SUCCESS - success\r
\r
--*/\r
+;\r
+\r
+VOID\r
+InitFrameList (\r
+ IN USB_HC_DEV *HcDev\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize FrameList\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+\r
+Returns:\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateQH (\r
+ IN USB_HC_DEV *HcDev,\r
+ OUT QH_STRUCT **pptrQH\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ CreateQH\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ pptrQH - QH_STRUCT content to return\r
+Returns:\r
+\r
+ EFI_SUCCESS - Success\r
+ EFI_OUT_OF_RESOURCES - Can't allocate memory\r
+ \r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHHorizontalLinkPtr (\r
+ IN QH_STRUCT *ptrQH,\r
+ IN VOID *ptrNext\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set QH Horizontal Link Pointer\r
+\r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+ ptrNext - Data to write \r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID *\r
+GetQHHorizontalLinkPtr (\r
+ IN QH_STRUCT *ptrQH\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get QH Horizontal Link Pointer\r
+\r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+ \r
+\r
+Returns:\r
+\r
+ Data to return \r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHHorizontalQHorTDSelect (\r
+ IN QH_STRUCT *ptrQH,\r
+ IN BOOLEAN bQH\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set QH Horizontal QH or TD \r
+\r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+ bQH - TRUE is QH FALSE is TD\r
+\r
+Returns:\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHHorizontalValidorInvalid (\r
+ IN QH_STRUCT *ptrQH,\r
+ IN BOOLEAN bValid\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set QH Horizontal Valid or Invalid\r
+\r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+ bValid - TRUE is Valid FALSE is Invalid\r
+\r
+Returns:\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHVerticalLinkPtr (\r
+ IN QH_STRUCT *ptrQH,\r
+ IN VOID *ptrNext\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set QH Vertical Link Pointer\r
+ \r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+ ptrNext - Data to write\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID *\r
+GetQHVerticalLinkPtr (\r
+ IN QH_STRUCT *ptrQH\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get QH Vertical Link Pointer\r
+ \r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+ \r
+Returns:\r
+\r
+ Data to return\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHVerticalQHorTDSelect (\r
+ IN QH_STRUCT *ptrQH,\r
+ IN BOOLEAN bQH\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set QH Vertical QH or TD\r
+\r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+ bQH - TRUE is QH FALSE is TD\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsQHHorizontalQHSelect (\r
+ IN QH_STRUCT *ptrQH\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Is QH Horizontal QH Select\r
+\r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+ \r
+Returns:\r
+\r
+ TRUE - QH\r
+ FALSE - TD\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetQHVerticalValidorInvalid (\r
+ IN QH_STRUCT *ptrQH,\r
+ IN BOOLEAN bValid\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set QH Vertical Valid or Invalid\r
+\r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+ IsValid - TRUE is valid FALSE is invalid\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+GetQHVerticalValidorInvalid (\r
+ IN QH_STRUCT *ptrQH\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get QH Vertical Valid or Invalid\r
+\r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+\r
+Returns:\r
+\r
+ TRUE - Valid\r
+ FALSE - Invalid\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+AllocateTDStruct (\r
+ IN USB_HC_DEV *HcDev,\r
+ OUT TD_STRUCT **ppTDStruct\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Allocate TD Struct\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ ppTDStruct - place to store TD_STRUCT pointer\r
+Returns:\r
+\r
+ EFI_SUCCESS\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+CreateTD (\r
+ IN USB_HC_DEV *HcDev,\r
+ OUT TD_STRUCT **pptrTD\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Create TD\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ pptrTD - TD_STRUCT pointer to store\r
+\r
+Returns:\r
+\r
+ EFI_OUT_OF_RESOURCES - Can't allocate resources\r
+ EFI_SUCCESS - Success\r
+\r
+--*/\r
+;\r
\r
\r
EFI_STATUS\r
IN UINT8 *pDevReq,\r
IN UINT8 RequestLen,\r
OUT TD_STRUCT **ppTD\r
- );\r
+ )\r
/*++\r
\r
Routine Description:\r
EFI_SUCCESS - Success\r
\r
--*/\r
+;\r
\r
EFI_STATUS\r
GenDataTD (\r
IN UINT8 Toggle,\r
IN BOOLEAN bSlow,\r
OUT TD_STRUCT **ppTD\r
- );\r
+ )\r
/*++\r
\r
Routine Description:\r
EFI_SUCCESS - Success\r
\r
--*/\r
+;\r
\r
EFI_STATUS\r
CreateStatusTD (\r
IN UINT8 PktID,\r
IN BOOLEAN bSlow,\r
OUT TD_STRUCT **ppTD\r
- );\r
+ )\r
/*++\r
\r
Routine Description:\r
EFI_SUCCESS - Success\r
\r
--*/\r
+;\r
\r
VOID\r
SetTDLinkPtrValidorInvalid (\r
IN TD_STRUCT *ptrTDStruct,\r
IN BOOLEAN bValid\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD Link Pointer Valid or Invalid\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - TD_STRUCT\r
+ bValid - TRUE is valid FALSE is invalid\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDLinkPtrQHorTDSelect (\r
IN TD_STRUCT *ptrTDStruct,\r
IN BOOLEAN bQH\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD Link Pointer QH or TD Select\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - TD_STRUCT\r
+ bQH - TRUE is QH FALSE is TD\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDLinkPtrDepthorBreadth (\r
IN TD_STRUCT *ptrTDStruct,\r
IN BOOLEAN bDepth\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD Link Pointer depth or bread priority\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - TD_STRUCT\r
+ bDepth - TRUE is Depth FALSE is Breadth\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDLinkPtr (\r
IN TD_STRUCT *ptrTDStruct,\r
IN VOID *ptrNext\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD Link Pointer\r
\r
-VOID *\r
+Arguments:\r
+\r
+ ptrTDStruct - TD_STRUCT\r
+ ptrNext - Pointer to set\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID *\r
GetTDLinkPtr (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get TD Link Pointer\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - TD_STRUCT\r
+ \r
+Returns:\r
+\r
+ Pointer to get\r
+\r
+--*/\r
+;\r
\r
VOID\r
EnableorDisableTDShortPacket (\r
IN TD_STRUCT *ptrTDStruct,\r
IN BOOLEAN bEnable\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Enable or Disable TD ShortPacket\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - TD_STRUCT\r
+ bEnable - TRUE is Enanble FALSE is Disable\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDControlErrorCounter (\r
IN TD_STRUCT *ptrTDStruct,\r
IN UINT8 nMaxErrors\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD Control ErrorCounter\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - TD_STRUCT\r
+ nMaxErrors - Error counter number\r
+ \r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDLoworFullSpeedDevice (\r
IN TD_STRUCT *ptrTDStruct,\r
IN BOOLEAN bLowSpeedDevice\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD status low speed or full speed\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+ bLowSpeedDevice - Show low speed or full speed\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDControlIsochronousorNot (\r
IN TD_STRUCT *ptrTDStruct,\r
IN BOOLEAN bIsochronous\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD status Isochronous or not\r
+ \r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+ IsIsochronous - Show Isochronous or not\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetorClearTDControlIOC (\r
IN TD_STRUCT *ptrTDStruct,\r
IN BOOLEAN bSet\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD status IOC IsSet\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+ IsSet - Show IOC set or not\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDStatusActiveorInactive (\r
IN TD_STRUCT *ptrTDStruct,\r
IN BOOLEAN bActive\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD status active or not\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+ IsActive - Active or not\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
UINT16\r
SetTDTokenMaxLength (\r
IN TD_STRUCT *ptrTDStruct,\r
IN UINT16 nMaxLen\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD Token maxlength\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+ MaximumLength - Maximum length of TD Token\r
+\r
+Returns:\r
+\r
+ Real maximum length set to TD Token\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDTokenDataToggle1 (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD Token data toggle1\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDTokenDataToggle0 (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD Token data toggle0\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
UINT8\r
GetTDTokenDataToggle (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get TD Token data toggle\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ data toggle value\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDTokenEndPoint (\r
IN TD_STRUCT *ptrTDStruct,\r
IN UINTN nEndPoint\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set Data Token endpoint number\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+ EndPoint - End point number\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDTokenDeviceAddress (\r
IN TD_STRUCT *ptrTDStruct,\r
IN UINTN nDevAddr\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD Token device address\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+ DeviceAddress - Device address\r
+\r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+;\r
\r
VOID\r
SetTDTokenPacketID (\r
IN TD_STRUCT *ptrTDStruct,\r
IN UINT8 nPID\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD Token packet ID\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+ PID - Packet ID\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetTDDataBuffer (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set TD data buffer\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
IsTDStatusActive (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Indicate whether TD status active or not\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ TRUE - Active\r
+ FALSE - Inactive \r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
IsTDStatusStalled (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Indicate whether TD status stalled or not\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ TRUE - Stalled\r
+ FALSE - not stalled\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
IsTDStatusBufferError (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Indicate whether TD status buffer error or not\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ TRUE - Buffer error\r
+ FALSE - No error\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
IsTDStatusBabbleError (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Indicate whether TD status babble error or not\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ TRUE - Babble error\r
+ FALSE - No error\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
IsTDStatusNAKReceived (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Indicate whether TD status NAK received\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ TRUE - NAK received\r
+ FALSE - NAK not received\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
IsTDStatusCRCTimeOutError (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Indicate whether TD status CRC timeout error or not\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+ \r
+Returns:\r
+\r
+ TRUE - CRC timeout error\r
+ FALSE - CRC timeout no error\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
IsTDStatusBitStuffError (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Indicate whether TD status bit stuff error or not\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ TRUE - Bit stuff error\r
+ FALSE - Bit stuff no error\r
+\r
+--*/\r
+;\r
\r
UINT16\r
GetTDStatusActualLength (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get TD status length\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ Return Td status length\r
+\r
+--*/\r
+;\r
\r
UINT16\r
GetTDTokenMaxLength (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get TD Token maximum length\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ Return TD token maximum length\r
+\r
+--*/\r
+;\r
\r
UINT8\r
GetTDTokenEndPoint (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get TD Token endpoint number\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ Return TD Token endpoint number\r
+\r
+--*/\r
+;\r
\r
UINT8\r
GetTDTokenDeviceAddress (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get TD Token device address\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ Return TD Token device address\r
+\r
+--*/\r
+;\r
\r
UINT8\r
GetTDTokenPacketID (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get TD Token packet ID\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
\r
-UINT8 *\r
+Returns:\r
+\r
+ Return TD Token packet ID\r
+\r
+--*/\r
+;\r
+\r
+UINT8 *\r
GetTDDataBuffer (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the point to TD data buffer\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ Return a point to TD data buffer\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
GetTDLinkPtrValidorInvalid (\r
IN TD_STRUCT *ptrTDStruct\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get TD LinkPtr valid or not\r
+\r
+Arguments:\r
+\r
+ ptrTDStruct - A point to TD_STRUCT\r
+\r
+Returns:\r
+\r
+ TRUE - Invalid\r
+ FALSE - Valid\r
+\r
+--*/\r
+;\r
\r
UINTN\r
CountTDsNumber (\r
IN TD_STRUCT *ptrFirstTD\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get the number of TDs\r
+\r
+Arguments:\r
+\r
+ PtrFirstTD - A point to the first TD_STRUCT\r
+\r
+Returns:\r
+\r
+ Return the number of TDs\r
+\r
+--*/\r
+;\r
\r
VOID\r
LinkTDToQH (\r
IN QH_STRUCT *ptrQH,\r
IN TD_STRUCT *ptrTD\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link TD To QH\r
+\r
+Arguments:\r
+\r
+ PtrQH - QH_STRUCT\r
+ PtrTD - TD_STRUCT\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
LinkTDToTD (\r
IN TD_STRUCT *ptrPreTD,\r
IN TD_STRUCT *ptrTD\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Link TD To TD\r
+\r
+Arguments:\r
+\r
+ ptrPreTD - Previous TD_STRUCT to be linked\r
+ PtrTD - TD_STRUCT to link\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetorClearCurFrameListTerminate (\r
IN FRAMELIST_ENTRY *pCurEntry,\r
IN BOOLEAN bSet\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set or clear current framelist terminate\r
+\r
+Arguments:\r
+\r
+ pCurEntry - A point to FRAMELIST_ENTITY\r
+ IsSet - TRUE to empty the frame and indicate the Pointer field is valid\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
+\r
+VOID\r
+SetCurFrameListQHorTD (\r
+ IN FRAMELIST_ENTRY *pCurEntry,\r
+ IN BOOLEAN bQH\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set current framelist QH or TD\r
+\r
+Arguments:\r
+\r
+ pCurEntry - A point to FRAMELIST_ENTITY\r
+ IsQH - TRUE to set QH and FALSE to set TD\r
+\r
+Returns:\r
\r
-VOID\r
-SetCurFrameListQHorTD (\r
- IN FRAMELIST_ENTRY *pCurEntry,\r
- IN BOOLEAN bQH\r
- );\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
GetCurFrameListTerminate (\r
IN FRAMELIST_ENTRY *pCurEntry\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get current framelist terminate\r
+\r
+Arguments:\r
+\r
+ pCurEntry - A point to FRAMELIST_ENTITY\r
+\r
+Returns:\r
+\r
+ TRUE - Terminate\r
+ FALSE - Not terminate\r
+\r
+--*/\r
+;\r
\r
VOID\r
SetCurFrameListPointer (\r
IN FRAMELIST_ENTRY *pCurEntry,\r
IN UINT8 *ptr\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set current framelist pointer\r
+\r
+Arguments:\r
+\r
+ pCurEntry - A point to FRAMELIST_ENTITY\r
+ ptr - A point to FrameListPtr point to\r
+\r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+;\r
\r
-VOID *\r
+VOID *\r
GetCurFrameListPointer (\r
IN FRAMELIST_ENTRY *pCurEntry\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Get current framelist pointer\r
+\r
+Arguments:\r
+\r
+ pCurEntry - A point to FRAMELIST_ENTITY\r
+\r
+Returns:\r
+\r
+ A point FrameListPtr point to\r
+\r
+--*/\r
+;\r
\r
VOID\r
LinkQHToFrameList (\r
IN FRAMELIST_ENTRY *pEntry,\r
IN UINT16 FrameListIndex,\r
IN QH_STRUCT *ptrQH\r
- );\r
+ )\r
/*++\r
\r
Routine Description:\r
VOID\r
\r
--*/\r
-VOID\r
-DeleteQHTDs (\r
- IN FRAMELIST_ENTRY *pEntry,\r
- IN QH_STRUCT *ptrQH,\r
- IN TD_STRUCT *ptrFirstTD,\r
- IN UINT16 FrameListIndex,\r
- IN BOOLEAN SearchOther\r
- );\r
+;\r
\r
VOID\r
DelLinkSingleQH (\r
IN UINT16 FrameListIndex,\r
IN BOOLEAN SearchOther,\r
IN BOOLEAN Delete\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Unlink from frame list and delete single QH\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ PtrQH - QH_STRUCT\r
+ FrameListIndex - Frame List Index\r
+ SearchOther - Search Other QH\r
+ Delete - TRUE is to delete the QH\r
+ \r
+Returns:\r
+\r
+ VOID\r
+ \r
+--*/\r
+;\r
\r
VOID\r
DeleteQueuedTDs (\r
IN USB_HC_DEV *HcDev,\r
IN TD_STRUCT *ptrFirstTD\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Delete Queued TDs\r
+ \r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ PtrFirstTD - TD link list head\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
InsertQHTDToINTList (\r
IN UINT8 *DataBuffer,\r
IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,\r
IN VOID *Context\r
- );\r
+ )\r
/*++\r
Routine Description:\r
+\r
Insert QH and TD To Interrupt List\r
+\r
Arguments:\r
\r
HcDev - USB_HC_DEV\r
DataBuffer - Data buffer\r
CallBackFunction- CallBackFunction after interrupt transfeer\r
Context - CallBackFunction Context passed as function parameter\r
+\r
Returns:\r
+\r
EFI_SUCCESS - Sucess\r
EFI_INVALID_PARAMETER - Paremeter is error \r
\r
--*/\r
+;\r
\r
EFI_STATUS\r
DeleteAsyncINTQHTDs (\r
IN UINT8 DeviceAddress,\r
IN UINT8 EndPointAddress,\r
OUT UINT8 *DataToggle\r
- );\r
+ )\r
/*++\r
Routine Description:\r
\r
Delete Async INT QH and TDs\r
+ \r
Arguments:\r
\r
HcDev - USB_HC_DEV\r
DataToggle - Data Toggle\r
\r
Returns:\r
+\r
EFI_SUCCESS - Sucess\r
EFI_INVALID_PARAMETER - Paremeter is error \r
\r
--*/\r
+;\r
+\r
BOOLEAN\r
CheckTDsResults (\r
IN TD_STRUCT *ptrTD,\r
OUT UINT32 *Result,\r
OUT UINTN *ErrTDPos,\r
OUT UINTN *ActualTransferSize\r
- );\r
+ )\r
/*++\r
\r
Routine Description:\r
FALSE - Fail\r
\r
--*/\r
+;\r
+\r
VOID\r
ExecuteAsyncINTTDs (\r
IN USB_HC_DEV *HcDev,\r
OUT UINT32 *Result,\r
OUT UINTN *ErrTDPos,\r
OUT UINTN *ActualLen\r
- ) ;\r
+ )\r
/*++\r
\r
Routine Description:\r
VOID\r
\r
--*/\r
+;\r
+\r
VOID\r
UpdateAsyncINTQHTDs (\r
IN INTERRUPT_LIST *ptrList,\r
IN UINT32 Result,\r
IN UINT32 ErrTDPos\r
- );\r
+ )\r
/*++\r
\r
Routine Description:\r
VOID\r
\r
--*/\r
+;\r
+\r
VOID\r
ReleaseInterruptList (\r
IN USB_HC_DEV *HcDev,\r
IN LIST_ENTRY *ListHead\r
- );\r
+ )\r
/*++\r
\r
Routine Description:\r
\r
Release Interrupt List\r
+ \r
Arguments:\r
\r
HcDev - USB_HC_DEV\r
VOID\r
\r
--*/\r
+;\r
+\r
EFI_STATUS\r
ExecuteControlTransfer (\r
IN USB_HC_DEV *HcDev,\r
OUT UINTN *ActualLen,\r
IN UINTN TimeOut,\r
OUT UINT32 *TransferResult\r
- );\r
+ )\r
/*++\r
\r
Routine Description:\r
\r
\r
--*/\r
+;\r
+\r
EFI_STATUS\r
ExecBulkorSyncInterruptTransfer (\r
IN USB_HC_DEV *HcDev,\r
OUT UINT8 *DataToggle,\r
IN UINTN TimeOut,\r
OUT UINT32 *TransferResult\r
- );\r
+ )\r
/*++\r
\r
Routine Description:\r
EFI_SUCCESS - Sucess\r
EFI_DEVICE_ERROR - Error\r
--*/\r
+;\r
\r
EFI_STATUS\r
InitializeMemoryManagement (\r
IN USB_HC_DEV *HcDev\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Initialize Memory Management\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - Success\r
+ \r
+--*/\r
+;\r
\r
EFI_STATUS\r
CreateMemoryBlock (\r
IN USB_HC_DEV *HcDev,\r
IN MEMORY_MANAGE_HEADER **MemoryHeader,\r
IN UINTN MemoryBlockSizeInPages\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Use PciIo->AllocateBuffer to allocate common buffer for the memory block,\r
+ and use PciIo->Map to map the common buffer for Bus Master Read/Write.\r
+\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ MemoryHeader - MEMORY_MANAGE_HEADER to output\r
+ MemoryBlockSizeInPages - MemoryBlockSizeInPages\r
+ \r
+Returns:\r
+\r
+ EFI_SUCCESS - Success\r
+ EFI_OUT_OF_RESOURCES - Out of resources\r
+ EFI_UNSUPPORTED - Unsupported\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
FreeMemoryHeader (\r
IN USB_HC_DEV *HcDev,\r
IN MEMORY_MANAGE_HEADER *MemoryHeader\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Free Memory Header\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ MemoryHeader - MemoryHeader to be freed\r
+\r
+Returns:\r
+\r
+ EFI_INVALID_PARAMETER - Parameter is error\r
+ EFI_SUCCESS - Success\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
UhciAllocatePool (\r
IN USB_HC_DEV *UhcDev,\r
IN UINT8 **Pool,\r
IN UINTN AllocSize\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Uhci Allocate Pool\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ Pool - Place to store pointer to the memory buffer\r
+ AllocSize - Alloc Size\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - Success\r
+\r
+--*/\r
+;\r
\r
VOID\r
UhciFreePool (\r
IN USB_HC_DEV *HcDev,\r
IN UINT8 *Pool,\r
IN UINTN AllocSize\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Uhci Free Pool\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+ Pool - Pool to free\r
+ AllocSize - Pool size\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
InsertMemoryHeaderToList (\r
IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
IN MEMORY_MANAGE_HEADER *NewMemoryHeader\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Insert Memory Header To List\r
+\r
+Arguments:\r
+\r
+ MemoryHeader - MEMORY_MANAGE_HEADER\r
+ NewMemoryHeader - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
AllocMemInMemoryBlock (\r
IN MEMORY_MANAGE_HEADER *MemoryHeader,\r
IN VOID **Pool,\r
IN UINTN NumberOfMemoryUnit\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Alloc Memory In MemoryBlock\r
+\r
+Arguments:\r
+\r
+ MemoryHeader - MEMORY_MANAGE_HEADER\r
+ Pool - Place to store pointer to memory\r
+ NumberOfMemoryUnit - Number Of Memory Unit\r
+\r
+Returns:\r
+\r
+ EFI_NOT_FOUND - Can't find the free memory \r
+ EFI_SUCCESS - Success\r
+\r
+--*/\r
+;\r
\r
BOOLEAN\r
IsMemoryBlockEmptied (\r
IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr\r
- );\r
+ )\r
+/*++\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Is Memory Block Emptied\r
+\r
+Arguments:\r
+\r
+ MemoryHeaderPtr - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+ TRUE - Empty\r
+ FALSE - Not Empty \r
+\r
+--*/\r
+;\r
\r
VOID\r
DelinkMemoryBlock (\r
IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,\r
IN MEMORY_MANAGE_HEADER *FreeMemoryHeader\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Delink Memory Block\r
+\r
+Arguments:\r
+\r
+ FirstMemoryHeader - MEMORY_MANAGE_HEADER\r
+ NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
DelMemoryManagement (\r
IN USB_HC_DEV *HcDev\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Delete Memory Management\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+\r
+Returns:\r
+\r
+ EFI_SUCCESS - Success\r
+\r
+--*/\r
+;\r
\r
VOID\r
EnableMaxPacketSize (\r
IN USB_HC_DEV *HcDev\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Enable Max Packet Size\r
+\r
+Arguments:\r
+\r
+ HcDev - USB_HC_DEV\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
CleanUsbTransactions (\r
IN USB_HC_DEV *HcDev\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Clean USB Transactions\r
+\r
+Arguments:\r
+\r
+ HcDev - A point to USB_HC_DEV\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
VOID\r
TurnOffUSBEmulation (\r
IN EFI_PCI_IO_PROTOCOL *PciIo\r
- );\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Set current framelist QH or TD\r
+\r
+Arguments:\r
+\r
+ pCurEntry - A point to FRAMELIST_ENTITY\r
+ IsQH - TRUE to set QH and FALSE to set TD\r
+\r
+Returns:\r
+\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
#endif\r
BufferPtr = (UINT8 *) DataBuffer;\r
TransferredSize = 0;\r
MaxRetry = 10;\r
- PackageNum = 15;\r
+ PackageNum = 128;\r
\r
//\r
// retrieve the the max packet length of the given endpoint\r
<Protocol Usage="BY_START">\r
<ProtocolCName>gEfiUsbIoProtocolGuid</ProtocolCName>\r
</Protocol>\r
- <Protocol Usage="TO_START">\r
+ <Protocol Usage="SOMETIMES_CONSUMED">\r
+ <ProtocolCName>gEfiUsb2HcProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="SOMETIMES_CONSUMED">\r
<ProtocolCName>gEfiUsbHcProtocolGuid</ProtocolCName>\r
</Protocol>\r
<Protocol Usage="TO_START">\r
\r
#include "usbbus.h"\r
\r
-//#ifdef EFI_DEBUG\r
-UINTN gUSBDebugLevel = EFI_D_ERROR;\r
+UINTN gUSBDebugLevel = EFI_D_INFO;\r
UINTN gUSBErrorLevel = EFI_D_ERROR;\r
-//#endif\r
+\r
//\r
// The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER\r
// structure in the UsbBusDriverControllerDriverStop(). Then we can\r
//\r
STATIC\r
VOID\r
-EFIAPI\r
-UsbEnumeration (\r
+RootHubEnumeration (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+STATIC\r
+VOID\r
+HubEnumeration (\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
);\r
\r
+STATIC\r
+EFI_STATUS\r
+UsbSetTransactionTranslator (\r
+ IN USB_IO_CONTROLLER_DEVICE *ParentHubController,\r
+ IN UINT8 ParentPort,\r
+ IN OUT USB_IO_DEVICE *Device\r
+ );\r
+\r
+STATIC\r
+EFI_STATUS\r
+UsbUnsetTransactionTranslator (\r
+ USB_IO_DEVICE *Device\r
+ );\r
+\r
+STATIC\r
+EFI_STATUS\r
+IdentifyDeviceSpeed (\r
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ USB_IO_DEVICE *NewDevice,\r
+ UINT8 Index\r
+ );\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReleasePortToCHC (\r
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ UINT8 PortNum\r
+ );\r
+\r
EFI_STATUS\r
ResetRootPort (\r
- IN EFI_USB_HC_PROTOCOL *UsbHCInterface,\r
- IN UINT8 PortNum,\r
- IN UINT8 RetryTimes\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNum,\r
+ IN UINT8 RetryTimes\r
);\r
\r
EFI_STATUS\r
IN UINT8 PortIndex\r
);\r
\r
-EFI_STATUS\r
-ClearRootPortConnectionChangeStatus (\r
- IN UINT8 PortNum,\r
- IN EFI_USB_HC_PROTOCOL *UsbHCInterface\r
- );\r
-\r
STATIC\r
EFI_STATUS\r
ParentPortReset (\r
UsbAllocateAddress (\r
IN UINT8 *AddressPool\r
)\r
+/*++\r
+\r
+ Routine Description:\r
+ Allocate address for usb device\r
+\r
+ Arguments:\r
+ AddressPool - Pool of usb device address\r
+\r
+ Returns:\r
+ Usb device address\r
+\r
+--*/\r
{\r
UINT8 ByteIndex;\r
UINT8 BitIndex;\r
IN UINT8 DevAddress,\r
IN UINT8 *AddressPool\r
)\r
+/*++\r
+\r
+ Routine Description:\r
+ Free address for usb device\r
+\r
+ Arguments:\r
+ DevAddress - Usb device address\r
+ AddressPool - Pool of usb device address\r
+ \r
+ Returns:\r
+ VOID\r
+\r
+--*/\r
{\r
UINT8 WhichByte;\r
UINT8 WhichBit;\r
\r
Arguments:\r
This - Protocol instance pointer.\r
- Controller - Handle of device to test\r
- RemainingDevicePath - Not used\r
+ Controller - Handle of device to test\r
+ RemainingDevicePath - Device Path Protocol instance pointer\r
\r
Returns:\r
EFI_SUCCESS - This driver supports this device.\r
\r
--*/\r
{\r
- EFI_STATUS OpenStatus;\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_USB2_HC_PROTOCOL *Usb2Hc;\r
+ EFI_USB_HC_PROTOCOL *UsbHc;\r
+ EFI_DEV_PATH_PTR Node;\r
+\r
+ //\r
+ // Check Device Path\r
+ //\r
+ if (RemainingDevicePath != NULL) {\r
+ Node.DevPath = RemainingDevicePath;\r
+ if (Node.DevPath->Type != MESSAGING_DEVICE_PATH ||\r
+ Node.DevPath->SubType != MSG_USB_DP ||\r
+ DevicePathNodeLength(Node.DevPath) != sizeof(USB_DEVICE_PATH)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Open the IO Abstraction(s) needed to perform the supported test\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ \r
//\r
// Check whether USB Host Controller Protocol is already\r
// installed on this handle. If it is installed, we can start\r
// USB Bus Driver now.\r
//\r
- OpenStatus = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- NULL,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
- );\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ (VOID **) &Usb2Hc,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ \r
+ if (EFI_ERROR (Status)) {\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ (VOID **) &UsbHc,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {\r
- return EFI_UNSUPPORTED;\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ return EFI_SUCCESS;\r
}\r
+ \r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
\r
- return OpenStatus;\r
+ return EFI_SUCCESS;\r
}\r
\r
-\r
EFI_STATUS\r
EFIAPI\r
UsbBusControllerDriverStart (\r
Returns:\r
\r
EFI_SUCCESS - This driver supports this device.\r
- EFI_UNSUPPORTED - This driver does not support this device.\r
EFI_DEVICE_ERROR - This driver cannot be started due to device\r
- Error\r
EFI_OUT_OF_RESOURCES- Can't allocate memory resources\r
- EFI_ALREADY_STARTED - This driver has been started\r
\r
--*/\r
{\r
USB_BUS_CONTROLLER_DEVICE *UsbBusDev;\r
USB_IO_DEVICE *RootHub;\r
USB_IO_CONTROLLER_DEVICE *RootHubController;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
+ UINT8 MaxSpeed;\r
+ UINT8 PortNumber;\r
+ UINT8 Is64BitCapable;\r
\r
//\r
// Allocate USB_BUS_CONTROLLER_DEVICE structure\r
\r
if (EFI_ERROR (OpenStatus)) {\r
gBS->FreePool (UsbBusDev);\r
- return EFI_UNSUPPORTED;\r
+ return OpenStatus;\r
}\r
//\r
// Locate the Host Controller Interface\r
//\r
OpenStatus = gBS->OpenProtocol (\r
Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- (VOID **) &UsbHCInterface,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ (VOID **) &(UsbBusDev->Usb2HCInterface),\r
This->DriverBindingHandle,\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
+ if (EFI_ERROR (OpenStatus)) {\r
\r
- if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {\r
- \r
- //\r
- // Report Status Code here since we will reset the host controller\r
- //\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,\r
- UsbBusDev->DevicePath\r
- );\r
+ UsbBusDev->Hc2ProtocolSupported = FALSE;\r
+ OpenStatus = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ (VOID **) &(UsbBusDev->UsbHCInterface),\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (OpenStatus)) {\r
+ //\r
+ // Report Status Code here since we will reset the host controller\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,\r
+ UsbBusDev->DevicePath\r
+ );\r
\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
- gBS->FreePool (UsbBusDev);\r
- return EFI_UNSUPPORTED;\r
- }\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ gBS->FreePool (UsbBusDev);\r
+ return OpenStatus;\r
+ }\r
\r
- if (OpenStatus == EFI_ALREADY_STARTED) {\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
- gBS->FreePool (UsbBusDev);\r
- return EFI_ALREADY_STARTED;\r
+ DEBUG ((gUSBDebugLevel, "UsbHcProtocol Opened.\n"));\r
+ } else {\r
+ DEBUG ((gUSBDebugLevel, "Usb2HcProtocol Opened.\n"));\r
+ UsbBusDev->Hc2ProtocolSupported = TRUE;\r
}\r
\r
- UsbBusDev->UsbHCInterface = UsbHCInterface;\r
-\r
//\r
// Attach EFI_USB_BUS_PROTOCOL to controller handle,\r
// for locate UsbBusDev later\r
This->DriverBindingHandle,\r
Controller\r
);\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
+\r
gBS->FreePool (UsbBusDev);\r
return Status;\r
}\r
This->DriverBindingHandle,\r
Controller\r
);\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
+\r
gBS->FreePool (UsbBusDev);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
This->DriverBindingHandle,\r
Controller\r
);\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
gBS->FreePool (UsbBusDev);\r
gBS->FreePool (RootHub);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- UsbHCInterface->GetRootHubPortNumber (\r
- UsbHCInterface,\r
- &RootHubController->DownstreamPorts\r
- );\r
- RootHubController->UsbDevice = RootHub;\r
- RootHubController->IsUsbHub = TRUE;\r
- RootHubController->DevicePath = UsbBusDev->DevicePath;\r
- RootHubController->HostController = Controller;\r
+ UsbVirtualHcGetCapability (\r
+ UsbBusDev,\r
+ &MaxSpeed,\r
+ &PortNumber,\r
+ &Is64BitCapable\r
+ );\r
+ RootHubController->DownstreamPorts = PortNumber;\r
+ RootHubController->UsbDevice = RootHub;\r
+ RootHubController->IsUsbHub = TRUE;\r
+ RootHubController->DevicePath = UsbBusDev->DevicePath;\r
+ RootHubController->HostController = Controller;\r
\r
- RootHub->NumOfControllers = 1;\r
- RootHub->UsbController[0] = RootHubController;\r
+ RootHub->NumOfControllers = 1;\r
+ RootHub->UsbController[0] = RootHubController;\r
+ RootHub->DeviceSpeed = MaxSpeed;\r
\r
//\r
// Report Status Code here since we will reset the host controller\r
//\r
// Reset USB Host Controller\r
//\r
- UsbHCInterface->Reset (\r
- UsbHCInterface,\r
- EFI_USB_HC_RESET_GLOBAL\r
- );\r
+ UsbVirtualHcReset (\r
+ UsbBusDev,\r
+ EFI_USB_HC_RESET_GLOBAL\r
+ );\r
\r
//\r
// Report Status Code while we are going to bring up the Host Controller\r
//\r
// Start USB Host Controller\r
//\r
- UsbHCInterface->SetState (\r
- UsbHCInterface,\r
- EfiUsbHcStateOperational\r
- );\r
+ UsbVirtualHcSetState (\r
+ UsbBusDev,\r
+ EfiUsbHcStateOperational\r
+ );\r
\r
//\r
// Create a timer to query root ports periodically\r
Status = gBS->CreateEvent (\r
EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,\r
EFI_TPL_CALLBACK,\r
- UsbEnumeration,\r
+ RootHubEnumeration,\r
RootHubController,\r
&RootHubController->HubNotify\r
);\r
Controller\r
);\r
\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
\r
gBS->FreePool (RootHubController);\r
gBS->FreePool (RootHub);\r
gBS->FreePool (UsbBusDev);\r
- return EFI_UNSUPPORTED;\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
//\r
Controller\r
);\r
\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
\r
gBS->CloseEvent (RootHubController->HubNotify);\r
gBS->FreePool (RootHubController);\r
gBS->FreePool (RootHub);\r
gBS->FreePool (UsbBusDev);\r
- return EFI_UNSUPPORTED;\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
+\r
//\r
// Stop the bus controller\r
//\r
USB_BUS_CONTROLLER_DEVICE *UsbBusController;\r
EFI_USB_BUS_PROTOCOL *UsbIdentifier;\r
UINT8 Index2;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
USB_IO_CONTROLLER_DEVICE *UsbController;\r
USB_IO_DEVICE *UsbIoDevice;\r
USB_IO_CONTROLLER_DEVICE *HubController;\r
//\r
// Stop USB Host Controller\r
//\r
- UsbHCInterface = UsbBusController->UsbHCInterface;\r
\r
//\r
// Report Status Code here since we will reset the host controller\r
EFI_IO_BUS_USB | EFI_IOB_PC_RESET\r
);\r
\r
- UsbHCInterface->SetState (\r
- UsbHCInterface,\r
- EfiUsbHcStateHalt\r
- );\r
+ UsbVirtualHcSetState (\r
+ UsbBusController,\r
+ EfiUsbHcStateHalt\r
+ );\r
\r
//\r
// Deconfiguration all its devices\r
// Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL\r
// Opened by this Controller\r
//\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusController->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
\r
gBS->CloseProtocol (\r
Controller,\r
USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
\r
UsbBusDev = UsbIoDevice->BusController;\r
+\r
+ UsbSetTransactionTranslator (\r
+ ParentHubController,\r
+ ParentPort,\r
+ UsbIoDevice\r
+ );\r
+\r
//\r
// Since a USB device must have at least on interface,\r
// so create this instance first\r
//\r
UsbIo = &FirstController->UsbIo;\r
\r
+ ParentPortReset (FirstController, FALSE, 0);\r
+\r
//\r
// First retrieve the 1st 8 bytes of\r
// in order to get the MaxPacketSize for Endpoint 0\r
\r
UsbIoDevice->DeviceDescriptor.MaxPacketSize0 = 8;\r
\r
- ParentPortReset (FirstController, FALSE, Index);\r
+ gBS->Stall (100 * 1000);\r
\r
Result = UsbGetDescriptor (\r
UsbIo,\r
&Status\r
);\r
if (!EFI_ERROR (Result)) {\r
- DEBUG ((gUSBDebugLevel,\r
+ DEBUG (\r
+ (gUSBDebugLevel,\r
"Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",\r
UsbIoDevice->DeviceDescriptor.MaxPacketSize0)\r
);\r
\r
UsbIoDevice->DeviceAddress = DevAddress;\r
\r
+ //\r
+ // SetAddress Complete Time by Spec, Max 50ms\r
+ //\r
+ gBS->Stall (10 * 1000);\r
+\r
//\r
// Get the whole device descriptor\r
//\r
//\r
// USB Device DeConfiguration\r
//\r
-\r
EFI_STATUS\r
UsbDeviceDeConfiguration (\r
IN USB_IO_DEVICE *UsbIoDevice\r
UINT8 Index;\r
EFI_USB_IO_PROTOCOL *UsbIo;\r
\r
- DEBUG ((gUSBDebugLevel, "Enter Usb Device Deconfiguration\n"));\r
-\r
//\r
// Double check UsbIoDevice exists\r
//\r
return EFI_SUCCESS;\r
}\r
\r
+ UsbUnsetTransactionTranslator (UsbIoDevice);\r
+\r
for (index = 0; index < UsbIoDevice->NumOfControllers; index++) {\r
//\r
// Check if it is a hub, if so, de configuration all its\r
//\r
// remove child handle reference to the USB_HC_PROTOCOL\r
//\r
- gBS->CloseProtocol (\r
- UsbController->HostController,\r
- &gEfiUsbHcProtocolGuid,\r
- gUsbBusDriverBinding.DriverBindingHandle,\r
- UsbController->Handle\r
- );\r
-\r
+ if (UsbIoDevice->BusController->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ UsbController->HostController,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ gUsbBusDriverBinding.DriverBindingHandle,\r
+ UsbController->Handle\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ UsbController->HostController,\r
+ &gEfiUsbHcProtocolGuid,\r
+ gUsbBusDriverBinding.DriverBindingHandle,\r
+ UsbController->Handle\r
+ );\r
+ }\r
//\r
// Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL\r
// installed on this handle\r
STATIC\r
VOID\r
EFIAPI\r
-UsbEnumeration (\r
+RootHubEnumeration (\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
)\r
/*++\r
\r
Routine Description:\r
- This is USB enumerator\r
+ \r
+ This is USB RootHub enumerator\r
\r
Arguments:\r
+ \r
Event - Indicating which event is signaled\r
Context - actually it is a USB_IO_DEVICE\r
\r
Returns:\r
- EFI_SUCCESS\r
- Others\r
-\r
+ \r
+ VOID\r
+ \r
--*/\r
{\r
USB_IO_CONTROLLER_DEVICE *HubController;\r
EFI_USB_PORT_STATUS HubPortStatus;\r
EFI_STATUS Status;\r
UINT8 Index;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
USB_IO_DEVICE *UsbIoDev;\r
USB_BUS_CONTROLLER_DEVICE *UsbBusDev;\r
EFI_HANDLE HostController;\r
USB_IO_CONTROLLER_DEVICE *NewController;\r
UINT8 Index2;\r
EFI_USB_IO_PROTOCOL *UsbIo;\r
- UINT8 StatusChangePort;\r
\r
HubController = (USB_IO_CONTROLLER_DEVICE *) Context;\r
HostController = HubController->HostController;\r
UsbBusDev = HubController->UsbDevice->BusController;\r
\r
- if (HubController->UsbDevice->DeviceAddress == 1) {\r
+ //\r
+ // Root hub has the address 1\r
+ //\r
+ UsbIoDev = HubController->UsbDevice;\r
+\r
+ for (Index = 0; Index < HubController->DownstreamPorts; Index++) {\r
+\r
+ UsbVirtualHcGetRootHubPortStatus (\r
+ UsbBusDev,\r
+ Index,\r
+ (EFI_USB_PORT_STATUS *) &HubPortStatus\r
+ );\r
+\r
+ if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
+ continue;\r
+ }\r
//\r
- // Root hub has the address 1\r
+ // Clear root hub status change status\r
//\r
- UsbIoDev = HubController->UsbDevice;\r
- UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;\r
-\r
- for (Index = 0; Index < HubController->DownstreamPorts; Index++) {\r
- UsbHCInterface->GetRootHubPortStatus (\r
- UsbHCInterface,\r
- Index,\r
- (EFI_USB_PORT_STATUS *) &HubPortStatus\r
- );\r
+ UsbVirtualHcClearRootHubPortFeature (\r
+ UsbBusDev,\r
+ Index,\r
+ EfiUsbPortConnectChange\r
+ );\r
\r
- if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
- continue;\r
- }\r
+ gBS->Stall (100 * 1000);\r
+\r
+ UsbVirtualHcGetRootHubPortStatus (\r
+ UsbBusDev,\r
+ Index,\r
+ (EFI_USB_PORT_STATUS *) &HubPortStatus\r
+ );\r
+\r
+ if (IsPortConnect (HubPortStatus.PortStatus)) {\r
+ \r
//\r
- // Clear root hub status change status\r
+ // There is something connected to this port\r
//\r
- ClearRootPortConnectionChangeStatus (\r
- Index,\r
- UsbHCInterface\r
+ DEBUG ((gUSBDebugLevel, "Something connected to Root Hub at Port0x%x\n", Index));\r
+\r
+ ReportUsbStatusCode (\r
+ UsbBusDev,\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
);\r
+ //\r
+ // if there is something physically detached, but still logically\r
+ // attached...\r
+ //\r
+ OldUsbIoDevice = HubController->Children[Index];\r
\r
- gBS->Stall (100 * 1000);\r
+ if (NULL != OldUsbIoDevice) {\r
+ UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+ HubController->Children[Index] = NULL;\r
+ }\r
\r
- UsbHCInterface->GetRootHubPortStatus (\r
- UsbHCInterface,\r
- Index,\r
- (EFI_USB_PORT_STATUS *) &HubPortStatus\r
- );\r
+ NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
+ if (NewDevice == NULL) {\r
+ return ;\r
+ }\r
+ //\r
+ // Initialize some fields by copying data from\r
+ // its parents\r
+ //\r
+ NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;\r
+ NewDevice->BusController = UsbIoDev->BusController;\r
\r
- if (IsPortConnect (HubPortStatus.PortStatus)) {\r
- \r
+ //\r
+ // Process of identify device speed\r
+ //\r
+ Status = IdentifyDeviceSpeed (\r
+ UsbBusDev, \r
+ NewDevice, \r
+ Index\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (NewDevice);\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Configure that device\r
+ //\r
+ Status = UsbDeviceConfiguration (\r
+ HubController,\r
+ HostController,\r
+ Index,\r
+ NewDevice\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (NewDevice);\r
+ return ;\r
+ }\r
+ //\r
+ // Add this device to the usb bus tree\r
+ //\r
+ HubController->Children[Index] = NewDevice;\r
+\r
+ for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
//\r
- // There is something connected to this port\r
+ // If this device is hub, add to the hub index\r
//\r
- DEBUG ((gUSBDebugLevel, "Something attached from Root Hub in 0x%x\n", Index));\r
+ NewController = NewDevice->UsbController[Index2];\r
\r
- ReportUsbStatusCode (\r
- UsbBusDev,\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
- );\r
- //\r
- // if there is something physically detached, but still logically\r
- // attached...\r
- //\r
- OldUsbIoDevice = HubController->Children[Index];\r
-\r
- if (NULL != OldUsbIoDevice) {\r
- UsbDeviceDeConfiguration (OldUsbIoDevice);\r
- HubController->Children[Index] = NULL;\r
- }\r
-\r
- NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
- if (NewDevice == NULL) {\r
- return ;\r
- }\r
+ Status = gBS->ConnectController (\r
+ NewController->Handle,\r
+ NULL,\r
+ NULL,\r
+ TRUE\r
+ );\r
//\r
- // Initialize some fields by copying data from\r
- // its parents\r
+ // If connect success, we need to disconnect when\r
+ // stop the controller, otherwise we need not call\r
+ // gBS->DisconnectController ()\r
+ // This is used by those usb devices we don't plan\r
+ // to support. We can allocate\r
+ // controller handles for them, but we don't have\r
+ // device drivers to manage them.\r
//\r
- NewDevice->IsSlowDevice = IsPortLowSpeedDeviceAttached (HubPortStatus.PortStatus);\r
-\r
- DEBUG ((gUSBDebugLevel, "DeviceSpeed 0x%x\n", NewDevice->IsSlowDevice));\r
+ NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
\r
- NewDevice->BusController = UsbIoDev->BusController;\r
+ if (IsHub (NewController)) {\r
\r
- //\r
- // Configure that device\r
- //\r
- Status = UsbDeviceConfiguration (\r
- HubController,\r
- HostController,\r
- Index,\r
- NewDevice\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (NewDevice);\r
- return ;\r
- }\r
- //\r
- // Add this device to the usb bus tree\r
- //\r
- HubController->Children[Index] = NewDevice;\r
+ NewController->IsUsbHub = TRUE;\r
\r
- for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
//\r
- // If this device is hub, add to the hub index\r
+ // Configure Hub Controller\r
//\r
- NewController = NewDevice->UsbController[Index2];\r
-\r
- Status = gBS->ConnectController (\r
- NewController->Handle,\r
- NULL,\r
- NULL,\r
- TRUE\r
- );\r
+ Status = DoHubConfig (NewController);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
//\r
- // If connect success, we need to disconnect when\r
- // stop the controller, otherwise we need not call\r
- // gBS->DisconnectController ()\r
- // This is used by those usb devices we don't plan\r
- // to support. We can allocate\r
- // controller handles for them, but we don't have\r
- // device drivers to manage them.\r
+ // Create an event to do hub enumeration\r
//\r
- NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
-\r
- if (IsHub (NewController)) {\r
-\r
- NewController->IsUsbHub = TRUE;\r
-\r
- //\r
- // Configure Hub Controller\r
- //\r
- Status = DoHubConfig (NewController);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
- //\r
- // Create an event to do hub enumeration\r
- //\r
- gBS->CreateEvent (\r
- EFI_EVENT_NOTIFY_SIGNAL,\r
- EFI_TPL_CALLBACK,\r
- UsbEnumeration,\r
- NewController,\r
- &NewController->HubNotify\r
- );\r
+ gBS->CreateEvent (\r
+ EFI_EVENT_NOTIFY_SIGNAL,\r
+ EFI_TPL_CALLBACK,\r
+ HubEnumeration,\r
+ NewController,\r
+ &NewController->HubNotify\r
+ );\r
\r
- //\r
- // Add request to do query hub status\r
- // change endpoint\r
- // Hub ports < 7\r
- //\r
- UsbIo = &NewController->UsbIo;\r
- UsbIo->UsbAsyncInterruptTransfer (\r
- UsbIo,\r
- NewController->HubEndpointAddress,\r
- TRUE,\r
- 100,\r
- 1,\r
- OnHubInterruptComplete,\r
- NewController\r
- );\r
+ //\r
+ // Add request to do query hub status\r
+ // change endpoint\r
+ // Hub ports < 7\r
+ //\r
+ UsbIo = &NewController->UsbIo;\r
+ UsbIo->UsbAsyncInterruptTransfer (\r
+ UsbIo,\r
+ NewController->HubEndpointAddress,\r
+ TRUE,\r
+ 100,\r
+ 1,\r
+ OnHubInterruptComplete,\r
+ NewController\r
+ );\r
\r
- }\r
}\r
- } else {\r
- //\r
- // Something disconnected from USB root hub\r
- //\r
- DEBUG ((gUSBDebugLevel, "Something deteached from Root Hub\n"));\r
+ }\r
+ } else {\r
+ //\r
+ // Something disconnected from USB root hub\r
+ //\r
+ DEBUG ((gUSBDebugLevel, "Something disconnected from Root Hub at Port0x%x\n", Index));\r
\r
- OldUsbIoDevice = HubController->Children[Index];\r
+ OldUsbIoDevice = HubController->Children[Index];\r
\r
- UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+ UsbDeviceDeConfiguration (OldUsbIoDevice);\r
\r
- HubController->Children[Index] = NULL;\r
+ HubController->Children[Index] = NULL;\r
+\r
+ UsbVirtualHcClearRootHubPortFeature (\r
+ UsbBusDev,\r
+ Index,\r
+ EfiUsbPortEnableChange\r
+ );\r
+ }\r
+ }\r
+\r
+ return ;\r
+}\r
+//\r
+// USB Root Hub Enumerator\r
+//\r
+STATIC\r
+VOID\r
+EFIAPI\r
+HubEnumeration (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
\r
- UsbHCInterface->ClearRootHubPortFeature (\r
- UsbHCInterface,\r
- Index,\r
- EfiUsbPortEnableChange\r
- );\r
+ Routine Description:\r
+ \r
+ This is Usb Hub enumerator\r
\r
- UsbHCInterface->GetRootHubPortStatus (\r
- UsbHCInterface,\r
- Index,\r
- (EFI_USB_PORT_STATUS *) &HubPortStatus\r
- );\r
+ Arguments:\r
+ \r
+ Event - Indicating which event is signaled\r
+ Context - actually it is a USB_IO_DEVICE\r
\r
- }\r
- }\r
+ Returns:\r
\r
- return ;\r
- } else {\r
+ VOID\r
+\r
+--*/\r
+{\r
+ USB_IO_CONTROLLER_DEVICE *HubController;\r
+ EFI_USB_PORT_STATUS HubPortStatus;\r
+ EFI_STATUS Status;\r
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev;\r
+ EFI_HANDLE HostController;\r
+ USB_IO_DEVICE *OldUsbIoDevice;\r
+ USB_IO_DEVICE *NewDevice;\r
+ USB_IO_CONTROLLER_DEVICE *NewController;\r
+ UINT8 Index2;\r
+ EFI_USB_IO_PROTOCOL *UsbIo;\r
+ UINT8 StatusChangePort;\r
+ UINT8 Number;\r
+\r
+ HubController = (USB_IO_CONTROLLER_DEVICE *) Context;\r
+ HostController = HubController->HostController;\r
+ UsbBusDev = HubController->UsbDevice->BusController;\r
+\r
+ //\r
+ // Event from Hub, Get the hub controller handle\r
+ //\r
+ //\r
+ // Get the status change endpoint\r
+ //\r
+ StatusChangePort = HubController->StatusChangePort;\r
+\r
+ //\r
+ // Clear HubController Status Change Bit\r
+ //\r
+ HubController->StatusChangePort = 0;\r
+\r
+ if (StatusChangePort == 0) {\r
//\r
- // Event from Hub, Get the hub controller handle\r
+ // Hub changes, we don't handle here\r
//\r
+ return ;\r
+ }\r
+ //\r
+ // Check which event took place at that port\r
+ //\r
+ UsbIo = &HubController->UsbIo;\r
+ Status = HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return ;\r
+ }\r
+ //\r
+ // Clear some change status\r
+ //\r
+ if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {\r
//\r
- // Get the status change endpoint\r
+ // Clear Hub port enable change\r
//\r
- StatusChangePort = HubController->StatusChangePort;\r
+ DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));\r
+ HubClearPortFeature (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ EfiUsbPortEnableChange\r
+ );\r
+\r
+ HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
+ );\r
+ }\r
\r
+ if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {\r
//\r
- // Clear HubController Status Change Bit\r
+ // Clear Hub reset change\r
//\r
- HubController->StatusChangePort = 0;\r
+ DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));\r
+ HubClearPortFeature (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ EfiUsbPortResetChange\r
+ );\r
\r
- if (StatusChangePort == 0) {\r
- //\r
- // Hub changes, we don't handle here\r
- //\r
- return ;\r
- }\r
+ HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
+ );\r
+ }\r
+\r
+ if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {\r
//\r
- // Check which event took place at that port\r
+ // Clear Hub overcurrent change\r
//\r
- UsbIo = &HubController->UsbIo;\r
- Status = HubGetPortStatus (\r
- UsbIo,\r
- StatusChangePort,\r
- (UINT32 *) &HubPortStatus\r
- );\r
+ DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));\r
+ HubClearPortFeature (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ EfiUsbPortOverCurrentChange\r
+ );\r
\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
+ HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
+ );\r
+ }\r
+\r
+ if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
//\r
- // Clear some change status\r
+ // First clear port connection change\r
//\r
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {\r
- //\r
- // Clear Hub port enable change\r
- //\r
- DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));\r
- HubClearPortFeature (\r
- UsbIo,\r
- StatusChangePort,\r
- EfiUsbPortEnableChange\r
- );\r
+ DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));\r
+ HubClearPortFeature (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ EfiUsbPortConnectChange\r
+ );\r
\r
- HubGetPortStatus (\r
- UsbIo,\r
- StatusChangePort,\r
- (UINT32 *) &HubPortStatus\r
+ HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
+ );\r
+\r
+ if (IsPortConnect (HubPortStatus.PortStatus)) {\r
+\r
+ DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));\r
+\r
+ ReportUsbStatusCode (\r
+ UsbBusDev,\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
);\r
- }\r
\r
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {\r
//\r
- // Clear Hub reset change\r
+ // if there is something physically detached, but still logically\r
+ // attached...\r
//\r
- DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));\r
- HubClearPortFeature (\r
- UsbIo,\r
- StatusChangePort,\r
- EfiUsbPortResetChange\r
- );\r
+ OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
\r
- HubGetPortStatus (\r
- UsbIo,\r
- StatusChangePort,\r
- (UINT32 *) &HubPortStatus\r
- );\r
- }\r
+ if (NULL != OldUsbIoDevice) {\r
+ UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+ HubController->Children[StatusChangePort - 1] = NULL;\r
+ }\r
\r
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {\r
+ NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
+ if (NewDevice == NULL) {\r
+ return ;\r
+ }\r
//\r
- // Clear Hub overcurrent change\r
+ // Initialize some fields\r
//\r
- DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));\r
- HubClearPortFeature (\r
- UsbIo,\r
- StatusChangePort,\r
- EfiUsbPortOverCurrentChange\r
- );\r
+ NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;\r
+ NewDevice->BusController = HubController->UsbDevice->BusController;\r
\r
- HubGetPortStatus (\r
- UsbIo,\r
- StatusChangePort,\r
- (UINT32 *) &HubPortStatus\r
- );\r
- }\r
-\r
- if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
//\r
- // First clear port connection change\r
+ // There is something connected to this port,\r
+ // reset that port\r
+ //\r
+ // Disable the enable bit in port status\r
//\r
- DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));\r
HubClearPortFeature (\r
UsbIo,\r
StatusChangePort,\r
- EfiUsbPortConnectChange\r
- );\r
-\r
- HubGetPortStatus (\r
- UsbIo,\r
- StatusChangePort,\r
- (UINT32 *) &HubPortStatus\r
+ EfiUsbPortEnable\r
);\r
\r
- if (IsPortConnect (HubPortStatus.PortStatus)) {\r
+ gBS->Stall (50 * 1000);\r
\r
- DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));\r
-\r
- ReportUsbStatusCode (\r
- UsbBusDev,\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
+ //\r
+ // Wait for bit change\r
+ //\r
+ Number = 10;\r
+ do {\r
+ HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
);\r
+ gBS->Stall (10 * 1000);\r
+ Number -= 1;\r
+ } while ((HubPortStatus.PortStatus & USB_PORT_STAT_ENABLE) == 1 && Number > 0);\r
\r
+ if (Number == 0) {\r
//\r
- // if there is something physically detached, but still logically\r
- // attached...\r
+ // Cannot disable port, return error\r
//\r
- OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
-\r
- if (NULL != OldUsbIoDevice) {\r
- UsbDeviceDeConfiguration (OldUsbIoDevice);\r
- HubController->Children[StatusChangePort - 1] = NULL;\r
- }\r
+ DEBUG ((gUSBErrorLevel, "Disable Port Failed\n"));\r
+ gBS->FreePool (NewDevice);\r
+ return ;\r
+ }\r
\r
- NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
- if (NewDevice == NULL) {\r
- return ;\r
- }\r
+ HubSetPortFeature (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ EfiUsbPortReset\r
+ );\r
\r
- ResetHubPort (HubController, StatusChangePort);\r
+ gBS->Stall (50 * 1000);\r
\r
+ //\r
+ // Wait for port reset complete\r
+ //\r
+ Number = 10;\r
+ do {\r
HubGetPortStatus (\r
UsbIo,\r
StatusChangePort,\r
(UINT32 *) &HubPortStatus\r
);\r
+ gBS->Stall (10 * 1000);\r
+ Number -= 1;\r
+ } while ((HubPortStatus.PortStatus & USB_PORT_STAT_RESET) == 1 && Number > 0);\r
\r
+ if (Number == 0) {\r
//\r
- // Initialize some fields\r
+ // Cannot reset port, return error\r
//\r
- NewDevice->IsSlowDevice = IsPortLowSpeedDeviceAttached (HubPortStatus.PortStatus);\r
+ DEBUG ((gUSBErrorLevel, "Reset Port Failed\n"));\r
+ gBS->FreePool (NewDevice);\r
+ return ;\r
+ }\r
+ //\r
+ // Check high speed or full speed device\r
+ //\r
+ if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {\r
+ DEBUG ((gUSBDebugLevel, "Low Speed Device Attached to Hub\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;\r
+ } else if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {\r
+ DEBUG ((gUSBDebugLevel, "High Speed Device Attached to Hub\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;\r
+ } else {\r
+ DEBUG ((gUSBDebugLevel, "Full Speed Device Attached to Hub\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;\r
+ }\r
+ //\r
+ // Configure that device\r
+ //\r
+ Status = UsbDeviceConfiguration (\r
+ HubController,\r
+ HostController,\r
+ (UINT8) (StatusChangePort - 1),\r
+ NewDevice\r
+ );\r
\r
- NewDevice->BusController = HubController->UsbDevice->BusController;\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (NewDevice);\r
+ return ;\r
+ }\r
+ //\r
+ // Add this device to the usb bus tree\r
+ // StatusChangePort is begin from 1,\r
+ //\r
+ HubController->Children[StatusChangePort - 1] = NewDevice;\r
\r
+ for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
//\r
- // Configure that device\r
+ // If this device is hub, add to the hub index\r
//\r
- Status = UsbDeviceConfiguration (\r
- HubController,\r
- HostController,\r
- (UINT8) (StatusChangePort - 1),\r
- NewDevice\r
- );\r
+ NewController = NewDevice->UsbController[Index2];\r
\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (NewDevice);\r
- return ;\r
- }\r
//\r
- // Add this device to the usb bus tree\r
- // StatusChangePort is begin from 1,\r
+ // Connect the controller to the driver image\r
+ //\r
+ Status = gBS->ConnectController (\r
+ NewController->Handle,\r
+ NULL,\r
+ NULL,\r
+ TRUE\r
+ );\r
+ //\r
+ // If connect success, we need to disconnect when\r
+ // stop the controller, otherwise we need not call\r
+ // gBS->DisconnectController ()\r
+ // This is used by those usb devices we don't plan\r
+ // to support. We can allocate\r
+ // controller handles for them, but we don't have\r
+ // device drivers to manage them.\r
//\r
- HubController->Children[StatusChangePort - 1] = NewDevice;\r
+ NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
\r
- for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
- //\r
- // If this device is hub, add to the hub index\r
- //\r
- NewController = NewDevice->UsbController[Index2];\r
+ //\r
+ // If this device is hub, add to the hub index\r
+ //\r
+ if (IsHub (NewController)) {\r
+\r
+ NewController->IsUsbHub = TRUE;\r
\r
//\r
- // Connect the controller to the driver image\r
+ // Configure Hub\r
//\r
- Status = gBS->ConnectController (\r
- NewController->Handle,\r
- NULL,\r
- NULL,\r
- TRUE\r
- );\r
+ Status = DoHubConfig (NewController);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
//\r
- // If connect success, we need to disconnect when\r
- // stop the controller, otherwise we need not call\r
- // gBS->DisconnectController ()\r
- // This is used by those usb devices we don't plan\r
- // to support. We can allocate\r
- // controller handles for them, but we don't have\r
- // device drivers to manage them.\r
+ // Create an event to do hub enumeration\r
//\r
- NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
+ gBS->CreateEvent (\r
+ EFI_EVENT_NOTIFY_SIGNAL,\r
+ EFI_TPL_CALLBACK,\r
+ HubEnumeration,\r
+ NewController,\r
+ &NewController->HubNotify\r
+ );\r
\r
//\r
- // If this device is hub, add to the hub index\r
+ // Add request to do query hub status\r
+ // change endpoint\r
//\r
- if (IsHub (NewController)) {\r
-\r
- NewController->IsUsbHub = TRUE;\r
-\r
- //\r
- // Configure Hub\r
- //\r
- Status = DoHubConfig (NewController);\r
-\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
- //\r
- // Create an event to do hub enumeration\r
- //\r
- gBS->CreateEvent (\r
- EFI_EVENT_NOTIFY_SIGNAL,\r
- EFI_TPL_CALLBACK,\r
- UsbEnumeration,\r
- NewController,\r
- &NewController->HubNotify\r
+ UsbIo = &NewController->UsbIo;\r
+ UsbIo->UsbAsyncInterruptTransfer (\r
+ UsbIo,\r
+ NewController->HubEndpointAddress, // Hub endpoint address\r
+ TRUE,\r
+ 100,\r
+ 1, // Hub ports < 7\r
+ OnHubInterruptComplete,\r
+ NewController\r
);\r
-\r
- //\r
- // Add request to do query hub status\r
- // change endpoint\r
- //\r
- UsbIo = &NewController->UsbIo;\r
- UsbIo->UsbAsyncInterruptTransfer (\r
- UsbIo,\r
- NewController->HubEndpointAddress, // Hub endpoint address\r
- TRUE,\r
- 100,\r
- 1, // Hub ports < 7\r
- OnHubInterruptComplete,\r
- NewController\r
- );\r
- }\r
}\r
- } else {\r
- //\r
- // Something disconnected from USB hub\r
- //\r
- DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));\r
-\r
- OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
+ }\r
+ } else {\r
+ //\r
+ // Something disconnected from USB hub\r
+ //\r
+ DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));\r
\r
- UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+ OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
\r
- HubController->Children[StatusChangePort - 1] = NULL;\r
+ UsbDeviceDeConfiguration (OldUsbIoDevice);\r
\r
- }\r
+ HubController->Children[StatusChangePort - 1] = NULL;\r
\r
- return ;\r
}\r
\r
return ;\r
}\r
-}\r
-//\r
-// Clear port connection change status over a given root hub port\r
-//\r
-EFI_STATUS\r
-ClearRootPortConnectionChangeStatus (\r
- UINT8 PortNum,\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Clear port connection change status over a given root hub port\r
-\r
- Arguments:\r
- PortNum - The given port.\r
- UsbHCInterface - The EFI_USB_HC_PROTOCOL instance.\r
-\r
- Returns:\r
- EFI_SUCCESS\r
\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- Status = UsbHCInterface->ClearRootHubPortFeature (\r
- UsbHCInterface,\r
- PortNum,\r
- EfiUsbPortConnectChange\r
- );\r
- return Status;\r
+ return ;\r
}\r
\r
STATIC\r
EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
EFI_USB_HC_PROTOCOL *UsbHcProtocol;\r
+ EFI_USB2_HC_PROTOCOL *Usb2HcProtocol;\r
\r
//\r
// Build the child device path for each new USB_IO device\r
return Status;\r
}\r
\r
- Status = gBS->OpenProtocol (\r
- UsbIoController->HostController,\r
- &gEfiUsbHcProtocolGuid,\r
- (VOID **) &UsbHcProtocol,\r
- gUsbBusDriverBinding.DriverBindingHandle,\r
- UsbIoController->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
+ if (UsbIoController->UsbDevice->BusController->Hc2ProtocolSupported) {\r
+ Status = gBS->OpenProtocol (\r
+ UsbIoController->HostController,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ (VOID **)&Usb2HcProtocol,\r
+ gUsbBusDriverBinding.DriverBindingHandle,\r
+ UsbIoController->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ } else {\r
+ Status = gBS->OpenProtocol (\r
+ UsbIoController->HostController,\r
+ &gEfiUsbHcProtocolGuid,\r
+ (VOID **)&UsbHcProtocol,\r
+ gUsbBusDriverBinding.DriverBindingHandle,\r
+ UsbIoController->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ }\r
\r
return Status;\r
}\r
\r
Arguments:\r
UsbIoController - Indicating the Usb Controller Device.\r
- Reconfigure - Do we need to reconfigure it.\r
+ ReConfigure - Do we need to reconfigure it.\r
RetryTimes - Retry Times when failed\r
+ \r
Returns:\r
EFI_SUCCESS\r
EFI_DEVICE_ERROR\r
\r
if (ParentIoDev->DeviceAddress == 1) {\r
DEBUG ((gUSBDebugLevel, "Reset from Root Hub 0x%x\n", HubPort));\r
- ResetRootPort (ParentIoDev->BusController->UsbHCInterface, HubPort, RetryTimes);\r
+ ResetRootPort (ParentIoDev->BusController, HubPort, RetryTimes);\r
} else {\r
DEBUG ((gUSBDebugLevel, "Reset from Hub, Addr 0x%x\n", ParentIoDev->DeviceAddress));\r
ResetHubPort (ParentController, HubPort + 1);\r
\r
EFI_STATUS\r
ResetRootPort (\r
- IN EFI_USB_HC_PROTOCOL *UsbHCInterface,\r
- IN UINT8 PortNum,\r
- IN UINT8 RetryTimes\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNum,\r
+ IN UINT8 RetryTimes\r
)\r
/*++\r
\r
Reset Root Hub port.\r
\r
Arguments:\r
- UsbHCInterface - The EFI_USB_HC_PROTOCOL instance.\r
- PortNum - The given port to be reset.\r
- RetryTimes - RetryTimes when failed\r
+ UsbBusDev - Bus controller of the device.\r
+ PortNum - The given port to be reset.\r
+ RetryTimes - RetryTimes when failed\r
+ \r
Returns:\r
- N/A\r
+ EFI_SUCCESS\r
+ EFI_DEVICE_ERROR\r
\r
--*/\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
+ EFI_USB_PORT_STATUS PortStatus;\r
\r
//\r
// reset root port\r
//\r
- Status = UsbHCInterface->SetRootHubPortFeature (\r
- UsbHCInterface,\r
- PortNum,\r
- EfiUsbPortReset\r
- );\r
-\r
+ Status = UsbVirtualHcSetRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortReset\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
//\r
// clear reset root port\r
//\r
- Status = UsbHCInterface->ClearRootHubPortFeature (\r
- UsbHCInterface,\r
- PortNum,\r
- EfiUsbPortReset\r
- );\r
-\r
+ Status = UsbVirtualHcClearRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortReset\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
gBS->Stall (1000);\r
\r
- Status = ClearRootPortConnectionChangeStatus (PortNum, UsbHCInterface);\r
-\r
+ Status = UsbVirtualHcClearRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortConnectChange\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
- //\r
- // Set port enable\r
- //\r
- Status = UsbHCInterface->SetRootHubPortFeature (\r
- UsbHCInterface,\r
- PortNum,\r
- EfiUsbPortEnable\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
+\r
+ UsbVirtualHcGetRootHubPortStatus (\r
+ UsbBusDev,\r
+ PortNum,\r
+ &PortStatus\r
+ );\r
+ if (PortStatus.PortStatus & USB_PORT_STAT_OWNER) {\r
+ //\r
+ // Set port enable\r
+ //\r
+ Status = UsbVirtualHcSetRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortEnable\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Status = UsbVirtualHcClearRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortEnableChange\r
+ );\r
}\r
\r
- Status = UsbHCInterface->ClearRootHubPortFeature (\r
- UsbHCInterface,\r
- PortNum,\r
- EfiUsbPortEnableChange\r
- );\r
gBS->Stall ((1 + RetryTimes) * 50 * 1000);\r
\r
return EFI_SUCCESS;\r
}\r
\r
-\r
EFI_STATUS\r
ResetHubPort (\r
IN USB_IO_CONTROLLER_DEVICE *UsbIoController,\r
return EFI_SUCCESS;\r
}\r
\r
-\r
-\r
-\r
-\r
STATIC\r
EFI_STATUS\r
ReportUsbStatusCode (\r
);\r
}\r
\r
-\r
EFI_STATUS\r
IsDeviceDisconnected (\r
IN USB_IO_CONTROLLER_DEVICE *UsbIoController,\r
EFI_STATUS Status;\r
EFI_USB_IO_PROTOCOL *UsbIo;\r
EFI_USB_PORT_STATUS PortStatus;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
\r
ParentController = UsbIoController->Parent;\r
ParentIoDev = ParentController->UsbDevice;\r
//\r
// Connected to the root hub\r
//\r
- UsbHCInterface = ParentIoDev->BusController->UsbHCInterface;\r
- Status = UsbHCInterface->GetRootHubPortStatus (\r
- UsbHCInterface,\r
- HubPort,\r
- &PortStatus\r
- );\r
+ UsbVirtualHcGetRootHubPortStatus (\r
+ ParentIoDev->BusController,\r
+ HubPort,\r
+ &PortStatus\r
+ );\r
\r
} else {\r
UsbIo = &UsbIoController->UsbIo;\r
\r
return EFI_SUCCESS;\r
}\r
+\r
+STATIC\r
+EFI_STATUS\r
+UsbSetTransactionTranslator (\r
+ IN USB_IO_CONTROLLER_DEVICE *ParentHubController,\r
+ IN UINT8 ParentPort,\r
+ IN OUT USB_IO_DEVICE *Device\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Set Transaction Translator parameter\r
+ \r
+ Arguments:\r
+ \r
+ ParentHubController - Controller structure of the parent Hub device\r
+ ParentPort - Number of parent port\r
+ Device - Structure of the device\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ USB_IO_CONTROLLER_DEVICE *AncestorHubController;\r
+\r
+ AncestorHubController = ParentHubController;\r
+ Device->Translator = NULL;\r
+\r
+ if (EFI_USB_SPEED_HIGH == Device->DeviceSpeed) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ do {\r
+ if (EFI_USB_SPEED_HIGH == AncestorHubController->UsbDevice->DeviceSpeed) {\r
+ break;\r
+ }\r
+\r
+ if (NULL == AncestorHubController->Parent) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ AncestorHubController = AncestorHubController->Parent;\r
+ } while (1);\r
+\r
+ Device->Translator = AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR));\r
+ if (NULL == Device->Translator) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Device->Translator->TranslatorHubAddress = AncestorHubController->UsbDevice->DeviceAddress;\r
+ Device->Translator->TranslatorPortNumber = ParentPort;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+UsbUnsetTransactionTranslator (\r
+ USB_IO_DEVICE *Device\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Unset Transaction Translator parameter\r
+ \r
+ Arguments:\r
+ \r
+ Device - Structure of the device\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ \r
+--*/\r
+{\r
+ if (Device->Translator) {\r
+ gBS->FreePool (Device->Translator);\r
+ Device->Translator = NULL;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+IdentifyDeviceSpeed (\r
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ USB_IO_DEVICE *NewDevice,\r
+ UINT8 Index\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Identify speed of USB device\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - UsbBus controller structure of the device\r
+ NewDevice - Devcie controller structure\r
+ Index - Number of the port\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ EFI_NOT_FOUND Device release to CHC or can't be found\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_USB_PORT_STATUS HubPortStatus;\r
+\r
+ UsbVirtualHcGetRootHubPortStatus (\r
+ UsbBusDev,\r
+ Index,\r
+ (EFI_USB_PORT_STATUS *) &HubPortStatus\r
+ );\r
+ \r
+ //\r
+ // Check device device\r
+ //\r
+ if (!(HubPortStatus.PortStatus & USB_PORT_STAT_OWNER)) {\r
+ //\r
+ // EHC Port Owner\r
+ //\r
+ if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {\r
+ DEBUG ((gUSBDebugLevel, "High Speed Device attached to EHC\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH; \r
+ } else {\r
+ Status = ReleasePortToCHC (UsbBusDev, Index);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((gUSBErrorLevel, "Fail to release port to CHC\n"));\r
+ } else {\r
+ DEBUG ((gUSBDebugLevel, "Success to release port to CHC\n"));\r
+ }\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ } else {\r
+ //\r
+ // CHC Port Owner\r
+ //\r
+ if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {\r
+ DEBUG ((gUSBDebugLevel, "Low Speed Device attached to CHC\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW; \r
+ } else {\r
+ DEBUG ((gUSBDebugLevel, "FULL Speed Device attached to CHC\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL; \r
+ }\r
+ }\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReleasePortToCHC (\r
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ UINT8 PortNum\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Set bit to release the port owner to CHC\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - UsbBus controller structure of the device\r
+ PortNum - Number of the port\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = UsbVirtualHcSetRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortOwner\r
+ );\r
+\r
+ gBS->Stall (100 * 1000);\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetCapability (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ OUT UINT8 *MaxSpeed,\r
+ OUT UINT8 *PortNumber,\r
+ OUT UINT8 *Is64BitCapable\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to Retrieves the capablility of root hub ports \r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ MaxSpeed - A pointer to the number of the host controller.\r
+ PortNumber - A pointer to the number of the root hub ports.\r
+ Is64BitCapable - A pointer to the flag for whether controller supports \r
+ 64-bit memory addressing.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The host controller capability were retrieved successfully.\r
+ EFI_INVALID_PARAMETER \r
+ MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to retrieve the capabilities. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->GetCapability (\r
+ UsbBusDev->Usb2HCInterface,\r
+ MaxSpeed,\r
+ PortNumber,\r
+ Is64BitCapable\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->GetRootHubPortNumber (\r
+ UsbBusDev->UsbHCInterface,\r
+ PortNumber\r
+ );\r
+ *MaxSpeed = EFI_USB_SPEED_FULL;\r
+ *Is64BitCapable = (UINT8) FALSE;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcReset (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT16 Attributes\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to provides software reset for the USB host controller\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ Attributes - A bit mask of the reset operation to perform. \r
+ See below for a list of the supported bit mask values.\r
+ \r
+ #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc\r
+ #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc\r
+ #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2\r
+ #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2\r
+\r
+ EFI_USB_HC_RESET_GLOBAL \r
+ If this bit is set, a global reset signal will be sent to the USB bus.\r
+ This resets all of the USB bus logic, including the USB host \r
+ controller hardware and all the devices attached on the USB bus.\r
+ EFI_USB_HC_RESET_HOST_CONTROLLER \r
+ If this bit is set, the USB host controller hardware will be reset. \r
+ No reset signal will be sent to the USB bus.\r
+ EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG\r
+ If this bit is set, a global reset signal will be sent to the USB bus.\r
+ This resets all of the USB bus logic, including the USB host \r
+ controller hardware and all the devices attached on the USB bus. \r
+ If this is an EHCI controller and the debug port has configured, then \r
+ this is will still reset the host controller.\r
+ EFI_USB_HC_RESET_HOST_WITH_DEBUG\r
+ If this bit is set, the USB host controller hardware will be reset. \r
+ If this is an EHCI controller and the debug port has been configured,\r
+ then this will still reset the host controller.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The reset operation succeeded.\r
+ EFI_INVALID_PARAMETER \r
+ Attributes is not valid.\r
+ EFI_UNSUPPOURTED\r
+ The type of reset specified by Attributes is not currently supported by\r
+ the host controller hardware.\r
+ EFI_ACCESS_DENIED\r
+ Reset operation is rejected due to the debug port being configured and \r
+ active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or \r
+ EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to\r
+ perform reset operation for this host controller.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to perform \r
+ the reset operation.\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->Reset (\r
+ UsbBusDev->Usb2HCInterface,\r
+ EFI_USB_HC_RESET_GLOBAL\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->Reset (\r
+ UsbBusDev->UsbHCInterface,\r
+ EFI_USB_HC_RESET_GLOBAL\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetState (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ OUT EFI_USB_HC_STATE *State\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to retrieves current state of the USB host controller\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ State - A pointer to the EFI_USB_HC_STATE data structure that \r
+ indicates current state of the USB host controller. \r
+ Type EFI_USB_HC_STATE is defined below.\r
+ \r
+ typedef enum {\r
+ EfiUsbHcStateHalt,\r
+ EfiUsbHcStateOperational,\r
+ EfiUsbHcStateSuspend,\r
+ EfiUsbHcStateMaximum\r
+ } EFI_USB_HC_STATE;\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The state information of the host controller was returned in State.\r
+ EFI_INVALID_PARAMETER \r
+ State is NULL.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to retrieve the \r
+ host controller's current state. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->GetState (\r
+ UsbBusDev->Usb2HCInterface,\r
+ State\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->GetState (\r
+ UsbBusDev->UsbHCInterface,\r
+ State\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSetState (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN EFI_USB_HC_STATE State\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to sets the USB host controller to a specific state\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ State - Indicates the state of the host controller that will be set.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The USB host controller was successfully placed in the state \r
+ specified by State.\r
+ EFI_INVALID_PARAMETER \r
+ State is invalid.\r
+ EFI_DEVICE_ERROR \r
+ Failed to set the state specified by State due to device error. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->SetState (\r
+ UsbBusDev->Usb2HCInterface,\r
+ State\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->SetState (\r
+ UsbBusDev->UsbHCInterface,\r
+ State\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetRootHubPortStatus (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNumber,\r
+ OUT EFI_USB_PORT_STATUS *PortStatus\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to retrieves the current status of a USB root hub port\r
+ both for Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ PortNumber - Specifies the root hub port from which the status \r
+ is to be retrieved. This value is zero-based. For example, \r
+ if a root hub has two ports, then the first port is numbered 0,\r
+ and the second port is numbered 1.\r
+ PortStatus - A pointer to the current port status bits and \r
+ port status change bits. \r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS The status of the USB root hub port specified by PortNumber \r
+ was returned in PortStatus.\r
+ EFI_INVALID_PARAMETER PortNumber is invalid. \r
+ EFI_DEVICE_ERROR Can't read register \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->GetRootHubPortStatus (\r
+ UsbBusDev->Usb2HCInterface,\r
+ PortNumber,\r
+ PortStatus\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->GetRootHubPortStatus (\r
+ UsbBusDev->UsbHCInterface,\r
+ PortNumber,\r
+ PortStatus\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSetRootHubPortFeature (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Virual interface to sets a feature for the specified root hub port\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ PortNumber - Specifies the root hub port whose feature \r
+ is requested to be set.\r
+ PortFeature - Indicates the feature selector associated \r
+ with the feature set request. \r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The feature specified by PortFeature was set for the \r
+ USB root hub port specified by PortNumber.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid or PortFeature is invalid.\r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->SetRootHubPortFeature (\r
+ UsbBusDev->Usb2HCInterface,\r
+ PortNumber,\r
+ PortFeature\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->SetRootHubPortFeature (\r
+ UsbBusDev->UsbHCInterface,\r
+ PortNumber,\r
+ PortFeature\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcClearRootHubPortFeature (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to clears a feature for the specified root hub port\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ PortNumber - Specifies the root hub port whose feature \r
+ is requested to be cleared.\r
+ PortFeature - Indicates the feature selector associated with the \r
+ feature clear request.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The feature specified by PortFeature was cleared for the \r
+ USB root hub port specified by PortNumber.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid or PortFeature is invalid.\r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->ClearRootHubPortFeature (\r
+ UsbBusDev->Usb2HCInterface,\r
+ PortNumber,\r
+ PortFeature\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->ClearRootHubPortFeature (\r
+ UsbBusDev->UsbHCInterface,\r
+ PortNumber,\r
+ PortFeature\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcControlTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN EFI_USB_DEVICE_REQUEST *Request,\r
+ IN EFI_USB_DATA_DIRECTION TransferDirection,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits control transfer to a target USB device\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ DeviceSpeed - Indicates target device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ Request - A pointer to the USB device request that will be sent \r
+ to the USB device. \r
+ TransferDirection - Specifies the data direction for the transfer.\r
+ There are three values available, DataIn, DataOut \r
+ and NoData.\r
+ Data - A pointer to the buffer of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ TimeOut - Indicates the maximum time, in microseconds, \r
+ which the transfer is allowed to complete.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information generated \r
+ by this control transfer.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The control transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The control transfer could not be completed due to a lack of resources.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The control transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The control transfer failed due to host controller or device error. \r
+ Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BOOLEAN IsSlowDevice;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->ControlTransfer (\r
+ UsbBusDev->Usb2HCInterface,\r
+ DeviceAddress,\r
+ DeviceSpeed,\r
+ MaximumPacketLength,\r
+ Request,\r
+ TransferDirection,\r
+ Data,\r
+ DataLength,\r
+ TimeOut,\r
+ Translator,\r
+ TransferResult\r
+ );\r
+ } else {\r
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+ Status = UsbBusDev->UsbHCInterface->ControlTransfer (\r
+ UsbBusDev->UsbHCInterface,\r
+ DeviceAddress,\r
+ IsSlowDevice,\r
+ (UINT8) MaximumPacketLength,\r
+ Request,\r
+ TransferDirection,\r
+ Data,\r
+ DataLength,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcBulkTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits bulk transfer to a bulk endpoint of a USB device\r
+ both for Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration. \r
+ EndPointAddress - The combination of an endpoint number and an \r
+ endpoint direction of the target USB device. \r
+ Each endpoint address supports data transfer in \r
+ one direction except the control endpoint \r
+ (whose default endpoint address is 0). \r
+ It is the caller's responsibility to make sure that \r
+ the EndPointAddress represents a bulk endpoint. \r
+ DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL\r
+ and EFI_USB_SPEED_HIGH.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint\r
+ is capable of sending or receiving. \r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be transmitted \r
+ to USB device or received from USB device. \r
+ DataLength - When input, indicates the size, in bytes, of the data buffer\r
+ specified by Data. When output, indicates the actually \r
+ transferred data size. \r
+ DataToggle - A pointer to the data toggle value. On input, it indicates \r
+ the initial data toggle value the bulk transfer should adopt;\r
+ on output, it is updated to indicate the data toggle value \r
+ of the subsequent bulk transfer. \r
+ Translator - A pointr to the transaction translator data. \r
+ TimeOut - Indicates the maximum time, in microseconds, which the \r
+ transfer is allowed to complete. \r
+ TransferResult - A pointer to the detailed result information of the \r
+ bulk transfer.\r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The bulk transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The bulk transfer could not be submitted due to lack of resource.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The bulk transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The bulk transfer failed due to host controller or device error.\r
+ Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->BulkTransfer (\r
+ UsbBusDev->Usb2HCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DeviceSpeed,\r
+ MaximumPacketLength,\r
+ DataBuffersNumber,\r
+ Data,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ Translator,\r
+ TransferResult\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->BulkTransfer (\r
+ UsbBusDev->UsbHCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ (UINT8) MaximumPacketLength,\r
+ *Data,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcAsyncInterruptTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE * UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN BOOLEAN IsNewTransfer,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN PollingInterval,\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,\r
+ IN VOID *Context OPTIONAL\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits an asynchronous interrupt transfer to an \r
+ interrupt endpoint of a USB device for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration. \r
+ EndPointAddress - The combination of an endpoint number and an endpoint \r
+ direction of the target USB device. Each endpoint address \r
+ supports data transfer in one direction except the \r
+ control endpoint (whose default endpoint address is 0). \r
+ It is the caller's responsibility to make sure that \r
+ the EndPointAddress represents an interrupt endpoint. \r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint\r
+ is capable of sending or receiving. \r
+ IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between\r
+ the host and the target interrupt endpoint. \r
+ If FALSE, the specified asynchronous interrupt pipe \r
+ is canceled. \r
+ DataToggle - A pointer to the data toggle value. On input, it is valid \r
+ when IsNewTransfer is TRUE, and it indicates the initial \r
+ data toggle value the asynchronous interrupt transfer \r
+ should adopt. \r
+ On output, it is valid when IsNewTransfer is FALSE, \r
+ and it is updated to indicate the data toggle value of \r
+ the subsequent asynchronous interrupt transfer. \r
+ PollingInterval - Indicates the interval, in milliseconds, that the \r
+ asynchronous interrupt transfer is polled. \r
+ This parameter is required when IsNewTransfer is TRUE. \r
+ DataLength - Indicates the length of data to be received at the \r
+ rate specified by PollingInterval from the target \r
+ asynchronous interrupt endpoint. This parameter \r
+ is only required when IsNewTransfer is TRUE. \r
+ Translator - A pointr to the transaction translator data.\r
+ CallBackFunction - The Callback function.This function is called at the \r
+ rate specified by PollingInterval.This parameter is \r
+ only required when IsNewTransfer is TRUE. \r
+ Context - The context that is passed to the CallBackFunction.\r
+ - This is an optional parameter and may be NULL.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The asynchronous interrupt transfer request has been successfully \r
+ submitted or canceled.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_OUT_OF_RESOURCES \r
+ The request could not be completed due to a lack of resources. \r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BOOLEAN IsSlowDevice;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->AsyncInterruptTransfer (\r
+ UsbBusDev->Usb2HCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DeviceSpeed,\r
+ MaximumPacketLength,\r
+ IsNewTransfer,\r
+ DataToggle,\r
+ PollingInterval,\r
+ DataLength,\r
+ Translator,\r
+ CallBackFunction,\r
+ Context\r
+ );\r
+ } else {\r
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+ Status = UsbBusDev->UsbHCInterface->AsyncInterruptTransfer (\r
+ UsbBusDev->UsbHCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ IsSlowDevice,\r
+ (UINT8) MaximumPacketLength,\r
+ IsNewTransfer,\r
+ DataToggle,\r
+ PollingInterval,\r
+ DataLength,\r
+ CallBackFunction,\r
+ Context\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSyncInterruptTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint \r
+ of a USB device for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB, \r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - The combination of an endpoint number and an endpoint \r
+ direction of the target USB device. Each endpoint \r
+ address supports data transfer in one direction \r
+ except the control endpoint (whose default \r
+ endpoint address is 0). It is the caller's responsibility\r
+ to make sure that the EndPointAddress represents \r
+ an interrupt endpoint. \r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint \r
+ is capable of sending or receiving.\r
+ Data - A pointer to the buffer of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - On input, the size, in bytes, of the data buffer specified \r
+ by Data. On output, the number of bytes transferred.\r
+ DataToggle - A pointer to the data toggle value. On input, it indicates\r
+ the initial data toggle value the synchronous interrupt \r
+ transfer should adopt; \r
+ on output, it is updated to indicate the data toggle value \r
+ of the subsequent synchronous interrupt transfer. \r
+ TimeOut - Indicates the maximum time, in microseconds, which the \r
+ transfer is allowed to complete.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information from \r
+ the synchronous interrupt transfer. \r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The synchronous interrupt transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The synchronous interrupt transfer could not be submitted due \r
+ to lack of resource.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The synchronous interrupt transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The synchronous interrupt transfer failed due to host controller \r
+ or device error. Caller should check TranferResult for detailed \r
+ error information. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BOOLEAN IsSlowDevice;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->SyncInterruptTransfer (\r
+ UsbBusDev->Usb2HCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DeviceSpeed,\r
+ MaximumPacketLength,\r
+ Data,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ Translator,\r
+ TransferResult\r
+ );\r
+ } else {\r
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+ Status = UsbBusDev->UsbHCInterface->SyncInterruptTransfer (\r
+ UsbBusDev->UsbHCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ IsSlowDevice,\r
+ (UINT8) MaximumPacketLength,\r
+ Data,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcIsochronousTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits isochronous transfer to a target USB device\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - End point address\r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be \r
+ transmitted to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information generated \r
+ by this control transfer. \r
+ \r
+ Returns:\r
+ \r
+ EFI_UNSUPPORTED \r
+\r
+--*/\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcAsyncIsochronousTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Vitual interface to submits Async isochronous transfer to a target USB device\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - End point address\r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ Translator - A pointr to the transaction translator data.\r
+ IsochronousCallBack - When the transfer complete, the call back function will be called\r
+ Context - Pass to the call back function as parameter\r
+ \r
+ Returns:\r
+ \r
+ EFI_UNSUPPORTED \r
+\r
+--*/\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
#include "hub.h"\r
#include "usbutil.h"\r
\r
-//#ifdef EFI_DEBUG\r
extern UINTN gUSBDebugLevel;\r
extern UINTN gUSBErrorLevel;\r
-//#endif\r
\r
-#define MICROSECOND 10000\r
-#define ONESECOND (1000 * MICROSECOND)\r
+#define MICROSECOND 10000\r
+#define ONESECOND (1000 * MICROSECOND)\r
#define BUSPOLLING_PERIOD ONESECOND\r
//\r
// We define some maximun value here\r
struct _usb_bus_controller_device;\r
\r
typedef struct usb_io_device {\r
- UINT8 DeviceAddress;\r
- BOOLEAN IsConfigured;\r
- BOOLEAN IsSlowDevice;\r
- EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor;\r
- LIST_ENTRY ConfigDescListHead;\r
- CONFIG_DESC_LIST_ENTRY *ActiveConfig;\r
- UINT16 LangID[USB_MAXLANID];\r
+ UINT8 DeviceAddress;\r
+ BOOLEAN IsConfigured;\r
+ BOOLEAN IsSlowDevice;\r
+ UINT8 DeviceSpeed;\r
+ EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator;\r
+ EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor;\r
+ LIST_ENTRY ConfigDescListHead;\r
+ CONFIG_DESC_LIST_ENTRY *ActiveConfig;\r
+ UINT16 LangID[USB_MAXLANID];\r
\r
- struct _usb_bus_controller_device *BusController;\r
+ struct _usb_bus_controller_device *BusController;\r
\r
//\r
// Track the controller handle\r
//\r
- UINT8 NumOfControllers;\r
- USB_IO_CONTROLLER_DEVICE *UsbController[USB_MAXCONTROLLERS];\r
+ UINT8 NumOfControllers;\r
+ USB_IO_CONTROLLER_DEVICE *UsbController[USB_MAXCONTROLLERS];\r
\r
} USB_IO_DEVICE;\r
\r
UINTN Signature;\r
\r
EFI_USB_BUS_PROTOCOL BusIdentify;\r
+ EFI_USB2_HC_PROTOCOL *Usb2HCInterface;\r
EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
UINT8 AddressPool[16];\r
USB_IO_DEVICE *Root;\r
+ BOOLEAN Hc2ProtocolSupported;\r
} USB_BUS_CONTROLLER_DEVICE;\r
\r
#define USB_BUS_CONTROLLER_DEVICE_FROM_THIS(a) \\r
BOOLEAN\r
IsHub (\r
IN USB_IO_CONTROLLER_DEVICE *Dev\r
- );\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Tell if a usb controller is a hub controller.\r
+ \r
+ Arguments:\r
+ Dev - UsbIoController device structure.\r
+ \r
+ Returns:\r
+ TRUE/FALSE\r
+--*/\r
+;\r
\r
EFI_STATUS\r
UsbGetStringtable (\r
IN USB_IO_DEVICE *UsbIoDevice\r
- );\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Get the string table stored in a usb device.\r
+ \r
+ Arguments:\r
+ Dev - UsbIoController device structure.\r
+ \r
+ Returns:\r
+ EFI_SUCCESS\r
+ EFI_UNSUPPORTED\r
+ EFI_OUT_OF_RESOURCES\r
+ \r
+--*/\r
+;\r
\r
EFI_STATUS\r
UsbGetAllConfigurations (\r
IN USB_IO_DEVICE *UsbIoDevice\r
- );\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ This function is to parse all the configuration descriptor.\r
+ \r
+ Arguments:\r
+ UsbIoDevice - USB_IO_DEVICE device structure.\r
+ \r
+ Returns:\r
+ EFI_SUCCESS\r
+ EFI_DEVICE_ERROR\r
+ EFI_OUT_OF_RESOURCES \r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
UsbSetConfiguration (\r
IN USB_IO_DEVICE *Dev,\r
IN UINTN ConfigurationValue\r
- );\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Set the device to a configuration value.\r
+ \r
+ Arguments:\r
+ UsbIoDev - USB_IO_DEVICE to be set configuration\r
+ ConfigrationValue - The configuration value to be set to that device\r
+ \r
+ Returns:\r
+ EFI_SUCCESS\r
+ EFI_DEVICE_ERROR\r
+ \r
+--*/\r
+;\r
\r
EFI_STATUS\r
UsbSetDefaultConfiguration (\r
IN USB_IO_DEVICE *Dev\r
- );\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Set the device to a default configuration value.\r
+ \r
+ Arguments:\r
+ UsbIoDev - USB_IO_DEVICE to be set configuration\r
+ \r
+ Returns\r
+ EFI_SUCCESS\r
+ EFI_DEVICE_ERROR\r
+ \r
+--*/\r
+;\r
\r
//\r
// Device Deconfiguration functions\r
VOID\r
UsbDestroyAllConfiguration (\r
IN USB_IO_DEVICE *UsbIoDevice\r
- );\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Delete all configuration data when device is not used.\r
+ \r
+ Arguments:\r
+ UsbIoDevice - USB_IO_DEVICE to be set configuration\r
+ \r
+ Returns:\r
+ VOID\r
+ \r
+--*/\r
+;\r
\r
EFI_STATUS\r
DoHubConfig (\r
IN USB_IO_CONTROLLER_DEVICE *HubIoDevice\r
- );\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Configure the hub\r
+ \r
+ Arguments:\r
+ HubController - Indicating the hub controller device that\r
+ will be configured\r
+ \r
+ Returns:\r
+ EFI_SUCCESS\r
+ EFI_DEVICE_ERROR\r
+ \r
+--*/\r
+\r
+;\r
\r
VOID\r
GetDeviceEndPointMaxPacketLength (\r
IN EFI_USB_IO_PROTOCOL *UsbIo,\r
IN UINT8 EndpointAddr,\r
- OUT UINT8 *MaxPacketLength\r
- );\r
+ OUT UINTN *MaxPacketLength\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Get the Max Packet Length of the speified Endpoint.\r
+\r
+ Arguments:\r
+ UsbIo - Given Usb Controller device.\r
+ EndpointAddr - Given Endpoint address.\r
+ MaxPacketLength - The max packet length of that endpoint\r
+\r
+ Returns:\r
+ N/A\r
+\r
+--*/\r
+;\r
\r
VOID\r
GetDataToggleBit (\r
IN EFI_USB_IO_PROTOCOL *UsbIo,\r
IN UINT8 EndpointAddr,\r
OUT UINT8 *DataToggle\r
- );\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Get the datatoggle of a specified endpoint.\r
+\r
+ Arguments:\r
+ UsbIo - Given Usb Controller device.\r
+ EndpointAddr - Given Endpoint address.\r
+ DataToggle - The current data toggle of that endpoint\r
+\r
+ Returns:\r
+ VOID\r
+ \r
+--*/\r
+;\r
\r
VOID\r
SetDataToggleBit (\r
IN EFI_USB_IO_PROTOCOL *UsbIo,\r
IN UINT8 EndpointAddr,\r
IN UINT8 DataToggle\r
- );\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Set the datatoggle of a specified endpoint\r
+\r
+ Arguments:\r
+ UsbIo - Given Usb Controller device.\r
+ EndpointAddr - Given Endpoint address.\r
+ DataToggle - The current data toggle of that endpoint to be set\r
+\r
+ Returns:\r
+ VOID\r
+\r
+--*/\r
+;\r
\r
-INTERFACE_DESC_LIST_ENTRY *\r
+INTERFACE_DESC_LIST_ENTRY *\r
FindInterfaceListEntry (\r
IN EFI_USB_IO_PROTOCOL *This\r
- );\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Find Interface ListEntry.\r
\r
-ENDPOINT_DESC_LIST_ENTRY *\r
+ Arguments:\r
+ This - EFI_USB_IO_PROTOCOL \r
+ \r
+ Returns:\r
+ INTERFACE_DESC_LIST_ENTRY pointer\r
+\r
+--*/\r
+;\r
+\r
+ENDPOINT_DESC_LIST_ENTRY *\r
FindEndPointListEntry (\r
IN EFI_USB_IO_PROTOCOL *This,\r
IN UINT8 EndPointAddress\r
- );\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Find EndPoint ListEntry.\r
\r
+ Arguments:\r
+ This - EFI_USB_IO_PROTOCOL \r
+ EndpointAddr - Endpoint address.\r
+ \r
+ Returns:\r
+ ENDPOINT_DESC_LIST_ENTRY pointer\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
IsDeviceDisconnected (\r
IN USB_IO_CONTROLLER_DEVICE *UsbIoController,\r
IN OUT BOOLEAN *Disconnected\r
- );\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Reset if the device is disconencted or not\r
+\r
+ Arguments:\r
+ UsbIoController - Indicating the Usb Controller Device.\r
+ Disconnected - Indicate whether the device is disconencted or not\r
+\r
+ Returns:\r
+ EFI_SUCCESS\r
+ EFI_DEVICE_ERROR\r
+\r
+--*/\r
+;\r
\r
EFI_STATUS\r
UsbDeviceDeConfiguration (\r
IN USB_IO_DEVICE *UsbIoDevice\r
- );\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Remove Device, Device Handles, Uninstall Protocols.\r
+\r
+ Arguments:\r
+ UsbIoDevice - The device to be deconfigured.\r
+\r
+ Returns: \r
+ EFI_SUCCESS\r
+ EFI_DEVICE_ERROR\r
+\r
+--*/\r
+;\r
\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetCapability (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ OUT UINT8 *MaxSpeed,\r
+ OUT UINT8 *PortNumber,\r
+ OUT UINT8 *Is64BitCapable\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to Retrieves the capablility of root hub ports \r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ MaxSpeed - A pointer to the number of the host controller.\r
+ PortNumber - A pointer to the number of the root hub ports.\r
+ Is64BitCapable - A pointer to the flag for whether controller supports \r
+ 64-bit memory addressing.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The host controller capability were retrieved successfully.\r
+ EFI_INVALID_PARAMETER \r
+ MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to retrieve the capabilities. \r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcReset (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT16 Attributes\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to provides software reset for the USB host controller\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ Attributes - A bit mask of the reset operation to perform. \r
+ See below for a list of the supported bit mask values.\r
+ \r
+ #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc\r
+ #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc\r
+ #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2\r
+ #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2\r
+\r
+ EFI_USB_HC_RESET_GLOBAL \r
+ If this bit is set, a global reset signal will be sent to the USB bus.\r
+ This resets all of the USB bus logic, including the USB host \r
+ controller hardware and all the devices attached on the USB bus.\r
+ EFI_USB_HC_RESET_HOST_CONTROLLER \r
+ If this bit is set, the USB host controller hardware will be reset. \r
+ No reset signal will be sent to the USB bus.\r
+ EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG\r
+ If this bit is set, a global reset signal will be sent to the USB bus.\r
+ This resets all of the USB bus logic, including the USB host \r
+ controller hardware and all the devices attached on the USB bus. \r
+ If this is an EHCI controller and the debug port has configured, then \r
+ this is will still reset the host controller.\r
+ EFI_USB_HC_RESET_HOST_WITH_DEBUG\r
+ If this bit is set, the USB host controller hardware will be reset. \r
+ If this is an EHCI controller and the debug port has been configured,\r
+ then this will still reset the host controller.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The reset operation succeeded.\r
+ EFI_INVALID_PARAMETER \r
+ Attributes is not valid.\r
+ EFI_UNSUPPOURTED\r
+ The type of reset specified by Attributes is not currently supported by\r
+ the host controller hardware.\r
+ EFI_ACCESS_DENIED\r
+ Reset operation is rejected due to the debug port being configured and \r
+ active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or \r
+ EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to\r
+ perform reset operation for this host controller.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to perform \r
+ the reset operation.\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetState (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ OUT EFI_USB_HC_STATE *State\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to retrieves current state of the USB host controller\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ State - A pointer to the EFI_USB_HC_STATE data structure that \r
+ indicates current state of the USB host controller. \r
+ Type EFI_USB_HC_STATE is defined below.\r
+ \r
+ typedef enum {\r
+ EfiUsbHcStateHalt,\r
+ EfiUsbHcStateOperational,\r
+ EfiUsbHcStateSuspend,\r
+ EfiUsbHcStateMaximum\r
+ } EFI_USB_HC_STATE;\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The state information of the host controller was returned in State.\r
+ EFI_INVALID_PARAMETER \r
+ State is NULL.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to retrieve the \r
+ host controller's current state. \r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSetState (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN EFI_USB_HC_STATE State\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to sets the USB host controller to a specific state\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ State - Indicates the state of the host controller that will be set.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The USB host controller was successfully placed in the state \r
+ specified by State.\r
+ EFI_INVALID_PARAMETER \r
+ State is invalid.\r
+ EFI_DEVICE_ERROR \r
+ Failed to set the state specified by State due to device error. \r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetRootHubPortStatus (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNumber,\r
+ OUT EFI_USB_PORT_STATUS *PortStatus\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to retrieves the current status of a USB root hub port\r
+ both for Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ PortNumber - Specifies the root hub port from which the status \r
+ is to be retrieved. This value is zero-based. For example, \r
+ if a root hub has two ports, then the first port is numbered 0,\r
+ and the second port is numbered 1.\r
+ PortStatus - A pointer to the current port status bits and \r
+ port status change bits. \r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS The status of the USB root hub port specified by PortNumber \r
+ was returned in PortStatus.\r
+ EFI_INVALID_PARAMETER PortNumber is invalid. \r
+ EFI_DEVICE_ERROR Can't read register \r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSetRootHubPortFeature (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Virual interface to sets a feature for the specified root hub port\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ PortNumber - Specifies the root hub port whose feature \r
+ is requested to be set.\r
+ PortFeature - Indicates the feature selector associated \r
+ with the feature set request. \r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The feature specified by PortFeature was set for the \r
+ USB root hub port specified by PortNumber.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid or PortFeature is invalid.\r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcClearRootHubPortFeature (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to clears a feature for the specified root hub port\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ PortNumber - Specifies the root hub port whose feature \r
+ is requested to be cleared.\r
+ PortFeature - Indicates the feature selector associated with the \r
+ feature clear request.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The feature specified by PortFeature was cleared for the \r
+ USB root hub port specified by PortNumber.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid or PortFeature is invalid.\r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcControlTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN EFI_USB_DEVICE_REQUEST *Request,\r
+ IN EFI_USB_DATA_DIRECTION TransferDirection,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits control transfer to a target USB device\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ DeviceSpeed - Indicates target device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ Request - A pointer to the USB device request that will be sent \r
+ to the USB device. \r
+ TransferDirection - Specifies the data direction for the transfer.\r
+ There are three values available, DataIn, DataOut \r
+ and NoData.\r
+ Data - A pointer to the buffer of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ TimeOut - Indicates the maximum time, in microseconds, \r
+ which the transfer is allowed to complete.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information generated \r
+ by this control transfer.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The control transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The control transfer could not be completed due to a lack of resources.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The control transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The control transfer failed due to host controller or device error. \r
+ Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcBulkTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits bulk transfer to a bulk endpoint of a USB device\r
+ both for Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration. \r
+ EndPointAddress - The combination of an endpoint number and an \r
+ endpoint direction of the target USB device. \r
+ Each endpoint address supports data transfer in \r
+ one direction except the control endpoint \r
+ (whose default endpoint address is 0). \r
+ It is the caller's responsibility to make sure that \r
+ the EndPointAddress represents a bulk endpoint. \r
+ DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL\r
+ and EFI_USB_SPEED_HIGH.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint\r
+ is capable of sending or receiving. \r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be transmitted \r
+ to USB device or received from USB device. \r
+ DataLength - When input, indicates the size, in bytes, of the data buffer\r
+ specified by Data. When output, indicates the actually \r
+ transferred data size. \r
+ DataToggle - A pointer to the data toggle value. On input, it indicates \r
+ the initial data toggle value the bulk transfer should adopt;\r
+ on output, it is updated to indicate the data toggle value \r
+ of the subsequent bulk transfer. \r
+ Translator - A pointr to the transaction translator data. \r
+ TimeOut - Indicates the maximum time, in microseconds, which the \r
+ transfer is allowed to complete. \r
+ TransferResult - A pointer to the detailed result information of the \r
+ bulk transfer.\r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The bulk transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The bulk transfer could not be submitted due to lack of resource.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The bulk transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The bulk transfer failed due to host controller or device error.\r
+ Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcAsyncInterruptTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE * UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN BOOLEAN IsNewTransfer,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN PollingInterval,\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,\r
+ IN VOID *Context OPTIONAL\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits an asynchronous interrupt transfer to an \r
+ interrupt endpoint of a USB device for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration. \r
+ EndPointAddress - The combination of an endpoint number and an endpoint \r
+ direction of the target USB device. Each endpoint address \r
+ supports data transfer in one direction except the \r
+ control endpoint (whose default endpoint address is 0). \r
+ It is the caller's responsibility to make sure that \r
+ the EndPointAddress represents an interrupt endpoint. \r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint\r
+ is capable of sending or receiving. \r
+ IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between\r
+ the host and the target interrupt endpoint. \r
+ If FALSE, the specified asynchronous interrupt pipe \r
+ is canceled. \r
+ DataToggle - A pointer to the data toggle value. On input, it is valid \r
+ when IsNewTransfer is TRUE, and it indicates the initial \r
+ data toggle value the asynchronous interrupt transfer \r
+ should adopt. \r
+ On output, it is valid when IsNewTransfer is FALSE, \r
+ and it is updated to indicate the data toggle value of \r
+ the subsequent asynchronous interrupt transfer. \r
+ PollingInterval - Indicates the interval, in milliseconds, that the \r
+ asynchronous interrupt transfer is polled. \r
+ This parameter is required when IsNewTransfer is TRUE. \r
+ DataLength - Indicates the length of data to be received at the \r
+ rate specified by PollingInterval from the target \r
+ asynchronous interrupt endpoint. This parameter \r
+ is only required when IsNewTransfer is TRUE. \r
+ Translator - A pointr to the transaction translator data.\r
+ CallBackFunction - The Callback function.This function is called at the \r
+ rate specified by PollingInterval.This parameter is \r
+ only required when IsNewTransfer is TRUE. \r
+ Context - The context that is passed to the CallBackFunction.\r
+ - This is an optional parameter and may be NULL.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The asynchronous interrupt transfer request has been successfully \r
+ submitted or canceled.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_OUT_OF_RESOURCES \r
+ The request could not be completed due to a lack of resources. \r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSyncInterruptTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint \r
+ of a USB device for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB, \r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - The combination of an endpoint number and an endpoint \r
+ direction of the target USB device. Each endpoint \r
+ address supports data transfer in one direction \r
+ except the control endpoint (whose default \r
+ endpoint address is 0). It is the caller's responsibility\r
+ to make sure that the EndPointAddress represents \r
+ an interrupt endpoint. \r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint \r
+ is capable of sending or receiving.\r
+ Data - A pointer to the buffer of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - On input, the size, in bytes, of the data buffer specified \r
+ by Data. On output, the number of bytes transferred.\r
+ DataToggle - A pointer to the data toggle value. On input, it indicates\r
+ the initial data toggle value the synchronous interrupt \r
+ transfer should adopt; \r
+ on output, it is updated to indicate the data toggle value \r
+ of the subsequent synchronous interrupt transfer. \r
+ TimeOut - Indicates the maximum time, in microseconds, which the \r
+ transfer is allowed to complete.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information from \r
+ the synchronous interrupt transfer. \r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The synchronous interrupt transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The synchronous interrupt transfer could not be submitted due \r
+ to lack of resource.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The synchronous interrupt transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The synchronous interrupt transfer failed due to host controller \r
+ or device error. Caller should check TranferResult for detailed \r
+ error information. \r
+ \r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcIsochronousTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits isochronous transfer to a target USB device\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - End point address\r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be \r
+ transmitted to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information generated \r
+ by this control transfer. \r
+ \r
+ Returns:\r
+ \r
+ EFI_UNSUPPORTED \r
+\r
+--*/\r
+;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcAsyncIsochronousTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Vitual interface to submits Async isochronous transfer to a target USB device\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - End point address\r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ Translator - A pointr to the transaction translator data.\r
+ IsochronousCallBack - When the transfer complete, the call back function will be called\r
+ Context - Pass to the call back function as parameter\r
+ \r
+ Returns:\r
+ \r
+ EFI_UNSUPPORTED \r
+\r
+--*/\r
+;\r
\r
#endif\r
--*/\r
{\r
USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
+\r
EFI_STATUS RetStatus;\r
- USB_IO_DEVICE *UsbIoDevice;\r
+ USB_IO_DEVICE *UsbIoDev;\r
UINT8 MaxPacketLength;\r
UINT32 TransferResult;\r
BOOLEAN Disconnected;\r
// to perform other parameters checking\r
//\r
UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
- UsbIoDevice = UsbIoController->UsbDevice;\r
- UsbHCInterface = UsbIoDevice->BusController->UsbHCInterface;\r
- MaxPacketLength = UsbIoDevice->DeviceDescriptor.MaxPacketSize0;\r
+ UsbIoDev = UsbIoController->UsbDevice;\r
+\r
+ MaxPacketLength = UsbIoDev->DeviceDescriptor.MaxPacketSize0;\r
\r
\r
if (Request->Request == USB_DEV_CLEAR_FEATURE && \r
return EFI_DEVICE_ERROR;\r
}\r
}\r
-\r
-\r
-\r
//\r
// using HostController's ControlTransfer to complete the request\r
//\r
- RetStatus = UsbHCInterface->ControlTransfer (\r
- UsbHCInterface,\r
- UsbIoDevice->DeviceAddress,\r
- UsbIoDevice->IsSlowDevice,\r
- MaxPacketLength,\r
- Request,\r
- Direction,\r
- Data,\r
- &DataLength,\r
- (UINTN) Timeout,\r
- &TransferResult\r
- );\r
+ RetStatus = UsbVirtualHcControlTransfer (\r
+ UsbIoDev->BusController,\r
+ UsbIoDev->DeviceAddress,\r
+ UsbIoDev->DeviceSpeed,\r
+ MaxPacketLength,\r
+ Request,\r
+ Direction,\r
+ Data,\r
+ &DataLength,\r
+ (UINTN) Timeout,\r
+ UsbIoDev->Translator,\r
+ &TransferResult\r
+ );\r
+\r
*Status = TransferResult;\r
\r
if (Request->Request == USB_DEV_CLEAR_FEATURE && \r
--*/\r
{\r
USB_IO_DEVICE *UsbIoDev;\r
- UINT8 MaxPacketLength;\r
+ UINTN MaxPacketLength;\r
UINT8 DataToggle;\r
UINT8 OldToggle;\r
EFI_STATUS RetStatus;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
+\r
USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;\r
UINT32 TransferResult;\r
-\r
- UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
- UsbIoDev = UsbIoController->UsbDevice;\r
- UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;\r
+ UINT8 DataBuffersNumber;\r
+ \r
+ DataBuffersNumber = 1;\r
+ UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
+ UsbIoDev = UsbIoController->UsbDevice;\r
\r
//\r
// Parameters Checking\r
//\r
// using HostController's BulkTransfer to complete the request\r
//\r
- RetStatus = UsbHCInterface->BulkTransfer (\r
- UsbHCInterface,\r
- UsbIoDev->DeviceAddress,\r
- DeviceEndpoint,\r
- MaxPacketLength,\r
- Data,\r
- DataLength,\r
- &DataToggle,\r
- Timeout,\r
- &TransferResult\r
- );\r
+ RetStatus = UsbVirtualHcBulkTransfer (\r
+ UsbIoDev->BusController,\r
+ UsbIoDev->DeviceAddress,\r
+ DeviceEndpoint,\r
+ UsbIoDev->DeviceSpeed,\r
+ MaxPacketLength,\r
+ DataBuffersNumber,\r
+ &Data,\r
+ DataLength,\r
+ &DataToggle,\r
+ Timeout,\r
+ UsbIoDev->Translator,\r
+ &TransferResult\r
+ );\r
\r
if (OldToggle != DataToggle) {\r
//\r
\r
--*/\r
{\r
- USB_IO_DEVICE *UsbIoDev;\r
- UINT8 MaxPacketLength;\r
- UINT8 DataToggle;\r
- UINT8 OldToggle;\r
- EFI_STATUS RetStatus;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
- USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
- ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;\r
+ USB_IO_DEVICE *UsbIoDev;\r
+ UINTN MaxPacketLength;\r
+ UINT8 DataToggle;\r
+ UINT8 OldToggle;\r
+ EFI_STATUS RetStatus;\r
+ USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
+ ENDPOINT_DESC_LIST_ENTRY *EndPointListEntry;\r
\r
//\r
// Parameters Checking\r
//\r
UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
UsbIoDev = UsbIoController->UsbDevice;\r
- UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;\r
-\r
GetDeviceEndPointMaxPacketLength (\r
This,\r
DeviceEndpoint,\r
//\r
// using HostController's SyncInterruptTransfer to complete the request\r
//\r
- RetStatus = UsbHCInterface->SyncInterruptTransfer (\r
- UsbHCInterface,\r
- UsbIoDev->DeviceAddress,\r
- DeviceEndpoint,\r
- UsbIoDev->IsSlowDevice,\r
- MaxPacketLength,\r
- Data,\r
- DataLength,\r
- &DataToggle,\r
- Timeout,\r
- Status\r
- );\r
+ RetStatus = UsbVirtualHcSyncInterruptTransfer (\r
+ UsbIoDev->BusController,\r
+ UsbIoDev->DeviceAddress,\r
+ DeviceEndpoint,\r
+ UsbIoDev->DeviceSpeed,\r
+ MaxPacketLength,\r
+ Data,\r
+ DataLength,\r
+ &DataToggle,\r
+ Timeout,\r
+ UsbIoDev->Translator,\r
+ Status\r
+ );\r
\r
if (OldToggle != DataToggle) {\r
//\r
the transfer is to be executed.\r
DataLength - Specifies the length, in bytes, of the data to be\r
received from the USB device.\r
- InterruptCallback - The Callback function. This function is called if\r
+ InterruptCallBack - The Callback function. This function is called if\r
the asynchronous interrupt transfer is completed.\r
Context - Passed to InterruptCallback \r
Returns:\r
\r
--*/\r
{\r
- USB_IO_DEVICE *UsbIoDev;\r
- UINT8 MaxPacketLength;\r
- UINT8 DataToggle;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
- EFI_STATUS RetStatus;\r
- USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
- ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;\r
+ USB_IO_DEVICE *UsbIoDev;\r
+ UINTN MaxPacketLength;\r
+ UINT8 DataToggle;\r
+ EFI_STATUS RetStatus;\r
+ USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
+ ENDPOINT_DESC_LIST_ENTRY *EndpointListEntry;\r
\r
//\r
// Check endpoint\r
\r
UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
UsbIoDev = UsbIoController->UsbDevice;\r
- UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;\r
\r
if (!IsNewTransfer) {\r
//\r
// Delete this transfer\r
//\r
- UsbHCInterface->AsyncInterruptTransfer (\r
- UsbHCInterface,\r
- UsbIoDev->DeviceAddress,\r
- DeviceEndpoint,\r
- UsbIoDev->IsSlowDevice,\r
- 0,\r
- FALSE,\r
- &DataToggle,\r
- PollingInterval,\r
- DataLength,\r
- NULL,\r
- NULL\r
- );\r
+ UsbVirtualHcAsyncInterruptTransfer (\r
+ UsbIoDev->BusController,\r
+ UsbIoDev->DeviceAddress,\r
+ DeviceEndpoint,\r
+ UsbIoDev->DeviceSpeed,\r
+ 0,\r
+ FALSE,\r
+ &DataToggle,\r
+ PollingInterval,\r
+ DataLength,\r
+ UsbIoDev->Translator,\r
+ NULL,\r
+ NULL\r
+ );\r
\r
//\r
// We need to store the toggle value\r
&DataToggle\r
);\r
\r
- RetStatus = UsbHCInterface->AsyncInterruptTransfer (\r
- UsbHCInterface,\r
- UsbIoDev->DeviceAddress,\r
- DeviceEndpoint,\r
- UsbIoDev->IsSlowDevice,\r
- MaxPacketLength,\r
- TRUE,\r
- &DataToggle,\r
- PollingInterval,\r
- DataLength,\r
- InterruptCallBack,\r
- Context\r
- );\r
+ RetStatus = UsbVirtualHcAsyncInterruptTransfer (\r
+ UsbIoDev->BusController,\r
+ UsbIoDev->DeviceAddress,\r
+ DeviceEndpoint,\r
+ UsbIoDev->DeviceSpeed,\r
+ MaxPacketLength,\r
+ TRUE,\r
+ &DataToggle,\r
+ PollingInterval,\r
+ DataLength,\r
+ UsbIoDev->Translator,\r
+ InterruptCallBack,\r
+ Context\r
+ );\r
\r
return RetStatus;\r
}\r
EFI_SUCCESS\r
EFI_NOT_FOUND\r
EFI_OUT_OF_RESOURCES\r
+ EFI_UNSUPPORTED\r
\r
--*/\r
{\r
Tell if there is a device connected to that port according to\r
the Port Status.\r
\r
- Parameters:\r
+ Arguments:\r
PortStatus - The status value of that port.\r
\r
- Return Value:\r
+ Returns:\r
TRUE\r
FALSE\r
\r
}\r
}\r
\r
-\r
BOOLEAN\r
IsPortSuspendChange (\r
IN UINT16 PortChangeStatus\r
}\r
}\r
\r
-\r
-INTERFACE_DESC_LIST_ENTRY* \r
+INTERFACE_DESC_LIST_ENTRY *\r
FindInterfaceListEntry (\r
IN EFI_USB_IO_PROTOCOL *This\r
)\r
{\r
USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
USB_IO_DEVICE *UsbIoDev;\r
- LIST_ENTRY *InterfaceListHead;\r
+ LIST_ENTRY *InterfaceListHead;\r
INTERFACE_DESC_LIST_ENTRY *InterfaceListEntry;\r
\r
UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);\r
Find EndPoint ListEntry.\r
\r
Arguments:\r
- This - EFI_USB_IO_PROTOCOL \r
- EndpointAddr - Endpoint address.\r
+ This - EFI_USB_IO_PROTOCOL \r
+ EndPointAddress - Endpoint address.\r
\r
Returns:\r
ENDPOINT_DESC_LIST_ENTRY pointer\r
GetDeviceEndPointMaxPacketLength (\r
IN EFI_USB_IO_PROTOCOL *UsbIo,\r
IN UINT8 EndpointAddr,\r
- OUT UINT8 *MaxPacketLength\r
+ OUT UINTN *MaxPacketLength\r
)\r
/*++\r
\r
return ;\r
}\r
\r
- *MaxPacketLength = (UINT8) (EndpointListEntry->EndpointDescriptor.MaxPacketSize);\r
+ *MaxPacketLength = (UINTN) (EndpointListEntry->EndpointDescriptor.MaxPacketSize);\r
\r
return ;\r
}\r
<Filename>Bus/Pci/IdeBus/Dxe/idebus.msa</Filename>\r
<Filename>Bus/Pci/PciBus/Dxe/PciBus.msa</Filename>\r
<Filename>Bus/Pci/Uhci/Dxe/Uhci.msa</Filename>\r
+ <Filename>Bus/Pci/Ehci/Dxe/Ehci.msa</Filename>\r
<Filename>Bus/Pci/Undi/RuntimeDxe/Undi.msa</Filename>\r
<Filename>Bus/Scsi/ScsiBus/Dxe/ScsiBus.msa</Filename>\r
<Filename>Bus/Scsi/ScsiDisk/Dxe/ScsiDisk.msa</Filename>\r
<Filename>Universal/Console/Terminal/Dxe/Terminal.msa</Filename>\r
<Filename>Universal/DataHub/DataHub/Dxe/DataHub.msa</Filename>\r
<Filename>Universal/DataHub/DataHubStdErr/Dxe/DataHubStdErr.msa</Filename>\r
+ <Filename>Universal/DevicePath/Dxe/DevicePath.msa</Filename>\r
<Filename>Universal/Debugger/Debugport/Dxe/DebugPort.msa</Filename>\r
<Filename>Universal/DebugSupport/Dxe/DebugSupport.msa</Filename>\r
<Filename>Universal/Disk/DiskIo/Dxe/DiskIo.msa</Filename>\r
--- /dev/null
+/*++
+
+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;
+}
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ DevicePathDriver.h\r
+ \r
+Abstract:\r
+ Definition for Device Path Utilities driver\r
+\r
+--*/\r
+\r
+#ifndef _DEVICE_PATH_DRIVER_H\r
+#define _DEVICE_PATH_DRIVER_H\r
+\r
+extern EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid;\r
+extern EFI_GUID mEfiDevicePathMessagingSASGuid;\r
+\r
+#define DEVICE_PATH_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('D', 'P', 'D', 'V')\r
+\r
+typedef struct {\r
+\r
+ UINT32 Signature;\r
+ EFI_HANDLE Handle;\r
+ //\r
+ // Produced protocols\r
+ //\r
+ EFI_DEVICE_PATH_UTILITIES_PROTOCOL DevicePathUtilities;\r
+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL DevicePathFromText;\r
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL DevicePathToText;\r
+\r
+} DEVICE_PATH_DRIVER_PRIVATE_DATA;\r
+\r
+#define MAX_CHAR 480\r
+\r
+#define MIN_ALIGNMENT_SIZE sizeof(UINTN)\r
+#define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)\r
+\r
+#define IS_COMMA(a) ((a) == L',')\r
+#define IS_HYPHEN(a) ((a) == L'-')\r
+#define IS_DOT(a) ((a) == L'.')\r
+#define IS_LEFT_PARENTH(a) ((a) == L'(')\r
+#define IS_RIGHT_PARENTH(a) ((a) == L')')\r
+#define IS_SLASH(a) ((a) == L'/')\r
+#define IS_NULL(a) ((a) == L'\0')\r
+\r
+#define DEVICE_NODE_END 1\r
+#define DEVICE_PATH_INSTANCE_END 2\r
+#define DEVICE_PATH_END 3\r
+\r
+#define SetDevicePathInstanceEndNode(a) { \\r
+ (a)->Type = END_DEVICE_PATH_TYPE; \\r
+ (a)->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; \\r
+ (a)->Length[0] = sizeof (EFI_DEVICE_PATH_PROTOCOL); \\r
+ (a)->Length[1] = 0; \\r
+ }\r
+\r
+//\r
+// Private Data structure\r
+//\r
+typedef struct {\r
+ CHAR16 *Str;\r
+ UINTN Len;\r
+ UINTN MaxLen;\r
+} POOL_PRINT;\r
+\r
+typedef struct {\r
+ UINT8 Type;\r
+ UINT8 SubType;\r
+ VOID (*Function) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);\r
+} DEVICE_PATH_TO_TEXT_TABLE;\r
+\r
+typedef struct {\r
+ CHAR16 *DevicePathNodeText;\r
+ EFI_DEVICE_PATH_PROTOCOL * (*Function) (CHAR16 *);\r
+} DEVICE_PATH_FROM_TEXT_TABLE;\r
+\r
+typedef struct {\r
+ BOOLEAN ClassExist;\r
+ UINT8 Class;\r
+ BOOLEAN SubClassExist;\r
+ UINT8 SubClass;\r
+} USB_CLASS_TEXT;\r
+\r
+#define USB_CLASS_AUDIO 1\r
+#define USB_CLASS_CDCCONTROL 2\r
+#define USB_CLASS_HID 3\r
+#define USB_CLASS_IMAGE 6\r
+#define USB_CLASS_PRINTER 7\r
+#define USB_CLASS_MASS_STORAGE 8\r
+#define USB_CLASS_HUB 9\r
+#define USB_CLASS_CDCDATA 10\r
+#define USB_CLASS_SMART_CARD 11\r
+#define USB_CLASS_VIDEO 14\r
+#define USB_CLASS_DIAGNOSTIC 220\r
+#define USB_CLASS_WIRELESS 224\r
+\r
+#define USB_CLASS_RESERVE 254\r
+#define USB_SUBCLASS_FW_UPDATE 1\r
+#define USB_SUBCLASS_IRDA_BRIDGE 2\r
+#define USB_SUBCLASS_TEST 3\r
+\r
+typedef struct {\r
+ EFI_DEVICE_PATH_PROTOCOL Header;\r
+ EFI_GUID Guid;\r
+ UINT8 VendorDefinedData[1];\r
+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH;\r
+\r
+typedef struct {\r
+ EFI_DEVICE_PATH_PROTOCOL Header;\r
+ EFI_GUID Guid;\r
+ UINT8 VendorDefinedData[1];\r
+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH;\r
+\r
+typedef struct {\r
+ EFI_DEVICE_PATH_PROTOCOL Header;\r
+ EFI_GUID Guid;\r
+ UINT8 VendorDefinedData[1];\r
+} VENDOR_DEFINED_MEDIA_DEVICE_PATH;\r
+\r
+typedef struct {\r
+ EFI_DEVICE_PATH_PROTOCOL Header;\r
+ UINT32 HID;\r
+ UINT32 UID;\r
+ UINT32 CID;\r
+ CHAR8 HidUidCidStr[3];\r
+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;\r
+\r
+typedef struct {\r
+ EFI_DEVICE_PATH_PROTOCOL Header;\r
+ UINT16 NetworkProtocol;\r
+ UINT16 LoginOption;\r
+ UINT16 Reserved;\r
+ UINT16 TargetPortalGroupTag;\r
+ UINT64 Lun;\r
+ CHAR16 iSCSITargetName[1];\r
+} ISCSI_DEVICE_PATH_WITH_NAME;\r
+\r
+typedef struct {\r
+ EFI_DEVICE_PATH_PROTOCOL Header;\r
+ EFI_GUID Guid;\r
+ UINT8 VendorDefinedData[1];\r
+} VENDOR_DEVICE_PATH_WITH_DATA;\r
+\r
+CHAR16 *\r
+ConvertDeviceNodeToText (\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Convert a device node to its text representation.\r
+\r
+ Arguments:\r
+ DeviceNode - Points to the device node to be converted.\r
+ DisplayOnly - If DisplayOnly is TRUE, then the shorter text representation\r
+ of the display node is used, where applicable. If DisplayOnly\r
+ is FALSE, then the longer text representation of the display node\r
+ is used.\r
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text\r
+ representation for a device node can be used, where applicable.\r
+\r
+ Returns:\r
+ A pointer - a pointer to the allocated text representation of the device node.\r
+ NULL - if DeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+CHAR16 *\r
+ConvertDevicePathToText (\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Convert a device path to its text representation.\r
+\r
+ Arguments:\r
+ DeviceNode - Points to the device path to be converted.\r
+ DisplayOnly - If DisplayOnly is TRUE, then the shorter text representation\r
+ of the display node is used, where applicable. If DisplayOnly\r
+ is FALSE, then the longer text representation of the display node\r
+ is used.\r
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text\r
+ representation for a device node can be used, where applicable.\r
+\r
+ Returns:\r
+ A pointer - a pointer to the allocated text representation of the device path.\r
+ NULL - if DeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+ConvertTextToDeviceNode (\r
+ IN CONST CHAR16 *TextDeviceNode\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Convert text to the binary representation of a device node.\r
+\r
+ Arguments:\r
+ TextDeviceNode - TextDeviceNode points to the text representation of a device\r
+ node. Conversion starts with the first character and continues\r
+ until the first non-device node character.\r
+\r
+ Returns:\r
+ A pointer - Pointer to the EFI device node.\r
+ NULL - if TextDeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+ConvertTextToDevicePath (\r
+ IN CONST CHAR16 *TextDevicePath\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Convert text to the binary representation of a device path.\r
+\r
+ Arguments:\r
+ TextDevicePath - TextDevicePath points to the text representation of a device\r
+ path. Conversion starts with the first character and continues\r
+ until the first non-device node character.\r
+\r
+ Returns:\r
+ A pointer - Pointer to the allocated device path.\r
+ NULL - if TextDeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+UINTN\r
+GetDevicePathSize (\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Returns the size of the device path, in bytes.\r
+\r
+ Arguments:\r
+ DevicePath - Points to the start of the EFI device path.\r
+\r
+ Returns:\r
+ Size - Size of the specified device path, in bytes, including the end-of-path tag.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+DuplicateDevicePath (\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Create a duplicate of the specified path.\r
+\r
+ Arguments:\r
+ DevicePath - Points to the source EFI device path.\r
+\r
+ Returns:\r
+ Pointer - A pointer to the duplicate device path.\r
+ NULL - Insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+AppendDevicePath (\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Create a new path by appending the second device path to the first.\r
+\r
+ Arguments:\r
+ Src1 - Points to the first device path. If NULL, then it is ignored.\r
+ Src2 - Points to the second device path. If NULL, then it is ignored.\r
+\r
+ Returns:\r
+ Pointer - A pointer to the newly created device path.\r
+ NULL - Memory could not be allocated\r
+ or either DevicePath or DeviceNode is NULL.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+AppendDeviceNode (\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Creates a new path by appending the device node to the device path.\r
+\r
+ Arguments:\r
+ DevicePath - Points to the device path.\r
+ DeviceNode - Points to the device node.\r
+\r
+ Returns:\r
+ Pointer - A pointer to the allocated device node.\r
+ NULL - Memory could not be allocated\r
+ or either DevicePath or DeviceNode is NULL.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+AppendDevicePathInstance (\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Creates a new path by appending the specified device path instance to the specified device path.\r
+\r
+ Arguments:\r
+ DevicePath - Points to the device path. If NULL, then ignored.\r
+ DevicePathInstance - Points to the device path instance.\r
+\r
+ Returns:\r
+ Pointer - A pointer to the newly created device path\r
+ NULL - Memory could not be allocated or DevicePathInstance is NULL.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+GetNextDevicePathInstance (\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance,\r
+ OUT UINTN *DevicePathInstanceSize\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Creates a copy of the current device path instance and returns a pointer to the next device path instance.\r
+\r
+ Arguments:\r
+ DevicePathInstance - On input, this holds the pointer to the current device path\r
+ instance. On output, this holds the pointer to the next\r
+ device path instance or NULL if there are no more device\r
+ path instances in the device path.\r
+ DevicePathInstanceSize - On output, this holds the size of the device path instance,\r
+ in bytes or zero, if DevicePathInstance is zero.\r
+\r
+ Returns:\r
+ Pointer - A pointer to the copy of the current device path instance.\r
+ NULL - DevicePathInstace was NULL on entry or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+BOOLEAN\r
+IsDevicePathMultiInstance (\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Returns whether a device path is multi-instance.\r
+\r
+ Arguments:\r
+ DevicePath - Points to the device path. If NULL, then ignored.\r
+\r
+ Returns:\r
+ TRUE - The device path has more than one instance\r
+ FALSE - The device path is empty or contains only a single instance.\r
+\r
+--*/\r
+;\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+CreateDeviceNode (\r
+ IN UINT8 NodeType,\r
+ IN UINT8 NodeSubType,\r
+ IN UINT16 NodeLength\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Creates a device node\r
+\r
+ Arguments:\r
+ NodeType - NodeType is the device node type (EFI_DEVICE_PATH.Type) for\r
+ the new device node.\r
+ NodeSubType - NodeSubType is the device node sub-type\r
+ EFI_DEVICE_PATH.SubType) for the new device node.\r
+ NodeLength - NodeLength is the length of the device node\r
+ (EFI_DEVICE_PATH.Length) for the new device node.\r
+\r
+ Returns:\r
+ Pointer - A pointer to the newly created device node.\r
+ NULL - NodeLength is less than\r
+ the size of the header or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+#endif\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<!--Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.-->\r
+<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0">\r
+\r
+ <MsaHeader>\r
+ <ModuleName>DevicePath</ModuleName>\r
+ <ModuleType>DXE_DRIVER</ModuleType>\r
+ <GuidValue>9B680FCE-AD6B-4F3A-B60B-F59899003443</GuidValue>\r
+ <Version>1.0</Version>\r
+ <Abstract>Component description file for Device Path Driver.</Abstract>\r
+ <Description>This driver is for DevicePathUtilities, DevicePahtToText and DevicePathFromText</Description>\r
+ <Copyright>Copyright (c) 2006, Intel Corporation</Copyright>\r
+ <License>All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>\r
+ <Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>\r
+ </MsaHeader>\r
+ <ModuleDefinitions>\r
+ <SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>\r
+ <BinaryModule>false</BinaryModule>\r
+ <OutputFileBasename>DevicePath</OutputFileBasename>\r
+ </ModuleDefinitions>\r
+ <LibraryClassDefinitions>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>DebugLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>PrintLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiDriverEntryPoint</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>BaseMemoryLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>MemoryAllocationLib</Keyword>\r
+ </LibraryClass>\r
+ <LibraryClass Usage="ALWAYS_CONSUMED">\r
+ <Keyword>UefiBootServicesTableLib</Keyword>\r
+ </LibraryClass>\r
+ </LibraryClassDefinitions>\r
+ <SourceFiles>\r
+ <Filename>DevicePath.c</Filename>\r
+ <Filename>DevicePath.h</Filename>\r
+ <Filename>DevicePathFromText.c</Filename>\r
+ <Filename>DevicePathToText.c</Filename>\r
+ <Filename>DevicePathUtilities.c</Filename>\r
+ </SourceFiles>\r
+ <PackageDependencies>\r
+ <Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Package PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>\r
+ </PackageDependencies>\r
+ <Protocols> \r
+ <Protocol Usage="ALWAYS_CONSUMED">\r
+ <ProtocolCName>gEfiDebugPortProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="ALWAYS_CONSUMED">\r
+ <ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="ALWAYS_PRODUCED">\r
+ <ProtocolCName>gEfiDevicePathUtilitiesProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="ALWAYS_PRODUCED">\r
+ <ProtocolCName>gEfiDevicePathFromTextProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ <Protocol Usage="ALWAYS_PRODUCED">\r
+ <ProtocolCName>gEfiDevicePathToTextProtocolGuid</ProtocolCName>\r
+ </Protocol>\r
+ </Protocols>\r
+ <Guids>\r
+ <GuidCNames Usage="ALWAYS_CONSUMED">\r
+ <GuidCName>gEfiPcAnsiGuid</GuidCName>\r
+ </GuidCNames>\r
+ <GuidCNames Usage="ALWAYS_CONSUMED">\r
+ <GuidCName>gEfiVT100PlusGuid</GuidCName>\r
+ </GuidCNames>\r
+ <GuidCNames Usage="ALWAYS_CONSUMED">\r
+ <GuidCName>gEfiVT100Guid</GuidCName>\r
+ </GuidCNames>\r
+ <GuidCNames Usage="ALWAYS_CONSUMED">\r
+ <GuidCName>gEfiVTUTF8Guid</GuidCName>\r
+ </GuidCNames>\r
+ </Guids>\r
+ <Externs>\r
+ <Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>\r
+ <Specification>EDK_RELEASE_VERSION 0x00090000</Specification>\r
+ <Extern>\r
+ <ModuleEntryPoint>DevicePathEntryPoint</ModuleEntryPoint>\r
+ </Extern>\r
+ </Externs>\r
+</ModuleSurfaceArea>\r
--- /dev/null
+/*++
+
+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;
+}
--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ DevicePathToText.c\r
+\r
+Abstract:\r
+\r
+ DevicePathToText protocol as defined in the UEFI 2.0 specification.\r
+\r
+--*/\r
+\r
+#include <protocol/DevicePathToText.h>\r
+#include "DevicePath.h"\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+UnpackDevicePath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Function unpacks a device path data structure so that all the nodes of a device path \r
+ are naturally aligned.\r
+\r
+ Arguments:\r
+ DevPath - A pointer to a device path data structure\r
+\r
+ Returns:\r
+ If the memory for the device path is successfully allocated, then a pointer to the \r
+ new device path is returned. Otherwise, NULL is returned.\r
+\r
+--*/\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *Src;\r
+ EFI_DEVICE_PATH_PROTOCOL *Dest;\r
+ EFI_DEVICE_PATH_PROTOCOL *NewPath;\r
+ UINTN Size;\r
+\r
+ if (DevPath == NULL) {\r
+ return NULL;\r
+ }\r
+ //\r
+ // Walk device path and round sizes to valid boundries\r
+ //\r
+ Src = DevPath;\r
+ Size = 0;\r
+ for (;;) {\r
+ Size += DevicePathNodeLength (Src);\r
+ Size += ALIGN_SIZE (Size);\r
+\r
+ if (IsDevicePathEnd (Src)) {\r
+ break;\r
+ }\r
+\r
+ Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);\r
+ }\r
+ //\r
+ // Allocate space for the unpacked path\r
+ //\r
+ NewPath = AllocateZeroPool (Size);\r
+ if (NewPath != NULL) {\r
+\r
+ ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);\r
+\r
+ //\r
+ // Copy each node\r
+ //\r
+ Src = DevPath;\r
+ Dest = NewPath;\r
+ for (;;) {\r
+ Size = DevicePathNodeLength (Src);\r
+ CopyMem (Dest, Src, Size);\r
+ Size += ALIGN_SIZE (Size);\r
+ SetDevicePathNodeLength (Dest, Size);\r
+ Dest->Type |= EFI_DP_TYPE_UNPACKED;\r
+ Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);\r
+\r
+ if (IsDevicePathEnd (Src)) {\r
+ break;\r
+ }\r
+\r
+ Src = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (Src);\r
+ }\r
+ }\r
+\r
+ return NewPath;\r
+}\r
+\r
+VOID *\r
+ReallocatePool (\r
+ IN VOID *OldPool,\r
+ IN UINTN OldSize,\r
+ IN UINTN NewSize\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Adjusts the size of a previously allocated buffer.\r
+\r
+ Arguments:\r
+ OldPool - A pointer to the buffer whose size is being adjusted.\r
+ OldSize - The size of the current buffer.\r
+ NewSize - The size of the new buffer.\r
+\r
+ Returns:\r
+ EFI_SUCEESS - The requested number of bytes were allocated.\r
+ EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.\r
+ EFI_INVALID_PARAMETER - The buffer was invalid.\r
+\r
+--*/\r
+{\r
+ VOID *NewPool;\r
+\r
+ NewPool = NULL;\r
+ if (NewSize) {\r
+ NewPool = AllocateZeroPool (NewSize);\r
+ }\r
+\r
+ if (OldPool) {\r
+ if (NewPool) {\r
+ CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);\r
+ }\r
+\r
+ gBS->FreePool (OldPool);\r
+ }\r
+\r
+ return NewPool;\r
+}\r
+\r
+CHAR16 *\r
+CatPrint (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN CHAR16 *Fmt,\r
+ ...\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Concatenates a formatted unicode string to allocated pool. \r
+ The caller must free the resulting buffer.\r
+\r
+ Arguments:\r
+ Str - Tracks the allocated pool, size in use, and \r
+ amount of pool allocated.\r
+ Fmt - The format string\r
+\r
+ Returns:\r
+ Allocated buffer with the formatted string printed in it. \r
+ The caller must free the allocated buffer. The buffer\r
+ allocation is not packed.\r
+\r
+--*/\r
+{\r
+ UINT16 *AppendStr;\r
+ VA_LIST Args;\r
+ UINTN Size;\r
+\r
+ AppendStr = AllocateZeroPool (0x1000);\r
+ if (AppendStr == NULL) {\r
+ return Str->Str;\r
+ }\r
+\r
+ VA_START (Args, Fmt);\r
+ UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);\r
+ VA_END (Args);\r
+ if (NULL == Str->Str) {\r
+ Size = StrSize (AppendStr);\r
+ Str->Str = AllocateZeroPool (Size);\r
+ ASSERT (Str->Str != NULL);\r
+ } else {\r
+ Size = StrSize (AppendStr) + StrSize (Str->Str) - sizeof (UINT16);\r
+ Str->Str = ReallocatePool (\r
+ Str->Str,\r
+ StrSize (Str->Str),\r
+ Size\r
+ );\r
+ ASSERT (Str->Str != NULL);\r
+ }\r
+\r
+ Str->MaxLen = MAX_CHAR * sizeof (UINT16);\r
+ if (Size < Str->MaxLen) {\r
+ StrCat (Str->Str, AppendStr);\r
+ Str->Len = Size - sizeof (UINT16);\r
+ }\r
+\r
+ gBS->FreePool (AppendStr);\r
+ return Str->Str;\r
+}\r
+\r
+VOID\r
+DevPathToTextPci (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ PCI_DEVICE_PATH *Pci;\r
+\r
+ Pci = DevPath;\r
+ CatPrint (Str, L"Pci(%x,%x)", Pci->Function, Pci->Device);\r
+}\r
+\r
+VOID\r
+DevPathToTextPccard (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ PCCARD_DEVICE_PATH *Pccard;\r
+\r
+ Pccard = DevPath;\r
+ CatPrint (Str, L"PcCard(%x)", Pccard->FunctionNumber);\r
+}\r
+\r
+VOID\r
+DevPathToTextMemMap (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ MEMMAP_DEVICE_PATH *MemMap;\r
+\r
+ MemMap = DevPath;\r
+ CatPrint (\r
+ Str,\r
+ L"MemoryMapped(%lx,%lx)",\r
+ MemMap->StartingAddress,\r
+ MemMap->EndingAddress\r
+ );\r
+}\r
+\r
+VOID\r
+DevPathToTextVendor (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ VENDOR_DEVICE_PATH *Vendor;\r
+ CHAR16 *Type;\r
+ UINTN Index;\r
+ UINT32 FlowControlMap;\r
+ UINT16 Info;\r
+\r
+ Vendor = (VENDOR_DEVICE_PATH *) DevPath;\r
+ switch (DevicePathType (&Vendor->Header)) {\r
+ case HARDWARE_DEVICE_PATH:\r
+ Type = L"Hw";\r
+ break;\r
+\r
+ case MESSAGING_DEVICE_PATH:\r
+ Type = L"Msg";\r
+ if (AllowShortcuts) {\r
+ if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {\r
+ CatPrint (Str, L"VenPcAnsi()");\r
+ return ;\r
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {\r
+ CatPrint (Str, L"VenVt100()");\r
+ return ;\r
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {\r
+ CatPrint (Str, L"VenVt100Plus()");\r
+ return ;\r
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {\r
+ CatPrint (Str, L"VenUft8()");\r
+ return ;\r
+ } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingUartFlowControlGuid)) {\r
+ FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);\r
+ switch (FlowControlMap & 0x00000003) {\r
+ case 0:\r
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"None");\r
+ break;\r
+\r
+ case 1:\r
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");\r
+ break;\r
+\r
+ case 2:\r
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return ;\r
+ } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingSASGuid)) {\r
+ CatPrint (\r
+ Str,\r
+ L"SAS(%lx,%lx,%x,",\r
+ ((SAS_DEVICE_PATH *) Vendor)->SasAddress,\r
+ ((SAS_DEVICE_PATH *) Vendor)->Lun,\r
+ ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort\r
+ );\r
+ Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);\r
+ if ((Info & 0x0f) == 0) {\r
+ CatPrint (Str, L"NoTopology,0,0,0,");\r
+ } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {\r
+ CatPrint (\r
+ Str,\r
+ L"%s,%s,%s,",\r
+ (Info & (0x1 << 4)) ? L"SATA" : L"SAS",\r
+ (Info & (0x1 << 5)) ? L"External" : L"Internal",\r
+ (Info & (0x1 << 6)) ? L"Expanded" : L"Direct"\r
+ );\r
+ if ((Info & 0x0f) == 1) {\r
+ CatPrint (Str, L"0,");\r
+ } else {\r
+ CatPrint (Str, L"%x,", (Info >> 8) & 0xff);\r
+ }\r
+ } else {\r
+ CatPrint (Str, L"0,0,0,0,");\r
+ }\r
+\r
+ CatPrint (Str, L"%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);\r
+ return ;\r
+ } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {\r
+ CatPrint (Str, L"DebugPort()");\r
+ return ;\r
+ } else {\r
+ return ;\r
+ //\r
+ // reserved\r
+ //\r
+ }\r
+ }\r
+ break;\r
+\r
+ case MEDIA_DEVICE_PATH:\r
+ Type = L"Media";\r
+ break;\r
+\r
+ default:\r
+ Type = L"?";\r
+ break;\r
+ }\r
+\r
+ CatPrint (Str, L"Ven%s(%g,", Type, &Vendor->Guid);\r
+ for (Index = 0; Index < DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH); Index++) {\r
+ CatPrint (Str, L"%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);\r
+ }\r
+\r
+ CatPrint (Str, L")");\r
+}\r
+\r
+VOID\r
+DevPathToTextController (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ CONTROLLER_DEVICE_PATH *Controller;\r
+\r
+ Controller = DevPath;\r
+ CatPrint (\r
+ Str,\r
+ L"Ctrl(%x)",\r
+ (UINT16 *)Controller->ControllerNumber\r
+ );\r
+}\r
+\r
+VOID\r
+DevPathToTextAcpi (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ ACPI_HID_DEVICE_PATH *Acpi;\r
+\r
+ Acpi = DevPath;\r
+ if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {\r
+ if (AllowShortcuts) {\r
+ switch (EISA_ID_TO_NUM (Acpi->HID)) {\r
+ case 0x0a03:\r
+ CatPrint (Str, L"PciRoot(%x)", Acpi->UID);\r
+ break;\r
+\r
+ case 0x0604:\r
+ CatPrint (Str, L"Floppy(%x)", Acpi->UID);\r
+ break;\r
+\r
+ case 0x0301:\r
+ CatPrint (Str, L"Keyboard(%x)", Acpi->UID);\r
+ break;\r
+\r
+ case 0x0501:\r
+ CatPrint (Str, L"Serial(%x)", Acpi->UID);\r
+ break;\r
+\r
+ case 0x0401:\r
+ CatPrint (Str, L"ParallelPort(%x)", Acpi->UID);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return ;\r
+ }\r
+\r
+ CatPrint (Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);\r
+ } else {\r
+ CatPrint (Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);\r
+ }\r
+}\r
+\r
+#define NextStrA(a) ((UINT8 *) (((UINT8 *) (a)) + AsciiStrLen (a) + 1))\r
+\r
+VOID\r
+DevPathToTextExtAcpi (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR *AcpiExt;\r
+\r
+ AcpiExt = DevPath;\r
+\r
+ if (AllowShortcuts) {\r
+ if ((*(AcpiExt->HidUidCidStr) == '\0') &&\r
+ (*(NextStrA (NextStrA (AcpiExt->HidUidCidStr))) == '\0') &&\r
+ (AcpiExt->UID == 0)\r
+ ) {\r
+ if ((AcpiExt->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {\r
+ CatPrint (\r
+ Str,\r
+ L"AcpiExp(PNP%04x,%x,%a)",\r
+ EISA_ID_TO_NUM (AcpiExt->HID),\r
+ AcpiExt->CID,\r
+ NextStrA (AcpiExt->HidUidCidStr)\r
+ );\r
+ } else {\r
+ CatPrint (\r
+ Str,\r
+ L"AcpiExp(%08x,%x,%a)",\r
+ AcpiExt->HID,\r
+ AcpiExt->CID,\r
+ NextStrA (AcpiExt->HidUidCidStr)\r
+ );\r
+ }\r
+ }\r
+ return ;\r
+ }\r
+\r
+ if ((AcpiExt->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {\r
+ CatPrint (\r
+ Str,\r
+ L"AcpiEx(PNP%04x,%x,%x,%a,%a,%a)",\r
+ EISA_ID_TO_NUM (AcpiExt->HID),\r
+ AcpiExt->CID,\r
+ AcpiExt->UID,\r
+ AcpiExt->HidUidCidStr,\r
+ NextStrA (NextStrA (AcpiExt->HidUidCidStr)),\r
+ NextStrA (AcpiExt->HidUidCidStr)\r
+ );\r
+ } else {\r
+ CatPrint (\r
+ Str,\r
+ L"AcpiEx(%08x,%x,%x,%a,%a,%a)",\r
+ AcpiExt->HID,\r
+ AcpiExt->CID,\r
+ AcpiExt->UID,\r
+ AcpiExt->HidUidCidStr,\r
+ NextStrA (NextStrA (AcpiExt->HidUidCidStr)),\r
+ NextStrA (AcpiExt->HidUidCidStr)\r
+ );\r
+ }\r
+}\r
+\r
+VOID\r
+DevPathToTextAtapi (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ ATAPI_DEVICE_PATH *Atapi;\r
+\r
+ Atapi = DevPath;\r
+\r
+ if (DisplayOnly) {\r
+ CatPrint (Str, L"Ata(%x)", Atapi->Lun);\r
+ } else {\r
+ CatPrint (\r
+ Str,\r
+ L"Ata(%s,%s,%x)",\r
+ Atapi->PrimarySecondary ? L"Secondary" : L"Primary",\r
+ Atapi->SlaveMaster ? L"Slave" : L"Master",\r
+ Atapi->Lun\r
+ );\r
+ }\r
+}\r
+\r
+VOID\r
+DevPathToTextScsi (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ SCSI_DEVICE_PATH *Scsi;\r
+\r
+ Scsi = DevPath;\r
+ CatPrint (Str, L"Scsi(%x,%x)", Scsi->Pun, Scsi->Lun);\r
+}\r
+\r
+VOID\r
+DevPathToTextFibre (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ FIBRECHANNEL_DEVICE_PATH *Fibre;\r
+\r
+ Fibre = DevPath;\r
+ CatPrint (Str, L"Fibre(%lx,%lx)", Fibre->WWN, Fibre->Lun);\r
+}\r
+\r
+VOID\r
+DevPathToText1394 (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ F1394_DEVICE_PATH *F1394;\r
+\r
+ F1394 = DevPath;\r
+ CatPrint (Str, L"I1394(%lx)", F1394->Guid);\r
+}\r
+\r
+VOID\r
+DevPathToTextUsb (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ USB_DEVICE_PATH *Usb;\r
+\r
+ Usb = DevPath;\r
+ CatPrint (Str, L"USB(%x,%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);\r
+}\r
+\r
+VOID\r
+DevPathToTextUsbWWID (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ USB_WWID_DEVICE_PATH *UsbWWId;\r
+\r
+ UsbWWId = DevPath;\r
+ CatPrint (\r
+ Str,\r
+ L"UsbWwid(%x,%x,%x,\"WWID\")",\r
+ UsbWWId->VendorId,\r
+ UsbWWId->ProductId,\r
+ UsbWWId->InterfaceNumber\r
+ );\r
+}\r
+\r
+VOID\r
+DevPathToTextLogicalUnit (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;\r
+\r
+ LogicalUnit = DevPath;\r
+ CatPrint (Str, L"Unit(%x)", LogicalUnit->Lun);\r
+}\r
+\r
+VOID\r
+DevPathToTextUsbClass (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ USB_CLASS_DEVICE_PATH *UsbClass;\r
+\r
+ UsbClass = DevPath;\r
+\r
+ if (AllowShortcuts == TRUE) {\r
+ switch (UsbClass->DeviceClass) {\r
+ case 1:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbAudio(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 2:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbCDCControl(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 3:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbHID(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 6:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbImage(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 7:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbPrinter(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 8:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbMassStorage(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 9:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbHub(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 10:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbCDCData(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 11:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbSmartCard(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 14:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbVideo(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 220:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbDiagnostic(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 224:\r
+ CatPrint (\r
+ Str,\r
+ L"UsbWireless(%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ break;\r
+\r
+ case 254:\r
+ if (UsbClass->DeviceSubClass == 1) {\r
+ CatPrint (\r
+ Str,\r
+ L"UsbDeviceFirmwareUpdate(%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ } else if (UsbClass->DeviceSubClass == 2) {\r
+ CatPrint (\r
+ Str,\r
+ L"UsbIrdaBridge(%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ } else if (UsbClass->DeviceSubClass == 3) {\r
+ CatPrint (\r
+ Str,\r
+ L"UsbTestAndMeasurement(%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+ }\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ return ;\r
+ }\r
+\r
+ CatPrint (\r
+ Str,\r
+ L"UsbClass(%x,%x,%x,%x,%x)",\r
+ UsbClass->VendorId,\r
+ UsbClass->ProductId,\r
+ UsbClass->DeviceClass,\r
+ UsbClass->DeviceSubClass,\r
+ UsbClass->DeviceProtocol\r
+ );\r
+}\r
+\r
+VOID\r
+DevPathToTextI2O (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ I2O_DEVICE_PATH *I2O;\r
+\r
+ I2O = DevPath;\r
+ CatPrint (Str, L"I2O(%x)", I2O->Tid);\r
+}\r
+\r
+VOID\r
+DevPathToTextMacAddr (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ MAC_ADDR_DEVICE_PATH *MAC;\r
+ UINTN HwAddressSize;\r
+ UINTN Index;\r
+\r
+ MAC = DevPath;\r
+\r
+ HwAddressSize = sizeof (EFI_MAC_ADDRESS);\r
+ if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {\r
+ HwAddressSize = 6;\r
+ }\r
+\r
+ CatPrint (Str, L"MAC(");\r
+\r
+ for (Index = 0; Index < HwAddressSize; Index++) {\r
+ CatPrint (Str, L"%02x", MAC->MacAddress.Addr[Index]);\r
+ }\r
+\r
+ CatPrint (Str, L",%x)", MAC->IfType);\r
+}\r
+\r
+VOID\r
+DevPathToTextIPv4 (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ IPv4_DEVICE_PATH *IP;\r
+\r
+ IP = DevPath;\r
+ if (DisplayOnly == TRUE) {\r
+ CatPrint (\r
+ Str,\r
+ L"IPv4(%d.%d.%d.%d)",\r
+ IP->RemoteIpAddress.Addr[0],\r
+ IP->RemoteIpAddress.Addr[1],\r
+ IP->RemoteIpAddress.Addr[2],\r
+ IP->RemoteIpAddress.Addr[3]\r
+ );\r
+ return ;\r
+ }\r
+\r
+ CatPrint (\r
+ Str,\r
+ L"IPv4(%d.%d.%d.%d,%s,%s,%d.%d.%d.%d)",\r
+ IP->RemoteIpAddress.Addr[0],\r
+ IP->RemoteIpAddress.Addr[1],\r
+ IP->RemoteIpAddress.Addr[2],\r
+ IP->RemoteIpAddress.Addr[3],\r
+ IP->Protocol ? L"TCP" : L"UDP",\r
+ (IP->StaticIpAddress == TRUE) ? L"Static" : L"DHCP",\r
+ IP->LocalIpAddress.Addr[0],\r
+ IP->LocalIpAddress.Addr[1],\r
+ IP->LocalIpAddress.Addr[2],\r
+ IP->LocalIpAddress.Addr[3]\r
+ );\r
+}\r
+\r
+VOID\r
+DevPathToTextIPv6 (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ IPv6_DEVICE_PATH *IP;\r
+\r
+ IP = DevPath;\r
+ if (DisplayOnly == TRUE) {\r
+ CatPrint (\r
+ Str,\r
+ L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",\r
+ IP->RemoteIpAddress.Addr[0],\r
+ IP->RemoteIpAddress.Addr[1],\r
+ IP->RemoteIpAddress.Addr[2],\r
+ IP->RemoteIpAddress.Addr[3],\r
+ IP->RemoteIpAddress.Addr[4],\r
+ IP->RemoteIpAddress.Addr[5],\r
+ IP->RemoteIpAddress.Addr[6],\r
+ IP->RemoteIpAddress.Addr[7],\r
+ IP->RemoteIpAddress.Addr[8],\r
+ IP->RemoteIpAddress.Addr[9],\r
+ IP->RemoteIpAddress.Addr[10],\r
+ IP->RemoteIpAddress.Addr[11],\r
+ IP->RemoteIpAddress.Addr[12],\r
+ IP->RemoteIpAddress.Addr[13],\r
+ IP->RemoteIpAddress.Addr[14],\r
+ IP->RemoteIpAddress.Addr[15]\r
+ );\r
+ return ;\r
+ }\r
+\r
+ CatPrint (\r
+ Str,\r
+ 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)",\r
+ IP->RemoteIpAddress.Addr[0],\r
+ IP->RemoteIpAddress.Addr[1],\r
+ IP->RemoteIpAddress.Addr[2],\r
+ IP->RemoteIpAddress.Addr[3],\r
+ IP->RemoteIpAddress.Addr[4],\r
+ IP->RemoteIpAddress.Addr[5],\r
+ IP->RemoteIpAddress.Addr[6],\r
+ IP->RemoteIpAddress.Addr[7],\r
+ IP->RemoteIpAddress.Addr[8],\r
+ IP->RemoteIpAddress.Addr[9],\r
+ IP->RemoteIpAddress.Addr[10],\r
+ IP->RemoteIpAddress.Addr[11],\r
+ IP->RemoteIpAddress.Addr[12],\r
+ IP->RemoteIpAddress.Addr[13],\r
+ IP->RemoteIpAddress.Addr[14],\r
+ IP->RemoteIpAddress.Addr[15],\r
+ IP->Protocol ? L"TCP" : L"UDP",\r
+ (IP->StaticIpAddress == TRUE) ? L"Static" : L"DHCP",\r
+ IP->LocalIpAddress.Addr[0],\r
+ IP->LocalIpAddress.Addr[1],\r
+ IP->LocalIpAddress.Addr[2],\r
+ IP->LocalIpAddress.Addr[3],\r
+ IP->LocalIpAddress.Addr[4],\r
+ IP->LocalIpAddress.Addr[5],\r
+ IP->LocalIpAddress.Addr[6],\r
+ IP->LocalIpAddress.Addr[7],\r
+ IP->LocalIpAddress.Addr[8],\r
+ IP->LocalIpAddress.Addr[9],\r
+ IP->LocalIpAddress.Addr[10],\r
+ IP->LocalIpAddress.Addr[11],\r
+ IP->LocalIpAddress.Addr[12],\r
+ IP->LocalIpAddress.Addr[13],\r
+ IP->LocalIpAddress.Addr[14],\r
+ IP->LocalIpAddress.Addr[15]\r
+ );\r
+}\r
+\r
+VOID\r
+DevPathToTextInfiniBand (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ INFINIBAND_DEVICE_PATH *InfiniBand;\r
+\r
+ InfiniBand = DevPath;\r
+ CatPrint (\r
+ Str,\r
+ L"Infiniband(%x,%g,%lx,%lx,%lx)",\r
+ InfiniBand->ResourceFlags,\r
+ InfiniBand->PortGid,\r
+ InfiniBand->ServiceId,\r
+ InfiniBand->TargetPortId,\r
+ InfiniBand->DeviceId\r
+ );\r
+}\r
+\r
+VOID\r
+DevPathToTextUart (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ UART_DEVICE_PATH *Uart;\r
+ CHAR8 Parity;\r
+\r
+ Uart = DevPath;\r
+ switch (Uart->Parity) {\r
+ case 0:\r
+ Parity = 'D';\r
+ break;\r
+\r
+ case 1:\r
+ Parity = 'N';\r
+ break;\r
+\r
+ case 2:\r
+ Parity = 'E';\r
+ break;\r
+\r
+ case 3:\r
+ Parity = 'O';\r
+ break;\r
+\r
+ case 4:\r
+ Parity = 'M';\r
+ break;\r
+\r
+ case 5:\r
+ Parity = 'S';\r
+ break;\r
+\r
+ default:\r
+ Parity = 'x';\r
+ break;\r
+ }\r
+\r
+ if (Uart->BaudRate == 0) {\r
+ CatPrint (Str, L"Uart(DEFAULT,");\r
+ } else {\r
+ CatPrint (Str, L"Uart(%ld,", Uart->BaudRate);\r
+ }\r
+\r
+ if (Uart->DataBits == 0) {\r
+ CatPrint (Str, L"DEFAULT,");\r
+ } else {\r
+ CatPrint (Str, L"%d,", Uart->DataBits);\r
+ }\r
+\r
+ CatPrint (Str, L"%c,", Parity);\r
+\r
+ switch (Uart->StopBits) {\r
+ case 0:\r
+ CatPrint (Str, L"D)");\r
+ break;\r
+\r
+ case 1:\r
+ CatPrint (Str, L"1)");\r
+ break;\r
+\r
+ case 2:\r
+ CatPrint (Str, L"1.5)");\r
+ break;\r
+\r
+ case 3:\r
+ CatPrint (Str, L"2)");\r
+ break;\r
+\r
+ default:\r
+ CatPrint (Str, L"x)");\r
+ break;\r
+ }\r
+}\r
+\r
+VOID\r
+DevPathToTextiSCSI (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ ISCSI_DEVICE_PATH_WITH_NAME *iSCSI;\r
+ UINT16 Options;\r
+\r
+ iSCSI = DevPath;\r
+ CatPrint (\r
+ Str,\r
+ L"iSCSI(%s,%x,%lx,",\r
+ iSCSI->iSCSITargetName,\r
+ iSCSI->TargetPortalGroupTag,\r
+ iSCSI->Lun\r
+ );\r
+\r
+ Options = iSCSI->LoginOption;\r
+ CatPrint (Str, L"%s,", ((Options >> 1) & 0x0001) ? L"CRC32C" : L"None");\r
+ CatPrint (Str, L"%s,", ((Options >> 3) & 0x0001) ? L"CRC32C" : L"None");\r
+ if ((Options >> 11) & 0x0001) {\r
+ CatPrint (Str, L"%s,", L"None");\r
+ } else if ((Options >> 12) & 0x0001) {\r
+ CatPrint (Str, L"%s,", L"CHAP_UNI");\r
+ } else {\r
+ CatPrint (Str, L"%s,", L"CHAP_BI");\r
+\r
+ }\r
+\r
+ CatPrint (Str, L"%s)", (iSCSI->NetworkProtocol == 0) ? L"TCP" : L"reserved");\r
+}\r
+\r
+VOID\r
+DevPathToTextHardDrive (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ HARDDRIVE_DEVICE_PATH *Hd;\r
+\r
+ Hd = DevPath;\r
+ switch (Hd->SignatureType) {\r
+ case 0:\r
+ CatPrint (\r
+ Str,\r
+ L"HD(%d,%s,0,",\r
+ Hd->PartitionNumber,\r
+ L"None"\r
+ );\r
+ break;\r
+\r
+ case SIGNATURE_TYPE_MBR:\r
+ CatPrint (\r
+ Str,\r
+ L"HD(%d,%s,%08x,",\r
+ Hd->PartitionNumber,\r
+ L"MBR",\r
+ *((UINT32 *) (&(Hd->Signature[0])))\r
+ );\r
+ break;\r
+\r
+ case SIGNATURE_TYPE_GUID:\r
+ CatPrint (\r
+ Str,\r
+ L"HD(%d,%s,%g,",\r
+ Hd->PartitionNumber,\r
+ L"GUID",\r
+ (EFI_GUID *) &(Hd->Signature[0])\r
+ );\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ CatPrint (Str, L"%lx,%lx)", Hd->PartitionStart, Hd->PartitionSize);\r
+}\r
+\r
+VOID\r
+DevPathToTextCDROM (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ CDROM_DEVICE_PATH *Cd;\r
+\r
+ Cd = DevPath;\r
+ if (DisplayOnly == TRUE) {\r
+ CatPrint (Str, L"CDROM(%x)", Cd->BootEntry);\r
+ return ;\r
+ }\r
+\r
+ CatPrint (Str, L"CDROM(%x,%lx,%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);\r
+}\r
+\r
+VOID\r
+DevPathToTextFilePath (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ FILEPATH_DEVICE_PATH *Fp;\r
+\r
+ Fp = DevPath;\r
+ CatPrint (Str, L"%s", Fp->PathName);\r
+}\r
+\r
+VOID\r
+DevPathToTextMediaProtocol (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;\r
+\r
+ MediaProt = DevPath;\r
+ CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);\r
+}\r
+\r
+VOID\r
+DevPathToTextBBS (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ BBS_BBS_DEVICE_PATH *Bbs;\r
+ CHAR16 *Type;\r
+\r
+ Bbs = DevPath;\r
+ switch (Bbs->DeviceType) {\r
+ case BBS_TYPE_FLOPPY:\r
+ Type = L"Floppy";\r
+ break;\r
+\r
+ case BBS_TYPE_HARDDRIVE:\r
+ Type = L"HD";\r
+ break;\r
+\r
+ case BBS_TYPE_CDROM:\r
+ Type = L"CDROM";\r
+ break;\r
+\r
+ case BBS_TYPE_PCMCIA:\r
+ Type = L"PCMCIA";\r
+ break;\r
+\r
+ case BBS_TYPE_USB:\r
+ Type = L"USB";\r
+ break;\r
+\r
+ case BBS_TYPE_EMBEDDED_NETWORK:\r
+ Type = L"Network";\r
+ break;\r
+\r
+ default:\r
+ Type = L"?";\r
+ break;\r
+ }\r
+\r
+ CatPrint (Str, L"BBS(%s,%a", Type, Bbs->String);\r
+\r
+ if (DisplayOnly == TRUE) {\r
+ CatPrint (Str, L")");\r
+ return ;\r
+ }\r
+\r
+ CatPrint (Str, L",%x)", Bbs->StatusFlag);\r
+}\r
+\r
+VOID\r
+DevPathToTextEndInstance (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ CatPrint (Str, L",");\r
+}\r
+\r
+VOID\r
+DevPathToTextNodeUnknown (\r
+ IN OUT POOL_PRINT *Str,\r
+ IN VOID *DevPath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+{\r
+ CatPrint (Str, L"?");\r
+}\r
+\r
+DEVICE_PATH_TO_TEXT_TABLE DevPathToTextTable[] = {\r
+ HARDWARE_DEVICE_PATH,\r
+ HW_PCI_DP,\r
+ DevPathToTextPci,\r
+ HARDWARE_DEVICE_PATH,\r
+ HW_PCCARD_DP,\r
+ DevPathToTextPccard,\r
+ HARDWARE_DEVICE_PATH,\r
+ HW_MEMMAP_DP,\r
+ DevPathToTextMemMap,\r
+ HARDWARE_DEVICE_PATH,\r
+ HW_VENDOR_DP,\r
+ DevPathToTextVendor,\r
+ HARDWARE_DEVICE_PATH,\r
+ HW_CONTROLLER_DP,\r
+ DevPathToTextController,\r
+ ACPI_DEVICE_PATH,\r
+ ACPI_DP,\r
+ DevPathToTextAcpi,\r
+ ACPI_DEVICE_PATH,\r
+ ACPI_EXTENDED_DP,\r
+ DevPathToTextExtAcpi,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_ATAPI_DP,\r
+ DevPathToTextAtapi,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_SCSI_DP,\r
+ DevPathToTextScsi,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_FIBRECHANNEL_DP,\r
+ DevPathToTextFibre,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_1394_DP,\r
+ DevPathToText1394,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_USB_DP,\r
+ DevPathToTextUsb,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_USB_WWID_DP,\r
+ DevPathToTextUsbWWID,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_DEVICE_LOGICAL_UNIT_DP,\r
+ DevPathToTextLogicalUnit,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_USB_CLASS_DP,\r
+ DevPathToTextUsbClass,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_I2O_DP,\r
+ DevPathToTextI2O,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_MAC_ADDR_DP,\r
+ DevPathToTextMacAddr,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_IPv4_DP,\r
+ DevPathToTextIPv4,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_IPv6_DP,\r
+ DevPathToTextIPv6,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_INFINIBAND_DP,\r
+ DevPathToTextInfiniBand,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_UART_DP,\r
+ DevPathToTextUart,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_VENDOR_DP,\r
+ DevPathToTextVendor,\r
+ MESSAGING_DEVICE_PATH,\r
+ MSG_ISCSI_DP,\r
+ DevPathToTextiSCSI,\r
+ MEDIA_DEVICE_PATH,\r
+ MEDIA_HARDDRIVE_DP,\r
+ DevPathToTextHardDrive,\r
+ MEDIA_DEVICE_PATH,\r
+ MEDIA_CDROM_DP,\r
+ DevPathToTextCDROM,\r
+ MEDIA_DEVICE_PATH,\r
+ MEDIA_VENDOR_DP,\r
+ DevPathToTextVendor,\r
+ MEDIA_DEVICE_PATH,\r
+ MEDIA_FILEPATH_DP,\r
+ DevPathToTextFilePath,\r
+ MEDIA_DEVICE_PATH,\r
+ MEDIA_PROTOCOL_DP,\r
+ DevPathToTextMediaProtocol,\r
+ MEDIA_DEVICE_PATH,\r
+ MEDIA_FILEPATH_DP,\r
+ DevPathToTextFilePath,\r
+ BBS_DEVICE_PATH,\r
+ BBS_BBS_DP,\r
+ DevPathToTextBBS,\r
+ END_DEVICE_PATH_TYPE,\r
+ END_INSTANCE_DEVICE_PATH_SUBTYPE,\r
+ DevPathToTextEndInstance,\r
+ 0,\r
+ 0,\r
+ NULL\r
+};\r
+\r
+CHAR16 *\r
+ConvertDeviceNodeToText (\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Convert a device node to its text representation.\r
+\r
+ Arguments:\r
+ DeviceNode - Points to the device node to be converted.\r
+ DisplayOnly - If DisplayOnly is TRUE, then the shorter text representation\r
+ of the display node is used, where applicable. If DisplayOnly\r
+ is FALSE, then the longer text representation of the display node\r
+ is used.\r
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text\r
+ representation for a device node can be used, where applicable.\r
+\r
+ Returns:\r
+ A pointer - a pointer to the allocated text representation of the device node.\r
+ NULL - if DeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+{\r
+ POOL_PRINT Str;\r
+ UINTN Index;\r
+ UINTN NewSize;\r
+ VOID (*DumpNode)(POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);\r
+\r
+ if (DeviceNode == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ ZeroMem (&Str, sizeof (Str));\r
+\r
+ //\r
+ // Process the device path node\r
+ //\r
+ DumpNode = NULL;\r
+ for (Index = 0; DevPathToTextTable[Index].Function != NULL; Index++) {\r
+ if (DevicePathType (DeviceNode) == DevPathToTextTable[Index].Type &&\r
+ DevicePathSubType (DeviceNode) == DevPathToTextTable[Index].SubType\r
+ ) {\r
+ DumpNode = DevPathToTextTable[Index].Function;\r
+ break;\r
+ }\r
+ }\r
+ //\r
+ // If not found, use a generic function\r
+ //\r
+ if (DumpNode == NULL) {\r
+ DumpNode = DevPathToTextNodeUnknown;\r
+ }\r
+\r
+ //\r
+ // Print this node\r
+ //\r
+ DumpNode (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);\r
+\r
+ //\r
+ // Shrink pool used for string allocation\r
+ //\r
+ NewSize = (Str.Len + 1) * sizeof (CHAR16);\r
+ Str.Str = ReallocatePool (Str.Str, NewSize, NewSize);\r
+ ASSERT (Str.Str != NULL);\r
+ Str.Str[Str.Len] = 0;\r
+ return Str.Str;\r
+}\r
+\r
+CHAR16 *\r
+ConvertDevicePathToText (\r
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN BOOLEAN DisplayOnly,\r
+ IN BOOLEAN AllowShortcuts\r
+ )\r
+/*++\r
+\r
+ Routine Description:\r
+ Convert a device path to its text representation.\r
+\r
+ Arguments:\r
+ DeviceNode - Points to the device path to be converted.\r
+ DisplayOnly - If DisplayOnly is TRUE, then the shorter text representation\r
+ of the display node is used, where applicable. If DisplayOnly\r
+ is FALSE, then the longer text representation of the display node\r
+ is used.\r
+ AllowShortcuts - If AllowShortcuts is TRUE, then the shortcut forms of text\r
+ representation for a device node can be used, where applicable.\r
+\r
+ Returns:\r
+ A pointer - a pointer to the allocated text representation of the device path.\r
+ NULL - if DeviceNode is NULL or there was insufficient memory.\r
+\r
+--*/\r
+{\r
+ POOL_PRINT Str;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;\r
+ EFI_DEVICE_PATH_PROTOCOL *UnpackDevPath;\r
+ UINTN Index;\r
+ UINTN NewSize;\r
+ VOID (*DumpNode) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);\r
+\r
+ if (DevicePath == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ ZeroMem (&Str, sizeof (Str));\r
+\r
+ //\r
+ // Unpacked the device path\r
+ //\r
+ UnpackDevPath = UnpackDevicePath ((EFI_DEVICE_PATH_PROTOCOL *) DevicePath);\r
+ ASSERT (UnpackDevPath != NULL);\r
+\r
+ //\r
+ // Process each device path node\r
+ //\r
+ DevPathNode = UnpackDevPath;\r
+ while (!IsDevicePathEnd (DevPathNode)) {\r
+ //\r
+ // Find the handler to dump this device path node\r
+ //\r
+ DumpNode = NULL;\r
+ for (Index = 0; DevPathToTextTable[Index].Function; Index += 1) {\r
+\r
+ if (DevicePathType (DevPathNode) == DevPathToTextTable[Index].Type &&\r
+ DevicePathSubType (DevPathNode) == DevPathToTextTable[Index].SubType\r
+ ) {\r
+ DumpNode = DevPathToTextTable[Index].Function;\r
+ break;\r
+ }\r
+ }\r
+ //\r
+ // If not found, use a generic function\r
+ //\r
+ if (!DumpNode) {\r
+ DumpNode = DevPathToTextNodeUnknown;\r
+ }\r
+ //\r
+ // Put a path seperator in if needed\r
+ //\r
+ if (Str.Len && DumpNode != DevPathToTextEndInstance) {\r
+ if (*(Str.Str + Str.Len / sizeof (CHAR16) - 1) != L',') { \r
+ CatPrint (&Str, L"/");\r
+ } \r
+ }\r
+ //\r
+ // Print this node of the device path\r
+ //\r
+ DumpNode (&Str, DevPathNode, DisplayOnly, AllowShortcuts);\r
+\r
+ //\r
+ // Next device path node\r
+ //\r
+ DevPathNode = NextDevicePathNode (DevPathNode);\r
+ }\r
+ //\r
+ // Shrink pool used for string allocation\r
+ //\r
+ gBS->FreePool (UnpackDevPath);\r
+\r
+ NewSize = (Str.Len + 1) * sizeof (CHAR16);\r
+ Str.Str = ReallocatePool (Str.Str, NewSize, NewSize);\r
+ ASSERT (Str.Str != NULL);\r
+ Str.Str[Str.Len] = 0;\r
+ return Str.Str;\r
+}\r
--- /dev/null
+/*++
+
+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;
+}
<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"/>
<FfsFormatKey>BS_DRIVER</FfsFormatKey>
</ModuleSaBuildOptions>
</ModuleSA>
+ <ModuleSA SupArchList="IA32" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674" ModuleGuid="BDFE430E-8F2A-4db0-9991-6F856594777E">\r
+ <Libraries>\r
+ <Instance ModuleGuid="ff5c7a2c-ab7a-4366-8616-11c6e53247b6" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Instance ModuleGuid="f1bbe03d-2f28-4dee-bec7-d98d7a30c36a" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Instance ModuleGuid="3a004ba5-efe0-4a61-9f1a-267a46ae5ba9" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Instance ModuleGuid="331deb15-454b-48d8-9b74-70d01f3f3556" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Instance ModuleGuid="52af22ae-9901-4484-8cdc-622dd5838b09" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Instance ModuleGuid="3ddc3b12-99ea-4364-b315-6310a2050be5" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Instance ModuleGuid="bda39d3a-451b-4350-8266-81ab10fa0523" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Instance ModuleGuid="50bcb105-6634-441d-b403-659110a03ad2" PackageGuid="B6EC423C-21D2-490D-85C6-DD5864EAA674"/>\r
+ <Instance ModuleGuid="27d67720-ea68-48ae-93da-a3a074c90e30" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ <Instance ModuleGuid="4674739d-3195-4fb2-8094-ac1d22d00194" PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>\r
+ </Libraries>\r
+ <PcdBuildDefinition>\r
+ <PcdData ItemType="FIXED_AT_BUILD">\r
+ <C_Name>PcdMaximumUnicodeStringLength</C_Name>\r
+ <Token>0x00000001</Token>\r
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <DatumType>UINT32</DatumType>\r
+ <MaxDatumSize>4</MaxDatumSize>\r
+ <Value>1000000</Value>\r
+ </PcdData>\r
+ <PcdData ItemType="FIXED_AT_BUILD">\r
+ <C_Name>PcdMaximumAsciiStringLength</C_Name>\r
+ <Token>0x00000002</Token>\r
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <DatumType>UINT32</DatumType>\r
+ <MaxDatumSize>4</MaxDatumSize>\r
+ <Value>1000000</Value>\r
+ </PcdData>\r
+ <PcdData ItemType="FIXED_AT_BUILD">\r
+ <C_Name>PcdSpinLockTimeout</C_Name>\r
+ <Token>0x00000004</Token>\r
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <DatumType>UINT32</DatumType>\r
+ <MaxDatumSize>4</MaxDatumSize>\r
+ <Value>10000000</Value>\r
+ </PcdData>\r
+ <PcdData ItemType="FIXED_AT_BUILD">\r
+ <C_Name>PcdMaximumLinkedListLength</C_Name>\r
+ <Token>0x00000003</Token>\r
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <DatumType>UINT32</DatumType>\r
+ <MaxDatumSize>4</MaxDatumSize>\r
+ <Value>1000000</Value>\r
+ </PcdData>\r
+ <PcdData ItemType="FIXED_AT_BUILD">\r
+ <C_Name>PcdReportStatusCodePropertyMask</C_Name>\r
+ <Token>0x00000007</Token>\r
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <DatumType>UINT8</DatumType>\r
+ <MaxDatumSize>1</MaxDatumSize>\r
+ <Value>0x07</Value>\r
+ </PcdData>\r
+ <PcdData ItemType="FIXED_AT_BUILD">\r
+ <C_Name>PcdDebugPropertyMask</C_Name>\r
+ <Token>0x00000005</Token>\r
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <DatumType>UINT8</DatumType>\r
+ <MaxDatumSize>1</MaxDatumSize>\r
+ <Value>0x0f</Value>\r
+ </PcdData>\r
+ <PcdData ItemType="PATCHABLE_IN_MODULE">\r
+ <C_Name>PcdDebugPrintErrorLevel</C_Name>\r
+ <Token>0x00000006</Token>\r
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <DatumType>UINT32</DatumType>\r
+ <MaxDatumSize>4</MaxDatumSize>\r
+ <Value>0x80000000</Value>\r
+ </PcdData>\r
+ <PcdData ItemType="FIXED_AT_BUILD">\r
+ <C_Name>PcdDebugClearMemoryValue</C_Name>\r
+ <Token>0x00000008</Token>\r
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <DatumType>UINT8</DatumType>\r
+ <MaxDatumSize>1</MaxDatumSize>\r
+ <Value>0xAF</Value>\r
+ </PcdData>\r
+ <PcdData ItemType="FIXED_AT_BUILD">\r
+ <C_Name>PcdPerformanceLibraryPropertyMask</C_Name>\r
+ <Token>0x00000009</Token>\r
+ <TokenSpaceGuidCName>gEfiMdePkgTokenSpaceGuid</TokenSpaceGuidCName>\r
+ <DatumType>UINT8</DatumType>\r
+ <MaxDatumSize>1</MaxDatumSize>\r
+ <Value>0</Value>\r
+ </PcdData>\r
+ </PcdBuildDefinition>\r
+ <ModuleSaBuildOptions>\r
+ <FvBinding>FV_MAIN</FvBinding>\r
+ <FfsFormatKey>BS_DRIVER</FfsFormatKey>\r
+ </ModuleSaBuildOptions>\r
+ </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"/>
0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88 } \\r
}\r
\r
+#define EFI_UART_DEVICE_PATH_GUID \\r
+ { \\r
+ 0x37499a9d, 0x542f, 0x4c89, {0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 } \\r
+ }\r
+ \r
+#define EFI_SAS_DEVICE_PATH_GUID \\r
+ { \\r
+ 0xb4dd87d4, 0x8b00, 0xd911, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \\r
+ }\r
+\r
extern EFI_GUID gEfiPcAnsiGuid;\r
extern EFI_GUID gEfiVT100Guid;\r
extern EFI_GUID gEfiVT100PlusGuid;\r
#define USB_PORT_STAT_RESET 0x0010\r
#define USB_PORT_STAT_POWER 0x0100\r
#define USB_PORT_STAT_LOW_SPEED 0x0200\r
+#define USB_PORT_STAT_HIGH_SPEED 0x0400\r
+#define USB_PORT_STAT_OWNER 0x0800\r
\r
#define USB_PORT_STAT_C_CONNECTION 0x0001\r
#define USB_PORT_STAT_C_ENABLE 0x0002\r
EfiUsbPortSuspend = 2,\r
EfiUsbPortReset = 4,\r
EfiUsbPortPower = 8,\r
+ EfiUsbPortOwner = 13,\r
EfiUsbPortConnectChange = 16,\r
EfiUsbPortEnableChange = 17,\r
EfiUsbPortSuspendChange = 18,\r
; \r
\r
typedef struct {\r
- EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertDeviceNodeFromText;\r
- EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertDevicePathFromText;\r
+ EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode;\r
+ EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath;\r
} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL;\r
\r
extern EFI_GUID gEfiDevicePathFromTextProtocolGuid;\r
IN OUT UINT8 *DataToggle,\r
IN UINTN PollingInterval OPTIONAL,\r
IN UINTN DataLength OPTIONAL,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator OPTIONAL,\r
IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction OPTIONAL,\r
IN VOID *Context OPTIONAL\r
)\r
typedef\r
EFI_STATUS\r
(EFIAPI *EFI_USB2_HC_PROTOCOL_SYNC_INTERRUPT_TRANSFER) (\r
- IN EFI_USB2_HC_PROTOCOL *This,\r
- IN UINT8 DeviceAddress,\r
- IN UINT8 EndPointAddress,\r
- IN UINT8 DeviceSpeed,\r
- IN UINTN MaximumPacketLength,\r
- IN OUT VOID *Data,\r
- IN OUT UINTN *DataLength,\r
- IN OUT UINT8 *DataToggle,\r
- IN UINTN TimeOut,\r
- OUT UINT32 *TransferResult\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
)\r
;\r
\r
#define HW_CONTROLLER_DP 0x05\r
typedef struct {\r
EFI_DEVICE_PATH_PROTOCOL Header;\r
-#if EDK_RELEASE_VERSION >= 0x00020000\r
UINT32 ControllerNumber;\r
-#else\r
- UINT32 Controller;\r
-#endif\r
} CONTROLLER_DEVICE_PATH;\r
\r
//\r
UINT8 DeviceProtocol;\r
} USB_CLASS_DEVICE_PATH;\r
\r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
#define MSG_USB_WWID_DP 0x10\r
typedef struct {\r
EFI_DEVICE_PATH_PROTOCOL Header;\r
#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11\r
typedef struct {\r
EFI_DEVICE_PATH_PROTOCOL Header;\r
- UINT8 LUN;\r
+ UINT8 Lun;\r
} DEVICE_LOGICAL_UNIT_DEVICE_PATH;\r
+#endif\r
\r
#define MSG_I2O_DP 0x06\r
typedef struct {\r
#define DEVICE_PATH_MESSAGING_VT_100 EFI_VT_100_GUID\r
#define DEVICE_PATH_MESSAGING_VT_100_PLUS EFI_VT_100_PLUS_GUID\r
#define DEVICE_PATH_MESSAGING_VT_UTF8 EFI_VT_UTF8_GUID\r
-#define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID\r
\r
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)\r
+\r
+#define DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL EFI_UART_DEVICE_PATH_GUID\r
+#define DEVICE_PATH_MESSAGING_SAS EFI_SAS_DEVICE_PATH_GUID\r
+\r
+typedef struct {\r
+ EFI_DEVICE_PATH_PROTOCOL Header;\r
+ EFI_GUID Guid;\r
+ UINT32 FlowControlMap;\r
+} UART_FLOW_CONTROL_DEVICE_PATH;\r
+\r
+typedef struct {\r
+ EFI_DEVICE_PATH_PROTOCOL Header;\r
+ EFI_GUID Guid;\r
+ UINT32 Reserved;\r
+ UINT64 SasAddress;\r
+ UINT64 Lun;\r
+ UINT16 DeviceTopology;\r
+ UINT16 RelativeTargetPort;\r
+} SAS_DEVICE_PATH;\r
\r
#define MSG_ISCSI_DP 0x13\r
typedef struct {\r
#define ISCSI_LOGIN_OPTION_CHAP_BI 0x0000\r
#define ISCSI_LOGIN_OPTION_CHAP_UNI 0x2000\r
\r
+#endif\r
\r
//\r
// Media Device Path\r