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