31 NumEndpoints = UsbIf->IfSetting->Desc.NumEndpoints;
33 for (Index = 0; Index < NumEndpoints; Index++) {
34 EpDesc = UsbIf->IfSetting->Endpoints[Index];
36 if (EpDesc->Desc.EndpointAddress == EpAddr) {
61 Status =
gBS->UninstallMultipleProtocolInterfaces (
63 &gEfiDevicePathProtocolGuid,
65 &gEfiUsbIoProtocolGuid,
69 if (!EFI_ERROR (Status)) {
70 if (UsbIf->DevicePath !=
NULL) {
109 UsbIf->Signature = USB_INTERFACE_SIGNATURE;
110 UsbIf->Device = Device;
111 UsbIf->IfDesc = IfDesc;
112 ASSERT (IfDesc->ActiveIndex < USB_MAX_INTERFACE_SETTING);
113 UsbIf->IfSetting = IfDesc->Settings[IfDesc->ActiveIndex];
131 HubIf = Device->ParentIf;
132 ASSERT (HubIf !=
NULL);
136 if (UsbIf->DevicePath ==
NULL) {
137 DEBUG ((DEBUG_ERROR,
"UsbCreateInterface: failed to create device path\n"));
139 Status = EFI_OUT_OF_RESOURCES;
143 Status =
gBS->InstallMultipleProtocolInterfaces (
145 &gEfiDevicePathProtocolGuid,
147 &gEfiUsbIoProtocolGuid,
152 if (EFI_ERROR (Status)) {
153 DEBUG ((DEBUG_ERROR,
"UsbCreateInterface: failed to install UsbIo - %r\n", Status));
162 if (EFI_ERROR (Status)) {
163 gBS->UninstallMultipleProtocolInterfaces (
165 &gEfiDevicePathProtocolGuid,
167 &gEfiUsbIoProtocolGuid,
172 DEBUG ((DEBUG_ERROR,
"UsbCreateInterface: failed to open host for child - %r\n", Status));
179 if (UsbIf->DevicePath !=
NULL) {
198 if (Device->DevDesc !=
NULL) {
202 gBS->FreePool (Device);
222 ASSERT (ParentIf !=
NULL);
226 if (Device ==
NULL) {
230 Device->Bus = ParentIf->Device->Bus;
231 Device->MaxPacket0 = 8;
232 Device->ParentAddr = ParentIf->Device->Address;
233 Device->ParentIf = ParentIf;
234 Device->ParentPort = ParentPort;
235 Device->Tier = (UINT8)(ParentIf->Device->Tier + 1);
264 DEBUG ((DEBUG_INFO,
"UsbConnectDriver: found a hub device\n"));
265 Status = mUsbHubApi.Init (UsbIf);
280 DEBUG ((DEBUG_INFO,
"UsbConnectDriver: TPL before connect is %d, %p\n", (UINT32)OldTpl, UsbIf->Handle));
282 gBS->RestoreTPL (TPL_CALLBACK);
285 UsbIf->IsManaged = (BOOLEAN) !EFI_ERROR (Status);
290 gBS->RaiseTPL (OldTpl);
324 for (Index = 0; Index < IfDesc->NumOfSetting; Index++) {
325 ASSERT (Index < USB_MAX_INTERFACE_SETTING);
326 Setting = IfDesc->Settings[Index];
328 if (Setting->Desc.AlternateSetting == Alternate) {
333 if (Index == IfDesc->NumOfSetting) {
334 return EFI_NOT_FOUND;
337 IfDesc->ActiveIndex = Index;
339 ASSERT (Setting !=
NULL);
342 "UsbSelectSetting: setting %d selected for interface %d\n",
344 Setting->Desc.InterfaceNumber
350 for (Index = 0; Index < Setting->Desc.NumEndpoints; Index++) {
351 Setting->Endpoints[Index]->Toggle = 0;
385 DevDesc = Device->DevDesc;
388 for (Index = 0; Index < DevDesc->Desc.NumConfigurations; Index++) {
389 ConfigDesc = DevDesc->Configs[Index];
391 if (ConfigDesc->Desc.ConfigurationValue == ConfigValue) {
396 if (Index == DevDesc->Desc.NumConfigurations) {
397 return EFI_NOT_FOUND;
400 Device->ActiveConfig = ConfigDesc;
404 "UsbSelectConfig: config %d selected for device %d\n",
412 for (Index = 0; Index < ConfigDesc->Desc.NumInterfaces; Index++) {
417 IfDesc = ConfigDesc->Interfaces[Index];
426 Device->NumOfInterface = Index;
427 return EFI_OUT_OF_RESOURCES;
430 ASSERT (Index < USB_MAX_INTERFACE);
431 Device->Interfaces[Index] = UsbIf;
440 if (EFI_ERROR (Status)) {
443 "UsbSelectConfig: failed to connect driver - %r, ignored\n",
449 Device->NumOfInterface = Index;
474 Status = UsbIf->HubApi->Release (UsbIf);
475 }
else if (UsbIf->IsManaged) {
484 DEBUG ((DEBUG_INFO,
"UsbDisconnectDriver: old TPL is %d, %p\n", (UINT32)OldTpl, UsbIf->Handle));
486 gBS->RestoreTPL (TPL_CALLBACK);
488 Status =
gBS->DisconnectController (UsbIf->Handle,
NULL,
NULL);
489 if (!EFI_ERROR (Status)) {
490 UsbIf->IsManaged =
FALSE;
493 DEBUG ((DEBUG_INFO,
"UsbDisconnectDriver: TPL after disconnect is %d, %d\n", (UINT32)
UsbGetCurrentTpl (), Status));
496 gBS->RaiseTPL (OldTpl);
522 for (Index = 0; Index < Device->NumOfInterface; Index++) {
523 ASSERT (Index < USB_MAX_INTERFACE);
524 UsbIf = Device->Interfaces[Index];
531 if (!EFI_ERROR (Status)) {
533 if (EFI_ERROR (Status)) {
538 if (!EFI_ERROR (Status)) {
539 Device->Interfaces[Index] =
NULL;
541 ReturnStatus = Status;
545 Device->ActiveConfig =
NULL;
575 for (Index = 1; Index < Bus->MaxDevices; Index++) {
576 Child = Bus->Devices[Index];
584 if (!EFI_ERROR (Status)) {
585 Bus->Devices[Index] =
NULL;
587 Bus->Devices[Index]->DisconnectFail =
TRUE;
588 ReturnStatus = Status;
589 DEBUG ((DEBUG_INFO,
"UsbRemoveDevice: failed to remove child %p at parent %p\n",
Child, Device));
593 if (EFI_ERROR (ReturnStatus)) {
599 if (!EFI_ERROR (Status)) {
600 DEBUG ((DEBUG_INFO,
"UsbRemoveDevice: device %d removed\n", Device->Address));
602 ASSERT (Device->Address < Bus->MaxDevices);
603 Bus->Devices[Device->Address] =
NULL;
606 Bus->Devices[Device->Address]->DisconnectFail =
TRUE;
631 Bus = HubIf->Device->Bus;
636 for (Index = 1; Index < Bus->MaxDevices; Index++) {
637 Device = Bus->Devices[Index];
639 if ((Device !=
NULL) && (Device->ParentAddr == HubIf->Device->Address) &&
640 (Device->ParentPort == Port))
665 IN BOOLEAN ResetIsNeeded
677 Parent = HubIf->Device;
679 HubApi = HubIf->HubApi;
680 Address = Bus->MaxDevices;
682 gBS->Stall (USB_WAIT_PORT_STABLE_STALL);
691 Status = HubApi->ResetPort (HubIf, Port);
692 if (EFI_ERROR (Status)) {
693 DEBUG ((DEBUG_ERROR,
"UsbEnumerateNewDev: failed to reset port %d - %r\n", Port, Status));
698 DEBUG ((DEBUG_INFO,
"UsbEnumerateNewDev: hub port %d is reset\n", Port));
700 DEBUG ((DEBUG_INFO,
"UsbEnumerateNewDev: hub port %d reset is skipped\n", Port));
706 return EFI_OUT_OF_RESOURCES;
713 Status = HubApi->GetPortStatus (HubIf, Port, &PortState);
715 if (EFI_ERROR (Status)) {
716 DEBUG ((DEBUG_ERROR,
"UsbEnumerateNewDev: failed to get speed of port %d\n", Port));
721 DEBUG ((DEBUG_ERROR,
"UsbEnumerateNewDev: No device present at port %d\n", Port));
722 Status = EFI_NOT_FOUND;
724 }
else if (USB_BIT_IS_SET (PortState.
PortStatus, USB_PORT_STAT_SUPER_SPEED)) {
726 Child->MaxPacket0 = 512;
727 }
else if (USB_BIT_IS_SET (PortState.
PortStatus, USB_PORT_STAT_HIGH_SPEED)) {
728 Child->Speed = EFI_USB_SPEED_HIGH;
729 Child->MaxPacket0 = 64;
730 }
else if (USB_BIT_IS_SET (PortState.
PortStatus, USB_PORT_STAT_LOW_SPEED)) {
731 Child->Speed = EFI_USB_SPEED_LOW;
732 Child->MaxPacket0 = 8;
734 Child->Speed = EFI_USB_SPEED_FULL;
735 Child->MaxPacket0 = 8;
738 DEBUG ((DEBUG_INFO,
"UsbEnumerateNewDev: device is of %d speed\n",
Child->Speed));
740 if (((
Child->Speed == EFI_USB_SPEED_LOW) || (
Child->Speed == EFI_USB_SPEED_FULL)) &&
741 (Parent->Speed == EFI_USB_SPEED_HIGH))
750 Child->Translator.TranslatorHubAddress = Parent->Address;
751 Child->Translator.TranslatorPortNumber = (UINT8)(Port + 1);
753 Child->Translator = Parent->Translator;
758 "UsbEnumerateNewDev: device uses translator (%d, %d)\n",
759 Child->Translator.TranslatorHubAddress,
760 Child->Translator.TranslatorPortNumber
775 ASSERT (Bus->MaxDevices <= 256);
776 for (Address = 1; Address < Bus->MaxDevices; Address++) {
777 if (Bus->Devices[Address] ==
NULL) {
782 if (Address >= Bus->MaxDevices) {
783 DEBUG ((DEBUG_ERROR,
"UsbEnumerateNewDev: address pool is full for port %d\n", Port));
785 Status = EFI_ACCESS_DENIED;
790 Child->Address = (UINT8)Address;
791 Bus->Devices[Address] =
Child;
793 if (EFI_ERROR (Status)) {
794 DEBUG ((DEBUG_ERROR,
"UsbEnumerateNewDev: failed to set device address - %r\n", Status));
798 gBS->Stall (USB_SET_DEVICE_ADDRESS_STALL);
800 DEBUG ((DEBUG_INFO,
"UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address));
808 if (EFI_ERROR (Status)) {
809 DEBUG ((DEBUG_ERROR,
"UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status));
813 DEBUG ((DEBUG_INFO,
"UsbEnumerateNewDev: max packet size for EP 0 is %d\n",
Child->MaxPacket0));
821 if (EFI_ERROR (Status)) {
822 DEBUG ((DEBUG_ERROR,
"UsbEnumerateNewDev: failed to build descriptor table - %r\n", Status));
830 Config =
Child->DevDesc->Configs[0]->Desc.ConfigurationValue;
833 if (EFI_ERROR (Status)) {
834 DEBUG ((DEBUG_ERROR,
"UsbEnumerateNewDev: failed to set configure %d - %r\n", Config, Status));
838 DEBUG ((DEBUG_INFO,
"UsbEnumerateNewDev: device %d is now in CONFIGED state\n", Address));
845 if (EFI_ERROR (Status)) {
846 DEBUG ((DEBUG_ERROR,
"UsbEnumerateNewDev: failed to create interfaces - %r\n", Status));
855 (EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG),
901 HubApi = HubIf->HubApi;
906 Status = HubApi->GetPortStatus (HubIf, Port, &PortState);
908 if (EFI_ERROR (Status)) {
909 DEBUG ((DEBUG_ERROR,
"UsbEnumeratePort: failed to get state of port %d\n", Port));
923 "UsbEnumeratePort: port %d state - %02x, change - %02x on %p\n",
936 if (USB_BIT_IS_SET (PortState.
PortChangeStatus, USB_PORT_STAT_C_OVERCURRENT)) {
937 if (USB_BIT_IS_SET (PortState.
PortStatus, USB_PORT_STAT_OVERCURRENT)) {
944 DEBUG ((DEBUG_ERROR,
"UsbEnumeratePort: Critical Over Current (port %d)\n", Port));
945 return EFI_DEVICE_ERROR;
954 DEBUG ((DEBUG_ERROR,
"UsbEnumeratePort: 2.0 device Recovery Over Current (port %d)\n", Port));
964 DEBUG ((DEBUG_ERROR,
"UsbEnumeratePort: 1.1 device Recovery Over Current (port %d)\n", Port));
972 DEBUG ((DEBUG_INFO,
"UsbEnumeratePort: Device Connect/Disconnect Normally (port %d)\n", Port));
981 DEBUG ((DEBUG_INFO,
"UsbEnumeratePort: device at port %d removed from root hub %p\n", Port, HubIf));
989 DEBUG ((DEBUG_INFO,
"UsbEnumeratePort: new device connected at port %d\n", Port));
996 DEBUG ((DEBUG_INFO,
"UsbEnumeratePort: device disconnected event on port %d\n", Port));
999 HubApi->ClearPortChange (HubIf, Port);
1023 ASSERT (Context !=
NULL);
1027 for (Index = 0; Index < HubIf->NumOfPort; Index++) {
1030 DEBUG ((DEBUG_INFO,
"UsbEnumeratePort: The device disconnect fails at port %d from hub %p, try again\n", Index, HubIf));
1035 if (HubIf->ChangeMap ==
NULL) {
1045 for (Index = 0; Index < HubIf->NumOfPort; Index++) {
1046 if (USB_BIT_IS_SET (HubIf->ChangeMap[Byte], USB_BIT (Bit))) {
1050 USB_NEXT_BIT (Byte, Bit);
1055 gBS->FreePool (HubIf->ChangeMap);
1056 HubIf->ChangeMap =
NULL;
1080 for (Index = 0; Index < RootHub->NumOfPort; Index++) {
1083 DEBUG ((DEBUG_INFO,
"UsbEnumeratePort: The device disconnect fails at port %d from root hub %p, try again\n", Index, RootHub));
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
NODE Child(IN NODE LoopVar6, IN UINT8 LoopVar5)
#define MESSAGING_DEVICE_PATH
UINT16 EFIAPI SetDevicePathNodeLength(IN OUT VOID *Node, IN UINTN Length)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define DEBUG(Expression)
#define REPORT_STATUS_CODE_WITH_DEVICE_PATH(Type, Value, DevicePathParameter)
#define USB_PORT_STAT_C_CONNECTION
#define EFI_USB_SPEED_SUPER
4.8 Gb/s, USB 3.0 XHCI HC.
#define USB_PORT_STAT_CONNECTION
#define EFI_PROGRESS_CODE
BOOLEAN EFIAPI UsbBusIsWantedUsbIO(IN USB_BUS *Bus, IN USB_INTERFACE *UsbIf)
EFI_STATUS UsbBuildDescTable(IN USB_DEVICE *UsbDev)
EFI_STATUS UsbSetConfig(IN USB_DEVICE *UsbDev, IN UINT8 ConfigIndex)
EFI_STATUS UsbSetAddress(IN USB_DEVICE *UsbDev, IN UINT8 Address)
EFI_STATUS UsbGetMaxPacketSize0(IN USB_DEVICE *UsbDev)
VOID UsbFreeDevDesc(IN USB_DEVICE_DESC *DevDesc)
VOID UsbFreeDevice(IN USB_DEVICE *Device)
EFI_STATUS UsbSelectConfig(IN USB_DEVICE *Device, IN UINT8 ConfigValue)
EFI_STATUS UsbRemoveDevice(IN USB_DEVICE *Device)
EFI_STATUS UsbRemoveConfig(IN USB_DEVICE *Device)
EFI_STATUS UsbSelectSetting(IN USB_INTERFACE_DESC *IfDesc, IN UINT8 Alternate)
EFI_STATUS UsbDisconnectDriver(IN USB_INTERFACE *UsbIf)
USB_INTERFACE * UsbCreateInterface(IN USB_DEVICE *Device, IN USB_INTERFACE_DESC *IfDesc)
USB_ENDPOINT_DESC * UsbGetEndpointDesc(IN USB_INTERFACE *UsbIf, IN UINT8 EpAddr)
VOID EFIAPI UsbHubEnumeration(IN EFI_EVENT Event, IN VOID *Context)
USB_DEVICE * UsbCreateDevice(IN USB_INTERFACE *ParentIf, IN UINT8 ParentPort)
EFI_STATUS UsbEnumerateNewDev(IN USB_INTERFACE *HubIf, IN UINT8 Port, IN BOOLEAN ResetIsNeeded)
USB_DEVICE * UsbFindChild(IN USB_INTERFACE *HubIf, IN UINT8 Port)
EFI_STATUS UsbEnumeratePort(IN USB_INTERFACE *HubIf, IN UINT8 Port)
EFI_STATUS UsbConnectDriver(IN USB_INTERFACE *UsbIf)
EFI_STATUS UsbFreeInterface(IN USB_INTERFACE *UsbIf)
VOID EFIAPI UsbRootHubEnumeration(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS UsbHubAckHubStatus(IN USB_DEVICE *HubDev)
BOOLEAN UsbIsHubInterface(IN USB_INTERFACE *UsbIf)
EFI_STATUS UsbOpenHostProtoByChild(IN USB_BUS *Bus, IN EFI_HANDLE Child)
EFI_TPL UsbGetCurrentTpl(VOID)
VOID UsbCloseHostProtoByChild(IN USB_BUS *Bus, IN EFI_HANDLE Child)
UINT16 PortChangeStatus
Contains current port status change bitmap.
UINT16 PortStatus
Contains current port status bitmap.