summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c')
-rw-r--r--EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c3719
1 files changed, 0 insertions, 3719 deletions
diff --git a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c b/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
deleted file mode 100644
index 97c9f5efee..0000000000
--- a/EdkModulePkg/Bus/Usb/UsbBus/Dxe/usbbus.c
+++ /dev/null
@@ -1,3719 +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:
-
- UsbBus.c
-
- Abstract:
-
- USB Bus Driver
-
- Revision History
-
---*/
-
-#include "usbbus.h"
-
-
-GLOBAL_REMOVE_IF_UNREFERENCED UINTN gUSBDebugLevel = EFI_D_INFO;
-GLOBAL_REMOVE_IF_UNREFERENCED UINTN gUSBErrorLevel = EFI_D_ERROR;
-
-//
-// The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER
-// structure in the UsbBusDriverControllerDriverStop(). Then we can
-// Close all opened protocols and release this structure.
-//
-STATIC EFI_GUID mUsbBusProtocolGuid = EFI_USB_BUS_PROTOCOL_GUID;
-
-EFI_DRIVER_BINDING_PROTOCOL gUsbBusDriverBinding = {
- UsbBusControllerDriverSupported,
- UsbBusControllerDriverStart,
- UsbBusControllerDriverStop,
- 0xa,
- NULL,
- NULL
-};
-
-//
-// Internal use only
-//
-STATIC
-EFI_STATUS
-ReportUsbStatusCode (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusController,
- IN EFI_STATUS_CODE_TYPE Type,
- IN EFI_STATUS_CODE_VALUE Code
- );
-
-STATIC
-USB_IO_CONTROLLER_DEVICE *
-CreateUsbIoControllerDevice (
- VOID
- );
-
-STATIC
-EFI_STATUS
-InitUsbIoController (
- IN USB_IO_CONTROLLER_DEVICE *UsbIoController
- );
-
-//
-// USB Device Configuration / Deconfiguration
-//
-STATIC
-EFI_STATUS
-UsbDeviceConfiguration (
- IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
- IN EFI_HANDLE HostController,
- IN UINT8 ParentPort,
- IN USB_IO_DEVICE *UsbIoDevice
- );
-
-//
-// Usb Bus enumeration function
-//
-STATIC
-VOID
-RootHubEnumeration (
- IN EFI_EVENT Event,
- IN VOID *Context
- );
-
-STATIC
-VOID
-HubEnumeration (
- IN EFI_EVENT Event,
- IN VOID *Context
- );
-
-STATIC
-EFI_STATUS
-UsbSetTransactionTranslator (
- IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
- IN UINT8 ParentPort,
- IN OUT USB_IO_DEVICE *Device
- );
-
-STATIC
-EFI_STATUS
-UsbUnsetTransactionTranslator (
- USB_IO_DEVICE *Device
- );
-
-STATIC
-EFI_STATUS
-IdentifyDeviceSpeed (
- USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- USB_IO_DEVICE *NewDevice,
- UINT8 Index
- );
-
-STATIC
-EFI_STATUS
-ReleasePortToCHC (
- USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- UINT8 PortNum
- );
-
-STATIC
-EFI_STATUS
-ResetRootPort (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT8 PortNum,
- IN UINT8 RetryTimes
- );
-
-STATIC
-EFI_STATUS
-ResetHubPort (
- IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
- IN UINT8 PortIndex
- );
-
-STATIC
-EFI_STATUS
-ParentPortReset (
- IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
- IN BOOLEAN ReConfigure,
- IN UINT8 RetryTimes
- );
-
-//
-// Following are address allocate and free functions
-//
-STATIC
-UINT8
-UsbAllocateAddress (
- IN UINT8 *AddressPool
- )
-/*++
-
- Routine Description:
- Allocate address for usb device
-
- Arguments:
- AddressPool - Pool of usb device address
-
- Returns:
- Usb device address
-
---*/
-{
- UINT8 ByteIndex;
- UINT8 BitIndex;
-
- for (ByteIndex = 0; ByteIndex < 16; ByteIndex++) {
- for (BitIndex = 0; BitIndex < 8; BitIndex++) {
- if ((AddressPool[ByteIndex] & (1 << BitIndex)) == 0) {
- //
- // Found one, covert to address, and mark it use
- //
- AddressPool[ByteIndex] = (UINT8) (AddressPool[ByteIndex] | (1 << BitIndex));
- return (UINT8) (ByteIndex * 8 + BitIndex);
- }
- }
- }
-
- return 0;
-
-}
-
-STATIC
-VOID
-UsbFreeAddress (
- IN UINT8 DevAddress,
- IN UINT8 *AddressPool
- )
-/*++
-
- Routine Description:
- Free address for usb device
-
- Arguments:
- DevAddress - Usb device address
- AddressPool - Pool of usb device address
-
- Returns:
- VOID
-
---*/
-{
- UINT8 WhichByte;
- UINT8 WhichBit;
- //
- // Locate the position
- //
- WhichByte = (UINT8) (DevAddress / 8);
- WhichBit = (UINT8) (DevAddress & 0x7);
-
- AddressPool[WhichByte] = (UINT8) (AddressPool[WhichByte] & (~(1 << WhichBit)));
-}
-
-EFI_STATUS
-EFIAPI
-UsbBusControllerDriverSupported (
- 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 UsbHcProtocol installed will be supported.
-
- Arguments:
- This - Protocol instance pointer.
- Controller - Handle of device to test
- RemainingDevicePath - Device Path Protocol instance pointer
-
- Returns:
- EFI_SUCCESS - This driver supports this device.
- EFI_UNSUPPORTED - This driver does not support this device.
-
---*/
-{
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
- EFI_USB2_HC_PROTOCOL *Usb2Hc;
- EFI_USB_HC_PROTOCOL *UsbHc;
- EFI_DEV_PATH_PTR Node;
-
- //
- // Check Device Path
- //
- if (RemainingDevicePath != NULL) {
- Node.DevPath = RemainingDevicePath;
- if (Node.DevPath->Type != MESSAGING_DEVICE_PATH ||
- Node.DevPath->SubType != MSG_USB_DP ||
- DevicePathNodeLength(Node.DevPath) != sizeof(USB_DEVICE_PATH)) {
- return EFI_UNSUPPORTED;
- }
- }
-
- //
- // Open the IO Abstraction(s) needed to perform the supported test
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- (VOID **) &ParentDevicePath,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (Status == EFI_ALREADY_STARTED) {
- return EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- //
- // Check whether USB Host Controller Protocol is already
- // installed on this handle. If it is installed, we can start
- // USB Bus Driver now.
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- (VOID **) &Usb2Hc,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (Status == EFI_ALREADY_STARTED) {
- return EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- (VOID **) &UsbHc,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (Status == EFI_ALREADY_STARTED) {
- return EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- return EFI_SUCCESS;
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-UsbBusControllerDriverStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-/*++
-
- Routine Description:
-
- Starting the Usb Bus Driver
-
- Arguments:
-
- This - Protocol instance pointer.
- Controller - Handle of device to test
- RemainingDevicePath - Not used
-
- Returns:
-
- EFI_SUCCESS - This driver supports this device.
- EFI_DEVICE_ERROR - This driver cannot be started due to device
- EFI_OUT_OF_RESOURCES- Can't allocate memory resources
-
---*/
-{
- EFI_STATUS Status;
- EFI_STATUS OpenStatus;
- USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
- USB_IO_DEVICE *RootHub;
- USB_IO_CONTROLLER_DEVICE *RootHubController;
- UINT8 MaxSpeed;
- UINT8 PortNumber;
- UINT8 Is64BitCapable;
-
- //
- // Allocate USB_BUS_CONTROLLER_DEVICE structure
- //
- UsbBusDev = NULL;
- UsbBusDev = AllocateZeroPool (sizeof (USB_BUS_CONTROLLER_DEVICE));
- if (UsbBusDev == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- UsbBusDev->Signature = USB_BUS_DEVICE_SIGNATURE;
- UsbBusDev->AddressPool[0] = 1;
-
- //
- // Get the Device Path Protocol on Controller's handle
- //
- OpenStatus = gBS->OpenProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- (VOID **) &UsbBusDev->DevicePath,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
-
- if (EFI_ERROR (OpenStatus)) {
- gBS->FreePool (UsbBusDev);
- return OpenStatus;
- }
- //
- // Locate the Host Controller Interface
- //
- OpenStatus = gBS->OpenProtocol (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- (VOID **) &(UsbBusDev->Usb2HCInterface),
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (OpenStatus)) {
-
- UsbBusDev->Hc2ProtocolSupported = FALSE;
- OpenStatus = gBS->OpenProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- (VOID **) &(UsbBusDev->UsbHCInterface),
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (OpenStatus)) {
- //
- // Report Status Code here since we will reset the host controller
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,
- UsbBusDev->DevicePath
- );
-
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- gBS->FreePool (UsbBusDev);
- return OpenStatus;
- }
-
- DEBUG ((gUSBDebugLevel, "UsbHcProtocol Opened.\n"));
- } else {
- DEBUG ((gUSBDebugLevel, "Usb2HcProtocol Opened.\n"));
- UsbBusDev->Hc2ProtocolSupported = TRUE;
- }
-
- //
- // Attach EFI_USB_BUS_PROTOCOL to controller handle,
- // for locate UsbBusDev later
- //
- Status = gBS->InstallProtocolInterface (
- &Controller,
- &mUsbBusProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &UsbBusDev->BusIdentify
- );
-
- if (EFI_ERROR (Status)) {
-
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- if (UsbBusDev->Hc2ProtocolSupported) {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- } else {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- }
-
- gBS->FreePool (UsbBusDev);
- return Status;
- }
- //
- // Add root hub to the tree
- //
- RootHub = NULL;
- RootHub = AllocateZeroPool (sizeof (USB_IO_DEVICE));
- if (RootHub == NULL) {
- gBS->UninstallProtocolInterface (
- Controller,
- &mUsbBusProtocolGuid,
- &UsbBusDev->BusIdentify
- );
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- if (UsbBusDev->Hc2ProtocolSupported) {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- } else {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- }
-
- gBS->FreePool (UsbBusDev);
- return EFI_OUT_OF_RESOURCES;
- }
-
- RootHub->BusController = UsbBusDev;
- RootHub->DeviceAddress = UsbAllocateAddress (UsbBusDev->AddressPool);
-
- UsbBusDev->Root = RootHub;
-
- //
- // Allocate Root Hub Controller
- //
- RootHubController = CreateUsbIoControllerDevice ();
- if (RootHubController == NULL) {
- gBS->UninstallProtocolInterface (
- Controller,
- &mUsbBusProtocolGuid,
- &UsbBusDev->BusIdentify
- );
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- if (UsbBusDev->Hc2ProtocolSupported) {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- } else {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- }
- gBS->FreePool (UsbBusDev);
- gBS->FreePool (RootHub);
- return EFI_OUT_OF_RESOURCES;
- }
-
- UsbVirtualHcGetCapability (
- UsbBusDev,
- &MaxSpeed,
- &PortNumber,
- &Is64BitCapable
- );
- RootHubController->DownstreamPorts = PortNumber;
- RootHubController->UsbDevice = RootHub;
- RootHubController->IsUsbHub = TRUE;
- RootHubController->DevicePath = UsbBusDev->DevicePath;
- RootHubController->HostController = Controller;
-
- RootHub->NumOfControllers = 1;
- RootHub->UsbController[0] = RootHubController;
- RootHub->DeviceSpeed = MaxSpeed;
-
- //
- // Report Status Code here since we will reset the host controller
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- EFI_IO_BUS_USB | EFI_IOB_PC_RESET,
- UsbBusDev->DevicePath
- );
-
- //
- // Reset USB Host Controller
- //
- UsbVirtualHcReset (
- UsbBusDev,
- EFI_USB_HC_RESET_GLOBAL
- );
-
- //
- // Report Status Code while we are going to bring up the Host Controller
- // and start bus enumeration
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- EFI_IO_BUS_USB | EFI_IOB_PC_ENABLE,
- UsbBusDev->DevicePath
- );
-
- //
- // Start USB Host Controller
- //
- UsbVirtualHcSetState (
- UsbBusDev,
- EfiUsbHcStateOperational
- );
-
- //
- // Create a timer to query root ports periodically
- //
- Status = gBS->CreateEvent (
- EVT_TIMER | EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- RootHubEnumeration,
- RootHubController,
- &RootHubController->HubNotify
- );
- if (EFI_ERROR (Status)) {
- gBS->UninstallProtocolInterface (
- Controller,
- &mUsbBusProtocolGuid,
- &UsbBusDev->BusIdentify
- );
-
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- } else {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- }
-
- gBS->FreePool (RootHubController);
- gBS->FreePool (RootHub);
- gBS->FreePool (UsbBusDev);
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Before depending on the timer to check root ports periodically,
- // here we should check them immediately for the first time, or
- // there will be an interval between bus start and devices start.
- //
- gBS->SignalEvent (RootHubController->HubNotify);
-
- Status = gBS->SetTimer (
- RootHubController->HubNotify,
- TimerPeriodic,
- BUSPOLLING_PERIOD
- );
- if (EFI_ERROR (Status)) {
- gBS->UninstallProtocolInterface (
- Controller,
- &mUsbBusProtocolGuid,
- &UsbBusDev->BusIdentify
- );
-
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- } else {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- }
-
- gBS->CloseEvent (RootHubController->HubNotify);
- gBS->FreePool (RootHubController);
- gBS->FreePool (RootHub);
- gBS->FreePool (UsbBusDev);
- return EFI_DEVICE_ERROR;
- }
-
- return EFI_SUCCESS;
-}
-
-//
-// Stop the bus controller
-//
-EFI_STATUS
-EFIAPI
-UsbBusControllerDriverStop (
- 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
- EFI_DEVICE_ERROR
- others
-
---*/
-{
- EFI_STATUS Status;
- USB_IO_DEVICE *Root;
- USB_IO_CONTROLLER_DEVICE *RootHubController;
- USB_BUS_CONTROLLER_DEVICE *UsbBusController;
- EFI_USB_BUS_PROTOCOL *UsbIdentifier;
- UINT8 Index2;
- USB_IO_CONTROLLER_DEVICE *UsbController;
- USB_IO_DEVICE *UsbIoDevice;
- USB_IO_CONTROLLER_DEVICE *HubController;
- UINTN Index;
- EFI_USB_IO_PROTOCOL *UsbIo;
-
- if (NumberOfChildren > 0) {
-
- for (Index = 0; Index < NumberOfChildren; Index++) {
- Status = gBS->OpenProtocol (
- ChildHandleBuffer[Index],
- &gEfiUsbIoProtocolGuid,
- (VOID **) &UsbIo,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- //
- // We are here since the handle passed in does not support
- // UsbIo protocol. There are several reasons that will cause
- // this.
- // For combo device such as keyboard, it may have 2 devices
- // in one, namely, keyboard and mouse. If we deconfigure one
- // of them, the other will be freed at the same time. This will
- // cause the status error. But this is the correct behavior.
- // For hub device, if we deconfigure hub first, the other chile
- // device will be disconnected also, this will also provide us
- // a status error. Now we will only report EFI_SUCCESS since Uhc
- // driver will be disconnected at the second time.(pls see
- // CoreDisconnectController for details)
- //
- continue;
- }
-
- UsbController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (UsbIo);
- UsbIoDevice = UsbController->UsbDevice;
- HubController = UsbController->Parent;
- UsbDeviceDeConfiguration (UsbIoDevice);
- for (Index2 = 0; Index2 < HubController->DownstreamPorts; Index2++) {
- if (HubController->Children[Index2] == UsbIoDevice) {
- HubController->Children[Index2] = NULL;
- }
- }
- }
-
- return EFI_SUCCESS;
- }
- //
- // Get the USB_BUS_CONTROLLER_DEVICE
- //
- Status = gBS->OpenProtocol (
- Controller,
- &mUsbBusProtocolGuid,
- (VOID **) &UsbIdentifier,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
-
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
-
- UsbBusController = USB_BUS_CONTROLLER_DEVICE_FROM_THIS (UsbIdentifier);
-
- //
- // Stop USB Host Controller
- //
-
- //
- // Report Status Code here since we will reset the host controller
- //
- ReportUsbStatusCode (
- UsbBusController,
- EFI_PROGRESS_CODE,
- EFI_IO_BUS_USB | EFI_IOB_PC_RESET
- );
-
- UsbVirtualHcSetState (
- UsbBusController,
- EfiUsbHcStateHalt
- );
-
- //
- // Deconfiguration all its devices
- //
- Root = UsbBusController->Root;
- RootHubController = Root->UsbController[0];
-
- gBS->CloseEvent (RootHubController->HubNotify);
-
- for (Index2 = 0; Index2 < RootHubController->DownstreamPorts; Index2++) {
- if (RootHubController->Children[Index2]) {
- UsbDeviceDeConfiguration (RootHubController->Children[Index2]);
- RootHubController->Children[Index2] = NULL;
- }
- }
-
- gBS->FreePool (RootHubController);
- gBS->FreePool (Root);
-
- //
- // Uninstall USB Bus Protocol
- //
- gBS->UninstallProtocolInterface (
- Controller,
- &mUsbBusProtocolGuid,
- &UsbBusController->BusIdentify
- );
-
- //
- // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL
- // Opened by this Controller
- //
- if (UsbBusController->Hc2ProtocolSupported) {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsb2HcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- } else {
- gBS->CloseProtocol (
- Controller,
- &gEfiUsbHcProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- gBS->FreePool (UsbBusController);
-
- return EFI_SUCCESS;
-}
-//
-// USB Device Configuration
-//
-STATIC
-EFI_STATUS
-UsbDeviceConfiguration (
- IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
- IN EFI_HANDLE HostController,
- IN UINT8 ParentPort,
- IN USB_IO_DEVICE *UsbIoDevice
- )
-/*++
-
- Routine Description:
- Configurate a new device attached to the usb bus
-
- Arguments:
- ParentHubController - Parent Hub which this device is connected.
- HostController - Host Controller handle
- ParentPort - Parent Hub port which this device is connected.
- UsbIoDevice - The device to be configured.
-
- Returns:
- EFI_SUCCESS
- EFI_DEVICE_ERROR
- EFI_OUT_OF_RESOURCES
-
---*/
-{
- UINT8 DevAddress;
- UINT8 Index;
- EFI_STATUS Result;
- UINT32 Status;
- CHAR16 *StrManufacturer;
- CHAR16 *StrProduct;
- CHAR16 *StrSerialNumber;
- EFI_USB_IO_PROTOCOL *UsbIo;
- UINT8 NumOfInterface;
- USB_IO_CONTROLLER_DEVICE *FirstController;
- USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
- USB_IO_CONTROLLER_DEVICE *UsbIoController;
-
- UsbBusDev = UsbIoDevice->BusController;
-
- UsbSetTransactionTranslator (
- ParentHubController,
- ParentPort,
- UsbIoDevice
- );
-
- //
- // Since a USB device must have at least on interface,
- // so create this instance first
- //
- FirstController = CreateUsbIoControllerDevice ();
- FirstController->UsbDevice = UsbIoDevice;
- UsbIoDevice->UsbController[0] = FirstController;
- FirstController->InterfaceNumber = 0;
- FirstController->ParentPort = ParentPort;
- FirstController->Parent = ParentHubController;
- FirstController->HostController = HostController;
-
- InitializeUsbIoInstance (FirstController);
-
- DEBUG ((gUSBDebugLevel, "Configuration Usb Device at 0x%x...\n", ParentPort));
-
- //
- // Ensure we used the correctly USB I/O instance
- //
- UsbIo = &FirstController->UsbIo;
-
- if (UsbIoDevice->DeviceSpeed != EFI_USB_SPEED_HIGH) {
- ParentPortReset (FirstController, FALSE, 0);
- }
-
- //
- // First retrieve the 1st 8 bytes of
- // in order to get the MaxPacketSize for Endpoint 0
- //
- for (Index = 0; Index < 3; Index++) {
-
- UsbIoDevice->DeviceDescriptor.MaxPacketSize0 = 8;
-
- gBS->Stall (100 * 1000);
-
- Result = UsbGetDescriptor (
- UsbIo,
- (USB_DT_DEVICE << 8),
- 0,
- 8,
- &UsbIoDevice->DeviceDescriptor,
- &Status
- );
- if (!EFI_ERROR (Result)) {
- DEBUG (
- (gUSBDebugLevel,
- "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
- UsbIoDevice->DeviceDescriptor.MaxPacketSize0)
- );
- break;
- }
-
- }
-
- if (Index == 3) {
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR
- );
- DEBUG ((gUSBErrorLevel, "Get Device Descriptor Fail when configing\n"));
- gBS->FreePool (FirstController);
- return EFI_DEVICE_ERROR;
- }
-
- DevAddress = UsbAllocateAddress (UsbIoDevice->BusController->AddressPool);
- if (DevAddress == 0) {
- DEBUG ((gUSBErrorLevel, "Cannot allocate address\n"));
- gBS->FreePool (FirstController);
- return EFI_OUT_OF_RESOURCES;
- }
-
- Result = UsbSetDeviceAddress (UsbIo, DevAddress, &Status);
-
- if (EFI_ERROR (Result)) {
- DEBUG ((gUSBErrorLevel, "Set address error\n"));
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_IO_BUS_USB | EFI_IOB_EC_WRITE_ERROR
- );
-
- UsbFreeAddress (
- DevAddress,
- UsbIoDevice->BusController->AddressPool
- );
-
- gBS->FreePool (FirstController);
- return EFI_DEVICE_ERROR;
- }
-
- UsbIoDevice->DeviceAddress = DevAddress;
-
- //
- // SetAddress Complete Time by Spec, Max 50ms
- //
- gBS->Stall (10 * 1000);
-
- //
- // Get the whole device descriptor
- //
- Result = UsbGetDescriptor (
- UsbIo,
- (USB_DT_DEVICE << 8),
- 0,
- sizeof (EFI_USB_DEVICE_DESCRIPTOR),
- &UsbIoDevice->DeviceDescriptor,
- &Status
- );
-
- if (EFI_ERROR (Result)) {
- DEBUG ((gUSBErrorLevel, "Get whole Device Descriptor error\n"));
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR
- );
- UsbFreeAddress (
- DevAddress,
- UsbIoDevice->BusController->AddressPool
- );
-
- gBS->FreePool (FirstController);
- return EFI_DEVICE_ERROR;
- }
- //
- // Get & parse all configurations for this device, including
- // all configuration descriptors, all interface descriptors, all
- // endpoint descriptors
- //
- Result = UsbGetAllConfigurations (UsbIoDevice);
-
- if (EFI_ERROR (Result)) {
- DEBUG ((gUSBErrorLevel, "Failed to get device configuration\n"));
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_IO_BUS_USB | EFI_IOB_EC_READ_ERROR
- );
- UsbFreeAddress (
- DevAddress,
- UsbIoDevice->BusController->AddressPool
- );
-
- gBS->FreePool (FirstController);
- return EFI_DEVICE_ERROR;
- }
- //
- // Set the 1st configuration value
- //
- Result = UsbSetDefaultConfiguration (UsbIoDevice);
- if (EFI_ERROR (Result)) {
- DEBUG ((gUSBErrorLevel, "Failed to set device configuration\n"));
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_IO_BUS_USB | EFI_IOB_EC_WRITE_ERROR
- );
- UsbFreeAddress (
- DevAddress,
- UsbIoDevice->BusController->AddressPool
- );
-
- gBS->FreePool (FirstController);
- return EFI_DEVICE_ERROR;
- }
-
- UsbIoDevice->IsConfigured = TRUE;
-
- //
- // Get all string table if applicable
- //
- Result = UsbGetStringtable (UsbIoDevice);
- if (EFI_ERROR (Result)) {
- DEBUG ((gUSBDebugLevel, "Device doesn't support string table\n"));
- } else {
-
- StrManufacturer = NULL;
- UsbIo->UsbGetStringDescriptor (
- UsbIo,
- UsbIoDevice->LangID[0],
- (UsbIoDevice->DeviceDescriptor).StrManufacturer,
- &StrManufacturer
- );
-
- StrProduct = NULL;
- UsbIo->UsbGetStringDescriptor (
- UsbIo,
- UsbIoDevice->LangID[0],
- (UsbIoDevice->DeviceDescriptor).StrProduct,
- &StrProduct
- );
-
- StrSerialNumber = NULL;
- UsbIo->UsbGetStringDescriptor (
- UsbIo,
- UsbIoDevice->LangID[0],
- (UsbIoDevice->DeviceDescriptor).StrSerialNumber,
- &StrSerialNumber
- );
-
- if (StrManufacturer) {
- gBS->FreePool (StrManufacturer);
- }
-
- if (StrProduct) {
- gBS->FreePool (StrProduct);
- }
-
- if (StrSerialNumber) {
- gBS->FreePool (StrSerialNumber);
- }
- }
- //
- // Create USB_IO_CONTROLLER_DEVICE for
- // each detected interface
- //
- FirstController->CurrentConfigValue =
- UsbIoDevice->ActiveConfig->CongfigDescriptor.ConfigurationValue;
-
- NumOfInterface =
- UsbIoDevice->ActiveConfig->CongfigDescriptor.NumInterfaces;
- UsbIoDevice->NumOfControllers = NumOfInterface;
-
- Result = InitUsbIoController (FirstController);
- if (EFI_ERROR (Result)) {
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_IO_BUS_USB | EFI_IOB_EC_INTERFACE_ERROR
- );
- gBS->FreePool (FirstController);
- UsbIoDevice->UsbController[0] = NULL;
- return EFI_DEVICE_ERROR;
- }
-
- for (Index = 1; Index < NumOfInterface; Index++) {
- UsbIoController = CreateUsbIoControllerDevice ();
- UsbIoController->UsbDevice = UsbIoDevice;
- UsbIoController->CurrentConfigValue =
- UsbIoDevice->ActiveConfig->CongfigDescriptor.ConfigurationValue;
- UsbIoController->InterfaceNumber = Index;
- UsbIoDevice->UsbController[Index] = UsbIoController;
- UsbIoController->ParentPort = ParentPort;
- UsbIoController->Parent = ParentHubController;
- UsbIoController->HostController = HostController;
-
- //
- // First copy the USB_IO Protocol instance
- //
- CopyMem (
- &UsbIoController->UsbIo,
- UsbIo,
- sizeof (EFI_USB_IO_PROTOCOL)
- );
-
- Result = InitUsbIoController (UsbIoController);
- if (EFI_ERROR (Result)) {
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_IO_BUS_USB | EFI_IOB_EC_INTERFACE_ERROR
- );
- gBS->FreePool (UsbIoController);
- UsbIoDevice->UsbController[Index] = NULL;
- }
- }
-
- return EFI_SUCCESS;
-}
-//
-// USB Device DeConfiguration
-//
-EFI_STATUS
-UsbDeviceDeConfiguration (
- IN USB_IO_DEVICE *UsbIoDevice
- )
-/*++
-
- Routine Description:
- Remove Device, Device Handles, Uninstall Protocols.
-
- Arguments:
- UsbIoDevice - The device to be deconfigured.
-
- Returns:
- EFI_SUCCESS
- EFI_DEVICE_ERROR
-
---*/
-{
- USB_IO_CONTROLLER_DEVICE *UsbController;
- UINT8 index;
- USB_IO_DEVICE *ChildDevice;
- UINT8 Index;
- EFI_USB_IO_PROTOCOL *UsbIo;
- EFI_STATUS Status;
-
- //
- // Double check UsbIoDevice exists
- //
- if (UsbIoDevice == NULL) {
- return EFI_SUCCESS;
- }
-
- UsbUnsetTransactionTranslator (UsbIoDevice);
-
- for (index = 0; index < UsbIoDevice->NumOfControllers; index++) {
- //
- // Check if it is a hub, if so, de configuration all its
- // downstream ports
- //
- UsbController = UsbIoDevice->UsbController[index];
-
- //
- // Check the controller pointer
- //
- if (UsbController == NULL) {
- continue;
- }
-
- if (UsbController->IsUsbHub) {
-
- DEBUG ((gUSBDebugLevel, "Hub Deconfig, First Deconfig its downstream ports\n"));
-
- //
- // First Remove interrupt transfer request for the status
- // change port
- //
- UsbIo = &UsbController->UsbIo;
- UsbIo->UsbAsyncInterruptTransfer (
- UsbIo,
- UsbController->HubEndpointAddress,
- FALSE,
- 0,
- 0,
- NULL,
- NULL
- );
-
- if (NULL != UsbController->HubNotify) {
- gBS->CloseEvent (UsbController->HubNotify);
- }
-
- for (Index = 0; Index < UsbController->DownstreamPorts; Index++) {
- if (UsbController->Children[Index]) {
- ChildDevice = UsbController->Children[Index];
- UsbDeviceDeConfiguration (ChildDevice);
- UsbController->Children[Index] = NULL;
- }
- }
- }
- //
- // If the controller is managed by a device driver, we need to
- // disconnect them
- //
- if (UsbController->IsManagedByDriver) {
- gBS->DisconnectController (
- UsbController->Handle,
- NULL,
- NULL
- );
- }
-
- //
- // remove child handle reference to the USB_HC_PROTOCOL
- //
- if (UsbIoDevice->BusController->Hc2ProtocolSupported) {
- gBS->CloseProtocol (
- UsbController->HostController,
- &gEfiUsb2HcProtocolGuid,
- gUsbBusDriverBinding.DriverBindingHandle,
- UsbController->Handle
- );
- } else {
- gBS->CloseProtocol (
- UsbController->HostController,
- &gEfiUsbHcProtocolGuid,
- gUsbBusDriverBinding.DriverBindingHandle,
- UsbController->Handle
- );
- }
- //
- // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
- // installed on this handle
- //
- Status = gBS->UninstallMultipleProtocolInterfaces (
- UsbController->Handle,
- &gEfiDevicePathProtocolGuid,
- UsbController->DevicePath,
- &gEfiUsbIoProtocolGuid,
- &UsbController->UsbIo,
- NULL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (UsbController->DevicePath != NULL) {
- gBS->FreePool (UsbController->DevicePath);
- }
-
- gBS->FreePool (UsbController);
- UsbIoDevice->UsbController[index] = NULL;
- }
- //
- // Free address for later use
- //
- UsbFreeAddress (
- UsbIoDevice->DeviceAddress,
- UsbIoDevice->BusController->AddressPool
- );
-
- //
- // Free all resouces allocated for all its configurations
- //
- UsbDestroyAllConfiguration (UsbIoDevice);
-
- if (UsbIoDevice) {
- gBS->FreePool (UsbIoDevice);
- UsbIoDevice = NULL;
- }
-
- return EFI_SUCCESS;
-}
-//
-// After interrupt complete, this function will be called,
-// This function need to be well-defined later
-//
-STATIC
-EFI_STATUS
-EFIAPI
-OnHubInterruptComplete (
- IN VOID *Data,
- IN UINTN DataLength,
- IN VOID *Context,
- IN UINT32 Result
- )
-/*++
-
- Routine Description:
- Whenever hub interrupt occurs, this routine will be called to check
- which event happens.
-
- Arguments:
- Data - Hub interrupt transfer data.
- DataLength - The length of the Data.
- Context - Hub Controller Device.
- Result - Hub interrupt transfer status.
-
- Returns:
- EFI_SUCCESS
- EFI_DEVICE_ERROR
-
---*/
-{
- USB_IO_CONTROLLER_DEVICE *HubController;
- UINT8 Index;
- UINT8 *ptr;
- EFI_USB_IO_PROTOCOL *UsbIo;
- UINT32 UsbResult;
- BOOLEAN Disconnected;
- EFI_STATUS Status;
-
- HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
- UsbIo = &HubController->UsbIo;
-
- //
- // If something error in this interrupt transfer,
- //
- if (Result != EFI_USB_NOERROR) {
- if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
- UsbClearEndpointHalt (
- UsbIo,
- HubController->HubEndpointAddress,
- &UsbResult
- );
- }
-
- //
- // Delete & Submit this interrupt again
- //
- UsbIo->UsbAsyncInterruptTransfer (
- UsbIo,
- HubController->HubEndpointAddress,
- FALSE,
- 0,
- 0,
- NULL,
- NULL
- );
-
- //
- // try to detect if the hub itself was disconnected or not
- //
- Status = IsDeviceDisconnected (
- HubController,
- &Disconnected
- );
-
- if (!EFI_ERROR (Status) && Disconnected == TRUE) {
- DEBUG ((gUSBErrorLevel, "Hub is disconnected\n"));
- return EFI_DEVICE_ERROR;
- }
- //
- // Hub ports < 7
- //
- UsbIo->UsbAsyncInterruptTransfer (
- UsbIo,
- HubController->HubEndpointAddress,
- TRUE,
- 100,
- 1,
- OnHubInterruptComplete,
- HubController
- );
-
- return EFI_DEVICE_ERROR;
- }
-
- if (DataLength == 0 || Data == NULL) {
- return EFI_SUCCESS;
- }
-
- //
- // Scan which port has status change
- // Bit 0 stands for hub itself, other bit stands for
- // the corresponding port
- //
- for (Index = 0; Index < DataLength * 8; Index++) {
- ptr = (UINT8 *) Data + Index / 8;
- if ((*ptr) & (1 << (Index & 0x7))) {
- HubController->StatusChangePort = Index;
- break;
- }
- }
- //
- // Signal hub notify event
- //
- gBS->SignalEvent (HubController->HubNotify);
-
- return EFI_SUCCESS;
-}
-//
-// USB Root Hub Enumerator
-//
-STATIC
-VOID
-EFIAPI
-RootHubEnumeration (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-/*++
-
- Routine Description:
-
- This is USB RootHub enumerator
-
- Arguments:
-
- Event - Indicating which event is signaled
- Context - actually it is a USB_IO_DEVICE
-
- Returns:
-
- VOID
-
---*/
-{
- USB_IO_CONTROLLER_DEVICE *HubController;
- EFI_USB_PORT_STATUS HubPortStatus;
- EFI_STATUS Status;
- UINT8 Index;
- USB_IO_DEVICE *UsbIoDev;
- USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
- EFI_HANDLE HostController;
- USB_IO_DEVICE *OldUsbIoDevice;
- USB_IO_DEVICE *NewDevice;
- USB_IO_CONTROLLER_DEVICE *NewController;
- UINT8 Index2;
- EFI_USB_IO_PROTOCOL *UsbIo;
-
- HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
- HostController = HubController->HostController;
- UsbBusDev = HubController->UsbDevice->BusController;
-
- //
- // Root hub has the address 1
- //
- UsbIoDev = HubController->UsbDevice;
-
- for (Index = 0; Index < HubController->DownstreamPorts; Index++) {
-
- UsbVirtualHcGetRootHubPortStatus (
- UsbBusDev,
- Index,
- (EFI_USB_PORT_STATUS *) &HubPortStatus
- );
-
- if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {
- continue;
- }
- //
- // Clear root hub status change status
- //
- UsbVirtualHcClearRootHubPortFeature (
- UsbBusDev,
- Index,
- EfiUsbPortConnectChange
- );
-
- gBS->Stall (100 * 1000);
-
- UsbVirtualHcGetRootHubPortStatus (
- UsbBusDev,
- Index,
- (EFI_USB_PORT_STATUS *) &HubPortStatus
- );
-
- if (IsPortConnect (HubPortStatus.PortStatus)) {
-
- //
- // There is something connected to this port
- //
- DEBUG ((gUSBDebugLevel, "Something connected to Root Hub at Port0x%x\n", Index));
-
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_PROGRESS_CODE,
- EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG
- );
- //
- // if there is something physically detached, but still logically
- // attached...
- //
- OldUsbIoDevice = HubController->Children[Index];
-
- if (NULL != OldUsbIoDevice) {
- UsbDeviceDeConfiguration (OldUsbIoDevice);
- HubController->Children[Index] = NULL;
- }
-
- NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));
- if (NewDevice == NULL) {
- return ;
- }
- //
- // Initialize some fields by copying data from
- // its parents
- //
- NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;
- NewDevice->BusController = UsbIoDev->BusController;
-
- //
- // Process of identify device speed
- //
- Status = IdentifyDeviceSpeed (
- UsbBusDev,
- NewDevice,
- Index
- );
- if (EFI_ERROR (Status)) {
- gBS->FreePool (NewDevice);
- continue;
- }
-
- //
- // Configure that device
- //
- Status = UsbDeviceConfiguration (
- HubController,
- HostController,
- Index,
- NewDevice
- );
- if (EFI_ERROR (Status)) {
- gBS->FreePool (NewDevice);
- return ;
- }
- //
- // Add this device to the usb bus tree
- //
- HubController->Children[Index] = NewDevice;
-
- for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {
- //
- // If this device is hub, add to the hub index
- //
- NewController = NewDevice->UsbController[Index2];
-
- Status = gBS->ConnectController (
- NewController->Handle,
- NULL,
- NULL,
- TRUE
- );
- //
- // If connect success, we need to disconnect when
- // stop the controller, otherwise we need not call
- // gBS->DisconnectController ()
- // This is used by those usb devices we don't plan
- // to support. We can allocate
- // controller handles for them, but we don't have
- // device drivers to manage them.
- //
- NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));
-
- if (IsHub (NewController)) {
-
- NewController->IsUsbHub = TRUE;
-
- //
- // Configure Hub Controller
- //
- Status = DoHubConfig (NewController);
- if (EFI_ERROR (Status)) {
- continue;
- }
- //
- // Create an event to do hub enumeration
- //
- gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- HubEnumeration,
- NewController,
- &NewController->HubNotify
- );
-
- //
- // Add request to do query hub status
- // change endpoint
- // Hub ports < 7
- //
- UsbIo = &NewController->UsbIo;
- UsbIo->UsbAsyncInterruptTransfer (
- UsbIo,
- NewController->HubEndpointAddress,
- TRUE,
- 100,
- 1,
- OnHubInterruptComplete,
- NewController
- );
-
- }
- }
- } else {
- //
- // Something disconnected from USB root hub
- //
- DEBUG ((gUSBDebugLevel, "Something disconnected from Root Hub at Port0x%x\n", Index));
-
- OldUsbIoDevice = HubController->Children[Index];
-
- UsbDeviceDeConfiguration (OldUsbIoDevice);
-
- HubController->Children[Index] = NULL;
-
- UsbVirtualHcClearRootHubPortFeature (
- UsbBusDev,
- Index,
- EfiUsbPortEnableChange
- );
- }
- }
-
- return ;
-}
-//
-// USB Root Hub Enumerator
-//
-STATIC
-VOID
-EFIAPI
-HubEnumeration (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-/*++
-
- Routine Description:
-
- This is Usb Hub enumerator
-
- Arguments:
-
- Event - Indicating which event is signaled
- Context - actually it is a USB_IO_DEVICE
-
- Returns:
-
- VOID
-
---*/
-{
- USB_IO_CONTROLLER_DEVICE *HubController;
- EFI_USB_PORT_STATUS HubPortStatus;
- EFI_STATUS Status;
- USB_BUS_CONTROLLER_DEVICE *UsbBusDev;
- EFI_HANDLE HostController;
- USB_IO_DEVICE *OldUsbIoDevice;
- USB_IO_DEVICE *NewDevice;
- USB_IO_CONTROLLER_DEVICE *NewController;
- UINT8 Index2;
- EFI_USB_IO_PROTOCOL *UsbIo;
- UINT8 StatusChangePort;
- UINT8 Number;
-
- HubController = (USB_IO_CONTROLLER_DEVICE *) Context;
- HostController = HubController->HostController;
- UsbBusDev = HubController->UsbDevice->BusController;
-
- //
- // Event from Hub, Get the hub controller handle
- //
- //
- // Get the status change endpoint
- //
- StatusChangePort = HubController->StatusChangePort;
-
- //
- // Clear HubController Status Change Bit
- //
- HubController->StatusChangePort = 0;
-
- if (StatusChangePort == 0) {
- //
- // Hub changes, we don't handle here
- //
- return ;
- }
- //
- // Check which event took place at that port
- //
- UsbIo = &HubController->UsbIo;
- Status = HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
- );
-
- if (EFI_ERROR (Status)) {
- return ;
- }
- //
- // Clear some change status
- //
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {
- //
- // Clear Hub port enable change
- //
- DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));
- HubClearPortFeature (
- UsbIo,
- StatusChangePort,
- EfiUsbPortEnableChange
- );
-
- HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
- );
- }
-
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {
- //
- // Clear Hub reset change
- //
- DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));
- HubClearPortFeature (
- UsbIo,
- StatusChangePort,
- EfiUsbPortResetChange
- );
-
- HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
- );
- }
-
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {
- //
- // Clear Hub overcurrent change
- //
- DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));
- HubClearPortFeature (
- UsbIo,
- StatusChangePort,
- EfiUsbPortOverCurrentChange
- );
-
- HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
- );
- }
-
- if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {
- //
- // First clear port connection change
- //
- DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));
- HubClearPortFeature (
- UsbIo,
- StatusChangePort,
- EfiUsbPortConnectChange
- );
-
- HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
- );
-
- if (IsPortConnect (HubPortStatus.PortStatus)) {
-
- DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));
-
- ReportUsbStatusCode (
- UsbBusDev,
- EFI_PROGRESS_CODE,
- EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG
- );
-
- //
- // if there is something physically detached, but still logically
- // attached...
- //
- OldUsbIoDevice = HubController->Children[StatusChangePort - 1];
-
- if (NULL != OldUsbIoDevice) {
- UsbDeviceDeConfiguration (OldUsbIoDevice);
- HubController->Children[StatusChangePort - 1] = NULL;
- }
-
- NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));
- if (NewDevice == NULL) {
- return ;
- }
- //
- // Initialize some fields
- //
- NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;
- NewDevice->BusController = HubController->UsbDevice->BusController;
-
- //
- // There is something connected to this port,
- // reset that port
- //
- // Disable the enable bit in port status
- //
- HubClearPortFeature (
- UsbIo,
- StatusChangePort,
- EfiUsbPortEnable
- );
-
- gBS->Stall (50 * 1000);
-
- //
- // Wait for bit change
- //
- Number = 10;
- do {
- HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
- );
- gBS->Stall (10 * 1000);
- Number -= 1;
- } while ((HubPortStatus.PortStatus & USB_PORT_STAT_ENABLE) == 1 && Number > 0);
-
- if (Number == 0) {
- //
- // Cannot disable port, return error
- //
- DEBUG ((gUSBErrorLevel, "Disable Port Failed\n"));
- gBS->FreePool (NewDevice);
- return ;
- }
-
- HubSetPortFeature (
- UsbIo,
- StatusChangePort,
- EfiUsbPortReset
- );
-
- gBS->Stall (50 * 1000);
-
- //
- // Wait for port reset complete
- //
- Number = 10;
- do {
- HubGetPortStatus (
- UsbIo,
- StatusChangePort,
- (UINT32 *) &HubPortStatus
- );
- gBS->Stall (10 * 1000);
- Number -= 1;
- } while ((HubPortStatus.PortStatus & USB_PORT_STAT_RESET) == 1 && Number > 0);
-
- if (Number == 0) {
- //
- // Cannot reset port, return error
- //
- DEBUG ((gUSBErrorLevel, "Reset Port Failed\n"));
- gBS->FreePool (NewDevice);
- return ;
- }
- //
- // Check high speed or full speed device
- //
- if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {
- DEBUG ((gUSBDebugLevel, "Low Speed Device Attached to Hub\n"));
- NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;
- } else if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {
- DEBUG ((gUSBDebugLevel, "High Speed Device Attached to Hub\n"));
- NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;
- } else {
- DEBUG ((gUSBDebugLevel, "Full Speed Device Attached to Hub\n"));
- NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;
- }
- //
- // Configure that device
- //
- Status = UsbDeviceConfiguration (
- HubController,
- HostController,
- (UINT8) (StatusChangePort - 1),
- NewDevice
- );
-
- if (EFI_ERROR (Status)) {
- gBS->FreePool (NewDevice);
- return ;
- }
- //
- // Add this device to the usb bus tree
- // StatusChangePort is begin from 1,
- //
- HubController->Children[StatusChangePort - 1] = NewDevice;
-
- for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {
- //
- // If this device is hub, add to the hub index
- //
- NewController = NewDevice->UsbController[Index2];
-
- //
- // Connect the controller to the driver image
- //
- Status = gBS->ConnectController (
- NewController->Handle,
- NULL,
- NULL,
- TRUE
- );
- //
- // If connect success, we need to disconnect when
- // stop the controller, otherwise we need not call
- // gBS->DisconnectController ()
- // This is used by those usb devices we don't plan
- // to support. We can allocate
- // controller handles for them, but we don't have
- // device drivers to manage them.
- //
- NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));
-
- //
- // If this device is hub, add to the hub index
- //
- if (IsHub (NewController)) {
-
- NewController->IsUsbHub = TRUE;
-
- //
- // Configure Hub
- //
- Status = DoHubConfig (NewController);
-
- if (EFI_ERROR (Status)) {
- continue;
- }
- //
- // Create an event to do hub enumeration
- //
- gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- HubEnumeration,
- NewController,
- &NewController->HubNotify
- );
-
- //
- // Add request to do query hub status
- // change endpoint
- //
- UsbIo = &NewController->UsbIo;
- UsbIo->UsbAsyncInterruptTransfer (
- UsbIo,
- NewController->HubEndpointAddress, // Hub endpoint address
- TRUE,
- 100,
- 1, // Hub ports < 7
- OnHubInterruptComplete,
- NewController
- );
- }
- }
- } else {
- //
- // Something disconnected from USB hub
- //
- DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));
-
- OldUsbIoDevice = HubController->Children[StatusChangePort - 1];
-
- UsbDeviceDeConfiguration (OldUsbIoDevice);
-
- HubController->Children[StatusChangePort - 1] = NULL;
-
- }
-
- return ;
- }
-
- return ;
-}
-
-STATIC
-USB_IO_CONTROLLER_DEVICE *
-CreateUsbIoControllerDevice (
- VOID
- )
-/*++
-
- Routine Description:
- Allocate a structure for USB_IO_CONTROLLER_DEVICE
-
- Arguments:
- N/A
-
- Returns:
- A pointer to a USB_IO_CONTROLLER_DEVICE structure,
- Or NULL.
-
---*/
-{
- USB_IO_CONTROLLER_DEVICE *UsbIoControllerDev;
-
- //
- // Allocate USB_IO_CONTROLLER_DEVICE structure
- //
- UsbIoControllerDev = NULL;
- UsbIoControllerDev = AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE));
-
- if (UsbIoControllerDev == NULL) {
- return NULL;
- }
-
- UsbIoControllerDev->Signature = USB_IO_CONTROLLER_SIGNATURE;
-
- return UsbIoControllerDev;
-}
-
-STATIC
-EFI_STATUS
-InitUsbIoController (
- IN USB_IO_CONTROLLER_DEVICE *UsbIoController
- )
-/*++
-
- Routine Description:
- Init and install EFI_USB_IO_PROTOCOL onto that controller.
-
- Arguments:
- UsbIoController - The Controller to be operated.
-
- Returns:
- EFI_SUCCESS
- Others
-
---*/
-{
- USB_DEVICE_PATH UsbNode;
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
- EFI_USB_HC_PROTOCOL *UsbHcProtocol;
- EFI_USB2_HC_PROTOCOL *Usb2HcProtocol;
-
- //
- // Build the child device path for each new USB_IO device
- //
- ZeroMem (&UsbNode, sizeof (UsbNode));
- UsbNode.Header.Type = MESSAGING_DEVICE_PATH;
- UsbNode.Header.SubType = MSG_USB_DP;
- SetDevicePathNodeLength (&UsbNode.Header, sizeof (UsbNode));
- UsbNode.InterfaceNumber = UsbIoController->InterfaceNumber;
- UsbNode.ParentPortNumber = UsbIoController->ParentPort;
- ParentDevicePath = UsbIoController->Parent->DevicePath;
-
- UsbIoController->DevicePath =
- AppendDevicePathNode (ParentDevicePath, &UsbNode.Header);
- if (UsbIoController->DevicePath == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = gBS->InstallMultipleProtocolInterfaces (
- &UsbIoController->Handle,
- &gEfiDevicePathProtocolGuid,
- UsbIoController->DevicePath,
- &gEfiUsbIoProtocolGuid,
- &UsbIoController->UsbIo,
- NULL
- );
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (UsbIoController->UsbDevice->BusController->Hc2ProtocolSupported) {
- Status = gBS->OpenProtocol (
- UsbIoController->HostController,
- &gEfiUsb2HcProtocolGuid,
- (VOID **)&Usb2HcProtocol,
- gUsbBusDriverBinding.DriverBindingHandle,
- UsbIoController->Handle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
- } else {
- Status = gBS->OpenProtocol (
- UsbIoController->HostController,
- &gEfiUsbHcProtocolGuid,
- (VOID **)&UsbHcProtocol,
- gUsbBusDriverBinding.DriverBindingHandle,
- UsbIoController->Handle,
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
- );
- }
-
- return Status;
-}
-
-STATIC
-EFI_STATUS
-ParentPortReset (
- IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
- IN BOOLEAN ReConfigure,
- IN UINT8 RetryTimes
- )
-/*++
-
- Routine Description:
- Reset parent hub port to which this device is connected.
-
- Arguments:
- UsbIoController - Indicating the Usb Controller Device.
- ReConfigure - Do we need to reconfigure it.
- RetryTimes - Retry Times when failed
-
- Returns:
- EFI_SUCCESS
- EFI_DEVICE_ERROR
-
---*/
-{
- USB_IO_DEVICE *ParentIoDev;
- USB_IO_DEVICE *UsbIoDev;
- USB_IO_CONTROLLER_DEVICE *ParentController;
- UINT8 HubPort;
- UINT32 Status;
- EFI_STATUS Result;
- EFI_USB_IO_PROTOCOL *UsbIo;
- UINT8 Address;
-
- ParentController = UsbIoController->Parent;
- ParentIoDev = ParentController->UsbDevice;
- UsbIoDev = UsbIoController->UsbDevice;
- HubPort = UsbIoController->ParentPort;
-
- gBS->Stall (100 * 1000);
-
- if (ParentIoDev->DeviceAddress == 1) {
- DEBUG ((gUSBDebugLevel, "Reset from Root Hub 0x%x\n", HubPort));
- ResetRootPort (ParentIoDev->BusController, HubPort, RetryTimes);
- } else {
- DEBUG ((gUSBDebugLevel, "Reset from Hub, Addr 0x%x\n", ParentIoDev->DeviceAddress));
- ResetHubPort (ParentController, (UINT8) (HubPort + 1));
- }
- //
- // If we only need port reset, just return
- //
- if (!ReConfigure) {
- return EFI_SUCCESS;
- }
- //
- // Re-config that USB device
- //
- UsbIo = &UsbIoController->UsbIo;
-
- //
- // Assign a unique address to this device
- //
- Address = UsbIoDev->DeviceAddress;
- UsbIoDev->DeviceAddress = 0;
-
- Result = UsbSetDeviceAddress (UsbIo, Address, &Status);
- UsbIoDev->DeviceAddress = Address;
-
- if (EFI_ERROR (Result)) {
- return EFI_DEVICE_ERROR;
- }
- //
- // Set the device to the default configuration
- //
- Result = UsbSetDefaultConfiguration (UsbIoDev);
- if (EFI_ERROR (Result)) {
- return EFI_DEVICE_ERROR;
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-UsbPortReset (
- IN EFI_USB_IO_PROTOCOL *This
- )
-/*++
-
- Routine Description:
- Resets and reconfigures the USB controller. This function will
- work for all USB devices except USB Hub Controllers.
-
- Arguments:
- This - Indicates the calling context.
-
- Returns:
- EFI_SUCCESS
- EFI_INVALID_PARAMETER
- EFI_DEVICE_ERROR
-
---*/
-{
- USB_IO_CONTROLLER_DEVICE *UsbIoController;
-
- UsbIoController = USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This);
-
- if (IsHub (UsbIoController)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Since at this time, this device has already been configured,
- // it needs to be re-configured.
- //
- return ParentPortReset (UsbIoController, TRUE, 0);
-}
-
-STATIC
-EFI_STATUS
-ResetRootPort (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT8 PortNum,
- IN UINT8 RetryTimes
- )
-/*++
-
- Routine Description:
- Reset Root Hub port.
-
- Arguments:
- UsbBusDev - Bus controller of the device.
- PortNum - The given port to be reset.
- RetryTimes - RetryTimes when failed
-
- Returns:
- EFI_SUCCESS
- EFI_DEVICE_ERROR
-
---*/
-{
- EFI_STATUS Status;
- EFI_USB_PORT_STATUS PortStatus;
-
- //
- // reset root port
- //
- Status = UsbVirtualHcSetRootHubPortFeature (
- UsbBusDev,
- PortNum,
- EfiUsbPortReset
- );
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
-
- gBS->Stall (50 * 1000);
-
- //
- // clear reset root port
- //
- Status = UsbVirtualHcClearRootHubPortFeature (
- UsbBusDev,
- PortNum,
- EfiUsbPortReset
- );
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
-
- gBS->Stall (1000);
-
- Status = UsbVirtualHcClearRootHubPortFeature (
- UsbBusDev,
- PortNum,
- EfiUsbPortConnectChange
- );
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
-
- UsbVirtualHcGetRootHubPortStatus (
- UsbBusDev,
- PortNum,
- &PortStatus
- );
- if (PortStatus.PortStatus & USB_PORT_STAT_OWNER) {
- //
- // Set port enable
- //
- Status = UsbVirtualHcSetRootHubPortFeature (
- UsbBusDev,
- PortNum,
- EfiUsbPortEnable
- );
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
-
- Status = UsbVirtualHcClearRootHubPortFeature (
- UsbBusDev,
- PortNum,
- EfiUsbPortEnableChange
- );
- }
-
- gBS->Stall ((1 + RetryTimes) * 50 * 1000);
-
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-ResetHubPort (
- IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
- IN UINT8 PortIndex
- )
-/*++
-
- Routine Description:
- Reset Hub port.
-
- Arguments:
- UsbIoController - The USB_IO_CONTROLLER_DEVICE instance.
- PortIndex - The given port to be reset.
-
- Returns:
- EFI_SUCCESS
- EFI_DEVICE_ERROR
-
---*/
-{
- EFI_USB_IO_PROTOCOL *UsbIo;
- EFI_USB_PORT_STATUS HubPortStatus;
- UINT8 Number;
-
- ASSERT (UsbIoController->IsUsbHub == TRUE);
-
- UsbIo = &UsbIoController->UsbIo;
-
- HubSetPortFeature (
- UsbIo,
- PortIndex,
- EfiUsbPortReset
- );
-
- gBS->Stall (10 * 1000);
-
- //
- // Wait for port reset complete
- //
- Number = 10;
- do {
- HubGetPortStatus (
- UsbIo,
- PortIndex,
- (UINT32 *) &HubPortStatus
- );
- gBS->Stall (10 * 100);
- Number -= 1;
- } while ((HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) == 0 && Number > 0);
-
- if (Number == 0) {
- //
- // Cannot reset port, return error
- //
- return EFI_DEVICE_ERROR;
- }
-
- gBS->Stall (1000);
-
- HubGetPortStatus (
- UsbIo,
- PortIndex,
- (UINT32 *) &HubPortStatus
- );
- //
- // reset port will cause some bits change, clear them
- //
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {
- DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));
- HubClearPortFeature (
- UsbIo,
- PortIndex,
- EfiUsbPortEnableChange
- );
- }
-
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {
- DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));
- HubClearPortFeature (
- UsbIo,
- PortIndex,
- EfiUsbPortResetChange
- );
- }
-
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-ReportUsbStatusCode (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusController,
- IN EFI_STATUS_CODE_TYPE Type,
- IN EFI_STATUS_CODE_VALUE Code
- )
-/*++
-
-Routine Description:
-
- report a error Status code of USB bus driver controller
-
- Arguments:
- UsbBusController - USB_BUS_CONTROLLER_DEVICE
- Type - EFI_STATUS_CODE_TYPE
- Code - EFI_STATUS_CODE_VALUE
- Returns:
-
- None
-
---*/
-{
- return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- Type,
- Code,
- UsbBusController->DevicePath
- );
-}
-
-EFI_STATUS
-IsDeviceDisconnected (
- IN USB_IO_CONTROLLER_DEVICE *UsbIoController,
- IN OUT BOOLEAN *Disconnected
- )
-/*++
-
- Routine Description:
- Reset if the device is disconencted or not
-
- Arguments:
- UsbIoController - Indicating the Usb Controller Device.
- Disconnected - Indicate whether the device is disconencted or not
-
- Returns:
- EFI_SUCCESS
- EFI_DEVICE_ERROR
-
---*/
-{
- USB_IO_DEVICE *ParentIoDev;
- USB_IO_CONTROLLER_DEVICE *ParentController;
- UINT8 HubPort;
- EFI_STATUS Status;
- EFI_USB_PORT_STATUS PortStatus;
-
- ParentController = UsbIoController->Parent;
- ParentIoDev = ParentController->UsbDevice;
- HubPort = UsbIoController->ParentPort;
-
- if (ParentIoDev->DeviceAddress == 1) {
- //
- // Connected to the root hub
- //
- UsbVirtualHcGetRootHubPortStatus (
- ParentIoDev->BusController,
- HubPort,
- &PortStatus
- );
-
- } else {
- Status = HubGetPortStatus (
- &ParentController->UsbIo,
- (UINT8) (HubPort + 1),
- (UINT32 *) &PortStatus
- );
-
- if (EFI_ERROR (Status)) {
- return IsDeviceDisconnected (ParentController, Disconnected);
- }
- }
-
- *Disconnected = FALSE;
-
- if (!IsPortConnect (PortStatus.PortStatus)) {
- *Disconnected = TRUE;
- }
-
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-UsbSetTransactionTranslator (
- IN USB_IO_CONTROLLER_DEVICE *ParentHubController,
- IN UINT8 ParentPort,
- IN OUT USB_IO_DEVICE *Device
- )
-/*++
-
- Routine Description:
-
- Set Transaction Translator parameter
-
- Arguments:
-
- ParentHubController - Controller structure of the parent Hub device
- ParentPort - Number of parent port
- Device - Structure of the device
-
- Returns:
-
- EFI_SUCCESS Success
- EFI_OUT_OF_RESOURCES Cannot allocate resources
-
---*/
-{
- USB_IO_CONTROLLER_DEVICE *AncestorHubController;
-
- AncestorHubController = ParentHubController;
- Device->Translator = NULL;
-
- if (EFI_USB_SPEED_HIGH == Device->DeviceSpeed) {
- return EFI_SUCCESS;
- }
-
- do {
- if (EFI_USB_SPEED_HIGH == AncestorHubController->UsbDevice->DeviceSpeed) {
- break;
- }
-
- if (NULL == AncestorHubController->Parent) {
- return EFI_SUCCESS;
- }
-
- AncestorHubController = AncestorHubController->Parent;
- } while (1);
-
- Device->Translator = AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR));
- if (NULL == Device->Translator) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Device->Translator->TranslatorHubAddress = AncestorHubController->UsbDevice->DeviceAddress;
- Device->Translator->TranslatorPortNumber = ParentPort;
-
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-UsbUnsetTransactionTranslator (
- USB_IO_DEVICE *Device
- )
-/*++
-
- Routine Description:
-
- Unset Transaction Translator parameter
-
- Arguments:
-
- Device - Structure of the device
-
- Returns:
-
- EFI_SUCCESS Success
-
---*/
-{
- if (Device->Translator) {
- gBS->FreePool (Device->Translator);
- Device->Translator = NULL;
- }
-
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-IdentifyDeviceSpeed (
- USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- USB_IO_DEVICE *NewDevice,
- UINT8 Index
- )
-/*++
-
- Routine Description:
-
- Identify speed of USB device
-
- Arguments:
-
- UsbBusDev - UsbBus controller structure of the device
- NewDevice - Devcie controller structure
- Index - Number of the port
-
- Returns:
-
- EFI_SUCCESS Success
- EFI_NOT_FOUND Device release to CHC or can't be found
-
---*/
-{
- EFI_STATUS Status;
- EFI_USB_PORT_STATUS HubPortStatus;
-
- UsbVirtualHcGetRootHubPortStatus (
- UsbBusDev,
- Index,
- (EFI_USB_PORT_STATUS *) &HubPortStatus
- );
-
- //
- // Check device device
- //
- if (!(HubPortStatus.PortStatus & USB_PORT_STAT_OWNER)) {
- //
- // EHC Port Owner
- //
- if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {
- DEBUG ((gUSBDebugLevel, "High Speed Device attached to EHC\n"));
- NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;
- } else {
- Status = ReleasePortToCHC (UsbBusDev, Index);
- if (EFI_ERROR (Status)) {
- DEBUG ((gUSBErrorLevel, "Fail to release port to CHC\n"));
- } else {
- DEBUG ((gUSBDebugLevel, "Success to release port to CHC\n"));
- }
- return EFI_DEVICE_ERROR;
- }
- } else {
- //
- // CHC Port Owner
- //
- if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {
- DEBUG ((gUSBDebugLevel, "Low Speed Device attached to CHC\n"));
- NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;
- } else {
- DEBUG ((gUSBDebugLevel, "FULL Speed Device attached to CHC\n"));
- NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-ReleasePortToCHC (
- USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- UINT8 PortNum
- )
-/*++
-
- Routine Description:
-
- Set bit to release the port owner to CHC
-
- Arguments:
-
- UsbBusDev - UsbBus controller structure of the device
- PortNum - Number of the port
-
- Returns:
-
- EFI_SUCCESS Success
- EFI_DEVICE_ERROR Fail
-
---*/
-{
- EFI_STATUS Status;
-
- Status = UsbVirtualHcSetRootHubPortFeature (
- UsbBusDev,
- PortNum,
- EfiUsbPortOwner
- );
-
- gBS->Stall (100 * 1000);
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcGetCapability (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- OUT UINT8 *MaxSpeed,
- OUT UINT8 *PortNumber,
- OUT UINT8 *Is64BitCapable
- )
-/*++
-
- Routine Description:
-
- Virtual interface to Retrieves the capablility of root hub ports
- for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- MaxSpeed - A pointer to the number of the host controller.
- PortNumber - A pointer to the number of the root hub ports.
- Is64BitCapable - A pointer to the flag for whether controller supports
- 64-bit memory addressing.
-
- Returns:
-
- EFI_SUCCESS
- The host controller capability were retrieved successfully.
- EFI_INVALID_PARAMETER
- MaxSpeed or PortNumber or Is64BitCapable is NULL.
- EFI_DEVICE_ERROR
- An error was encountered while attempting to retrieve the capabilities.
-
---*/
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->GetCapability (
- UsbBusDev->Usb2HCInterface,
- MaxSpeed,
- PortNumber,
- Is64BitCapable
- );
- } else {
- Status = UsbBusDev->UsbHCInterface->GetRootHubPortNumber (
- UsbBusDev->UsbHCInterface,
- PortNumber
- );
- *MaxSpeed = EFI_USB_SPEED_FULL;
- *Is64BitCapable = (UINT8) FALSE;
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcReset (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT16 Attributes
- )
-/*++
-
- Routine Description:
-
- Virtual interface to provides software reset for the USB host controller
- for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- Attributes - A bit mask of the reset operation to perform.
- See below for a list of the supported bit mask values.
-
- #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc
- #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
- #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
- #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
-
- EFI_USB_HC_RESET_GLOBAL
- If this bit is set, a global reset signal will be sent to the USB bus.
- This resets all of the USB bus logic, including the USB host
- controller hardware and all the devices attached on the USB bus.
- EFI_USB_HC_RESET_HOST_CONTROLLER
- If this bit is set, the USB host controller hardware will be reset.
- No reset signal will be sent to the USB bus.
- EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
- If this bit is set, a global reset signal will be sent to the USB bus.
- This resets all of the USB bus logic, including the USB host
- controller hardware and all the devices attached on the USB bus.
- If this is an EHCI controller and the debug port has configured, then
- this is will still reset the host controller.
- EFI_USB_HC_RESET_HOST_WITH_DEBUG
- If this bit is set, the USB host controller hardware will be reset.
- If this is an EHCI controller and the debug port has been configured,
- then this will still reset the host controller.
-
- Returns:
-
- EFI_SUCCESS
- The reset operation succeeded.
- EFI_INVALID_PARAMETER
- Attributes is not valid.
- EFI_UNSUPPOURTED
- The type of reset specified by Attributes is not currently supported by
- the host controller hardware.
- EFI_ACCESS_DENIED
- Reset operation is rejected due to the debug port being configured and
- active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
- EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
- perform reset operation for this host controller.
- EFI_DEVICE_ERROR
- An error was encountered while attempting to perform
- the reset operation.
-
---*/
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->Reset (
- UsbBusDev->Usb2HCInterface,
- EFI_USB_HC_RESET_GLOBAL
- );
- } else {
- Status = UsbBusDev->UsbHCInterface->Reset (
- UsbBusDev->UsbHCInterface,
- EFI_USB_HC_RESET_GLOBAL
- );
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcGetState (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- OUT EFI_USB_HC_STATE *State
- )
-/*++
-
- Routine Description:
-
- Virtual interface to retrieves current state of the USB host controller
- for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- State - A pointer to the EFI_USB_HC_STATE data structure that
- indicates current state of the USB host controller.
- Type EFI_USB_HC_STATE is defined below.
-
- typedef enum {
- EfiUsbHcStateHalt,
- EfiUsbHcStateOperational,
- EfiUsbHcStateSuspend,
- EfiUsbHcStateMaximum
- } EFI_USB_HC_STATE;
-
- Returns:
-
- EFI_SUCCESS
- The state information of the host controller was returned in State.
- EFI_INVALID_PARAMETER
- State is NULL.
- EFI_DEVICE_ERROR
- An error was encountered while attempting to retrieve the
- host controller's current state.
-
---*/
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->GetState (
- UsbBusDev->Usb2HCInterface,
- State
- );
- } else {
- Status = UsbBusDev->UsbHCInterface->GetState (
- UsbBusDev->UsbHCInterface,
- State
- );
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcSetState (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN EFI_USB_HC_STATE State
- )
-/*++
-
- Routine Description:
-
- Virtual interface to sets the USB host controller to a specific state
- for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- State - Indicates the state of the host controller that will be set.
-
- Returns:
-
- EFI_SUCCESS
- The USB host controller was successfully placed in the state
- specified by State.
- EFI_INVALID_PARAMETER
- State is invalid.
- EFI_DEVICE_ERROR
- Failed to set the state specified by State due to device error.
-
---*/
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->SetState (
- UsbBusDev->Usb2HCInterface,
- State
- );
- } else {
- Status = UsbBusDev->UsbHCInterface->SetState (
- UsbBusDev->UsbHCInterface,
- State
- );
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcGetRootHubPortStatus (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT8 PortNumber,
- OUT EFI_USB_PORT_STATUS *PortStatus
- )
-/*++
-
- Routine Description:
-
- Virtual interface to retrieves the current status of a USB root hub port
- both for Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- PortNumber - Specifies the root hub port from which the status
- is to be retrieved. This value is zero-based. For example,
- if a root hub has two ports, then the first port is numbered 0,
- and the second port is numbered 1.
- PortStatus - A pointer to the current port status bits and
- port status change bits.
-
- Returns:
-
- EFI_SUCCESS The status of the USB root hub port specified by PortNumber
- was returned in PortStatus.
- EFI_INVALID_PARAMETER PortNumber is invalid.
- EFI_DEVICE_ERROR Can't read register
-
---*/
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->GetRootHubPortStatus (
- UsbBusDev->Usb2HCInterface,
- PortNumber,
- PortStatus
- );
- } else {
- Status = UsbBusDev->UsbHCInterface->GetRootHubPortStatus (
- UsbBusDev->UsbHCInterface,
- PortNumber,
- PortStatus
- );
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcSetRootHubPortFeature (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT8 PortNumber,
- IN EFI_USB_PORT_FEATURE PortFeature
- )
-/*++
-
- Routine Description:
- Virual interface to sets a feature for the specified root hub port
- for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- PortNumber - Specifies the root hub port whose feature
- is requested to be set.
- PortFeature - Indicates the feature selector associated
- with the feature set request.
-
- Returns:
-
- EFI_SUCCESS
- The feature specified by PortFeature was set for the
- USB root hub port specified by PortNumber.
- EFI_INVALID_PARAMETER
- PortNumber is invalid or PortFeature is invalid.
- EFI_DEVICE_ERROR
- Can't read register
-
---*/
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->SetRootHubPortFeature (
- UsbBusDev->Usb2HCInterface,
- PortNumber,
- PortFeature
- );
- } else {
- Status = UsbBusDev->UsbHCInterface->SetRootHubPortFeature (
- UsbBusDev->UsbHCInterface,
- PortNumber,
- PortFeature
- );
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcClearRootHubPortFeature (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT8 PortNumber,
- IN EFI_USB_PORT_FEATURE PortFeature
- )
-/*++
-
- Routine Description:
-
- Virtual interface to clears a feature for the specified root hub port
- for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- PortNumber - Specifies the root hub port whose feature
- is requested to be cleared.
- PortFeature - Indicates the feature selector associated with the
- feature clear request.
-
- Returns:
-
- EFI_SUCCESS
- The feature specified by PortFeature was cleared for the
- USB root hub port specified by PortNumber.
- EFI_INVALID_PARAMETER
- PortNumber is invalid or PortFeature is invalid.
- EFI_DEVICE_ERROR
- Can't read register
-
---*/
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->ClearRootHubPortFeature (
- UsbBusDev->Usb2HCInterface,
- PortNumber,
- PortFeature
- );
- } else {
- Status = UsbBusDev->UsbHCInterface->ClearRootHubPortFeature (
- UsbBusDev->UsbHCInterface,
- PortNumber,
- PortFeature
- );
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcControlTransfer (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT8 DeviceAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN EFI_USB_DEVICE_REQUEST *Request,
- IN EFI_USB_DATA_DIRECTION TransferDirection,
- IN OUT VOID *Data,
- IN OUT UINTN *DataLength,
- IN UINTN TimeOut,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
- OUT UINT32 *TransferResult
- )
-/*++
-
- Routine Description:
-
- Virtual interface to submits control transfer to a target USB device
- for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- DeviceSpeed - Indicates target device speed.
- MaximumPacketLength - Indicates the maximum packet size that the
- default control transfer endpoint is capable of
- sending or receiving.
- Request - A pointer to the USB device request that will be sent
- to the USB device.
- TransferDirection - Specifies the data direction for the transfer.
- There are three values available, DataIn, DataOut
- and NoData.
- Data - A pointer to the buffer of data that will be transmitted
- to USB device or received from USB device.
- DataLength - Indicates the size, in bytes, of the data buffer
- specified by Data.
- TimeOut - Indicates the maximum time, in microseconds,
- which the transfer is allowed to complete.
- Translator - A pointr to the transaction translator data.
- TransferResult - A pointer to the detailed result information generated
- by this control transfer.
-
- Returns:
-
- EFI_SUCCESS
- The control transfer was completed successfully.
- EFI_OUT_OF_RESOURCES
- The control transfer could not be completed due to a lack of resources.
- EFI_INVALID_PARAMETER
- Some parameters are invalid.
- EFI_TIMEOUT
- The control transfer failed due to timeout.
- EFI_DEVICE_ERROR
- The control transfer failed due to host controller or device error.
- Caller should check TranferResult for detailed error information.
-
---*/
-{
- EFI_STATUS Status;
- BOOLEAN IsSlowDevice;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->ControlTransfer (
- UsbBusDev->Usb2HCInterface,
- DeviceAddress,
- DeviceSpeed,
- MaximumPacketLength,
- Request,
- TransferDirection,
- Data,
- DataLength,
- TimeOut,
- Translator,
- TransferResult
- );
- } else {
- IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
- Status = UsbBusDev->UsbHCInterface->ControlTransfer (
- UsbBusDev->UsbHCInterface,
- DeviceAddress,
- IsSlowDevice,
- (UINT8) MaximumPacketLength,
- Request,
- TransferDirection,
- Data,
- DataLength,
- TimeOut,
- TransferResult
- );
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcBulkTransfer (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN UINT8 DataBuffersNumber,
- IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
- IN OUT UINTN *DataLength,
- IN OUT UINT8 *DataToggle,
- IN UINTN TimeOut,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
- OUT UINT32 *TransferResult
- )
-/*++
-
- Routine Description:
-
- Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
- both for Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- EndPointAddress - The combination of an endpoint number and an
- endpoint direction of the target USB device.
- Each endpoint address supports data transfer in
- one direction except the control endpoint
- (whose default endpoint address is 0).
- It is the caller's responsibility to make sure that
- the EndPointAddress represents a bulk endpoint.
- DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
- and EFI_USB_SPEED_HIGH.
- MaximumPacketLength - Indicates the maximum packet size the target endpoint
- is capable of sending or receiving.
- DataBuffersNumber - Number of data buffers prepared for the transfer.
- Data - Array of pointers to the buffers of data that will be transmitted
- to USB device or received from USB device.
- DataLength - When input, indicates the size, in bytes, of the data buffer
- specified by Data. When output, indicates the actually
- transferred data size.
- DataToggle - A pointer to the data toggle value. On input, it indicates
- the initial data toggle value the bulk transfer should adopt;
- on output, it is updated to indicate the data toggle value
- of the subsequent bulk transfer.
- Translator - A pointr to the transaction translator data.
- TimeOut - Indicates the maximum time, in microseconds, which the
- transfer is allowed to complete.
- TransferResult - A pointer to the detailed result information of the
- bulk transfer.
-
- Returns:
-
- EFI_SUCCESS
- The bulk transfer was completed successfully.
- EFI_OUT_OF_RESOURCES
- The bulk transfer could not be submitted due to lack of resource.
- EFI_INVALID_PARAMETER
- Some parameters are invalid.
- EFI_TIMEOUT
- The bulk transfer failed due to timeout.
- EFI_DEVICE_ERROR
- The bulk transfer failed due to host controller or device error.
- Caller should check TranferResult for detailed error information.
-
---*/
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->BulkTransfer (
- UsbBusDev->Usb2HCInterface,
- DeviceAddress,
- EndPointAddress,
- DeviceSpeed,
- MaximumPacketLength,
- DataBuffersNumber,
- Data,
- DataLength,
- DataToggle,
- TimeOut,
- Translator,
- TransferResult
- );
- } else {
- Status = UsbBusDev->UsbHCInterface->BulkTransfer (
- UsbBusDev->UsbHCInterface,
- DeviceAddress,
- EndPointAddress,
- (UINT8) MaximumPacketLength,
- *Data,
- DataLength,
- DataToggle,
- TimeOut,
- TransferResult
- );
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcAsyncInterruptTransfer (
- IN USB_BUS_CONTROLLER_DEVICE * UsbBusDev,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN BOOLEAN IsNewTransfer,
- IN OUT UINT8 *DataToggle,
- IN UINTN PollingInterval,
- IN UINTN DataLength,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,
- IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
- IN VOID *Context OPTIONAL
- )
-/*++
-
- Routine Description:
-
- Virtual interface to submits an asynchronous interrupt transfer to an
- interrupt endpoint of a USB device for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- EndPointAddress - The combination of an endpoint number and an endpoint
- direction of the target USB device. Each endpoint address
- supports data transfer in one direction except the
- control endpoint (whose default endpoint address is 0).
- It is the caller's responsibility to make sure that
- the EndPointAddress represents an interrupt endpoint.
- DeviceSpeed - Indicates device speed.
- MaximumPacketLength - Indicates the maximum packet size the target endpoint
- is capable of sending or receiving.
- IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
- the host and the target interrupt endpoint.
- If FALSE, the specified asynchronous interrupt pipe
- is canceled.
- DataToggle - A pointer to the data toggle value. On input, it is valid
- when IsNewTransfer is TRUE, and it indicates the initial
- data toggle value the asynchronous interrupt transfer
- should adopt.
- On output, it is valid when IsNewTransfer is FALSE,
- and it is updated to indicate the data toggle value of
- the subsequent asynchronous interrupt transfer.
- PollingInterval - Indicates the interval, in milliseconds, that the
- asynchronous interrupt transfer is polled.
- This parameter is required when IsNewTransfer is TRUE.
- DataLength - Indicates the length of data to be received at the
- rate specified by PollingInterval from the target
- asynchronous interrupt endpoint. This parameter
- is only required when IsNewTransfer is TRUE.
- Translator - A pointr to the transaction translator data.
- CallBackFunction - The Callback function.This function is called at the
- rate specified by PollingInterval.This parameter is
- only required when IsNewTransfer is TRUE.
- Context - The context that is passed to the CallBackFunction.
- - This is an optional parameter and may be NULL.
-
- Returns:
-
- EFI_SUCCESS
- The asynchronous interrupt transfer request has been successfully
- submitted or canceled.
- EFI_INVALID_PARAMETER
- Some parameters are invalid.
- EFI_OUT_OF_RESOURCES
- The request could not be completed due to a lack of resources.
- EFI_DEVICE_ERROR
- Can't read register
-
---*/
-{
- EFI_STATUS Status;
- BOOLEAN IsSlowDevice;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->AsyncInterruptTransfer (
- UsbBusDev->Usb2HCInterface,
- DeviceAddress,
- EndPointAddress,
- DeviceSpeed,
- MaximumPacketLength,
- IsNewTransfer,
- DataToggle,
- PollingInterval,
- DataLength,
- Translator,
- CallBackFunction,
- Context
- );
- } else {
- IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
- Status = UsbBusDev->UsbHCInterface->AsyncInterruptTransfer (
- UsbBusDev->UsbHCInterface,
- DeviceAddress,
- EndPointAddress,
- IsSlowDevice,
- (UINT8) MaximumPacketLength,
- IsNewTransfer,
- DataToggle,
- PollingInterval,
- DataLength,
- CallBackFunction,
- Context
- );
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcSyncInterruptTransfer (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN OUT VOID *Data,
- IN OUT UINTN *DataLength,
- IN OUT UINT8 *DataToggle,
- IN UINTN TimeOut,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
- OUT UINT32 *TransferResult
- )
-/*++
-
- Routine Description:
-
- Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
- of a USB device for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- EndPointAddress - The combination of an endpoint number and an endpoint
- direction of the target USB device. Each endpoint
- address supports data transfer in one direction
- except the control endpoint (whose default
- endpoint address is 0). It is the caller's responsibility
- to make sure that the EndPointAddress represents
- an interrupt endpoint.
- DeviceSpeed - Indicates device speed.
- MaximumPacketLength - Indicates the maximum packet size the target endpoint
- is capable of sending or receiving.
- Data - A pointer to the buffer of data that will be transmitted
- to USB device or received from USB device.
- DataLength - On input, the size, in bytes, of the data buffer specified
- by Data. On output, the number of bytes transferred.
- DataToggle - A pointer to the data toggle value. On input, it indicates
- the initial data toggle value the synchronous interrupt
- transfer should adopt;
- on output, it is updated to indicate the data toggle value
- of the subsequent synchronous interrupt transfer.
- TimeOut - Indicates the maximum time, in microseconds, which the
- transfer is allowed to complete.
- Translator - A pointr to the transaction translator data.
- TransferResult - A pointer to the detailed result information from
- the synchronous interrupt transfer.
-
- Returns:
-
- EFI_SUCCESS
- The synchronous interrupt transfer was completed successfully.
- EFI_OUT_OF_RESOURCES
- The synchronous interrupt transfer could not be submitted due
- to lack of resource.
- EFI_INVALID_PARAMETER
- Some parameters are invalid.
- EFI_TIMEOUT
- The synchronous interrupt transfer failed due to timeout.
- EFI_DEVICE_ERROR
- The synchronous interrupt transfer failed due to host controller
- or device error. Caller should check TranferResult for detailed
- error information.
-
---*/
-{
- EFI_STATUS Status;
- BOOLEAN IsSlowDevice;
-
- Status = EFI_SUCCESS;
-
- if (UsbBusDev->Hc2ProtocolSupported) {
- Status = UsbBusDev->Usb2HCInterface->SyncInterruptTransfer (
- UsbBusDev->Usb2HCInterface,
- DeviceAddress,
- EndPointAddress,
- DeviceSpeed,
- MaximumPacketLength,
- Data,
- DataLength,
- DataToggle,
- TimeOut,
- Translator,
- TransferResult
- );
- } else {
- IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
- Status = UsbBusDev->UsbHCInterface->SyncInterruptTransfer (
- UsbBusDev->UsbHCInterface,
- DeviceAddress,
- EndPointAddress,
- IsSlowDevice,
- (UINT8) MaximumPacketLength,
- Data,
- DataLength,
- DataToggle,
- TimeOut,
- TransferResult
- );
- }
-
- return Status;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcIsochronousTransfer (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN UINT8 DataBuffersNumber,
- IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
- IN UINTN DataLength,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
- OUT UINT32 *TransferResult
- )
-/*++
-
- Routine Description:
-
- Virtual interface to submits isochronous transfer to a target USB device
- for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- EndPointAddress - End point address
- DeviceSpeed - Indicates device speed.
- MaximumPacketLength - Indicates the maximum packet size that the
- default control transfer endpoint is capable of
- sending or receiving.
- DataBuffersNumber - Number of data buffers prepared for the transfer.
- Data - Array of pointers to the buffers of data that will be
- transmitted to USB device or received from USB device.
- DataLength - Indicates the size, in bytes, of the data buffer
- specified by Data.
- Translator - A pointr to the transaction translator data.
- TransferResult - A pointer to the detailed result information generated
- by this control transfer.
-
- Returns:
-
- EFI_UNSUPPORTED
-
---*/
-{
- return EFI_UNSUPPORTED;
-}
-
-EFI_STATUS
-EFIAPI
-UsbVirtualHcAsyncIsochronousTransfer (
- IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DeviceSpeed,
- IN UINTN MaximumPacketLength,
- IN UINT8 DataBuffersNumber,
- IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
- IN UINTN DataLength,
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
- IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
- IN VOID *Context
- )
-/*++
-
- Routine Description:
-
- Vitual interface to submits Async isochronous transfer to a target USB device
- for both Hc2 and Hc protocol.
-
- Arguments:
-
- UsbBusDev - A pointer to bus controller of the device.
- DeviceAddress - Represents the address of the target device on the USB,
- which is assigned during USB enumeration.
- EndPointAddress - End point address
- DeviceSpeed - Indicates device speed.
- MaximumPacketLength - Indicates the maximum packet size that the
- default control transfer endpoint is capable of
- sending or receiving.
- DataBuffersNumber - Number of data buffers prepared for the transfer.
- Data - Array of pointers to the buffers of data that will be transmitted
- to USB device or received from USB device.
- DataLength - Indicates the size, in bytes, of the data buffer
- specified by Data.
- Translator - A pointr to the transaction translator data.
- IsochronousCallBack - When the transfer complete, the call back function will be called
- Context - Pass to the call back function as parameter
-
- Returns:
-
- EFI_UNSUPPORTED
-
---*/
-{
- return EFI_UNSUPPORTED;
-}