\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
@param State Variable to return the hub port state.\r
\r
@retval EFI_SUCCESS The port state is returned in State.\r
- @retval Others Failed to retrive the port state.\r
+ @retval Others Failed to retrieve the port state.\r
\r
**/\r
EFI_STATUS\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
USB_DEVICE *HubDev;\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
Setting = HubIf->IfSetting;\r
HubDev = HubIf->Device;\r
EpDesc = NULL;\r
+ NumEndpoints = Setting->Desc.NumEndpoints;\r
\r
- for (Index = 0; Index < Setting->Desc.NumEndpoints; Index++) {\r
+ for (Index = 0; Index < NumEndpoints; Index++) {\r
ASSERT ((Setting->Endpoints != NULL) && (Setting->Endpoints[Index] != NULL));\r
\r
EpDesc = Setting->Endpoints[Index];\r
}\r
}\r
\r
- if (Index == Setting->Desc.NumEndpoints) {\r
+ if (Index == NumEndpoints) {\r
DEBUG (( EFI_D_ERROR, "UsbHubInit: no interrupt endpoint found for hub %d\n", HubDev->Address));\r
return EFI_DEVICE_ERROR;\r
}\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
\r
\r
/**\r
- Interface funtion to reset the port.\r
+ Interface function to reset the port.\r
\r
@param HubIf The hub interface.\r
@param Port The port to reset.\r
\r
@param HubIf The root hub interface.\r
\r
- @retval EFI_SUCCESS The interface is initialied for root hub.\r
+ @retval EFI_SUCCESS The interface is initialized for root hub.\r
@retval Others Failed to initialize the hub.\r
\r
**/\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
\r
\r
/**\r
- Interface funtion to reset the root hub port.\r
+ Interface function to reset the root hub port.\r
\r
@param RootIf The root hub interface.\r
@param Port The port to reset.\r