\r
Unified interface for RootHub and Hub.\r
\r
-Copyright (c) 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR> \r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
// 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
+\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
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
UsbOnHubInterrupt (\r
IN VOID *Data,\r
IN UINTN DataLength,\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
@param HubIf The hub interface.\r
@param Port The hub port.\r
\r
- @return None.\r
-\r
**/\r
VOID\r
UsbHubClearPortChange (\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
@param HubIf The root hub interface.\r
@param Port The root hub port.\r
\r
- @return None.\r
-\r
**/\r
VOID\r
UsbRootHubClearPortChange (\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