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