summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Bus/Usb/UsbBusDxe
diff options
context:
space:
mode:
authorerictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>2011-08-23 14:36:33 +0000
committererictian <erictian@6f19259b-4bc3-4df7-8a09-765794883524>2011-08-23 14:36:33 +0000
commit92870c983c6d99d31f449d8dcd729090255dda49 (patch)
treee38460d4f6151ea738bd057c8938452c5cfb61ae /MdeModulePkg/Bus/Usb/UsbBusDxe
parentda910a42c0421a9895898537026276acf0935099 (diff)
downloadedk2-platforms-92870c983c6d99d31f449d8dcd729090255dda49.tar.xz
Enabling usb3.0 XHCI support.
Signed-off-by: erictian Reviewed-by: jshi19 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12185 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Bus/Usb/UsbBusDxe')
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c18
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h6
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c6
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c83
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c169
-rw-r--r--MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h33
6 files changed, 231 insertions, 84 deletions
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c
index 64aa9d9545..b592913bd3 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.c
@@ -45,6 +45,7 @@ EFI_DRIVER_BINDING_PROTOCOL mUsbBusDriverBinding = {
NULL
};
+UINT16 mMaxUsbDeviceNum = USB_MAX_DEVICES;
/**
USB_IO function to execute a control transfer. This
@@ -111,7 +112,7 @@ UsbIoControlTransfer (
// Clear TT buffer when CTRL/BULK split transaction failes
// Clear the TRANSLATOR TT buffer, not parent's buffer
//
- ASSERT (Dev->Translator.TranslatorHubAddress < USB_MAX_DEVICES);
+ ASSERT (Dev->Translator.TranslatorHubAddress < mMaxUsbDeviceNum);
if (Dev->Translator.TranslatorHubAddress != 0) {
UsbHubCtrlClearTTBuffer (
Dev->Bus->Devices[Dev->Translator.TranslatorHubAddress],
@@ -284,7 +285,7 @@ UsbIoBulkTransfer (
// Clear TT buffer when CTRL/BULK split transaction failes.
// Clear the TRANSLATOR TT buffer, not parent's buffer
//
- ASSERT (Dev->Translator.TranslatorHubAddress < USB_MAX_DEVICES);
+ ASSERT (Dev->Translator.TranslatorHubAddress < mMaxUsbDeviceNum);
if (Dev->Translator.TranslatorHubAddress != 0) {
UsbHubCtrlClearTTBuffer (
Dev->Bus->Devices[Dev->Translator.TranslatorHubAddress],
@@ -966,6 +967,16 @@ UsbBusBuildProtocol (
goto CLOSE_HC;
}
+ if (!EFI_ERROR (Status)) {
+ if (UsbBus->Usb2Hc->MajorRevision == 0x3) {
+ //
+ // The EFI_USB2_HC_PROTOCOL is produced for XHCI support.
+ // Then its max supported devices are 256.
+ //
+ mMaxUsbDeviceNum = 256;
+ }
+ }
+
UsbHcReset (UsbBus, EFI_USB_HC_RESET_GLOBAL);
UsbHcSetState (UsbBus, EfiUsbHcStateOperational);
@@ -1011,6 +1022,7 @@ UsbBusBuildProtocol (
RootHub->Bus = UsbBus;
RootHub->NumOfInterface = 1;
RootHub->Interfaces[0] = RootIf;
+ RootHub->Tier = 0;
RootIf->Signature = USB_INTERFACE_SIGNATURE;
RootIf->Device = RootHub;
RootIf->DevicePath = UsbBus->DevicePath;
@@ -1434,7 +1446,7 @@ UsbBusControllerDriverStop (
mUsbRootHubApi.Release (RootIf);
- for (Index = 1; Index < USB_MAX_DEVICES; Index++) {
+ for (Index = 1; Index < mMaxUsbDeviceNum; Index++) {
if (Bus->Devices[Index] != NULL) {
UsbRemoveDevice (Bus->Devices[Index]);
}
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
index c41c1272fc..ce041b9f79 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBus.h
@@ -167,7 +167,7 @@ struct _USB_DEVICE {
//
UINT8 Speed;
UINT8 Address;
- UINT8 MaxPacket0;
+ UINT32 MaxPacket0;
//
// The device's descriptors and its configuration
@@ -189,6 +189,7 @@ struct _USB_DEVICE {
UINT8 ParentAddr;
USB_INTERFACE *ParentIf;
UINT8 ParentPort; // Start at 0
+ UINT8 Tier;
};
//
@@ -249,7 +250,7 @@ struct _USB_BUS {
// An array of device that is on the bus. Devices[0] is
// for root hub. Device with address i is at Devices[i].
//
- USB_DEVICE *Devices[USB_MAX_DEVICES];
+ USB_DEVICE *Devices[256];
//
// USB Bus driver need to control the recursive connect policy of the bus, only those wanted
@@ -746,6 +747,7 @@ UsbBusControllerDriverStop (
IN EFI_HANDLE *ChildHandleBuffer
);
+extern UINT16 mMaxUsbDeviceNum;
extern EFI_USB_IO_PROTOCOL mUsbIoProtocol;
extern EFI_DRIVER_BINDING_PROTOCOL mUsbBusDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL mUsbBusComponentName;
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
index 55fe5c873c..529b136188 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
@@ -527,12 +527,14 @@ UsbGetMaxPacketSize0 (
// Get the first 8 bytes of the device descriptor which contains
// max packet size for endpoint 0, which is at least 8.
//
- UsbDev->MaxPacket0 = 8;
-
for (Index = 0; Index < 3; Index++) {
Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_DEVICE, 0, 0, &DevDesc, 8);
if (!EFI_ERROR (Status)) {
+ if ((DevDesc.BcdUSB == 0x0300) && (DevDesc.MaxPacketSize0 == 9)) {
+ UsbDev->MaxPacket0 = 1 << 9;
+ return EFI_SUCCESS;
+ }
UsbDev->MaxPacket0 = DevDesc.MaxPacketSize0;
return EFI_SUCCESS;
}
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
index a6dc1c0c29..b004212fa2 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
@@ -2,7 +2,7 @@
Usb bus enumeration support.
-Copyright (c) 2007 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -15,7 +15,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "UsbBus.h"
-
/**
Return the endpoint descriptor in this interface.
@@ -234,6 +233,7 @@ UsbCreateDevice (
Device->ParentAddr = ParentIf->Device->Address;
Device->ParentIf = ParentIf;
Device->ParentPort = ParentPort;
+ Device->Tier = ParentIf->Device->Tier + 1;
return Device;
}
@@ -540,7 +540,7 @@ UsbRemoveDevice (
USB_BUS *Bus;
USB_DEVICE *Child;
EFI_STATUS Status;
- UINT8 Index;
+ UINTN Index;
Bus = Device->Bus;
@@ -548,7 +548,7 @@ UsbRemoveDevice (
// Remove all the devices on its downstream ports. Search from devices[1].
// Devices[0] is the root hub.
//
- for (Index = 1; Index < USB_MAX_DEVICES; Index++) {
+ for (Index = 1; Index < mMaxUsbDeviceNum; Index++) {
Child = Bus->Devices[Index];
if ((Child == NULL) || (Child->ParentAddr != Device->Address)) {
@@ -567,7 +567,7 @@ UsbRemoveDevice (
DEBUG (( EFI_D_INFO, "UsbRemoveDevice: device %d removed\n", Device->Address));
- ASSERT (Device->Address < USB_MAX_DEVICES);
+ ASSERT (Device->Address < mMaxUsbDeviceNum);
Bus->Devices[Device->Address] = NULL;
UsbFreeDevice (Device);
@@ -599,7 +599,7 @@ UsbFindChild (
//
// Start checking from device 1, device 0 is the root hub
//
- for (Index = 1; Index < USB_MAX_DEVICES; Index++) {
+ for (Index = 1; Index < mMaxUsbDeviceNum; Index++) {
Device = Bus->Devices[Index];
if ((Device != NULL) && (Device->ParentAddr == HubIf->Device->Address) &&
@@ -635,11 +635,11 @@ UsbEnumerateNewDev (
USB_DEVICE *Child;
USB_DEVICE *Parent;
EFI_USB_PORT_STATUS PortState;
- UINT8 Address;
+ UINTN Address;
UINT8 Config;
EFI_STATUS Status;
- Address = USB_MAX_DEVICES;
+ Address = mMaxUsbDeviceNum;
Parent = HubIf->Device;
Bus = Parent->Bus;
HubApi = HubIf->HubApi;
@@ -679,14 +679,21 @@ UsbEnumerateNewDev (
goto ON_ERROR;
}
- if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_LOW_SPEED)) {
- Child->Speed = EFI_USB_SPEED_LOW;
-
+ if (!USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_CONNECTION)) {
+ DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: No device presented at port %d\n", Port));
+ goto ON_ERROR;
+ } else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_SUPER_SPEED)){
+ Child->Speed = EFI_USB_SPEED_SUPER;
+ Child->MaxPacket0 = 512;
} else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_HIGH_SPEED)) {
- Child->Speed = EFI_USB_SPEED_HIGH;
-
+ Child->Speed = EFI_USB_SPEED_HIGH;
+ Child->MaxPacket0 = 64;
+ } else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_LOW_SPEED)) {
+ Child->Speed = EFI_USB_SPEED_LOW;
+ Child->MaxPacket0 = 8;
} else {
- Child->Speed = EFI_USB_SPEED_FULL;
+ Child->Speed = EFI_USB_SPEED_FULL;
+ Child->MaxPacket0 = 8;
}
DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: device is of %d speed\n", Child->Speed));
@@ -720,50 +727,50 @@ UsbEnumerateNewDev (
//
//
- // Host sends a Get_Descriptor request to learn the max packet
- // size of default pipe (only part of the device's descriptor).
- //
- Status = UsbGetMaxPacketSize0 (Child);
-
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status));
- goto ON_ERROR;
- }
-
- DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: max packet size for EP 0 is %d\n", Child->MaxPacket0));
-
- //
// Host assigns an address to the device. Device completes the
// status stage with default address, then switches to new address.
// ADDRESS state. Address zero is reserved for root hub.
//
- for (Address = 1; Address < USB_MAX_DEVICES; Address++) {
+ for (Address = 1; Address < mMaxUsbDeviceNum; Address++) {
if (Bus->Devices[Address] == NULL) {
break;
}
}
- if (Address == USB_MAX_DEVICES) {
+ if (Address == mMaxUsbDeviceNum) {
DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: address pool is full for port %d\n", Port));
Status = EFI_ACCESS_DENIED;
goto ON_ERROR;
}
+ Status = UsbSetAddress (Child, (UINT8)Address);
+ Child->Address = (UINT8)Address;
Bus->Devices[Address] = Child;
- Status = UsbSetAddress (Child, Address);
- Child->Address = Address;
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to set device address - %r\n", Status));
goto ON_ERROR;
}
-
+
gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL);
DEBUG ((EFI_D_INFO, "UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address));
//
+ // Host sends a Get_Descriptor request to learn the max packet
+ // size of default pipe (only part of the device's descriptor).
+ //
+ Status = UsbGetMaxPacketSize0 (Child);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status));
+ goto ON_ERROR;
+ }
+
+ DEBUG (( EFI_D_INFO, "UsbEnumerateNewDev: max packet size for EP 0 is %d\n", Child->MaxPacket0));
+
+ //
// Host learns about the device's abilities by requesting device's
// entire descriptions.
//
@@ -801,7 +808,7 @@ UsbEnumerateNewDev (
return EFI_SUCCESS;
ON_ERROR:
- if (Address != USB_MAX_DEVICES) {
+ if (Address != mMaxUsbDeviceNum) {
Bus->Devices[Address] = NULL;
}
@@ -848,12 +855,16 @@ UsbEnumeratePort (
return Status;
}
- if (PortState.PortChangeStatus == 0) {
+ //
+ // Only handle connection/enable/overcurrent/reset change.
+ // Usb super speed hub may report other changes, such as warm reset change. Ignore them.
+ //
+ if ((PortState.PortChangeStatus & (USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_OVERCURRENT | USB_PORT_STAT_C_RESET)) == 0) {
return EFI_SUCCESS;
}
- DEBUG (( EFI_D_INFO, "UsbEnumeratePort: port %d state - %x, change - %x on %p\n",
- Port, PortState.PortStatus, PortState.PortChangeStatus, HubIf));
+ DEBUG (( EFI_D_INFO, "UsbEnumeratePort: port %d state - %02x, change - %02x on %p\n",
+ Port, PortState.PortChangeStatus, PortState.PortStatus, HubIf));
//
// This driver only process two kinds of events now: over current and
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
index 21270b8080..2dfc5751d5 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
@@ -22,19 +22,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// bits determine whether hub will report the port in changed
// bit maps.
//
-#define USB_HUB_MAP_SIZE 5
-
-USB_CHANGE_FEATURE_MAP mHubFeatureMap[USB_HUB_MAP_SIZE] = {
+USB_CHANGE_FEATURE_MAP mHubFeatureMap[] = {
{USB_PORT_STAT_C_CONNECTION, EfiUsbPortConnectChange},
{USB_PORT_STAT_C_ENABLE, EfiUsbPortEnableChange},
{USB_PORT_STAT_C_SUSPEND, EfiUsbPortSuspendChange},
{USB_PORT_STAT_C_OVERCURRENT, EfiUsbPortOverCurrentChange},
- {USB_PORT_STAT_C_RESET, EfiUsbPortResetChange},
+ {USB_PORT_STAT_C_RESET, EfiUsbPortResetChange}
};
-#define USB_ROOT_HUB_MAP_SIZE 5
-
-USB_CHANGE_FEATURE_MAP mRootHubFeatureMap[USB_ROOT_HUB_MAP_SIZE] = {
+USB_CHANGE_FEATURE_MAP mRootHubFeatureMap[] = {
{USB_PORT_STAT_C_CONNECTION, EfiUsbPortConnectChange},
{USB_PORT_STAT_C_ENABLE, EfiUsbPortEnableChange},
{USB_PORT_STAT_C_SUSPEND, EfiUsbPortSuspendChange},
@@ -47,7 +43,38 @@ USB_CHANGE_FEATURE_MAP mRootHubFeatureMap[USB_ROOT_HUB_MAP_SIZE] = {
// is related to an interface, these requests are sent
// to the control endpoint of the device.
//
+/**
+ USB hub control transfer to set the hub depth.
+
+ @param HubDev The device of the hub.
+ @param Depth The depth to set.
+
+ @retval EFI_SUCCESS Depth of the hub is set.
+ @retval Others Failed to set the depth.
+
+**/
+EFI_STATUS
+UsbHubCtrlSetHubDepth (
+ IN USB_DEVICE *HubDev,
+ IN UINT16 Depth
+ )
+{
+ EFI_STATUS Status;
+ Status = UsbCtrlRequest (
+ HubDev,
+ EfiUsbNoData,
+ USB_REQ_TYPE_CLASS,
+ USB_HUB_TARGET_HUB,
+ USB_HUB_REQ_SET_DEPTH,
+ Depth,
+ 0,
+ NULL,
+ 0
+ );
+
+ return Status;
+}
/**
USB hub control transfer to clear the hub feature.
@@ -173,6 +200,41 @@ UsbHubCtrlClearTTBuffer (
return Status;
}
+/**
+ Usb hub control transfer to get the super speed hub descriptor.
+
+ @param HubDev The hub device.
+ @param Buf The buffer to hold the descriptor.
+ @param Len The length to retrieve.
+
+ @retval EFI_SUCCESS The hub descriptor is retrieved.
+ @retval Others Failed to retrieve the hub descriptor.
+
+**/
+EFI_STATUS
+UsbHubCtrlGetSuperSpeedHubDesc (
+ IN USB_DEVICE *HubDev,
+ OUT VOID *Buf
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_INVALID_PARAMETER;
+
+ Status = UsbCtrlRequest (
+ HubDev,
+ EfiUsbDataIn,
+ USB_REQ_TYPE_CLASS,
+ USB_HUB_TARGET_HUB,
+ USB_HUB_REQ_GET_DESC,
+ (UINT16) (USB_DESC_TYPE_HUB_SUPER_SPEED << 8),
+ 0,
+ Buf,
+ 32
+ );
+
+ return Status;
+}
/**
Usb hub control transfer to get the hub descriptor.
@@ -414,19 +476,27 @@ UsbHubReadDesc (
{
EFI_STATUS Status;
- //
- // First get the hub descriptor length
- //
- Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, 2);
+ if (HubDev->Speed == EFI_USB_SPEED_SUPER) {
+ //
+ // Get the super speed hub descriptor
+ //
+ Status = UsbHubCtrlGetSuperSpeedHubDesc (HubDev, HubDesc);
+ } else {
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ //
+ // First get the hub descriptor length
+ //
+ Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, 2);
- //
- // Get the whole hub descriptor
- //
- Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, HubDesc->Length);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the whole hub descriptor
+ //
+ Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, HubDesc->Length);
+ }
return Status;
}
@@ -629,6 +699,7 @@ UsbHubInit (
EFI_STATUS Status;
UINT8 Index;
UINT8 NumEndpoints;
+ UINT16 Depth;
//
// Locate the interrupt endpoint for port change map
@@ -667,6 +738,37 @@ UsbHubInit (
DEBUG (( EFI_D_INFO, "UsbHubInit: hub %d has %d ports\n", HubDev->Address,HubIf->NumOfPort));
//
+ // OK, set IsHub to TRUE. Now usb bus can handle this device
+ // as a working HUB. If failed eariler, bus driver will not
+ // recognize it as a hub. Other parts of the bus should be able
+ // to work.
+ //
+ HubIf->IsHub = TRUE;
+ HubIf->HubApi = &mUsbHubApi;
+ HubIf->HubEp = EpDesc;
+
+ if (HubIf->Device->Speed == EFI_USB_SPEED_SUPER) {
+ Depth = (UINT16)(HubIf->Device->Tier - 1);
+ DEBUG ((EFI_D_INFO, "UsbHubInit: Set Hub Depth as 0x%x\n", Depth));
+ UsbHubCtrlSetHubDepth (HubIf->Device, Depth);
+
+ for (Index = 0; Index < HubDesc.NumPorts; Index++) {
+ UsbHubCtrlSetPortFeature (HubIf->Device, Index, USB_HUB_PORT_REMOTE_WAKE_MASK);
+ }
+ } else {
+ //
+ // Feed power to all the hub ports. It should be ok
+ // for both gang/individual powered hubs.
+ //
+ for (Index = 0; Index < HubDesc.NumPorts; Index++) {
+ UsbHubCtrlSetPortFeature (HubIf->Device, Index, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_POWER);
+ }
+
+ gBS->Stall (HubDesc.PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);
+ UsbHubAckHubStatus (HubIf->Device);
+ }
+
+ //
// Create an event to enumerate the hub's port. On
//
Status = gBS->CreateEvent (
@@ -712,27 +814,6 @@ UsbHubInit (
return Status;
}
- //
- // OK, set IsHub to TRUE. Now usb bus can handle this device
- // as a working HUB. If failed eariler, bus driver will not
- // recognize it as a hub. Other parts of the bus should be able
- // to work.
- //
- HubIf->IsHub = TRUE;
- HubIf->HubApi = &mUsbHubApi;
- HubIf->HubEp = EpDesc;
-
- //
- // Feed power to all the hub ports. It should be ok
- // for both gang/individual powered hubs.
- //
- for (Index = 0; Index < HubDesc.NumPorts; Index++) {
- UsbHubCtrlSetPortFeature (HubIf->Device, Index, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_POWER);
- }
-
- gBS->Stall (HubDesc.PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);
- UsbHubAckHubStatus (HubIf->Device);
-
DEBUG (( EFI_D_INFO, "UsbHubInit: hub %d initialized\n", HubDev->Address));
return Status;
}
@@ -764,6 +845,12 @@ UsbHubGetPortStatus (
Status = UsbHubCtrlGetPortStatus (HubIf->Device, Port, PortState);
+ //
+ // Mark the USB_PORT_STAT_SUPER_SPEED bit if SuperSpeed
+ //
+ if (HubIf->Device->Speed == EFI_USB_SPEED_SUPER) {
+ PortState->PortStatus |= USB_PORT_STAT_SUPER_SPEED;
+ }
return Status;
}
@@ -799,7 +886,7 @@ UsbHubClearPortChange (
// It may lead to extra port state report. USB bus should
// be able to handle this.
//
- for (Index = 0; Index < USB_HUB_MAP_SIZE; Index++) {
+ for (Index = 0; Index < sizeof (mHubFeatureMap) / sizeof (mHubFeatureMap[0]); Index++) {
Map = &mHubFeatureMap[Index];
if (USB_BIT_IS_SET (PortState.PortChangeStatus, Map->ChangedBit)) {
@@ -1091,7 +1178,7 @@ UsbRootHubClearPortChange (
// It may lead to extra port state report. USB bus should
// be able to handle this.
//
- for (Index = 0; Index < USB_ROOT_HUB_MAP_SIZE; Index++) {
+ for (Index = 0; Index < sizeof (mRootHubFeatureMap) / sizeof (mRootHubFeatureMap[0]); Index++) {
Map = &mRootHubFeatureMap[Index];
if (USB_BIT_IS_SET (PortState.PortChangeStatus, Map->ChangedBit)) {
diff --git a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
index 1a6ebdd6ca..c7ee16db46 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
+++ b/MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
@@ -23,6 +23,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define USB_DESC_TYPE_HUB 0x29
+
+#define USB_DESC_TYPE_HUB_SUPER_SPEED 0x2a
+
//
// Hub class control transfer target
//
@@ -40,6 +43,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define USB_HUB_REQ_RESET_TT 9
#define USB_HUB_REQ_GET_TT_STATE 10
#define USB_HUB_REQ_STOP_TT 11
+
+#define USB_HUB_REQ_SET_DEPTH 12
+
//
// USB hub class feature selector
//
@@ -50,6 +56,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define USB_HUB_PORT_SUSPEND 2
#define USB_HUB_PORT_OVER_CURRENT 3
#define USB_HUB_PORT_RESET 4
+
+#define USB_HUB_PORT_LINK_STATE 5
+
#define USB_HUB_PORT_POWER 8
#define USB_HUB_PORT_LOW_SPEED 9
#define USB_HUB_C_PORT_CONNECT 16
@@ -59,6 +68,17 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define USB_HUB_C_PORT_RESET 20
#define USB_HUB_PORT_TEST 21
#define USB_HUB_PORT_INDICATOR 22
+
+#define USB_HUB_C_PORT_LINK_STATE 25
+#define USB_HUB_PORT_REMOTE_WAKE_MASK 27
+#define USB_HUB_BH_PORT_RESET 28
+#define USB_HUB_C_BH_PORT_RESET 29
+
+//
+// Constant value for Port Status & Port Change Status of SuperSpeed port
+//
+#define USB_SS_PORT_STAT_C_BH_RESET 0x0020
+#define USB_SS_PORT_STAT_C_PORT_LINK_STATE 0x0040
//
// USB hub power control method. In gang power control
//
@@ -94,6 +114,19 @@ typedef struct {
UINT8 HubContrCurrent;
UINT8 Filler[16];
} EFI_USB_HUB_DESCRIPTOR;
+
+typedef struct {
+ UINT8 Length;
+ UINT8 DescType;
+ UINT8 NumPorts;
+ UINT16 HubCharacter;
+ UINT8 PwrOn2PwrGood;
+ UINT8 HubContrCurrent;
+ UINT8 HubHdrDecLat;
+ UINT8 HubDelay;
+ UINT8 DeviceRemovable;
+} EFI_USB_SUPER_SPEED_HUB_DESCRIPTOR;
+
#pragma pack()