\r
#include "usbbus.h"\r
\r
-//#ifdef EFI_DEBUG\r
-UINTN gUSBDebugLevel = EFI_D_ERROR;\r
+UINTN gUSBDebugLevel = EFI_D_INFO;\r
UINTN gUSBErrorLevel = EFI_D_ERROR;\r
-//#endif\r
+\r
//\r
// The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER\r
// structure in the UsbBusDriverControllerDriverStop(). Then we can\r
//\r
STATIC\r
VOID\r
-EFIAPI\r
-UsbEnumeration (\r
+RootHubEnumeration (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ );\r
+\r
+STATIC\r
+VOID\r
+HubEnumeration (\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
);\r
\r
+STATIC\r
+EFI_STATUS\r
+UsbSetTransactionTranslator (\r
+ IN USB_IO_CONTROLLER_DEVICE *ParentHubController,\r
+ IN UINT8 ParentPort,\r
+ IN OUT USB_IO_DEVICE *Device\r
+ );\r
+\r
+STATIC\r
+EFI_STATUS\r
+UsbUnsetTransactionTranslator (\r
+ USB_IO_DEVICE *Device\r
+ );\r
+\r
+STATIC\r
+EFI_STATUS\r
+IdentifyDeviceSpeed (\r
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ USB_IO_DEVICE *NewDevice,\r
+ UINT8 Index\r
+ );\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReleasePortToCHC (\r
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ UINT8 PortNum\r
+ );\r
+\r
EFI_STATUS\r
ResetRootPort (\r
- IN EFI_USB_HC_PROTOCOL *UsbHCInterface,\r
- IN UINT8 PortNum,\r
- IN UINT8 RetryTimes\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNum,\r
+ IN UINT8 RetryTimes\r
);\r
\r
EFI_STATUS\r
IN UINT8 PortIndex\r
);\r
\r
-EFI_STATUS\r
-ClearRootPortConnectionChangeStatus (\r
- IN UINT8 PortNum,\r
- IN EFI_USB_HC_PROTOCOL *UsbHCInterface\r
- );\r
-\r
STATIC\r
EFI_STATUS\r
ParentPortReset (\r
UsbAllocateAddress (\r
IN UINT8 *AddressPool\r
)\r
+/*++\r
+\r
+ Routine Description:\r
+ Allocate address for usb device\r
+\r
+ Arguments:\r
+ AddressPool - Pool of usb device address\r
+\r
+ Returns:\r
+ Usb device address\r
+\r
+--*/\r
{\r
UINT8 ByteIndex;\r
UINT8 BitIndex;\r
IN UINT8 DevAddress,\r
IN UINT8 *AddressPool\r
)\r
+/*++\r
+\r
+ Routine Description:\r
+ Free address for usb device\r
+\r
+ Arguments:\r
+ DevAddress - Usb device address\r
+ AddressPool - Pool of usb device address\r
+ \r
+ Returns:\r
+ VOID\r
+\r
+--*/\r
{\r
UINT8 WhichByte;\r
UINT8 WhichBit;\r
\r
Arguments:\r
This - Protocol instance pointer.\r
- Controller - Handle of device to test\r
- RemainingDevicePath - Not used\r
+ Controller - Handle of device to test\r
+ RemainingDevicePath - Device Path Protocol instance pointer\r
\r
Returns:\r
EFI_SUCCESS - This driver supports this device.\r
\r
--*/\r
{\r
- EFI_STATUS OpenStatus;\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
+ EFI_USB2_HC_PROTOCOL *Usb2Hc;\r
+ EFI_USB_HC_PROTOCOL *UsbHc;\r
+ EFI_DEV_PATH_PTR Node;\r
+\r
+ //\r
+ // Check Device Path\r
+ //\r
+ if (RemainingDevicePath != NULL) {\r
+ Node.DevPath = RemainingDevicePath;\r
+ if (Node.DevPath->Type != MESSAGING_DEVICE_PATH ||\r
+ Node.DevPath->SubType != MSG_USB_DP ||\r
+ DevicePathNodeLength(Node.DevPath) != sizeof(USB_DEVICE_PATH)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ }\r
+ \r
+ //\r
+ // Open the IO Abstraction(s) needed to perform the supported test\r
+ //\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **) &ParentDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ \r
//\r
// Check whether USB Host Controller Protocol is already\r
// installed on this handle. If it is installed, we can start\r
// USB Bus Driver now.\r
//\r
- OpenStatus = gBS->OpenProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- NULL,\r
- This->DriverBindingHandle,\r
- Controller,\r
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
- );\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ (VOID **) &Usb2Hc,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ \r
+ if (EFI_ERROR (Status)) {\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ (VOID **) &UsbHc,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {\r
- return EFI_UNSUPPORTED;\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ return EFI_SUCCESS;\r
}\r
+ \r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
\r
- return OpenStatus;\r
+ return EFI_SUCCESS;\r
}\r
\r
-\r
EFI_STATUS\r
EFIAPI\r
UsbBusControllerDriverStart (\r
Returns:\r
\r
EFI_SUCCESS - This driver supports this device.\r
- EFI_UNSUPPORTED - This driver does not support this device.\r
EFI_DEVICE_ERROR - This driver cannot be started due to device\r
- Error\r
EFI_OUT_OF_RESOURCES- Can't allocate memory resources\r
- EFI_ALREADY_STARTED - This driver has been started\r
\r
--*/\r
{\r
USB_BUS_CONTROLLER_DEVICE *UsbBusDev;\r
USB_IO_DEVICE *RootHub;\r
USB_IO_CONTROLLER_DEVICE *RootHubController;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
+ UINT8 MaxSpeed;\r
+ UINT8 PortNumber;\r
+ UINT8 Is64BitCapable;\r
\r
//\r
// Allocate USB_BUS_CONTROLLER_DEVICE structure\r
\r
if (EFI_ERROR (OpenStatus)) {\r
gBS->FreePool (UsbBusDev);\r
- return EFI_UNSUPPORTED;\r
+ return OpenStatus;\r
}\r
//\r
// Locate the Host Controller Interface\r
//\r
OpenStatus = gBS->OpenProtocol (\r
Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- (VOID **) &UsbHCInterface,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ (VOID **) &(UsbBusDev->Usb2HCInterface),\r
This->DriverBindingHandle,\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
+ if (EFI_ERROR (OpenStatus)) {\r
\r
- if (EFI_ERROR (OpenStatus) && (OpenStatus != EFI_ALREADY_STARTED)) {\r
- \r
- //\r
- // Report Status Code here since we will reset the host controller\r
- //\r
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
- EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
- EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,\r
- UsbBusDev->DevicePath\r
- );\r
+ UsbBusDev->Hc2ProtocolSupported = FALSE;\r
+ OpenStatus = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ (VOID **) &(UsbBusDev->UsbHCInterface),\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_BY_DRIVER\r
+ );\r
+ if (EFI_ERROR (OpenStatus)) {\r
+ //\r
+ // Report Status Code here since we will reset the host controller\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
+ EFI_IO_BUS_USB | EFI_IOB_EC_CONTROLLER_ERROR,\r
+ UsbBusDev->DevicePath\r
+ );\r
\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
- gBS->FreePool (UsbBusDev);\r
- return EFI_UNSUPPORTED;\r
- }\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ gBS->FreePool (UsbBusDev);\r
+ return OpenStatus;\r
+ }\r
\r
- if (OpenStatus == EFI_ALREADY_STARTED) {\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiDevicePathProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
- gBS->FreePool (UsbBusDev);\r
- return EFI_ALREADY_STARTED;\r
+ DEBUG ((gUSBDebugLevel, "UsbHcProtocol Opened.\n"));\r
+ } else {\r
+ DEBUG ((gUSBDebugLevel, "Usb2HcProtocol Opened.\n"));\r
+ UsbBusDev->Hc2ProtocolSupported = TRUE;\r
}\r
\r
- UsbBusDev->UsbHCInterface = UsbHCInterface;\r
-\r
//\r
// Attach EFI_USB_BUS_PROTOCOL to controller handle,\r
// for locate UsbBusDev later\r
This->DriverBindingHandle,\r
Controller\r
);\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
+\r
gBS->FreePool (UsbBusDev);\r
return Status;\r
}\r
This->DriverBindingHandle,\r
Controller\r
);\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
+\r
gBS->FreePool (UsbBusDev);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
This->DriverBindingHandle,\r
Controller\r
);\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
gBS->FreePool (UsbBusDev);\r
gBS->FreePool (RootHub);\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- UsbHCInterface->GetRootHubPortNumber (\r
- UsbHCInterface,\r
- &RootHubController->DownstreamPorts\r
- );\r
- RootHubController->UsbDevice = RootHub;\r
- RootHubController->IsUsbHub = TRUE;\r
- RootHubController->DevicePath = UsbBusDev->DevicePath;\r
- RootHubController->HostController = Controller;\r
+ UsbVirtualHcGetCapability (\r
+ UsbBusDev,\r
+ &MaxSpeed,\r
+ &PortNumber,\r
+ &Is64BitCapable\r
+ );\r
+ RootHubController->DownstreamPorts = PortNumber;\r
+ RootHubController->UsbDevice = RootHub;\r
+ RootHubController->IsUsbHub = TRUE;\r
+ RootHubController->DevicePath = UsbBusDev->DevicePath;\r
+ RootHubController->HostController = Controller;\r
\r
- RootHub->NumOfControllers = 1;\r
- RootHub->UsbController[0] = RootHubController;\r
+ RootHub->NumOfControllers = 1;\r
+ RootHub->UsbController[0] = RootHubController;\r
+ RootHub->DeviceSpeed = MaxSpeed;\r
\r
//\r
// Report Status Code here since we will reset the host controller\r
//\r
// Reset USB Host Controller\r
//\r
- UsbHCInterface->Reset (\r
- UsbHCInterface,\r
- EFI_USB_HC_RESET_GLOBAL\r
- );\r
+ UsbVirtualHcReset (\r
+ UsbBusDev,\r
+ EFI_USB_HC_RESET_GLOBAL\r
+ );\r
\r
//\r
// Report Status Code while we are going to bring up the Host Controller\r
//\r
// Start USB Host Controller\r
//\r
- UsbHCInterface->SetState (\r
- UsbHCInterface,\r
- EfiUsbHcStateOperational\r
- );\r
+ UsbVirtualHcSetState (\r
+ UsbBusDev,\r
+ EfiUsbHcStateOperational\r
+ );\r
\r
//\r
// Create a timer to query root ports periodically\r
Status = gBS->CreateEvent (\r
EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,\r
EFI_TPL_CALLBACK,\r
- UsbEnumeration,\r
+ RootHubEnumeration,\r
RootHubController,\r
&RootHubController->HubNotify\r
);\r
Controller\r
);\r
\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
\r
gBS->FreePool (RootHubController);\r
gBS->FreePool (RootHub);\r
gBS->FreePool (UsbBusDev);\r
- return EFI_UNSUPPORTED;\r
+ return EFI_OUT_OF_RESOURCES;\r
}\r
\r
//\r
Controller\r
);\r
\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
\r
gBS->CloseEvent (RootHubController->HubNotify);\r
gBS->FreePool (RootHubController);\r
gBS->FreePool (RootHub);\r
gBS->FreePool (UsbBusDev);\r
- return EFI_UNSUPPORTED;\r
+ return EFI_DEVICE_ERROR;\r
}\r
\r
return EFI_SUCCESS;\r
}\r
+\r
//\r
// Stop the bus controller\r
//\r
USB_BUS_CONTROLLER_DEVICE *UsbBusController;\r
EFI_USB_BUS_PROTOCOL *UsbIdentifier;\r
UINT8 Index2;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
USB_IO_CONTROLLER_DEVICE *UsbController;\r
USB_IO_DEVICE *UsbIoDevice;\r
USB_IO_CONTROLLER_DEVICE *HubController;\r
//\r
// Stop USB Host Controller\r
//\r
- UsbHCInterface = UsbBusController->UsbHCInterface;\r
\r
//\r
// Report Status Code here since we will reset the host controller\r
EFI_IO_BUS_USB | EFI_IOB_PC_RESET\r
);\r
\r
- UsbHCInterface->SetState (\r
- UsbHCInterface,\r
- EfiUsbHcStateHalt\r
- );\r
+ UsbVirtualHcSetState (\r
+ UsbBusController,\r
+ EfiUsbHcStateHalt\r
+ );\r
\r
//\r
// Deconfiguration all its devices\r
// Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL\r
// Opened by this Controller\r
//\r
- gBS->CloseProtocol (\r
- Controller,\r
- &gEfiUsbHcProtocolGuid,\r
- This->DriverBindingHandle,\r
- Controller\r
- );\r
+ if (UsbBusController->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiUsbHcProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ }\r
\r
gBS->CloseProtocol (\r
Controller,\r
USB_IO_CONTROLLER_DEVICE *UsbIoController;\r
\r
UsbBusDev = UsbIoDevice->BusController;\r
+\r
+ UsbSetTransactionTranslator (\r
+ ParentHubController,\r
+ ParentPort,\r
+ UsbIoDevice\r
+ );\r
+\r
//\r
// Since a USB device must have at least on interface,\r
// so create this instance first\r
//\r
UsbIo = &FirstController->UsbIo;\r
\r
+ ParentPortReset (FirstController, FALSE, 0);\r
+\r
//\r
// First retrieve the 1st 8 bytes of\r
// in order to get the MaxPacketSize for Endpoint 0\r
\r
UsbIoDevice->DeviceDescriptor.MaxPacketSize0 = 8;\r
\r
- ParentPortReset (FirstController, FALSE, Index);\r
+ gBS->Stall (100 * 1000);\r
\r
Result = UsbGetDescriptor (\r
UsbIo,\r
&Status\r
);\r
if (!EFI_ERROR (Result)) {\r
- DEBUG ((gUSBDebugLevel,\r
+ DEBUG (\r
+ (gUSBDebugLevel,\r
"Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",\r
UsbIoDevice->DeviceDescriptor.MaxPacketSize0)\r
);\r
\r
UsbIoDevice->DeviceAddress = DevAddress;\r
\r
+ //\r
+ // SetAddress Complete Time by Spec, Max 50ms\r
+ //\r
+ gBS->Stall (10 * 1000);\r
+\r
//\r
// Get the whole device descriptor\r
//\r
//\r
// USB Device DeConfiguration\r
//\r
-\r
EFI_STATUS\r
UsbDeviceDeConfiguration (\r
IN USB_IO_DEVICE *UsbIoDevice\r
UINT8 Index;\r
EFI_USB_IO_PROTOCOL *UsbIo;\r
\r
- DEBUG ((gUSBDebugLevel, "Enter Usb Device Deconfiguration\n"));\r
-\r
//\r
// Double check UsbIoDevice exists\r
//\r
return EFI_SUCCESS;\r
}\r
\r
+ UsbUnsetTransactionTranslator (UsbIoDevice);\r
+\r
for (index = 0; index < UsbIoDevice->NumOfControllers; index++) {\r
//\r
// Check if it is a hub, if so, de configuration all its\r
//\r
// remove child handle reference to the USB_HC_PROTOCOL\r
//\r
- gBS->CloseProtocol (\r
- UsbController->HostController,\r
- &gEfiUsbHcProtocolGuid,\r
- gUsbBusDriverBinding.DriverBindingHandle,\r
- UsbController->Handle\r
- );\r
-\r
+ if (UsbIoDevice->BusController->Hc2ProtocolSupported) {\r
+ gBS->CloseProtocol (\r
+ UsbController->HostController,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ gUsbBusDriverBinding.DriverBindingHandle,\r
+ UsbController->Handle\r
+ );\r
+ } else {\r
+ gBS->CloseProtocol (\r
+ UsbController->HostController,\r
+ &gEfiUsbHcProtocolGuid,\r
+ gUsbBusDriverBinding.DriverBindingHandle,\r
+ UsbController->Handle\r
+ );\r
+ }\r
//\r
// Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL\r
// installed on this handle\r
STATIC\r
VOID\r
EFIAPI\r
-UsbEnumeration (\r
+RootHubEnumeration (\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
)\r
/*++\r
\r
Routine Description:\r
- This is USB enumerator\r
+ \r
+ This is USB RootHub enumerator\r
\r
Arguments:\r
+ \r
Event - Indicating which event is signaled\r
Context - actually it is a USB_IO_DEVICE\r
\r
Returns:\r
- EFI_SUCCESS\r
- Others\r
-\r
+ \r
+ VOID\r
+ \r
--*/\r
{\r
USB_IO_CONTROLLER_DEVICE *HubController;\r
EFI_USB_PORT_STATUS HubPortStatus;\r
EFI_STATUS Status;\r
UINT8 Index;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
USB_IO_DEVICE *UsbIoDev;\r
USB_BUS_CONTROLLER_DEVICE *UsbBusDev;\r
EFI_HANDLE HostController;\r
USB_IO_CONTROLLER_DEVICE *NewController;\r
UINT8 Index2;\r
EFI_USB_IO_PROTOCOL *UsbIo;\r
- UINT8 StatusChangePort;\r
\r
HubController = (USB_IO_CONTROLLER_DEVICE *) Context;\r
HostController = HubController->HostController;\r
UsbBusDev = HubController->UsbDevice->BusController;\r
\r
- if (HubController->UsbDevice->DeviceAddress == 1) {\r
+ //\r
+ // Root hub has the address 1\r
+ //\r
+ UsbIoDev = HubController->UsbDevice;\r
+\r
+ for (Index = 0; Index < HubController->DownstreamPorts; Index++) {\r
+\r
+ UsbVirtualHcGetRootHubPortStatus (\r
+ UsbBusDev,\r
+ Index,\r
+ (EFI_USB_PORT_STATUS *) &HubPortStatus\r
+ );\r
+\r
+ if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
+ continue;\r
+ }\r
//\r
- // Root hub has the address 1\r
+ // Clear root hub status change status\r
//\r
- UsbIoDev = HubController->UsbDevice;\r
- UsbHCInterface = UsbIoDev->BusController->UsbHCInterface;\r
-\r
- for (Index = 0; Index < HubController->DownstreamPorts; Index++) {\r
- UsbHCInterface->GetRootHubPortStatus (\r
- UsbHCInterface,\r
- Index,\r
- (EFI_USB_PORT_STATUS *) &HubPortStatus\r
- );\r
+ UsbVirtualHcClearRootHubPortFeature (\r
+ UsbBusDev,\r
+ Index,\r
+ EfiUsbPortConnectChange\r
+ );\r
\r
- if (!IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
- continue;\r
- }\r
+ gBS->Stall (100 * 1000);\r
+\r
+ UsbVirtualHcGetRootHubPortStatus (\r
+ UsbBusDev,\r
+ Index,\r
+ (EFI_USB_PORT_STATUS *) &HubPortStatus\r
+ );\r
+\r
+ if (IsPortConnect (HubPortStatus.PortStatus)) {\r
+ \r
//\r
- // Clear root hub status change status\r
+ // There is something connected to this port\r
//\r
- ClearRootPortConnectionChangeStatus (\r
- Index,\r
- UsbHCInterface\r
+ DEBUG ((gUSBDebugLevel, "Something connected to Root Hub at Port0x%x\n", Index));\r
+\r
+ ReportUsbStatusCode (\r
+ UsbBusDev,\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
);\r
+ //\r
+ // if there is something physically detached, but still logically\r
+ // attached...\r
+ //\r
+ OldUsbIoDevice = HubController->Children[Index];\r
\r
- gBS->Stall (100 * 1000);\r
+ if (NULL != OldUsbIoDevice) {\r
+ UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+ HubController->Children[Index] = NULL;\r
+ }\r
\r
- UsbHCInterface->GetRootHubPortStatus (\r
- UsbHCInterface,\r
- Index,\r
- (EFI_USB_PORT_STATUS *) &HubPortStatus\r
- );\r
+ NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
+ if (NewDevice == NULL) {\r
+ return ;\r
+ }\r
+ //\r
+ // Initialize some fields by copying data from\r
+ // its parents\r
+ //\r
+ NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;\r
+ NewDevice->BusController = UsbIoDev->BusController;\r
\r
- if (IsPortConnect (HubPortStatus.PortStatus)) {\r
- \r
+ //\r
+ // Process of identify device speed\r
+ //\r
+ Status = IdentifyDeviceSpeed (\r
+ UsbBusDev, \r
+ NewDevice, \r
+ Index\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (NewDevice);\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Configure that device\r
+ //\r
+ Status = UsbDeviceConfiguration (\r
+ HubController,\r
+ HostController,\r
+ Index,\r
+ NewDevice\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (NewDevice);\r
+ return ;\r
+ }\r
+ //\r
+ // Add this device to the usb bus tree\r
+ //\r
+ HubController->Children[Index] = NewDevice;\r
+\r
+ for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
//\r
- // There is something connected to this port\r
+ // If this device is hub, add to the hub index\r
//\r
- DEBUG ((gUSBDebugLevel, "Something attached from Root Hub in 0x%x\n", Index));\r
+ NewController = NewDevice->UsbController[Index2];\r
\r
- ReportUsbStatusCode (\r
- UsbBusDev,\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
- );\r
- //\r
- // if there is something physically detached, but still logically\r
- // attached...\r
- //\r
- OldUsbIoDevice = HubController->Children[Index];\r
-\r
- if (NULL != OldUsbIoDevice) {\r
- UsbDeviceDeConfiguration (OldUsbIoDevice);\r
- HubController->Children[Index] = NULL;\r
- }\r
-\r
- NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
- if (NewDevice == NULL) {\r
- return ;\r
- }\r
+ Status = gBS->ConnectController (\r
+ NewController->Handle,\r
+ NULL,\r
+ NULL,\r
+ TRUE\r
+ );\r
//\r
- // Initialize some fields by copying data from\r
- // its parents\r
+ // If connect success, we need to disconnect when\r
+ // stop the controller, otherwise we need not call\r
+ // gBS->DisconnectController ()\r
+ // This is used by those usb devices we don't plan\r
+ // to support. We can allocate\r
+ // controller handles for them, but we don't have\r
+ // device drivers to manage them.\r
//\r
- NewDevice->IsSlowDevice = IsPortLowSpeedDeviceAttached (HubPortStatus.PortStatus);\r
-\r
- DEBUG ((gUSBDebugLevel, "DeviceSpeed 0x%x\n", NewDevice->IsSlowDevice));\r
+ NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
\r
- NewDevice->BusController = UsbIoDev->BusController;\r
+ if (IsHub (NewController)) {\r
\r
- //\r
- // Configure that device\r
- //\r
- Status = UsbDeviceConfiguration (\r
- HubController,\r
- HostController,\r
- Index,\r
- NewDevice\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (NewDevice);\r
- return ;\r
- }\r
- //\r
- // Add this device to the usb bus tree\r
- //\r
- HubController->Children[Index] = NewDevice;\r
+ NewController->IsUsbHub = TRUE;\r
\r
- for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
//\r
- // If this device is hub, add to the hub index\r
+ // Configure Hub Controller\r
//\r
- NewController = NewDevice->UsbController[Index2];\r
-\r
- Status = gBS->ConnectController (\r
- NewController->Handle,\r
- NULL,\r
- NULL,\r
- TRUE\r
- );\r
+ Status = DoHubConfig (NewController);\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
//\r
- // If connect success, we need to disconnect when\r
- // stop the controller, otherwise we need not call\r
- // gBS->DisconnectController ()\r
- // This is used by those usb devices we don't plan\r
- // to support. We can allocate\r
- // controller handles for them, but we don't have\r
- // device drivers to manage them.\r
+ // Create an event to do hub enumeration\r
//\r
- NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
-\r
- if (IsHub (NewController)) {\r
-\r
- NewController->IsUsbHub = TRUE;\r
-\r
- //\r
- // Configure Hub Controller\r
- //\r
- Status = DoHubConfig (NewController);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
- //\r
- // Create an event to do hub enumeration\r
- //\r
- gBS->CreateEvent (\r
- EFI_EVENT_NOTIFY_SIGNAL,\r
- EFI_TPL_CALLBACK,\r
- UsbEnumeration,\r
- NewController,\r
- &NewController->HubNotify\r
- );\r
+ gBS->CreateEvent (\r
+ EFI_EVENT_NOTIFY_SIGNAL,\r
+ EFI_TPL_CALLBACK,\r
+ HubEnumeration,\r
+ NewController,\r
+ &NewController->HubNotify\r
+ );\r
\r
- //\r
- // Add request to do query hub status\r
- // change endpoint\r
- // Hub ports < 7\r
- //\r
- UsbIo = &NewController->UsbIo;\r
- UsbIo->UsbAsyncInterruptTransfer (\r
- UsbIo,\r
- NewController->HubEndpointAddress,\r
- TRUE,\r
- 100,\r
- 1,\r
- OnHubInterruptComplete,\r
- NewController\r
- );\r
+ //\r
+ // Add request to do query hub status\r
+ // change endpoint\r
+ // Hub ports < 7\r
+ //\r
+ UsbIo = &NewController->UsbIo;\r
+ UsbIo->UsbAsyncInterruptTransfer (\r
+ UsbIo,\r
+ NewController->HubEndpointAddress,\r
+ TRUE,\r
+ 100,\r
+ 1,\r
+ OnHubInterruptComplete,\r
+ NewController\r
+ );\r
\r
- }\r
}\r
- } else {\r
- //\r
- // Something disconnected from USB root hub\r
- //\r
- DEBUG ((gUSBDebugLevel, "Something deteached from Root Hub\n"));\r
+ }\r
+ } else {\r
+ //\r
+ // Something disconnected from USB root hub\r
+ //\r
+ DEBUG ((gUSBDebugLevel, "Something disconnected from Root Hub at Port0x%x\n", Index));\r
\r
- OldUsbIoDevice = HubController->Children[Index];\r
+ OldUsbIoDevice = HubController->Children[Index];\r
\r
- UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+ UsbDeviceDeConfiguration (OldUsbIoDevice);\r
\r
- HubController->Children[Index] = NULL;\r
+ HubController->Children[Index] = NULL;\r
+\r
+ UsbVirtualHcClearRootHubPortFeature (\r
+ UsbBusDev,\r
+ Index,\r
+ EfiUsbPortEnableChange\r
+ );\r
+ }\r
+ }\r
+\r
+ return ;\r
+}\r
+//\r
+// USB Root Hub Enumerator\r
+//\r
+STATIC\r
+VOID\r
+EFIAPI\r
+HubEnumeration (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
\r
- UsbHCInterface->ClearRootHubPortFeature (\r
- UsbHCInterface,\r
- Index,\r
- EfiUsbPortEnableChange\r
- );\r
+ Routine Description:\r
+ \r
+ This is Usb Hub enumerator\r
\r
- UsbHCInterface->GetRootHubPortStatus (\r
- UsbHCInterface,\r
- Index,\r
- (EFI_USB_PORT_STATUS *) &HubPortStatus\r
- );\r
+ Arguments:\r
+ \r
+ Event - Indicating which event is signaled\r
+ Context - actually it is a USB_IO_DEVICE\r
\r
- }\r
- }\r
+ Returns:\r
\r
- return ;\r
- } else {\r
+ VOID\r
+\r
+--*/\r
+{\r
+ USB_IO_CONTROLLER_DEVICE *HubController;\r
+ EFI_USB_PORT_STATUS HubPortStatus;\r
+ EFI_STATUS Status;\r
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev;\r
+ EFI_HANDLE HostController;\r
+ USB_IO_DEVICE *OldUsbIoDevice;\r
+ USB_IO_DEVICE *NewDevice;\r
+ USB_IO_CONTROLLER_DEVICE *NewController;\r
+ UINT8 Index2;\r
+ EFI_USB_IO_PROTOCOL *UsbIo;\r
+ UINT8 StatusChangePort;\r
+ UINT8 Number;\r
+\r
+ HubController = (USB_IO_CONTROLLER_DEVICE *) Context;\r
+ HostController = HubController->HostController;\r
+ UsbBusDev = HubController->UsbDevice->BusController;\r
+\r
+ //\r
+ // Event from Hub, Get the hub controller handle\r
+ //\r
+ //\r
+ // Get the status change endpoint\r
+ //\r
+ StatusChangePort = HubController->StatusChangePort;\r
+\r
+ //\r
+ // Clear HubController Status Change Bit\r
+ //\r
+ HubController->StatusChangePort = 0;\r
+\r
+ if (StatusChangePort == 0) {\r
//\r
- // Event from Hub, Get the hub controller handle\r
+ // Hub changes, we don't handle here\r
//\r
+ return ;\r
+ }\r
+ //\r
+ // Check which event took place at that port\r
+ //\r
+ UsbIo = &HubController->UsbIo;\r
+ Status = HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return ;\r
+ }\r
+ //\r
+ // Clear some change status\r
+ //\r
+ if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {\r
//\r
- // Get the status change endpoint\r
+ // Clear Hub port enable change\r
//\r
- StatusChangePort = HubController->StatusChangePort;\r
+ DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));\r
+ HubClearPortFeature (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ EfiUsbPortEnableChange\r
+ );\r
+\r
+ HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
+ );\r
+ }\r
\r
+ if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {\r
//\r
- // Clear HubController Status Change Bit\r
+ // Clear Hub reset change\r
//\r
- HubController->StatusChangePort = 0;\r
+ DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));\r
+ HubClearPortFeature (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ EfiUsbPortResetChange\r
+ );\r
\r
- if (StatusChangePort == 0) {\r
- //\r
- // Hub changes, we don't handle here\r
- //\r
- return ;\r
- }\r
+ HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
+ );\r
+ }\r
+\r
+ if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {\r
//\r
- // Check which event took place at that port\r
+ // Clear Hub overcurrent change\r
//\r
- UsbIo = &HubController->UsbIo;\r
- Status = HubGetPortStatus (\r
- UsbIo,\r
- StatusChangePort,\r
- (UINT32 *) &HubPortStatus\r
- );\r
+ DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));\r
+ HubClearPortFeature (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ EfiUsbPortOverCurrentChange\r
+ );\r
\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
+ HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
+ );\r
+ }\r
+\r
+ if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
//\r
- // Clear some change status\r
+ // First clear port connection change\r
//\r
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_ENABLE) {\r
- //\r
- // Clear Hub port enable change\r
- //\r
- DEBUG ((gUSBDebugLevel, "Port Enable Change\n"));\r
- HubClearPortFeature (\r
- UsbIo,\r
- StatusChangePort,\r
- EfiUsbPortEnableChange\r
- );\r
+ DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));\r
+ HubClearPortFeature (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ EfiUsbPortConnectChange\r
+ );\r
\r
- HubGetPortStatus (\r
- UsbIo,\r
- StatusChangePort,\r
- (UINT32 *) &HubPortStatus\r
+ HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
+ );\r
+\r
+ if (IsPortConnect (HubPortStatus.PortStatus)) {\r
+\r
+ DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));\r
+\r
+ ReportUsbStatusCode (\r
+ UsbBusDev,\r
+ EFI_PROGRESS_CODE,\r
+ EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
);\r
- }\r
\r
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) {\r
//\r
- // Clear Hub reset change\r
+ // if there is something physically detached, but still logically\r
+ // attached...\r
//\r
- DEBUG ((gUSBDebugLevel, "Port Reset Change\n"));\r
- HubClearPortFeature (\r
- UsbIo,\r
- StatusChangePort,\r
- EfiUsbPortResetChange\r
- );\r
+ OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
\r
- HubGetPortStatus (\r
- UsbIo,\r
- StatusChangePort,\r
- (UINT32 *) &HubPortStatus\r
- );\r
- }\r
+ if (NULL != OldUsbIoDevice) {\r
+ UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+ HubController->Children[StatusChangePort - 1] = NULL;\r
+ }\r
\r
- if (HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_OVERCURRENT) {\r
+ NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
+ if (NewDevice == NULL) {\r
+ return ;\r
+ }\r
//\r
- // Clear Hub overcurrent change\r
+ // Initialize some fields\r
//\r
- DEBUG ((gUSBDebugLevel, "Port Overcurrent Change\n"));\r
- HubClearPortFeature (\r
- UsbIo,\r
- StatusChangePort,\r
- EfiUsbPortOverCurrentChange\r
- );\r
+ NewDevice->DeviceDescriptor.MaxPacketSize0 = 8;\r
+ NewDevice->BusController = HubController->UsbDevice->BusController;\r
\r
- HubGetPortStatus (\r
- UsbIo,\r
- StatusChangePort,\r
- (UINT32 *) &HubPortStatus\r
- );\r
- }\r
-\r
- if (IsPortConnectChange (HubPortStatus.PortChangeStatus)) {\r
//\r
- // First clear port connection change\r
+ // There is something connected to this port,\r
+ // reset that port\r
+ //\r
+ // Disable the enable bit in port status\r
//\r
- DEBUG ((gUSBDebugLevel, "Port Connection Change\n"));\r
HubClearPortFeature (\r
UsbIo,\r
StatusChangePort,\r
- EfiUsbPortConnectChange\r
- );\r
-\r
- HubGetPortStatus (\r
- UsbIo,\r
- StatusChangePort,\r
- (UINT32 *) &HubPortStatus\r
+ EfiUsbPortEnable\r
);\r
\r
- if (IsPortConnect (HubPortStatus.PortStatus)) {\r
+ gBS->Stall (50 * 1000);\r
\r
- DEBUG ((gUSBDebugLevel, "New Device Connect on Hub port \n"));\r
-\r
- ReportUsbStatusCode (\r
- UsbBusDev,\r
- EFI_PROGRESS_CODE,\r
- EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG\r
+ //\r
+ // Wait for bit change\r
+ //\r
+ Number = 10;\r
+ do {\r
+ HubGetPortStatus (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ (UINT32 *) &HubPortStatus\r
);\r
+ gBS->Stall (10 * 1000);\r
+ Number -= 1;\r
+ } while ((HubPortStatus.PortStatus & USB_PORT_STAT_ENABLE) == 1 && Number > 0);\r
\r
+ if (Number == 0) {\r
//\r
- // if there is something physically detached, but still logically\r
- // attached...\r
+ // Cannot disable port, return error\r
//\r
- OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
-\r
- if (NULL != OldUsbIoDevice) {\r
- UsbDeviceDeConfiguration (OldUsbIoDevice);\r
- HubController->Children[StatusChangePort - 1] = NULL;\r
- }\r
+ DEBUG ((gUSBErrorLevel, "Disable Port Failed\n"));\r
+ gBS->FreePool (NewDevice);\r
+ return ;\r
+ }\r
\r
- NewDevice = AllocateZeroPool (sizeof (USB_IO_DEVICE));\r
- if (NewDevice == NULL) {\r
- return ;\r
- }\r
+ HubSetPortFeature (\r
+ UsbIo,\r
+ StatusChangePort,\r
+ EfiUsbPortReset\r
+ );\r
\r
- ResetHubPort (HubController, StatusChangePort);\r
+ gBS->Stall (50 * 1000);\r
\r
+ //\r
+ // Wait for port reset complete\r
+ //\r
+ Number = 10;\r
+ do {\r
HubGetPortStatus (\r
UsbIo,\r
StatusChangePort,\r
(UINT32 *) &HubPortStatus\r
);\r
+ gBS->Stall (10 * 1000);\r
+ Number -= 1;\r
+ } while ((HubPortStatus.PortStatus & USB_PORT_STAT_RESET) == 1 && Number > 0);\r
\r
+ if (Number == 0) {\r
//\r
- // Initialize some fields\r
+ // Cannot reset port, return error\r
//\r
- NewDevice->IsSlowDevice = IsPortLowSpeedDeviceAttached (HubPortStatus.PortStatus);\r
+ DEBUG ((gUSBErrorLevel, "Reset Port Failed\n"));\r
+ gBS->FreePool (NewDevice);\r
+ return ;\r
+ }\r
+ //\r
+ // Check high speed or full speed device\r
+ //\r
+ if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {\r
+ DEBUG ((gUSBDebugLevel, "Low Speed Device Attached to Hub\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW;\r
+ } else if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {\r
+ DEBUG ((gUSBDebugLevel, "High Speed Device Attached to Hub\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH;\r
+ } else {\r
+ DEBUG ((gUSBDebugLevel, "Full Speed Device Attached to Hub\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL;\r
+ }\r
+ //\r
+ // Configure that device\r
+ //\r
+ Status = UsbDeviceConfiguration (\r
+ HubController,\r
+ HostController,\r
+ (UINT8) (StatusChangePort - 1),\r
+ NewDevice\r
+ );\r
\r
- NewDevice->BusController = HubController->UsbDevice->BusController;\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (NewDevice);\r
+ return ;\r
+ }\r
+ //\r
+ // Add this device to the usb bus tree\r
+ // StatusChangePort is begin from 1,\r
+ //\r
+ HubController->Children[StatusChangePort - 1] = NewDevice;\r
\r
+ for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
//\r
- // Configure that device\r
+ // If this device is hub, add to the hub index\r
//\r
- Status = UsbDeviceConfiguration (\r
- HubController,\r
- HostController,\r
- (UINT8) (StatusChangePort - 1),\r
- NewDevice\r
- );\r
+ NewController = NewDevice->UsbController[Index2];\r
\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePool (NewDevice);\r
- return ;\r
- }\r
//\r
- // Add this device to the usb bus tree\r
- // StatusChangePort is begin from 1,\r
+ // Connect the controller to the driver image\r
+ //\r
+ Status = gBS->ConnectController (\r
+ NewController->Handle,\r
+ NULL,\r
+ NULL,\r
+ TRUE\r
+ );\r
+ //\r
+ // If connect success, we need to disconnect when\r
+ // stop the controller, otherwise we need not call\r
+ // gBS->DisconnectController ()\r
+ // This is used by those usb devices we don't plan\r
+ // to support. We can allocate\r
+ // controller handles for them, but we don't have\r
+ // device drivers to manage them.\r
//\r
- HubController->Children[StatusChangePort - 1] = NewDevice;\r
+ NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
\r
- for (Index2 = 0; Index2 < NewDevice->NumOfControllers; Index2++) {\r
- //\r
- // If this device is hub, add to the hub index\r
- //\r
- NewController = NewDevice->UsbController[Index2];\r
+ //\r
+ // If this device is hub, add to the hub index\r
+ //\r
+ if (IsHub (NewController)) {\r
+\r
+ NewController->IsUsbHub = TRUE;\r
\r
//\r
- // Connect the controller to the driver image\r
+ // Configure Hub\r
//\r
- Status = gBS->ConnectController (\r
- NewController->Handle,\r
- NULL,\r
- NULL,\r
- TRUE\r
- );\r
+ Status = DoHubConfig (NewController);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
//\r
- // If connect success, we need to disconnect when\r
- // stop the controller, otherwise we need not call\r
- // gBS->DisconnectController ()\r
- // This is used by those usb devices we don't plan\r
- // to support. We can allocate\r
- // controller handles for them, but we don't have\r
- // device drivers to manage them.\r
+ // Create an event to do hub enumeration\r
//\r
- NewController->IsManagedByDriver = (BOOLEAN) (!EFI_ERROR (Status));\r
+ gBS->CreateEvent (\r
+ EFI_EVENT_NOTIFY_SIGNAL,\r
+ EFI_TPL_CALLBACK,\r
+ HubEnumeration,\r
+ NewController,\r
+ &NewController->HubNotify\r
+ );\r
\r
//\r
- // If this device is hub, add to the hub index\r
+ // Add request to do query hub status\r
+ // change endpoint\r
//\r
- if (IsHub (NewController)) {\r
-\r
- NewController->IsUsbHub = TRUE;\r
-\r
- //\r
- // Configure Hub\r
- //\r
- Status = DoHubConfig (NewController);\r
-\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
- //\r
- // Create an event to do hub enumeration\r
- //\r
- gBS->CreateEvent (\r
- EFI_EVENT_NOTIFY_SIGNAL,\r
- EFI_TPL_CALLBACK,\r
- UsbEnumeration,\r
- NewController,\r
- &NewController->HubNotify\r
+ UsbIo = &NewController->UsbIo;\r
+ UsbIo->UsbAsyncInterruptTransfer (\r
+ UsbIo,\r
+ NewController->HubEndpointAddress, // Hub endpoint address\r
+ TRUE,\r
+ 100,\r
+ 1, // Hub ports < 7\r
+ OnHubInterruptComplete,\r
+ NewController\r
);\r
-\r
- //\r
- // Add request to do query hub status\r
- // change endpoint\r
- //\r
- UsbIo = &NewController->UsbIo;\r
- UsbIo->UsbAsyncInterruptTransfer (\r
- UsbIo,\r
- NewController->HubEndpointAddress, // Hub endpoint address\r
- TRUE,\r
- 100,\r
- 1, // Hub ports < 7\r
- OnHubInterruptComplete,\r
- NewController\r
- );\r
- }\r
}\r
- } else {\r
- //\r
- // Something disconnected from USB hub\r
- //\r
- DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));\r
-\r
- OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
+ }\r
+ } else {\r
+ //\r
+ // Something disconnected from USB hub\r
+ //\r
+ DEBUG ((gUSBDebugLevel, "Something Device Detached on Hub port\n"));\r
\r
- UsbDeviceDeConfiguration (OldUsbIoDevice);\r
+ OldUsbIoDevice = HubController->Children[StatusChangePort - 1];\r
\r
- HubController->Children[StatusChangePort - 1] = NULL;\r
+ UsbDeviceDeConfiguration (OldUsbIoDevice);\r
\r
- }\r
+ HubController->Children[StatusChangePort - 1] = NULL;\r
\r
- return ;\r
}\r
\r
return ;\r
}\r
-}\r
-//\r
-// Clear port connection change status over a given root hub port\r
-//\r
-EFI_STATUS\r
-ClearRootPortConnectionChangeStatus (\r
- UINT8 PortNum,\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface\r
- )\r
-/*++\r
-\r
- Routine Description:\r
- Clear port connection change status over a given root hub port\r
-\r
- Arguments:\r
- PortNum - The given port.\r
- UsbHCInterface - The EFI_USB_HC_PROTOCOL instance.\r
-\r
- Returns:\r
- EFI_SUCCESS\r
\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- Status = UsbHCInterface->ClearRootHubPortFeature (\r
- UsbHCInterface,\r
- PortNum,\r
- EfiUsbPortConnectChange\r
- );\r
- return Status;\r
+ return ;\r
}\r
\r
STATIC\r
EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
EFI_USB_HC_PROTOCOL *UsbHcProtocol;\r
+ EFI_USB2_HC_PROTOCOL *Usb2HcProtocol;\r
\r
//\r
// Build the child device path for each new USB_IO device\r
return Status;\r
}\r
\r
- Status = gBS->OpenProtocol (\r
- UsbIoController->HostController,\r
- &gEfiUsbHcProtocolGuid,\r
- (VOID **) &UsbHcProtocol,\r
- gUsbBusDriverBinding.DriverBindingHandle,\r
- UsbIoController->Handle,\r
- EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
- );\r
+ if (UsbIoController->UsbDevice->BusController->Hc2ProtocolSupported) {\r
+ Status = gBS->OpenProtocol (\r
+ UsbIoController->HostController,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ (VOID **)&Usb2HcProtocol,\r
+ gUsbBusDriverBinding.DriverBindingHandle,\r
+ UsbIoController->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ } else {\r
+ Status = gBS->OpenProtocol (\r
+ UsbIoController->HostController,\r
+ &gEfiUsbHcProtocolGuid,\r
+ (VOID **)&UsbHcProtocol,\r
+ gUsbBusDriverBinding.DriverBindingHandle,\r
+ UsbIoController->Handle,\r
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+ );\r
+ }\r
\r
return Status;\r
}\r
\r
Arguments:\r
UsbIoController - Indicating the Usb Controller Device.\r
- Reconfigure - Do we need to reconfigure it.\r
+ ReConfigure - Do we need to reconfigure it.\r
RetryTimes - Retry Times when failed\r
+ \r
Returns:\r
EFI_SUCCESS\r
EFI_DEVICE_ERROR\r
\r
if (ParentIoDev->DeviceAddress == 1) {\r
DEBUG ((gUSBDebugLevel, "Reset from Root Hub 0x%x\n", HubPort));\r
- ResetRootPort (ParentIoDev->BusController->UsbHCInterface, HubPort, RetryTimes);\r
+ ResetRootPort (ParentIoDev->BusController, HubPort, RetryTimes);\r
} else {\r
DEBUG ((gUSBDebugLevel, "Reset from Hub, Addr 0x%x\n", ParentIoDev->DeviceAddress));\r
ResetHubPort (ParentController, HubPort + 1);\r
\r
EFI_STATUS\r
ResetRootPort (\r
- IN EFI_USB_HC_PROTOCOL *UsbHCInterface,\r
- IN UINT8 PortNum,\r
- IN UINT8 RetryTimes\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNum,\r
+ IN UINT8 RetryTimes\r
)\r
/*++\r
\r
Reset Root Hub port.\r
\r
Arguments:\r
- UsbHCInterface - The EFI_USB_HC_PROTOCOL instance.\r
- PortNum - The given port to be reset.\r
- RetryTimes - RetryTimes when failed\r
+ UsbBusDev - Bus controller of the device.\r
+ PortNum - The given port to be reset.\r
+ RetryTimes - RetryTimes when failed\r
+ \r
Returns:\r
- N/A\r
+ EFI_SUCCESS\r
+ EFI_DEVICE_ERROR\r
\r
--*/\r
{\r
- EFI_STATUS Status;\r
+ EFI_STATUS Status;\r
+ EFI_USB_PORT_STATUS PortStatus;\r
\r
//\r
// reset root port\r
//\r
- Status = UsbHCInterface->SetRootHubPortFeature (\r
- UsbHCInterface,\r
- PortNum,\r
- EfiUsbPortReset\r
- );\r
-\r
+ Status = UsbVirtualHcSetRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortReset\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
//\r
// clear reset root port\r
//\r
- Status = UsbHCInterface->ClearRootHubPortFeature (\r
- UsbHCInterface,\r
- PortNum,\r
- EfiUsbPortReset\r
- );\r
-\r
+ Status = UsbVirtualHcClearRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortReset\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
gBS->Stall (1000);\r
\r
- Status = ClearRootPortConnectionChangeStatus (PortNum, UsbHCInterface);\r
-\r
+ Status = UsbVirtualHcClearRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortConnectChange\r
+ );\r
if (EFI_ERROR (Status)) {\r
return EFI_DEVICE_ERROR;\r
}\r
- //\r
- // Set port enable\r
- //\r
- Status = UsbHCInterface->SetRootHubPortFeature (\r
- UsbHCInterface,\r
- PortNum,\r
- EfiUsbPortEnable\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return EFI_DEVICE_ERROR;\r
+\r
+ UsbVirtualHcGetRootHubPortStatus (\r
+ UsbBusDev,\r
+ PortNum,\r
+ &PortStatus\r
+ );\r
+ if (PortStatus.PortStatus & USB_PORT_STAT_OWNER) {\r
+ //\r
+ // Set port enable\r
+ //\r
+ Status = UsbVirtualHcSetRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortEnable\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ Status = UsbVirtualHcClearRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortEnableChange\r
+ );\r
}\r
\r
- Status = UsbHCInterface->ClearRootHubPortFeature (\r
- UsbHCInterface,\r
- PortNum,\r
- EfiUsbPortEnableChange\r
- );\r
gBS->Stall ((1 + RetryTimes) * 50 * 1000);\r
\r
return EFI_SUCCESS;\r
}\r
\r
-\r
EFI_STATUS\r
ResetHubPort (\r
IN USB_IO_CONTROLLER_DEVICE *UsbIoController,\r
return EFI_SUCCESS;\r
}\r
\r
-\r
-\r
-\r
-\r
STATIC\r
EFI_STATUS\r
ReportUsbStatusCode (\r
);\r
}\r
\r
-\r
EFI_STATUS\r
IsDeviceDisconnected (\r
IN USB_IO_CONTROLLER_DEVICE *UsbIoController,\r
EFI_STATUS Status;\r
EFI_USB_IO_PROTOCOL *UsbIo;\r
EFI_USB_PORT_STATUS PortStatus;\r
- EFI_USB_HC_PROTOCOL *UsbHCInterface;\r
\r
ParentController = UsbIoController->Parent;\r
ParentIoDev = ParentController->UsbDevice;\r
//\r
// Connected to the root hub\r
//\r
- UsbHCInterface = ParentIoDev->BusController->UsbHCInterface;\r
- Status = UsbHCInterface->GetRootHubPortStatus (\r
- UsbHCInterface,\r
- HubPort,\r
- &PortStatus\r
- );\r
+ UsbVirtualHcGetRootHubPortStatus (\r
+ ParentIoDev->BusController,\r
+ HubPort,\r
+ &PortStatus\r
+ );\r
\r
} else {\r
UsbIo = &UsbIoController->UsbIo;\r
\r
return EFI_SUCCESS;\r
}\r
+\r
+STATIC\r
+EFI_STATUS\r
+UsbSetTransactionTranslator (\r
+ IN USB_IO_CONTROLLER_DEVICE *ParentHubController,\r
+ IN UINT8 ParentPort,\r
+ IN OUT USB_IO_DEVICE *Device\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Set Transaction Translator parameter\r
+ \r
+ Arguments:\r
+ \r
+ ParentHubController - Controller structure of the parent Hub device\r
+ ParentPort - Number of parent port\r
+ Device - Structure of the device\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ EFI_OUT_OF_RESOURCES Cannot allocate resources\r
+ \r
+--*/\r
+{\r
+ USB_IO_CONTROLLER_DEVICE *AncestorHubController;\r
+\r
+ AncestorHubController = ParentHubController;\r
+ Device->Translator = NULL;\r
+\r
+ if (EFI_USB_SPEED_HIGH == Device->DeviceSpeed) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ do {\r
+ if (EFI_USB_SPEED_HIGH == AncestorHubController->UsbDevice->DeviceSpeed) {\r
+ break;\r
+ }\r
+\r
+ if (NULL == AncestorHubController->Parent) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ AncestorHubController = AncestorHubController->Parent;\r
+ } while (1);\r
+\r
+ Device->Translator = AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR));\r
+ if (NULL == Device->Translator) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Device->Translator->TranslatorHubAddress = AncestorHubController->UsbDevice->DeviceAddress;\r
+ Device->Translator->TranslatorPortNumber = ParentPort;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+UsbUnsetTransactionTranslator (\r
+ USB_IO_DEVICE *Device\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Unset Transaction Translator parameter\r
+ \r
+ Arguments:\r
+ \r
+ Device - Structure of the device\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ \r
+--*/\r
+{\r
+ if (Device->Translator) {\r
+ gBS->FreePool (Device->Translator);\r
+ Device->Translator = NULL;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+IdentifyDeviceSpeed (\r
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ USB_IO_DEVICE *NewDevice,\r
+ UINT8 Index\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Identify speed of USB device\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - UsbBus controller structure of the device\r
+ NewDevice - Devcie controller structure\r
+ Index - Number of the port\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ EFI_NOT_FOUND Device release to CHC or can't be found\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_USB_PORT_STATUS HubPortStatus;\r
+\r
+ UsbVirtualHcGetRootHubPortStatus (\r
+ UsbBusDev,\r
+ Index,\r
+ (EFI_USB_PORT_STATUS *) &HubPortStatus\r
+ );\r
+ \r
+ //\r
+ // Check device device\r
+ //\r
+ if (!(HubPortStatus.PortStatus & USB_PORT_STAT_OWNER)) {\r
+ //\r
+ // EHC Port Owner\r
+ //\r
+ if (HubPortStatus.PortStatus & USB_PORT_STAT_HIGH_SPEED) {\r
+ DEBUG ((gUSBDebugLevel, "High Speed Device attached to EHC\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_HIGH; \r
+ } else {\r
+ Status = ReleasePortToCHC (UsbBusDev, Index);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((gUSBErrorLevel, "Fail to release port to CHC\n"));\r
+ } else {\r
+ DEBUG ((gUSBDebugLevel, "Success to release port to CHC\n"));\r
+ }\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ } else {\r
+ //\r
+ // CHC Port Owner\r
+ //\r
+ if (HubPortStatus.PortStatus & USB_PORT_STAT_LOW_SPEED) {\r
+ DEBUG ((gUSBDebugLevel, "Low Speed Device attached to CHC\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_LOW; \r
+ } else {\r
+ DEBUG ((gUSBDebugLevel, "FULL Speed Device attached to CHC\n"));\r
+ NewDevice->DeviceSpeed = EFI_USB_SPEED_FULL; \r
+ }\r
+ }\r
+ \r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+ReleasePortToCHC (\r
+ USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ UINT8 PortNum\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Set bit to release the port owner to CHC\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - UsbBus controller structure of the device\r
+ PortNum - Number of the port\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS Success\r
+ EFI_DEVICE_ERROR Fail\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = UsbVirtualHcSetRootHubPortFeature (\r
+ UsbBusDev,\r
+ PortNum,\r
+ EfiUsbPortOwner\r
+ );\r
+\r
+ gBS->Stall (100 * 1000);\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetCapability (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ OUT UINT8 *MaxSpeed,\r
+ OUT UINT8 *PortNumber,\r
+ OUT UINT8 *Is64BitCapable\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to Retrieves the capablility of root hub ports \r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ MaxSpeed - A pointer to the number of the host controller.\r
+ PortNumber - A pointer to the number of the root hub ports.\r
+ Is64BitCapable - A pointer to the flag for whether controller supports \r
+ 64-bit memory addressing.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The host controller capability were retrieved successfully.\r
+ EFI_INVALID_PARAMETER \r
+ MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to retrieve the capabilities. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->GetCapability (\r
+ UsbBusDev->Usb2HCInterface,\r
+ MaxSpeed,\r
+ PortNumber,\r
+ Is64BitCapable\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->GetRootHubPortNumber (\r
+ UsbBusDev->UsbHCInterface,\r
+ PortNumber\r
+ );\r
+ *MaxSpeed = EFI_USB_SPEED_FULL;\r
+ *Is64BitCapable = (UINT8) FALSE;\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcReset (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT16 Attributes\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to provides software reset for the USB host controller\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ Attributes - A bit mask of the reset operation to perform. \r
+ See below for a list of the supported bit mask values.\r
+ \r
+ #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc\r
+ #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc\r
+ #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2\r
+ #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2\r
+\r
+ EFI_USB_HC_RESET_GLOBAL \r
+ If this bit is set, a global reset signal will be sent to the USB bus.\r
+ This resets all of the USB bus logic, including the USB host \r
+ controller hardware and all the devices attached on the USB bus.\r
+ EFI_USB_HC_RESET_HOST_CONTROLLER \r
+ If this bit is set, the USB host controller hardware will be reset. \r
+ No reset signal will be sent to the USB bus.\r
+ EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG\r
+ If this bit is set, a global reset signal will be sent to the USB bus.\r
+ This resets all of the USB bus logic, including the USB host \r
+ controller hardware and all the devices attached on the USB bus. \r
+ If this is an EHCI controller and the debug port has configured, then \r
+ this is will still reset the host controller.\r
+ EFI_USB_HC_RESET_HOST_WITH_DEBUG\r
+ If this bit is set, the USB host controller hardware will be reset. \r
+ If this is an EHCI controller and the debug port has been configured,\r
+ then this will still reset the host controller.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The reset operation succeeded.\r
+ EFI_INVALID_PARAMETER \r
+ Attributes is not valid.\r
+ EFI_UNSUPPOURTED\r
+ The type of reset specified by Attributes is not currently supported by\r
+ the host controller hardware.\r
+ EFI_ACCESS_DENIED\r
+ Reset operation is rejected due to the debug port being configured and \r
+ active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or \r
+ EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to\r
+ perform reset operation for this host controller.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to perform \r
+ the reset operation.\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->Reset (\r
+ UsbBusDev->Usb2HCInterface,\r
+ EFI_USB_HC_RESET_GLOBAL\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->Reset (\r
+ UsbBusDev->UsbHCInterface,\r
+ EFI_USB_HC_RESET_GLOBAL\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetState (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ OUT EFI_USB_HC_STATE *State\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to retrieves current state of the USB host controller\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ State - A pointer to the EFI_USB_HC_STATE data structure that \r
+ indicates current state of the USB host controller. \r
+ Type EFI_USB_HC_STATE is defined below.\r
+ \r
+ typedef enum {\r
+ EfiUsbHcStateHalt,\r
+ EfiUsbHcStateOperational,\r
+ EfiUsbHcStateSuspend,\r
+ EfiUsbHcStateMaximum\r
+ } EFI_USB_HC_STATE;\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The state information of the host controller was returned in State.\r
+ EFI_INVALID_PARAMETER \r
+ State is NULL.\r
+ EFI_DEVICE_ERROR \r
+ An error was encountered while attempting to retrieve the \r
+ host controller's current state. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->GetState (\r
+ UsbBusDev->Usb2HCInterface,\r
+ State\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->GetState (\r
+ UsbBusDev->UsbHCInterface,\r
+ State\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSetState (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN EFI_USB_HC_STATE State\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to sets the USB host controller to a specific state\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ State - Indicates the state of the host controller that will be set.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The USB host controller was successfully placed in the state \r
+ specified by State.\r
+ EFI_INVALID_PARAMETER \r
+ State is invalid.\r
+ EFI_DEVICE_ERROR \r
+ Failed to set the state specified by State due to device error. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->SetState (\r
+ UsbBusDev->Usb2HCInterface,\r
+ State\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->SetState (\r
+ UsbBusDev->UsbHCInterface,\r
+ State\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcGetRootHubPortStatus (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNumber,\r
+ OUT EFI_USB_PORT_STATUS *PortStatus\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to retrieves the current status of a USB root hub port\r
+ both for Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ PortNumber - Specifies the root hub port from which the status \r
+ is to be retrieved. This value is zero-based. For example, \r
+ if a root hub has two ports, then the first port is numbered 0,\r
+ and the second port is numbered 1.\r
+ PortStatus - A pointer to the current port status bits and \r
+ port status change bits. \r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS The status of the USB root hub port specified by PortNumber \r
+ was returned in PortStatus.\r
+ EFI_INVALID_PARAMETER PortNumber is invalid. \r
+ EFI_DEVICE_ERROR Can't read register \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->GetRootHubPortStatus (\r
+ UsbBusDev->Usb2HCInterface,\r
+ PortNumber,\r
+ PortStatus\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->GetRootHubPortStatus (\r
+ UsbBusDev->UsbHCInterface,\r
+ PortNumber,\r
+ PortStatus\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSetRootHubPortFeature (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ Virual interface to sets a feature for the specified root hub port\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ PortNumber - Specifies the root hub port whose feature \r
+ is requested to be set.\r
+ PortFeature - Indicates the feature selector associated \r
+ with the feature set request. \r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The feature specified by PortFeature was set for the \r
+ USB root hub port specified by PortNumber.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid or PortFeature is invalid.\r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->SetRootHubPortFeature (\r
+ UsbBusDev->Usb2HCInterface,\r
+ PortNumber,\r
+ PortFeature\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->SetRootHubPortFeature (\r
+ UsbBusDev->UsbHCInterface,\r
+ PortNumber,\r
+ PortFeature\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcClearRootHubPortFeature (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 PortNumber,\r
+ IN EFI_USB_PORT_FEATURE PortFeature\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to clears a feature for the specified root hub port\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ PortNumber - Specifies the root hub port whose feature \r
+ is requested to be cleared.\r
+ PortFeature - Indicates the feature selector associated with the \r
+ feature clear request.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The feature specified by PortFeature was cleared for the \r
+ USB root hub port specified by PortNumber.\r
+ EFI_INVALID_PARAMETER \r
+ PortNumber is invalid or PortFeature is invalid.\r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->ClearRootHubPortFeature (\r
+ UsbBusDev->Usb2HCInterface,\r
+ PortNumber,\r
+ PortFeature\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->ClearRootHubPortFeature (\r
+ UsbBusDev->UsbHCInterface,\r
+ PortNumber,\r
+ PortFeature\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcControlTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN EFI_USB_DEVICE_REQUEST *Request,\r
+ IN EFI_USB_DATA_DIRECTION TransferDirection,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits control transfer to a target USB device\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ DeviceSpeed - Indicates target device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ Request - A pointer to the USB device request that will be sent \r
+ to the USB device. \r
+ TransferDirection - Specifies the data direction for the transfer.\r
+ There are three values available, DataIn, DataOut \r
+ and NoData.\r
+ Data - A pointer to the buffer of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ TimeOut - Indicates the maximum time, in microseconds, \r
+ which the transfer is allowed to complete.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information generated \r
+ by this control transfer.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The control transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The control transfer could not be completed due to a lack of resources.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The control transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The control transfer failed due to host controller or device error. \r
+ Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BOOLEAN IsSlowDevice;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->ControlTransfer (\r
+ UsbBusDev->Usb2HCInterface,\r
+ DeviceAddress,\r
+ DeviceSpeed,\r
+ MaximumPacketLength,\r
+ Request,\r
+ TransferDirection,\r
+ Data,\r
+ DataLength,\r
+ TimeOut,\r
+ Translator,\r
+ TransferResult\r
+ );\r
+ } else {\r
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+ Status = UsbBusDev->UsbHCInterface->ControlTransfer (\r
+ UsbBusDev->UsbHCInterface,\r
+ DeviceAddress,\r
+ IsSlowDevice,\r
+ (UINT8) MaximumPacketLength,\r
+ Request,\r
+ TransferDirection,\r
+ Data,\r
+ DataLength,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcBulkTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits bulk transfer to a bulk endpoint of a USB device\r
+ both for Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration. \r
+ EndPointAddress - The combination of an endpoint number and an \r
+ endpoint direction of the target USB device. \r
+ Each endpoint address supports data transfer in \r
+ one direction except the control endpoint \r
+ (whose default endpoint address is 0). \r
+ It is the caller's responsibility to make sure that \r
+ the EndPointAddress represents a bulk endpoint. \r
+ DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL\r
+ and EFI_USB_SPEED_HIGH.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint\r
+ is capable of sending or receiving. \r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be transmitted \r
+ to USB device or received from USB device. \r
+ DataLength - When input, indicates the size, in bytes, of the data buffer\r
+ specified by Data. When output, indicates the actually \r
+ transferred data size. \r
+ DataToggle - A pointer to the data toggle value. On input, it indicates \r
+ the initial data toggle value the bulk transfer should adopt;\r
+ on output, it is updated to indicate the data toggle value \r
+ of the subsequent bulk transfer. \r
+ Translator - A pointr to the transaction translator data. \r
+ TimeOut - Indicates the maximum time, in microseconds, which the \r
+ transfer is allowed to complete. \r
+ TransferResult - A pointer to the detailed result information of the \r
+ bulk transfer.\r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The bulk transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The bulk transfer could not be submitted due to lack of resource.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The bulk transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The bulk transfer failed due to host controller or device error.\r
+ Caller should check TranferResult for detailed error information.\r
+\r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->BulkTransfer (\r
+ UsbBusDev->Usb2HCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DeviceSpeed,\r
+ MaximumPacketLength,\r
+ DataBuffersNumber,\r
+ Data,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ Translator,\r
+ TransferResult\r
+ );\r
+ } else {\r
+ Status = UsbBusDev->UsbHCInterface->BulkTransfer (\r
+ UsbBusDev->UsbHCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ (UINT8) MaximumPacketLength,\r
+ *Data,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcAsyncInterruptTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE * UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN BOOLEAN IsNewTransfer,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN PollingInterval,\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,\r
+ IN VOID *Context OPTIONAL\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits an asynchronous interrupt transfer to an \r
+ interrupt endpoint of a USB device for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration. \r
+ EndPointAddress - The combination of an endpoint number and an endpoint \r
+ direction of the target USB device. Each endpoint address \r
+ supports data transfer in one direction except the \r
+ control endpoint (whose default endpoint address is 0). \r
+ It is the caller's responsibility to make sure that \r
+ the EndPointAddress represents an interrupt endpoint. \r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint\r
+ is capable of sending or receiving. \r
+ IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between\r
+ the host and the target interrupt endpoint. \r
+ If FALSE, the specified asynchronous interrupt pipe \r
+ is canceled. \r
+ DataToggle - A pointer to the data toggle value. On input, it is valid \r
+ when IsNewTransfer is TRUE, and it indicates the initial \r
+ data toggle value the asynchronous interrupt transfer \r
+ should adopt. \r
+ On output, it is valid when IsNewTransfer is FALSE, \r
+ and it is updated to indicate the data toggle value of \r
+ the subsequent asynchronous interrupt transfer. \r
+ PollingInterval - Indicates the interval, in milliseconds, that the \r
+ asynchronous interrupt transfer is polled. \r
+ This parameter is required when IsNewTransfer is TRUE. \r
+ DataLength - Indicates the length of data to be received at the \r
+ rate specified by PollingInterval from the target \r
+ asynchronous interrupt endpoint. This parameter \r
+ is only required when IsNewTransfer is TRUE. \r
+ Translator - A pointr to the transaction translator data.\r
+ CallBackFunction - The Callback function.This function is called at the \r
+ rate specified by PollingInterval.This parameter is \r
+ only required when IsNewTransfer is TRUE. \r
+ Context - The context that is passed to the CallBackFunction.\r
+ - This is an optional parameter and may be NULL.\r
+ \r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The asynchronous interrupt transfer request has been successfully \r
+ submitted or canceled.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_OUT_OF_RESOURCES \r
+ The request could not be completed due to a lack of resources. \r
+ EFI_DEVICE_ERROR\r
+ Can't read register\r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BOOLEAN IsSlowDevice;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->AsyncInterruptTransfer (\r
+ UsbBusDev->Usb2HCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DeviceSpeed,\r
+ MaximumPacketLength,\r
+ IsNewTransfer,\r
+ DataToggle,\r
+ PollingInterval,\r
+ DataLength,\r
+ Translator,\r
+ CallBackFunction,\r
+ Context\r
+ );\r
+ } else {\r
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+ Status = UsbBusDev->UsbHCInterface->AsyncInterruptTransfer (\r
+ UsbBusDev->UsbHCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ IsSlowDevice,\r
+ (UINT8) MaximumPacketLength,\r
+ IsNewTransfer,\r
+ DataToggle,\r
+ PollingInterval,\r
+ DataLength,\r
+ CallBackFunction,\r
+ Context\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcSyncInterruptTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN OUT VOID *Data,\r
+ IN OUT UINTN *DataLength,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN TimeOut,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint \r
+ of a USB device for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB, \r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - The combination of an endpoint number and an endpoint \r
+ direction of the target USB device. Each endpoint \r
+ address supports data transfer in one direction \r
+ except the control endpoint (whose default \r
+ endpoint address is 0). It is the caller's responsibility\r
+ to make sure that the EndPointAddress represents \r
+ an interrupt endpoint. \r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size the target endpoint \r
+ is capable of sending or receiving.\r
+ Data - A pointer to the buffer of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - On input, the size, in bytes, of the data buffer specified \r
+ by Data. On output, the number of bytes transferred.\r
+ DataToggle - A pointer to the data toggle value. On input, it indicates\r
+ the initial data toggle value the synchronous interrupt \r
+ transfer should adopt; \r
+ on output, it is updated to indicate the data toggle value \r
+ of the subsequent synchronous interrupt transfer. \r
+ TimeOut - Indicates the maximum time, in microseconds, which the \r
+ transfer is allowed to complete.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information from \r
+ the synchronous interrupt transfer. \r
+\r
+ Returns:\r
+ \r
+ EFI_SUCCESS \r
+ The synchronous interrupt transfer was completed successfully.\r
+ EFI_OUT_OF_RESOURCES \r
+ The synchronous interrupt transfer could not be submitted due \r
+ to lack of resource.\r
+ EFI_INVALID_PARAMETER \r
+ Some parameters are invalid.\r
+ EFI_TIMEOUT \r
+ The synchronous interrupt transfer failed due to timeout.\r
+ EFI_DEVICE_ERROR \r
+ The synchronous interrupt transfer failed due to host controller \r
+ or device error. Caller should check TranferResult for detailed \r
+ error information. \r
+ \r
+--*/\r
+{\r
+ EFI_STATUS Status;\r
+ BOOLEAN IsSlowDevice;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ if (UsbBusDev->Hc2ProtocolSupported) {\r
+ Status = UsbBusDev->Usb2HCInterface->SyncInterruptTransfer (\r
+ UsbBusDev->Usb2HCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ DeviceSpeed,\r
+ MaximumPacketLength,\r
+ Data,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ Translator,\r
+ TransferResult\r
+ );\r
+ } else {\r
+ IsSlowDevice = (EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE;\r
+ Status = UsbBusDev->UsbHCInterface->SyncInterruptTransfer (\r
+ UsbBusDev->UsbHCInterface,\r
+ DeviceAddress,\r
+ EndPointAddress,\r
+ IsSlowDevice,\r
+ (UINT8) MaximumPacketLength,\r
+ Data,\r
+ DataLength,\r
+ DataToggle,\r
+ TimeOut,\r
+ TransferResult\r
+ );\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcIsochronousTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ OUT UINT32 *TransferResult\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Virtual interface to submits isochronous transfer to a target USB device\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - End point address\r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be \r
+ transmitted to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ Translator - A pointr to the transaction translator data.\r
+ TransferResult - A pointer to the detailed result information generated \r
+ by this control transfer. \r
+ \r
+ Returns:\r
+ \r
+ EFI_UNSUPPORTED \r
+\r
+--*/\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+UsbVirtualHcAsyncIsochronousTransfer (\r
+ IN USB_BUS_CONTROLLER_DEVICE *UsbBusDev,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN UINT8 DataBuffersNumber,\r
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,\r
+ IN VOID *Context\r
+ )\r
+/*++\r
+ \r
+ Routine Description:\r
+ \r
+ Vitual interface to submits Async isochronous transfer to a target USB device\r
+ for both Hc2 and Hc protocol.\r
+ \r
+ Arguments:\r
+ \r
+ UsbBusDev - A pointer to bus controller of the device.\r
+ DeviceAddress - Represents the address of the target device on the USB,\r
+ which is assigned during USB enumeration.\r
+ EndPointAddress - End point address\r
+ DeviceSpeed - Indicates device speed.\r
+ MaximumPacketLength - Indicates the maximum packet size that the \r
+ default control transfer endpoint is capable of \r
+ sending or receiving.\r
+ DataBuffersNumber - Number of data buffers prepared for the transfer.\r
+ Data - Array of pointers to the buffers of data that will be transmitted \r
+ to USB device or received from USB device.\r
+ DataLength - Indicates the size, in bytes, of the data buffer \r
+ specified by Data.\r
+ Translator - A pointr to the transaction translator data.\r
+ IsochronousCallBack - When the transfer complete, the call back function will be called\r
+ Context - Pass to the call back function as parameter\r
+ \r
+ Returns:\r
+ \r
+ EFI_UNSUPPORTED \r
+\r
+--*/\r
+{\r
+ return EFI_UNSUPPORTED;\r
+}\r