// bits determine whether hub will report the port in changed\r
// bit maps.\r
//\r
-#define USB_HUB_MAP_SIZE 5\r
-\r
-USB_CHANGE_FEATURE_MAP mHubFeatureMap[USB_HUB_MAP_SIZE] = {\r
+USB_CHANGE_FEATURE_MAP mHubFeatureMap[] = {\r
{USB_PORT_STAT_C_CONNECTION, EfiUsbPortConnectChange},\r
{USB_PORT_STAT_C_ENABLE, EfiUsbPortEnableChange},\r
{USB_PORT_STAT_C_SUSPEND, EfiUsbPortSuspendChange},\r
{USB_PORT_STAT_C_OVERCURRENT, EfiUsbPortOverCurrentChange},\r
- {USB_PORT_STAT_C_RESET, EfiUsbPortResetChange},\r
+ {USB_PORT_STAT_C_RESET, EfiUsbPortResetChange}\r
};\r
\r
-#define USB_ROOT_HUB_MAP_SIZE 5\r
-\r
-USB_CHANGE_FEATURE_MAP mRootHubFeatureMap[USB_ROOT_HUB_MAP_SIZE] = {\r
+USB_CHANGE_FEATURE_MAP mRootHubFeatureMap[] = {\r
{USB_PORT_STAT_C_CONNECTION, EfiUsbPortConnectChange},\r
{USB_PORT_STAT_C_ENABLE, EfiUsbPortEnableChange},\r
{USB_PORT_STAT_C_SUSPEND, EfiUsbPortSuspendChange},\r
// is related to an interface, these requests are sent\r
// to the control endpoint of the device.\r
//\r
+/**\r
+ USB hub control transfer to set the hub depth.\r
+\r
+ @param HubDev The device of the hub.\r
+ @param Depth The depth to set.\r
+\r
+ @retval EFI_SUCCESS Depth of the hub is set.\r
+ @retval Others Failed to set the depth.\r
+\r
+**/\r
+EFI_STATUS\r
+UsbHubCtrlSetHubDepth (\r
+ IN USB_DEVICE *HubDev,\r
+ IN UINT16 Depth\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
\r
+ Status = UsbCtrlRequest (\r
+ HubDev,\r
+ EfiUsbNoData,\r
+ USB_REQ_TYPE_CLASS,\r
+ USB_HUB_TARGET_HUB,\r
+ USB_HUB_REQ_SET_DEPTH,\r
+ Depth,\r
+ 0,\r
+ NULL,\r
+ 0\r
+ );\r
+\r
+ return Status;\r
+}\r
\r
/**\r
USB hub control transfer to clear the hub feature.\r
return Status;\r
}\r
\r
+/**\r
+ Usb hub control transfer to get the super speed hub descriptor.\r
+\r
+ @param HubDev The hub device.\r
+ @param Buf The buffer to hold the descriptor.\r
+ @param Len The length to retrieve.\r
+\r
+ @retval EFI_SUCCESS The hub descriptor is retrieved.\r
+ @retval Others Failed to retrieve the hub descriptor.\r
+\r
+**/\r
+EFI_STATUS\r
+UsbHubCtrlGetSuperSpeedHubDesc (\r
+ IN USB_DEVICE *HubDev,\r
+ OUT VOID *Buf\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ \r
+ Status = EFI_INVALID_PARAMETER;\r
+ \r
+ Status = UsbCtrlRequest (\r
+ HubDev,\r
+ EfiUsbDataIn,\r
+ USB_REQ_TYPE_CLASS,\r
+ USB_HUB_TARGET_HUB,\r
+ USB_HUB_REQ_GET_DESC,\r
+ (UINT16) (USB_DESC_TYPE_HUB_SUPER_SPEED << 8),\r
+ 0,\r
+ Buf,\r
+ 32\r
+ );\r
+\r
+ return Status;\r
+}\r
\r
/**\r
Usb hub control transfer to get the hub descriptor.\r
{\r
EFI_STATUS Status;\r
\r
- //\r
- // First get the hub descriptor length\r
- //\r
- Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, 2);\r
+ if (HubDev->Speed == EFI_USB_SPEED_SUPER) {\r
+ //\r
+ // Get the super speed hub descriptor\r
+ //\r
+ Status = UsbHubCtrlGetSuperSpeedHubDesc (HubDev, HubDesc);\r
+ } else {\r
\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
+ //\r
+ // First get the hub descriptor length\r
+ //\r
+ Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, 2);\r
\r
- //\r
- // Get the whole hub descriptor\r
- //\r
- Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, HubDesc->Length);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get the whole hub descriptor\r
+ //\r
+ Status = UsbHubCtrlGetHubDesc (HubDev, HubDesc, HubDesc->Length);\r
+ }\r
\r
return Status;\r
}\r
EFI_STATUS Status;\r
UINT8 Index;\r
UINT8 NumEndpoints;\r
+ UINT16 Depth;\r
\r
//\r
// Locate the interrupt endpoint for port change map\r
\r
DEBUG (( EFI_D_INFO, "UsbHubInit: hub %d has %d ports\n", HubDev->Address,HubIf->NumOfPort));\r
\r
+ //\r
+ // OK, set IsHub to TRUE. Now usb bus can handle this device\r
+ // as a working HUB. If failed eariler, bus driver will not\r
+ // recognize it as a hub. Other parts of the bus should be able\r
+ // to work.\r
+ //\r
+ HubIf->IsHub = TRUE;\r
+ HubIf->HubApi = &mUsbHubApi;\r
+ HubIf->HubEp = EpDesc;\r
+\r
+ if (HubIf->Device->Speed == EFI_USB_SPEED_SUPER) {\r
+ Depth = (UINT16)(HubIf->Device->Tier - 1);\r
+ DEBUG ((EFI_D_INFO, "UsbHubInit: Set Hub Depth as 0x%x\n", Depth));\r
+ UsbHubCtrlSetHubDepth (HubIf->Device, Depth);\r
+ \r
+ for (Index = 0; Index < HubDesc.NumPorts; Index++) {\r
+ UsbHubCtrlSetPortFeature (HubIf->Device, Index, USB_HUB_PORT_REMOTE_WAKE_MASK);\r
+ } \r
+ } else {\r
+ //\r
+ // Feed power to all the hub ports. It should be ok\r
+ // for both gang/individual powered hubs.\r
+ //\r
+ for (Index = 0; Index < HubDesc.NumPorts; Index++) {\r
+ UsbHubCtrlSetPortFeature (HubIf->Device, Index, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_POWER);\r
+ }\r
+\r
+ gBS->Stall (HubDesc.PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);\r
+ UsbHubAckHubStatus (HubIf->Device);\r
+ }\r
+\r
//\r
// Create an event to enumerate the hub's port. On\r
//\r
return Status;\r
}\r
\r
- //\r
- // OK, set IsHub to TRUE. Now usb bus can handle this device\r
- // as a working HUB. If failed eariler, bus driver will not\r
- // recognize it as a hub. Other parts of the bus should be able\r
- // to work.\r
- //\r
- HubIf->IsHub = TRUE;\r
- HubIf->HubApi = &mUsbHubApi;\r
- HubIf->HubEp = EpDesc;\r
-\r
- //\r
- // Feed power to all the hub ports. It should be ok\r
- // for both gang/individual powered hubs.\r
- //\r
- for (Index = 0; Index < HubDesc.NumPorts; Index++) {\r
- UsbHubCtrlSetPortFeature (HubIf->Device, Index, (EFI_USB_PORT_FEATURE) USB_HUB_PORT_POWER);\r
- }\r
-\r
- gBS->Stall (HubDesc.PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);\r
- UsbHubAckHubStatus (HubIf->Device);\r
-\r
DEBUG (( EFI_D_INFO, "UsbHubInit: hub %d initialized\n", HubDev->Address));\r
return Status;\r
}\r
\r
Status = UsbHubCtrlGetPortStatus (HubIf->Device, Port, PortState);\r
\r
+ //\r
+ // Mark the USB_PORT_STAT_SUPER_SPEED bit if SuperSpeed\r
+ //\r
+ if (HubIf->Device->Speed == EFI_USB_SPEED_SUPER) {\r
+ PortState->PortStatus |= USB_PORT_STAT_SUPER_SPEED;\r
+ } \r
return Status;\r
}\r
\r
// It may lead to extra port state report. USB bus should\r
// be able to handle this.\r
//\r
- for (Index = 0; Index < USB_HUB_MAP_SIZE; Index++) {\r
+ for (Index = 0; Index < sizeof (mHubFeatureMap) / sizeof (mHubFeatureMap[0]); Index++) {\r
Map = &mHubFeatureMap[Index];\r
\r
if (USB_BIT_IS_SET (PortState.PortChangeStatus, Map->ChangedBit)) {\r
// It may lead to extra port state report. USB bus should\r
// be able to handle this.\r
//\r
- for (Index = 0; Index < USB_ROOT_HUB_MAP_SIZE; Index++) {\r
+ for (Index = 0; Index < sizeof (mRootHubFeatureMap) / sizeof (mRootHubFeatureMap[0]); Index++) {\r
Map = &mRootHubFeatureMap[Index];\r
\r
if (USB_BIT_IS_SET (PortState.PortChangeStatus, Map->ChangedBit)) {\r