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
;
40 // EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
44 UsbBusControllerDriverSupported (
45 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
46 IN EFI_HANDLE Controller
,
47 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
52 UsbBusControllerDriverStart (
53 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
54 IN EFI_HANDLE Controller
,
55 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
60 UsbBusControllerDriverStop (
61 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
62 IN EFI_HANDLE Controller
,
63 IN UINTN NumberOfChildren
,
64 IN EFI_HANDLE
*ChildHandleBuffer
67 EFI_DRIVER_BINDING_PROTOCOL gUsbBusDriverBinding
= {
68 UsbBusControllerDriverSupported
,
69 UsbBusControllerDriverStart
,
70 UsbBusControllerDriverStop
,
82 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
83 IN EFI_STATUS_CODE_TYPE Type
,
84 IN EFI_STATUS_CODE_VALUE Code
91 InitializeUsbIoInstance (
92 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
96 USB_IO_CONTROLLER_DEVICE
*
97 CreateUsbIoControllerDevice (
103 InitUsbIoController (
104 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
108 // USB Device Configuration / Deconfiguration
112 UsbDeviceConfiguration (
113 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
114 IN EFI_HANDLE HostController
,
116 IN USB_IO_DEVICE
*UsbIoDevice
120 // Usb Bus enumeration function
138 UsbSetTransactionTranslator (
139 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
141 IN OUT USB_IO_DEVICE
*Device
146 UsbUnsetTransactionTranslator (
147 USB_IO_DEVICE
*Device
152 IdentifyDeviceSpeed (
153 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
154 USB_IO_DEVICE
*NewDevice
,
161 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
167 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
174 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
181 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
182 IN BOOLEAN ReConfigure
,
187 // Following are address allocate and free functions
192 IN UINT8
*AddressPool
197 Allocate address for usb device
200 AddressPool - Pool of usb device address
210 for (ByteIndex
= 0; ByteIndex
< 16; ByteIndex
++) {
211 for (BitIndex
= 0; BitIndex
< 8; BitIndex
++) {
212 if ((AddressPool
[ByteIndex
] & (1 << BitIndex
)) == 0) {
214 // Found one, covert to address, and mark it use
216 AddressPool
[ByteIndex
] |= (1 << BitIndex
);
217 return (UINT8
) (ByteIndex
* 8 + BitIndex
);
230 IN UINT8
*AddressPool
235 Free address for usb device
238 DevAddress - Usb device address
239 AddressPool - Pool of usb device address
249 // Locate the position
251 WhichByte
= (UINT8
) (DevAddress
/ 8);
252 WhichBit
= (UINT8
) (DevAddress
& 0x7);
254 AddressPool
[WhichByte
] &= (~(1 << WhichBit
));
259 UsbBusControllerDriverSupported (
260 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
261 IN EFI_HANDLE Controller
,
262 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
267 Test to see if this driver supports ControllerHandle. Any ControllerHandle
268 that has UsbHcProtocol installed will be supported.
271 This - Protocol instance pointer.
272 Controller - Handle of device to test
273 RemainingDevicePath - Device Path Protocol instance pointer
276 EFI_SUCCESS - This driver supports this device.
277 EFI_UNSUPPORTED - This driver does not support this device.
282 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
283 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
284 EFI_USB_HC_PROTOCOL
*UsbHc
;
285 EFI_DEV_PATH_PTR Node
;
290 if (RemainingDevicePath
!= NULL
) {
291 Node
.DevPath
= RemainingDevicePath
;
292 if (Node
.DevPath
->Type
!= MESSAGING_DEVICE_PATH
||
293 Node
.DevPath
->SubType
!= MSG_USB_DP
||
294 DevicePathNodeLength(Node
.DevPath
) != sizeof(USB_DEVICE_PATH
)) {
295 return EFI_UNSUPPORTED
;
300 // Open the IO Abstraction(s) needed to perform the supported test
302 Status
= gBS
->OpenProtocol (
304 &gEfiDevicePathProtocolGuid
,
305 (VOID
**) &ParentDevicePath
,
306 This
->DriverBindingHandle
,
308 EFI_OPEN_PROTOCOL_BY_DRIVER
310 if (Status
== EFI_ALREADY_STARTED
) {
314 if (EFI_ERROR (Status
)) {
320 &gEfiDevicePathProtocolGuid
,
321 This
->DriverBindingHandle
,
326 // Check whether USB Host Controller Protocol is already
327 // installed on this handle. If it is installed, we can start
328 // USB Bus Driver now.
330 Status
= gBS
->OpenProtocol (
332 &gEfiUsb2HcProtocolGuid
,
334 This
->DriverBindingHandle
,
336 EFI_OPEN_PROTOCOL_BY_DRIVER
338 if (Status
== EFI_ALREADY_STARTED
) {
342 if (EFI_ERROR (Status
)) {
343 Status
= gBS
->OpenProtocol (
345 &gEfiUsbHcProtocolGuid
,
347 This
->DriverBindingHandle
,
349 EFI_OPEN_PROTOCOL_BY_DRIVER
351 if (Status
== EFI_ALREADY_STARTED
) {
355 if (EFI_ERROR (Status
)) {
361 &gEfiUsbHcProtocolGuid
,
362 This
->DriverBindingHandle
,
370 &gEfiUsb2HcProtocolGuid
,
371 This
->DriverBindingHandle
,
380 UsbBusControllerDriverStart (
381 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
382 IN EFI_HANDLE Controller
,
383 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
389 Starting the Usb Bus Driver
393 This - Protocol instance pointer.
394 Controller - Handle of device to test
395 RemainingDevicePath - Not used
399 EFI_SUCCESS - This driver supports this device.
400 EFI_DEVICE_ERROR - This driver cannot be started due to device
401 EFI_OUT_OF_RESOURCES- Can't allocate memory resources
406 EFI_STATUS OpenStatus
;
407 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
408 USB_IO_DEVICE
*RootHub
;
409 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
412 UINT8 Is64BitCapable
;
415 // Allocate USB_BUS_CONTROLLER_DEVICE structure
418 UsbBusDev
= AllocateZeroPool (sizeof (USB_BUS_CONTROLLER_DEVICE
));
419 if (UsbBusDev
== NULL
) {
420 return EFI_OUT_OF_RESOURCES
;
423 UsbBusDev
->Signature
= USB_BUS_DEVICE_SIGNATURE
;
424 UsbBusDev
->AddressPool
[0] = 1;
427 // Get the Device Path Protocol on Controller's handle
429 OpenStatus
= gBS
->OpenProtocol (
431 &gEfiDevicePathProtocolGuid
,
432 (VOID
**) &UsbBusDev
->DevicePath
,
433 This
->DriverBindingHandle
,
435 EFI_OPEN_PROTOCOL_BY_DRIVER
438 if (EFI_ERROR (OpenStatus
)) {
439 gBS
->FreePool (UsbBusDev
);
443 // Locate the Host Controller Interface
445 OpenStatus
= gBS
->OpenProtocol (
447 &gEfiUsb2HcProtocolGuid
,
448 (VOID
**) &(UsbBusDev
->Usb2HCInterface
),
449 This
->DriverBindingHandle
,
451 EFI_OPEN_PROTOCOL_BY_DRIVER
453 if (EFI_ERROR (OpenStatus
)) {
455 UsbBusDev
->Hc2ProtocolSupported
= FALSE
;
456 OpenStatus
= gBS
->OpenProtocol (
458 &gEfiUsbHcProtocolGuid
,
459 (VOID
**) &(UsbBusDev
->UsbHCInterface
),
460 This
->DriverBindingHandle
,
462 EFI_OPEN_PROTOCOL_BY_DRIVER
464 if (EFI_ERROR (OpenStatus
)) {
466 // Report Status Code here since we will reset the host controller
468 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
469 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
470 EFI_IO_BUS_USB
| EFI_IOB_EC_CONTROLLER_ERROR
,
471 UsbBusDev
->DevicePath
476 &gEfiDevicePathProtocolGuid
,
477 This
->DriverBindingHandle
,
480 gBS
->FreePool (UsbBusDev
);
484 DEBUG ((gUSBDebugLevel
, "UsbHcProtocol Opened.\n"));
486 DEBUG ((gUSBDebugLevel
, "Usb2HcProtocol Opened.\n"));
487 UsbBusDev
->Hc2ProtocolSupported
= TRUE
;
491 // Attach EFI_USB_BUS_PROTOCOL to controller handle,
492 // for locate UsbBusDev later
494 Status
= gBS
->InstallProtocolInterface (
496 &mUsbBusProtocolGuid
,
497 EFI_NATIVE_INTERFACE
,
498 &UsbBusDev
->BusIdentify
501 if (EFI_ERROR (Status
)) {
505 &gEfiDevicePathProtocolGuid
,
506 This
->DriverBindingHandle
,
509 if (UsbBusDev
->Hc2ProtocolSupported
) {
512 &gEfiUsb2HcProtocolGuid
,
513 This
->DriverBindingHandle
,
519 &gEfiUsbHcProtocolGuid
,
520 This
->DriverBindingHandle
,
525 gBS
->FreePool (UsbBusDev
);
529 // Add root hub to the tree
532 RootHub
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
533 if (RootHub
== NULL
) {
534 gBS
->UninstallProtocolInterface (
536 &mUsbBusProtocolGuid
,
537 &UsbBusDev
->BusIdentify
541 &gEfiDevicePathProtocolGuid
,
542 This
->DriverBindingHandle
,
545 if (UsbBusDev
->Hc2ProtocolSupported
) {
548 &gEfiUsb2HcProtocolGuid
,
549 This
->DriverBindingHandle
,
555 &gEfiUsbHcProtocolGuid
,
556 This
->DriverBindingHandle
,
561 gBS
->FreePool (UsbBusDev
);
562 return EFI_OUT_OF_RESOURCES
;
565 RootHub
->BusController
= UsbBusDev
;
566 RootHub
->DeviceAddress
= UsbAllocateAddress (UsbBusDev
->AddressPool
);
568 UsbBusDev
->Root
= RootHub
;
571 // Allocate Root Hub Controller
573 RootHubController
= CreateUsbIoControllerDevice ();
574 if (RootHubController
== NULL
) {
575 gBS
->UninstallProtocolInterface (
577 &mUsbBusProtocolGuid
,
578 &UsbBusDev
->BusIdentify
582 &gEfiDevicePathProtocolGuid
,
583 This
->DriverBindingHandle
,
586 if (UsbBusDev
->Hc2ProtocolSupported
) {
589 &gEfiUsb2HcProtocolGuid
,
590 This
->DriverBindingHandle
,
596 &gEfiUsbHcProtocolGuid
,
597 This
->DriverBindingHandle
,
601 gBS
->FreePool (UsbBusDev
);
602 gBS
->FreePool (RootHub
);
603 return EFI_OUT_OF_RESOURCES
;
606 UsbVirtualHcGetCapability (
612 RootHubController
->DownstreamPorts
= PortNumber
;
613 RootHubController
->UsbDevice
= RootHub
;
614 RootHubController
->IsUsbHub
= TRUE
;
615 RootHubController
->DevicePath
= UsbBusDev
->DevicePath
;
616 RootHubController
->HostController
= Controller
;
618 RootHub
->NumOfControllers
= 1;
619 RootHub
->UsbController
[0] = RootHubController
;
620 RootHub
->DeviceSpeed
= MaxSpeed
;
623 // Report Status Code here since we will reset the host controller
625 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
627 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
,
628 UsbBusDev
->DevicePath
632 // Reset USB Host Controller
636 EFI_USB_HC_RESET_GLOBAL
640 // Report Status Code while we are going to bring up the Host Controller
641 // and start bus enumeration
643 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
645 EFI_IO_BUS_USB
| EFI_IOB_PC_ENABLE
,
646 UsbBusDev
->DevicePath
650 // Start USB Host Controller
652 UsbVirtualHcSetState (
654 EfiUsbHcStateOperational
658 // Create a timer to query root ports periodically
660 Status
= gBS
->CreateEvent (
661 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
665 &RootHubController
->HubNotify
667 if (EFI_ERROR (Status
)) {
668 gBS
->UninstallProtocolInterface (
670 &mUsbBusProtocolGuid
,
671 &UsbBusDev
->BusIdentify
676 &gEfiDevicePathProtocolGuid
,
677 This
->DriverBindingHandle
,
681 if (UsbBusDev
->Hc2ProtocolSupported
) {
684 &gEfiUsb2HcProtocolGuid
,
685 This
->DriverBindingHandle
,
691 &gEfiUsbHcProtocolGuid
,
692 This
->DriverBindingHandle
,
697 gBS
->FreePool (RootHubController
);
698 gBS
->FreePool (RootHub
);
699 gBS
->FreePool (UsbBusDev
);
700 return EFI_OUT_OF_RESOURCES
;
704 // Before depending on the timer to check root ports periodically,
705 // here we should check them immediately for the first time, or
706 // there will be an interval between bus start and devices start.
708 gBS
->SignalEvent (RootHubController
->HubNotify
);
710 Status
= gBS
->SetTimer (
711 RootHubController
->HubNotify
,
715 if (EFI_ERROR (Status
)) {
716 gBS
->UninstallProtocolInterface (
718 &mUsbBusProtocolGuid
,
719 &UsbBusDev
->BusIdentify
724 &gEfiDevicePathProtocolGuid
,
725 This
->DriverBindingHandle
,
729 if (UsbBusDev
->Hc2ProtocolSupported
) {
732 &gEfiUsb2HcProtocolGuid
,
733 This
->DriverBindingHandle
,
739 &gEfiUsbHcProtocolGuid
,
740 This
->DriverBindingHandle
,
745 gBS
->CloseEvent (RootHubController
->HubNotify
);
746 gBS
->FreePool (RootHubController
);
747 gBS
->FreePool (RootHub
);
748 gBS
->FreePool (UsbBusDev
);
749 return EFI_DEVICE_ERROR
;
756 // Stop the bus controller
760 UsbBusControllerDriverStop (
761 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
762 IN EFI_HANDLE Controller
,
763 IN UINTN NumberOfChildren
,
764 IN EFI_HANDLE
*ChildHandleBuffer
769 Stop this driver on ControllerHandle. Support stoping any child handles
770 created by this driver.
773 This - Protocol instance pointer.
774 Controller - Handle of device to stop driver on
775 NumberOfChildren - Number of Children in the ChildHandleBuffer
776 ChildHandleBuffer - List of handles for the children we need to stop.
787 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
788 USB_BUS_CONTROLLER_DEVICE
*UsbBusController
;
789 EFI_USB_BUS_PROTOCOL
*UsbIdentifier
;
791 USB_IO_CONTROLLER_DEVICE
*UsbController
;
792 USB_IO_DEVICE
*UsbIoDevice
;
793 USB_IO_CONTROLLER_DEVICE
*HubController
;
795 EFI_USB_IO_PROTOCOL
*UsbIo
;
797 if (NumberOfChildren
> 0) {
799 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
800 Status
= gBS
->OpenProtocol (
801 ChildHandleBuffer
[Index
],
802 &gEfiUsbIoProtocolGuid
,
804 This
->DriverBindingHandle
,
806 EFI_OPEN_PROTOCOL_GET_PROTOCOL
808 if (EFI_ERROR (Status
)) {
810 // We are here since the handle passed in does not support
811 // UsbIo protocol. There are several reasons that will cause
813 // For combo device such as keyboard, it may have 2 devices
814 // in one, namely, keyboard and mouse. If we deconfigure one
815 // of them, the other will be freed at the same time. This will
816 // cause the status error. But this is the correct behavior.
817 // For hub device, if we deconfigure hub first, the other chile
818 // device will be disconnected also, this will also provide us
819 // a status error. Now we will only report EFI_SUCCESS since Uhc
820 // driver will be disconnected at the second time.(pls see
821 // CoreDisconnectController for details)
826 UsbController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (UsbIo
);
827 UsbIoDevice
= UsbController
->UsbDevice
;
828 HubController
= UsbController
->Parent
;
829 UsbDeviceDeConfiguration (UsbIoDevice
);
830 for (Index2
= 0; Index2
< HubController
->DownstreamPorts
; Index2
++) {
831 if (HubController
->Children
[Index2
] == UsbIoDevice
) {
832 HubController
->Children
[Index2
] = NULL
;
840 // Get the USB_BUS_CONTROLLER_DEVICE
842 Status
= gBS
->OpenProtocol (
844 &mUsbBusProtocolGuid
,
845 (VOID
**) &UsbIdentifier
,
846 This
->DriverBindingHandle
,
848 EFI_OPEN_PROTOCOL_GET_PROTOCOL
851 if (EFI_ERROR (Status
)) {
852 return EFI_DEVICE_ERROR
;
855 UsbBusController
= USB_BUS_CONTROLLER_DEVICE_FROM_THIS (UsbIdentifier
);
858 // Stop USB Host Controller
862 // Report Status Code here since we will reset the host controller
864 ReportUsbStatusCode (
867 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
870 UsbVirtualHcSetState (
876 // Deconfiguration all its devices
878 Root
= UsbBusController
->Root
;
879 RootHubController
= Root
->UsbController
[0];
881 gBS
->CloseEvent (RootHubController
->HubNotify
);
883 for (Index2
= 0; Index2
< RootHubController
->DownstreamPorts
; Index2
++) {
884 if (RootHubController
->Children
[Index2
]) {
885 UsbDeviceDeConfiguration (RootHubController
->Children
[Index2
]);
886 RootHubController
->Children
[Index2
] = NULL
;
890 gBS
->FreePool (RootHubController
);
891 gBS
->FreePool (Root
);
894 // Uninstall USB Bus Protocol
896 gBS
->UninstallProtocolInterface (
898 &mUsbBusProtocolGuid
,
899 &UsbBusController
->BusIdentify
903 // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL
904 // Opened by this Controller
906 if (UsbBusController
->Hc2ProtocolSupported
) {
909 &gEfiUsb2HcProtocolGuid
,
910 This
->DriverBindingHandle
,
916 &gEfiUsbHcProtocolGuid
,
917 This
->DriverBindingHandle
,
924 &gEfiDevicePathProtocolGuid
,
925 This
->DriverBindingHandle
,
929 gBS
->FreePool (UsbBusController
);
934 // USB Device Configuration
938 UsbDeviceConfiguration (
939 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
940 IN EFI_HANDLE HostController
,
942 IN USB_IO_DEVICE
*UsbIoDevice
947 Configurate a new device attached to the usb bus
950 ParentHubController - Parent Hub which this device is connected.
951 HostController - Host Controller handle
952 ParentPort - Parent Hub port which this device is connected.
953 UsbIoDevice - The device to be configured.
966 CHAR16
*StrManufacturer
;
968 CHAR16
*StrSerialNumber
;
969 EFI_USB_IO_PROTOCOL
*UsbIo
;
970 UINT8 NumOfInterface
;
971 USB_IO_CONTROLLER_DEVICE
*FirstController
;
972 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
973 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
975 UsbBusDev
= UsbIoDevice
->BusController
;
977 UsbSetTransactionTranslator (
984 // Since a USB device must have at least on interface,
985 // so create this instance first
987 FirstController
= CreateUsbIoControllerDevice ();
988 FirstController
->UsbDevice
= UsbIoDevice
;
989 UsbIoDevice
->UsbController
[0] = FirstController
;
990 FirstController
->InterfaceNumber
= 0;
991 FirstController
->ParentPort
= ParentPort
;
992 FirstController
->Parent
= ParentHubController
;
993 FirstController
->HostController
= HostController
;
995 InitializeUsbIoInstance (FirstController
);
997 DEBUG ((gUSBDebugLevel
, "Configuration Usb Device at 0x%x...\n", ParentPort
));
1000 // Ensure we used the correctly USB I/O instance
1002 UsbIo
= &FirstController
->UsbIo
;
1004 if (UsbIoDevice
->DeviceSpeed
!= EFI_USB_SPEED_HIGH
) {
1005 ParentPortReset (FirstController
, FALSE
, 0);
1009 // First retrieve the 1st 8 bytes of
1010 // in order to get the MaxPacketSize for Endpoint 0
1012 for (Index
= 0; Index
< 3; Index
++) {
1014 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1016 gBS
->Stall (100 * 1000);
1018 Result
= UsbGetDescriptor (
1020 (USB_DT_DEVICE
<< 8),
1023 &UsbIoDevice
->DeviceDescriptor
,
1026 if (!EFI_ERROR (Result
)) {
1029 "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
1030 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
)
1038 ReportUsbStatusCode (
1040 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1041 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1043 DEBUG ((gUSBErrorLevel
, "Get Device Descriptor Fail when configing\n"));
1044 gBS
->FreePool (FirstController
);
1045 return EFI_DEVICE_ERROR
;
1048 DevAddress
= UsbAllocateAddress (UsbIoDevice
->BusController
->AddressPool
);
1049 if (DevAddress
== 0) {
1050 DEBUG ((gUSBErrorLevel
, "Cannot allocate address\n"));
1051 gBS
->FreePool (FirstController
);
1052 return EFI_OUT_OF_RESOURCES
;
1055 Result
= UsbSetDeviceAddress (UsbIo
, DevAddress
, &Status
);
1057 if (EFI_ERROR (Result
)) {
1058 DEBUG ((gUSBErrorLevel
, "Set address error\n"));
1059 ReportUsbStatusCode (
1061 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1062 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1067 UsbIoDevice
->BusController
->AddressPool
1070 gBS
->FreePool (FirstController
);
1071 return EFI_DEVICE_ERROR
;
1074 UsbIoDevice
->DeviceAddress
= DevAddress
;
1077 // SetAddress Complete Time by Spec, Max 50ms
1079 gBS
->Stall (10 * 1000);
1082 // Get the whole device descriptor
1084 Result
= UsbGetDescriptor (
1086 (USB_DT_DEVICE
<< 8),
1088 sizeof (EFI_USB_DEVICE_DESCRIPTOR
),
1089 &UsbIoDevice
->DeviceDescriptor
,
1093 if (EFI_ERROR (Result
)) {
1094 DEBUG ((gUSBErrorLevel
, "Get whole Device Descriptor error\n"));
1095 ReportUsbStatusCode (
1097 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1098 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1102 UsbIoDevice
->BusController
->AddressPool
1105 gBS
->FreePool (FirstController
);
1106 return EFI_DEVICE_ERROR
;
1109 // Get & parse all configurations for this device, including
1110 // all configuration descriptors, all interface descriptors, all
1111 // endpoint descriptors
1113 Result
= UsbGetAllConfigurations (UsbIoDevice
);
1115 if (EFI_ERROR (Result
)) {
1116 DEBUG ((gUSBErrorLevel
, "Failed to get device configuration\n"));
1117 ReportUsbStatusCode (
1119 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1120 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1124 UsbIoDevice
->BusController
->AddressPool
1127 gBS
->FreePool (FirstController
);
1128 return EFI_DEVICE_ERROR
;
1131 // Set the 1st configuration value
1133 Result
= UsbSetDefaultConfiguration (UsbIoDevice
);
1134 if (EFI_ERROR (Result
)) {
1135 DEBUG ((gUSBErrorLevel
, "Failed to set device configuration\n"));
1136 ReportUsbStatusCode (
1138 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1139 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1143 UsbIoDevice
->BusController
->AddressPool
1146 gBS
->FreePool (FirstController
);
1147 return EFI_DEVICE_ERROR
;
1150 UsbIoDevice
->IsConfigured
= TRUE
;
1153 // Get all string table if applicable
1155 Result
= UsbGetStringtable (UsbIoDevice
);
1156 if (EFI_ERROR (Result
)) {
1157 DEBUG ((gUSBDebugLevel
, "Device doesn't support string table\n"));
1160 StrManufacturer
= NULL
;
1161 UsbIo
->UsbGetStringDescriptor (
1163 UsbIoDevice
->LangID
[0],
1164 (UsbIoDevice
->DeviceDescriptor
).StrManufacturer
,
1169 UsbIo
->UsbGetStringDescriptor (
1171 UsbIoDevice
->LangID
[0],
1172 (UsbIoDevice
->DeviceDescriptor
).StrProduct
,
1176 StrSerialNumber
= NULL
;
1177 UsbIo
->UsbGetStringDescriptor (
1179 UsbIoDevice
->LangID
[0],
1180 (UsbIoDevice
->DeviceDescriptor
).StrSerialNumber
,
1184 if (StrManufacturer
) {
1185 gBS
->FreePool (StrManufacturer
);
1189 gBS
->FreePool (StrProduct
);
1192 if (StrSerialNumber
) {
1193 gBS
->FreePool (StrSerialNumber
);
1197 // Create USB_IO_CONTROLLER_DEVICE for
1198 // each detected interface
1200 FirstController
->CurrentConfigValue
=
1201 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1204 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.NumInterfaces
;
1205 UsbIoDevice
->NumOfControllers
= NumOfInterface
;
1207 Result
= InitUsbIoController (FirstController
);
1208 if (EFI_ERROR (Result
)) {
1209 ReportUsbStatusCode (
1211 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1212 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1214 gBS
->FreePool (FirstController
);
1215 UsbIoDevice
->UsbController
[0] = NULL
;
1216 return EFI_DEVICE_ERROR
;
1219 for (Index
= 1; Index
< NumOfInterface
; Index
++) {
1220 UsbIoController
= CreateUsbIoControllerDevice ();
1221 UsbIoController
->UsbDevice
= UsbIoDevice
;
1222 UsbIoController
->CurrentConfigValue
=
1223 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1224 UsbIoController
->InterfaceNumber
= Index
;
1225 UsbIoDevice
->UsbController
[Index
] = UsbIoController
;
1226 UsbIoController
->ParentPort
= ParentPort
;
1227 UsbIoController
->Parent
= ParentHubController
;
1228 UsbIoController
->HostController
= HostController
;
1231 // First copy the USB_IO Protocol instance
1234 &UsbIoController
->UsbIo
,
1236 sizeof (EFI_USB_IO_PROTOCOL
)
1239 Result
= InitUsbIoController (UsbIoController
);
1240 if (EFI_ERROR (Result
)) {
1241 ReportUsbStatusCode (
1243 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1244 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1246 gBS
->FreePool (UsbIoController
);
1247 UsbIoDevice
->UsbController
[Index
] = NULL
;
1254 // USB Device DeConfiguration
1257 UsbDeviceDeConfiguration (
1258 IN USB_IO_DEVICE
*UsbIoDevice
1262 Routine Description:
1263 Remove Device, Device Handles, Uninstall Protocols.
1266 UsbIoDevice - The device to be deconfigured.
1274 USB_IO_CONTROLLER_DEVICE
*UsbController
;
1276 USB_IO_DEVICE
*ChildDevice
;
1278 EFI_USB_IO_PROTOCOL
*UsbIo
;
1282 // Double check UsbIoDevice exists
1284 if (UsbIoDevice
== NULL
) {
1288 UsbUnsetTransactionTranslator (UsbIoDevice
);
1290 for (index
= 0; index
< UsbIoDevice
->NumOfControllers
; index
++) {
1292 // Check if it is a hub, if so, de configuration all its
1295 UsbController
= UsbIoDevice
->UsbController
[index
];
1298 // Check the controller pointer
1300 if (UsbController
== NULL
) {
1304 if (UsbController
->IsUsbHub
) {
1306 DEBUG ((gUSBDebugLevel
, "Hub Deconfig, First Deconfig its downstream ports\n"));
1309 // First Remove interrupt transfer request for the status
1312 UsbIo
= &UsbController
->UsbIo
;
1313 UsbIo
->UsbAsyncInterruptTransfer (
1315 UsbController
->HubEndpointAddress
,
1323 if (NULL
!= UsbController
->HubNotify
) {
1324 gBS
->CloseEvent (UsbController
->HubNotify
);
1327 for (Index
= 0; Index
< UsbController
->DownstreamPorts
; Index
++) {
1328 if (UsbController
->Children
[Index
]) {
1329 ChildDevice
= UsbController
->Children
[Index
];
1330 UsbDeviceDeConfiguration (ChildDevice
);
1331 UsbController
->Children
[Index
] = NULL
;
1336 // If the controller is managed by a device driver, we need to
1339 if (UsbController
->IsManagedByDriver
) {
1340 gBS
->DisconnectController (
1341 UsbController
->Handle
,
1348 // remove child handle reference to the USB_HC_PROTOCOL
1350 if (UsbIoDevice
->BusController
->Hc2ProtocolSupported
) {
1351 gBS
->CloseProtocol (
1352 UsbController
->HostController
,
1353 &gEfiUsb2HcProtocolGuid
,
1354 gUsbBusDriverBinding
.DriverBindingHandle
,
1355 UsbController
->Handle
1358 gBS
->CloseProtocol (
1359 UsbController
->HostController
,
1360 &gEfiUsbHcProtocolGuid
,
1361 gUsbBusDriverBinding
.DriverBindingHandle
,
1362 UsbController
->Handle
1366 // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
1367 // installed on this handle
1369 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1370 UsbController
->Handle
,
1371 &gEfiDevicePathProtocolGuid
,
1372 UsbController
->DevicePath
,
1373 &gEfiUsbIoProtocolGuid
,
1374 &UsbController
->UsbIo
,
1377 if (EFI_ERROR (Status
)) {
1381 if (UsbController
->DevicePath
!= NULL
) {
1382 gBS
->FreePool (UsbController
->DevicePath
);
1385 gBS
->FreePool (UsbController
);
1386 UsbIoDevice
->UsbController
[index
] = NULL
;
1389 // Free address for later use
1392 UsbIoDevice
->DeviceAddress
,
1393 UsbIoDevice
->BusController
->AddressPool
1397 // Free all resouces allocated for all its configurations
1399 UsbDestroyAllConfiguration (UsbIoDevice
);
1402 gBS
->FreePool (UsbIoDevice
);
1409 // After interrupt complete, this function will be called,
1410 // This function need to be well-defined later
1415 OnHubInterruptComplete (
1417 IN UINTN DataLength
,
1423 Routine Description:
1424 Whenever hub interrupt occurs, this routine will be called to check
1425 which event happens.
1428 Data - Hub interrupt transfer data.
1429 DataLength - The length of the Data.
1430 Context - Hub Controller Device.
1431 Result - Hub interrupt transfer status.
1439 USB_IO_CONTROLLER_DEVICE
*HubController
;
1442 EFI_USB_IO_PROTOCOL
*UsbIo
;
1444 BOOLEAN Disconnected
;
1447 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1448 UsbIo
= &HubController
->UsbIo
;
1451 // If something error in this interrupt transfer,
1453 if (Result
!= EFI_USB_NOERROR
) {
1454 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1455 UsbClearEndpointHalt (
1457 HubController
->HubEndpointAddress
,
1463 // Delete & Submit this interrupt again
1465 UsbIo
->UsbAsyncInterruptTransfer (
1467 HubController
->HubEndpointAddress
,
1476 // try to detect if the hub itself was disconnected or not
1478 Status
= IsDeviceDisconnected (
1483 if (!EFI_ERROR (Status
) && Disconnected
== TRUE
) {
1484 DEBUG ((gUSBErrorLevel
, "Hub is disconnected\n"));
1485 return EFI_DEVICE_ERROR
;
1490 UsbIo
->UsbAsyncInterruptTransfer (
1492 HubController
->HubEndpointAddress
,
1496 OnHubInterruptComplete
,
1500 return EFI_DEVICE_ERROR
;
1503 if (DataLength
== 0 || Data
== NULL
) {
1508 // Scan which port has status change
1509 // Bit 0 stands for hub itself, other bit stands for
1510 // the corresponding port
1512 for (Index
= 0; Index
< DataLength
* 8; Index
++) {
1513 ptr
= (UINT8
*) Data
+ Index
/ 8;
1514 if ((*ptr
) & (1 << (Index
& 0x7))) {
1515 HubController
->StatusChangePort
= Index
;
1520 // Signal hub notify event
1522 gBS
->SignalEvent (HubController
->HubNotify
);
1527 // USB Root Hub Enumerator
1532 RootHubEnumeration (
1538 Routine Description:
1540 This is USB RootHub enumerator
1544 Event - Indicating which event is signaled
1545 Context - actually it is a USB_IO_DEVICE
1553 USB_IO_CONTROLLER_DEVICE
*HubController
;
1554 EFI_USB_PORT_STATUS HubPortStatus
;
1557 USB_IO_DEVICE
*UsbIoDev
;
1558 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1559 EFI_HANDLE HostController
;
1560 USB_IO_DEVICE
*OldUsbIoDevice
;
1561 USB_IO_DEVICE
*NewDevice
;
1562 USB_IO_CONTROLLER_DEVICE
*NewController
;
1564 EFI_USB_IO_PROTOCOL
*UsbIo
;
1566 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1567 HostController
= HubController
->HostController
;
1568 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1571 // Root hub has the address 1
1573 UsbIoDev
= HubController
->UsbDevice
;
1575 for (Index
= 0; Index
< HubController
->DownstreamPorts
; Index
++) {
1577 UsbVirtualHcGetRootHubPortStatus (
1580 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1583 if (!IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1587 // Clear root hub status change status
1589 UsbVirtualHcClearRootHubPortFeature (
1592 EfiUsbPortConnectChange
1595 gBS
->Stall (100 * 1000);
1597 UsbVirtualHcGetRootHubPortStatus (
1600 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1603 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1606 // There is something connected to this port
1608 DEBUG ((gUSBDebugLevel
, "Something connected to Root Hub at Port0x%x\n", Index
));
1610 ReportUsbStatusCode (
1613 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1616 // if there is something physically detached, but still logically
1619 OldUsbIoDevice
= HubController
->Children
[Index
];
1621 if (NULL
!= OldUsbIoDevice
) {
1622 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1623 HubController
->Children
[Index
] = NULL
;
1626 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1627 if (NewDevice
== NULL
) {
1631 // Initialize some fields by copying data from
1634 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1635 NewDevice
->BusController
= UsbIoDev
->BusController
;
1638 // Process of identify device speed
1640 Status
= IdentifyDeviceSpeed (
1645 if (EFI_ERROR (Status
)) {
1646 gBS
->FreePool (NewDevice
);
1651 // Configure that device
1653 Status
= UsbDeviceConfiguration (
1659 if (EFI_ERROR (Status
)) {
1660 gBS
->FreePool (NewDevice
);
1664 // Add this device to the usb bus tree
1666 HubController
->Children
[Index
] = NewDevice
;
1668 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
1670 // If this device is hub, add to the hub index
1672 NewController
= NewDevice
->UsbController
[Index2
];
1674 Status
= gBS
->ConnectController (
1675 NewController
->Handle
,
1681 // If connect success, we need to disconnect when
1682 // stop the controller, otherwise we need not call
1683 // gBS->DisconnectController ()
1684 // This is used by those usb devices we don't plan
1685 // to support. We can allocate
1686 // controller handles for them, but we don't have
1687 // device drivers to manage them.
1689 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
1691 if (IsHub (NewController
)) {
1693 NewController
->IsUsbHub
= TRUE
;
1696 // Configure Hub Controller
1698 Status
= DoHubConfig (NewController
);
1699 if (EFI_ERROR (Status
)) {
1703 // Create an event to do hub enumeration
1706 EFI_EVENT_NOTIFY_SIGNAL
,
1710 &NewController
->HubNotify
1714 // Add request to do query hub status
1718 UsbIo
= &NewController
->UsbIo
;
1719 UsbIo
->UsbAsyncInterruptTransfer (
1721 NewController
->HubEndpointAddress
,
1725 OnHubInterruptComplete
,
1733 // Something disconnected from USB root hub
1735 DEBUG ((gUSBDebugLevel
, "Something disconnected from Root Hub at Port0x%x\n", Index
));
1737 OldUsbIoDevice
= HubController
->Children
[Index
];
1739 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1741 HubController
->Children
[Index
] = NULL
;
1743 UsbVirtualHcClearRootHubPortFeature (
1746 EfiUsbPortEnableChange
1754 // USB Root Hub Enumerator
1765 Routine Description:
1767 This is Usb Hub enumerator
1771 Event - Indicating which event is signaled
1772 Context - actually it is a USB_IO_DEVICE
1780 USB_IO_CONTROLLER_DEVICE
*HubController
;
1781 EFI_USB_PORT_STATUS HubPortStatus
;
1783 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1784 EFI_HANDLE HostController
;
1785 USB_IO_DEVICE
*OldUsbIoDevice
;
1786 USB_IO_DEVICE
*NewDevice
;
1787 USB_IO_CONTROLLER_DEVICE
*NewController
;
1789 EFI_USB_IO_PROTOCOL
*UsbIo
;
1790 UINT8 StatusChangePort
;
1793 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1794 HostController
= HubController
->HostController
;
1795 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1798 // Event from Hub, Get the hub controller handle
1801 // Get the status change endpoint
1803 StatusChangePort
= HubController
->StatusChangePort
;
1806 // Clear HubController Status Change Bit
1808 HubController
->StatusChangePort
= 0;
1810 if (StatusChangePort
== 0) {
1812 // Hub changes, we don't handle here
1817 // Check which event took place at that port
1819 UsbIo
= &HubController
->UsbIo
;
1820 Status
= HubGetPortStatus (
1823 (UINT32
*) &HubPortStatus
1826 if (EFI_ERROR (Status
)) {
1830 // Clear some change status
1832 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
1834 // Clear Hub port enable change
1836 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
1837 HubClearPortFeature (
1840 EfiUsbPortEnableChange
1846 (UINT32
*) &HubPortStatus
1850 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
1852 // Clear Hub reset change
1854 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
1855 HubClearPortFeature (
1858 EfiUsbPortResetChange
1864 (UINT32
*) &HubPortStatus
1868 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_OVERCURRENT
) {
1870 // Clear Hub overcurrent change
1872 DEBUG ((gUSBDebugLevel
, "Port Overcurrent Change\n"));
1873 HubClearPortFeature (
1876 EfiUsbPortOverCurrentChange
1882 (UINT32
*) &HubPortStatus
1886 if (IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1888 // First clear port connection change
1890 DEBUG ((gUSBDebugLevel
, "Port Connection Change\n"));
1891 HubClearPortFeature (
1894 EfiUsbPortConnectChange
1900 (UINT32
*) &HubPortStatus
1903 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1905 DEBUG ((gUSBDebugLevel
, "New Device Connect on Hub port \n"));
1907 ReportUsbStatusCode (
1910 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1914 // if there is something physically detached, but still logically
1917 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
1919 if (NULL
!= OldUsbIoDevice
) {
1920 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1921 HubController
->Children
[StatusChangePort
- 1] = NULL
;
1924 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1925 if (NewDevice
== NULL
) {
1929 // Initialize some fields
1931 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1932 NewDevice
->BusController
= HubController
->UsbDevice
->BusController
;
1935 // There is something connected to this port,
1938 // Disable the enable bit in port status
1940 HubClearPortFeature (
1946 gBS
->Stall (50 * 1000);
1949 // Wait for bit change
1956 (UINT32
*) &HubPortStatus
1958 gBS
->Stall (10 * 1000);
1960 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_ENABLE
) == 1 && Number
> 0);
1964 // Cannot disable port, return error
1966 DEBUG ((gUSBErrorLevel
, "Disable Port Failed\n"));
1967 gBS
->FreePool (NewDevice
);
1977 gBS
->Stall (50 * 1000);
1980 // Wait for port reset complete
1987 (UINT32
*) &HubPortStatus
1989 gBS
->Stall (10 * 1000);
1991 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_RESET
) == 1 && Number
> 0);
1995 // Cannot reset port, return error
1997 DEBUG ((gUSBErrorLevel
, "Reset Port Failed\n"));
1998 gBS
->FreePool (NewDevice
);
2002 // Check high speed or full speed device
2004 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
2005 DEBUG ((gUSBDebugLevel
, "Low Speed Device Attached to Hub\n"));
2006 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
2007 } else if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2008 DEBUG ((gUSBDebugLevel
, "High Speed Device Attached to Hub\n"));
2009 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2011 DEBUG ((gUSBDebugLevel
, "Full Speed Device Attached to Hub\n"));
2012 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2015 // Configure that device
2017 Status
= UsbDeviceConfiguration (
2020 (UINT8
) (StatusChangePort
- 1),
2024 if (EFI_ERROR (Status
)) {
2025 gBS
->FreePool (NewDevice
);
2029 // Add this device to the usb bus tree
2030 // StatusChangePort is begin from 1,
2032 HubController
->Children
[StatusChangePort
- 1] = NewDevice
;
2034 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
2036 // If this device is hub, add to the hub index
2038 NewController
= NewDevice
->UsbController
[Index2
];
2041 // Connect the controller to the driver image
2043 Status
= gBS
->ConnectController (
2044 NewController
->Handle
,
2050 // If connect success, we need to disconnect when
2051 // stop the controller, otherwise we need not call
2052 // gBS->DisconnectController ()
2053 // This is used by those usb devices we don't plan
2054 // to support. We can allocate
2055 // controller handles for them, but we don't have
2056 // device drivers to manage them.
2058 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
2061 // If this device is hub, add to the hub index
2063 if (IsHub (NewController
)) {
2065 NewController
->IsUsbHub
= TRUE
;
2070 Status
= DoHubConfig (NewController
);
2072 if (EFI_ERROR (Status
)) {
2076 // Create an event to do hub enumeration
2079 EFI_EVENT_NOTIFY_SIGNAL
,
2083 &NewController
->HubNotify
2087 // Add request to do query hub status
2090 UsbIo
= &NewController
->UsbIo
;
2091 UsbIo
->UsbAsyncInterruptTransfer (
2093 NewController
->HubEndpointAddress
, // Hub endpoint address
2097 OnHubInterruptComplete
,
2104 // Something disconnected from USB hub
2106 DEBUG ((gUSBDebugLevel
, "Something Device Detached on Hub port\n"));
2108 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
2110 UsbDeviceDeConfiguration (OldUsbIoDevice
);
2112 HubController
->Children
[StatusChangePort
- 1] = NULL
;
2123 USB_IO_CONTROLLER_DEVICE
*
2124 CreateUsbIoControllerDevice (
2129 Routine Description:
2130 Allocate a structure for USB_IO_CONTROLLER_DEVICE
2136 A pointer to a USB_IO_CONTROLLER_DEVICE structure,
2141 USB_IO_CONTROLLER_DEVICE
*UsbIoControllerDev
;
2144 // Allocate USB_IO_CONTROLLER_DEVICE structure
2146 UsbIoControllerDev
= NULL
;
2147 UsbIoControllerDev
= AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE
));
2149 if (UsbIoControllerDev
== NULL
) {
2153 UsbIoControllerDev
->Signature
= USB_IO_CONTROLLER_SIGNATURE
;
2155 return UsbIoControllerDev
;
2160 InitUsbIoController (
2161 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
2165 Routine Description:
2166 Init and install EFI_USB_IO_PROTOCOL onto that controller.
2169 UsbIoController - The Controller to be operated.
2177 USB_DEVICE_PATH UsbNode
;
2179 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
2180 EFI_USB_HC_PROTOCOL
*UsbHcProtocol
;
2181 EFI_USB2_HC_PROTOCOL
*Usb2HcProtocol
;
2184 // Build the child device path for each new USB_IO device
2186 ZeroMem (&UsbNode
, sizeof (UsbNode
));
2187 UsbNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
2188 UsbNode
.Header
.SubType
= MSG_USB_DP
;
2189 SetDevicePathNodeLength (&UsbNode
.Header
, sizeof (UsbNode
));
2190 UsbNode
.InterfaceNumber
= UsbIoController
->InterfaceNumber
;
2191 UsbNode
.ParentPortNumber
= UsbIoController
->ParentPort
;
2192 ParentDevicePath
= UsbIoController
->Parent
->DevicePath
;
2194 UsbIoController
->DevicePath
=
2195 AppendDevicePathNode (ParentDevicePath
, &UsbNode
.Header
);
2196 if (UsbIoController
->DevicePath
== NULL
) {
2197 return EFI_OUT_OF_RESOURCES
;
2200 Status
= gBS
->InstallMultipleProtocolInterfaces (
2201 &UsbIoController
->Handle
,
2202 &gEfiDevicePathProtocolGuid
,
2203 UsbIoController
->DevicePath
,
2204 &gEfiUsbIoProtocolGuid
,
2205 &UsbIoController
->UsbIo
,
2209 if (EFI_ERROR (Status
)) {
2213 if (UsbIoController
->UsbDevice
->BusController
->Hc2ProtocolSupported
) {
2214 Status
= gBS
->OpenProtocol (
2215 UsbIoController
->HostController
,
2216 &gEfiUsb2HcProtocolGuid
,
2217 (VOID
**)&Usb2HcProtocol
,
2218 gUsbBusDriverBinding
.DriverBindingHandle
,
2219 UsbIoController
->Handle
,
2220 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2223 Status
= gBS
->OpenProtocol (
2224 UsbIoController
->HostController
,
2225 &gEfiUsbHcProtocolGuid
,
2226 (VOID
**)&UsbHcProtocol
,
2227 gUsbBusDriverBinding
.DriverBindingHandle
,
2228 UsbIoController
->Handle
,
2229 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2239 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2240 IN BOOLEAN ReConfigure
,
2245 Routine Description:
2246 Reset parent hub port to which this device is connected.
2249 UsbIoController - Indicating the Usb Controller Device.
2250 ReConfigure - Do we need to reconfigure it.
2251 RetryTimes - Retry Times when failed
2259 USB_IO_DEVICE
*ParentIoDev
;
2260 USB_IO_DEVICE
*UsbIoDev
;
2261 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2265 EFI_USB_IO_PROTOCOL
*UsbIo
;
2268 ParentController
= UsbIoController
->Parent
;
2269 ParentIoDev
= ParentController
->UsbDevice
;
2270 UsbIoDev
= UsbIoController
->UsbDevice
;
2271 HubPort
= UsbIoController
->ParentPort
;
2273 gBS
->Stall (100 * 1000);
2275 if (ParentIoDev
->DeviceAddress
== 1) {
2276 DEBUG ((gUSBDebugLevel
, "Reset from Root Hub 0x%x\n", HubPort
));
2277 ResetRootPort (ParentIoDev
->BusController
, HubPort
, RetryTimes
);
2279 DEBUG ((gUSBDebugLevel
, "Reset from Hub, Addr 0x%x\n", ParentIoDev
->DeviceAddress
));
2280 ResetHubPort (ParentController
, HubPort
+ 1);
2283 // If we only need port reset, just return
2289 // Re-config that USB device
2291 UsbIo
= &UsbIoController
->UsbIo
;
2294 // Assign a unique address to this device
2296 Address
= UsbIoDev
->DeviceAddress
;
2297 UsbIoDev
->DeviceAddress
= 0;
2299 Result
= UsbSetDeviceAddress (UsbIo
, Address
, &Status
);
2300 UsbIoDev
->DeviceAddress
= Address
;
2302 if (EFI_ERROR (Result
)) {
2303 return EFI_DEVICE_ERROR
;
2306 // Set the device to the default configuration
2308 Result
= UsbSetDefaultConfiguration (UsbIoDev
);
2309 if (EFI_ERROR (Result
)) {
2310 return EFI_DEVICE_ERROR
;
2319 IN EFI_USB_IO_PROTOCOL
*This
2323 Routine Description:
2324 Resets and reconfigures the USB controller. This function will
2325 work for all USB devices except USB Hub Controllers.
2328 This - Indicates the calling context.
2332 EFI_INVALID_PARAMETER
2337 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
2339 UsbIoController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This
);
2341 if (IsHub (UsbIoController
)) {
2342 return EFI_INVALID_PARAMETER
;
2346 // Since at this time, this device has already been configured,
2347 // it needs to be re-configured.
2349 return ParentPortReset (UsbIoController
, TRUE
, 0);
2354 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2360 Routine Description:
2361 Reset Root Hub port.
2364 UsbBusDev - Bus controller of the device.
2365 PortNum - The given port to be reset.
2366 RetryTimes - RetryTimes when failed
2375 EFI_USB_PORT_STATUS PortStatus
;
2380 Status
= UsbVirtualHcSetRootHubPortFeature (
2385 if (EFI_ERROR (Status
)) {
2386 return EFI_DEVICE_ERROR
;
2389 gBS
->Stall (50 * 1000);
2392 // clear reset root port
2394 Status
= UsbVirtualHcClearRootHubPortFeature (
2399 if (EFI_ERROR (Status
)) {
2400 return EFI_DEVICE_ERROR
;
2405 Status
= UsbVirtualHcClearRootHubPortFeature (
2408 EfiUsbPortConnectChange
2410 if (EFI_ERROR (Status
)) {
2411 return EFI_DEVICE_ERROR
;
2414 UsbVirtualHcGetRootHubPortStatus (
2419 if (PortStatus
.PortStatus
& USB_PORT_STAT_OWNER
) {
2423 Status
= UsbVirtualHcSetRootHubPortFeature (
2428 if (EFI_ERROR (Status
)) {
2429 return EFI_DEVICE_ERROR
;
2432 Status
= UsbVirtualHcClearRootHubPortFeature (
2435 EfiUsbPortEnableChange
2439 gBS
->Stall ((1 + RetryTimes
) * 50 * 1000);
2446 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2451 Routine Description:
2455 UsbIoController - The USB_IO_CONTROLLER_DEVICE instance.
2456 PortIndex - The given port to be reset.
2464 EFI_USB_IO_PROTOCOL
*UsbIo
;
2465 EFI_USB_PORT_STATUS HubPortStatus
;
2468 ASSERT (UsbIoController
->IsUsbHub
== TRUE
);
2470 UsbIo
= &UsbIoController
->UsbIo
;
2478 gBS
->Stall (10 * 1000);
2481 // Wait for port reset complete
2488 (UINT32
*) &HubPortStatus
2490 gBS
->Stall (10 * 100);
2492 } while ((HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) == 0 && Number
> 0);
2496 // Cannot reset port, return error
2498 return EFI_DEVICE_ERROR
;
2506 (UINT32
*) &HubPortStatus
2509 // reset port will cause some bits change, clear them
2511 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
2512 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
2513 HubClearPortFeature (
2516 EfiUsbPortEnableChange
2520 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
2521 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
2522 HubClearPortFeature (
2525 EfiUsbPortResetChange
2534 ReportUsbStatusCode (
2535 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
2536 IN EFI_STATUS_CODE_TYPE Type
,
2537 IN EFI_STATUS_CODE_VALUE Code
2541 Routine Description:
2543 report a error Status code of USB bus driver controller
2546 UsbBusController - USB_BUS_CONTROLLER_DEVICE
2547 Type - EFI_STATUS_CODE_TYPE
2548 Code - EFI_STATUS_CODE_VALUE
2555 return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
2558 UsbBusController
->DevicePath
2563 IsDeviceDisconnected (
2564 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2565 IN OUT BOOLEAN
*Disconnected
2569 Routine Description:
2570 Reset if the device is disconencted or not
2573 UsbIoController - Indicating the Usb Controller Device.
2574 Disconnected - Indicate whether the device is disconencted or not
2582 USB_IO_DEVICE
*ParentIoDev
;
2583 USB_IO_DEVICE
*UsbIoDev
;
2584 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2587 EFI_USB_IO_PROTOCOL
*UsbIo
;
2588 EFI_USB_PORT_STATUS PortStatus
;
2590 ParentController
= UsbIoController
->Parent
;
2591 ParentIoDev
= ParentController
->UsbDevice
;
2592 UsbIoDev
= UsbIoController
->UsbDevice
;
2593 HubPort
= UsbIoController
->ParentPort
;
2595 if (ParentIoDev
->DeviceAddress
== 1) {
2597 // Connected to the root hub
2599 UsbVirtualHcGetRootHubPortStatus (
2600 ParentIoDev
->BusController
,
2606 UsbIo
= &UsbIoController
->UsbIo
;
2607 Status
= HubGetPortStatus (
2608 &ParentController
->UsbIo
,
2610 (UINT32
*) &PortStatus
2613 if (EFI_ERROR (Status
)) {
2614 return IsDeviceDisconnected (ParentController
, Disconnected
);
2618 *Disconnected
= FALSE
;
2620 if (!IsPortConnect (PortStatus
.PortStatus
)) {
2621 *Disconnected
= TRUE
;
2629 UsbSetTransactionTranslator (
2630 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
2631 IN UINT8 ParentPort
,
2632 IN OUT USB_IO_DEVICE
*Device
2636 Routine Description:
2638 Set Transaction Translator parameter
2642 ParentHubController - Controller structure of the parent Hub device
2643 ParentPort - Number of parent port
2644 Device - Structure of the device
2649 EFI_OUT_OF_RESOURCES Cannot allocate resources
2653 USB_IO_CONTROLLER_DEVICE
*AncestorHubController
;
2655 AncestorHubController
= ParentHubController
;
2656 Device
->Translator
= NULL
;
2658 if (EFI_USB_SPEED_HIGH
== Device
->DeviceSpeed
) {
2663 if (EFI_USB_SPEED_HIGH
== AncestorHubController
->UsbDevice
->DeviceSpeed
) {
2667 if (NULL
== AncestorHubController
->Parent
) {
2671 AncestorHubController
= AncestorHubController
->Parent
;
2674 Device
->Translator
= AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR
));
2675 if (NULL
== Device
->Translator
) {
2676 return EFI_OUT_OF_RESOURCES
;
2679 Device
->Translator
->TranslatorHubAddress
= AncestorHubController
->UsbDevice
->DeviceAddress
;
2680 Device
->Translator
->TranslatorPortNumber
= ParentPort
;
2687 UsbUnsetTransactionTranslator (
2688 USB_IO_DEVICE
*Device
2692 Routine Description:
2694 Unset Transaction Translator parameter
2698 Device - Structure of the device
2706 if (Device
->Translator
) {
2707 gBS
->FreePool (Device
->Translator
);
2708 Device
->Translator
= NULL
;
2716 IdentifyDeviceSpeed (
2717 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2718 USB_IO_DEVICE
*NewDevice
,
2723 Routine Description:
2725 Identify speed of USB device
2729 UsbBusDev - UsbBus controller structure of the device
2730 NewDevice - Devcie controller structure
2731 Index - Number of the port
2736 EFI_NOT_FOUND Device release to CHC or can't be found
2741 EFI_USB_PORT_STATUS HubPortStatus
;
2743 UsbVirtualHcGetRootHubPortStatus (
2746 (EFI_USB_PORT_STATUS
*) &HubPortStatus
2750 // Check device device
2752 if (!(HubPortStatus
.PortStatus
& USB_PORT_STAT_OWNER
)) {
2756 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2757 DEBUG ((gUSBDebugLevel
, "High Speed Device attached to EHC\n"));
2758 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2760 Status
= ReleasePortToCHC (UsbBusDev
, Index
);
2761 if (EFI_ERROR (Status
)) {
2762 DEBUG ((gUSBErrorLevel
, "Fail to release port to CHC\n"));
2764 DEBUG ((gUSBDebugLevel
, "Success to release port to CHC\n"));
2766 return EFI_DEVICE_ERROR
;
2772 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
2773 DEBUG ((gUSBDebugLevel
, "Low Speed Device attached to CHC\n"));
2774 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
2776 DEBUG ((gUSBDebugLevel
, "FULL Speed Device attached to CHC\n"));
2777 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2787 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2792 Routine Description:
2794 Set bit to release the port owner to CHC
2798 UsbBusDev - UsbBus controller structure of the device
2799 PortNum - Number of the port
2804 EFI_DEVICE_ERROR Fail
2810 Status
= UsbVirtualHcSetRootHubPortFeature (
2816 gBS
->Stall (100 * 1000);
2823 UsbVirtualHcGetCapability (
2824 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2825 OUT UINT8
*MaxSpeed
,
2826 OUT UINT8
*PortNumber
,
2827 OUT UINT8
*Is64BitCapable
2831 Routine Description:
2833 Virtual interface to Retrieves the capablility of root hub ports
2834 for both Hc2 and Hc protocol.
2838 UsbBusDev - A pointer to bus controller of the device.
2839 MaxSpeed - A pointer to the number of the host controller.
2840 PortNumber - A pointer to the number of the root hub ports.
2841 Is64BitCapable - A pointer to the flag for whether controller supports
2842 64-bit memory addressing.
2847 The host controller capability were retrieved successfully.
2848 EFI_INVALID_PARAMETER
2849 MaxSpeed or PortNumber or Is64BitCapable is NULL.
2851 An error was encountered while attempting to retrieve the capabilities.
2857 Status
= EFI_SUCCESS
;
2859 if (UsbBusDev
->Hc2ProtocolSupported
) {
2860 Status
= UsbBusDev
->Usb2HCInterface
->GetCapability (
2861 UsbBusDev
->Usb2HCInterface
,
2867 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortNumber (
2868 UsbBusDev
->UsbHCInterface
,
2871 *MaxSpeed
= EFI_USB_SPEED_FULL
;
2872 *Is64BitCapable
= (UINT8
) FALSE
;
2881 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2882 IN UINT16 Attributes
2886 Routine Description:
2888 Virtual interface to provides software reset for the USB host controller
2889 for both Hc2 and Hc protocol.
2893 UsbBusDev - A pointer to bus controller of the device.
2894 Attributes - A bit mask of the reset operation to perform.
2895 See below for a list of the supported bit mask values.
2897 #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc
2898 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
2899 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
2900 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
2902 EFI_USB_HC_RESET_GLOBAL
2903 If this bit is set, a global reset signal will be sent to the USB bus.
2904 This resets all of the USB bus logic, including the USB host
2905 controller hardware and all the devices attached on the USB bus.
2906 EFI_USB_HC_RESET_HOST_CONTROLLER
2907 If this bit is set, the USB host controller hardware will be reset.
2908 No reset signal will be sent to the USB bus.
2909 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
2910 If this bit is set, a global reset signal will be sent to the USB bus.
2911 This resets all of the USB bus logic, including the USB host
2912 controller hardware and all the devices attached on the USB bus.
2913 If this is an EHCI controller and the debug port has configured, then
2914 this is will still reset the host controller.
2915 EFI_USB_HC_RESET_HOST_WITH_DEBUG
2916 If this bit is set, the USB host controller hardware will be reset.
2917 If this is an EHCI controller and the debug port has been configured,
2918 then this will still reset the host controller.
2923 The reset operation succeeded.
2924 EFI_INVALID_PARAMETER
2925 Attributes is not valid.
2927 The type of reset specified by Attributes is not currently supported by
2928 the host controller hardware.
2930 Reset operation is rejected due to the debug port being configured and
2931 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
2932 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
2933 perform reset operation for this host controller.
2935 An error was encountered while attempting to perform
2936 the reset operation.
2942 Status
= EFI_SUCCESS
;
2944 if (UsbBusDev
->Hc2ProtocolSupported
) {
2945 Status
= UsbBusDev
->Usb2HCInterface
->Reset (
2946 UsbBusDev
->Usb2HCInterface
,
2947 EFI_USB_HC_RESET_GLOBAL
2950 Status
= UsbBusDev
->UsbHCInterface
->Reset (
2951 UsbBusDev
->UsbHCInterface
,
2952 EFI_USB_HC_RESET_GLOBAL
2961 UsbVirtualHcGetState (
2962 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2963 OUT EFI_USB_HC_STATE
*State
2967 Routine Description:
2969 Virtual interface to retrieves current state of the USB host controller
2970 for both Hc2 and Hc protocol.
2974 UsbBusDev - A pointer to bus controller of the device.
2975 State - A pointer to the EFI_USB_HC_STATE data structure that
2976 indicates current state of the USB host controller.
2977 Type EFI_USB_HC_STATE is defined below.
2981 EfiUsbHcStateOperational,
2982 EfiUsbHcStateSuspend,
2983 EfiUsbHcStateMaximum
2989 The state information of the host controller was returned in State.
2990 EFI_INVALID_PARAMETER
2993 An error was encountered while attempting to retrieve the
2994 host controller's current state.
3000 Status
= EFI_SUCCESS
;
3002 if (UsbBusDev
->Hc2ProtocolSupported
) {
3003 Status
= UsbBusDev
->Usb2HCInterface
->GetState (
3004 UsbBusDev
->Usb2HCInterface
,
3008 Status
= UsbBusDev
->UsbHCInterface
->GetState (
3009 UsbBusDev
->UsbHCInterface
,
3019 UsbVirtualHcSetState (
3020 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3021 IN EFI_USB_HC_STATE State
3025 Routine Description:
3027 Virtual interface to sets the USB host controller to a specific state
3028 for both Hc2 and Hc protocol.
3032 UsbBusDev - A pointer to bus controller of the device.
3033 State - Indicates the state of the host controller that will be set.
3038 The USB host controller was successfully placed in the state
3040 EFI_INVALID_PARAMETER
3043 Failed to set the state specified by State due to device error.
3049 Status
= EFI_SUCCESS
;
3051 if (UsbBusDev
->Hc2ProtocolSupported
) {
3052 Status
= UsbBusDev
->Usb2HCInterface
->SetState (
3053 UsbBusDev
->Usb2HCInterface
,
3057 Status
= UsbBusDev
->UsbHCInterface
->SetState (
3058 UsbBusDev
->UsbHCInterface
,
3068 UsbVirtualHcGetRootHubPortStatus (
3069 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3070 IN UINT8 PortNumber
,
3071 OUT EFI_USB_PORT_STATUS
*PortStatus
3075 Routine Description:
3077 Virtual interface to retrieves the current status of a USB root hub port
3078 both for Hc2 and Hc protocol.
3082 UsbBusDev - A pointer to bus controller of the device.
3083 PortNumber - Specifies the root hub port from which the status
3084 is to be retrieved. This value is zero-based. For example,
3085 if a root hub has two ports, then the first port is numbered 0,
3086 and the second port is numbered 1.
3087 PortStatus - A pointer to the current port status bits and
3088 port status change bits.
3092 EFI_SUCCESS The status of the USB root hub port specified by PortNumber
3093 was returned in PortStatus.
3094 EFI_INVALID_PARAMETER PortNumber is invalid.
3095 EFI_DEVICE_ERROR Can't read register
3101 Status
= EFI_SUCCESS
;
3103 if (UsbBusDev
->Hc2ProtocolSupported
) {
3104 Status
= UsbBusDev
->Usb2HCInterface
->GetRootHubPortStatus (
3105 UsbBusDev
->Usb2HCInterface
,
3110 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortStatus (
3111 UsbBusDev
->UsbHCInterface
,
3122 UsbVirtualHcSetRootHubPortFeature (
3123 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3124 IN UINT8 PortNumber
,
3125 IN EFI_USB_PORT_FEATURE PortFeature
3129 Routine Description:
3130 Virual interface to sets a feature for the specified root hub port
3131 for both Hc2 and Hc protocol.
3135 UsbBusDev - A pointer to bus controller of the device.
3136 PortNumber - Specifies the root hub port whose feature
3137 is requested to be set.
3138 PortFeature - Indicates the feature selector associated
3139 with the feature set request.
3144 The feature specified by PortFeature was set for the
3145 USB root hub port specified by PortNumber.
3146 EFI_INVALID_PARAMETER
3147 PortNumber is invalid or PortFeature is invalid.
3155 Status
= EFI_SUCCESS
;
3157 if (UsbBusDev
->Hc2ProtocolSupported
) {
3158 Status
= UsbBusDev
->Usb2HCInterface
->SetRootHubPortFeature (
3159 UsbBusDev
->Usb2HCInterface
,
3164 Status
= UsbBusDev
->UsbHCInterface
->SetRootHubPortFeature (
3165 UsbBusDev
->UsbHCInterface
,
3176 UsbVirtualHcClearRootHubPortFeature (
3177 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3178 IN UINT8 PortNumber
,
3179 IN EFI_USB_PORT_FEATURE PortFeature
3183 Routine Description:
3185 Virtual interface to clears a feature for the specified root hub port
3186 for both Hc2 and Hc protocol.
3190 UsbBusDev - A pointer to bus controller of the device.
3191 PortNumber - Specifies the root hub port whose feature
3192 is requested to be cleared.
3193 PortFeature - Indicates the feature selector associated with the
3194 feature clear request.
3199 The feature specified by PortFeature was cleared for the
3200 USB root hub port specified by PortNumber.
3201 EFI_INVALID_PARAMETER
3202 PortNumber is invalid or PortFeature is invalid.
3210 Status
= EFI_SUCCESS
;
3212 if (UsbBusDev
->Hc2ProtocolSupported
) {
3213 Status
= UsbBusDev
->Usb2HCInterface
->ClearRootHubPortFeature (
3214 UsbBusDev
->Usb2HCInterface
,
3219 Status
= UsbBusDev
->UsbHCInterface
->ClearRootHubPortFeature (
3220 UsbBusDev
->UsbHCInterface
,
3231 UsbVirtualHcControlTransfer (
3232 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3233 IN UINT8 DeviceAddress
,
3234 IN UINT8 DeviceSpeed
,
3235 IN UINTN MaximumPacketLength
,
3236 IN EFI_USB_DEVICE_REQUEST
*Request
,
3237 IN EFI_USB_DATA_DIRECTION TransferDirection
,
3239 IN OUT UINTN
*DataLength
,
3241 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3242 OUT UINT32
*TransferResult
3246 Routine Description:
3248 Virtual interface to submits control transfer to a target USB device
3249 for both Hc2 and Hc protocol.
3253 UsbBusDev - A pointer to bus controller of the device.
3254 DeviceAddress - Represents the address of the target device on the USB,
3255 which is assigned during USB enumeration.
3256 DeviceSpeed - Indicates target device speed.
3257 MaximumPacketLength - Indicates the maximum packet size that the
3258 default control transfer endpoint is capable of
3259 sending or receiving.
3260 Request - A pointer to the USB device request that will be sent
3262 TransferDirection - Specifies the data direction for the transfer.
3263 There are three values available, DataIn, DataOut
3265 Data - A pointer to the buffer of data that will be transmitted
3266 to USB device or received from USB device.
3267 DataLength - Indicates the size, in bytes, of the data buffer
3269 TimeOut - Indicates the maximum time, in microseconds,
3270 which the transfer is allowed to complete.
3271 Translator - A pointr to the transaction translator data.
3272 TransferResult - A pointer to the detailed result information generated
3273 by this control transfer.
3278 The control transfer was completed successfully.
3279 EFI_OUT_OF_RESOURCES
3280 The control transfer could not be completed due to a lack of resources.
3281 EFI_INVALID_PARAMETER
3282 Some parameters are invalid.
3284 The control transfer failed due to timeout.
3286 The control transfer failed due to host controller or device error.
3287 Caller should check TranferResult for detailed error information.
3292 BOOLEAN IsSlowDevice
;
3294 Status
= EFI_SUCCESS
;
3296 if (UsbBusDev
->Hc2ProtocolSupported
) {
3297 Status
= UsbBusDev
->Usb2HCInterface
->ControlTransfer (
3298 UsbBusDev
->Usb2HCInterface
,
3301 MaximumPacketLength
,
3311 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3312 Status
= UsbBusDev
->UsbHCInterface
->ControlTransfer (
3313 UsbBusDev
->UsbHCInterface
,
3316 (UINT8
) MaximumPacketLength
,
3331 UsbVirtualHcBulkTransfer (
3332 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3333 IN UINT8 DeviceAddress
,
3334 IN UINT8 EndPointAddress
,
3335 IN UINT8 DeviceSpeed
,
3336 IN UINTN MaximumPacketLength
,
3337 IN UINT8 DataBuffersNumber
,
3338 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
3339 IN OUT UINTN
*DataLength
,
3340 IN OUT UINT8
*DataToggle
,
3342 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3343 OUT UINT32
*TransferResult
3347 Routine Description:
3349 Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
3350 both for Hc2 and Hc protocol.
3354 UsbBusDev - A pointer to bus controller of the device.
3355 DeviceAddress - Represents the address of the target device on the USB,
3356 which is assigned during USB enumeration.
3357 EndPointAddress - The combination of an endpoint number and an
3358 endpoint direction of the target USB device.
3359 Each endpoint address supports data transfer in
3360 one direction except the control endpoint
3361 (whose default endpoint address is 0).
3362 It is the caller's responsibility to make sure that
3363 the EndPointAddress represents a bulk endpoint.
3364 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
3365 and EFI_USB_SPEED_HIGH.
3366 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3367 is capable of sending or receiving.
3368 DataBuffersNumber - Number of data buffers prepared for the transfer.
3369 Data - Array of pointers to the buffers of data that will be transmitted
3370 to USB device or received from USB device.
3371 DataLength - When input, indicates the size, in bytes, of the data buffer
3372 specified by Data. When output, indicates the actually
3373 transferred data size.
3374 DataToggle - A pointer to the data toggle value. On input, it indicates
3375 the initial data toggle value the bulk transfer should adopt;
3376 on output, it is updated to indicate the data toggle value
3377 of the subsequent bulk transfer.
3378 Translator - A pointr to the transaction translator data.
3379 TimeOut - Indicates the maximum time, in microseconds, which the
3380 transfer is allowed to complete.
3381 TransferResult - A pointer to the detailed result information of the
3387 The bulk transfer was completed successfully.
3388 EFI_OUT_OF_RESOURCES
3389 The bulk transfer could not be submitted due to lack of resource.
3390 EFI_INVALID_PARAMETER
3391 Some parameters are invalid.
3393 The bulk transfer failed due to timeout.
3395 The bulk transfer failed due to host controller or device error.
3396 Caller should check TranferResult for detailed error information.
3402 Status
= EFI_SUCCESS
;
3404 if (UsbBusDev
->Hc2ProtocolSupported
) {
3405 Status
= UsbBusDev
->Usb2HCInterface
->BulkTransfer (
3406 UsbBusDev
->Usb2HCInterface
,
3410 MaximumPacketLength
,
3420 Status
= UsbBusDev
->UsbHCInterface
->BulkTransfer (
3421 UsbBusDev
->UsbHCInterface
,
3424 (UINT8
) MaximumPacketLength
,
3438 UsbVirtualHcAsyncInterruptTransfer (
3439 IN USB_BUS_CONTROLLER_DEVICE
* UsbBusDev
,
3440 IN UINT8 DeviceAddress
,
3441 IN UINT8 EndPointAddress
,
3442 IN UINT8 DeviceSpeed
,
3443 IN UINTN MaximumPacketLength
,
3444 IN BOOLEAN IsNewTransfer
,
3445 IN OUT UINT8
*DataToggle
,
3446 IN UINTN PollingInterval
,
3447 IN UINTN DataLength
,
3448 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
3449 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
3450 IN VOID
*Context OPTIONAL
3454 Routine Description:
3456 Virtual interface to submits an asynchronous interrupt transfer to an
3457 interrupt endpoint of a USB device for both Hc2 and Hc protocol.
3461 UsbBusDev - A pointer to bus controller of the device.
3462 DeviceAddress - Represents the address of the target device on the USB,
3463 which is assigned during USB enumeration.
3464 EndPointAddress - The combination of an endpoint number and an endpoint
3465 direction of the target USB device. Each endpoint address
3466 supports data transfer in one direction except the
3467 control endpoint (whose default endpoint address is 0).
3468 It is the caller's responsibility to make sure that
3469 the EndPointAddress represents an interrupt endpoint.
3470 DeviceSpeed - Indicates device speed.
3471 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3472 is capable of sending or receiving.
3473 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
3474 the host and the target interrupt endpoint.
3475 If FALSE, the specified asynchronous interrupt pipe
3477 DataToggle - A pointer to the data toggle value. On input, it is valid
3478 when IsNewTransfer is TRUE, and it indicates the initial
3479 data toggle value the asynchronous interrupt transfer
3481 On output, it is valid when IsNewTransfer is FALSE,
3482 and it is updated to indicate the data toggle value of
3483 the subsequent asynchronous interrupt transfer.
3484 PollingInterval - Indicates the interval, in milliseconds, that the
3485 asynchronous interrupt transfer is polled.
3486 This parameter is required when IsNewTransfer is TRUE.
3487 DataLength - Indicates the length of data to be received at the
3488 rate specified by PollingInterval from the target
3489 asynchronous interrupt endpoint. This parameter
3490 is only required when IsNewTransfer is TRUE.
3491 Translator - A pointr to the transaction translator data.
3492 CallBackFunction - The Callback function.This function is called at the
3493 rate specified by PollingInterval.This parameter is
3494 only required when IsNewTransfer is TRUE.
3495 Context - The context that is passed to the CallBackFunction.
3496 - This is an optional parameter and may be NULL.
3501 The asynchronous interrupt transfer request has been successfully
3502 submitted or canceled.
3503 EFI_INVALID_PARAMETER
3504 Some parameters are invalid.
3505 EFI_OUT_OF_RESOURCES
3506 The request could not be completed due to a lack of resources.
3513 BOOLEAN IsSlowDevice
;
3515 Status
= EFI_SUCCESS
;
3517 if (UsbBusDev
->Hc2ProtocolSupported
) {
3518 Status
= UsbBusDev
->Usb2HCInterface
->AsyncInterruptTransfer (
3519 UsbBusDev
->Usb2HCInterface
,
3523 MaximumPacketLength
,
3533 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3534 Status
= UsbBusDev
->UsbHCInterface
->AsyncInterruptTransfer (
3535 UsbBusDev
->UsbHCInterface
,
3539 (UINT8
) MaximumPacketLength
,
3554 UsbVirtualHcSyncInterruptTransfer (
3555 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3556 IN UINT8 DeviceAddress
,
3557 IN UINT8 EndPointAddress
,
3558 IN UINT8 DeviceSpeed
,
3559 IN UINTN MaximumPacketLength
,
3561 IN OUT UINTN
*DataLength
,
3562 IN OUT UINT8
*DataToggle
,
3564 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3565 OUT UINT32
*TransferResult
3569 Routine Description:
3571 Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
3572 of a USB device for both Hc2 and Hc protocol.
3576 UsbBusDev - A pointer to bus controller of the device.
3577 DeviceAddress - Represents the address of the target device on the USB,
3578 which is assigned during USB enumeration.
3579 EndPointAddress - The combination of an endpoint number and an endpoint
3580 direction of the target USB device. Each endpoint
3581 address supports data transfer in one direction
3582 except the control endpoint (whose default
3583 endpoint address is 0). It is the caller's responsibility
3584 to make sure that the EndPointAddress represents
3585 an interrupt endpoint.
3586 DeviceSpeed - Indicates device speed.
3587 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3588 is capable of sending or receiving.
3589 Data - A pointer to the buffer of data that will be transmitted
3590 to USB device or received from USB device.
3591 DataLength - On input, the size, in bytes, of the data buffer specified
3592 by Data. On output, the number of bytes transferred.
3593 DataToggle - A pointer to the data toggle value. On input, it indicates
3594 the initial data toggle value the synchronous interrupt
3595 transfer should adopt;
3596 on output, it is updated to indicate the data toggle value
3597 of the subsequent synchronous interrupt transfer.
3598 TimeOut - Indicates the maximum time, in microseconds, which the
3599 transfer is allowed to complete.
3600 Translator - A pointr to the transaction translator data.
3601 TransferResult - A pointer to the detailed result information from
3602 the synchronous interrupt transfer.
3607 The synchronous interrupt transfer was completed successfully.
3608 EFI_OUT_OF_RESOURCES
3609 The synchronous interrupt transfer could not be submitted due
3610 to lack of resource.
3611 EFI_INVALID_PARAMETER
3612 Some parameters are invalid.
3614 The synchronous interrupt transfer failed due to timeout.
3616 The synchronous interrupt transfer failed due to host controller
3617 or device error. Caller should check TranferResult for detailed
3623 BOOLEAN IsSlowDevice
;
3625 Status
= EFI_SUCCESS
;
3627 if (UsbBusDev
->Hc2ProtocolSupported
) {
3628 Status
= UsbBusDev
->Usb2HCInterface
->SyncInterruptTransfer (
3629 UsbBusDev
->Usb2HCInterface
,
3633 MaximumPacketLength
,
3642 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3643 Status
= UsbBusDev
->UsbHCInterface
->SyncInterruptTransfer (
3644 UsbBusDev
->UsbHCInterface
,
3648 (UINT8
) MaximumPacketLength
,
3662 UsbVirtualHcIsochronousTransfer (
3663 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3664 IN UINT8 DeviceAddress
,
3665 IN UINT8 EndPointAddress
,
3666 IN UINT8 DeviceSpeed
,
3667 IN UINTN MaximumPacketLength
,
3668 IN UINT8 DataBuffersNumber
,
3669 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3670 IN UINTN DataLength
,
3671 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3672 OUT UINT32
*TransferResult
3676 Routine Description:
3678 Virtual interface to submits isochronous transfer to a target USB device
3679 for both Hc2 and Hc protocol.
3683 UsbBusDev - A pointer to bus controller of the device.
3684 DeviceAddress - Represents the address of the target device on the USB,
3685 which is assigned during USB enumeration.
3686 EndPointAddress - End point address
3687 DeviceSpeed - Indicates device speed.
3688 MaximumPacketLength - Indicates the maximum packet size that the
3689 default control transfer endpoint is capable of
3690 sending or receiving.
3691 DataBuffersNumber - Number of data buffers prepared for the transfer.
3692 Data - Array of pointers to the buffers of data that will be
3693 transmitted to USB device or received from USB device.
3694 DataLength - Indicates the size, in bytes, of the data buffer
3696 Translator - A pointr to the transaction translator data.
3697 TransferResult - A pointer to the detailed result information generated
3698 by this control transfer.
3706 return EFI_UNSUPPORTED
;
3711 UsbVirtualHcAsyncIsochronousTransfer (
3712 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3713 IN UINT8 DeviceAddress
,
3714 IN UINT8 EndPointAddress
,
3715 IN UINT8 DeviceSpeed
,
3716 IN UINTN MaximumPacketLength
,
3717 IN UINT8 DataBuffersNumber
,
3718 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3719 IN UINTN DataLength
,
3720 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3721 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
3726 Routine Description:
3728 Vitual interface to submits Async isochronous transfer to a target USB device
3729 for both Hc2 and Hc protocol.
3733 UsbBusDev - A pointer to bus controller of the device.
3734 DeviceAddress - Represents the address of the target device on the USB,
3735 which is assigned during USB enumeration.
3736 EndPointAddress - End point address
3737 DeviceSpeed - Indicates device speed.
3738 MaximumPacketLength - Indicates the maximum packet size that the
3739 default control transfer endpoint is capable of
3740 sending or receiving.
3741 DataBuffersNumber - Number of data buffers prepared for the transfer.
3742 Data - Array of pointers to the buffers of data that will be transmitted
3743 to USB device or received from USB device.
3744 DataLength - Indicates the size, in bytes, of the data buffer
3746 Translator - A pointr to the transaction translator data.
3747 IsochronousCallBack - When the transfer complete, the call back function will be called
3748 Context - Pass to the call back function as parameter
3756 return EFI_UNSUPPORTED
;