21 { USB_PORT_STAT_C_ENABLE, EfiUsbPortEnableChange },
22 { USB_PORT_STAT_C_SUSPEND, EfiUsbPortSuspendChange },
23 { USB_PORT_STAT_C_OVERCURRENT, EfiUsbPortOverCurrentChange },
24 { USB_PORT_STAT_C_RESET, EfiUsbPortResetChange }
29 { USB_PORT_STAT_C_ENABLE, EfiUsbPortEnableChange },
30 { USB_PORT_STAT_C_SUSPEND, EfiUsbPortSuspendChange },
31 { USB_PORT_STAT_C_OVERCURRENT, EfiUsbPortOverCurrentChange },
32 { USB_PORT_STAT_C_RESET, EfiUsbPortResetChange },
64 USB_HUB_REQ_SET_DEPTH,
97 USB_HUB_REQ_CLEAR_FEATURE,
136 USB_HUB_REQ_CLEAR_FEATURE,
178 Value = (UINT16)((EpNum & 0x0F) | (DevAddr << 4) |
179 ((EpType & 0x03) << 11) | ((EpNum & 0x80) << 15));
186 USB_HUB_REQ_CLEAR_TT,
218 USB_DESC_TYPE_HUB_SUPER_SPEED :
226 USB_HUB_REQ_GET_DESC,
227 (UINT16)(DescType << 8),
259 USB_HUB_REQ_GET_STATUS,
300 USB_HUB_REQ_GET_STATUS,
339 USB_HUB_REQ_SET_FEATURE,
374 if (EFI_ERROR (Status)) {
404 if (EFI_ERROR (Status)) {
408 if (USB_BIT_IS_SET (HubState.
PortChangeStatus, USB_HUB_STAT_C_LOCAL_POWER)) {
412 if (USB_BIT_IS_SET (HubState.
PortChangeStatus, USB_HUB_STAT_C_OVER_CURRENT)) {
439 Setting = &UsbIf->IfSetting->Desc;
441 if ((Setting->InterfaceClass == USB_HUB_CLASS_CODE) &&
442 (Setting->InterfaceSubClass == USB_HUB_SUBCLASS_CODE))
479 UsbIo = &(HubIf->UsbIo);
480 EpDesc = &(HubIf->HubEp->Desc);
482 if (Result != EFI_USB_NOERROR) {
487 if (USB_BIT_IS_SET (Result, EFI_USB_ERR_STALL)) {
491 USB_FEATURE_ENDPOINT_HALT,
492 EpDesc->EndpointAddress
499 Status = UsbIo->UsbAsyncInterruptTransfer (
501 EpDesc->EndpointAddress,
509 if (EFI_ERROR (Status)) {
510 DEBUG ((DEBUG_ERROR,
"UsbOnHubInterrupt: failed to remove async transfer - %r\n", Status));
514 Status = UsbIo->UsbAsyncInterruptTransfer (
516 EpDesc->EndpointAddress,
518 USB_HUB_POLL_INTERVAL,
519 HubIf->NumOfPort / 8 + 1,
524 if (EFI_ERROR (Status)) {
525 DEBUG ((DEBUG_ERROR,
"UsbOnHubInterrupt: failed to submit new async transfer - %r\n", Status));
531 if ((DataLength == 0) || (Data ==
NULL)) {
543 if (HubIf->ChangeMap ==
NULL) {
544 return EFI_OUT_OF_RESOURCES;
547 CopyMem (HubIf->ChangeMap, Data, DataLength);
548 gBS->SignalEvent (HubIf->HubNotify);
567 UINT8 HubDescBuffer[256];
581 HubIf->IsHub =
FALSE;
582 Setting = HubIf->IfSetting;
583 HubDev = HubIf->Device;
585 NumEndpoints = Setting->Desc.NumEndpoints;
587 for (Index = 0; Index < NumEndpoints; Index++) {
588 ASSERT ((Setting->Endpoints !=
NULL) && (Setting->Endpoints[Index] !=
NULL));
590 EpDesc = Setting->Endpoints[Index];
592 if (USB_BIT_IS_SET (EpDesc->Desc.EndpointAddress, USB_ENDPOINT_DIR_IN) &&
593 (USB_ENDPOINT_TYPE (&EpDesc->Desc) == USB_ENDPOINT_INTERRUPT))
599 if (Index == NumEndpoints) {
600 DEBUG ((DEBUG_ERROR,
"UsbHubInit: no interrupt endpoint found for hub %d\n", HubDev->Address));
601 return EFI_DEVICE_ERROR;
611 if (EFI_ERROR (Status)) {
612 DEBUG ((DEBUG_ERROR,
"UsbHubInit: failed to read HUB descriptor - %r\n", Status));
616 HubIf->NumOfPort = HubDesc->NumPorts;
618 DEBUG ((DEBUG_INFO,
"UsbHubInit: hub %d has %d ports\n", HubDev->Address, HubIf->NumOfPort));
627 HubIf->HubApi = &mUsbHubApi;
628 HubIf->HubEp = EpDesc;
631 Depth = (UINT16)(HubIf->Device->Tier - 1);
632 DEBUG ((DEBUG_INFO,
"UsbHubInit: Set Hub Depth as 0x%x\n", Depth));
635 for (Index = 0; Index < HubDesc->NumPorts; Index++) {
643 for (Index = 0; Index < HubDesc->NumPorts; Index++) {
650 if (HubDesc->PwrOn2PwrGood > 0) {
651 gBS->Stall (HubDesc->PwrOn2PwrGood * USB_SET_PORT_POWER_STALL);
660 Status =
gBS->CreateEvent (
668 if (EFI_ERROR (Status)) {
671 "UsbHubInit: failed to create signal for hub %d - %r\n",
686 UsbIo = &HubIf->UsbIo;
687 Status = UsbIo->UsbAsyncInterruptTransfer (
689 EpDesc->Desc.EndpointAddress,
691 USB_HUB_POLL_INTERVAL,
692 HubIf->NumOfPort / 8 + 1,
697 if (EFI_ERROR (Status)) {
700 "UsbHubInit: failed to queue interrupt transfer for hub %d - %r\n",
705 gBS->CloseEvent (HubIf->HubNotify);
706 HubIf->HubNotify =
NULL;
711 DEBUG ((DEBUG_INFO,
"UsbHubInit: hub %d initialized\n", HubDev->Address));
763 if (EFI_ERROR (Status)) {
773 for (Index = 0; Index <
ARRAY_SIZE (mHubFeatureMap); Index++) {
774 Map = &mHubFeatureMap[Index];
855 if (EFI_ERROR (Status)) {
863 gBS->Stall (USB_SET_PORT_RESET_STALL);
870 for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {
873 if (EFI_ERROR (Status)) {
877 if (!EFI_ERROR (Status) &&
880 gBS->Stall (USB_SET_PORT_RECOVERY_STALL);
884 gBS->Stall (USB_WAIT_PORT_STS_CHANGE_STALL);
906 UsbIo = &HubIf->UsbIo;
907 Status = UsbIo->UsbAsyncInterruptTransfer (
909 HubIf->HubEp->Desc.EndpointAddress,
911 USB_HUB_POLL_INTERVAL,
917 if (EFI_ERROR (Status)) {
921 gBS->CloseEvent (HubIf->HubNotify);
923 HubIf->IsHub =
FALSE;
924 HubIf->HubApi =
NULL;
926 HubIf->HubNotify =
NULL;
928 DEBUG ((DEBUG_INFO,
"UsbHubRelease: hub device %d released\n", HubIf->Device->Address));
953 if (EFI_ERROR (Status)) {
959 "UsbRootHubInit: root hub %p - max speed %d, %d ports\n",
966 HubIf->HubApi = &mUsbRootHubApi;
968 HubIf->MaxSpeed = MaxSpeed;
969 HubIf->NumOfPort = NumOfPort;
970 HubIf->HubNotify =
NULL;
975 Status =
gBS->CreateEvent (
976 EVT_TIMER | EVT_NOTIFY_SIGNAL,
983 if (EFI_ERROR (Status)) {
991 gBS->SignalEvent (HubIf->HubNotify);
993 Status =
gBS->SetTimer (
996 USB_ROOTHUB_POLL_INTERVAL
999 if (EFI_ERROR (Status)) {
1000 gBS->CloseEvent (HubIf->HubNotify);
1030 Bus = HubIf->Device->Bus;
1056 if (EFI_ERROR (Status)) {
1066 for (Index = 0; Index <
ARRAY_SIZE (mRootHubFeatureMap); Index++) {
1067 Map = &mRootHubFeatureMap[Index];
1154 Bus = RootIf->Device->Bus;
1158 if (EFI_ERROR (Status)) {
1159 DEBUG ((DEBUG_ERROR,
"UsbRootHubResetPort: failed to start reset on port %d\n", Port));
1167 gBS->Stall (USB_SET_ROOT_PORT_RESET_STALL);
1171 if (EFI_ERROR (Status)) {
1172 DEBUG ((DEBUG_ERROR,
"UsbRootHubResetPort: failed to clear reset on port %d\n", Port));
1176 gBS->Stall (USB_CLR_ROOT_PORT_RESET_STALL);
1184 for (Index = 0; Index < USB_WAIT_PORT_STS_CHANGE_LOOP; Index++) {
1187 if (EFI_ERROR (Status)) {
1191 if (!USB_BIT_IS_SET (PortState.
PortStatus, USB_PORT_STAT_RESET)) {
1195 gBS->Stall (USB_WAIT_PORT_STS_CHANGE_STALL);
1198 if (Index == USB_WAIT_PORT_STS_CHANGE_LOOP) {
1199 DEBUG ((DEBUG_ERROR,
"UsbRootHubResetPort: reset not finished in time on port %d\n", Port));
1203 if (!USB_BIT_IS_SET (PortState.
PortStatus, USB_PORT_STAT_ENABLE)) {
1210 if (RootIf->MaxSpeed == EFI_USB_SPEED_HIGH) {
1211 DEBUG ((DEBUG_ERROR,
"UsbRootHubResetPort: release low/full speed device (%d) to UHCI\n", Port));
1214 return EFI_NOT_FOUND;
1218 if (EFI_ERROR (Status)) {
1219 DEBUG ((DEBUG_ERROR,
"UsbRootHubResetPort: failed to enable port %d for UHCI\n", Port));
1223 gBS->Stall (USB_SET_ROOT_PORT_ENABLE_STALL);
1244 DEBUG ((DEBUG_INFO,
"UsbRootHubRelease: root hub released for hub %p\n", HubIf));
1246 gBS->SetTimer (HubIf->HubNotify,
TimerCancel, USB_ROOTHUB_POLL_INTERVAL);
1247 gBS->CloseEvent (HubIf->HubNotify);
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
#define ARRAY_SIZE(Array)
#define DEBUG(Expression)
#define USB_PORT_STAT_C_CONNECTION
#define EFI_USB_SPEED_SUPER
4.8 Gb/s, USB 3.0 XHCI HC.
EFI_STATUS UsbIoClearFeature(IN EFI_USB_IO_PROTOCOL *UsbIo, IN UINTN Target, IN UINT16 Feature, IN UINT16 Index)
EFI_STATUS UsbCtrlRequest(IN USB_DEVICE *UsbDev, IN EFI_USB_DATA_DIRECTION Direction, IN UINTN Type, IN UINTN Target, IN UINTN Request, IN UINT16 Value, IN UINT16 Index, IN OUT VOID *Buf, IN UINTN Length)
VOID EFIAPI UsbHubEnumeration(IN EFI_EVENT Event, IN VOID *Context)
VOID EFIAPI UsbRootHubEnumeration(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS UsbRootHubResetPort(IN USB_INTERFACE *RootIf, IN UINT8 Port)
EFI_STATUS UsbHubCtrlClearTTBuffer(IN USB_DEVICE *HubDev, IN UINT8 Port, IN UINT16 DevAddr, IN UINT16 EpNum, IN UINT16 EpType)
EFI_STATUS UsbHubInit(IN USB_INTERFACE *HubIf)
EFI_STATUS EFIAPI UsbOnHubInterrupt(IN VOID *Data, IN UINTN DataLength, IN VOID *Context, IN UINT32 Result)
EFI_STATUS UsbRootHubClearPortFeature(IN USB_INTERFACE *HubIf, IN UINT8 Port, IN EFI_USB_PORT_FEATURE Feature)
EFI_STATUS UsbHubResetPort(IN USB_INTERFACE *HubIf, IN UINT8 Port)
EFI_STATUS UsbHubCtrlSetPortFeature(IN USB_DEVICE *HubDev, IN UINT8 Port, IN UINT8 Feature)
EFI_STATUS UsbHubCtrlClearPortFeature(IN USB_DEVICE *HubDev, IN UINT8 Port, IN UINT16 Feature)
EFI_STATUS UsbHubClearPortFeature(IN USB_INTERFACE *HubIf, IN UINT8 Port, IN EFI_USB_PORT_FEATURE Feature)
EFI_STATUS UsbRootHubGetPortStatus(IN USB_INTERFACE *HubIf, IN UINT8 Port, OUT EFI_USB_PORT_STATUS *PortState)
EFI_STATUS UsbHubCtrlGetPortStatus(IN USB_DEVICE *HubDev, IN UINT8 Port, OUT VOID *State)
EFI_STATUS UsbHubRelease(IN USB_INTERFACE *HubIf)
EFI_STATUS UsbHubAckHubStatus(IN USB_DEVICE *HubDev)
EFI_STATUS UsbHubCtrlSetHubDepth(IN USB_DEVICE *HubDev, IN UINT16 Depth)
EFI_STATUS UsbRootHubInit(IN USB_INTERFACE *HubIf)
EFI_STATUS UsbHubGetPortStatus(IN USB_INTERFACE *HubIf, IN UINT8 Port, OUT EFI_USB_PORT_STATUS *PortState)
VOID UsbRootHubClearPortChange(IN USB_INTERFACE *HubIf, IN UINT8 Port)
EFI_STATUS UsbHubSetPortFeature(IN USB_INTERFACE *HubIf, IN UINT8 Port, IN EFI_USB_PORT_FEATURE Feature)
EFI_STATUS UsbRootHubRelease(IN USB_INTERFACE *HubIf)
EFI_STATUS UsbHubCtrlGetHubDesc(IN USB_DEVICE *HubDev, OUT VOID *Buf, IN UINTN Len)
EFI_STATUS UsbHubCtrlGetHubStatus(IN USB_DEVICE *HubDev, OUT UINT32 *State)
EFI_STATUS UsbHubReadDesc(IN USB_DEVICE *HubDev, OUT EFI_USB_HUB_DESCRIPTOR *HubDesc)
EFI_STATUS UsbHubCtrlClearHubFeature(IN USB_DEVICE *HubDev, IN UINT16 Feature)
BOOLEAN UsbIsHubInterface(IN USB_INTERFACE *UsbIf)
EFI_STATUS UsbRootHubSetPortFeature(IN USB_INTERFACE *HubIf, IN UINT8 Port, IN EFI_USB_PORT_FEATURE Feature)
VOID UsbHubClearPortChange(IN USB_INTERFACE *HubIf, IN UINT8 Port)
EFI_STATUS UsbHcGetRootHubPortStatus(IN USB_BUS *UsbBus, IN UINT8 PortIndex, OUT EFI_USB_PORT_STATUS *PortStatus)
EFI_STATUS UsbHcClearRootHubPortFeature(IN USB_BUS *UsbBus, IN UINT8 PortIndex, IN EFI_USB_PORT_FEATURE Feature)
EFI_STATUS UsbHcSetRootHubPortFeature(IN USB_BUS *UsbBus, IN UINT8 PortIndex, IN EFI_USB_PORT_FEATURE Feature)
EFI_STATUS UsbHcGetCapability(IN USB_BUS *UsbBus, OUT UINT8 *MaxSpeed, OUT UINT8 *NumOfPort, OUT UINT8 *Is64BitCapable)
UINT16 PortChangeStatus
Contains current port status change bitmap.
UINT16 PortStatus
Contains current port status bitmap.