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.
27 GLOBAL_REMOVE_IF_UNREFERENCED UINTN gUSBDebugLevel
= EFI_D_INFO
;
28 GLOBAL_REMOVE_IF_UNREFERENCED UINTN gUSBErrorLevel
= EFI_D_ERROR
;
31 // The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER
32 // structure in the UsbBusDriverControllerDriverStop(). Then we can
33 // Close all opened protocols and release this structure.
35 STATIC EFI_GUID mUsbBusProtocolGuid
= EFI_USB_BUS_PROTOCOL_GUID
;
37 EFI_DRIVER_BINDING_PROTOCOL gUsbBusDriverBinding
= {
38 UsbBusControllerDriverSupported
,
39 UsbBusControllerDriverStart
,
40 UsbBusControllerDriverStop
,
52 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
53 IN EFI_STATUS_CODE_TYPE Type
,
54 IN EFI_STATUS_CODE_VALUE Code
58 USB_IO_CONTROLLER_DEVICE
*
59 CreateUsbIoControllerDevice (
66 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
70 // USB Device Configuration / Deconfiguration
74 UsbDeviceConfiguration (
75 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
76 IN EFI_HANDLE HostController
,
78 IN USB_IO_DEVICE
*UsbIoDevice
82 // Usb Bus enumeration function
100 UsbSetTransactionTranslator (
101 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
103 IN OUT USB_IO_DEVICE
*Device
108 UsbUnsetTransactionTranslator (
109 USB_IO_DEVICE
*Device
114 IdentifyDeviceSpeed (
115 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
116 USB_IO_DEVICE
*NewDevice
,
123 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
130 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
138 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
145 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
146 IN BOOLEAN ReConfigure
,
151 // Following are address allocate and free functions
156 IN UINT8
*AddressPool
161 Allocate address for usb device
164 AddressPool - Pool of usb device address
174 for (ByteIndex
= 0; ByteIndex
< 16; ByteIndex
++) {
175 for (BitIndex
= 0; BitIndex
< 8; BitIndex
++) {
176 if ((AddressPool
[ByteIndex
] & (1 << BitIndex
)) == 0) {
178 // Found one, covert to address, and mark it use
180 AddressPool
[ByteIndex
] = (UINT8
) (AddressPool
[ByteIndex
] | (1 << BitIndex
));
181 return (UINT8
) (ByteIndex
* 8 + BitIndex
);
194 IN UINT8
*AddressPool
199 Free address for usb device
202 DevAddress - Usb device address
203 AddressPool - Pool of usb device address
213 // Locate the position
215 WhichByte
= (UINT8
) (DevAddress
/ 8);
216 WhichBit
= (UINT8
) (DevAddress
& 0x7);
218 AddressPool
[WhichByte
] = (UINT8
) (AddressPool
[WhichByte
] & (~(1 << WhichBit
)));
223 UsbBusControllerDriverSupported (
224 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
225 IN EFI_HANDLE Controller
,
226 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
231 Test to see if this driver supports ControllerHandle. Any ControllerHandle
232 that has UsbHcProtocol installed will be supported.
235 This - Protocol instance pointer.
236 Controller - Handle of device to test
237 RemainingDevicePath - Device Path Protocol instance pointer
240 EFI_SUCCESS - This driver supports this device.
241 EFI_UNSUPPORTED - This driver does not support this device.
246 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
247 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
248 EFI_USB_HC_PROTOCOL
*UsbHc
;
249 EFI_DEV_PATH_PTR Node
;
254 if (RemainingDevicePath
!= NULL
) {
255 Node
.DevPath
= RemainingDevicePath
;
256 if (Node
.DevPath
->Type
!= MESSAGING_DEVICE_PATH
||
257 Node
.DevPath
->SubType
!= MSG_USB_DP
||
258 DevicePathNodeLength(Node
.DevPath
) != sizeof(USB_DEVICE_PATH
)) {
259 return EFI_UNSUPPORTED
;
264 // Open the IO Abstraction(s) needed to perform the supported test
266 Status
= gBS
->OpenProtocol (
268 &gEfiDevicePathProtocolGuid
,
269 (VOID
**) &ParentDevicePath
,
270 This
->DriverBindingHandle
,
272 EFI_OPEN_PROTOCOL_BY_DRIVER
274 if (Status
== EFI_ALREADY_STARTED
) {
278 if (EFI_ERROR (Status
)) {
284 &gEfiDevicePathProtocolGuid
,
285 This
->DriverBindingHandle
,
290 // Check whether USB Host Controller Protocol is already
291 // installed on this handle. If it is installed, we can start
292 // USB Bus Driver now.
294 Status
= gBS
->OpenProtocol (
296 &gEfiUsb2HcProtocolGuid
,
298 This
->DriverBindingHandle
,
300 EFI_OPEN_PROTOCOL_BY_DRIVER
302 if (Status
== EFI_ALREADY_STARTED
) {
306 if (EFI_ERROR (Status
)) {
307 Status
= gBS
->OpenProtocol (
309 &gEfiUsbHcProtocolGuid
,
311 This
->DriverBindingHandle
,
313 EFI_OPEN_PROTOCOL_BY_DRIVER
315 if (Status
== EFI_ALREADY_STARTED
) {
319 if (EFI_ERROR (Status
)) {
325 &gEfiUsbHcProtocolGuid
,
326 This
->DriverBindingHandle
,
334 &gEfiUsb2HcProtocolGuid
,
335 This
->DriverBindingHandle
,
344 UsbBusControllerDriverStart (
345 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
346 IN EFI_HANDLE Controller
,
347 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
353 Starting the Usb Bus Driver
357 This - Protocol instance pointer.
358 Controller - Handle of device to test
359 RemainingDevicePath - Not used
363 EFI_SUCCESS - This driver supports this device.
364 EFI_DEVICE_ERROR - This driver cannot be started due to device
365 EFI_OUT_OF_RESOURCES- Can't allocate memory resources
370 EFI_STATUS OpenStatus
;
371 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
372 USB_IO_DEVICE
*RootHub
;
373 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
376 UINT8 Is64BitCapable
;
379 // Allocate USB_BUS_CONTROLLER_DEVICE structure
382 UsbBusDev
= AllocateZeroPool (sizeof (USB_BUS_CONTROLLER_DEVICE
));
383 if (UsbBusDev
== NULL
) {
384 return EFI_OUT_OF_RESOURCES
;
387 UsbBusDev
->Signature
= USB_BUS_DEVICE_SIGNATURE
;
388 UsbBusDev
->AddressPool
[0] = 1;
391 // Get the Device Path Protocol on Controller's handle
393 OpenStatus
= gBS
->OpenProtocol (
395 &gEfiDevicePathProtocolGuid
,
396 (VOID
**) &UsbBusDev
->DevicePath
,
397 This
->DriverBindingHandle
,
399 EFI_OPEN_PROTOCOL_BY_DRIVER
402 if (EFI_ERROR (OpenStatus
)) {
403 gBS
->FreePool (UsbBusDev
);
407 // Locate the Host Controller Interface
409 OpenStatus
= gBS
->OpenProtocol (
411 &gEfiUsb2HcProtocolGuid
,
412 (VOID
**) &(UsbBusDev
->Usb2HCInterface
),
413 This
->DriverBindingHandle
,
415 EFI_OPEN_PROTOCOL_BY_DRIVER
417 if (EFI_ERROR (OpenStatus
)) {
419 UsbBusDev
->Hc2ProtocolSupported
= FALSE
;
420 OpenStatus
= gBS
->OpenProtocol (
422 &gEfiUsbHcProtocolGuid
,
423 (VOID
**) &(UsbBusDev
->UsbHCInterface
),
424 This
->DriverBindingHandle
,
426 EFI_OPEN_PROTOCOL_BY_DRIVER
428 if (EFI_ERROR (OpenStatus
)) {
430 // Report Status Code here since we will reset the host controller
432 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
433 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
434 EFI_IO_BUS_USB
| EFI_IOB_EC_CONTROLLER_ERROR
,
435 UsbBusDev
->DevicePath
440 &gEfiDevicePathProtocolGuid
,
441 This
->DriverBindingHandle
,
444 gBS
->FreePool (UsbBusDev
);
448 DEBUG ((gUSBDebugLevel
, "UsbHcProtocol Opened.\n"));
450 DEBUG ((gUSBDebugLevel
, "Usb2HcProtocol Opened.\n"));
451 UsbBusDev
->Hc2ProtocolSupported
= TRUE
;
455 // Attach EFI_USB_BUS_PROTOCOL to controller handle,
456 // for locate UsbBusDev later
458 Status
= gBS
->InstallProtocolInterface (
460 &mUsbBusProtocolGuid
,
461 EFI_NATIVE_INTERFACE
,
462 &UsbBusDev
->BusIdentify
465 if (EFI_ERROR (Status
)) {
469 &gEfiDevicePathProtocolGuid
,
470 This
->DriverBindingHandle
,
473 if (UsbBusDev
->Hc2ProtocolSupported
) {
476 &gEfiUsb2HcProtocolGuid
,
477 This
->DriverBindingHandle
,
483 &gEfiUsbHcProtocolGuid
,
484 This
->DriverBindingHandle
,
489 gBS
->FreePool (UsbBusDev
);
493 // Add root hub to the tree
496 RootHub
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
497 if (RootHub
== NULL
) {
498 gBS
->UninstallProtocolInterface (
500 &mUsbBusProtocolGuid
,
501 &UsbBusDev
->BusIdentify
505 &gEfiDevicePathProtocolGuid
,
506 This
->DriverBindingHandle
,
509 if (UsbBusDev
->Hc2ProtocolSupported
) {
512 &gEfiUsb2HcProtocolGuid
,
513 This
->DriverBindingHandle
,
519 &gEfiUsbHcProtocolGuid
,
520 This
->DriverBindingHandle
,
525 gBS
->FreePool (UsbBusDev
);
526 return EFI_OUT_OF_RESOURCES
;
529 RootHub
->BusController
= UsbBusDev
;
530 RootHub
->DeviceAddress
= UsbAllocateAddress (UsbBusDev
->AddressPool
);
532 UsbBusDev
->Root
= RootHub
;
535 // Allocate Root Hub Controller
537 RootHubController
= CreateUsbIoControllerDevice ();
538 if (RootHubController
== NULL
) {
539 gBS
->UninstallProtocolInterface (
541 &mUsbBusProtocolGuid
,
542 &UsbBusDev
->BusIdentify
546 &gEfiDevicePathProtocolGuid
,
547 This
->DriverBindingHandle
,
550 if (UsbBusDev
->Hc2ProtocolSupported
) {
553 &gEfiUsb2HcProtocolGuid
,
554 This
->DriverBindingHandle
,
560 &gEfiUsbHcProtocolGuid
,
561 This
->DriverBindingHandle
,
565 gBS
->FreePool (UsbBusDev
);
566 gBS
->FreePool (RootHub
);
567 return EFI_OUT_OF_RESOURCES
;
570 UsbVirtualHcGetCapability (
576 RootHubController
->DownstreamPorts
= PortNumber
;
577 RootHubController
->UsbDevice
= RootHub
;
578 RootHubController
->IsUsbHub
= TRUE
;
579 RootHubController
->DevicePath
= UsbBusDev
->DevicePath
;
580 RootHubController
->HostController
= Controller
;
582 RootHub
->NumOfControllers
= 1;
583 RootHub
->UsbController
[0] = RootHubController
;
584 RootHub
->DeviceSpeed
= MaxSpeed
;
587 // Report Status Code here since we will reset the host controller
589 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
591 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
,
592 UsbBusDev
->DevicePath
596 // Reset USB Host Controller
600 EFI_USB_HC_RESET_GLOBAL
604 // Report Status Code while we are going to bring up the Host Controller
605 // and start bus enumeration
607 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
609 EFI_IO_BUS_USB
| EFI_IOB_PC_ENABLE
,
610 UsbBusDev
->DevicePath
614 // Start USB Host Controller
616 UsbVirtualHcSetState (
618 EfiUsbHcStateOperational
622 // Create a timer to query root ports periodically
624 Status
= gBS
->CreateEvent (
625 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
629 &RootHubController
->HubNotify
631 if (EFI_ERROR (Status
)) {
632 gBS
->UninstallProtocolInterface (
634 &mUsbBusProtocolGuid
,
635 &UsbBusDev
->BusIdentify
640 &gEfiDevicePathProtocolGuid
,
641 This
->DriverBindingHandle
,
645 if (UsbBusDev
->Hc2ProtocolSupported
) {
648 &gEfiUsb2HcProtocolGuid
,
649 This
->DriverBindingHandle
,
655 &gEfiUsbHcProtocolGuid
,
656 This
->DriverBindingHandle
,
661 gBS
->FreePool (RootHubController
);
662 gBS
->FreePool (RootHub
);
663 gBS
->FreePool (UsbBusDev
);
664 return EFI_OUT_OF_RESOURCES
;
668 // Before depending on the timer to check root ports periodically,
669 // here we should check them immediately for the first time, or
670 // there will be an interval between bus start and devices start.
672 gBS
->SignalEvent (RootHubController
->HubNotify
);
674 Status
= gBS
->SetTimer (
675 RootHubController
->HubNotify
,
679 if (EFI_ERROR (Status
)) {
680 gBS
->UninstallProtocolInterface (
682 &mUsbBusProtocolGuid
,
683 &UsbBusDev
->BusIdentify
688 &gEfiDevicePathProtocolGuid
,
689 This
->DriverBindingHandle
,
693 if (UsbBusDev
->Hc2ProtocolSupported
) {
696 &gEfiUsb2HcProtocolGuid
,
697 This
->DriverBindingHandle
,
703 &gEfiUsbHcProtocolGuid
,
704 This
->DriverBindingHandle
,
709 gBS
->CloseEvent (RootHubController
->HubNotify
);
710 gBS
->FreePool (RootHubController
);
711 gBS
->FreePool (RootHub
);
712 gBS
->FreePool (UsbBusDev
);
713 return EFI_DEVICE_ERROR
;
720 // Stop the bus controller
724 UsbBusControllerDriverStop (
725 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
726 IN EFI_HANDLE Controller
,
727 IN UINTN NumberOfChildren
,
728 IN EFI_HANDLE
*ChildHandleBuffer
733 Stop this driver on ControllerHandle. Support stoping any child handles
734 created by this driver.
737 This - Protocol instance pointer.
738 Controller - Handle of device to stop driver on
739 NumberOfChildren - Number of Children in the ChildHandleBuffer
740 ChildHandleBuffer - List of handles for the children we need to stop.
751 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
752 USB_BUS_CONTROLLER_DEVICE
*UsbBusController
;
753 EFI_USB_BUS_PROTOCOL
*UsbIdentifier
;
755 USB_IO_CONTROLLER_DEVICE
*UsbController
;
756 USB_IO_DEVICE
*UsbIoDevice
;
757 USB_IO_CONTROLLER_DEVICE
*HubController
;
759 EFI_USB_IO_PROTOCOL
*UsbIo
;
761 if (NumberOfChildren
> 0) {
763 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
764 Status
= gBS
->OpenProtocol (
765 ChildHandleBuffer
[Index
],
766 &gEfiUsbIoProtocolGuid
,
768 This
->DriverBindingHandle
,
770 EFI_OPEN_PROTOCOL_GET_PROTOCOL
772 if (EFI_ERROR (Status
)) {
774 // We are here since the handle passed in does not support
775 // UsbIo protocol. There are several reasons that will cause
777 // For combo device such as keyboard, it may have 2 devices
778 // in one, namely, keyboard and mouse. If we deconfigure one
779 // of them, the other will be freed at the same time. This will
780 // cause the status error. But this is the correct behavior.
781 // For hub device, if we deconfigure hub first, the other chile
782 // device will be disconnected also, this will also provide us
783 // a status error. Now we will only report EFI_SUCCESS since Uhc
784 // driver will be disconnected at the second time.(pls see
785 // CoreDisconnectController for details)
790 UsbController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (UsbIo
);
791 UsbIoDevice
= UsbController
->UsbDevice
;
792 HubController
= UsbController
->Parent
;
793 UsbDeviceDeConfiguration (UsbIoDevice
);
794 for (Index2
= 0; Index2
< HubController
->DownstreamPorts
; Index2
++) {
795 if (HubController
->Children
[Index2
] == UsbIoDevice
) {
796 HubController
->Children
[Index2
] = NULL
;
804 // Get the USB_BUS_CONTROLLER_DEVICE
806 Status
= gBS
->OpenProtocol (
808 &mUsbBusProtocolGuid
,
809 (VOID
**) &UsbIdentifier
,
810 This
->DriverBindingHandle
,
812 EFI_OPEN_PROTOCOL_GET_PROTOCOL
815 if (EFI_ERROR (Status
)) {
816 return EFI_DEVICE_ERROR
;
819 UsbBusController
= USB_BUS_CONTROLLER_DEVICE_FROM_THIS (UsbIdentifier
);
822 // Stop USB Host Controller
826 // Report Status Code here since we will reset the host controller
828 ReportUsbStatusCode (
831 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
834 UsbVirtualHcSetState (
840 // Deconfiguration all its devices
842 Root
= UsbBusController
->Root
;
843 RootHubController
= Root
->UsbController
[0];
845 gBS
->CloseEvent (RootHubController
->HubNotify
);
847 for (Index2
= 0; Index2
< RootHubController
->DownstreamPorts
; Index2
++) {
848 if (RootHubController
->Children
[Index2
]) {
849 UsbDeviceDeConfiguration (RootHubController
->Children
[Index2
]);
850 RootHubController
->Children
[Index2
] = NULL
;
854 gBS
->FreePool (RootHubController
);
855 gBS
->FreePool (Root
);
858 // Uninstall USB Bus Protocol
860 gBS
->UninstallProtocolInterface (
862 &mUsbBusProtocolGuid
,
863 &UsbBusController
->BusIdentify
867 // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL
868 // Opened by this Controller
870 if (UsbBusController
->Hc2ProtocolSupported
) {
873 &gEfiUsb2HcProtocolGuid
,
874 This
->DriverBindingHandle
,
880 &gEfiUsbHcProtocolGuid
,
881 This
->DriverBindingHandle
,
888 &gEfiDevicePathProtocolGuid
,
889 This
->DriverBindingHandle
,
893 gBS
->FreePool (UsbBusController
);
898 // USB Device Configuration
902 UsbDeviceConfiguration (
903 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
904 IN EFI_HANDLE HostController
,
906 IN USB_IO_DEVICE
*UsbIoDevice
911 Configurate a new device attached to the usb bus
914 ParentHubController - Parent Hub which this device is connected.
915 HostController - Host Controller handle
916 ParentPort - Parent Hub port which this device is connected.
917 UsbIoDevice - The device to be configured.
930 CHAR16
*StrManufacturer
;
932 CHAR16
*StrSerialNumber
;
933 EFI_USB_IO_PROTOCOL
*UsbIo
;
934 UINT8 NumOfInterface
;
935 USB_IO_CONTROLLER_DEVICE
*FirstController
;
936 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
937 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
939 UsbBusDev
= UsbIoDevice
->BusController
;
941 UsbSetTransactionTranslator (
948 // Since a USB device must have at least on interface,
949 // so create this instance first
951 FirstController
= CreateUsbIoControllerDevice ();
952 FirstController
->UsbDevice
= UsbIoDevice
;
953 UsbIoDevice
->UsbController
[0] = FirstController
;
954 FirstController
->InterfaceNumber
= 0;
955 FirstController
->ParentPort
= ParentPort
;
956 FirstController
->Parent
= ParentHubController
;
957 FirstController
->HostController
= HostController
;
959 InitializeUsbIoInstance (FirstController
);
961 DEBUG ((gUSBDebugLevel
, "Configuration Usb Device at 0x%x...\n", ParentPort
));
964 // Ensure we used the correctly USB I/O instance
966 UsbIo
= &FirstController
->UsbIo
;
968 if (UsbIoDevice
->DeviceSpeed
!= EFI_USB_SPEED_HIGH
) {
969 ParentPortReset (FirstController
, FALSE
, 0);
973 // First retrieve the 1st 8 bytes of
974 // in order to get the MaxPacketSize for Endpoint 0
976 for (Index
= 0; Index
< 3; Index
++) {
978 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
980 gBS
->Stall (100 * 1000);
982 Result
= UsbGetDescriptor (
984 (USB_DT_DEVICE
<< 8),
987 &UsbIoDevice
->DeviceDescriptor
,
990 if (!EFI_ERROR (Result
)) {
993 "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
994 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
)
1002 ReportUsbStatusCode (
1004 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1005 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1007 DEBUG ((gUSBErrorLevel
, "Get Device Descriptor Fail when configing\n"));
1008 gBS
->FreePool (FirstController
);
1009 return EFI_DEVICE_ERROR
;
1012 DevAddress
= UsbAllocateAddress (UsbIoDevice
->BusController
->AddressPool
);
1013 if (DevAddress
== 0) {
1014 DEBUG ((gUSBErrorLevel
, "Cannot allocate address\n"));
1015 gBS
->FreePool (FirstController
);
1016 return EFI_OUT_OF_RESOURCES
;
1019 Result
= UsbSetDeviceAddress (UsbIo
, DevAddress
, &Status
);
1021 if (EFI_ERROR (Result
)) {
1022 DEBUG ((gUSBErrorLevel
, "Set address error\n"));
1023 ReportUsbStatusCode (
1025 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1026 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1031 UsbIoDevice
->BusController
->AddressPool
1034 gBS
->FreePool (FirstController
);
1035 return EFI_DEVICE_ERROR
;
1038 UsbIoDevice
->DeviceAddress
= DevAddress
;
1041 // SetAddress Complete Time by Spec, Max 50ms
1043 gBS
->Stall (10 * 1000);
1046 // Get the whole device descriptor
1048 Result
= UsbGetDescriptor (
1050 (USB_DT_DEVICE
<< 8),
1052 sizeof (EFI_USB_DEVICE_DESCRIPTOR
),
1053 &UsbIoDevice
->DeviceDescriptor
,
1057 if (EFI_ERROR (Result
)) {
1058 DEBUG ((gUSBErrorLevel
, "Get whole Device Descriptor error\n"));
1059 ReportUsbStatusCode (
1061 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1062 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1066 UsbIoDevice
->BusController
->AddressPool
1069 gBS
->FreePool (FirstController
);
1070 return EFI_DEVICE_ERROR
;
1073 // Get & parse all configurations for this device, including
1074 // all configuration descriptors, all interface descriptors, all
1075 // endpoint descriptors
1077 Result
= UsbGetAllConfigurations (UsbIoDevice
);
1079 if (EFI_ERROR (Result
)) {
1080 DEBUG ((gUSBErrorLevel
, "Failed to get device configuration\n"));
1081 ReportUsbStatusCode (
1083 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1084 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1088 UsbIoDevice
->BusController
->AddressPool
1091 gBS
->FreePool (FirstController
);
1092 return EFI_DEVICE_ERROR
;
1095 // Set the 1st configuration value
1097 Result
= UsbSetDefaultConfiguration (UsbIoDevice
);
1098 if (EFI_ERROR (Result
)) {
1099 DEBUG ((gUSBErrorLevel
, "Failed to set device configuration\n"));
1100 ReportUsbStatusCode (
1102 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1103 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1107 UsbIoDevice
->BusController
->AddressPool
1110 gBS
->FreePool (FirstController
);
1111 return EFI_DEVICE_ERROR
;
1114 UsbIoDevice
->IsConfigured
= TRUE
;
1117 // Get all string table if applicable
1119 Result
= UsbGetStringtable (UsbIoDevice
);
1120 if (EFI_ERROR (Result
)) {
1121 DEBUG ((gUSBDebugLevel
, "Device doesn't support string table\n"));
1124 StrManufacturer
= NULL
;
1125 UsbIo
->UsbGetStringDescriptor (
1127 UsbIoDevice
->LangID
[0],
1128 (UsbIoDevice
->DeviceDescriptor
).StrManufacturer
,
1133 UsbIo
->UsbGetStringDescriptor (
1135 UsbIoDevice
->LangID
[0],
1136 (UsbIoDevice
->DeviceDescriptor
).StrProduct
,
1140 StrSerialNumber
= NULL
;
1141 UsbIo
->UsbGetStringDescriptor (
1143 UsbIoDevice
->LangID
[0],
1144 (UsbIoDevice
->DeviceDescriptor
).StrSerialNumber
,
1148 if (StrManufacturer
) {
1149 gBS
->FreePool (StrManufacturer
);
1153 gBS
->FreePool (StrProduct
);
1156 if (StrSerialNumber
) {
1157 gBS
->FreePool (StrSerialNumber
);
1161 // Create USB_IO_CONTROLLER_DEVICE for
1162 // each detected interface
1164 FirstController
->CurrentConfigValue
=
1165 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1168 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.NumInterfaces
;
1169 UsbIoDevice
->NumOfControllers
= NumOfInterface
;
1171 Result
= InitUsbIoController (FirstController
);
1172 if (EFI_ERROR (Result
)) {
1173 ReportUsbStatusCode (
1175 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1176 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1178 gBS
->FreePool (FirstController
);
1179 UsbIoDevice
->UsbController
[0] = NULL
;
1180 return EFI_DEVICE_ERROR
;
1183 for (Index
= 1; Index
< NumOfInterface
; Index
++) {
1184 UsbIoController
= CreateUsbIoControllerDevice ();
1185 UsbIoController
->UsbDevice
= UsbIoDevice
;
1186 UsbIoController
->CurrentConfigValue
=
1187 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1188 UsbIoController
->InterfaceNumber
= Index
;
1189 UsbIoDevice
->UsbController
[Index
] = UsbIoController
;
1190 UsbIoController
->ParentPort
= ParentPort
;
1191 UsbIoController
->Parent
= ParentHubController
;
1192 UsbIoController
->HostController
= HostController
;
1195 // First copy the USB_IO Protocol instance
1198 &UsbIoController
->UsbIo
,
1200 sizeof (EFI_USB_IO_PROTOCOL
)
1203 Result
= InitUsbIoController (UsbIoController
);
1204 if (EFI_ERROR (Result
)) {
1205 ReportUsbStatusCode (
1207 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1208 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1210 gBS
->FreePool (UsbIoController
);
1211 UsbIoDevice
->UsbController
[Index
] = NULL
;
1218 // USB Device DeConfiguration
1221 UsbDeviceDeConfiguration (
1222 IN USB_IO_DEVICE
*UsbIoDevice
1226 Routine Description:
1227 Remove Device, Device Handles, Uninstall Protocols.
1230 UsbIoDevice - The device to be deconfigured.
1238 USB_IO_CONTROLLER_DEVICE
*UsbController
;
1240 USB_IO_DEVICE
*ChildDevice
;
1242 EFI_USB_IO_PROTOCOL
*UsbIo
;
1246 // Double check UsbIoDevice exists
1248 if (UsbIoDevice
== NULL
) {
1252 UsbUnsetTransactionTranslator (UsbIoDevice
);
1254 for (index
= 0; index
< UsbIoDevice
->NumOfControllers
; index
++) {
1256 // Check if it is a hub, if so, de configuration all its
1259 UsbController
= UsbIoDevice
->UsbController
[index
];
1262 // Check the controller pointer
1264 if (UsbController
== NULL
) {
1268 if (UsbController
->IsUsbHub
) {
1270 DEBUG ((gUSBDebugLevel
, "Hub Deconfig, First Deconfig its downstream ports\n"));
1273 // First Remove interrupt transfer request for the status
1276 UsbIo
= &UsbController
->UsbIo
;
1277 UsbIo
->UsbAsyncInterruptTransfer (
1279 UsbController
->HubEndpointAddress
,
1287 if (NULL
!= UsbController
->HubNotify
) {
1288 gBS
->CloseEvent (UsbController
->HubNotify
);
1291 for (Index
= 0; Index
< UsbController
->DownstreamPorts
; Index
++) {
1292 if (UsbController
->Children
[Index
]) {
1293 ChildDevice
= UsbController
->Children
[Index
];
1294 UsbDeviceDeConfiguration (ChildDevice
);
1295 UsbController
->Children
[Index
] = NULL
;
1300 // If the controller is managed by a device driver, we need to
1303 if (UsbController
->IsManagedByDriver
) {
1304 gBS
->DisconnectController (
1305 UsbController
->Handle
,
1312 // remove child handle reference to the USB_HC_PROTOCOL
1314 if (UsbIoDevice
->BusController
->Hc2ProtocolSupported
) {
1315 gBS
->CloseProtocol (
1316 UsbController
->HostController
,
1317 &gEfiUsb2HcProtocolGuid
,
1318 gUsbBusDriverBinding
.DriverBindingHandle
,
1319 UsbController
->Handle
1322 gBS
->CloseProtocol (
1323 UsbController
->HostController
,
1324 &gEfiUsbHcProtocolGuid
,
1325 gUsbBusDriverBinding
.DriverBindingHandle
,
1326 UsbController
->Handle
1330 // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
1331 // installed on this handle
1333 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1334 UsbController
->Handle
,
1335 &gEfiDevicePathProtocolGuid
,
1336 UsbController
->DevicePath
,
1337 &gEfiUsbIoProtocolGuid
,
1338 &UsbController
->UsbIo
,
1341 if (EFI_ERROR (Status
)) {
1345 if (UsbController
->DevicePath
!= NULL
) {
1346 gBS
->FreePool (UsbController
->DevicePath
);
1349 gBS
->FreePool (UsbController
);
1350 UsbIoDevice
->UsbController
[index
] = NULL
;
1353 // Free address for later use
1356 UsbIoDevice
->DeviceAddress
,
1357 UsbIoDevice
->BusController
->AddressPool
1361 // Free all resouces allocated for all its configurations
1363 UsbDestroyAllConfiguration (UsbIoDevice
);
1366 gBS
->FreePool (UsbIoDevice
);
1373 // After interrupt complete, this function will be called,
1374 // This function need to be well-defined later
1379 OnHubInterruptComplete (
1381 IN UINTN DataLength
,
1387 Routine Description:
1388 Whenever hub interrupt occurs, this routine will be called to check
1389 which event happens.
1392 Data - Hub interrupt transfer data.
1393 DataLength - The length of the Data.
1394 Context - Hub Controller Device.
1395 Result - Hub interrupt transfer status.
1403 USB_IO_CONTROLLER_DEVICE
*HubController
;
1406 EFI_USB_IO_PROTOCOL
*UsbIo
;
1408 BOOLEAN Disconnected
;
1411 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1412 UsbIo
= &HubController
->UsbIo
;
1415 // If something error in this interrupt transfer,
1417 if (Result
!= EFI_USB_NOERROR
) {
1418 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1419 UsbClearEndpointHalt (
1421 HubController
->HubEndpointAddress
,
1427 // Delete & Submit this interrupt again
1429 UsbIo
->UsbAsyncInterruptTransfer (
1431 HubController
->HubEndpointAddress
,
1440 // try to detect if the hub itself was disconnected or not
1442 Status
= IsDeviceDisconnected (
1447 if (!EFI_ERROR (Status
) && Disconnected
== TRUE
) {
1448 DEBUG ((gUSBErrorLevel
, "Hub is disconnected\n"));
1449 return EFI_DEVICE_ERROR
;
1454 UsbIo
->UsbAsyncInterruptTransfer (
1456 HubController
->HubEndpointAddress
,
1460 OnHubInterruptComplete
,
1464 return EFI_DEVICE_ERROR
;
1467 if (DataLength
== 0 || Data
== NULL
) {
1472 // Scan which port has status change
1473 // Bit 0 stands for hub itself, other bit stands for
1474 // the corresponding port
1476 for (Index
= 0; Index
< DataLength
* 8; Index
++) {
1477 ptr
= (UINT8
*) Data
+ Index
/ 8;
1478 if ((*ptr
) & (1 << (Index
& 0x7))) {
1479 HubController
->StatusChangePort
= Index
;
1484 // Signal hub notify event
1486 gBS
->SignalEvent (HubController
->HubNotify
);
1491 // USB Root Hub Enumerator
1496 RootHubEnumeration (
1502 Routine Description:
1504 This is USB RootHub enumerator
1508 Event - Indicating which event is signaled
1509 Context - actually it is a USB_IO_DEVICE
1517 USB_IO_CONTROLLER_DEVICE
*HubController
;
1518 EFI_USB_PORT_STATUS HubPortStatus
;
1521 USB_IO_DEVICE
*UsbIoDev
;
1522 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1523 EFI_HANDLE HostController
;
1524 USB_IO_DEVICE
*OldUsbIoDevice
;
1525 USB_IO_DEVICE
*NewDevice
;
1526 USB_IO_CONTROLLER_DEVICE
*NewController
;
1528 EFI_USB_IO_PROTOCOL
*UsbIo
;
1530 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1531 HostController
= HubController
->HostController
;
1532 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1535 // Root hub has the address 1
1537 UsbIoDev
= HubController
->UsbDevice
;
1539 for (Index
= 0; Index
< HubController
->DownstreamPorts
; Index
++) {
1541 UsbVirtualHcGetRootHubPortStatus (
1544 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1547 if (!IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1551 // Clear root hub status change status
1553 UsbVirtualHcClearRootHubPortFeature (
1556 EfiUsbPortConnectChange
1559 gBS
->Stall (100 * 1000);
1561 UsbVirtualHcGetRootHubPortStatus (
1564 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1567 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1570 // There is something connected to this port
1572 DEBUG ((gUSBDebugLevel
, "Something connected to Root Hub at Port0x%x\n", Index
));
1574 ReportUsbStatusCode (
1577 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1580 // if there is something physically detached, but still logically
1583 OldUsbIoDevice
= HubController
->Children
[Index
];
1585 if (NULL
!= OldUsbIoDevice
) {
1586 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1587 HubController
->Children
[Index
] = NULL
;
1590 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1591 if (NewDevice
== NULL
) {
1595 // Initialize some fields by copying data from
1598 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1599 NewDevice
->BusController
= UsbIoDev
->BusController
;
1602 // Process of identify device speed
1604 Status
= IdentifyDeviceSpeed (
1609 if (EFI_ERROR (Status
)) {
1610 gBS
->FreePool (NewDevice
);
1615 // Configure that device
1617 Status
= UsbDeviceConfiguration (
1623 if (EFI_ERROR (Status
)) {
1624 gBS
->FreePool (NewDevice
);
1628 // Add this device to the usb bus tree
1630 HubController
->Children
[Index
] = NewDevice
;
1632 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
1634 // If this device is hub, add to the hub index
1636 NewController
= NewDevice
->UsbController
[Index2
];
1638 Status
= gBS
->ConnectController (
1639 NewController
->Handle
,
1645 // If connect success, we need to disconnect when
1646 // stop the controller, otherwise we need not call
1647 // gBS->DisconnectController ()
1648 // This is used by those usb devices we don't plan
1649 // to support. We can allocate
1650 // controller handles for them, but we don't have
1651 // device drivers to manage them.
1653 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
1655 if (IsHub (NewController
)) {
1657 NewController
->IsUsbHub
= TRUE
;
1660 // Configure Hub Controller
1662 Status
= DoHubConfig (NewController
);
1663 if (EFI_ERROR (Status
)) {
1667 // Create an event to do hub enumeration
1670 EFI_EVENT_NOTIFY_SIGNAL
,
1674 &NewController
->HubNotify
1678 // Add request to do query hub status
1682 UsbIo
= &NewController
->UsbIo
;
1683 UsbIo
->UsbAsyncInterruptTransfer (
1685 NewController
->HubEndpointAddress
,
1689 OnHubInterruptComplete
,
1697 // Something disconnected from USB root hub
1699 DEBUG ((gUSBDebugLevel
, "Something disconnected from Root Hub at Port0x%x\n", Index
));
1701 OldUsbIoDevice
= HubController
->Children
[Index
];
1703 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1705 HubController
->Children
[Index
] = NULL
;
1707 UsbVirtualHcClearRootHubPortFeature (
1710 EfiUsbPortEnableChange
1718 // USB Root Hub Enumerator
1729 Routine Description:
1731 This is Usb Hub enumerator
1735 Event - Indicating which event is signaled
1736 Context - actually it is a USB_IO_DEVICE
1744 USB_IO_CONTROLLER_DEVICE
*HubController
;
1745 EFI_USB_PORT_STATUS HubPortStatus
;
1747 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1748 EFI_HANDLE HostController
;
1749 USB_IO_DEVICE
*OldUsbIoDevice
;
1750 USB_IO_DEVICE
*NewDevice
;
1751 USB_IO_CONTROLLER_DEVICE
*NewController
;
1753 EFI_USB_IO_PROTOCOL
*UsbIo
;
1754 UINT8 StatusChangePort
;
1757 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1758 HostController
= HubController
->HostController
;
1759 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1762 // Event from Hub, Get the hub controller handle
1765 // Get the status change endpoint
1767 StatusChangePort
= HubController
->StatusChangePort
;
1770 // Clear HubController Status Change Bit
1772 HubController
->StatusChangePort
= 0;
1774 if (StatusChangePort
== 0) {
1776 // Hub changes, we don't handle here
1781 // Check which event took place at that port
1783 UsbIo
= &HubController
->UsbIo
;
1784 Status
= HubGetPortStatus (
1787 (UINT32
*) &HubPortStatus
1790 if (EFI_ERROR (Status
)) {
1794 // Clear some change status
1796 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
1798 // Clear Hub port enable change
1800 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
1801 HubClearPortFeature (
1804 EfiUsbPortEnableChange
1810 (UINT32
*) &HubPortStatus
1814 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
1816 // Clear Hub reset change
1818 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
1819 HubClearPortFeature (
1822 EfiUsbPortResetChange
1828 (UINT32
*) &HubPortStatus
1832 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_OVERCURRENT
) {
1834 // Clear Hub overcurrent change
1836 DEBUG ((gUSBDebugLevel
, "Port Overcurrent Change\n"));
1837 HubClearPortFeature (
1840 EfiUsbPortOverCurrentChange
1846 (UINT32
*) &HubPortStatus
1850 if (IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1852 // First clear port connection change
1854 DEBUG ((gUSBDebugLevel
, "Port Connection Change\n"));
1855 HubClearPortFeature (
1858 EfiUsbPortConnectChange
1864 (UINT32
*) &HubPortStatus
1867 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1869 DEBUG ((gUSBDebugLevel
, "New Device Connect on Hub port \n"));
1871 ReportUsbStatusCode (
1874 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1878 // if there is something physically detached, but still logically
1881 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
1883 if (NULL
!= OldUsbIoDevice
) {
1884 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1885 HubController
->Children
[StatusChangePort
- 1] = NULL
;
1888 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1889 if (NewDevice
== NULL
) {
1893 // Initialize some fields
1895 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1896 NewDevice
->BusController
= HubController
->UsbDevice
->BusController
;
1899 // There is something connected to this port,
1902 // Disable the enable bit in port status
1904 HubClearPortFeature (
1910 gBS
->Stall (50 * 1000);
1913 // Wait for bit change
1920 (UINT32
*) &HubPortStatus
1922 gBS
->Stall (10 * 1000);
1924 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_ENABLE
) == 1 && Number
> 0);
1928 // Cannot disable port, return error
1930 DEBUG ((gUSBErrorLevel
, "Disable Port Failed\n"));
1931 gBS
->FreePool (NewDevice
);
1941 gBS
->Stall (50 * 1000);
1944 // Wait for port reset complete
1951 (UINT32
*) &HubPortStatus
1953 gBS
->Stall (10 * 1000);
1955 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_RESET
) == 1 && Number
> 0);
1959 // Cannot reset port, return error
1961 DEBUG ((gUSBErrorLevel
, "Reset Port Failed\n"));
1962 gBS
->FreePool (NewDevice
);
1966 // Check high speed or full speed device
1968 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
1969 DEBUG ((gUSBDebugLevel
, "Low Speed Device Attached to Hub\n"));
1970 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
1971 } else if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
1972 DEBUG ((gUSBDebugLevel
, "High Speed Device Attached to Hub\n"));
1973 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
1975 DEBUG ((gUSBDebugLevel
, "Full Speed Device Attached to Hub\n"));
1976 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
1979 // Configure that device
1981 Status
= UsbDeviceConfiguration (
1984 (UINT8
) (StatusChangePort
- 1),
1988 if (EFI_ERROR (Status
)) {
1989 gBS
->FreePool (NewDevice
);
1993 // Add this device to the usb bus tree
1994 // StatusChangePort is begin from 1,
1996 HubController
->Children
[StatusChangePort
- 1] = NewDevice
;
1998 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
2000 // If this device is hub, add to the hub index
2002 NewController
= NewDevice
->UsbController
[Index2
];
2005 // Connect the controller to the driver image
2007 Status
= gBS
->ConnectController (
2008 NewController
->Handle
,
2014 // If connect success, we need to disconnect when
2015 // stop the controller, otherwise we need not call
2016 // gBS->DisconnectController ()
2017 // This is used by those usb devices we don't plan
2018 // to support. We can allocate
2019 // controller handles for them, but we don't have
2020 // device drivers to manage them.
2022 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
2025 // If this device is hub, add to the hub index
2027 if (IsHub (NewController
)) {
2029 NewController
->IsUsbHub
= TRUE
;
2034 Status
= DoHubConfig (NewController
);
2036 if (EFI_ERROR (Status
)) {
2040 // Create an event to do hub enumeration
2043 EFI_EVENT_NOTIFY_SIGNAL
,
2047 &NewController
->HubNotify
2051 // Add request to do query hub status
2054 UsbIo
= &NewController
->UsbIo
;
2055 UsbIo
->UsbAsyncInterruptTransfer (
2057 NewController
->HubEndpointAddress
, // Hub endpoint address
2061 OnHubInterruptComplete
,
2068 // Something disconnected from USB hub
2070 DEBUG ((gUSBDebugLevel
, "Something Device Detached on Hub port\n"));
2072 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
2074 UsbDeviceDeConfiguration (OldUsbIoDevice
);
2076 HubController
->Children
[StatusChangePort
- 1] = NULL
;
2087 USB_IO_CONTROLLER_DEVICE
*
2088 CreateUsbIoControllerDevice (
2093 Routine Description:
2094 Allocate a structure for USB_IO_CONTROLLER_DEVICE
2100 A pointer to a USB_IO_CONTROLLER_DEVICE structure,
2105 USB_IO_CONTROLLER_DEVICE
*UsbIoControllerDev
;
2108 // Allocate USB_IO_CONTROLLER_DEVICE structure
2110 UsbIoControllerDev
= NULL
;
2111 UsbIoControllerDev
= AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE
));
2113 if (UsbIoControllerDev
== NULL
) {
2117 UsbIoControllerDev
->Signature
= USB_IO_CONTROLLER_SIGNATURE
;
2119 return UsbIoControllerDev
;
2124 InitUsbIoController (
2125 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
2129 Routine Description:
2130 Init and install EFI_USB_IO_PROTOCOL onto that controller.
2133 UsbIoController - The Controller to be operated.
2141 USB_DEVICE_PATH UsbNode
;
2143 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
2144 EFI_USB_HC_PROTOCOL
*UsbHcProtocol
;
2145 EFI_USB2_HC_PROTOCOL
*Usb2HcProtocol
;
2148 // Build the child device path for each new USB_IO device
2150 ZeroMem (&UsbNode
, sizeof (UsbNode
));
2151 UsbNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
2152 UsbNode
.Header
.SubType
= MSG_USB_DP
;
2153 SetDevicePathNodeLength (&UsbNode
.Header
, sizeof (UsbNode
));
2154 UsbNode
.InterfaceNumber
= UsbIoController
->InterfaceNumber
;
2155 UsbNode
.ParentPortNumber
= UsbIoController
->ParentPort
;
2156 ParentDevicePath
= UsbIoController
->Parent
->DevicePath
;
2158 UsbIoController
->DevicePath
=
2159 AppendDevicePathNode (ParentDevicePath
, &UsbNode
.Header
);
2160 if (UsbIoController
->DevicePath
== NULL
) {
2161 return EFI_OUT_OF_RESOURCES
;
2164 Status
= gBS
->InstallMultipleProtocolInterfaces (
2165 &UsbIoController
->Handle
,
2166 &gEfiDevicePathProtocolGuid
,
2167 UsbIoController
->DevicePath
,
2168 &gEfiUsbIoProtocolGuid
,
2169 &UsbIoController
->UsbIo
,
2173 if (EFI_ERROR (Status
)) {
2177 if (UsbIoController
->UsbDevice
->BusController
->Hc2ProtocolSupported
) {
2178 Status
= gBS
->OpenProtocol (
2179 UsbIoController
->HostController
,
2180 &gEfiUsb2HcProtocolGuid
,
2181 (VOID
**)&Usb2HcProtocol
,
2182 gUsbBusDriverBinding
.DriverBindingHandle
,
2183 UsbIoController
->Handle
,
2184 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2187 Status
= gBS
->OpenProtocol (
2188 UsbIoController
->HostController
,
2189 &gEfiUsbHcProtocolGuid
,
2190 (VOID
**)&UsbHcProtocol
,
2191 gUsbBusDriverBinding
.DriverBindingHandle
,
2192 UsbIoController
->Handle
,
2193 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2203 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2204 IN BOOLEAN ReConfigure
,
2209 Routine Description:
2210 Reset parent hub port to which this device is connected.
2213 UsbIoController - Indicating the Usb Controller Device.
2214 ReConfigure - Do we need to reconfigure it.
2215 RetryTimes - Retry Times when failed
2223 USB_IO_DEVICE
*ParentIoDev
;
2224 USB_IO_DEVICE
*UsbIoDev
;
2225 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2229 EFI_USB_IO_PROTOCOL
*UsbIo
;
2232 ParentController
= UsbIoController
->Parent
;
2233 ParentIoDev
= ParentController
->UsbDevice
;
2234 UsbIoDev
= UsbIoController
->UsbDevice
;
2235 HubPort
= UsbIoController
->ParentPort
;
2237 gBS
->Stall (100 * 1000);
2239 if (ParentIoDev
->DeviceAddress
== 1) {
2240 DEBUG ((gUSBDebugLevel
, "Reset from Root Hub 0x%x\n", HubPort
));
2241 ResetRootPort (ParentIoDev
->BusController
, HubPort
, RetryTimes
);
2243 DEBUG ((gUSBDebugLevel
, "Reset from Hub, Addr 0x%x\n", ParentIoDev
->DeviceAddress
));
2244 ResetHubPort (ParentController
, (UINT8
) (HubPort
+ 1));
2247 // If we only need port reset, just return
2253 // Re-config that USB device
2255 UsbIo
= &UsbIoController
->UsbIo
;
2258 // Assign a unique address to this device
2260 Address
= UsbIoDev
->DeviceAddress
;
2261 UsbIoDev
->DeviceAddress
= 0;
2263 Result
= UsbSetDeviceAddress (UsbIo
, Address
, &Status
);
2264 UsbIoDev
->DeviceAddress
= Address
;
2266 if (EFI_ERROR (Result
)) {
2267 return EFI_DEVICE_ERROR
;
2270 // Set the device to the default configuration
2272 Result
= UsbSetDefaultConfiguration (UsbIoDev
);
2273 if (EFI_ERROR (Result
)) {
2274 return EFI_DEVICE_ERROR
;
2283 IN EFI_USB_IO_PROTOCOL
*This
2287 Routine Description:
2288 Resets and reconfigures the USB controller. This function will
2289 work for all USB devices except USB Hub Controllers.
2292 This - Indicates the calling context.
2296 EFI_INVALID_PARAMETER
2301 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
2303 UsbIoController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This
);
2305 if (IsHub (UsbIoController
)) {
2306 return EFI_INVALID_PARAMETER
;
2310 // Since at this time, this device has already been configured,
2311 // it needs to be re-configured.
2313 return ParentPortReset (UsbIoController
, TRUE
, 0);
2319 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2325 Routine Description:
2326 Reset Root Hub port.
2329 UsbBusDev - Bus controller of the device.
2330 PortNum - The given port to be reset.
2331 RetryTimes - RetryTimes when failed
2340 EFI_USB_PORT_STATUS PortStatus
;
2345 Status
= UsbVirtualHcSetRootHubPortFeature (
2350 if (EFI_ERROR (Status
)) {
2351 return EFI_DEVICE_ERROR
;
2354 gBS
->Stall (50 * 1000);
2357 // clear reset root port
2359 Status
= UsbVirtualHcClearRootHubPortFeature (
2364 if (EFI_ERROR (Status
)) {
2365 return EFI_DEVICE_ERROR
;
2370 Status
= UsbVirtualHcClearRootHubPortFeature (
2373 EfiUsbPortConnectChange
2375 if (EFI_ERROR (Status
)) {
2376 return EFI_DEVICE_ERROR
;
2379 UsbVirtualHcGetRootHubPortStatus (
2384 if (PortStatus
.PortStatus
& USB_PORT_STAT_OWNER
) {
2388 Status
= UsbVirtualHcSetRootHubPortFeature (
2393 if (EFI_ERROR (Status
)) {
2394 return EFI_DEVICE_ERROR
;
2397 Status
= UsbVirtualHcClearRootHubPortFeature (
2400 EfiUsbPortEnableChange
2404 gBS
->Stall ((1 + RetryTimes
) * 50 * 1000);
2412 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2417 Routine Description:
2421 UsbIoController - The USB_IO_CONTROLLER_DEVICE instance.
2422 PortIndex - The given port to be reset.
2430 EFI_USB_IO_PROTOCOL
*UsbIo
;
2431 EFI_USB_PORT_STATUS HubPortStatus
;
2434 ASSERT (UsbIoController
->IsUsbHub
== TRUE
);
2436 UsbIo
= &UsbIoController
->UsbIo
;
2444 gBS
->Stall (10 * 1000);
2447 // Wait for port reset complete
2454 (UINT32
*) &HubPortStatus
2456 gBS
->Stall (10 * 100);
2458 } while ((HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) == 0 && Number
> 0);
2462 // Cannot reset port, return error
2464 return EFI_DEVICE_ERROR
;
2472 (UINT32
*) &HubPortStatus
2475 // reset port will cause some bits change, clear them
2477 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
2478 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
2479 HubClearPortFeature (
2482 EfiUsbPortEnableChange
2486 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
2487 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
2488 HubClearPortFeature (
2491 EfiUsbPortResetChange
2500 ReportUsbStatusCode (
2501 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
2502 IN EFI_STATUS_CODE_TYPE Type
,
2503 IN EFI_STATUS_CODE_VALUE Code
2507 Routine Description:
2509 report a error Status code of USB bus driver controller
2512 UsbBusController - USB_BUS_CONTROLLER_DEVICE
2513 Type - EFI_STATUS_CODE_TYPE
2514 Code - EFI_STATUS_CODE_VALUE
2521 return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
2524 UsbBusController
->DevicePath
2529 IsDeviceDisconnected (
2530 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2531 IN OUT BOOLEAN
*Disconnected
2535 Routine Description:
2536 Reset if the device is disconencted or not
2539 UsbIoController - Indicating the Usb Controller Device.
2540 Disconnected - Indicate whether the device is disconencted or not
2548 USB_IO_DEVICE
*ParentIoDev
;
2549 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2552 EFI_USB_PORT_STATUS PortStatus
;
2554 ParentController
= UsbIoController
->Parent
;
2555 ParentIoDev
= ParentController
->UsbDevice
;
2556 HubPort
= UsbIoController
->ParentPort
;
2558 if (ParentIoDev
->DeviceAddress
== 1) {
2560 // Connected to the root hub
2562 UsbVirtualHcGetRootHubPortStatus (
2563 ParentIoDev
->BusController
,
2569 Status
= HubGetPortStatus (
2570 &ParentController
->UsbIo
,
2571 (UINT8
) (HubPort
+ 1),
2572 (UINT32
*) &PortStatus
2575 if (EFI_ERROR (Status
)) {
2576 return IsDeviceDisconnected (ParentController
, Disconnected
);
2580 *Disconnected
= FALSE
;
2582 if (!IsPortConnect (PortStatus
.PortStatus
)) {
2583 *Disconnected
= TRUE
;
2591 UsbSetTransactionTranslator (
2592 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
2593 IN UINT8 ParentPort
,
2594 IN OUT USB_IO_DEVICE
*Device
2598 Routine Description:
2600 Set Transaction Translator parameter
2604 ParentHubController - Controller structure of the parent Hub device
2605 ParentPort - Number of parent port
2606 Device - Structure of the device
2611 EFI_OUT_OF_RESOURCES Cannot allocate resources
2615 USB_IO_CONTROLLER_DEVICE
*AncestorHubController
;
2617 AncestorHubController
= ParentHubController
;
2618 Device
->Translator
= NULL
;
2620 if (EFI_USB_SPEED_HIGH
== Device
->DeviceSpeed
) {
2625 if (EFI_USB_SPEED_HIGH
== AncestorHubController
->UsbDevice
->DeviceSpeed
) {
2629 if (NULL
== AncestorHubController
->Parent
) {
2633 AncestorHubController
= AncestorHubController
->Parent
;
2636 Device
->Translator
= AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR
));
2637 if (NULL
== Device
->Translator
) {
2638 return EFI_OUT_OF_RESOURCES
;
2641 Device
->Translator
->TranslatorHubAddress
= AncestorHubController
->UsbDevice
->DeviceAddress
;
2642 Device
->Translator
->TranslatorPortNumber
= ParentPort
;
2649 UsbUnsetTransactionTranslator (
2650 USB_IO_DEVICE
*Device
2654 Routine Description:
2656 Unset Transaction Translator parameter
2660 Device - Structure of the device
2668 if (Device
->Translator
) {
2669 gBS
->FreePool (Device
->Translator
);
2670 Device
->Translator
= NULL
;
2678 IdentifyDeviceSpeed (
2679 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2680 USB_IO_DEVICE
*NewDevice
,
2685 Routine Description:
2687 Identify speed of USB device
2691 UsbBusDev - UsbBus controller structure of the device
2692 NewDevice - Devcie controller structure
2693 Index - Number of the port
2698 EFI_NOT_FOUND Device release to CHC or can't be found
2703 EFI_USB_PORT_STATUS HubPortStatus
;
2705 UsbVirtualHcGetRootHubPortStatus (
2708 (EFI_USB_PORT_STATUS
*) &HubPortStatus
2712 // Check device device
2714 if (!(HubPortStatus
.PortStatus
& USB_PORT_STAT_OWNER
)) {
2718 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2719 DEBUG ((gUSBDebugLevel
, "High Speed Device attached to EHC\n"));
2720 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2722 Status
= ReleasePortToCHC (UsbBusDev
, Index
);
2723 if (EFI_ERROR (Status
)) {
2724 DEBUG ((gUSBErrorLevel
, "Fail to release port to CHC\n"));
2726 DEBUG ((gUSBDebugLevel
, "Success to release port to CHC\n"));
2728 return EFI_DEVICE_ERROR
;
2734 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
2735 DEBUG ((gUSBDebugLevel
, "Low Speed Device attached to CHC\n"));
2736 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
2738 DEBUG ((gUSBDebugLevel
, "FULL Speed Device attached to CHC\n"));
2739 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2749 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2754 Routine Description:
2756 Set bit to release the port owner to CHC
2760 UsbBusDev - UsbBus controller structure of the device
2761 PortNum - Number of the port
2766 EFI_DEVICE_ERROR Fail
2772 Status
= UsbVirtualHcSetRootHubPortFeature (
2778 gBS
->Stall (100 * 1000);
2785 UsbVirtualHcGetCapability (
2786 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2787 OUT UINT8
*MaxSpeed
,
2788 OUT UINT8
*PortNumber
,
2789 OUT UINT8
*Is64BitCapable
2793 Routine Description:
2795 Virtual interface to Retrieves the capablility of root hub ports
2796 for both Hc2 and Hc protocol.
2800 UsbBusDev - A pointer to bus controller of the device.
2801 MaxSpeed - A pointer to the number of the host controller.
2802 PortNumber - A pointer to the number of the root hub ports.
2803 Is64BitCapable - A pointer to the flag for whether controller supports
2804 64-bit memory addressing.
2809 The host controller capability were retrieved successfully.
2810 EFI_INVALID_PARAMETER
2811 MaxSpeed or PortNumber or Is64BitCapable is NULL.
2813 An error was encountered while attempting to retrieve the capabilities.
2819 Status
= EFI_SUCCESS
;
2821 if (UsbBusDev
->Hc2ProtocolSupported
) {
2822 Status
= UsbBusDev
->Usb2HCInterface
->GetCapability (
2823 UsbBusDev
->Usb2HCInterface
,
2829 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortNumber (
2830 UsbBusDev
->UsbHCInterface
,
2833 *MaxSpeed
= EFI_USB_SPEED_FULL
;
2834 *Is64BitCapable
= (UINT8
) FALSE
;
2843 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2844 IN UINT16 Attributes
2848 Routine Description:
2850 Virtual interface to provides software reset for the USB host controller
2851 for both Hc2 and Hc protocol.
2855 UsbBusDev - A pointer to bus controller of the device.
2856 Attributes - A bit mask of the reset operation to perform.
2857 See below for a list of the supported bit mask values.
2859 #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc
2860 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
2861 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
2862 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
2864 EFI_USB_HC_RESET_GLOBAL
2865 If this bit is set, a global reset signal will be sent to the USB bus.
2866 This resets all of the USB bus logic, including the USB host
2867 controller hardware and all the devices attached on the USB bus.
2868 EFI_USB_HC_RESET_HOST_CONTROLLER
2869 If this bit is set, the USB host controller hardware will be reset.
2870 No reset signal will be sent to the USB bus.
2871 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
2872 If this bit is set, a global reset signal will be sent to the USB bus.
2873 This resets all of the USB bus logic, including the USB host
2874 controller hardware and all the devices attached on the USB bus.
2875 If this is an EHCI controller and the debug port has configured, then
2876 this is will still reset the host controller.
2877 EFI_USB_HC_RESET_HOST_WITH_DEBUG
2878 If this bit is set, the USB host controller hardware will be reset.
2879 If this is an EHCI controller and the debug port has been configured,
2880 then this will still reset the host controller.
2885 The reset operation succeeded.
2886 EFI_INVALID_PARAMETER
2887 Attributes is not valid.
2889 The type of reset specified by Attributes is not currently supported by
2890 the host controller hardware.
2892 Reset operation is rejected due to the debug port being configured and
2893 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
2894 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
2895 perform reset operation for this host controller.
2897 An error was encountered while attempting to perform
2898 the reset operation.
2904 Status
= EFI_SUCCESS
;
2906 if (UsbBusDev
->Hc2ProtocolSupported
) {
2907 Status
= UsbBusDev
->Usb2HCInterface
->Reset (
2908 UsbBusDev
->Usb2HCInterface
,
2909 EFI_USB_HC_RESET_GLOBAL
2912 Status
= UsbBusDev
->UsbHCInterface
->Reset (
2913 UsbBusDev
->UsbHCInterface
,
2914 EFI_USB_HC_RESET_GLOBAL
2923 UsbVirtualHcGetState (
2924 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2925 OUT EFI_USB_HC_STATE
*State
2929 Routine Description:
2931 Virtual interface to retrieves current state of the USB host controller
2932 for both Hc2 and Hc protocol.
2936 UsbBusDev - A pointer to bus controller of the device.
2937 State - A pointer to the EFI_USB_HC_STATE data structure that
2938 indicates current state of the USB host controller.
2939 Type EFI_USB_HC_STATE is defined below.
2943 EfiUsbHcStateOperational,
2944 EfiUsbHcStateSuspend,
2945 EfiUsbHcStateMaximum
2951 The state information of the host controller was returned in State.
2952 EFI_INVALID_PARAMETER
2955 An error was encountered while attempting to retrieve the
2956 host controller's current state.
2962 Status
= EFI_SUCCESS
;
2964 if (UsbBusDev
->Hc2ProtocolSupported
) {
2965 Status
= UsbBusDev
->Usb2HCInterface
->GetState (
2966 UsbBusDev
->Usb2HCInterface
,
2970 Status
= UsbBusDev
->UsbHCInterface
->GetState (
2971 UsbBusDev
->UsbHCInterface
,
2981 UsbVirtualHcSetState (
2982 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2983 IN EFI_USB_HC_STATE State
2987 Routine Description:
2989 Virtual interface to sets the USB host controller to a specific state
2990 for both Hc2 and Hc protocol.
2994 UsbBusDev - A pointer to bus controller of the device.
2995 State - Indicates the state of the host controller that will be set.
3000 The USB host controller was successfully placed in the state
3002 EFI_INVALID_PARAMETER
3005 Failed to set the state specified by State due to device error.
3011 Status
= EFI_SUCCESS
;
3013 if (UsbBusDev
->Hc2ProtocolSupported
) {
3014 Status
= UsbBusDev
->Usb2HCInterface
->SetState (
3015 UsbBusDev
->Usb2HCInterface
,
3019 Status
= UsbBusDev
->UsbHCInterface
->SetState (
3020 UsbBusDev
->UsbHCInterface
,
3030 UsbVirtualHcGetRootHubPortStatus (
3031 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3032 IN UINT8 PortNumber
,
3033 OUT EFI_USB_PORT_STATUS
*PortStatus
3037 Routine Description:
3039 Virtual interface to retrieves the current status of a USB root hub port
3040 both for Hc2 and Hc protocol.
3044 UsbBusDev - A pointer to bus controller of the device.
3045 PortNumber - Specifies the root hub port from which the status
3046 is to be retrieved. This value is zero-based. For example,
3047 if a root hub has two ports, then the first port is numbered 0,
3048 and the second port is numbered 1.
3049 PortStatus - A pointer to the current port status bits and
3050 port status change bits.
3054 EFI_SUCCESS The status of the USB root hub port specified by PortNumber
3055 was returned in PortStatus.
3056 EFI_INVALID_PARAMETER PortNumber is invalid.
3057 EFI_DEVICE_ERROR Can't read register
3063 Status
= EFI_SUCCESS
;
3065 if (UsbBusDev
->Hc2ProtocolSupported
) {
3066 Status
= UsbBusDev
->Usb2HCInterface
->GetRootHubPortStatus (
3067 UsbBusDev
->Usb2HCInterface
,
3072 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortStatus (
3073 UsbBusDev
->UsbHCInterface
,
3084 UsbVirtualHcSetRootHubPortFeature (
3085 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3086 IN UINT8 PortNumber
,
3087 IN EFI_USB_PORT_FEATURE PortFeature
3091 Routine Description:
3092 Virual interface to sets a feature for the specified root hub port
3093 for both Hc2 and Hc protocol.
3097 UsbBusDev - A pointer to bus controller of the device.
3098 PortNumber - Specifies the root hub port whose feature
3099 is requested to be set.
3100 PortFeature - Indicates the feature selector associated
3101 with the feature set request.
3106 The feature specified by PortFeature was set for the
3107 USB root hub port specified by PortNumber.
3108 EFI_INVALID_PARAMETER
3109 PortNumber is invalid or PortFeature is invalid.
3117 Status
= EFI_SUCCESS
;
3119 if (UsbBusDev
->Hc2ProtocolSupported
) {
3120 Status
= UsbBusDev
->Usb2HCInterface
->SetRootHubPortFeature (
3121 UsbBusDev
->Usb2HCInterface
,
3126 Status
= UsbBusDev
->UsbHCInterface
->SetRootHubPortFeature (
3127 UsbBusDev
->UsbHCInterface
,
3138 UsbVirtualHcClearRootHubPortFeature (
3139 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3140 IN UINT8 PortNumber
,
3141 IN EFI_USB_PORT_FEATURE PortFeature
3145 Routine Description:
3147 Virtual interface to clears a feature for the specified root hub port
3148 for both Hc2 and Hc protocol.
3152 UsbBusDev - A pointer to bus controller of the device.
3153 PortNumber - Specifies the root hub port whose feature
3154 is requested to be cleared.
3155 PortFeature - Indicates the feature selector associated with the
3156 feature clear request.
3161 The feature specified by PortFeature was cleared for the
3162 USB root hub port specified by PortNumber.
3163 EFI_INVALID_PARAMETER
3164 PortNumber is invalid or PortFeature is invalid.
3172 Status
= EFI_SUCCESS
;
3174 if (UsbBusDev
->Hc2ProtocolSupported
) {
3175 Status
= UsbBusDev
->Usb2HCInterface
->ClearRootHubPortFeature (
3176 UsbBusDev
->Usb2HCInterface
,
3181 Status
= UsbBusDev
->UsbHCInterface
->ClearRootHubPortFeature (
3182 UsbBusDev
->UsbHCInterface
,
3193 UsbVirtualHcControlTransfer (
3194 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3195 IN UINT8 DeviceAddress
,
3196 IN UINT8 DeviceSpeed
,
3197 IN UINTN MaximumPacketLength
,
3198 IN EFI_USB_DEVICE_REQUEST
*Request
,
3199 IN EFI_USB_DATA_DIRECTION TransferDirection
,
3201 IN OUT UINTN
*DataLength
,
3203 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3204 OUT UINT32
*TransferResult
3208 Routine Description:
3210 Virtual interface to submits control transfer to a target USB device
3211 for both Hc2 and Hc protocol.
3215 UsbBusDev - A pointer to bus controller of the device.
3216 DeviceAddress - Represents the address of the target device on the USB,
3217 which is assigned during USB enumeration.
3218 DeviceSpeed - Indicates target device speed.
3219 MaximumPacketLength - Indicates the maximum packet size that the
3220 default control transfer endpoint is capable of
3221 sending or receiving.
3222 Request - A pointer to the USB device request that will be sent
3224 TransferDirection - Specifies the data direction for the transfer.
3225 There are three values available, DataIn, DataOut
3227 Data - A pointer to the buffer of data that will be transmitted
3228 to USB device or received from USB device.
3229 DataLength - Indicates the size, in bytes, of the data buffer
3231 TimeOut - Indicates the maximum time, in microseconds,
3232 which the transfer is allowed to complete.
3233 Translator - A pointr to the transaction translator data.
3234 TransferResult - A pointer to the detailed result information generated
3235 by this control transfer.
3240 The control transfer was completed successfully.
3241 EFI_OUT_OF_RESOURCES
3242 The control transfer could not be completed due to a lack of resources.
3243 EFI_INVALID_PARAMETER
3244 Some parameters are invalid.
3246 The control transfer failed due to timeout.
3248 The control transfer failed due to host controller or device error.
3249 Caller should check TranferResult for detailed error information.
3254 BOOLEAN IsSlowDevice
;
3256 Status
= EFI_SUCCESS
;
3258 if (UsbBusDev
->Hc2ProtocolSupported
) {
3259 Status
= UsbBusDev
->Usb2HCInterface
->ControlTransfer (
3260 UsbBusDev
->Usb2HCInterface
,
3263 MaximumPacketLength
,
3273 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
3274 Status
= UsbBusDev
->UsbHCInterface
->ControlTransfer (
3275 UsbBusDev
->UsbHCInterface
,
3278 (UINT8
) MaximumPacketLength
,
3293 UsbVirtualHcBulkTransfer (
3294 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3295 IN UINT8 DeviceAddress
,
3296 IN UINT8 EndPointAddress
,
3297 IN UINT8 DeviceSpeed
,
3298 IN UINTN MaximumPacketLength
,
3299 IN UINT8 DataBuffersNumber
,
3300 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
3301 IN OUT UINTN
*DataLength
,
3302 IN OUT UINT8
*DataToggle
,
3304 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3305 OUT UINT32
*TransferResult
3309 Routine Description:
3311 Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
3312 both for Hc2 and Hc protocol.
3316 UsbBusDev - A pointer to bus controller of the device.
3317 DeviceAddress - Represents the address of the target device on the USB,
3318 which is assigned during USB enumeration.
3319 EndPointAddress - The combination of an endpoint number and an
3320 endpoint direction of the target USB device.
3321 Each endpoint address supports data transfer in
3322 one direction except the control endpoint
3323 (whose default endpoint address is 0).
3324 It is the caller's responsibility to make sure that
3325 the EndPointAddress represents a bulk endpoint.
3326 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
3327 and EFI_USB_SPEED_HIGH.
3328 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3329 is capable of sending or receiving.
3330 DataBuffersNumber - Number of data buffers prepared for the transfer.
3331 Data - Array of pointers to the buffers of data that will be transmitted
3332 to USB device or received from USB device.
3333 DataLength - When input, indicates the size, in bytes, of the data buffer
3334 specified by Data. When output, indicates the actually
3335 transferred data size.
3336 DataToggle - A pointer to the data toggle value. On input, it indicates
3337 the initial data toggle value the bulk transfer should adopt;
3338 on output, it is updated to indicate the data toggle value
3339 of the subsequent bulk transfer.
3340 Translator - A pointr to the transaction translator data.
3341 TimeOut - Indicates the maximum time, in microseconds, which the
3342 transfer is allowed to complete.
3343 TransferResult - A pointer to the detailed result information of the
3349 The bulk transfer was completed successfully.
3350 EFI_OUT_OF_RESOURCES
3351 The bulk transfer could not be submitted due to lack of resource.
3352 EFI_INVALID_PARAMETER
3353 Some parameters are invalid.
3355 The bulk transfer failed due to timeout.
3357 The bulk transfer failed due to host controller or device error.
3358 Caller should check TranferResult for detailed error information.
3364 Status
= EFI_SUCCESS
;
3366 if (UsbBusDev
->Hc2ProtocolSupported
) {
3367 Status
= UsbBusDev
->Usb2HCInterface
->BulkTransfer (
3368 UsbBusDev
->Usb2HCInterface
,
3372 MaximumPacketLength
,
3382 Status
= UsbBusDev
->UsbHCInterface
->BulkTransfer (
3383 UsbBusDev
->UsbHCInterface
,
3386 (UINT8
) MaximumPacketLength
,
3400 UsbVirtualHcAsyncInterruptTransfer (
3401 IN USB_BUS_CONTROLLER_DEVICE
* UsbBusDev
,
3402 IN UINT8 DeviceAddress
,
3403 IN UINT8 EndPointAddress
,
3404 IN UINT8 DeviceSpeed
,
3405 IN UINTN MaximumPacketLength
,
3406 IN BOOLEAN IsNewTransfer
,
3407 IN OUT UINT8
*DataToggle
,
3408 IN UINTN PollingInterval
,
3409 IN UINTN DataLength
,
3410 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
3411 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
3412 IN VOID
*Context OPTIONAL
3416 Routine Description:
3418 Virtual interface to submits an asynchronous interrupt transfer to an
3419 interrupt endpoint of a USB device for both Hc2 and Hc protocol.
3423 UsbBusDev - A pointer to bus controller of the device.
3424 DeviceAddress - Represents the address of the target device on the USB,
3425 which is assigned during USB enumeration.
3426 EndPointAddress - The combination of an endpoint number and an endpoint
3427 direction of the target USB device. Each endpoint address
3428 supports data transfer in one direction except the
3429 control endpoint (whose default endpoint address is 0).
3430 It is the caller's responsibility to make sure that
3431 the EndPointAddress represents an interrupt endpoint.
3432 DeviceSpeed - Indicates device speed.
3433 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3434 is capable of sending or receiving.
3435 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
3436 the host and the target interrupt endpoint.
3437 If FALSE, the specified asynchronous interrupt pipe
3439 DataToggle - A pointer to the data toggle value. On input, it is valid
3440 when IsNewTransfer is TRUE, and it indicates the initial
3441 data toggle value the asynchronous interrupt transfer
3443 On output, it is valid when IsNewTransfer is FALSE,
3444 and it is updated to indicate the data toggle value of
3445 the subsequent asynchronous interrupt transfer.
3446 PollingInterval - Indicates the interval, in milliseconds, that the
3447 asynchronous interrupt transfer is polled.
3448 This parameter is required when IsNewTransfer is TRUE.
3449 DataLength - Indicates the length of data to be received at the
3450 rate specified by PollingInterval from the target
3451 asynchronous interrupt endpoint. This parameter
3452 is only required when IsNewTransfer is TRUE.
3453 Translator - A pointr to the transaction translator data.
3454 CallBackFunction - The Callback function.This function is called at the
3455 rate specified by PollingInterval.This parameter is
3456 only required when IsNewTransfer is TRUE.
3457 Context - The context that is passed to the CallBackFunction.
3458 - This is an optional parameter and may be NULL.
3463 The asynchronous interrupt transfer request has been successfully
3464 submitted or canceled.
3465 EFI_INVALID_PARAMETER
3466 Some parameters are invalid.
3467 EFI_OUT_OF_RESOURCES
3468 The request could not be completed due to a lack of resources.
3475 BOOLEAN IsSlowDevice
;
3477 Status
= EFI_SUCCESS
;
3479 if (UsbBusDev
->Hc2ProtocolSupported
) {
3480 Status
= UsbBusDev
->Usb2HCInterface
->AsyncInterruptTransfer (
3481 UsbBusDev
->Usb2HCInterface
,
3485 MaximumPacketLength
,
3495 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
3496 Status
= UsbBusDev
->UsbHCInterface
->AsyncInterruptTransfer (
3497 UsbBusDev
->UsbHCInterface
,
3501 (UINT8
) MaximumPacketLength
,
3516 UsbVirtualHcSyncInterruptTransfer (
3517 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3518 IN UINT8 DeviceAddress
,
3519 IN UINT8 EndPointAddress
,
3520 IN UINT8 DeviceSpeed
,
3521 IN UINTN MaximumPacketLength
,
3523 IN OUT UINTN
*DataLength
,
3524 IN OUT UINT8
*DataToggle
,
3526 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3527 OUT UINT32
*TransferResult
3531 Routine Description:
3533 Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
3534 of a USB device for both Hc2 and Hc protocol.
3538 UsbBusDev - A pointer to bus controller of the device.
3539 DeviceAddress - Represents the address of the target device on the USB,
3540 which is assigned during USB enumeration.
3541 EndPointAddress - The combination of an endpoint number and an endpoint
3542 direction of the target USB device. Each endpoint
3543 address supports data transfer in one direction
3544 except the control endpoint (whose default
3545 endpoint address is 0). It is the caller's responsibility
3546 to make sure that the EndPointAddress represents
3547 an interrupt endpoint.
3548 DeviceSpeed - Indicates device speed.
3549 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3550 is capable of sending or receiving.
3551 Data - A pointer to the buffer of data that will be transmitted
3552 to USB device or received from USB device.
3553 DataLength - On input, the size, in bytes, of the data buffer specified
3554 by Data. On output, the number of bytes transferred.
3555 DataToggle - A pointer to the data toggle value. On input, it indicates
3556 the initial data toggle value the synchronous interrupt
3557 transfer should adopt;
3558 on output, it is updated to indicate the data toggle value
3559 of the subsequent synchronous interrupt transfer.
3560 TimeOut - Indicates the maximum time, in microseconds, which the
3561 transfer is allowed to complete.
3562 Translator - A pointr to the transaction translator data.
3563 TransferResult - A pointer to the detailed result information from
3564 the synchronous interrupt transfer.
3569 The synchronous interrupt transfer was completed successfully.
3570 EFI_OUT_OF_RESOURCES
3571 The synchronous interrupt transfer could not be submitted due
3572 to lack of resource.
3573 EFI_INVALID_PARAMETER
3574 Some parameters are invalid.
3576 The synchronous interrupt transfer failed due to timeout.
3578 The synchronous interrupt transfer failed due to host controller
3579 or device error. Caller should check TranferResult for detailed
3585 BOOLEAN IsSlowDevice
;
3587 Status
= EFI_SUCCESS
;
3589 if (UsbBusDev
->Hc2ProtocolSupported
) {
3590 Status
= UsbBusDev
->Usb2HCInterface
->SyncInterruptTransfer (
3591 UsbBusDev
->Usb2HCInterface
,
3595 MaximumPacketLength
,
3604 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
3605 Status
= UsbBusDev
->UsbHCInterface
->SyncInterruptTransfer (
3606 UsbBusDev
->UsbHCInterface
,
3610 (UINT8
) MaximumPacketLength
,
3624 UsbVirtualHcIsochronousTransfer (
3625 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3626 IN UINT8 DeviceAddress
,
3627 IN UINT8 EndPointAddress
,
3628 IN UINT8 DeviceSpeed
,
3629 IN UINTN MaximumPacketLength
,
3630 IN UINT8 DataBuffersNumber
,
3631 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3632 IN UINTN DataLength
,
3633 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3634 OUT UINT32
*TransferResult
3638 Routine Description:
3640 Virtual interface to submits isochronous transfer to a target USB device
3641 for both Hc2 and Hc protocol.
3645 UsbBusDev - A pointer to bus controller of the device.
3646 DeviceAddress - Represents the address of the target device on the USB,
3647 which is assigned during USB enumeration.
3648 EndPointAddress - End point address
3649 DeviceSpeed - Indicates device speed.
3650 MaximumPacketLength - Indicates the maximum packet size that the
3651 default control transfer endpoint is capable of
3652 sending or receiving.
3653 DataBuffersNumber - Number of data buffers prepared for the transfer.
3654 Data - Array of pointers to the buffers of data that will be
3655 transmitted to USB device or received from USB device.
3656 DataLength - Indicates the size, in bytes, of the data buffer
3658 Translator - A pointr to the transaction translator data.
3659 TransferResult - A pointer to the detailed result information generated
3660 by this control transfer.
3668 return EFI_UNSUPPORTED
;
3673 UsbVirtualHcAsyncIsochronousTransfer (
3674 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3675 IN UINT8 DeviceAddress
,
3676 IN UINT8 EndPointAddress
,
3677 IN UINT8 DeviceSpeed
,
3678 IN UINTN MaximumPacketLength
,
3679 IN UINT8 DataBuffersNumber
,
3680 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3681 IN UINTN DataLength
,
3682 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3683 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
3688 Routine Description:
3690 Vitual interface to submits Async isochronous transfer to a target USB device
3691 for both Hc2 and Hc protocol.
3695 UsbBusDev - A pointer to bus controller of the device.
3696 DeviceAddress - Represents the address of the target device on the USB,
3697 which is assigned during USB enumeration.
3698 EndPointAddress - End point address
3699 DeviceSpeed - Indicates device speed.
3700 MaximumPacketLength - Indicates the maximum packet size that the
3701 default control transfer endpoint is capable of
3702 sending or receiving.
3703 DataBuffersNumber - Number of data buffers prepared for the transfer.
3704 Data - Array of pointers to the buffers of data that will be transmitted
3705 to USB device or received from USB device.
3706 DataLength - Indicates the size, in bytes, of the data buffer
3708 Translator - A pointr to the transaction translator data.
3709 IsochronousCallBack - When the transfer complete, the call back function will be called
3710 Context - Pass to the call back function as parameter
3718 return EFI_UNSUPPORTED
;