3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
26 UINTN gUSBDebugLevel
= EFI_D_INFO
;
27 UINTN gUSBErrorLevel
= EFI_D_ERROR
;
30 // The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER
31 // structure in the UsbBusDriverControllerDriverStop(). Then we can
32 // Close all opened protocols and release this structure.
34 STATIC EFI_GUID mUsbBusProtocolGuid
= EFI_USB_BUS_PROTOCOL_GUID
;
39 // EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
43 UsbBusControllerDriverSupported (
44 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
45 IN EFI_HANDLE Controller
,
46 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
51 UsbBusControllerDriverStart (
52 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
53 IN EFI_HANDLE Controller
,
54 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
59 UsbBusControllerDriverStop (
60 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
61 IN EFI_HANDLE Controller
,
62 IN UINTN NumberOfChildren
,
63 IN EFI_HANDLE
*ChildHandleBuffer
66 EFI_DRIVER_BINDING_PROTOCOL gUsbBusDriverBinding
= {
67 UsbBusControllerDriverSupported
,
68 UsbBusControllerDriverStart
,
69 UsbBusControllerDriverStop
,
81 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
82 IN EFI_STATUS_CODE_TYPE Type
,
83 IN EFI_STATUS_CODE_VALUE Code
90 InitializeUsbIoInstance (
91 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
95 USB_IO_CONTROLLER_DEVICE
*
96 CreateUsbIoControllerDevice (
102 InitUsbIoController (
103 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
107 // USB Device Configuration / Deconfiguration
111 UsbDeviceConfiguration (
112 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
113 IN EFI_HANDLE HostController
,
115 IN USB_IO_DEVICE
*UsbIoDevice
119 // Usb Bus enumeration function
137 UsbSetTransactionTranslator (
138 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
140 IN OUT USB_IO_DEVICE
*Device
145 UsbUnsetTransactionTranslator (
146 USB_IO_DEVICE
*Device
151 IdentifyDeviceSpeed (
152 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
153 USB_IO_DEVICE
*NewDevice
,
160 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
166 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
173 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
180 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
181 IN BOOLEAN ReConfigure
,
186 // Following are address allocate and free functions
191 IN UINT8
*AddressPool
196 Allocate address for usb device
199 AddressPool - Pool of usb device address
209 for (ByteIndex
= 0; ByteIndex
< 16; ByteIndex
++) {
210 for (BitIndex
= 0; BitIndex
< 8; BitIndex
++) {
211 if ((AddressPool
[ByteIndex
] & (1 << BitIndex
)) == 0) {
213 // Found one, covert to address, and mark it use
215 AddressPool
[ByteIndex
] |= (1 << BitIndex
);
216 return (UINT8
) (ByteIndex
* 8 + BitIndex
);
229 IN UINT8
*AddressPool
234 Free address for usb device
237 DevAddress - Usb device address
238 AddressPool - Pool of usb device address
248 // Locate the position
250 WhichByte
= (UINT8
) (DevAddress
/ 8);
251 WhichBit
= (UINT8
) (DevAddress
& 0x7);
253 AddressPool
[WhichByte
] &= (~(1 << WhichBit
));
258 UsbBusControllerDriverSupported (
259 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
260 IN EFI_HANDLE Controller
,
261 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
266 Test to see if this driver supports ControllerHandle. Any ControllerHandle
267 that has UsbHcProtocol installed will be supported.
270 This - Protocol instance pointer.
271 Controller - Handle of device to test
272 RemainingDevicePath - Device Path Protocol instance pointer
275 EFI_SUCCESS - This driver supports this device.
276 EFI_UNSUPPORTED - This driver does not support this device.
281 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
282 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
283 EFI_USB_HC_PROTOCOL
*UsbHc
;
284 EFI_DEV_PATH_PTR Node
;
289 if (RemainingDevicePath
!= NULL
) {
290 Node
.DevPath
= RemainingDevicePath
;
291 if (Node
.DevPath
->Type
!= MESSAGING_DEVICE_PATH
||
292 Node
.DevPath
->SubType
!= MSG_USB_DP
||
293 DevicePathNodeLength(Node
.DevPath
) != sizeof(USB_DEVICE_PATH
)) {
294 return EFI_UNSUPPORTED
;
299 // Open the IO Abstraction(s) needed to perform the supported test
301 Status
= gBS
->OpenProtocol (
303 &gEfiDevicePathProtocolGuid
,
304 (VOID
**) &ParentDevicePath
,
305 This
->DriverBindingHandle
,
307 EFI_OPEN_PROTOCOL_BY_DRIVER
309 if (Status
== EFI_ALREADY_STARTED
) {
313 if (EFI_ERROR (Status
)) {
319 &gEfiDevicePathProtocolGuid
,
320 This
->DriverBindingHandle
,
325 // Check whether USB Host Controller Protocol is already
326 // installed on this handle. If it is installed, we can start
327 // USB Bus Driver now.
329 Status
= gBS
->OpenProtocol (
331 &gEfiUsb2HcProtocolGuid
,
333 This
->DriverBindingHandle
,
335 EFI_OPEN_PROTOCOL_BY_DRIVER
337 if (Status
== EFI_ALREADY_STARTED
) {
341 if (EFI_ERROR (Status
)) {
342 Status
= gBS
->OpenProtocol (
344 &gEfiUsbHcProtocolGuid
,
346 This
->DriverBindingHandle
,
348 EFI_OPEN_PROTOCOL_BY_DRIVER
350 if (Status
== EFI_ALREADY_STARTED
) {
354 if (EFI_ERROR (Status
)) {
360 &gEfiUsbHcProtocolGuid
,
361 This
->DriverBindingHandle
,
369 &gEfiUsb2HcProtocolGuid
,
370 This
->DriverBindingHandle
,
379 UsbBusControllerDriverStart (
380 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
381 IN EFI_HANDLE Controller
,
382 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
388 Starting the Usb Bus Driver
392 This - Protocol instance pointer.
393 Controller - Handle of device to test
394 RemainingDevicePath - Not used
398 EFI_SUCCESS - This driver supports this device.
399 EFI_DEVICE_ERROR - This driver cannot be started due to device
400 EFI_OUT_OF_RESOURCES- Can't allocate memory resources
405 EFI_STATUS OpenStatus
;
406 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
407 USB_IO_DEVICE
*RootHub
;
408 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
411 UINT8 Is64BitCapable
;
414 // Allocate USB_BUS_CONTROLLER_DEVICE structure
417 UsbBusDev
= AllocateZeroPool (sizeof (USB_BUS_CONTROLLER_DEVICE
));
418 if (UsbBusDev
== NULL
) {
419 return EFI_OUT_OF_RESOURCES
;
422 UsbBusDev
->Signature
= USB_BUS_DEVICE_SIGNATURE
;
423 UsbBusDev
->AddressPool
[0] = 1;
426 // Get the Device Path Protocol on Controller's handle
428 OpenStatus
= gBS
->OpenProtocol (
430 &gEfiDevicePathProtocolGuid
,
431 (VOID
**) &UsbBusDev
->DevicePath
,
432 This
->DriverBindingHandle
,
434 EFI_OPEN_PROTOCOL_BY_DRIVER
437 if (EFI_ERROR (OpenStatus
)) {
438 gBS
->FreePool (UsbBusDev
);
442 // Locate the Host Controller Interface
444 OpenStatus
= gBS
->OpenProtocol (
446 &gEfiUsb2HcProtocolGuid
,
447 (VOID
**) &(UsbBusDev
->Usb2HCInterface
),
448 This
->DriverBindingHandle
,
450 EFI_OPEN_PROTOCOL_BY_DRIVER
452 if (EFI_ERROR (OpenStatus
)) {
454 UsbBusDev
->Hc2ProtocolSupported
= FALSE
;
455 OpenStatus
= gBS
->OpenProtocol (
457 &gEfiUsbHcProtocolGuid
,
458 (VOID
**) &(UsbBusDev
->UsbHCInterface
),
459 This
->DriverBindingHandle
,
461 EFI_OPEN_PROTOCOL_BY_DRIVER
463 if (EFI_ERROR (OpenStatus
)) {
465 // Report Status Code here since we will reset the host controller
467 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
468 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
469 EFI_IO_BUS_USB
| EFI_IOB_EC_CONTROLLER_ERROR
,
470 UsbBusDev
->DevicePath
475 &gEfiDevicePathProtocolGuid
,
476 This
->DriverBindingHandle
,
479 gBS
->FreePool (UsbBusDev
);
483 DEBUG ((gUSBDebugLevel
, "UsbHcProtocol Opened.\n"));
485 DEBUG ((gUSBDebugLevel
, "Usb2HcProtocol Opened.\n"));
486 UsbBusDev
->Hc2ProtocolSupported
= TRUE
;
490 // Attach EFI_USB_BUS_PROTOCOL to controller handle,
491 // for locate UsbBusDev later
493 Status
= gBS
->InstallProtocolInterface (
495 &mUsbBusProtocolGuid
,
496 EFI_NATIVE_INTERFACE
,
497 &UsbBusDev
->BusIdentify
500 if (EFI_ERROR (Status
)) {
504 &gEfiDevicePathProtocolGuid
,
505 This
->DriverBindingHandle
,
508 if (UsbBusDev
->Hc2ProtocolSupported
) {
511 &gEfiUsb2HcProtocolGuid
,
512 This
->DriverBindingHandle
,
518 &gEfiUsbHcProtocolGuid
,
519 This
->DriverBindingHandle
,
524 gBS
->FreePool (UsbBusDev
);
528 // Add root hub to the tree
531 RootHub
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
532 if (RootHub
== NULL
) {
533 gBS
->UninstallProtocolInterface (
535 &mUsbBusProtocolGuid
,
536 &UsbBusDev
->BusIdentify
540 &gEfiDevicePathProtocolGuid
,
541 This
->DriverBindingHandle
,
544 if (UsbBusDev
->Hc2ProtocolSupported
) {
547 &gEfiUsb2HcProtocolGuid
,
548 This
->DriverBindingHandle
,
554 &gEfiUsbHcProtocolGuid
,
555 This
->DriverBindingHandle
,
560 gBS
->FreePool (UsbBusDev
);
561 return EFI_OUT_OF_RESOURCES
;
564 RootHub
->BusController
= UsbBusDev
;
565 RootHub
->DeviceAddress
= UsbAllocateAddress (UsbBusDev
->AddressPool
);
567 UsbBusDev
->Root
= RootHub
;
570 // Allocate Root Hub Controller
572 RootHubController
= CreateUsbIoControllerDevice ();
573 if (RootHubController
== NULL
) {
574 gBS
->UninstallProtocolInterface (
576 &mUsbBusProtocolGuid
,
577 &UsbBusDev
->BusIdentify
581 &gEfiDevicePathProtocolGuid
,
582 This
->DriverBindingHandle
,
585 if (UsbBusDev
->Hc2ProtocolSupported
) {
588 &gEfiUsb2HcProtocolGuid
,
589 This
->DriverBindingHandle
,
595 &gEfiUsbHcProtocolGuid
,
596 This
->DriverBindingHandle
,
600 gBS
->FreePool (UsbBusDev
);
601 gBS
->FreePool (RootHub
);
602 return EFI_OUT_OF_RESOURCES
;
605 UsbVirtualHcGetCapability (
611 RootHubController
->DownstreamPorts
= PortNumber
;
612 RootHubController
->UsbDevice
= RootHub
;
613 RootHubController
->IsUsbHub
= TRUE
;
614 RootHubController
->DevicePath
= UsbBusDev
->DevicePath
;
615 RootHubController
->HostController
= Controller
;
617 RootHub
->NumOfControllers
= 1;
618 RootHub
->UsbController
[0] = RootHubController
;
619 RootHub
->DeviceSpeed
= MaxSpeed
;
622 // Report Status Code here since we will reset the host controller
624 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
626 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
,
627 UsbBusDev
->DevicePath
631 // Reset USB Host Controller
635 EFI_USB_HC_RESET_GLOBAL
639 // Report Status Code while we are going to bring up the Host Controller
640 // and start bus enumeration
642 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
644 EFI_IO_BUS_USB
| EFI_IOB_PC_ENABLE
,
645 UsbBusDev
->DevicePath
649 // Start USB Host Controller
651 UsbVirtualHcSetState (
653 EfiUsbHcStateOperational
657 // Create a timer to query root ports periodically
659 Status
= gBS
->CreateEvent (
660 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
664 &RootHubController
->HubNotify
666 if (EFI_ERROR (Status
)) {
667 gBS
->UninstallProtocolInterface (
669 &mUsbBusProtocolGuid
,
670 &UsbBusDev
->BusIdentify
675 &gEfiDevicePathProtocolGuid
,
676 This
->DriverBindingHandle
,
680 if (UsbBusDev
->Hc2ProtocolSupported
) {
683 &gEfiUsb2HcProtocolGuid
,
684 This
->DriverBindingHandle
,
690 &gEfiUsbHcProtocolGuid
,
691 This
->DriverBindingHandle
,
696 gBS
->FreePool (RootHubController
);
697 gBS
->FreePool (RootHub
);
698 gBS
->FreePool (UsbBusDev
);
699 return EFI_OUT_OF_RESOURCES
;
703 // Before depending on the timer to check root ports periodically,
704 // here we should check them immediately for the first time, or
705 // there will be an interval between bus start and devices start.
707 gBS
->SignalEvent (RootHubController
->HubNotify
);
709 Status
= gBS
->SetTimer (
710 RootHubController
->HubNotify
,
714 if (EFI_ERROR (Status
)) {
715 gBS
->UninstallProtocolInterface (
717 &mUsbBusProtocolGuid
,
718 &UsbBusDev
->BusIdentify
723 &gEfiDevicePathProtocolGuid
,
724 This
->DriverBindingHandle
,
728 if (UsbBusDev
->Hc2ProtocolSupported
) {
731 &gEfiUsb2HcProtocolGuid
,
732 This
->DriverBindingHandle
,
738 &gEfiUsbHcProtocolGuid
,
739 This
->DriverBindingHandle
,
744 gBS
->CloseEvent (RootHubController
->HubNotify
);
745 gBS
->FreePool (RootHubController
);
746 gBS
->FreePool (RootHub
);
747 gBS
->FreePool (UsbBusDev
);
748 return EFI_DEVICE_ERROR
;
755 // Stop the bus controller
759 UsbBusControllerDriverStop (
760 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
761 IN EFI_HANDLE Controller
,
762 IN UINTN NumberOfChildren
,
763 IN EFI_HANDLE
*ChildHandleBuffer
768 Stop this driver on ControllerHandle. Support stoping any child handles
769 created by this driver.
772 This - Protocol instance pointer.
773 Controller - Handle of device to stop driver on
774 NumberOfChildren - Number of Children in the ChildHandleBuffer
775 ChildHandleBuffer - List of handles for the children we need to stop.
786 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
787 USB_BUS_CONTROLLER_DEVICE
*UsbBusController
;
788 EFI_USB_BUS_PROTOCOL
*UsbIdentifier
;
790 USB_IO_CONTROLLER_DEVICE
*UsbController
;
791 USB_IO_DEVICE
*UsbIoDevice
;
792 USB_IO_CONTROLLER_DEVICE
*HubController
;
794 EFI_USB_IO_PROTOCOL
*UsbIo
;
796 if (NumberOfChildren
> 0) {
798 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
799 Status
= gBS
->OpenProtocol (
800 ChildHandleBuffer
[Index
],
801 &gEfiUsbIoProtocolGuid
,
803 This
->DriverBindingHandle
,
805 EFI_OPEN_PROTOCOL_GET_PROTOCOL
807 if (EFI_ERROR (Status
)) {
809 // We are here since the handle passed in does not support
810 // UsbIo protocol. There are several reasons that will cause
812 // For combo device such as keyboard, it may have 2 devices
813 // in one, namely, keyboard and mouse. If we deconfigure one
814 // of them, the other will be freed at the same time. This will
815 // cause the status error. But this is the correct behavior.
816 // For hub device, if we deconfigure hub first, the other chile
817 // device will be disconnected also, this will also provide us
818 // a status error. Now we will only report EFI_SUCCESS since Uhc
819 // driver will be disconnected at the second time.(pls see
820 // CoreDisconnectController for details)
825 UsbController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (UsbIo
);
826 UsbIoDevice
= UsbController
->UsbDevice
;
827 HubController
= UsbController
->Parent
;
828 UsbDeviceDeConfiguration (UsbIoDevice
);
829 for (Index2
= 0; Index2
< HubController
->DownstreamPorts
; Index2
++) {
830 if (HubController
->Children
[Index2
] == UsbIoDevice
) {
831 HubController
->Children
[Index2
] = NULL
;
839 // Get the USB_BUS_CONTROLLER_DEVICE
841 Status
= gBS
->OpenProtocol (
843 &mUsbBusProtocolGuid
,
844 (VOID
**) &UsbIdentifier
,
845 This
->DriverBindingHandle
,
847 EFI_OPEN_PROTOCOL_GET_PROTOCOL
850 if (EFI_ERROR (Status
)) {
851 return EFI_DEVICE_ERROR
;
854 UsbBusController
= USB_BUS_CONTROLLER_DEVICE_FROM_THIS (UsbIdentifier
);
857 // Stop USB Host Controller
861 // Report Status Code here since we will reset the host controller
863 ReportUsbStatusCode (
866 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
869 UsbVirtualHcSetState (
875 // Deconfiguration all its devices
877 Root
= UsbBusController
->Root
;
878 RootHubController
= Root
->UsbController
[0];
880 gBS
->CloseEvent (RootHubController
->HubNotify
);
882 for (Index2
= 0; Index2
< RootHubController
->DownstreamPorts
; Index2
++) {
883 if (RootHubController
->Children
[Index2
]) {
884 UsbDeviceDeConfiguration (RootHubController
->Children
[Index2
]);
885 RootHubController
->Children
[Index2
] = NULL
;
889 gBS
->FreePool (RootHubController
);
890 gBS
->FreePool (Root
);
893 // Uninstall USB Bus Protocol
895 gBS
->UninstallProtocolInterface (
897 &mUsbBusProtocolGuid
,
898 &UsbBusController
->BusIdentify
902 // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL
903 // Opened by this Controller
905 if (UsbBusController
->Hc2ProtocolSupported
) {
908 &gEfiUsb2HcProtocolGuid
,
909 This
->DriverBindingHandle
,
915 &gEfiUsbHcProtocolGuid
,
916 This
->DriverBindingHandle
,
923 &gEfiDevicePathProtocolGuid
,
924 This
->DriverBindingHandle
,
928 gBS
->FreePool (UsbBusController
);
933 // USB Device Configuration
937 UsbDeviceConfiguration (
938 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
939 IN EFI_HANDLE HostController
,
941 IN USB_IO_DEVICE
*UsbIoDevice
946 Configurate a new device attached to the usb bus
949 ParentHubController - Parent Hub which this device is connected.
950 HostController - Host Controller handle
951 ParentPort - Parent Hub port which this device is connected.
952 UsbIoDevice - The device to be configured.
965 CHAR16
*StrManufacturer
;
967 CHAR16
*StrSerialNumber
;
968 EFI_USB_IO_PROTOCOL
*UsbIo
;
969 UINT8 NumOfInterface
;
970 USB_IO_CONTROLLER_DEVICE
*FirstController
;
971 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
972 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
974 UsbBusDev
= UsbIoDevice
->BusController
;
976 UsbSetTransactionTranslator (
983 // Since a USB device must have at least on interface,
984 // so create this instance first
986 FirstController
= CreateUsbIoControllerDevice ();
987 FirstController
->UsbDevice
= UsbIoDevice
;
988 UsbIoDevice
->UsbController
[0] = FirstController
;
989 FirstController
->InterfaceNumber
= 0;
990 FirstController
->ParentPort
= ParentPort
;
991 FirstController
->Parent
= ParentHubController
;
992 FirstController
->HostController
= HostController
;
994 InitializeUsbIoInstance (FirstController
);
996 DEBUG ((gUSBDebugLevel
, "Configuration Usb Device at 0x%x...\n", ParentPort
));
999 // Ensure we used the correctly USB I/O instance
1001 UsbIo
= &FirstController
->UsbIo
;
1003 ParentPortReset (FirstController
, FALSE
, 0);
1006 // First retrieve the 1st 8 bytes of
1007 // in order to get the MaxPacketSize for Endpoint 0
1009 for (Index
= 0; Index
< 3; Index
++) {
1011 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1013 gBS
->Stall (100 * 1000);
1015 Result
= UsbGetDescriptor (
1017 (USB_DT_DEVICE
<< 8),
1020 &UsbIoDevice
->DeviceDescriptor
,
1023 if (!EFI_ERROR (Result
)) {
1026 "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
1027 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
)
1035 ReportUsbStatusCode (
1037 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1038 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1040 DEBUG ((gUSBErrorLevel
, "Get Device Descriptor Fail when configing\n"));
1041 gBS
->FreePool (FirstController
);
1042 return EFI_DEVICE_ERROR
;
1045 DevAddress
= UsbAllocateAddress (UsbIoDevice
->BusController
->AddressPool
);
1046 if (DevAddress
== 0) {
1047 DEBUG ((gUSBErrorLevel
, "Cannot allocate address\n"));
1048 gBS
->FreePool (FirstController
);
1049 return EFI_OUT_OF_RESOURCES
;
1052 Result
= UsbSetDeviceAddress (UsbIo
, DevAddress
, &Status
);
1054 if (EFI_ERROR (Result
)) {
1055 DEBUG ((gUSBErrorLevel
, "Set address error\n"));
1056 ReportUsbStatusCode (
1058 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1059 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1064 UsbIoDevice
->BusController
->AddressPool
1067 gBS
->FreePool (FirstController
);
1068 return EFI_DEVICE_ERROR
;
1071 UsbIoDevice
->DeviceAddress
= DevAddress
;
1074 // SetAddress Complete Time by Spec, Max 50ms
1076 gBS
->Stall (10 * 1000);
1079 // Get the whole device descriptor
1081 Result
= UsbGetDescriptor (
1083 (USB_DT_DEVICE
<< 8),
1085 sizeof (EFI_USB_DEVICE_DESCRIPTOR
),
1086 &UsbIoDevice
->DeviceDescriptor
,
1090 if (EFI_ERROR (Result
)) {
1091 DEBUG ((gUSBErrorLevel
, "Get whole Device Descriptor error\n"));
1092 ReportUsbStatusCode (
1094 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1095 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1099 UsbIoDevice
->BusController
->AddressPool
1102 gBS
->FreePool (FirstController
);
1103 return EFI_DEVICE_ERROR
;
1106 // Get & parse all configurations for this device, including
1107 // all configuration descriptors, all interface descriptors, all
1108 // endpoint descriptors
1110 Result
= UsbGetAllConfigurations (UsbIoDevice
);
1112 if (EFI_ERROR (Result
)) {
1113 DEBUG ((gUSBErrorLevel
, "Failed to get device configuration\n"));
1114 ReportUsbStatusCode (
1116 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1117 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1121 UsbIoDevice
->BusController
->AddressPool
1124 gBS
->FreePool (FirstController
);
1125 return EFI_DEVICE_ERROR
;
1128 // Set the 1st configuration value
1130 Result
= UsbSetDefaultConfiguration (UsbIoDevice
);
1131 if (EFI_ERROR (Result
)) {
1132 DEBUG ((gUSBErrorLevel
, "Failed to set device configuration\n"));
1133 ReportUsbStatusCode (
1135 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1136 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1140 UsbIoDevice
->BusController
->AddressPool
1143 gBS
->FreePool (FirstController
);
1144 return EFI_DEVICE_ERROR
;
1147 UsbIoDevice
->IsConfigured
= TRUE
;
1150 // Get all string table if applicable
1152 Result
= UsbGetStringtable (UsbIoDevice
);
1153 if (EFI_ERROR (Result
)) {
1154 DEBUG ((gUSBDebugLevel
, "Device doesn't support string table\n"));
1157 StrManufacturer
= NULL
;
1158 UsbIo
->UsbGetStringDescriptor (
1160 UsbIoDevice
->LangID
[0],
1161 (UsbIoDevice
->DeviceDescriptor
).StrManufacturer
,
1166 UsbIo
->UsbGetStringDescriptor (
1168 UsbIoDevice
->LangID
[0],
1169 (UsbIoDevice
->DeviceDescriptor
).StrProduct
,
1173 StrSerialNumber
= NULL
;
1174 UsbIo
->UsbGetStringDescriptor (
1176 UsbIoDevice
->LangID
[0],
1177 (UsbIoDevice
->DeviceDescriptor
).StrSerialNumber
,
1181 if (StrManufacturer
) {
1182 gBS
->FreePool (StrManufacturer
);
1186 gBS
->FreePool (StrProduct
);
1189 if (StrSerialNumber
) {
1190 gBS
->FreePool (StrSerialNumber
);
1194 // Create USB_IO_CONTROLLER_DEVICE for
1195 // each detected interface
1197 FirstController
->CurrentConfigValue
=
1198 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1201 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.NumInterfaces
;
1202 UsbIoDevice
->NumOfControllers
= NumOfInterface
;
1204 Result
= InitUsbIoController (FirstController
);
1205 if (EFI_ERROR (Result
)) {
1206 ReportUsbStatusCode (
1208 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1209 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1211 gBS
->FreePool (FirstController
);
1212 UsbIoDevice
->UsbController
[0] = NULL
;
1213 return EFI_DEVICE_ERROR
;
1216 for (Index
= 1; Index
< NumOfInterface
; Index
++) {
1217 UsbIoController
= CreateUsbIoControllerDevice ();
1218 UsbIoController
->UsbDevice
= UsbIoDevice
;
1219 UsbIoController
->CurrentConfigValue
=
1220 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1221 UsbIoController
->InterfaceNumber
= Index
;
1222 UsbIoDevice
->UsbController
[Index
] = UsbIoController
;
1223 UsbIoController
->ParentPort
= ParentPort
;
1224 UsbIoController
->Parent
= ParentHubController
;
1225 UsbIoController
->HostController
= HostController
;
1228 // First copy the USB_IO Protocol instance
1231 &UsbIoController
->UsbIo
,
1233 sizeof (EFI_USB_IO_PROTOCOL
)
1236 Result
= InitUsbIoController (UsbIoController
);
1237 if (EFI_ERROR (Result
)) {
1238 ReportUsbStatusCode (
1240 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1241 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1243 gBS
->FreePool (UsbIoController
);
1244 UsbIoDevice
->UsbController
[Index
] = NULL
;
1251 // USB Device DeConfiguration
1254 UsbDeviceDeConfiguration (
1255 IN USB_IO_DEVICE
*UsbIoDevice
1259 Routine Description:
1260 Remove Device, Device Handles, Uninstall Protocols.
1263 UsbIoDevice - The device to be deconfigured.
1271 USB_IO_CONTROLLER_DEVICE
*UsbController
;
1273 USB_IO_DEVICE
*ChildDevice
;
1275 EFI_USB_IO_PROTOCOL
*UsbIo
;
1278 // Double check UsbIoDevice exists
1280 if (UsbIoDevice
== NULL
) {
1284 UsbUnsetTransactionTranslator (UsbIoDevice
);
1286 for (index
= 0; index
< UsbIoDevice
->NumOfControllers
; index
++) {
1288 // Check if it is a hub, if so, de configuration all its
1291 UsbController
= UsbIoDevice
->UsbController
[index
];
1294 // Check the controller pointer
1296 if (UsbController
== NULL
) {
1300 if (UsbController
->IsUsbHub
) {
1302 DEBUG ((gUSBDebugLevel
, "Hub Deconfig, First Deconfig its downstream ports\n"));
1305 // First Remove interrupt transfer request for the status
1308 UsbIo
= &UsbController
->UsbIo
;
1309 UsbIo
->UsbAsyncInterruptTransfer (
1311 UsbController
->HubEndpointAddress
,
1319 if (NULL
!= UsbController
->HubNotify
) {
1320 gBS
->CloseEvent (UsbController
->HubNotify
);
1323 for (Index
= 0; Index
< UsbController
->DownstreamPorts
; Index
++) {
1324 if (UsbController
->Children
[Index
]) {
1325 ChildDevice
= UsbController
->Children
[Index
];
1326 UsbDeviceDeConfiguration (ChildDevice
);
1327 UsbController
->Children
[Index
] = NULL
;
1332 // If the controller is managed by a device driver, we need to
1335 if (UsbController
->IsManagedByDriver
) {
1336 gBS
->DisconnectController (
1337 UsbController
->Handle
,
1344 // remove child handle reference to the USB_HC_PROTOCOL
1346 if (UsbIoDevice
->BusController
->Hc2ProtocolSupported
) {
1347 gBS
->CloseProtocol (
1348 UsbController
->HostController
,
1349 &gEfiUsb2HcProtocolGuid
,
1350 gUsbBusDriverBinding
.DriverBindingHandle
,
1351 UsbController
->Handle
1354 gBS
->CloseProtocol (
1355 UsbController
->HostController
,
1356 &gEfiUsbHcProtocolGuid
,
1357 gUsbBusDriverBinding
.DriverBindingHandle
,
1358 UsbController
->Handle
1362 // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
1363 // installed on this handle
1365 gBS
->UninstallMultipleProtocolInterfaces (
1366 UsbController
->Handle
,
1367 &gEfiDevicePathProtocolGuid
,
1368 UsbController
->DevicePath
,
1369 &gEfiUsbIoProtocolGuid
,
1370 &UsbController
->UsbIo
,
1374 if (UsbController
->DevicePath
!= NULL
) {
1375 gBS
->FreePool (UsbController
->DevicePath
);
1378 gBS
->FreePool (UsbController
);
1379 UsbIoDevice
->UsbController
[index
] = NULL
;
1382 // Free address for later use
1385 UsbIoDevice
->DeviceAddress
,
1386 UsbIoDevice
->BusController
->AddressPool
1390 // Free all resouces allocated for all its configurations
1392 UsbDestroyAllConfiguration (UsbIoDevice
);
1395 gBS
->FreePool (UsbIoDevice
);
1402 // After interrupt complete, this function will be called,
1403 // This function need to be well-defined later
1408 OnHubInterruptComplete (
1410 IN UINTN DataLength
,
1416 Routine Description:
1417 Whenever hub interrupt occurs, this routine will be called to check
1418 which event happens.
1421 Data - Hub interrupt transfer data.
1422 DataLength - The length of the Data.
1423 Context - Hub Controller Device.
1424 Result - Hub interrupt transfer status.
1432 USB_IO_CONTROLLER_DEVICE
*HubController
;
1435 EFI_USB_IO_PROTOCOL
*UsbIo
;
1437 BOOLEAN Disconnected
;
1440 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1441 UsbIo
= &HubController
->UsbIo
;
1444 // If something error in this interrupt transfer,
1446 if (Result
!= EFI_USB_NOERROR
) {
1447 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1448 UsbClearEndpointHalt (
1450 HubController
->HubEndpointAddress
,
1456 // Delete & Submit this interrupt again
1458 UsbIo
->UsbAsyncInterruptTransfer (
1460 HubController
->HubEndpointAddress
,
1469 // try to detect if the hub itself was disconnected or not
1471 Status
= IsDeviceDisconnected (
1476 if (!EFI_ERROR (Status
) && Disconnected
== TRUE
) {
1477 DEBUG ((gUSBErrorLevel
, "Hub is disconnected\n"));
1478 return EFI_DEVICE_ERROR
;
1483 UsbIo
->UsbAsyncInterruptTransfer (
1485 HubController
->HubEndpointAddress
,
1489 OnHubInterruptComplete
,
1493 return EFI_DEVICE_ERROR
;
1496 if (DataLength
== 0 || Data
== NULL
) {
1501 // Scan which port has status change
1502 // Bit 0 stands for hub itself, other bit stands for
1503 // the corresponding port
1505 for (Index
= 0; Index
< DataLength
* 8; Index
++) {
1506 ptr
= (UINT8
*) Data
+ Index
/ 8;
1507 if ((*ptr
) & (1 << (Index
& 0x7))) {
1508 HubController
->StatusChangePort
= Index
;
1513 // Signal hub notify event
1515 gBS
->SignalEvent (HubController
->HubNotify
);
1520 // USB Root Hub Enumerator
1525 RootHubEnumeration (
1531 Routine Description:
1533 This is USB RootHub enumerator
1537 Event - Indicating which event is signaled
1538 Context - actually it is a USB_IO_DEVICE
1546 USB_IO_CONTROLLER_DEVICE
*HubController
;
1547 EFI_USB_PORT_STATUS HubPortStatus
;
1550 USB_IO_DEVICE
*UsbIoDev
;
1551 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1552 EFI_HANDLE HostController
;
1553 USB_IO_DEVICE
*OldUsbIoDevice
;
1554 USB_IO_DEVICE
*NewDevice
;
1555 USB_IO_CONTROLLER_DEVICE
*NewController
;
1557 EFI_USB_IO_PROTOCOL
*UsbIo
;
1559 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1560 HostController
= HubController
->HostController
;
1561 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1564 // Root hub has the address 1
1566 UsbIoDev
= HubController
->UsbDevice
;
1568 for (Index
= 0; Index
< HubController
->DownstreamPorts
; Index
++) {
1570 UsbVirtualHcGetRootHubPortStatus (
1573 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1576 if (!IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1580 // Clear root hub status change status
1582 UsbVirtualHcClearRootHubPortFeature (
1585 EfiUsbPortConnectChange
1588 gBS
->Stall (100 * 1000);
1590 UsbVirtualHcGetRootHubPortStatus (
1593 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1596 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1599 // There is something connected to this port
1601 DEBUG ((gUSBDebugLevel
, "Something connected to Root Hub at Port0x%x\n", Index
));
1603 ReportUsbStatusCode (
1606 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1609 // if there is something physically detached, but still logically
1612 OldUsbIoDevice
= HubController
->Children
[Index
];
1614 if (NULL
!= OldUsbIoDevice
) {
1615 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1616 HubController
->Children
[Index
] = NULL
;
1619 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1620 if (NewDevice
== NULL
) {
1624 // Initialize some fields by copying data from
1627 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1628 NewDevice
->BusController
= UsbIoDev
->BusController
;
1631 // Process of identify device speed
1633 Status
= IdentifyDeviceSpeed (
1638 if (EFI_ERROR (Status
)) {
1639 gBS
->FreePool (NewDevice
);
1644 // Configure that device
1646 Status
= UsbDeviceConfiguration (
1652 if (EFI_ERROR (Status
)) {
1653 gBS
->FreePool (NewDevice
);
1657 // Add this device to the usb bus tree
1659 HubController
->Children
[Index
] = NewDevice
;
1661 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
1663 // If this device is hub, add to the hub index
1665 NewController
= NewDevice
->UsbController
[Index2
];
1667 Status
= gBS
->ConnectController (
1668 NewController
->Handle
,
1674 // If connect success, we need to disconnect when
1675 // stop the controller, otherwise we need not call
1676 // gBS->DisconnectController ()
1677 // This is used by those usb devices we don't plan
1678 // to support. We can allocate
1679 // controller handles for them, but we don't have
1680 // device drivers to manage them.
1682 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
1684 if (IsHub (NewController
)) {
1686 NewController
->IsUsbHub
= TRUE
;
1689 // Configure Hub Controller
1691 Status
= DoHubConfig (NewController
);
1692 if (EFI_ERROR (Status
)) {
1696 // Create an event to do hub enumeration
1699 EFI_EVENT_NOTIFY_SIGNAL
,
1703 &NewController
->HubNotify
1707 // Add request to do query hub status
1711 UsbIo
= &NewController
->UsbIo
;
1712 UsbIo
->UsbAsyncInterruptTransfer (
1714 NewController
->HubEndpointAddress
,
1718 OnHubInterruptComplete
,
1726 // Something disconnected from USB root hub
1728 DEBUG ((gUSBDebugLevel
, "Something disconnected from Root Hub at Port0x%x\n", Index
));
1730 OldUsbIoDevice
= HubController
->Children
[Index
];
1732 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1734 HubController
->Children
[Index
] = NULL
;
1736 UsbVirtualHcClearRootHubPortFeature (
1739 EfiUsbPortEnableChange
1747 // USB Root Hub Enumerator
1758 Routine Description:
1760 This is Usb Hub enumerator
1764 Event - Indicating which event is signaled
1765 Context - actually it is a USB_IO_DEVICE
1773 USB_IO_CONTROLLER_DEVICE
*HubController
;
1774 EFI_USB_PORT_STATUS HubPortStatus
;
1776 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1777 EFI_HANDLE HostController
;
1778 USB_IO_DEVICE
*OldUsbIoDevice
;
1779 USB_IO_DEVICE
*NewDevice
;
1780 USB_IO_CONTROLLER_DEVICE
*NewController
;
1782 EFI_USB_IO_PROTOCOL
*UsbIo
;
1783 UINT8 StatusChangePort
;
1786 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1787 HostController
= HubController
->HostController
;
1788 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1791 // Event from Hub, Get the hub controller handle
1794 // Get the status change endpoint
1796 StatusChangePort
= HubController
->StatusChangePort
;
1799 // Clear HubController Status Change Bit
1801 HubController
->StatusChangePort
= 0;
1803 if (StatusChangePort
== 0) {
1805 // Hub changes, we don't handle here
1810 // Check which event took place at that port
1812 UsbIo
= &HubController
->UsbIo
;
1813 Status
= HubGetPortStatus (
1816 (UINT32
*) &HubPortStatus
1819 if (EFI_ERROR (Status
)) {
1823 // Clear some change status
1825 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
1827 // Clear Hub port enable change
1829 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
1830 HubClearPortFeature (
1833 EfiUsbPortEnableChange
1839 (UINT32
*) &HubPortStatus
1843 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
1845 // Clear Hub reset change
1847 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
1848 HubClearPortFeature (
1851 EfiUsbPortResetChange
1857 (UINT32
*) &HubPortStatus
1861 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_OVERCURRENT
) {
1863 // Clear Hub overcurrent change
1865 DEBUG ((gUSBDebugLevel
, "Port Overcurrent Change\n"));
1866 HubClearPortFeature (
1869 EfiUsbPortOverCurrentChange
1875 (UINT32
*) &HubPortStatus
1879 if (IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1881 // First clear port connection change
1883 DEBUG ((gUSBDebugLevel
, "Port Connection Change\n"));
1884 HubClearPortFeature (
1887 EfiUsbPortConnectChange
1893 (UINT32
*) &HubPortStatus
1896 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1898 DEBUG ((gUSBDebugLevel
, "New Device Connect on Hub port \n"));
1900 ReportUsbStatusCode (
1903 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1907 // if there is something physically detached, but still logically
1910 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
1912 if (NULL
!= OldUsbIoDevice
) {
1913 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1914 HubController
->Children
[StatusChangePort
- 1] = NULL
;
1917 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1918 if (NewDevice
== NULL
) {
1922 // Initialize some fields
1924 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1925 NewDevice
->BusController
= HubController
->UsbDevice
->BusController
;
1928 // There is something connected to this port,
1931 // Disable the enable bit in port status
1933 HubClearPortFeature (
1939 gBS
->Stall (50 * 1000);
1942 // Wait for bit change
1949 (UINT32
*) &HubPortStatus
1951 gBS
->Stall (10 * 1000);
1953 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_ENABLE
) == 1 && Number
> 0);
1957 // Cannot disable port, return error
1959 DEBUG ((gUSBErrorLevel
, "Disable Port Failed\n"));
1960 gBS
->FreePool (NewDevice
);
1970 gBS
->Stall (50 * 1000);
1973 // Wait for port reset complete
1980 (UINT32
*) &HubPortStatus
1982 gBS
->Stall (10 * 1000);
1984 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_RESET
) == 1 && Number
> 0);
1988 // Cannot reset port, return error
1990 DEBUG ((gUSBErrorLevel
, "Reset Port Failed\n"));
1991 gBS
->FreePool (NewDevice
);
1995 // Check high speed or full speed device
1997 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
1998 DEBUG ((gUSBDebugLevel
, "Low Speed Device Attached to Hub\n"));
1999 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
2000 } else if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2001 DEBUG ((gUSBDebugLevel
, "High Speed Device Attached to Hub\n"));
2002 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2004 DEBUG ((gUSBDebugLevel
, "Full Speed Device Attached to Hub\n"));
2005 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2008 // Configure that device
2010 Status
= UsbDeviceConfiguration (
2013 (UINT8
) (StatusChangePort
- 1),
2017 if (EFI_ERROR (Status
)) {
2018 gBS
->FreePool (NewDevice
);
2022 // Add this device to the usb bus tree
2023 // StatusChangePort is begin from 1,
2025 HubController
->Children
[StatusChangePort
- 1] = NewDevice
;
2027 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
2029 // If this device is hub, add to the hub index
2031 NewController
= NewDevice
->UsbController
[Index2
];
2034 // Connect the controller to the driver image
2036 Status
= gBS
->ConnectController (
2037 NewController
->Handle
,
2043 // If connect success, we need to disconnect when
2044 // stop the controller, otherwise we need not call
2045 // gBS->DisconnectController ()
2046 // This is used by those usb devices we don't plan
2047 // to support. We can allocate
2048 // controller handles for them, but we don't have
2049 // device drivers to manage them.
2051 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
2054 // If this device is hub, add to the hub index
2056 if (IsHub (NewController
)) {
2058 NewController
->IsUsbHub
= TRUE
;
2063 Status
= DoHubConfig (NewController
);
2065 if (EFI_ERROR (Status
)) {
2069 // Create an event to do hub enumeration
2072 EFI_EVENT_NOTIFY_SIGNAL
,
2076 &NewController
->HubNotify
2080 // Add request to do query hub status
2083 UsbIo
= &NewController
->UsbIo
;
2084 UsbIo
->UsbAsyncInterruptTransfer (
2086 NewController
->HubEndpointAddress
, // Hub endpoint address
2090 OnHubInterruptComplete
,
2097 // Something disconnected from USB hub
2099 DEBUG ((gUSBDebugLevel
, "Something Device Detached on Hub port\n"));
2101 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
2103 UsbDeviceDeConfiguration (OldUsbIoDevice
);
2105 HubController
->Children
[StatusChangePort
- 1] = NULL
;
2116 USB_IO_CONTROLLER_DEVICE
*
2117 CreateUsbIoControllerDevice (
2122 Routine Description:
2123 Allocate a structure for USB_IO_CONTROLLER_DEVICE
2129 A pointer to a USB_IO_CONTROLLER_DEVICE structure,
2134 USB_IO_CONTROLLER_DEVICE
*UsbIoControllerDev
;
2137 // Allocate USB_IO_CONTROLLER_DEVICE structure
2139 UsbIoControllerDev
= NULL
;
2140 UsbIoControllerDev
= AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE
));
2142 if (UsbIoControllerDev
== NULL
) {
2146 UsbIoControllerDev
->Signature
= USB_IO_CONTROLLER_SIGNATURE
;
2148 return UsbIoControllerDev
;
2153 InitUsbIoController (
2154 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
2158 Routine Description:
2159 Init and install EFI_USB_IO_PROTOCOL onto that controller.
2162 UsbIoController - The Controller to be operated.
2170 USB_DEVICE_PATH UsbNode
;
2172 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
2173 EFI_USB_HC_PROTOCOL
*UsbHcProtocol
;
2174 EFI_USB2_HC_PROTOCOL
*Usb2HcProtocol
;
2177 // Build the child device path for each new USB_IO device
2179 ZeroMem (&UsbNode
, sizeof (UsbNode
));
2180 UsbNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
2181 UsbNode
.Header
.SubType
= MSG_USB_DP
;
2182 SetDevicePathNodeLength (&UsbNode
.Header
, sizeof (UsbNode
));
2183 UsbNode
.InterfaceNumber
= UsbIoController
->InterfaceNumber
;
2184 UsbNode
.ParentPortNumber
= UsbIoController
->ParentPort
;
2185 ParentDevicePath
= UsbIoController
->Parent
->DevicePath
;
2187 UsbIoController
->DevicePath
=
2188 AppendDevicePathNode (ParentDevicePath
, &UsbNode
.Header
);
2189 if (UsbIoController
->DevicePath
== NULL
) {
2190 return EFI_OUT_OF_RESOURCES
;
2193 Status
= gBS
->InstallMultipleProtocolInterfaces (
2194 &UsbIoController
->Handle
,
2195 &gEfiDevicePathProtocolGuid
,
2196 UsbIoController
->DevicePath
,
2197 &gEfiUsbIoProtocolGuid
,
2198 &UsbIoController
->UsbIo
,
2202 if (EFI_ERROR (Status
)) {
2206 if (UsbIoController
->UsbDevice
->BusController
->Hc2ProtocolSupported
) {
2207 Status
= gBS
->OpenProtocol (
2208 UsbIoController
->HostController
,
2209 &gEfiUsb2HcProtocolGuid
,
2210 (VOID
**)&Usb2HcProtocol
,
2211 gUsbBusDriverBinding
.DriverBindingHandle
,
2212 UsbIoController
->Handle
,
2213 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2216 Status
= gBS
->OpenProtocol (
2217 UsbIoController
->HostController
,
2218 &gEfiUsbHcProtocolGuid
,
2219 (VOID
**)&UsbHcProtocol
,
2220 gUsbBusDriverBinding
.DriverBindingHandle
,
2221 UsbIoController
->Handle
,
2222 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2232 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2233 IN BOOLEAN ReConfigure
,
2238 Routine Description:
2239 Reset parent hub port to which this device is connected.
2242 UsbIoController - Indicating the Usb Controller Device.
2243 ReConfigure - Do we need to reconfigure it.
2244 RetryTimes - Retry Times when failed
2252 USB_IO_DEVICE
*ParentIoDev
;
2253 USB_IO_DEVICE
*UsbIoDev
;
2254 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2258 EFI_USB_IO_PROTOCOL
*UsbIo
;
2261 ParentController
= UsbIoController
->Parent
;
2262 ParentIoDev
= ParentController
->UsbDevice
;
2263 UsbIoDev
= UsbIoController
->UsbDevice
;
2264 HubPort
= UsbIoController
->ParentPort
;
2266 gBS
->Stall (100 * 1000);
2268 if (ParentIoDev
->DeviceAddress
== 1) {
2269 DEBUG ((gUSBDebugLevel
, "Reset from Root Hub 0x%x\n", HubPort
));
2270 ResetRootPort (ParentIoDev
->BusController
, HubPort
, RetryTimes
);
2272 DEBUG ((gUSBDebugLevel
, "Reset from Hub, Addr 0x%x\n", ParentIoDev
->DeviceAddress
));
2273 ResetHubPort (ParentController
, HubPort
+ 1);
2276 // If we only need port reset, just return
2282 // Re-config that USB device
2284 UsbIo
= &UsbIoController
->UsbIo
;
2287 // Assign a unique address to this device
2289 Address
= UsbIoDev
->DeviceAddress
;
2290 UsbIoDev
->DeviceAddress
= 0;
2292 Result
= UsbSetDeviceAddress (UsbIo
, Address
, &Status
);
2293 UsbIoDev
->DeviceAddress
= Address
;
2295 if (EFI_ERROR (Result
)) {
2296 return EFI_DEVICE_ERROR
;
2299 // Set the device to the default configuration
2301 Result
= UsbSetDefaultConfiguration (UsbIoDev
);
2302 if (EFI_ERROR (Result
)) {
2303 return EFI_DEVICE_ERROR
;
2312 IN EFI_USB_IO_PROTOCOL
*This
2316 Routine Description:
2317 Resets and reconfigures the USB controller. This function will
2318 work for all USB devices except USB Hub Controllers.
2321 This - Indicates the calling context.
2325 EFI_INVALID_PARAMETER
2330 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
2333 UsbIoController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This
);
2336 // Since at this time, this device has already been configured,
2337 // it needs to be re-configured.
2339 Status
= ParentPortReset (UsbIoController
, TRUE
, 0);
2346 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2352 Routine Description:
2353 Reset Root Hub port.
2356 UsbBusDev - Bus controller of the device.
2357 PortNum - The given port to be reset.
2358 RetryTimes - RetryTimes when failed
2367 EFI_USB_PORT_STATUS PortStatus
;
2372 Status
= UsbVirtualHcSetRootHubPortFeature (
2377 if (EFI_ERROR (Status
)) {
2378 return EFI_DEVICE_ERROR
;
2381 gBS
->Stall (50 * 1000);
2384 // clear reset root port
2386 Status
= UsbVirtualHcClearRootHubPortFeature (
2391 if (EFI_ERROR (Status
)) {
2392 return EFI_DEVICE_ERROR
;
2397 Status
= UsbVirtualHcClearRootHubPortFeature (
2400 EfiUsbPortConnectChange
2402 if (EFI_ERROR (Status
)) {
2403 return EFI_DEVICE_ERROR
;
2406 UsbVirtualHcGetRootHubPortStatus (
2411 if (PortStatus
.PortStatus
& USB_PORT_STAT_OWNER
) {
2415 Status
= UsbVirtualHcSetRootHubPortFeature (
2420 if (EFI_ERROR (Status
)) {
2421 return EFI_DEVICE_ERROR
;
2424 Status
= UsbVirtualHcClearRootHubPortFeature (
2427 EfiUsbPortEnableChange
2431 gBS
->Stall ((1 + RetryTimes
) * 50 * 1000);
2438 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2443 Routine Description:
2447 UsbIoController - The USB_IO_CONTROLLER_DEVICE instance.
2448 PortIndex - The given port to be reset.
2456 EFI_USB_IO_PROTOCOL
*UsbIo
;
2457 EFI_USB_PORT_STATUS HubPortStatus
;
2460 ASSERT (UsbIoController
->IsUsbHub
== TRUE
);
2462 UsbIo
= &UsbIoController
->UsbIo
;
2470 gBS
->Stall (10 * 1000);
2473 // Wait for port reset complete
2480 (UINT32
*) &HubPortStatus
2482 gBS
->Stall (10 * 100);
2484 } while ((HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) == 0 && Number
> 0);
2488 // Cannot reset port, return error
2490 return EFI_DEVICE_ERROR
;
2498 (UINT32
*) &HubPortStatus
2501 // reset port will cause some bits change, clear them
2503 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
2504 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
2505 HubClearPortFeature (
2508 EfiUsbPortEnableChange
2512 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
2513 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
2514 HubClearPortFeature (
2517 EfiUsbPortResetChange
2526 ReportUsbStatusCode (
2527 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
2528 IN EFI_STATUS_CODE_TYPE Type
,
2529 IN EFI_STATUS_CODE_VALUE Code
2533 Routine Description:
2535 report a error Status code of USB bus driver controller
2538 UsbBusController - USB_BUS_CONTROLLER_DEVICE
2539 Type - EFI_STATUS_CODE_TYPE
2540 Code - EFI_STATUS_CODE_VALUE
2547 return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
2550 UsbBusController
->DevicePath
2555 IsDeviceDisconnected (
2556 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2557 IN OUT BOOLEAN
*Disconnected
2561 Routine Description:
2562 Reset if the device is disconencted or not
2565 UsbIoController - Indicating the Usb Controller Device.
2566 Disconnected - Indicate whether the device is disconencted or not
2574 USB_IO_DEVICE
*ParentIoDev
;
2575 USB_IO_DEVICE
*UsbIoDev
;
2576 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2579 EFI_USB_IO_PROTOCOL
*UsbIo
;
2580 EFI_USB_PORT_STATUS PortStatus
;
2582 ParentController
= UsbIoController
->Parent
;
2583 ParentIoDev
= ParentController
->UsbDevice
;
2584 UsbIoDev
= UsbIoController
->UsbDevice
;
2585 HubPort
= UsbIoController
->ParentPort
;
2587 if (ParentIoDev
->DeviceAddress
== 1) {
2589 // Connected to the root hub
2591 UsbVirtualHcGetRootHubPortStatus (
2592 ParentIoDev
->BusController
,
2598 UsbIo
= &UsbIoController
->UsbIo
;
2599 Status
= HubGetPortStatus (
2600 &ParentController
->UsbIo
,
2602 (UINT32
*) &PortStatus
2605 if (EFI_ERROR (Status
)) {
2606 return IsDeviceDisconnected (ParentController
, Disconnected
);
2610 *Disconnected
= FALSE
;
2612 if (!IsPortConnect (PortStatus
.PortStatus
)) {
2613 *Disconnected
= TRUE
;
2621 UsbSetTransactionTranslator (
2622 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
2623 IN UINT8 ParentPort
,
2624 IN OUT USB_IO_DEVICE
*Device
2628 Routine Description:
2630 Set Transaction Translator parameter
2634 ParentHubController - Controller structure of the parent Hub device
2635 ParentPort - Number of parent port
2636 Device - Structure of the device
2641 EFI_OUT_OF_RESOURCES Cannot allocate resources
2645 USB_IO_CONTROLLER_DEVICE
*AncestorHubController
;
2647 AncestorHubController
= ParentHubController
;
2648 Device
->Translator
= NULL
;
2650 if (EFI_USB_SPEED_HIGH
== Device
->DeviceSpeed
) {
2655 if (EFI_USB_SPEED_HIGH
== AncestorHubController
->UsbDevice
->DeviceSpeed
) {
2659 if (NULL
== AncestorHubController
->Parent
) {
2663 AncestorHubController
= AncestorHubController
->Parent
;
2666 Device
->Translator
= AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR
));
2667 if (NULL
== Device
->Translator
) {
2668 return EFI_OUT_OF_RESOURCES
;
2671 Device
->Translator
->TranslatorHubAddress
= AncestorHubController
->UsbDevice
->DeviceAddress
;
2672 Device
->Translator
->TranslatorPortNumber
= ParentPort
;
2679 UsbUnsetTransactionTranslator (
2680 USB_IO_DEVICE
*Device
2684 Routine Description:
2686 Unset Transaction Translator parameter
2690 Device - Structure of the device
2698 if (Device
->Translator
) {
2699 gBS
->FreePool (Device
->Translator
);
2700 Device
->Translator
= NULL
;
2708 IdentifyDeviceSpeed (
2709 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2710 USB_IO_DEVICE
*NewDevice
,
2715 Routine Description:
2717 Identify speed of USB device
2721 UsbBusDev - UsbBus controller structure of the device
2722 NewDevice - Devcie controller structure
2723 Index - Number of the port
2728 EFI_NOT_FOUND Device release to CHC or can't be found
2733 EFI_USB_PORT_STATUS HubPortStatus
;
2735 UsbVirtualHcGetRootHubPortStatus (
2738 (EFI_USB_PORT_STATUS
*) &HubPortStatus
2742 // Check device device
2744 if (!(HubPortStatus
.PortStatus
& USB_PORT_STAT_OWNER
)) {
2748 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2749 DEBUG ((gUSBDebugLevel
, "High Speed Device attached to EHC\n"));
2750 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2752 Status
= ReleasePortToCHC (UsbBusDev
, Index
);
2753 if (EFI_ERROR (Status
)) {
2754 DEBUG ((gUSBErrorLevel
, "Fail to release port to CHC\n"));
2756 DEBUG ((gUSBDebugLevel
, "Success to release port to CHC\n"));
2758 return EFI_DEVICE_ERROR
;
2764 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
2765 DEBUG ((gUSBDebugLevel
, "Low Speed Device attached to CHC\n"));
2766 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
2768 DEBUG ((gUSBDebugLevel
, "FULL Speed Device attached to CHC\n"));
2769 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2779 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2784 Routine Description:
2786 Set bit to release the port owner to CHC
2790 UsbBusDev - UsbBus controller structure of the device
2791 PortNum - Number of the port
2796 EFI_DEVICE_ERROR Fail
2802 Status
= UsbVirtualHcSetRootHubPortFeature (
2808 gBS
->Stall (100 * 1000);
2815 UsbVirtualHcGetCapability (
2816 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2817 OUT UINT8
*MaxSpeed
,
2818 OUT UINT8
*PortNumber
,
2819 OUT UINT8
*Is64BitCapable
2823 Routine Description:
2825 Virtual interface to Retrieves the capablility of root hub ports
2826 for both Hc2 and Hc protocol.
2830 UsbBusDev - A pointer to bus controller of the device.
2831 MaxSpeed - A pointer to the number of the host controller.
2832 PortNumber - A pointer to the number of the root hub ports.
2833 Is64BitCapable - A pointer to the flag for whether controller supports
2834 64-bit memory addressing.
2839 The host controller capability were retrieved successfully.
2840 EFI_INVALID_PARAMETER
2841 MaxSpeed or PortNumber or Is64BitCapable is NULL.
2843 An error was encountered while attempting to retrieve the capabilities.
2849 Status
= EFI_SUCCESS
;
2851 if (UsbBusDev
->Hc2ProtocolSupported
) {
2852 Status
= UsbBusDev
->Usb2HCInterface
->GetCapability (
2853 UsbBusDev
->Usb2HCInterface
,
2859 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortNumber (
2860 UsbBusDev
->UsbHCInterface
,
2863 *MaxSpeed
= EFI_USB_SPEED_FULL
;
2864 *Is64BitCapable
= (UINT8
) FALSE
;
2873 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2874 IN UINT16 Attributes
2878 Routine Description:
2880 Virtual interface to provides software reset for the USB host controller
2881 for both Hc2 and Hc protocol.
2885 UsbBusDev - A pointer to bus controller of the device.
2886 Attributes - A bit mask of the reset operation to perform.
2887 See below for a list of the supported bit mask values.
2889 #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc
2890 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
2891 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
2892 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
2894 EFI_USB_HC_RESET_GLOBAL
2895 If this bit is set, a global reset signal will be sent to the USB bus.
2896 This resets all of the USB bus logic, including the USB host
2897 controller hardware and all the devices attached on the USB bus.
2898 EFI_USB_HC_RESET_HOST_CONTROLLER
2899 If this bit is set, the USB host controller hardware will be reset.
2900 No reset signal will be sent to the USB bus.
2901 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
2902 If this bit is set, a global reset signal will be sent to the USB bus.
2903 This resets all of the USB bus logic, including the USB host
2904 controller hardware and all the devices attached on the USB bus.
2905 If this is an EHCI controller and the debug port has configured, then
2906 this is will still reset the host controller.
2907 EFI_USB_HC_RESET_HOST_WITH_DEBUG
2908 If this bit is set, the USB host controller hardware will be reset.
2909 If this is an EHCI controller and the debug port has been configured,
2910 then this will still reset the host controller.
2915 The reset operation succeeded.
2916 EFI_INVALID_PARAMETER
2917 Attributes is not valid.
2919 The type of reset specified by Attributes is not currently supported by
2920 the host controller hardware.
2922 Reset operation is rejected due to the debug port being configured and
2923 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
2924 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
2925 perform reset operation for this host controller.
2927 An error was encountered while attempting to perform
2928 the reset operation.
2934 Status
= EFI_SUCCESS
;
2936 if (UsbBusDev
->Hc2ProtocolSupported
) {
2937 Status
= UsbBusDev
->Usb2HCInterface
->Reset (
2938 UsbBusDev
->Usb2HCInterface
,
2939 EFI_USB_HC_RESET_GLOBAL
2942 Status
= UsbBusDev
->UsbHCInterface
->Reset (
2943 UsbBusDev
->UsbHCInterface
,
2944 EFI_USB_HC_RESET_GLOBAL
2953 UsbVirtualHcGetState (
2954 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2955 OUT EFI_USB_HC_STATE
*State
2959 Routine Description:
2961 Virtual interface to retrieves current state of the USB host controller
2962 for both Hc2 and Hc protocol.
2966 UsbBusDev - A pointer to bus controller of the device.
2967 State - A pointer to the EFI_USB_HC_STATE data structure that
2968 indicates current state of the USB host controller.
2969 Type EFI_USB_HC_STATE is defined below.
2973 EfiUsbHcStateOperational,
2974 EfiUsbHcStateSuspend,
2975 EfiUsbHcStateMaximum
2981 The state information of the host controller was returned in State.
2982 EFI_INVALID_PARAMETER
2985 An error was encountered while attempting to retrieve the
2986 host controller's current state.
2992 Status
= EFI_SUCCESS
;
2994 if (UsbBusDev
->Hc2ProtocolSupported
) {
2995 Status
= UsbBusDev
->Usb2HCInterface
->GetState (
2996 UsbBusDev
->Usb2HCInterface
,
3000 Status
= UsbBusDev
->UsbHCInterface
->GetState (
3001 UsbBusDev
->UsbHCInterface
,
3011 UsbVirtualHcSetState (
3012 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3013 IN EFI_USB_HC_STATE State
3017 Routine Description:
3019 Virtual interface to sets the USB host controller to a specific state
3020 for both Hc2 and Hc protocol.
3024 UsbBusDev - A pointer to bus controller of the device.
3025 State - Indicates the state of the host controller that will be set.
3030 The USB host controller was successfully placed in the state
3032 EFI_INVALID_PARAMETER
3035 Failed to set the state specified by State due to device error.
3041 Status
= EFI_SUCCESS
;
3043 if (UsbBusDev
->Hc2ProtocolSupported
) {
3044 Status
= UsbBusDev
->Usb2HCInterface
->SetState (
3045 UsbBusDev
->Usb2HCInterface
,
3049 Status
= UsbBusDev
->UsbHCInterface
->SetState (
3050 UsbBusDev
->UsbHCInterface
,
3060 UsbVirtualHcGetRootHubPortStatus (
3061 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3062 IN UINT8 PortNumber
,
3063 OUT EFI_USB_PORT_STATUS
*PortStatus
3067 Routine Description:
3069 Virtual interface to retrieves the current status of a USB root hub port
3070 both for Hc2 and Hc protocol.
3074 UsbBusDev - A pointer to bus controller of the device.
3075 PortNumber - Specifies the root hub port from which the status
3076 is to be retrieved. This value is zero-based. For example,
3077 if a root hub has two ports, then the first port is numbered 0,
3078 and the second port is numbered 1.
3079 PortStatus - A pointer to the current port status bits and
3080 port status change bits.
3084 EFI_SUCCESS The status of the USB root hub port specified by PortNumber
3085 was returned in PortStatus.
3086 EFI_INVALID_PARAMETER PortNumber is invalid.
3087 EFI_DEVICE_ERROR Can't read register
3093 Status
= EFI_SUCCESS
;
3095 if (UsbBusDev
->Hc2ProtocolSupported
) {
3096 Status
= UsbBusDev
->Usb2HCInterface
->GetRootHubPortStatus (
3097 UsbBusDev
->Usb2HCInterface
,
3102 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortStatus (
3103 UsbBusDev
->UsbHCInterface
,
3114 UsbVirtualHcSetRootHubPortFeature (
3115 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3116 IN UINT8 PortNumber
,
3117 IN EFI_USB_PORT_FEATURE PortFeature
3121 Routine Description:
3122 Virual interface to sets a feature for the specified root hub port
3123 for both Hc2 and Hc protocol.
3127 UsbBusDev - A pointer to bus controller of the device.
3128 PortNumber - Specifies the root hub port whose feature
3129 is requested to be set.
3130 PortFeature - Indicates the feature selector associated
3131 with the feature set request.
3136 The feature specified by PortFeature was set for the
3137 USB root hub port specified by PortNumber.
3138 EFI_INVALID_PARAMETER
3139 PortNumber is invalid or PortFeature is invalid.
3147 Status
= EFI_SUCCESS
;
3149 if (UsbBusDev
->Hc2ProtocolSupported
) {
3150 Status
= UsbBusDev
->Usb2HCInterface
->SetRootHubPortFeature (
3151 UsbBusDev
->Usb2HCInterface
,
3156 Status
= UsbBusDev
->UsbHCInterface
->SetRootHubPortFeature (
3157 UsbBusDev
->UsbHCInterface
,
3168 UsbVirtualHcClearRootHubPortFeature (
3169 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3170 IN UINT8 PortNumber
,
3171 IN EFI_USB_PORT_FEATURE PortFeature
3175 Routine Description:
3177 Virtual interface to clears a feature for the specified root hub port
3178 for both Hc2 and Hc protocol.
3182 UsbBusDev - A pointer to bus controller of the device.
3183 PortNumber - Specifies the root hub port whose feature
3184 is requested to be cleared.
3185 PortFeature - Indicates the feature selector associated with the
3186 feature clear request.
3191 The feature specified by PortFeature was cleared for the
3192 USB root hub port specified by PortNumber.
3193 EFI_INVALID_PARAMETER
3194 PortNumber is invalid or PortFeature is invalid.
3202 Status
= EFI_SUCCESS
;
3204 if (UsbBusDev
->Hc2ProtocolSupported
) {
3205 Status
= UsbBusDev
->Usb2HCInterface
->ClearRootHubPortFeature (
3206 UsbBusDev
->Usb2HCInterface
,
3211 Status
= UsbBusDev
->UsbHCInterface
->ClearRootHubPortFeature (
3212 UsbBusDev
->UsbHCInterface
,
3223 UsbVirtualHcControlTransfer (
3224 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3225 IN UINT8 DeviceAddress
,
3226 IN UINT8 DeviceSpeed
,
3227 IN UINTN MaximumPacketLength
,
3228 IN EFI_USB_DEVICE_REQUEST
*Request
,
3229 IN EFI_USB_DATA_DIRECTION TransferDirection
,
3231 IN OUT UINTN
*DataLength
,
3233 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3234 OUT UINT32
*TransferResult
3238 Routine Description:
3240 Virtual interface to submits control transfer to a target USB device
3241 for both Hc2 and Hc protocol.
3245 UsbBusDev - A pointer to bus controller of the device.
3246 DeviceAddress - Represents the address of the target device on the USB,
3247 which is assigned during USB enumeration.
3248 DeviceSpeed - Indicates target device speed.
3249 MaximumPacketLength - Indicates the maximum packet size that the
3250 default control transfer endpoint is capable of
3251 sending or receiving.
3252 Request - A pointer to the USB device request that will be sent
3254 TransferDirection - Specifies the data direction for the transfer.
3255 There are three values available, DataIn, DataOut
3257 Data - A pointer to the buffer of data that will be transmitted
3258 to USB device or received from USB device.
3259 DataLength - Indicates the size, in bytes, of the data buffer
3261 TimeOut - Indicates the maximum time, in microseconds,
3262 which the transfer is allowed to complete.
3263 Translator - A pointr to the transaction translator data.
3264 TransferResult - A pointer to the detailed result information generated
3265 by this control transfer.
3270 The control transfer was completed successfully.
3271 EFI_OUT_OF_RESOURCES
3272 The control transfer could not be completed due to a lack of resources.
3273 EFI_INVALID_PARAMETER
3274 Some parameters are invalid.
3276 The control transfer failed due to timeout.
3278 The control transfer failed due to host controller or device error.
3279 Caller should check TranferResult for detailed error information.
3284 BOOLEAN IsSlowDevice
;
3286 Status
= EFI_SUCCESS
;
3288 if (UsbBusDev
->Hc2ProtocolSupported
) {
3289 Status
= UsbBusDev
->Usb2HCInterface
->ControlTransfer (
3290 UsbBusDev
->Usb2HCInterface
,
3293 MaximumPacketLength
,
3303 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3304 Status
= UsbBusDev
->UsbHCInterface
->ControlTransfer (
3305 UsbBusDev
->UsbHCInterface
,
3308 (UINT8
) MaximumPacketLength
,
3323 UsbVirtualHcBulkTransfer (
3324 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3325 IN UINT8 DeviceAddress
,
3326 IN UINT8 EndPointAddress
,
3327 IN UINT8 DeviceSpeed
,
3328 IN UINTN MaximumPacketLength
,
3329 IN UINT8 DataBuffersNumber
,
3330 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
3331 IN OUT UINTN
*DataLength
,
3332 IN OUT UINT8
*DataToggle
,
3334 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3335 OUT UINT32
*TransferResult
3339 Routine Description:
3341 Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
3342 both for Hc2 and Hc protocol.
3346 UsbBusDev - A pointer to bus controller of the device.
3347 DeviceAddress - Represents the address of the target device on the USB,
3348 which is assigned during USB enumeration.
3349 EndPointAddress - The combination of an endpoint number and an
3350 endpoint direction of the target USB device.
3351 Each endpoint address supports data transfer in
3352 one direction except the control endpoint
3353 (whose default endpoint address is 0).
3354 It is the caller's responsibility to make sure that
3355 the EndPointAddress represents a bulk endpoint.
3356 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
3357 and EFI_USB_SPEED_HIGH.
3358 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3359 is capable of sending or receiving.
3360 DataBuffersNumber - Number of data buffers prepared for the transfer.
3361 Data - Array of pointers to the buffers of data that will be transmitted
3362 to USB device or received from USB device.
3363 DataLength - When input, indicates the size, in bytes, of the data buffer
3364 specified by Data. When output, indicates the actually
3365 transferred data size.
3366 DataToggle - A pointer to the data toggle value. On input, it indicates
3367 the initial data toggle value the bulk transfer should adopt;
3368 on output, it is updated to indicate the data toggle value
3369 of the subsequent bulk transfer.
3370 Translator - A pointr to the transaction translator data.
3371 TimeOut - Indicates the maximum time, in microseconds, which the
3372 transfer is allowed to complete.
3373 TransferResult - A pointer to the detailed result information of the
3379 The bulk transfer was completed successfully.
3380 EFI_OUT_OF_RESOURCES
3381 The bulk transfer could not be submitted due to lack of resource.
3382 EFI_INVALID_PARAMETER
3383 Some parameters are invalid.
3385 The bulk transfer failed due to timeout.
3387 The bulk transfer failed due to host controller or device error.
3388 Caller should check TranferResult for detailed error information.
3394 Status
= EFI_SUCCESS
;
3396 if (UsbBusDev
->Hc2ProtocolSupported
) {
3397 Status
= UsbBusDev
->Usb2HCInterface
->BulkTransfer (
3398 UsbBusDev
->Usb2HCInterface
,
3402 MaximumPacketLength
,
3412 Status
= UsbBusDev
->UsbHCInterface
->BulkTransfer (
3413 UsbBusDev
->UsbHCInterface
,
3416 (UINT8
) MaximumPacketLength
,
3430 UsbVirtualHcAsyncInterruptTransfer (
3431 IN USB_BUS_CONTROLLER_DEVICE
* UsbBusDev
,
3432 IN UINT8 DeviceAddress
,
3433 IN UINT8 EndPointAddress
,
3434 IN UINT8 DeviceSpeed
,
3435 IN UINTN MaximumPacketLength
,
3436 IN BOOLEAN IsNewTransfer
,
3437 IN OUT UINT8
*DataToggle
,
3438 IN UINTN PollingInterval
,
3439 IN UINTN DataLength
,
3440 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
3441 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
3442 IN VOID
*Context OPTIONAL
3446 Routine Description:
3448 Virtual interface to submits an asynchronous interrupt transfer to an
3449 interrupt endpoint of a USB device for both Hc2 and Hc protocol.
3453 UsbBusDev - A pointer to bus controller of the device.
3454 DeviceAddress - Represents the address of the target device on the USB,
3455 which is assigned during USB enumeration.
3456 EndPointAddress - The combination of an endpoint number and an endpoint
3457 direction of the target USB device. Each endpoint address
3458 supports data transfer in one direction except the
3459 control endpoint (whose default endpoint address is 0).
3460 It is the caller's responsibility to make sure that
3461 the EndPointAddress represents an interrupt endpoint.
3462 DeviceSpeed - Indicates device speed.
3463 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3464 is capable of sending or receiving.
3465 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
3466 the host and the target interrupt endpoint.
3467 If FALSE, the specified asynchronous interrupt pipe
3469 DataToggle - A pointer to the data toggle value. On input, it is valid
3470 when IsNewTransfer is TRUE, and it indicates the initial
3471 data toggle value the asynchronous interrupt transfer
3473 On output, it is valid when IsNewTransfer is FALSE,
3474 and it is updated to indicate the data toggle value of
3475 the subsequent asynchronous interrupt transfer.
3476 PollingInterval - Indicates the interval, in milliseconds, that the
3477 asynchronous interrupt transfer is polled.
3478 This parameter is required when IsNewTransfer is TRUE.
3479 DataLength - Indicates the length of data to be received at the
3480 rate specified by PollingInterval from the target
3481 asynchronous interrupt endpoint. This parameter
3482 is only required when IsNewTransfer is TRUE.
3483 Translator - A pointr to the transaction translator data.
3484 CallBackFunction - The Callback function.This function is called at the
3485 rate specified by PollingInterval.This parameter is
3486 only required when IsNewTransfer is TRUE.
3487 Context - The context that is passed to the CallBackFunction.
3488 - This is an optional parameter and may be NULL.
3493 The asynchronous interrupt transfer request has been successfully
3494 submitted or canceled.
3495 EFI_INVALID_PARAMETER
3496 Some parameters are invalid.
3497 EFI_OUT_OF_RESOURCES
3498 The request could not be completed due to a lack of resources.
3505 BOOLEAN IsSlowDevice
;
3507 Status
= EFI_SUCCESS
;
3509 if (UsbBusDev
->Hc2ProtocolSupported
) {
3510 Status
= UsbBusDev
->Usb2HCInterface
->AsyncInterruptTransfer (
3511 UsbBusDev
->Usb2HCInterface
,
3515 MaximumPacketLength
,
3525 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3526 Status
= UsbBusDev
->UsbHCInterface
->AsyncInterruptTransfer (
3527 UsbBusDev
->UsbHCInterface
,
3531 (UINT8
) MaximumPacketLength
,
3546 UsbVirtualHcSyncInterruptTransfer (
3547 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3548 IN UINT8 DeviceAddress
,
3549 IN UINT8 EndPointAddress
,
3550 IN UINT8 DeviceSpeed
,
3551 IN UINTN MaximumPacketLength
,
3553 IN OUT UINTN
*DataLength
,
3554 IN OUT UINT8
*DataToggle
,
3556 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3557 OUT UINT32
*TransferResult
3561 Routine Description:
3563 Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
3564 of a USB device for both Hc2 and Hc protocol.
3568 UsbBusDev - A pointer to bus controller of the device.
3569 DeviceAddress - Represents the address of the target device on the USB,
3570 which is assigned during USB enumeration.
3571 EndPointAddress - The combination of an endpoint number and an endpoint
3572 direction of the target USB device. Each endpoint
3573 address supports data transfer in one direction
3574 except the control endpoint (whose default
3575 endpoint address is 0). It is the caller's responsibility
3576 to make sure that the EndPointAddress represents
3577 an interrupt endpoint.
3578 DeviceSpeed - Indicates device speed.
3579 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3580 is capable of sending or receiving.
3581 Data - A pointer to the buffer of data that will be transmitted
3582 to USB device or received from USB device.
3583 DataLength - On input, the size, in bytes, of the data buffer specified
3584 by Data. On output, the number of bytes transferred.
3585 DataToggle - A pointer to the data toggle value. On input, it indicates
3586 the initial data toggle value the synchronous interrupt
3587 transfer should adopt;
3588 on output, it is updated to indicate the data toggle value
3589 of the subsequent synchronous interrupt transfer.
3590 TimeOut - Indicates the maximum time, in microseconds, which the
3591 transfer is allowed to complete.
3592 Translator - A pointr to the transaction translator data.
3593 TransferResult - A pointer to the detailed result information from
3594 the synchronous interrupt transfer.
3599 The synchronous interrupt transfer was completed successfully.
3600 EFI_OUT_OF_RESOURCES
3601 The synchronous interrupt transfer could not be submitted due
3602 to lack of resource.
3603 EFI_INVALID_PARAMETER
3604 Some parameters are invalid.
3606 The synchronous interrupt transfer failed due to timeout.
3608 The synchronous interrupt transfer failed due to host controller
3609 or device error. Caller should check TranferResult for detailed
3615 BOOLEAN IsSlowDevice
;
3617 Status
= EFI_SUCCESS
;
3619 if (UsbBusDev
->Hc2ProtocolSupported
) {
3620 Status
= UsbBusDev
->Usb2HCInterface
->SyncInterruptTransfer (
3621 UsbBusDev
->Usb2HCInterface
,
3625 MaximumPacketLength
,
3634 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3635 Status
= UsbBusDev
->UsbHCInterface
->SyncInterruptTransfer (
3636 UsbBusDev
->UsbHCInterface
,
3640 (UINT8
) MaximumPacketLength
,
3654 UsbVirtualHcIsochronousTransfer (
3655 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3656 IN UINT8 DeviceAddress
,
3657 IN UINT8 EndPointAddress
,
3658 IN UINT8 DeviceSpeed
,
3659 IN UINTN MaximumPacketLength
,
3660 IN UINT8 DataBuffersNumber
,
3661 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3662 IN UINTN DataLength
,
3663 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3664 OUT UINT32
*TransferResult
3668 Routine Description:
3670 Virtual interface to submits isochronous transfer to a target USB device
3671 for both Hc2 and Hc protocol.
3675 UsbBusDev - A pointer to bus controller of the device.
3676 DeviceAddress - Represents the address of the target device on the USB,
3677 which is assigned during USB enumeration.
3678 EndPointAddress - End point address
3679 DeviceSpeed - Indicates device speed.
3680 MaximumPacketLength - Indicates the maximum packet size that the
3681 default control transfer endpoint is capable of
3682 sending or receiving.
3683 DataBuffersNumber - Number of data buffers prepared for the transfer.
3684 Data - Array of pointers to the buffers of data that will be
3685 transmitted to USB device or received from USB device.
3686 DataLength - Indicates the size, in bytes, of the data buffer
3688 Translator - A pointr to the transaction translator data.
3689 TransferResult - A pointer to the detailed result information generated
3690 by this control transfer.
3698 return EFI_UNSUPPORTED
;
3703 UsbVirtualHcAsyncIsochronousTransfer (
3704 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3705 IN UINT8 DeviceAddress
,
3706 IN UINT8 EndPointAddress
,
3707 IN UINT8 DeviceSpeed
,
3708 IN UINTN MaximumPacketLength
,
3709 IN UINT8 DataBuffersNumber
,
3710 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3711 IN UINTN DataLength
,
3712 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3713 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
3718 Routine Description:
3720 Vitual interface to submits Async isochronous transfer to a target USB device
3721 for both Hc2 and Hc protocol.
3725 UsbBusDev - A pointer to bus controller of the device.
3726 DeviceAddress - Represents the address of the target device on the USB,
3727 which is assigned during USB enumeration.
3728 EndPointAddress - End point address
3729 DeviceSpeed - Indicates device speed.
3730 MaximumPacketLength - Indicates the maximum packet size that the
3731 default control transfer endpoint is capable of
3732 sending or receiving.
3733 DataBuffersNumber - Number of data buffers prepared for the transfer.
3734 Data - Array of pointers to the buffers of data that will be transmitted
3735 to USB device or received from USB device.
3736 DataLength - Indicates the size, in bytes, of the data buffer
3738 Translator - A pointr to the transaction translator data.
3739 IsochronousCallBack - When the transfer complete, the call back function will be called
3740 Context - Pass to the call back function as parameter
3748 return EFI_UNSUPPORTED
;