summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c')
-rw-r--r--EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c2679
1 files changed, 0 insertions, 2679 deletions
diff --git a/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c b/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c
deleted file mode 100644
index 9065a2a886..0000000000
--- a/EdkModulePkg/Bus/Pci/Ehci/Dxe/Ehci.c
+++ /dev/null
@@ -1,2679 +0,0 @@
-/*++
-
-Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-Module Name:
-
- Ehci.c
-
-Abstract:
-
-
-Revision History
---*/
-
-
-#include "Ehci.h"
-
-
-GLOBAL_REMOVE_IF_UNREFERENCED UINTN gEHCDebugLevel = EFI_D_ERROR;
-GLOBAL_REMOVE_IF_UNREFERENCED UINTN gEHCErrorLevel = EFI_D_ERROR;
-
-
-//
-// Ehci Driver Global Variables
-//
-EFI_DRIVER_BINDING_PROTOCOL gEhciDriverBinding = {
- EhciDriverBindingSupported,
- EhciDriverBindingStart,
- EhciDriverBindingStop,
- 0xa,
- NULL,
- NULL
-};
-
-
-EFI_STATUS
-EFIAPI
-EhciDriverBindingSupported (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-/*++
-
- Routine Description:
-
- Test to see if this driver supports ControllerHandle. Any ControllerHandle
- that has Usb2HcProtocol installed will be supported.
-
- Arguments:
-
- This - Protocol instance pointer.
- Controlle - Handle of device to test
- RemainingDevicePath - Not used
-
- Returns:
-
- EFI_SUCCESS This driver supports this device.
- EFI_UNSUPPORTED This driver does not support this device.
-
---*/
-{
- EFI_STATUS Status;
- EFI_PCI_IO_PROTOCOL *PciIo;
- USB_CLASSC UsbClassCReg;
-
-
- //
- // Test whether there is PCI IO Protocol attached on the controller handle.
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- (VOID **) &PciIo,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- goto exit;
- }
-
- Status = PciIo->Pci.Read (
- PciIo,
- EfiPciIoWidthUint8,
- CLASSC,
- sizeof (USB_CLASSC) / sizeof (UINT8),
- &UsbClassCReg
- );
- if (EFI_ERROR (Status)) {
- gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- Status = EFI_UNSUPPORTED;
- goto exit;
- }
-
- //
- // Test whether the controller belongs to Ehci type
- //
- if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
- (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
- (UsbClassCReg.PI != PCI_CLASSC_PI_EHCI)
- ) {
-
- gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- Status = EFI_UNSUPPORTED;
- goto exit;
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciDriverBindingStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-/*++
-
- Routine Description:
-
- Starting the Usb EHCI Driver
-
- Arguments:
-
- This - Protocol instance pointer.
- Controller - Handle of device to test
- RemainingDevicePath - Not used
-
- Returns:
-
- EFI_SUCCESS supports this device.
- EFI_UNSUPPORTED do not support this device.
- EFI_DEVICE_ERROR cannot be started due to device Error
- EFI_OUT_OF_RESOURCES cannot allocate resources
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- EFI_PCI_IO_PROTOCOL *PciIo;
- UINT8 MaxSpeed;
- UINT8 PortNumber;
- UINT8 Is64BitCapable;
- UINT64 Supports;
-
- //
- // Open the PciIo Protocol
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- (VOID **) &PciIo,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto exit;
- }
-
- //
- // Enable the USB Host Controller
- //
- Status = PciIo->Attributes (
- PciIo,
- EfiPciIoAttributeOperationSupported,
- 0,
- &Supports
- );
- if (!EFI_ERROR (Status)) {
- Supports &= EFI_PCI_DEVICE_ENABLE;
- Status = PciIo->Attributes (
- PciIo,
- EfiPciIoAttributeOperationEnable,
- Supports,
- NULL
- );
- }
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto close_pciio_protocol;
- }
-
- //
- // Allocate memory for EHC private data structure
- //
- HcDev = AllocateZeroPool (sizeof (USB2_HC_DEV));
- if (NULL == HcDev) {
- Status = EFI_OUT_OF_RESOURCES;
- goto close_pciio_protocol;
- }
-
- //
- // Init EFI_USB2_HC_PROTOCOL interface and private data structure
- //
- HcDev->Usb2Hc.GetCapability = EhciGetCapability;
- HcDev->Usb2Hc.Reset = EhciReset;
- HcDev->Usb2Hc.GetState = EhciGetState;
- HcDev->Usb2Hc.SetState = EhciSetState;
- HcDev->Usb2Hc.ControlTransfer = EhciControlTransfer;
- HcDev->Usb2Hc.BulkTransfer = EhciBulkTransfer;
- HcDev->Usb2Hc.AsyncInterruptTransfer = EhciAsyncInterruptTransfer;
- HcDev->Usb2Hc.SyncInterruptTransfer = EhciSyncInterruptTransfer;
- HcDev->Usb2Hc.IsochronousTransfer = EhciIsochronousTransfer;
- HcDev->Usb2Hc.AsyncIsochronousTransfer = EhciAsyncIsochronousTransfer;
- HcDev->Usb2Hc.GetRootHubPortStatus = EhciGetRootHubPortStatus;
- HcDev->Usb2Hc.SetRootHubPortFeature = EhciSetRootHubPortFeature;
- HcDev->Usb2Hc.ClearRootHubPortFeature = EhciClearRootHubPortFeature;
- HcDev->Usb2Hc.MajorRevision = 0x1;
- HcDev->Usb2Hc.MinorRevision = 0x1;
-
- HcDev->AsyncRequestList = NULL;
- HcDev->ControllerNameTable = NULL;
- HcDev->Signature = USB2_HC_DEV_SIGNATURE;
- HcDev->PciIo = PciIo;
-
- //
- // Install USB2_HC_PROTOCOL
- //
- Status = gBS->InstallProtocolInterface (
- &Controller,
- &gEfiUsb2HcProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &HcDev->Usb2Hc
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto free_pool;
- }
-
- //
- // Get Capability Register Length
- //
- Status = GetCapabilityLen (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto uninstall_usb2hc_protocol;
- }
-
- ClearLegacySupport (HcDev);
- HostReset (HcDev);
-
- DEBUG_CODE (
- DumpEHCIPortsStatus (HcDev);
- );
-
- //
- // Create and Init Perodic Frame List
- //
- Status = EhciGetCapability (
- &HcDev->Usb2Hc,
- &MaxSpeed,
- &PortNumber,
- &Is64BitCapable
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto uninstall_usb2hc_protocol;
- }
- HcDev->Is64BitCapable = Is64BitCapable;
-
- //
- // Create and Init Perodic Frame List
- //
- Status = InitialPeriodicFrameList (
- HcDev,
- EHCI_MAX_FRAME_LIST_LENGTH
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto uninstall_usb2hc_protocol;
- }
-
- //
- // Init memory pool management
- //
- Status = InitialMemoryManagement (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto deinit_perodic_frame_list;
- }
-
- Status = CreateNULLQH (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto deinit_perodic_frame_list;
- }
- //
- // Create AsyncRequest Polling Timer
- //
- Status = CreatePollingTimer (HcDev, (EFI_EVENT_NOTIFY) AsyncRequestMoniter);
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto deinit_null_qh;
- }
-
- //
- // Default Maxximum Interrupt Interval is 8,
- // it means that 8 micro frame = 1ms
- //
-
- //
- // Start the Host Controller
- //
- if (IsEhcHalted (HcDev)) {
- Status = StartScheduleExecution (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto deinit_timer;
- }
- }
-
- //
- // Set all ports routing to EHC
- //
- Status = SetPortRoutingEhc (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto deinit_timer;
- }
-
- //
- // Component name protocol
- //
- Status = AddUnicodeString (
- "eng",
- gEhciComponentName.SupportedLanguages,
- &HcDev->ControllerNameTable,
- L"Usb Enhanced Host Controller"
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto deinit_timer;
- }
-
- goto exit;
-
- //
- // Error handle process
- //
-deinit_timer:
- DestoryPollingTimer (HcDev);
-deinit_null_qh:
- DestroyNULLQH(HcDev);
- DeinitialMemoryManagement (HcDev);
-deinit_perodic_frame_list:
- DeinitialPeriodicFrameList (HcDev);
-uninstall_usb2hc_protocol:
- gBS->UninstallProtocolInterface (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- &HcDev->Usb2Hc
- );
-free_pool:
- gBS->FreePool (HcDev);
-close_pciio_protocol:
- gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciDriverBindingStop (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN UINTN NumberOfChildren,
- IN EFI_HANDLE *ChildHandleBuffer
- )
-/*++
-
- Routine Description:
-
- Stop this driver on ControllerHandle. Support stoping any child handles
- created by this driver.
-
- Arguments:
-
- This - Protocol instance pointer.
- Controller - Handle of device to stop driver on
- NumberOfChildren - Number of Children in the ChildHandleBuffer
- ChildHandleBuffer - List of handles for the children we need to stop.
-
- Returns:
-
- EFI_SUCCESS Success
- EFI_DEVICE_ERROR Fail
---*/
-{
- EFI_STATUS Status;
- EFI_USB2_HC_PROTOCOL *Usb2Hc;
- USB2_HC_DEV *HcDev;
- UINT64 Supports;
-
- //
- // Test whether the Controller handler passed in is a valid
- // Usb controller handle that should be supported, if not,
- // return the error status directly
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- (VOID **) &Usb2Hc,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- HcDev = USB2_HC_DEV_FROM_THIS (Usb2Hc);
-
- //
- // free all the controller related memory and uninstall UHCI Protocol.
- //
- Status = gBS->UninstallProtocolInterface (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- Usb2Hc
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Set Host Controller state as halt
- //
- Status = Usb2Hc->SetState (
- Usb2Hc,
- EfiUsbHcStateHalt
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Stop AsyncRequest Polling Timer
- //
- Status = StopPollingTimer (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Destroy Asynchronous Request Event
- //
- DestoryPollingTimer (HcDev);
-
- //
- // Destroy Perodic Frame List
- //
- DeinitialPeriodicFrameList (HcDev);
-
- //
- // Destroy NULLQH
- //
- DestroyNULLQH (HcDev);
-
- //
- // Deinit Ehci pool memory management
- //
- DeinitialMemoryManagement (HcDev);
-
- //
- // Denint Unicode String Table
- //
- FreeUnicodeStringTable (HcDev->ControllerNameTable);
-
- //
- // Disable the USB Host Controller
- //
- Status = HcDev->PciIo->Attributes (
- HcDev->PciIo,
- EfiPciIoAttributeOperationSupported,
- 0,
- &Supports
- );
- if (!EFI_ERROR (Status)) {
- Supports &= EFI_PCI_DEVICE_ENABLE;
- Status = HcDev->PciIo->Attributes (
- HcDev->PciIo,
- EfiPciIoAttributeOperationDisable,
- Supports,
- NULL
- );
- }
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- gBS->FreePool (HcDev);
-
- gBS->CloseProtocol (
- Controller,
- &gEfiPciIoProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciGetCapability (
- IN EFI_USB2_HC_PROTOCOL *This,
- OUT UINT8 *MaxSpeed,
- OUT UINT8 *PortNumber,
- OUT UINT8 *Is64BitCapable
- )
-/*++
-
- Routine Description:
-
- Retrieves the capablility of root hub ports.
-
- Arguments:
-
- This - A pointer to the EFI_USB_HC_PROTOCOL instance.
- MaxSpeed - A pointer to the number of the host controller.
- PortNumber - A pointer to the number of the root hub ports.
- Is64BitCapable - A pointer to the flag for whether controller supports
- 64-bit memory addressing.
-
- Returns:
-
- EFI_SUCCESS host controller capability were retrieved successfully.
- EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
- EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the capabilities.
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINT32 HcStructParamsAddr;
- UINT32 HcStructParamsReg;
- UINT32 HcCapParamsAddr;
- UINT32 HcCapParamsReg;
-
- if (MaxSpeed == NULL || PortNumber == NULL || Is64BitCapable == NULL) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- HcStructParamsAddr = HCSPARAMS;
- HcCapParamsAddr = HCCPARAMS;
- HcDev = USB2_HC_DEV_FROM_THIS (This);
-
- Status = ReadEhcCapabiltiyReg (
- HcDev,
- HcStructParamsAddr,
- &HcStructParamsReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- Status = ReadEhcCapabiltiyReg (
- HcDev,
- HcCapParamsAddr,
- &HcCapParamsReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- *MaxSpeed = EFI_USB_SPEED_HIGH;
- *PortNumber = (UINT8) (HcStructParamsReg & HCSP_NPORTS);
- *Is64BitCapable = (UINT8) (HcCapParamsReg & HCCP_64BIT);
-
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciReset (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN UINT16 Attributes
- )
-/*++
-
- Routine Description:
-
- Provides software reset for the USB host controller.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
- Attributes - A bit mask of the reset operation to perform.
- See below for a list of the supported bit mask values.
-
- #define EFI_USB_HC_RESET_GLOBAL 0x0001
- #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002
- #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004
- #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008
-
- EFI_USB_HC_RESET_GLOBAL
- If this bit is set, a global reset signal will be sent to the USB bus.
- This resets all of the USB bus logic, including the USB host
- controller hardware and all the devices attached on the USB bus.
- EFI_USB_HC_RESET_HOST_CONTROLLER
- If this bit is set, the USB host controller hardware will be reset.
- No reset signal will be sent to the USB bus.
- EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
- If this bit is set, a global reset signal will be sent to the USB bus.
- This resets all of the USB bus logic, including the USB host
- controller hardware and all the devices attached on the USB bus.
- If this is an EHCI controller and the debug port has configured, then
- this is will still reset the host controller.
- EFI_USB_HC_RESET_HOST_WITH_DEBUG
- If this bit is set, the USB host controller hardware will be reset.
- If this is an EHCI controller and the debug port has been configured,
- then this will still reset the host controller.
-
- Returns:
-
- EFI_SUCCESS
- The reset operation succeeded.
- EFI_INVALID_PARAMETER
- Attributes is not valid.
- EFI_UNSUPPOURTED
- The type of reset specified by Attributes is not currently supported by
- the host controller hardware.
- EFI_ACCESS_DENIED
- Reset operation is rejected due to the debug port being configured and
- active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
- EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
- perform reset operation for this host controller.
- EFI_DEVICE_ERROR
- An error was encountered while attempting to perform
- the reset operation.
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINTN FrameIndex;
- FRAME_LIST_ENTRY *FrameEntryPtr;
-
- HcDev = USB2_HC_DEV_FROM_THIS (This);
-
- switch (Attributes) {
-
- case EFI_USB_HC_RESET_GLOBAL:
-
- //
- // Same behavior as Host Controller Reset
- //
-
- case EFI_USB_HC_RESET_HOST_CONTROLLER:
-
- //
- // Host Controller must be Halt when Reset it
- //
- if (IsEhcHalted (HcDev)) {
- Status = ResetEhc (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- //
- // Set to zero by Host Controller when reset process completes
- //
- Status = WaitForEhcReset (HcDev, EHCI_GENERIC_TIMEOUT);
- if (EFI_ERROR (Status)) {
- Status = EFI_TIMEOUT;
- goto exit;
- }
- } else {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // only asynchronous interrupt transfers are always alive on the bus, need to cleanup
- //
- CleanUpAllAsyncRequestTransfer (HcDev);
- Status = ClearEhcAllStatus (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Set appropriate 4G Segment Selector
- //
- Status = SetCtrlDataStructSeg (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Init Perodic List Base Addr and Frame List
- //
- Status = SetFrameListBaseAddr (
- HcDev,
- (UINT32)GET_0B_TO_31B (HcDev->PeriodicFrameListBuffer)
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- FrameEntryPtr = (FRAME_LIST_ENTRY *) HcDev->PeriodicFrameListBuffer;
- for (FrameIndex = 0; FrameIndex < HcDev->PeriodicFrameListLength; FrameIndex++) {
- FrameEntryPtr->LinkTerminate = TRUE;
- FrameEntryPtr++;
- }
-
- //
- // Start the Host Controller
- //
- if (IsEhcHalted (HcDev)) {
- Status = StartScheduleExecution (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- }
-
- //
- // Set all ports routing to EHC
- //
- Status = SetPortRoutingEhc (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- break;
-
- case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:
-
- Status = EFI_UNSUPPORTED;
- break;
-
- case EFI_USB_HC_RESET_HOST_WITH_DEBUG:
-
- Status = EFI_UNSUPPORTED;
- break;
-
- default:
- Status = EFI_INVALID_PARAMETER;
- }
-
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciGetState (
- IN EFI_USB2_HC_PROTOCOL *This,
- OUT EFI_USB_HC_STATE *State
- )
-/*++
-
- Routine Description:
-
- Retrieves current state of the USB host controller.
-
- Arguments:
-
- This A pointer to the EFI_USB2_HC_PROTOCOL instance.
- State A pointer to the EFI_USB_HC_STATE data structure that
- indicates current state of the USB host controller.
- Type EFI_USB_HC_STATE is defined below.
-
- typedef enum {
- EfiUsbHcStateHalt,
- EfiUsbHcStateOperational,
- EfiUsbHcStateSuspend,
- EfiUsbHcStateMaximum
- } EFI_USB_HC_STATE;
-
- Returns:
-
- EFI_SUCCESS
- The state information of the host controller was returned in State.
- EFI_INVALID_PARAMETER
- State is NULL.
- EFI_DEVICE_ERROR
- An error was encountered while attempting to retrieve the
- host controller's current state.
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINT32 UsbStatusAddr;
- UINT32 UsbStatusReg;
-
- if (State == NULL) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- UsbStatusAddr = USBSTS;
- HcDev = USB2_HC_DEV_FROM_THIS (This);
-
- Status = ReadEhcOperationalReg (
- HcDev,
- UsbStatusAddr,
- &UsbStatusReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- if (UsbStatusReg & USBSTS_HCH) {
- *State = EfiUsbHcStateHalt;
- } else {
- *State = EfiUsbHcStateOperational;
- }
-
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciSetState (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN EFI_USB_HC_STATE State
- )
-/*++
-
- Routine Description:
-
- Sets the USB host controller to a specific state.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
- State - Indicates the state of the host controller that will be set.
-
- Returns:
-
- EFI_SUCCESS
- The USB host controller was successfully placed in the state
- specified by State.
- EFI_INVALID_PARAMETER
- State is invalid.
- EFI_DEVICE_ERROR
- Failed to set the state specified by State due to device error.
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINT32 UsbCommandAddr;
- UINT32 UsbCommandReg;
- EFI_USB_HC_STATE CurrentState;
-
- UsbCommandAddr = USBCMD;
- HcDev = USB2_HC_DEV_FROM_THIS (This);
-
- Status = EhciGetState (This, &CurrentState);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- switch (State) {
-
- case EfiUsbHcStateHalt:
-
- if (EfiUsbHcStateHalt == CurrentState) {
- Status = EFI_SUCCESS;
- goto exit;
- } else if (EfiUsbHcStateOperational == CurrentState) {
- Status = ReadEhcOperationalReg (
- HcDev,
- UsbCommandAddr,
- &UsbCommandReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- UsbCommandReg &= ~USBCMD_RS;
- Status = WriteEhcOperationalReg (
- HcDev,
- UsbCommandAddr,
- UsbCommandReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- //
- // Ensure the HC is in halt status after send the stop command
- //
- Status = WaitForEhcHalt (HcDev, EHCI_GENERIC_TIMEOUT);
- if (EFI_ERROR (Status)) {
- Status = EFI_TIMEOUT;
- goto exit;
- }
- }
- break;
-
- case EfiUsbHcStateOperational:
-
- if (IsEhcSysError (HcDev)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- if (EfiUsbHcStateOperational == CurrentState) {
- Status = EFI_SUCCESS;
- goto exit;
- } else if (EfiUsbHcStateHalt == CurrentState) {
- //
- // Set Host Controller Run
- //
- Status = ReadEhcOperationalReg (
- HcDev,
- UsbCommandAddr,
- &UsbCommandReg
- );
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
-
- UsbCommandReg |= USBCMD_RS;
- Status = WriteEhcOperationalReg (
- HcDev,
- UsbCommandAddr,
- UsbCommandReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- }
- break;
-
- case EfiUsbHcStateSuspend:
-
- Status = EFI_UNSUPPORTED;
- break;
-
- default:
-
- Status = EFI_INVALID_PARAMETER;
- }
-
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciGetRootHubPortStatus (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN UINT8 PortNumber,
- OUT EFI_USB_PORT_STATUS *PortStatus
- )
-/*++
-
- Routine Description:
-
- Retrieves the current status of a USB root hub port.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL.
- PortNumber - Specifies the root hub port from which the status
- is to be retrieved. This value is zero-based. For example,
- if a root hub has two ports, then the first port is numbered 0,
- and the second port is numbered 1.
- PortStatus - A pointer to the current port status bits and
- port status change bits.
-
- Returns:
-
- EFI_SUCCESS The status of the USB root hub port specified
- by PortNumber was returned in PortStatus.
- EFI_INVALID_PARAMETER PortNumber is invalid.
- EFI_DEVICE_ERROR Can't read register
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINT32 PortStatusControlAddr;
- UINT32 PortStatusControlReg;
- UINT8 MaxSpeed;
- UINT8 TotalPortNumber;
- UINT8 Is64BitCapable;
-
- if (PortStatus == NULL) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- EhciGetCapability (
- This,
- &MaxSpeed,
- &TotalPortNumber,
- &Is64BitCapable
- );
-
- if (PortNumber >= TotalPortNumber) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- HcDev = USB2_HC_DEV_FROM_THIS (This);
- PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));
-
- //
- // Clear port status
- //
- PortStatus->PortStatus = 0;
- PortStatus->PortChangeStatus = 0;
-
- Status = ReadEhcOperationalReg (
- HcDev,
- PortStatusControlAddr,
- &PortStatusControlReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Fill Port Status bits
- //
-
- //
- // Current Connect Status
- //
- if (PORTSC_CCS & PortStatusControlReg) {
- PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
- }
- //
- // Port Enabled/Disabled
- //
- if (PORTSC_PED & PortStatusControlReg) {
- PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
- }
- //
- // Port Suspend
- //
- if (PORTSC_SUSP & PortStatusControlReg) {
- PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
- }
- //
- // Over-current Active
- //
- if (PORTSC_OCA & PortStatusControlReg) {
- PortStatus->PortStatus |= USB_PORT_STAT_OVERCURRENT;
- }
- //
- // Port Reset
- //
- if (PORTSC_PR & PortStatusControlReg) {
- PortStatus->PortStatus |= USB_PORT_STAT_RESET;
- }
- //
- // Port Power
- //
- if (PORTSC_PP & PortStatusControlReg) {
- PortStatus->PortStatus |= USB_PORT_STAT_POWER;
- }
- //
- // Port Owner
- //
- if (PORTSC_PO & PortStatusControlReg) {
- PortStatus->PortStatus |= USB_PORT_STAT_OWNER;
- }
- //
- // Identify device speed
- //
- if (PORTSC_LS_KSTATE & PortStatusControlReg) {
- //
- // Low Speed Device Attached
- //
- PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
- } else {
- //
- // Not Low Speed Device Attached
- //
- if ((PORTSC_CCS & PortStatusControlReg) && (PORTSC_CSC & PortStatusControlReg)) {
- HcDev->DeviceSpeed[PortNumber] = (UINT16) (IsHighSpeedDevice (This, PortNumber) ? USB_PORT_STAT_HIGH_SPEED : 0);
- }
- PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | HcDev->DeviceSpeed[PortNumber]);
- }
- //
- // Fill Port Status Change bits
- //
- //
- // Connect Status Change
- //
- if (PORTSC_CSC & PortStatusControlReg) {
- PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
- }
- //
- // Port Enabled/Disabled Change
- //
- if (PORTSC_PEDC & PortStatusControlReg) {
- PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
- }
- //
- // Port Over Current Change
- //
- if (PORTSC_OCC & PortStatusControlReg) {
- PortStatus->PortChangeStatus |= USB_PORT_STAT_C_OVERCURRENT;
- }
-
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciSetRootHubPortFeature (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN UINT8 PortNumber,
- IN EFI_USB_PORT_FEATURE PortFeature
- )
-/*++
-
- Routine Description:
-
- Sets a feature for the specified root hub port.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL.
- PortNumber - Specifies the root hub port whose feature
- is requested to be set.
- PortFeature - Indicates the feature selector associated
- with the feature set request.
-
- Returns:
-
- EFI_SUCCESS
- The feature specified by PortFeature was set for the
- USB root hub port specified by PortNumber.
- EFI_INVALID_PARAMETER
- PortNumber is invalid or PortFeature is invalid.
- EFI_DEVICE_ERROR
- Can't read register
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINT32 PortStatusControlAddr;
- UINT32 PortStatusControlReg;
- UINT8 MaxSpeed;
- UINT8 TotalPortNumber;
- UINT8 Is64BitCapable;
-
- EhciGetCapability (
- This,
- &MaxSpeed,
- &TotalPortNumber,
- &Is64BitCapable
- );
-
- if (PortNumber >= TotalPortNumber) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- HcDev = USB2_HC_DEV_FROM_THIS (This);
- PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));
-
- Status = ReadEhcOperationalReg (
- HcDev,
- PortStatusControlAddr,
- &PortStatusControlReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- switch (PortFeature) {
-
- case EfiUsbPortEnable:
-
- //
- // Sofeware can't set this bit, Port can only be enable by the Host Controller
- // as a part of the reset and enable
- //
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg |= PORTSC_PED;
- break;
-
- case EfiUsbPortSuspend:
-
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg |= PORTSC_SUSP;
- break;
-
- case EfiUsbPortReset:
-
- //
- // Make sure Host Controller not halt before reset it
- //
- if (IsEhcHalted (HcDev)) {
- Status = StartScheduleExecution (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- Status = WaitForEhcNotHalt (HcDev, EHCI_GENERIC_TIMEOUT);
- if (EFI_ERROR (Status)) {
- DEBUG ((gEHCDebugLevel, "EHCI: WaitForEhcNotHalt TimeOut\n"));
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- }
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg |= PORTSC_PR;
- //
- // Set one to PortReset bit must also set zero to PortEnable bit
- //
- PortStatusControlReg &= ~PORTSC_PED;
- break;
-
- case EfiUsbPortPower:
-
- //
- // No support, no operation
- //
- goto exit;
-
- case EfiUsbPortOwner:
-
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg |= PORTSC_PO;
- break;
-
- default:
-
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- Status = WriteEhcOperationalReg (
- HcDev,
- PortStatusControlAddr,
- PortStatusControlReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- }
-
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciClearRootHubPortFeature (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN UINT8 PortNumber,
- IN EFI_USB_PORT_FEATURE PortFeature
- )
-/*++
-
- Routine Description:
-
- Clears a feature for the specified root hub port.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
- PortNumber - Specifies the root hub port whose feature
- is requested to be cleared.
- PortFeature - Indicates the feature selector associated with the
- feature clear request.
-
- Returns:
-
- EFI_SUCCESS
- The feature specified by PortFeature was cleared for the
- USB root hub port specified by PortNumber.
- EFI_INVALID_PARAMETER
- PortNumber is invalid or PortFeature is invalid.
- EFI_DEVICE_ERROR
- Can't read register
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINT32 PortStatusControlAddr;
- UINT32 PortStatusControlReg;
- UINT8 MaxSpeed;
- UINT8 TotalPortNumber;
- UINT8 Is64BitCapable;
-
- EhciGetCapability (
- This,
- &MaxSpeed,
- &TotalPortNumber,
- &Is64BitCapable
- );
-
- if (PortNumber >= TotalPortNumber) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- HcDev = USB2_HC_DEV_FROM_THIS (This);
- PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNumber));
-
- Status = ReadEhcOperationalReg (
- HcDev,
- PortStatusControlAddr,
- &PortStatusControlReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- switch (PortFeature) {
-
- case EfiUsbPortEnable:
-
- //
- // Clear PORT_ENABLE feature means disable port.
- //
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg &= ~PORTSC_PED;
- break;
-
- case EfiUsbPortSuspend:
-
- //
- // A write of zero to this bit is ignored by the host controller.
- // The host controller will unconditionally set this bit to a zero when:
- // 1. software sets the Forct Port Resume bit to a zero from a one.
- // 2. software sets the Port Reset bit to a one frome a zero.
- //
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg &= ~PORTSC_FPR;
- break;
-
- case EfiUsbPortReset:
-
- //
- // Clear PORT_RESET means clear the reset signal.
- //
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg &= ~PORTSC_PR;
- break;
-
- case EfiUsbPortPower:
-
- //
- // No support, no operation
- //
- goto exit;
-
- case EfiUsbPortOwner:
-
- //
- // Clear port owner means this port owned by EHC
- //
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg &= ~PORTSC_PO;
- break;
-
- case EfiUsbPortConnectChange:
-
- //
- // Clear connect status change
- //
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg |= PORTSC_CSC;
- break;
-
- case EfiUsbPortEnableChange:
-
- //
- // Clear enable status change
- //
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg |= PORTSC_PEDC;
- break;
-
- case EfiUsbPortSuspendChange:
-
- //
- // No related bit, no operation
- //
- goto exit;
-
- case EfiUsbPortOverCurrentChange:
-
- //
- // Clear PortOverCurrent change
- //
- PortStatusControlReg &= 0xffffffd5;
- PortStatusControlReg |= PORTSC_OCC;
- break;
-
- case EfiUsbPortResetChange:
-
- //
- // No related bit, no operation
- //
- goto exit;
-
- default:
-
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- Status = WriteEhcOperationalReg (
- HcDev,
- PortStatusControlAddr,
- PortStatusControlReg
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciControlTransfer (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN UINT8 DeviceAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN EFI_USB_DEVICE_REQUEST *Request,
- IN EFI_USB_DATA_DIRECTION TransferDirection,
- IN OUT VOID *Data,
- IN OUT UINTN *DataLength,
- IN UINTN TimeOut,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
- OUT UINT32 *TransferResult
- )
-/*++
-
- Routine Description:
-
- Submits control transfer to a target USB device.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- DeviceSpeed - Indicates target device speed.
- MaximumPacketLength - Indicates the maximum packet size that the
- default control transfer endpoint is capable of
- sending or receiving.
- Request - A pointer to the USB device request that will be sent
- to the USB device.
- TransferDirection - Specifies the data direction for the transfer.
- There are three values available, DataIn, DataOut
- and NoData.
- Data - A pointer to the buffer of data that will be transmitted
- to USB device or received from USB device.
- DataLength - Indicates the size, in bytes, of the data buffer
- specified by Data.
- TimeOut - Indicates the maximum time, in microseconds,
- which the transfer is allowed to complete.
- Translator - A pointr to the transaction translator data.
- TransferResult - A pointer to the detailed result information generated
- by this control transfer.
-
- Returns:
-
- EFI_SUCCESS
- The control transfer was completed successfully.
- EFI_OUT_OF_RESOURCES
- The control transfer could not be completed due to a lack of resources.
- EFI_INVALID_PARAMETER
- Some parameters are invalid.
- EFI_TIMEOUT
- The control transfer failed due to timeout.
- EFI_DEVICE_ERROR
- The control transfer failed due to host controller or device error.
- Caller should check TranferResult for detailed error information.
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINT8 PktId;
- EHCI_QH_ENTITY *QhPtr;
- EHCI_QTD_ENTITY *ControlQtdsPtr;
- UINT8 *DataCursor;
- VOID *DataMap;
- UINT8 *RequestCursor;
- VOID *RequestMap;
-
- QhPtr = NULL;
- ControlQtdsPtr = NULL;
- DataCursor = NULL;
- DataMap = NULL;
- RequestCursor = NULL;
- RequestMap = NULL;
- HcDev = USB2_HC_DEV_FROM_THIS (This);
-
- //
- // Parameters Checking
- //
- if (TransferDirection != EfiUsbDataIn &&
- TransferDirection != EfiUsbDataOut &&
- TransferDirection != EfiUsbNoData
- ) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (EfiUsbNoData == TransferDirection) {
- if (NULL != Data || 0 != *DataLength) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
- } else {
- if (NULL == Data || 0 == *DataLength) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
- }
-
- if (Request == NULL || TransferResult == NULL) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (EFI_USB_SPEED_LOW == DeviceSpeed) {
- if (MaximumPacketLength != 8) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
- } else if (MaximumPacketLength != 8 &&
- MaximumPacketLength != 16 &&
- MaximumPacketLength != 32 &&
- MaximumPacketLength != 64
- ) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- //
- // If errors exist that cause host controller halt,
- // then return EFI_DEVICE_ERROR.
- //
- if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
- ClearEhcAllStatus (HcDev);
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Map the Request for bus master access.
- // BusMasterRead means cpu write
- //
- Status = MapRequestBuffer (
- HcDev,
- Request,
- &RequestCursor,
- &RequestMap
- );
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Map the source data buffer for bus master access.
- //
- Status = MapDataBuffer (
- HcDev,
- TransferDirection,
- Data,
- DataLength,
- &PktId,
- &DataCursor,
- &DataMap
- );
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_DEVICE_ERROR;
- goto unmap_request;
- }
-
- //
- // Create and init control Qh
- //
- Status = CreateControlQh (
- HcDev,
- DeviceAddress,
- DeviceSpeed,
- MaximumPacketLength,
- Translator,
- &QhPtr
- );
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_OUT_OF_RESOURCES;
- goto unmap_data;
- }
-
- //
- // Create and init control Qtds
- //
- Status = CreateControlQtds (
- HcDev,
- PktId,
- RequestCursor,
- DataCursor,
- *DataLength,
- Translator,
- &ControlQtdsPtr
- );
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_OUT_OF_RESOURCES;
- goto destory_qh;
- }
-
- //
- // Link Qtds to Qh
- //
- LinkQtdToQh (QhPtr, ControlQtdsPtr);
-
- ClearEhcAllStatus (HcDev);
-
- //
- // Link Qh and Qtds to Async Schedule List
- //
- Status = LinkQhToAsyncList (HcDev, QhPtr);
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_DEVICE_ERROR;
- goto destory_qtds;
- }
-
- //
- // Poll Qh-Qtds execution and get result.
- // detail status is returned
- //
- Status = ExecuteTransfer (
- HcDev,
- TRUE,
- QhPtr,
- DataLength,
- 0,
- TimeOut,
- TransferResult
- );
- if (EFI_ERROR (Status)) {
- goto destory_qtds;
- }
-
- //
- // If has errors that cause host controller halt,
- // then return EFI_DEVICE_ERROR directly.
- //
- if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
- *TransferResult |= EFI_USB_ERR_SYSTEM;
- }
-
- ClearEhcAllStatus (HcDev);
-
-destory_qtds:
- UnlinkQhFromAsyncList (HcDev, QhPtr);
- DestoryQtds (HcDev, ControlQtdsPtr);
-destory_qh:
- DestoryQh (HcDev, QhPtr);
-unmap_data:
- HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);
-unmap_request:
- HcDev->PciIo->Unmap (HcDev->PciIo, RequestMap);
-exit:
- HcDev->PciIo->Flush (HcDev->PciIo);
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciBulkTransfer (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN UINT8 DataBuffersNumber,
- IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
- IN OUT UINTN *DataLength,
- IN OUT UINT8 *DataToggle,
- IN UINTN TimeOut,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
- OUT UINT32 *TransferResult
- )
-/*++
-
- Routine Description:
-
- Submits bulk transfer to a bulk endpoint of a USB device.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- EndPointAddress - The combination of an endpoint number and an
- endpoint direction of the target USB device.
- Each endpoint address supports data transfer in
- one direction except the control endpoint
- (whose default endpoint address is 0).
- It is the caller's responsibility to make sure that
- the EndPointAddress represents a bulk endpoint.
- DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
- and EFI_USB_SPEED_HIGH.
- MaximumPacketLength - Indicates the maximum packet size the target endpoint
- is capable of sending or receiving.
- DataBuffersNumber - Number of data buffers prepared for the transfer.
- Data - Array of pointers to the buffers of data that will be transmitted
- to USB device or received from USB device.
- DataLength - When input, indicates the size, in bytes, of the data buffer
- specified by Data. When output, indicates the actually
- transferred data size.
- DataToggle - A pointer to the data toggle value. On input, it indicates
- the initial data toggle value the bulk transfer should adopt;
- on output, it is updated to indicate the data toggle value
- of the subsequent bulk transfer.
- Translator - A pointr to the transaction translator data.
- TimeOut - Indicates the maximum time, in microseconds, which the
- transfer is allowed to complete.
- TransferResult - A pointer to the detailed result information of the
- bulk transfer.
-
- Returns:
-
- EFI_SUCCESS
- The bulk transfer was completed successfully.
- EFI_OUT_OF_RESOURCES
- The bulk transfer could not be submitted due to lack of resource.
- EFI_INVALID_PARAMETER
- Some parameters are invalid.
- EFI_TIMEOUT
- The bulk transfer failed due to timeout.
- EFI_DEVICE_ERROR
- The bulk transfer failed due to host controller or device error.
- Caller should check TranferResult for detailed error information.
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINT8 PktId;
- EHCI_QH_ENTITY *QhPtr;
- EHCI_QTD_ENTITY *BulkQtdsPtr;
- UINT8 *DataCursor;
- VOID *DataMap;
- EFI_USB_DATA_DIRECTION TransferDirection;
-
- QhPtr = NULL;
- BulkQtdsPtr = NULL;
- DataCursor = NULL;
- DataMap = NULL;
- HcDev = USB2_HC_DEV_FROM_THIS (This);
-
- //
- // Parameters Checking
- //
- if (NULL == DataLength ||
- NULL == Data ||
- NULL == Data[0] ||
- NULL == TransferResult
- ) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (*DataLength == 0) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (1 != *DataToggle && 0 != *DataToggle) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (EFI_USB_SPEED_LOW == DeviceSpeed) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (EFI_USB_SPEED_FULL == DeviceSpeed) {
- if (MaximumPacketLength > 64) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
- }
-
- if (EFI_USB_SPEED_HIGH == DeviceSpeed) {
- if (MaximumPacketLength > 512) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
- }
-
- //
- // if has errors that cause host controller halt,
- // then return EFI_DEVICE_ERROR directly.
- //
- if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
- ClearEhcAllStatus (HcDev);
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- Status = ClearEhcAllStatus (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // construct QH and TD data structures,
- // and link them together
- //
- if (EndPointAddress & 0x80) {
- TransferDirection = EfiUsbDataIn;
- } else {
- TransferDirection = EfiUsbDataOut;
- }
-
- Status = MapDataBuffer (
- HcDev,
- TransferDirection,
- Data[0],
- DataLength,
- &PktId,
- &DataCursor,
- &DataMap
- );
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Create and init Bulk Qh
- //
- Status = CreateBulkQh (
- HcDev,
- DeviceAddress,
- EndPointAddress,
- DeviceSpeed,
- *DataToggle,
- MaximumPacketLength,
- Translator,
- &QhPtr
- );
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_OUT_OF_RESOURCES;
- goto unmap_data;
- }
-
- //
- // Create and init Bulk Qtds
- //
- Status = CreateBulkOrInterruptQtds (
- HcDev,
- PktId,
- DataCursor,
- *DataLength,
- Translator,
- &BulkQtdsPtr
- );
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_OUT_OF_RESOURCES;
- goto destory_qh;
- }
-
- //
- // Link Qtds to Qh
- //
- LinkQtdToQh (QhPtr, BulkQtdsPtr);
-
- ClearEhcAllStatus (HcDev);
-
- //
- // Link Qh and qtds to Async Schedule List
- //
- Status = LinkQhToAsyncList (HcDev, QhPtr);
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_DEVICE_ERROR;
- goto destory_qtds;
- }
-
- //
- // Poll QH-TDs execution and get result.
- // detail status is returned
- //
- Status = ExecuteTransfer (
- HcDev,
- FALSE,
- QhPtr,
- DataLength,
- DataToggle,
- TimeOut,
- TransferResult
- );
- if (EFI_ERROR (Status)) {
- goto destory_qtds;
- }
-
- //
- // if has errors that cause host controller halt,
- // then return EFI_DEVICE_ERROR directly.
- //
- if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
- *TransferResult |= EFI_USB_ERR_SYSTEM;
- }
-
- ClearEhcAllStatus (HcDev);
-
-destory_qtds:
- UnlinkQhFromAsyncList (HcDev, QhPtr);
- DestoryQtds (HcDev, BulkQtdsPtr);
-destory_qh:
- DestoryQh (HcDev, QhPtr);
-unmap_data:
- HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);
-exit:
- HcDev->PciIo->Flush (HcDev->PciIo);
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciAsyncInterruptTransfer (
- IN EFI_USB2_HC_PROTOCOL * This,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN BOOLEAN IsNewTransfer,
- IN OUT UINT8 *DataToggle,
- IN UINTN PollingInterval,
- IN UINTN DataLength,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,
- IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
- IN VOID *Context OPTIONAL
- )
-/*++
-
- Routine Description:
-
- Submits an asynchronous interrupt transfer to an
- interrupt endpoint of a USB device.
- Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
- in the following specification version.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- EndPointAddress - The combination of an endpoint number and an endpoint
- direction of the target USB device. Each endpoint address
- supports data transfer in one direction except the
- control endpoint (whose default endpoint address is 0).
- It is the caller's responsibility to make sure that
- the EndPointAddress represents an interrupt endpoint.
- DeviceSpeed - Indicates device speed.
- MaximumPacketLength - Indicates the maximum packet size the target endpoint
- is capable of sending or receiving.
- IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
- the host and the target interrupt endpoint.
- If FALSE, the specified asynchronous interrupt pipe
- is canceled.
- DataToggle - A pointer to the data toggle value. On input, it is valid
- when IsNewTransfer is TRUE, and it indicates the initial
- data toggle value the asynchronous interrupt transfer
- should adopt.
- On output, it is valid when IsNewTransfer is FALSE,
- and it is updated to indicate the data toggle value of
- the subsequent asynchronous interrupt transfer.
- PollingInterval - Indicates the interval, in milliseconds, that the
- asynchronous interrupt transfer is polled.
- This parameter is required when IsNewTransfer is TRUE.
- DataLength - Indicates the length of data to be received at the
- rate specified by PollingInterval from the target
- asynchronous interrupt endpoint. This parameter
- is only required when IsNewTransfer is TRUE.
- Translator - A pointr to the transaction translator data.
- CallBackFunction - The Callback function.This function is called at the
- rate specified by PollingInterval.This parameter is
- only required when IsNewTransfer is TRUE.
- Context - The context that is passed to the CallBackFunction.
- - This is an optional parameter and may be NULL.
-
- Returns:
-
- EFI_SUCCESS
- The asynchronous interrupt transfer request has been successfully
- submitted or canceled.
- EFI_INVALID_PARAMETER
- Some parameters are invalid.
- EFI_OUT_OF_RESOURCES
- The request could not be completed due to a lack of resources.
- EFI_DEVICE_ERROR
- Can't read register
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINT8 PktId;
- EHCI_QH_ENTITY *QhPtr;
- EHCI_QTD_ENTITY *InterruptQtdsPtr;
- UINT8 *DataPtr;
- UINT8 *DataCursor;
- VOID *DataMap;
- UINTN MappedLength;
- EHCI_ASYNC_REQUEST *AsyncRequestPtr;
- EFI_TPL OldTpl;
-
- QhPtr = NULL;
- InterruptQtdsPtr = NULL;
- DataPtr = NULL;
- DataCursor = NULL;
- DataMap = NULL;
- AsyncRequestPtr = NULL;
- HcDev = USB2_HC_DEV_FROM_THIS (This);
-
- //
- // Parameters Checking
- //
- if (!IsDataInTransfer (EndPointAddress)) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (IsNewTransfer) {
- if (0 == DataLength) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (*DataToggle != 1 && *DataToggle != 0) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (PollingInterval > 255 || PollingInterval < 1) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
- }
-
- //
- // if has errors that cause host controller halt,
- // then return EFI_DEVICE_ERROR directly.
- //
- if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
- ClearEhcAllStatus (HcDev);
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- Status = ClearEhcAllStatus (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Delete Async interrupt transfer request
- //
- if (!IsNewTransfer) {
-
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
-
- Status = DeleteAsyncRequestTransfer (
- HcDev,
- DeviceAddress,
- EndPointAddress,
- DataToggle
- );
-
- gBS->RestoreTPL (OldTpl);
-
- goto exit;
- }
-
- Status = EhciAllocatePool (
- HcDev,
- (UINT8 **) &AsyncRequestPtr,
- sizeof (EHCI_ASYNC_REQUEST)
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto exit;
- }
-
- Status = EhciAllocatePool (HcDev, &DataPtr, DataLength);
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto free_request;
- }
-
- MappedLength = DataLength;
- Status = MapDataBuffer (
- HcDev,
- EfiUsbDataIn,
- DataPtr,
- &MappedLength,
- &PktId,
- &DataCursor,
- &DataMap
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto free_data;
- }
-
- //
- // Create and init Interrupt Qh
- //
- Status = CreateInterruptQh (
- HcDev,
- DeviceAddress,
- EndPointAddress,
- DeviceSpeed,
- *DataToggle,
- MaximumPacketLength,
- PollingInterval,
- Translator,
- &QhPtr
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto unmap_data;
- }
-
- //
- // Create and init Interrupt Qtds
- //
- Status = CreateBulkOrInterruptQtds (
- HcDev,
- PktId,
- DataCursor,
- MappedLength,
- Translator,
- &InterruptQtdsPtr
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto destory_qh;
- }
-
- //
- // Link Qtds to Qh
- //
- LinkQtdToQh (QhPtr, InterruptQtdsPtr);
-
- //
- // Init AsyncRequest Entry
- //
- AsyncRequestPtr->Context = Context;
- AsyncRequestPtr->CallBackFunc = CallBackFunction;
- AsyncRequestPtr->TransferType = ASYNC_INTERRUPT_TRANSFER;
- AsyncRequestPtr->QhPtr = QhPtr;
- AsyncRequestPtr->Prev = NULL;
- AsyncRequestPtr->Next = NULL;
-
- if (NULL == HcDev->AsyncRequestList) {
- Status = StartPollingTimer (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- CleanUpAllAsyncRequestTransfer (HcDev);
- goto exit;
- }
- }
-
- //
- // Link Entry to AsyncRequest List
- //
- LinkToAsyncReqeust (HcDev, AsyncRequestPtr);
-
- ClearEhcAllStatus (HcDev);
-
- Status = DisablePeriodicSchedule (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
- if (EFI_ERROR (Status)) {
- Status = EFI_TIMEOUT;
- goto exit;
- }
-
- //
- // Link Qh and Qtds to Periodic Schedule List
- //
- LinkQhToPeriodicList (HcDev, QhPtr);
-
- Status = EnablePeriodicSchedule (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
- if (EFI_ERROR (Status)) {
- Status = EFI_TIMEOUT;
- goto exit;
- }
-
- if (IsEhcHalted (HcDev)) {
- Status = StartScheduleExecution (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- }
-
- HcDev->PciIo->Flush (HcDev->PciIo);
- goto exit;
-
-destory_qh:
- DestoryQh (HcDev, QhPtr);
-free_data:
- EhciFreePool (HcDev, DataPtr, DataLength);
-free_request:
- EhciFreePool (
- HcDev,
- (UINT8 *) AsyncRequestPtr,
- sizeof (EHCI_ASYNC_REQUEST)
- );
-unmap_data:
- HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);
-exit:
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciSyncInterruptTransfer (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN OUT VOID *Data,
- IN OUT UINTN *DataLength,
- IN OUT UINT8 *DataToggle,
- IN UINTN TimeOut,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
- OUT UINT32 *TransferResult
- )
-/*++
-
- Routine Description:
-
- Submits synchronous interrupt transfer to an interrupt endpoint
- of a USB device.
- Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
- in the following specification version.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- EndPointAddress - The combination of an endpoint number and an endpoint
- direction of the target USB device. Each endpoint
- address supports data transfer in one direction
- except the control endpoint (whose default
- endpoint address is 0). It is the caller's responsibility
- to make sure that the EndPointAddress represents
- an interrupt endpoint.
- DeviceSpeed - Indicates device speed.
- MaximumPacketLength - Indicates the maximum packet size the target endpoint
- is capable of sending or receiving.
- Data - A pointer to the buffer of data that will be transmitted
- to USB device or received from USB device.
- DataLength - On input, the size, in bytes, of the data buffer specified
- by Data. On output, the number of bytes transferred.
- DataToggle - A pointer to the data toggle value. On input, it indicates
- the initial data toggle value the synchronous interrupt
- transfer should adopt;
- on output, it is updated to indicate the data toggle value
- of the subsequent synchronous interrupt transfer.
- TimeOut - Indicates the maximum time, in microseconds, which the
- transfer is allowed to complete.
- Translator - A pointr to the transaction translator data.
- TransferResult - A pointer to the detailed result information from
- the synchronous interrupt transfer.
-
- Returns:
-
- EFI_SUCCESS
- The synchronous interrupt transfer was completed successfully.
- EFI_OUT_OF_RESOURCES
- The synchronous interrupt transfer could not be submitted due
- to lack of resource.
- EFI_INVALID_PARAMETER
- Some parameters are invalid.
- EFI_TIMEOUT
- The synchronous interrupt transfer failed due to timeout.
- EFI_DEVICE_ERROR
- The synchronous interrupt transfer failed due to host controller
- or device error. Caller should check TranferResult for detailed
- error information.
-
---*/
-{
- EFI_STATUS Status;
- USB2_HC_DEV *HcDev;
- UINT8 PktId;
- EHCI_QH_ENTITY *QhPtr;
- EHCI_QTD_ENTITY *InterruptQtdsPtr;
- UINT8 *DataCursor;
- VOID *DataMap;
-
- QhPtr = NULL;
- InterruptQtdsPtr = NULL;
- DataCursor = NULL;
- DataMap = NULL;
- HcDev = USB2_HC_DEV_FROM_THIS (This);
-
- //
- // Parameters Checking
- //
- if (DataLength == NULL ||
- Data == NULL ||
- TransferResult == NULL
- ) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (!IsDataInTransfer (EndPointAddress)) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (0 == *DataLength) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (*DataToggle != 1 && *DataToggle != 0) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (EFI_USB_SPEED_LOW == DeviceSpeed && 8 != MaximumPacketLength) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (EFI_USB_SPEED_FULL == DeviceSpeed && MaximumPacketLength > 64) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- if (EFI_USB_SPEED_HIGH == DeviceSpeed && MaximumPacketLength > 3072) {
- Status = EFI_INVALID_PARAMETER;
- goto exit;
- }
-
- //
- // if has errors that cause host controller halt,
- // then return EFI_DEVICE_ERROR directly.
- //
- if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
- ClearEhcAllStatus (HcDev);
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- Status = ClearEhcAllStatus (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- Status = MapDataBuffer (
- HcDev,
- EfiUsbDataIn,
- Data,
- DataLength,
- &PktId,
- &DataCursor,
- &DataMap
- );
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- //
- // Create and init Interrupt Qh
- //
- Status = CreateInterruptQh (
- HcDev,
- DeviceAddress,
- EndPointAddress,
- DeviceSpeed,
- *DataToggle,
- MaximumPacketLength,
- 0,
- Translator,
- &QhPtr
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- goto unmap_data;
- }
-
- //
- // Create and init Interrupt Qtds
- //
- Status = CreateBulkOrInterruptQtds (
- HcDev,
- PktId,
- DataCursor,
- *DataLength,
- Translator,
- &InterruptQtdsPtr
- );
- if (EFI_ERROR (Status)) {
- *TransferResult = EFI_USB_ERR_SYSTEM;
- Status = EFI_OUT_OF_RESOURCES;
- goto destory_qh;
- }
-
- //
- // Link Qtds to Qh
- //
- LinkQtdToQh (QhPtr, InterruptQtdsPtr);
-
- ClearEhcAllStatus (HcDev);
-
- Status = DisablePeriodicSchedule (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- Status = WaitForPeriodicScheduleDisable (HcDev, EHCI_GENERIC_TIMEOUT);
- if (EFI_ERROR (Status)) {
- Status = EFI_TIMEOUT;
- goto exit;
- }
-
- //
- // Link Qh and Qtds to Periodic Schedule List
- //
- LinkQhToPeriodicList (HcDev, QhPtr);
-
- Status = EnablePeriodicSchedule (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
-
- Status = WaitForPeriodicScheduleEnable (HcDev, EHCI_GENERIC_TIMEOUT);
- if (EFI_ERROR (Status)) {
- Status = EFI_TIMEOUT;
- goto exit;
- }
-
- if (IsEhcHalted (HcDev)) {
- Status = StartScheduleExecution (HcDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- goto exit;
- }
- }
-
- //
- // Poll QH-TDs execution and get result.
- // detail status is returned
- //
- Status = ExecuteTransfer (
- HcDev,
- FALSE,
- QhPtr,
- DataLength,
- DataToggle,
- TimeOut,
- TransferResult
- );
- if (EFI_ERROR (Status)) {
- goto destory_qtds;
- }
-
- //
- // if has errors that cause host controller halt,
- // then return EFI_DEVICE_ERROR directly.
- //
- if (IsEhcHalted (HcDev) || IsEhcSysError (HcDev)) {
- *TransferResult |= EFI_USB_ERR_SYSTEM;
- }
-
- ClearEhcAllStatus (HcDev);
-
-destory_qtds:
- UnlinkQhFromPeriodicList (HcDev, QhPtr, 0);
- DestoryQtds (HcDev, InterruptQtdsPtr);
-destory_qh:
- DestoryQh (HcDev, QhPtr);
-unmap_data:
- HcDev->PciIo->Unmap (HcDev->PciIo, DataMap);
-exit:
- HcDev->PciIo->Flush (HcDev->PciIo);
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-EhciIsochronousTransfer (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN UINT8 DataBuffersNumber,
- IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
- IN UINTN DataLength,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
- OUT UINT32 *TransferResult
- )
-/*++
-
- Routine Description:
-
- Submits isochronous transfer to a target USB device.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- EndPointAddress - End point address
- DeviceSpeed - Indicates device speed.
- MaximumPacketLength - Indicates the maximum packet size that the
- default control transfer endpoint is capable of
- sending or receiving.
- DataBuffersNumber - Number of data buffers prepared for the transfer.
- Data - Array of pointers to the buffers of data that will be
- transmitted to USB device or received from USB device.
- DataLength - Indicates the size, in bytes, of the data buffer
- specified by Data.
- Translator - A pointr to the transaction translator data.
- TransferResult - A pointer to the detailed result information generated
- by this control transfer.
-
- Returns:
-
- EFI_UNSUPPORTED
-
---*/
-{
- return EFI_UNSUPPORTED;
-}
-
-EFI_STATUS
-EFIAPI
-EhciAsyncIsochronousTransfer (
- IN EFI_USB2_HC_PROTOCOL *This,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN UINT8 DataBuffersNumber,
- IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
- IN UINTN DataLength,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
- IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
- IN VOID *Context
- )
-/*++
-
- Routine Description:
-
- Submits Async isochronous transfer to a target USB device.
-
- Arguments:
-
- This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- EndPointAddress - End point address
- DeviceSpeed - Indicates device speed.
- MaximumPacketLength - Indicates the maximum packet size that the
- default control transfer endpoint is capable of
- sending or receiving.
- DataBuffersNumber - Number of data buffers prepared for the transfer.
- Data - Array of pointers to the buffers of data that will be transmitted
- to USB device or received from USB device.
- Translator - A pointr to the transaction translator data.
- IsochronousCallBack - When the transfer complete, the call back function will be called
- Context - Pass to the call back function as parameter
-
- Returns:
-
- EFI_UNSUPPORTED
-
---*/
-{
- return EFI_UNSUPPORTED;
-}