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
88 USB_IO_CONTROLLER_DEVICE
*
89 CreateUsbIoControllerDevice (
96 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
100 // USB Device Configuration / Deconfiguration
104 UsbDeviceConfiguration (
105 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
106 IN EFI_HANDLE HostController
,
108 IN USB_IO_DEVICE
*UsbIoDevice
112 // Usb Bus enumeration function
130 UsbSetTransactionTranslator (
131 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
133 IN OUT USB_IO_DEVICE
*Device
138 UsbUnsetTransactionTranslator (
139 USB_IO_DEVICE
*Device
144 IdentifyDeviceSpeed (
145 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
146 USB_IO_DEVICE
*NewDevice
,
153 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
159 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
166 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
173 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
174 IN BOOLEAN ReConfigure
,
179 // Following are address allocate and free functions
184 IN UINT8
*AddressPool
189 Allocate address for usb device
192 AddressPool - Pool of usb device address
202 for (ByteIndex
= 0; ByteIndex
< 16; ByteIndex
++) {
203 for (BitIndex
= 0; BitIndex
< 8; BitIndex
++) {
204 if ((AddressPool
[ByteIndex
] & (1 << BitIndex
)) == 0) {
206 // Found one, covert to address, and mark it use
208 AddressPool
[ByteIndex
] = (UINT8
) (AddressPool
[ByteIndex
] | (1 << BitIndex
));
209 return (UINT8
) (ByteIndex
* 8 + BitIndex
);
222 IN UINT8
*AddressPool
227 Free address for usb device
230 DevAddress - Usb device address
231 AddressPool - Pool of usb device address
241 // Locate the position
243 WhichByte
= (UINT8
) (DevAddress
/ 8);
244 WhichBit
= (UINT8
) (DevAddress
& 0x7);
246 AddressPool
[WhichByte
] = (UINT8
) (AddressPool
[WhichByte
] & (~(1 << WhichBit
)));
251 UsbBusControllerDriverSupported (
252 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
253 IN EFI_HANDLE Controller
,
254 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
259 Test to see if this driver supports ControllerHandle. Any ControllerHandle
260 that has UsbHcProtocol installed will be supported.
263 This - Protocol instance pointer.
264 Controller - Handle of device to test
265 RemainingDevicePath - Device Path Protocol instance pointer
268 EFI_SUCCESS - This driver supports this device.
269 EFI_UNSUPPORTED - This driver does not support this device.
274 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
275 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
276 EFI_USB_HC_PROTOCOL
*UsbHc
;
277 EFI_DEV_PATH_PTR Node
;
282 if (RemainingDevicePath
!= NULL
) {
283 Node
.DevPath
= RemainingDevicePath
;
284 if (Node
.DevPath
->Type
!= MESSAGING_DEVICE_PATH
||
285 Node
.DevPath
->SubType
!= MSG_USB_DP
||
286 DevicePathNodeLength(Node
.DevPath
) != sizeof(USB_DEVICE_PATH
)) {
287 return EFI_UNSUPPORTED
;
292 // Open the IO Abstraction(s) needed to perform the supported test
294 Status
= gBS
->OpenProtocol (
296 &gEfiDevicePathProtocolGuid
,
297 (VOID
**) &ParentDevicePath
,
298 This
->DriverBindingHandle
,
300 EFI_OPEN_PROTOCOL_BY_DRIVER
302 if (Status
== EFI_ALREADY_STARTED
) {
306 if (EFI_ERROR (Status
)) {
312 &gEfiDevicePathProtocolGuid
,
313 This
->DriverBindingHandle
,
318 // Check whether USB Host Controller Protocol is already
319 // installed on this handle. If it is installed, we can start
320 // USB Bus Driver now.
322 Status
= gBS
->OpenProtocol (
324 &gEfiUsb2HcProtocolGuid
,
326 This
->DriverBindingHandle
,
328 EFI_OPEN_PROTOCOL_BY_DRIVER
330 if (Status
== EFI_ALREADY_STARTED
) {
334 if (EFI_ERROR (Status
)) {
335 Status
= gBS
->OpenProtocol (
337 &gEfiUsbHcProtocolGuid
,
339 This
->DriverBindingHandle
,
341 EFI_OPEN_PROTOCOL_BY_DRIVER
343 if (Status
== EFI_ALREADY_STARTED
) {
347 if (EFI_ERROR (Status
)) {
353 &gEfiUsbHcProtocolGuid
,
354 This
->DriverBindingHandle
,
362 &gEfiUsb2HcProtocolGuid
,
363 This
->DriverBindingHandle
,
372 UsbBusControllerDriverStart (
373 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
374 IN EFI_HANDLE Controller
,
375 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
381 Starting the Usb Bus Driver
385 This - Protocol instance pointer.
386 Controller - Handle of device to test
387 RemainingDevicePath - Not used
391 EFI_SUCCESS - This driver supports this device.
392 EFI_DEVICE_ERROR - This driver cannot be started due to device
393 EFI_OUT_OF_RESOURCES- Can't allocate memory resources
398 EFI_STATUS OpenStatus
;
399 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
400 USB_IO_DEVICE
*RootHub
;
401 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
404 UINT8 Is64BitCapable
;
407 // Allocate USB_BUS_CONTROLLER_DEVICE structure
410 UsbBusDev
= AllocateZeroPool (sizeof (USB_BUS_CONTROLLER_DEVICE
));
411 if (UsbBusDev
== NULL
) {
412 return EFI_OUT_OF_RESOURCES
;
415 UsbBusDev
->Signature
= USB_BUS_DEVICE_SIGNATURE
;
416 UsbBusDev
->AddressPool
[0] = 1;
419 // Get the Device Path Protocol on Controller's handle
421 OpenStatus
= gBS
->OpenProtocol (
423 &gEfiDevicePathProtocolGuid
,
424 (VOID
**) &UsbBusDev
->DevicePath
,
425 This
->DriverBindingHandle
,
427 EFI_OPEN_PROTOCOL_BY_DRIVER
430 if (EFI_ERROR (OpenStatus
)) {
431 gBS
->FreePool (UsbBusDev
);
435 // Locate the Host Controller Interface
437 OpenStatus
= gBS
->OpenProtocol (
439 &gEfiUsb2HcProtocolGuid
,
440 (VOID
**) &(UsbBusDev
->Usb2HCInterface
),
441 This
->DriverBindingHandle
,
443 EFI_OPEN_PROTOCOL_BY_DRIVER
445 if (EFI_ERROR (OpenStatus
)) {
447 UsbBusDev
->Hc2ProtocolSupported
= FALSE
;
448 OpenStatus
= gBS
->OpenProtocol (
450 &gEfiUsbHcProtocolGuid
,
451 (VOID
**) &(UsbBusDev
->UsbHCInterface
),
452 This
->DriverBindingHandle
,
454 EFI_OPEN_PROTOCOL_BY_DRIVER
456 if (EFI_ERROR (OpenStatus
)) {
458 // Report Status Code here since we will reset the host controller
460 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
461 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
462 EFI_IO_BUS_USB
| EFI_IOB_EC_CONTROLLER_ERROR
,
463 UsbBusDev
->DevicePath
468 &gEfiDevicePathProtocolGuid
,
469 This
->DriverBindingHandle
,
472 gBS
->FreePool (UsbBusDev
);
476 DEBUG ((gUSBDebugLevel
, "UsbHcProtocol Opened.\n"));
478 DEBUG ((gUSBDebugLevel
, "Usb2HcProtocol Opened.\n"));
479 UsbBusDev
->Hc2ProtocolSupported
= TRUE
;
483 // Attach EFI_USB_BUS_PROTOCOL to controller handle,
484 // for locate UsbBusDev later
486 Status
= gBS
->InstallProtocolInterface (
488 &mUsbBusProtocolGuid
,
489 EFI_NATIVE_INTERFACE
,
490 &UsbBusDev
->BusIdentify
493 if (EFI_ERROR (Status
)) {
497 &gEfiDevicePathProtocolGuid
,
498 This
->DriverBindingHandle
,
501 if (UsbBusDev
->Hc2ProtocolSupported
) {
504 &gEfiUsb2HcProtocolGuid
,
505 This
->DriverBindingHandle
,
511 &gEfiUsbHcProtocolGuid
,
512 This
->DriverBindingHandle
,
517 gBS
->FreePool (UsbBusDev
);
521 // Add root hub to the tree
524 RootHub
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
525 if (RootHub
== NULL
) {
526 gBS
->UninstallProtocolInterface (
528 &mUsbBusProtocolGuid
,
529 &UsbBusDev
->BusIdentify
533 &gEfiDevicePathProtocolGuid
,
534 This
->DriverBindingHandle
,
537 if (UsbBusDev
->Hc2ProtocolSupported
) {
540 &gEfiUsb2HcProtocolGuid
,
541 This
->DriverBindingHandle
,
547 &gEfiUsbHcProtocolGuid
,
548 This
->DriverBindingHandle
,
553 gBS
->FreePool (UsbBusDev
);
554 return EFI_OUT_OF_RESOURCES
;
557 RootHub
->BusController
= UsbBusDev
;
558 RootHub
->DeviceAddress
= UsbAllocateAddress (UsbBusDev
->AddressPool
);
560 UsbBusDev
->Root
= RootHub
;
563 // Allocate Root Hub Controller
565 RootHubController
= CreateUsbIoControllerDevice ();
566 if (RootHubController
== NULL
) {
567 gBS
->UninstallProtocolInterface (
569 &mUsbBusProtocolGuid
,
570 &UsbBusDev
->BusIdentify
574 &gEfiDevicePathProtocolGuid
,
575 This
->DriverBindingHandle
,
578 if (UsbBusDev
->Hc2ProtocolSupported
) {
581 &gEfiUsb2HcProtocolGuid
,
582 This
->DriverBindingHandle
,
588 &gEfiUsbHcProtocolGuid
,
589 This
->DriverBindingHandle
,
593 gBS
->FreePool (UsbBusDev
);
594 gBS
->FreePool (RootHub
);
595 return EFI_OUT_OF_RESOURCES
;
598 UsbVirtualHcGetCapability (
604 RootHubController
->DownstreamPorts
= PortNumber
;
605 RootHubController
->UsbDevice
= RootHub
;
606 RootHubController
->IsUsbHub
= TRUE
;
607 RootHubController
->DevicePath
= UsbBusDev
->DevicePath
;
608 RootHubController
->HostController
= Controller
;
610 RootHub
->NumOfControllers
= 1;
611 RootHub
->UsbController
[0] = RootHubController
;
612 RootHub
->DeviceSpeed
= MaxSpeed
;
615 // Report Status Code here since we will reset the host controller
617 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
619 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
,
620 UsbBusDev
->DevicePath
624 // Reset USB Host Controller
628 EFI_USB_HC_RESET_GLOBAL
632 // Report Status Code while we are going to bring up the Host Controller
633 // and start bus enumeration
635 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
637 EFI_IO_BUS_USB
| EFI_IOB_PC_ENABLE
,
638 UsbBusDev
->DevicePath
642 // Start USB Host Controller
644 UsbVirtualHcSetState (
646 EfiUsbHcStateOperational
650 // Create a timer to query root ports periodically
652 Status
= gBS
->CreateEvent (
653 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
657 &RootHubController
->HubNotify
659 if (EFI_ERROR (Status
)) {
660 gBS
->UninstallProtocolInterface (
662 &mUsbBusProtocolGuid
,
663 &UsbBusDev
->BusIdentify
668 &gEfiDevicePathProtocolGuid
,
669 This
->DriverBindingHandle
,
673 if (UsbBusDev
->Hc2ProtocolSupported
) {
676 &gEfiUsb2HcProtocolGuid
,
677 This
->DriverBindingHandle
,
683 &gEfiUsbHcProtocolGuid
,
684 This
->DriverBindingHandle
,
689 gBS
->FreePool (RootHubController
);
690 gBS
->FreePool (RootHub
);
691 gBS
->FreePool (UsbBusDev
);
692 return EFI_OUT_OF_RESOURCES
;
696 // Before depending on the timer to check root ports periodically,
697 // here we should check them immediately for the first time, or
698 // there will be an interval between bus start and devices start.
700 gBS
->SignalEvent (RootHubController
->HubNotify
);
702 Status
= gBS
->SetTimer (
703 RootHubController
->HubNotify
,
707 if (EFI_ERROR (Status
)) {
708 gBS
->UninstallProtocolInterface (
710 &mUsbBusProtocolGuid
,
711 &UsbBusDev
->BusIdentify
716 &gEfiDevicePathProtocolGuid
,
717 This
->DriverBindingHandle
,
721 if (UsbBusDev
->Hc2ProtocolSupported
) {
724 &gEfiUsb2HcProtocolGuid
,
725 This
->DriverBindingHandle
,
731 &gEfiUsbHcProtocolGuid
,
732 This
->DriverBindingHandle
,
737 gBS
->CloseEvent (RootHubController
->HubNotify
);
738 gBS
->FreePool (RootHubController
);
739 gBS
->FreePool (RootHub
);
740 gBS
->FreePool (UsbBusDev
);
741 return EFI_DEVICE_ERROR
;
748 // Stop the bus controller
752 UsbBusControllerDriverStop (
753 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
754 IN EFI_HANDLE Controller
,
755 IN UINTN NumberOfChildren
,
756 IN EFI_HANDLE
*ChildHandleBuffer
761 Stop this driver on ControllerHandle. Support stoping any child handles
762 created by this driver.
765 This - Protocol instance pointer.
766 Controller - Handle of device to stop driver on
767 NumberOfChildren - Number of Children in the ChildHandleBuffer
768 ChildHandleBuffer - List of handles for the children we need to stop.
779 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
780 USB_BUS_CONTROLLER_DEVICE
*UsbBusController
;
781 EFI_USB_BUS_PROTOCOL
*UsbIdentifier
;
783 USB_IO_CONTROLLER_DEVICE
*UsbController
;
784 USB_IO_DEVICE
*UsbIoDevice
;
785 USB_IO_CONTROLLER_DEVICE
*HubController
;
787 EFI_USB_IO_PROTOCOL
*UsbIo
;
789 if (NumberOfChildren
> 0) {
791 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
792 Status
= gBS
->OpenProtocol (
793 ChildHandleBuffer
[Index
],
794 &gEfiUsbIoProtocolGuid
,
796 This
->DriverBindingHandle
,
798 EFI_OPEN_PROTOCOL_GET_PROTOCOL
800 if (EFI_ERROR (Status
)) {
802 // We are here since the handle passed in does not support
803 // UsbIo protocol. There are several reasons that will cause
805 // For combo device such as keyboard, it may have 2 devices
806 // in one, namely, keyboard and mouse. If we deconfigure one
807 // of them, the other will be freed at the same time. This will
808 // cause the status error. But this is the correct behavior.
809 // For hub device, if we deconfigure hub first, the other chile
810 // device will be disconnected also, this will also provide us
811 // a status error. Now we will only report EFI_SUCCESS since Uhc
812 // driver will be disconnected at the second time.(pls see
813 // CoreDisconnectController for details)
818 UsbController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (UsbIo
);
819 UsbIoDevice
= UsbController
->UsbDevice
;
820 HubController
= UsbController
->Parent
;
821 UsbDeviceDeConfiguration (UsbIoDevice
);
822 for (Index2
= 0; Index2
< HubController
->DownstreamPorts
; Index2
++) {
823 if (HubController
->Children
[Index2
] == UsbIoDevice
) {
824 HubController
->Children
[Index2
] = NULL
;
832 // Get the USB_BUS_CONTROLLER_DEVICE
834 Status
= gBS
->OpenProtocol (
836 &mUsbBusProtocolGuid
,
837 (VOID
**) &UsbIdentifier
,
838 This
->DriverBindingHandle
,
840 EFI_OPEN_PROTOCOL_GET_PROTOCOL
843 if (EFI_ERROR (Status
)) {
844 return EFI_DEVICE_ERROR
;
847 UsbBusController
= USB_BUS_CONTROLLER_DEVICE_FROM_THIS (UsbIdentifier
);
850 // Stop USB Host Controller
854 // Report Status Code here since we will reset the host controller
856 ReportUsbStatusCode (
859 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
862 UsbVirtualHcSetState (
868 // Deconfiguration all its devices
870 Root
= UsbBusController
->Root
;
871 RootHubController
= Root
->UsbController
[0];
873 gBS
->CloseEvent (RootHubController
->HubNotify
);
875 for (Index2
= 0; Index2
< RootHubController
->DownstreamPorts
; Index2
++) {
876 if (RootHubController
->Children
[Index2
]) {
877 UsbDeviceDeConfiguration (RootHubController
->Children
[Index2
]);
878 RootHubController
->Children
[Index2
] = NULL
;
882 gBS
->FreePool (RootHubController
);
883 gBS
->FreePool (Root
);
886 // Uninstall USB Bus Protocol
888 gBS
->UninstallProtocolInterface (
890 &mUsbBusProtocolGuid
,
891 &UsbBusController
->BusIdentify
895 // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL
896 // Opened by this Controller
898 if (UsbBusController
->Hc2ProtocolSupported
) {
901 &gEfiUsb2HcProtocolGuid
,
902 This
->DriverBindingHandle
,
908 &gEfiUsbHcProtocolGuid
,
909 This
->DriverBindingHandle
,
916 &gEfiDevicePathProtocolGuid
,
917 This
->DriverBindingHandle
,
921 gBS
->FreePool (UsbBusController
);
926 // USB Device Configuration
930 UsbDeviceConfiguration (
931 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
932 IN EFI_HANDLE HostController
,
934 IN USB_IO_DEVICE
*UsbIoDevice
939 Configurate a new device attached to the usb bus
942 ParentHubController - Parent Hub which this device is connected.
943 HostController - Host Controller handle
944 ParentPort - Parent Hub port which this device is connected.
945 UsbIoDevice - The device to be configured.
958 CHAR16
*StrManufacturer
;
960 CHAR16
*StrSerialNumber
;
961 EFI_USB_IO_PROTOCOL
*UsbIo
;
962 UINT8 NumOfInterface
;
963 USB_IO_CONTROLLER_DEVICE
*FirstController
;
964 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
965 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
967 UsbBusDev
= UsbIoDevice
->BusController
;
969 UsbSetTransactionTranslator (
976 // Since a USB device must have at least on interface,
977 // so create this instance first
979 FirstController
= CreateUsbIoControllerDevice ();
980 FirstController
->UsbDevice
= UsbIoDevice
;
981 UsbIoDevice
->UsbController
[0] = FirstController
;
982 FirstController
->InterfaceNumber
= 0;
983 FirstController
->ParentPort
= ParentPort
;
984 FirstController
->Parent
= ParentHubController
;
985 FirstController
->HostController
= HostController
;
987 InitializeUsbIoInstance (FirstController
);
989 DEBUG ((gUSBDebugLevel
, "Configuration Usb Device at 0x%x...\n", ParentPort
));
992 // Ensure we used the correctly USB I/O instance
994 UsbIo
= &FirstController
->UsbIo
;
996 if (UsbIoDevice
->DeviceSpeed
!= EFI_USB_SPEED_HIGH
) {
997 ParentPortReset (FirstController
, FALSE
, 0);
1001 // First retrieve the 1st 8 bytes of
1002 // in order to get the MaxPacketSize for Endpoint 0
1004 for (Index
= 0; Index
< 3; Index
++) {
1006 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1008 gBS
->Stall (100 * 1000);
1010 Result
= UsbGetDescriptor (
1012 (USB_DT_DEVICE
<< 8),
1015 &UsbIoDevice
->DeviceDescriptor
,
1018 if (!EFI_ERROR (Result
)) {
1021 "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
1022 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
)
1030 ReportUsbStatusCode (
1032 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1033 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1035 DEBUG ((gUSBErrorLevel
, "Get Device Descriptor Fail when configing\n"));
1036 gBS
->FreePool (FirstController
);
1037 return EFI_DEVICE_ERROR
;
1040 DevAddress
= UsbAllocateAddress (UsbIoDevice
->BusController
->AddressPool
);
1041 if (DevAddress
== 0) {
1042 DEBUG ((gUSBErrorLevel
, "Cannot allocate address\n"));
1043 gBS
->FreePool (FirstController
);
1044 return EFI_OUT_OF_RESOURCES
;
1047 Result
= UsbSetDeviceAddress (UsbIo
, DevAddress
, &Status
);
1049 if (EFI_ERROR (Result
)) {
1050 DEBUG ((gUSBErrorLevel
, "Set address error\n"));
1051 ReportUsbStatusCode (
1053 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1054 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1059 UsbIoDevice
->BusController
->AddressPool
1062 gBS
->FreePool (FirstController
);
1063 return EFI_DEVICE_ERROR
;
1066 UsbIoDevice
->DeviceAddress
= DevAddress
;
1069 // SetAddress Complete Time by Spec, Max 50ms
1071 gBS
->Stall (10 * 1000);
1074 // Get the whole device descriptor
1076 Result
= UsbGetDescriptor (
1078 (USB_DT_DEVICE
<< 8),
1080 sizeof (EFI_USB_DEVICE_DESCRIPTOR
),
1081 &UsbIoDevice
->DeviceDescriptor
,
1085 if (EFI_ERROR (Result
)) {
1086 DEBUG ((gUSBErrorLevel
, "Get whole Device Descriptor error\n"));
1087 ReportUsbStatusCode (
1089 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1090 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1094 UsbIoDevice
->BusController
->AddressPool
1097 gBS
->FreePool (FirstController
);
1098 return EFI_DEVICE_ERROR
;
1101 // Get & parse all configurations for this device, including
1102 // all configuration descriptors, all interface descriptors, all
1103 // endpoint descriptors
1105 Result
= UsbGetAllConfigurations (UsbIoDevice
);
1107 if (EFI_ERROR (Result
)) {
1108 DEBUG ((gUSBErrorLevel
, "Failed to get device configuration\n"));
1109 ReportUsbStatusCode (
1111 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1112 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1116 UsbIoDevice
->BusController
->AddressPool
1119 gBS
->FreePool (FirstController
);
1120 return EFI_DEVICE_ERROR
;
1123 // Set the 1st configuration value
1125 Result
= UsbSetDefaultConfiguration (UsbIoDevice
);
1126 if (EFI_ERROR (Result
)) {
1127 DEBUG ((gUSBErrorLevel
, "Failed to set device configuration\n"));
1128 ReportUsbStatusCode (
1130 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1131 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1135 UsbIoDevice
->BusController
->AddressPool
1138 gBS
->FreePool (FirstController
);
1139 return EFI_DEVICE_ERROR
;
1142 UsbIoDevice
->IsConfigured
= TRUE
;
1145 // Get all string table if applicable
1147 Result
= UsbGetStringtable (UsbIoDevice
);
1148 if (EFI_ERROR (Result
)) {
1149 DEBUG ((gUSBDebugLevel
, "Device doesn't support string table\n"));
1152 StrManufacturer
= NULL
;
1153 UsbIo
->UsbGetStringDescriptor (
1155 UsbIoDevice
->LangID
[0],
1156 (UsbIoDevice
->DeviceDescriptor
).StrManufacturer
,
1161 UsbIo
->UsbGetStringDescriptor (
1163 UsbIoDevice
->LangID
[0],
1164 (UsbIoDevice
->DeviceDescriptor
).StrProduct
,
1168 StrSerialNumber
= NULL
;
1169 UsbIo
->UsbGetStringDescriptor (
1171 UsbIoDevice
->LangID
[0],
1172 (UsbIoDevice
->DeviceDescriptor
).StrSerialNumber
,
1176 if (StrManufacturer
) {
1177 gBS
->FreePool (StrManufacturer
);
1181 gBS
->FreePool (StrProduct
);
1184 if (StrSerialNumber
) {
1185 gBS
->FreePool (StrSerialNumber
);
1189 // Create USB_IO_CONTROLLER_DEVICE for
1190 // each detected interface
1192 FirstController
->CurrentConfigValue
=
1193 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1196 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.NumInterfaces
;
1197 UsbIoDevice
->NumOfControllers
= NumOfInterface
;
1199 Result
= InitUsbIoController (FirstController
);
1200 if (EFI_ERROR (Result
)) {
1201 ReportUsbStatusCode (
1203 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1204 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1206 gBS
->FreePool (FirstController
);
1207 UsbIoDevice
->UsbController
[0] = NULL
;
1208 return EFI_DEVICE_ERROR
;
1211 for (Index
= 1; Index
< NumOfInterface
; Index
++) {
1212 UsbIoController
= CreateUsbIoControllerDevice ();
1213 UsbIoController
->UsbDevice
= UsbIoDevice
;
1214 UsbIoController
->CurrentConfigValue
=
1215 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1216 UsbIoController
->InterfaceNumber
= Index
;
1217 UsbIoDevice
->UsbController
[Index
] = UsbIoController
;
1218 UsbIoController
->ParentPort
= ParentPort
;
1219 UsbIoController
->Parent
= ParentHubController
;
1220 UsbIoController
->HostController
= HostController
;
1223 // First copy the USB_IO Protocol instance
1226 &UsbIoController
->UsbIo
,
1228 sizeof (EFI_USB_IO_PROTOCOL
)
1231 Result
= InitUsbIoController (UsbIoController
);
1232 if (EFI_ERROR (Result
)) {
1233 ReportUsbStatusCode (
1235 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1236 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1238 gBS
->FreePool (UsbIoController
);
1239 UsbIoDevice
->UsbController
[Index
] = NULL
;
1246 // USB Device DeConfiguration
1249 UsbDeviceDeConfiguration (
1250 IN USB_IO_DEVICE
*UsbIoDevice
1254 Routine Description:
1255 Remove Device, Device Handles, Uninstall Protocols.
1258 UsbIoDevice - The device to be deconfigured.
1266 USB_IO_CONTROLLER_DEVICE
*UsbController
;
1268 USB_IO_DEVICE
*ChildDevice
;
1270 EFI_USB_IO_PROTOCOL
*UsbIo
;
1274 // Double check UsbIoDevice exists
1276 if (UsbIoDevice
== NULL
) {
1280 UsbUnsetTransactionTranslator (UsbIoDevice
);
1282 for (index
= 0; index
< UsbIoDevice
->NumOfControllers
; index
++) {
1284 // Check if it is a hub, if so, de configuration all its
1287 UsbController
= UsbIoDevice
->UsbController
[index
];
1290 // Check the controller pointer
1292 if (UsbController
== NULL
) {
1296 if (UsbController
->IsUsbHub
) {
1298 DEBUG ((gUSBDebugLevel
, "Hub Deconfig, First Deconfig its downstream ports\n"));
1301 // First Remove interrupt transfer request for the status
1304 UsbIo
= &UsbController
->UsbIo
;
1305 UsbIo
->UsbAsyncInterruptTransfer (
1307 UsbController
->HubEndpointAddress
,
1315 if (NULL
!= UsbController
->HubNotify
) {
1316 gBS
->CloseEvent (UsbController
->HubNotify
);
1319 for (Index
= 0; Index
< UsbController
->DownstreamPorts
; Index
++) {
1320 if (UsbController
->Children
[Index
]) {
1321 ChildDevice
= UsbController
->Children
[Index
];
1322 UsbDeviceDeConfiguration (ChildDevice
);
1323 UsbController
->Children
[Index
] = NULL
;
1328 // If the controller is managed by a device driver, we need to
1331 if (UsbController
->IsManagedByDriver
) {
1332 gBS
->DisconnectController (
1333 UsbController
->Handle
,
1340 // remove child handle reference to the USB_HC_PROTOCOL
1342 if (UsbIoDevice
->BusController
->Hc2ProtocolSupported
) {
1343 gBS
->CloseProtocol (
1344 UsbController
->HostController
,
1345 &gEfiUsb2HcProtocolGuid
,
1346 gUsbBusDriverBinding
.DriverBindingHandle
,
1347 UsbController
->Handle
1350 gBS
->CloseProtocol (
1351 UsbController
->HostController
,
1352 &gEfiUsbHcProtocolGuid
,
1353 gUsbBusDriverBinding
.DriverBindingHandle
,
1354 UsbController
->Handle
1358 // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
1359 // installed on this handle
1361 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1362 UsbController
->Handle
,
1363 &gEfiDevicePathProtocolGuid
,
1364 UsbController
->DevicePath
,
1365 &gEfiUsbIoProtocolGuid
,
1366 &UsbController
->UsbIo
,
1369 if (EFI_ERROR (Status
)) {
1373 if (UsbController
->DevicePath
!= NULL
) {
1374 gBS
->FreePool (UsbController
->DevicePath
);
1377 gBS
->FreePool (UsbController
);
1378 UsbIoDevice
->UsbController
[index
] = NULL
;
1381 // Free address for later use
1384 UsbIoDevice
->DeviceAddress
,
1385 UsbIoDevice
->BusController
->AddressPool
1389 // Free all resouces allocated for all its configurations
1391 UsbDestroyAllConfiguration (UsbIoDevice
);
1394 gBS
->FreePool (UsbIoDevice
);
1401 // After interrupt complete, this function will be called,
1402 // This function need to be well-defined later
1407 OnHubInterruptComplete (
1409 IN UINTN DataLength
,
1415 Routine Description:
1416 Whenever hub interrupt occurs, this routine will be called to check
1417 which event happens.
1420 Data - Hub interrupt transfer data.
1421 DataLength - The length of the Data.
1422 Context - Hub Controller Device.
1423 Result - Hub interrupt transfer status.
1431 USB_IO_CONTROLLER_DEVICE
*HubController
;
1434 EFI_USB_IO_PROTOCOL
*UsbIo
;
1436 BOOLEAN Disconnected
;
1439 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1440 UsbIo
= &HubController
->UsbIo
;
1443 // If something error in this interrupt transfer,
1445 if (Result
!= EFI_USB_NOERROR
) {
1446 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1447 UsbClearEndpointHalt (
1449 HubController
->HubEndpointAddress
,
1455 // Delete & Submit this interrupt again
1457 UsbIo
->UsbAsyncInterruptTransfer (
1459 HubController
->HubEndpointAddress
,
1468 // try to detect if the hub itself was disconnected or not
1470 Status
= IsDeviceDisconnected (
1475 if (!EFI_ERROR (Status
) && Disconnected
== TRUE
) {
1476 DEBUG ((gUSBErrorLevel
, "Hub is disconnected\n"));
1477 return EFI_DEVICE_ERROR
;
1482 UsbIo
->UsbAsyncInterruptTransfer (
1484 HubController
->HubEndpointAddress
,
1488 OnHubInterruptComplete
,
1492 return EFI_DEVICE_ERROR
;
1495 if (DataLength
== 0 || Data
== NULL
) {
1500 // Scan which port has status change
1501 // Bit 0 stands for hub itself, other bit stands for
1502 // the corresponding port
1504 for (Index
= 0; Index
< DataLength
* 8; Index
++) {
1505 ptr
= (UINT8
*) Data
+ Index
/ 8;
1506 if ((*ptr
) & (1 << (Index
& 0x7))) {
1507 HubController
->StatusChangePort
= Index
;
1512 // Signal hub notify event
1514 gBS
->SignalEvent (HubController
->HubNotify
);
1519 // USB Root Hub Enumerator
1524 RootHubEnumeration (
1530 Routine Description:
1532 This is USB RootHub enumerator
1536 Event - Indicating which event is signaled
1537 Context - actually it is a USB_IO_DEVICE
1545 USB_IO_CONTROLLER_DEVICE
*HubController
;
1546 EFI_USB_PORT_STATUS HubPortStatus
;
1549 USB_IO_DEVICE
*UsbIoDev
;
1550 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1551 EFI_HANDLE HostController
;
1552 USB_IO_DEVICE
*OldUsbIoDevice
;
1553 USB_IO_DEVICE
*NewDevice
;
1554 USB_IO_CONTROLLER_DEVICE
*NewController
;
1556 EFI_USB_IO_PROTOCOL
*UsbIo
;
1558 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1559 HostController
= HubController
->HostController
;
1560 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1563 // Root hub has the address 1
1565 UsbIoDev
= HubController
->UsbDevice
;
1567 for (Index
= 0; Index
< HubController
->DownstreamPorts
; Index
++) {
1569 UsbVirtualHcGetRootHubPortStatus (
1572 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1575 if (!IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1579 // Clear root hub status change status
1581 UsbVirtualHcClearRootHubPortFeature (
1584 EfiUsbPortConnectChange
1587 gBS
->Stall (100 * 1000);
1589 UsbVirtualHcGetRootHubPortStatus (
1592 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1595 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1598 // There is something connected to this port
1600 DEBUG ((gUSBDebugLevel
, "Something connected to Root Hub at Port0x%x\n", Index
));
1602 ReportUsbStatusCode (
1605 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1608 // if there is something physically detached, but still logically
1611 OldUsbIoDevice
= HubController
->Children
[Index
];
1613 if (NULL
!= OldUsbIoDevice
) {
1614 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1615 HubController
->Children
[Index
] = NULL
;
1618 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1619 if (NewDevice
== NULL
) {
1623 // Initialize some fields by copying data from
1626 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1627 NewDevice
->BusController
= UsbIoDev
->BusController
;
1630 // Process of identify device speed
1632 Status
= IdentifyDeviceSpeed (
1637 if (EFI_ERROR (Status
)) {
1638 gBS
->FreePool (NewDevice
);
1643 // Configure that device
1645 Status
= UsbDeviceConfiguration (
1651 if (EFI_ERROR (Status
)) {
1652 gBS
->FreePool (NewDevice
);
1656 // Add this device to the usb bus tree
1658 HubController
->Children
[Index
] = NewDevice
;
1660 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
1662 // If this device is hub, add to the hub index
1664 NewController
= NewDevice
->UsbController
[Index2
];
1666 Status
= gBS
->ConnectController (
1667 NewController
->Handle
,
1673 // If connect success, we need to disconnect when
1674 // stop the controller, otherwise we need not call
1675 // gBS->DisconnectController ()
1676 // This is used by those usb devices we don't plan
1677 // to support. We can allocate
1678 // controller handles for them, but we don't have
1679 // device drivers to manage them.
1681 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
1683 if (IsHub (NewController
)) {
1685 NewController
->IsUsbHub
= TRUE
;
1688 // Configure Hub Controller
1690 Status
= DoHubConfig (NewController
);
1691 if (EFI_ERROR (Status
)) {
1695 // Create an event to do hub enumeration
1698 EFI_EVENT_NOTIFY_SIGNAL
,
1702 &NewController
->HubNotify
1706 // Add request to do query hub status
1710 UsbIo
= &NewController
->UsbIo
;
1711 UsbIo
->UsbAsyncInterruptTransfer (
1713 NewController
->HubEndpointAddress
,
1717 OnHubInterruptComplete
,
1725 // Something disconnected from USB root hub
1727 DEBUG ((gUSBDebugLevel
, "Something disconnected from Root Hub at Port0x%x\n", Index
));
1729 OldUsbIoDevice
= HubController
->Children
[Index
];
1731 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1733 HubController
->Children
[Index
] = NULL
;
1735 UsbVirtualHcClearRootHubPortFeature (
1738 EfiUsbPortEnableChange
1746 // USB Root Hub Enumerator
1757 Routine Description:
1759 This is Usb Hub enumerator
1763 Event - Indicating which event is signaled
1764 Context - actually it is a USB_IO_DEVICE
1772 USB_IO_CONTROLLER_DEVICE
*HubController
;
1773 EFI_USB_PORT_STATUS HubPortStatus
;
1775 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1776 EFI_HANDLE HostController
;
1777 USB_IO_DEVICE
*OldUsbIoDevice
;
1778 USB_IO_DEVICE
*NewDevice
;
1779 USB_IO_CONTROLLER_DEVICE
*NewController
;
1781 EFI_USB_IO_PROTOCOL
*UsbIo
;
1782 UINT8 StatusChangePort
;
1785 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1786 HostController
= HubController
->HostController
;
1787 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1790 // Event from Hub, Get the hub controller handle
1793 // Get the status change endpoint
1795 StatusChangePort
= HubController
->StatusChangePort
;
1798 // Clear HubController Status Change Bit
1800 HubController
->StatusChangePort
= 0;
1802 if (StatusChangePort
== 0) {
1804 // Hub changes, we don't handle here
1809 // Check which event took place at that port
1811 UsbIo
= &HubController
->UsbIo
;
1812 Status
= HubGetPortStatus (
1815 (UINT32
*) &HubPortStatus
1818 if (EFI_ERROR (Status
)) {
1822 // Clear some change status
1824 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
1826 // Clear Hub port enable change
1828 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
1829 HubClearPortFeature (
1832 EfiUsbPortEnableChange
1838 (UINT32
*) &HubPortStatus
1842 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
1844 // Clear Hub reset change
1846 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
1847 HubClearPortFeature (
1850 EfiUsbPortResetChange
1856 (UINT32
*) &HubPortStatus
1860 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_OVERCURRENT
) {
1862 // Clear Hub overcurrent change
1864 DEBUG ((gUSBDebugLevel
, "Port Overcurrent Change\n"));
1865 HubClearPortFeature (
1868 EfiUsbPortOverCurrentChange
1874 (UINT32
*) &HubPortStatus
1878 if (IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1880 // First clear port connection change
1882 DEBUG ((gUSBDebugLevel
, "Port Connection Change\n"));
1883 HubClearPortFeature (
1886 EfiUsbPortConnectChange
1892 (UINT32
*) &HubPortStatus
1895 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1897 DEBUG ((gUSBDebugLevel
, "New Device Connect on Hub port \n"));
1899 ReportUsbStatusCode (
1902 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1906 // if there is something physically detached, but still logically
1909 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
1911 if (NULL
!= OldUsbIoDevice
) {
1912 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1913 HubController
->Children
[StatusChangePort
- 1] = NULL
;
1916 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1917 if (NewDevice
== NULL
) {
1921 // Initialize some fields
1923 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1924 NewDevice
->BusController
= HubController
->UsbDevice
->BusController
;
1927 // There is something connected to this port,
1930 // Disable the enable bit in port status
1932 HubClearPortFeature (
1938 gBS
->Stall (50 * 1000);
1941 // Wait for bit change
1948 (UINT32
*) &HubPortStatus
1950 gBS
->Stall (10 * 1000);
1952 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_ENABLE
) == 1 && Number
> 0);
1956 // Cannot disable port, return error
1958 DEBUG ((gUSBErrorLevel
, "Disable Port Failed\n"));
1959 gBS
->FreePool (NewDevice
);
1969 gBS
->Stall (50 * 1000);
1972 // Wait for port reset complete
1979 (UINT32
*) &HubPortStatus
1981 gBS
->Stall (10 * 1000);
1983 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_RESET
) == 1 && Number
> 0);
1987 // Cannot reset port, return error
1989 DEBUG ((gUSBErrorLevel
, "Reset Port Failed\n"));
1990 gBS
->FreePool (NewDevice
);
1994 // Check high speed or full speed device
1996 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
1997 DEBUG ((gUSBDebugLevel
, "Low Speed Device Attached to Hub\n"));
1998 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
1999 } else if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2000 DEBUG ((gUSBDebugLevel
, "High Speed Device Attached to Hub\n"));
2001 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2003 DEBUG ((gUSBDebugLevel
, "Full Speed Device Attached to Hub\n"));
2004 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2007 // Configure that device
2009 Status
= UsbDeviceConfiguration (
2012 (UINT8
) (StatusChangePort
- 1),
2016 if (EFI_ERROR (Status
)) {
2017 gBS
->FreePool (NewDevice
);
2021 // Add this device to the usb bus tree
2022 // StatusChangePort is begin from 1,
2024 HubController
->Children
[StatusChangePort
- 1] = NewDevice
;
2026 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
2028 // If this device is hub, add to the hub index
2030 NewController
= NewDevice
->UsbController
[Index2
];
2033 // Connect the controller to the driver image
2035 Status
= gBS
->ConnectController (
2036 NewController
->Handle
,
2042 // If connect success, we need to disconnect when
2043 // stop the controller, otherwise we need not call
2044 // gBS->DisconnectController ()
2045 // This is used by those usb devices we don't plan
2046 // to support. We can allocate
2047 // controller handles for them, but we don't have
2048 // device drivers to manage them.
2050 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
2053 // If this device is hub, add to the hub index
2055 if (IsHub (NewController
)) {
2057 NewController
->IsUsbHub
= TRUE
;
2062 Status
= DoHubConfig (NewController
);
2064 if (EFI_ERROR (Status
)) {
2068 // Create an event to do hub enumeration
2071 EFI_EVENT_NOTIFY_SIGNAL
,
2075 &NewController
->HubNotify
2079 // Add request to do query hub status
2082 UsbIo
= &NewController
->UsbIo
;
2083 UsbIo
->UsbAsyncInterruptTransfer (
2085 NewController
->HubEndpointAddress
, // Hub endpoint address
2089 OnHubInterruptComplete
,
2096 // Something disconnected from USB hub
2098 DEBUG ((gUSBDebugLevel
, "Something Device Detached on Hub port\n"));
2100 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
2102 UsbDeviceDeConfiguration (OldUsbIoDevice
);
2104 HubController
->Children
[StatusChangePort
- 1] = NULL
;
2115 USB_IO_CONTROLLER_DEVICE
*
2116 CreateUsbIoControllerDevice (
2121 Routine Description:
2122 Allocate a structure for USB_IO_CONTROLLER_DEVICE
2128 A pointer to a USB_IO_CONTROLLER_DEVICE structure,
2133 USB_IO_CONTROLLER_DEVICE
*UsbIoControllerDev
;
2136 // Allocate USB_IO_CONTROLLER_DEVICE structure
2138 UsbIoControllerDev
= NULL
;
2139 UsbIoControllerDev
= AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE
));
2141 if (UsbIoControllerDev
== NULL
) {
2145 UsbIoControllerDev
->Signature
= USB_IO_CONTROLLER_SIGNATURE
;
2147 return UsbIoControllerDev
;
2152 InitUsbIoController (
2153 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
2157 Routine Description:
2158 Init and install EFI_USB_IO_PROTOCOL onto that controller.
2161 UsbIoController - The Controller to be operated.
2169 USB_DEVICE_PATH UsbNode
;
2171 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
2172 EFI_USB_HC_PROTOCOL
*UsbHcProtocol
;
2173 EFI_USB2_HC_PROTOCOL
*Usb2HcProtocol
;
2176 // Build the child device path for each new USB_IO device
2178 ZeroMem (&UsbNode
, sizeof (UsbNode
));
2179 UsbNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
2180 UsbNode
.Header
.SubType
= MSG_USB_DP
;
2181 SetDevicePathNodeLength (&UsbNode
.Header
, sizeof (UsbNode
));
2182 UsbNode
.InterfaceNumber
= UsbIoController
->InterfaceNumber
;
2183 UsbNode
.ParentPortNumber
= UsbIoController
->ParentPort
;
2184 ParentDevicePath
= UsbIoController
->Parent
->DevicePath
;
2186 UsbIoController
->DevicePath
=
2187 AppendDevicePathNode (ParentDevicePath
, &UsbNode
.Header
);
2188 if (UsbIoController
->DevicePath
== NULL
) {
2189 return EFI_OUT_OF_RESOURCES
;
2192 Status
= gBS
->InstallMultipleProtocolInterfaces (
2193 &UsbIoController
->Handle
,
2194 &gEfiDevicePathProtocolGuid
,
2195 UsbIoController
->DevicePath
,
2196 &gEfiUsbIoProtocolGuid
,
2197 &UsbIoController
->UsbIo
,
2201 if (EFI_ERROR (Status
)) {
2205 if (UsbIoController
->UsbDevice
->BusController
->Hc2ProtocolSupported
) {
2206 Status
= gBS
->OpenProtocol (
2207 UsbIoController
->HostController
,
2208 &gEfiUsb2HcProtocolGuid
,
2209 (VOID
**)&Usb2HcProtocol
,
2210 gUsbBusDriverBinding
.DriverBindingHandle
,
2211 UsbIoController
->Handle
,
2212 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2215 Status
= gBS
->OpenProtocol (
2216 UsbIoController
->HostController
,
2217 &gEfiUsbHcProtocolGuid
,
2218 (VOID
**)&UsbHcProtocol
,
2219 gUsbBusDriverBinding
.DriverBindingHandle
,
2220 UsbIoController
->Handle
,
2221 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2231 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2232 IN BOOLEAN ReConfigure
,
2237 Routine Description:
2238 Reset parent hub port to which this device is connected.
2241 UsbIoController - Indicating the Usb Controller Device.
2242 ReConfigure - Do we need to reconfigure it.
2243 RetryTimes - Retry Times when failed
2251 USB_IO_DEVICE
*ParentIoDev
;
2252 USB_IO_DEVICE
*UsbIoDev
;
2253 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2257 EFI_USB_IO_PROTOCOL
*UsbIo
;
2260 ParentController
= UsbIoController
->Parent
;
2261 ParentIoDev
= ParentController
->UsbDevice
;
2262 UsbIoDev
= UsbIoController
->UsbDevice
;
2263 HubPort
= UsbIoController
->ParentPort
;
2265 gBS
->Stall (100 * 1000);
2267 if (ParentIoDev
->DeviceAddress
== 1) {
2268 DEBUG ((gUSBDebugLevel
, "Reset from Root Hub 0x%x\n", HubPort
));
2269 ResetRootPort (ParentIoDev
->BusController
, HubPort
, RetryTimes
);
2271 DEBUG ((gUSBDebugLevel
, "Reset from Hub, Addr 0x%x\n", ParentIoDev
->DeviceAddress
));
2272 ResetHubPort (ParentController
, (UINT8
) (HubPort
+ 1));
2275 // If we only need port reset, just return
2281 // Re-config that USB device
2283 UsbIo
= &UsbIoController
->UsbIo
;
2286 // Assign a unique address to this device
2288 Address
= UsbIoDev
->DeviceAddress
;
2289 UsbIoDev
->DeviceAddress
= 0;
2291 Result
= UsbSetDeviceAddress (UsbIo
, Address
, &Status
);
2292 UsbIoDev
->DeviceAddress
= Address
;
2294 if (EFI_ERROR (Result
)) {
2295 return EFI_DEVICE_ERROR
;
2298 // Set the device to the default configuration
2300 Result
= UsbSetDefaultConfiguration (UsbIoDev
);
2301 if (EFI_ERROR (Result
)) {
2302 return EFI_DEVICE_ERROR
;
2311 IN EFI_USB_IO_PROTOCOL
*This
2315 Routine Description:
2316 Resets and reconfigures the USB controller. This function will
2317 work for all USB devices except USB Hub Controllers.
2320 This - Indicates the calling context.
2324 EFI_INVALID_PARAMETER
2329 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
2331 UsbIoController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This
);
2333 if (IsHub (UsbIoController
)) {
2334 return EFI_INVALID_PARAMETER
;
2338 // Since at this time, this device has already been configured,
2339 // it needs to be re-configured.
2341 return ParentPortReset (UsbIoController
, TRUE
, 0);
2346 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2352 Routine Description:
2353 Reset Root Hub port.
2356 UsbBusDev - Bus controller of the device.
2357 PortNum - The given port to be reset.
2358 RetryTimes - RetryTimes when failed
2367 EFI_USB_PORT_STATUS PortStatus
;
2372 Status
= UsbVirtualHcSetRootHubPortFeature (
2377 if (EFI_ERROR (Status
)) {
2378 return EFI_DEVICE_ERROR
;
2381 gBS
->Stall (50 * 1000);
2384 // clear reset root port
2386 Status
= UsbVirtualHcClearRootHubPortFeature (
2391 if (EFI_ERROR (Status
)) {
2392 return EFI_DEVICE_ERROR
;
2397 Status
= UsbVirtualHcClearRootHubPortFeature (
2400 EfiUsbPortConnectChange
2402 if (EFI_ERROR (Status
)) {
2403 return EFI_DEVICE_ERROR
;
2406 UsbVirtualHcGetRootHubPortStatus (
2411 if (PortStatus
.PortStatus
& USB_PORT_STAT_OWNER
) {
2415 Status
= UsbVirtualHcSetRootHubPortFeature (
2420 if (EFI_ERROR (Status
)) {
2421 return EFI_DEVICE_ERROR
;
2424 Status
= UsbVirtualHcClearRootHubPortFeature (
2427 EfiUsbPortEnableChange
2431 gBS
->Stall ((1 + RetryTimes
) * 50 * 1000);
2438 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2443 Routine Description:
2447 UsbIoController - The USB_IO_CONTROLLER_DEVICE instance.
2448 PortIndex - The given port to be reset.
2456 EFI_USB_IO_PROTOCOL
*UsbIo
;
2457 EFI_USB_PORT_STATUS HubPortStatus
;
2460 ASSERT (UsbIoController
->IsUsbHub
== TRUE
);
2462 UsbIo
= &UsbIoController
->UsbIo
;
2470 gBS
->Stall (10 * 1000);
2473 // Wait for port reset complete
2480 (UINT32
*) &HubPortStatus
2482 gBS
->Stall (10 * 100);
2484 } while ((HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) == 0 && Number
> 0);
2488 // Cannot reset port, return error
2490 return EFI_DEVICE_ERROR
;
2498 (UINT32
*) &HubPortStatus
2501 // reset port will cause some bits change, clear them
2503 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
2504 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
2505 HubClearPortFeature (
2508 EfiUsbPortEnableChange
2512 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
2513 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
2514 HubClearPortFeature (
2517 EfiUsbPortResetChange
2526 ReportUsbStatusCode (
2527 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
2528 IN EFI_STATUS_CODE_TYPE Type
,
2529 IN EFI_STATUS_CODE_VALUE Code
2533 Routine Description:
2535 report a error Status code of USB bus driver controller
2538 UsbBusController - USB_BUS_CONTROLLER_DEVICE
2539 Type - EFI_STATUS_CODE_TYPE
2540 Code - EFI_STATUS_CODE_VALUE
2547 return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
2550 UsbBusController
->DevicePath
2555 IsDeviceDisconnected (
2556 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2557 IN OUT BOOLEAN
*Disconnected
2561 Routine Description:
2562 Reset if the device is disconencted or not
2565 UsbIoController - Indicating the Usb Controller Device.
2566 Disconnected - Indicate whether the device is disconencted or not
2574 USB_IO_DEVICE
*ParentIoDev
;
2575 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2578 EFI_USB_PORT_STATUS PortStatus
;
2580 ParentController
= UsbIoController
->Parent
;
2581 ParentIoDev
= ParentController
->UsbDevice
;
2582 HubPort
= UsbIoController
->ParentPort
;
2584 if (ParentIoDev
->DeviceAddress
== 1) {
2586 // Connected to the root hub
2588 UsbVirtualHcGetRootHubPortStatus (
2589 ParentIoDev
->BusController
,
2595 Status
= HubGetPortStatus (
2596 &ParentController
->UsbIo
,
2597 (UINT8
) (HubPort
+ 1),
2598 (UINT32
*) &PortStatus
2601 if (EFI_ERROR (Status
)) {
2602 return IsDeviceDisconnected (ParentController
, Disconnected
);
2606 *Disconnected
= FALSE
;
2608 if (!IsPortConnect (PortStatus
.PortStatus
)) {
2609 *Disconnected
= TRUE
;
2617 UsbSetTransactionTranslator (
2618 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
2619 IN UINT8 ParentPort
,
2620 IN OUT USB_IO_DEVICE
*Device
2624 Routine Description:
2626 Set Transaction Translator parameter
2630 ParentHubController - Controller structure of the parent Hub device
2631 ParentPort - Number of parent port
2632 Device - Structure of the device
2637 EFI_OUT_OF_RESOURCES Cannot allocate resources
2641 USB_IO_CONTROLLER_DEVICE
*AncestorHubController
;
2643 AncestorHubController
= ParentHubController
;
2644 Device
->Translator
= NULL
;
2646 if (EFI_USB_SPEED_HIGH
== Device
->DeviceSpeed
) {
2651 if (EFI_USB_SPEED_HIGH
== AncestorHubController
->UsbDevice
->DeviceSpeed
) {
2655 if (NULL
== AncestorHubController
->Parent
) {
2659 AncestorHubController
= AncestorHubController
->Parent
;
2662 Device
->Translator
= AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR
));
2663 if (NULL
== Device
->Translator
) {
2664 return EFI_OUT_OF_RESOURCES
;
2667 Device
->Translator
->TranslatorHubAddress
= AncestorHubController
->UsbDevice
->DeviceAddress
;
2668 Device
->Translator
->TranslatorPortNumber
= ParentPort
;
2675 UsbUnsetTransactionTranslator (
2676 USB_IO_DEVICE
*Device
2680 Routine Description:
2682 Unset Transaction Translator parameter
2686 Device - Structure of the device
2694 if (Device
->Translator
) {
2695 gBS
->FreePool (Device
->Translator
);
2696 Device
->Translator
= NULL
;
2704 IdentifyDeviceSpeed (
2705 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2706 USB_IO_DEVICE
*NewDevice
,
2711 Routine Description:
2713 Identify speed of USB device
2717 UsbBusDev - UsbBus controller structure of the device
2718 NewDevice - Devcie controller structure
2719 Index - Number of the port
2724 EFI_NOT_FOUND Device release to CHC or can't be found
2729 EFI_USB_PORT_STATUS HubPortStatus
;
2731 UsbVirtualHcGetRootHubPortStatus (
2734 (EFI_USB_PORT_STATUS
*) &HubPortStatus
2738 // Check device device
2740 if (!(HubPortStatus
.PortStatus
& USB_PORT_STAT_OWNER
)) {
2744 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2745 DEBUG ((gUSBDebugLevel
, "High Speed Device attached to EHC\n"));
2746 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2748 Status
= ReleasePortToCHC (UsbBusDev
, Index
);
2749 if (EFI_ERROR (Status
)) {
2750 DEBUG ((gUSBErrorLevel
, "Fail to release port to CHC\n"));
2752 DEBUG ((gUSBDebugLevel
, "Success to release port to CHC\n"));
2754 return EFI_DEVICE_ERROR
;
2760 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
2761 DEBUG ((gUSBDebugLevel
, "Low Speed Device attached to CHC\n"));
2762 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
2764 DEBUG ((gUSBDebugLevel
, "FULL Speed Device attached to CHC\n"));
2765 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2775 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2780 Routine Description:
2782 Set bit to release the port owner to CHC
2786 UsbBusDev - UsbBus controller structure of the device
2787 PortNum - Number of the port
2792 EFI_DEVICE_ERROR Fail
2798 Status
= UsbVirtualHcSetRootHubPortFeature (
2804 gBS
->Stall (100 * 1000);
2811 UsbVirtualHcGetCapability (
2812 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2813 OUT UINT8
*MaxSpeed
,
2814 OUT UINT8
*PortNumber
,
2815 OUT UINT8
*Is64BitCapable
2819 Routine Description:
2821 Virtual interface to Retrieves the capablility of root hub ports
2822 for both Hc2 and Hc protocol.
2826 UsbBusDev - A pointer to bus controller of the device.
2827 MaxSpeed - A pointer to the number of the host controller.
2828 PortNumber - A pointer to the number of the root hub ports.
2829 Is64BitCapable - A pointer to the flag for whether controller supports
2830 64-bit memory addressing.
2835 The host controller capability were retrieved successfully.
2836 EFI_INVALID_PARAMETER
2837 MaxSpeed or PortNumber or Is64BitCapable is NULL.
2839 An error was encountered while attempting to retrieve the capabilities.
2845 Status
= EFI_SUCCESS
;
2847 if (UsbBusDev
->Hc2ProtocolSupported
) {
2848 Status
= UsbBusDev
->Usb2HCInterface
->GetCapability (
2849 UsbBusDev
->Usb2HCInterface
,
2855 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortNumber (
2856 UsbBusDev
->UsbHCInterface
,
2859 *MaxSpeed
= EFI_USB_SPEED_FULL
;
2860 *Is64BitCapable
= (UINT8
) FALSE
;
2869 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2870 IN UINT16 Attributes
2874 Routine Description:
2876 Virtual interface to provides software reset for the USB host controller
2877 for both Hc2 and Hc protocol.
2881 UsbBusDev - A pointer to bus controller of the device.
2882 Attributes - A bit mask of the reset operation to perform.
2883 See below for a list of the supported bit mask values.
2885 #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc
2886 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
2887 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
2888 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
2890 EFI_USB_HC_RESET_GLOBAL
2891 If this bit is set, a global reset signal will be sent to the USB bus.
2892 This resets all of the USB bus logic, including the USB host
2893 controller hardware and all the devices attached on the USB bus.
2894 EFI_USB_HC_RESET_HOST_CONTROLLER
2895 If this bit is set, the USB host controller hardware will be reset.
2896 No reset signal will be sent to the USB bus.
2897 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
2898 If this bit is set, a global reset signal will be sent to the USB bus.
2899 This resets all of the USB bus logic, including the USB host
2900 controller hardware and all the devices attached on the USB bus.
2901 If this is an EHCI controller and the debug port has configured, then
2902 this is will still reset the host controller.
2903 EFI_USB_HC_RESET_HOST_WITH_DEBUG
2904 If this bit is set, the USB host controller hardware will be reset.
2905 If this is an EHCI controller and the debug port has been configured,
2906 then this will still reset the host controller.
2911 The reset operation succeeded.
2912 EFI_INVALID_PARAMETER
2913 Attributes is not valid.
2915 The type of reset specified by Attributes is not currently supported by
2916 the host controller hardware.
2918 Reset operation is rejected due to the debug port being configured and
2919 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
2920 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
2921 perform reset operation for this host controller.
2923 An error was encountered while attempting to perform
2924 the reset operation.
2930 Status
= EFI_SUCCESS
;
2932 if (UsbBusDev
->Hc2ProtocolSupported
) {
2933 Status
= UsbBusDev
->Usb2HCInterface
->Reset (
2934 UsbBusDev
->Usb2HCInterface
,
2935 EFI_USB_HC_RESET_GLOBAL
2938 Status
= UsbBusDev
->UsbHCInterface
->Reset (
2939 UsbBusDev
->UsbHCInterface
,
2940 EFI_USB_HC_RESET_GLOBAL
2949 UsbVirtualHcGetState (
2950 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2951 OUT EFI_USB_HC_STATE
*State
2955 Routine Description:
2957 Virtual interface to retrieves current state of the USB host controller
2958 for both Hc2 and Hc protocol.
2962 UsbBusDev - A pointer to bus controller of the device.
2963 State - A pointer to the EFI_USB_HC_STATE data structure that
2964 indicates current state of the USB host controller.
2965 Type EFI_USB_HC_STATE is defined below.
2969 EfiUsbHcStateOperational,
2970 EfiUsbHcStateSuspend,
2971 EfiUsbHcStateMaximum
2977 The state information of the host controller was returned in State.
2978 EFI_INVALID_PARAMETER
2981 An error was encountered while attempting to retrieve the
2982 host controller's current state.
2988 Status
= EFI_SUCCESS
;
2990 if (UsbBusDev
->Hc2ProtocolSupported
) {
2991 Status
= UsbBusDev
->Usb2HCInterface
->GetState (
2992 UsbBusDev
->Usb2HCInterface
,
2996 Status
= UsbBusDev
->UsbHCInterface
->GetState (
2997 UsbBusDev
->UsbHCInterface
,
3007 UsbVirtualHcSetState (
3008 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3009 IN EFI_USB_HC_STATE State
3013 Routine Description:
3015 Virtual interface to sets the USB host controller to a specific state
3016 for both Hc2 and Hc protocol.
3020 UsbBusDev - A pointer to bus controller of the device.
3021 State - Indicates the state of the host controller that will be set.
3026 The USB host controller was successfully placed in the state
3028 EFI_INVALID_PARAMETER
3031 Failed to set the state specified by State due to device error.
3037 Status
= EFI_SUCCESS
;
3039 if (UsbBusDev
->Hc2ProtocolSupported
) {
3040 Status
= UsbBusDev
->Usb2HCInterface
->SetState (
3041 UsbBusDev
->Usb2HCInterface
,
3045 Status
= UsbBusDev
->UsbHCInterface
->SetState (
3046 UsbBusDev
->UsbHCInterface
,
3056 UsbVirtualHcGetRootHubPortStatus (
3057 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3058 IN UINT8 PortNumber
,
3059 OUT EFI_USB_PORT_STATUS
*PortStatus
3063 Routine Description:
3065 Virtual interface to retrieves the current status of a USB root hub port
3066 both for Hc2 and Hc protocol.
3070 UsbBusDev - A pointer to bus controller of the device.
3071 PortNumber - Specifies the root hub port from which the status
3072 is to be retrieved. This value is zero-based. For example,
3073 if a root hub has two ports, then the first port is numbered 0,
3074 and the second port is numbered 1.
3075 PortStatus - A pointer to the current port status bits and
3076 port status change bits.
3080 EFI_SUCCESS The status of the USB root hub port specified by PortNumber
3081 was returned in PortStatus.
3082 EFI_INVALID_PARAMETER PortNumber is invalid.
3083 EFI_DEVICE_ERROR Can't read register
3089 Status
= EFI_SUCCESS
;
3091 if (UsbBusDev
->Hc2ProtocolSupported
) {
3092 Status
= UsbBusDev
->Usb2HCInterface
->GetRootHubPortStatus (
3093 UsbBusDev
->Usb2HCInterface
,
3098 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortStatus (
3099 UsbBusDev
->UsbHCInterface
,
3110 UsbVirtualHcSetRootHubPortFeature (
3111 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3112 IN UINT8 PortNumber
,
3113 IN EFI_USB_PORT_FEATURE PortFeature
3117 Routine Description:
3118 Virual interface to sets a feature for the specified root hub port
3119 for both Hc2 and Hc protocol.
3123 UsbBusDev - A pointer to bus controller of the device.
3124 PortNumber - Specifies the root hub port whose feature
3125 is requested to be set.
3126 PortFeature - Indicates the feature selector associated
3127 with the feature set request.
3132 The feature specified by PortFeature was set for the
3133 USB root hub port specified by PortNumber.
3134 EFI_INVALID_PARAMETER
3135 PortNumber is invalid or PortFeature is invalid.
3143 Status
= EFI_SUCCESS
;
3145 if (UsbBusDev
->Hc2ProtocolSupported
) {
3146 Status
= UsbBusDev
->Usb2HCInterface
->SetRootHubPortFeature (
3147 UsbBusDev
->Usb2HCInterface
,
3152 Status
= UsbBusDev
->UsbHCInterface
->SetRootHubPortFeature (
3153 UsbBusDev
->UsbHCInterface
,
3164 UsbVirtualHcClearRootHubPortFeature (
3165 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3166 IN UINT8 PortNumber
,
3167 IN EFI_USB_PORT_FEATURE PortFeature
3171 Routine Description:
3173 Virtual interface to clears a feature for the specified root hub port
3174 for both Hc2 and Hc protocol.
3178 UsbBusDev - A pointer to bus controller of the device.
3179 PortNumber - Specifies the root hub port whose feature
3180 is requested to be cleared.
3181 PortFeature - Indicates the feature selector associated with the
3182 feature clear request.
3187 The feature specified by PortFeature was cleared for the
3188 USB root hub port specified by PortNumber.
3189 EFI_INVALID_PARAMETER
3190 PortNumber is invalid or PortFeature is invalid.
3198 Status
= EFI_SUCCESS
;
3200 if (UsbBusDev
->Hc2ProtocolSupported
) {
3201 Status
= UsbBusDev
->Usb2HCInterface
->ClearRootHubPortFeature (
3202 UsbBusDev
->Usb2HCInterface
,
3207 Status
= UsbBusDev
->UsbHCInterface
->ClearRootHubPortFeature (
3208 UsbBusDev
->UsbHCInterface
,
3219 UsbVirtualHcControlTransfer (
3220 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3221 IN UINT8 DeviceAddress
,
3222 IN UINT8 DeviceSpeed
,
3223 IN UINTN MaximumPacketLength
,
3224 IN EFI_USB_DEVICE_REQUEST
*Request
,
3225 IN EFI_USB_DATA_DIRECTION TransferDirection
,
3227 IN OUT UINTN
*DataLength
,
3229 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3230 OUT UINT32
*TransferResult
3234 Routine Description:
3236 Virtual interface to submits control transfer to a target USB device
3237 for both Hc2 and Hc protocol.
3241 UsbBusDev - A pointer to bus controller of the device.
3242 DeviceAddress - Represents the address of the target device on the USB,
3243 which is assigned during USB enumeration.
3244 DeviceSpeed - Indicates target device speed.
3245 MaximumPacketLength - Indicates the maximum packet size that the
3246 default control transfer endpoint is capable of
3247 sending or receiving.
3248 Request - A pointer to the USB device request that will be sent
3250 TransferDirection - Specifies the data direction for the transfer.
3251 There are three values available, DataIn, DataOut
3253 Data - A pointer to the buffer of data that will be transmitted
3254 to USB device or received from USB device.
3255 DataLength - Indicates the size, in bytes, of the data buffer
3257 TimeOut - Indicates the maximum time, in microseconds,
3258 which the transfer is allowed to complete.
3259 Translator - A pointr to the transaction translator data.
3260 TransferResult - A pointer to the detailed result information generated
3261 by this control transfer.
3266 The control transfer was completed successfully.
3267 EFI_OUT_OF_RESOURCES
3268 The control transfer could not be completed due to a lack of resources.
3269 EFI_INVALID_PARAMETER
3270 Some parameters are invalid.
3272 The control transfer failed due to timeout.
3274 The control transfer failed due to host controller or device error.
3275 Caller should check TranferResult for detailed error information.
3280 BOOLEAN IsSlowDevice
;
3282 Status
= EFI_SUCCESS
;
3284 if (UsbBusDev
->Hc2ProtocolSupported
) {
3285 Status
= UsbBusDev
->Usb2HCInterface
->ControlTransfer (
3286 UsbBusDev
->Usb2HCInterface
,
3289 MaximumPacketLength
,
3299 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
3300 Status
= UsbBusDev
->UsbHCInterface
->ControlTransfer (
3301 UsbBusDev
->UsbHCInterface
,
3304 (UINT8
) MaximumPacketLength
,
3319 UsbVirtualHcBulkTransfer (
3320 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3321 IN UINT8 DeviceAddress
,
3322 IN UINT8 EndPointAddress
,
3323 IN UINT8 DeviceSpeed
,
3324 IN UINTN MaximumPacketLength
,
3325 IN UINT8 DataBuffersNumber
,
3326 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
3327 IN OUT UINTN
*DataLength
,
3328 IN OUT UINT8
*DataToggle
,
3330 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3331 OUT UINT32
*TransferResult
3335 Routine Description:
3337 Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
3338 both for Hc2 and Hc protocol.
3342 UsbBusDev - A pointer to bus controller of the device.
3343 DeviceAddress - Represents the address of the target device on the USB,
3344 which is assigned during USB enumeration.
3345 EndPointAddress - The combination of an endpoint number and an
3346 endpoint direction of the target USB device.
3347 Each endpoint address supports data transfer in
3348 one direction except the control endpoint
3349 (whose default endpoint address is 0).
3350 It is the caller's responsibility to make sure that
3351 the EndPointAddress represents a bulk endpoint.
3352 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
3353 and EFI_USB_SPEED_HIGH.
3354 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3355 is capable of sending or receiving.
3356 DataBuffersNumber - Number of data buffers prepared for the transfer.
3357 Data - Array of pointers to the buffers of data that will be transmitted
3358 to USB device or received from USB device.
3359 DataLength - When input, indicates the size, in bytes, of the data buffer
3360 specified by Data. When output, indicates the actually
3361 transferred data size.
3362 DataToggle - A pointer to the data toggle value. On input, it indicates
3363 the initial data toggle value the bulk transfer should adopt;
3364 on output, it is updated to indicate the data toggle value
3365 of the subsequent bulk transfer.
3366 Translator - A pointr to the transaction translator data.
3367 TimeOut - Indicates the maximum time, in microseconds, which the
3368 transfer is allowed to complete.
3369 TransferResult - A pointer to the detailed result information of the
3375 The bulk transfer was completed successfully.
3376 EFI_OUT_OF_RESOURCES
3377 The bulk transfer could not be submitted due to lack of resource.
3378 EFI_INVALID_PARAMETER
3379 Some parameters are invalid.
3381 The bulk transfer failed due to timeout.
3383 The bulk transfer failed due to host controller or device error.
3384 Caller should check TranferResult for detailed error information.
3390 Status
= EFI_SUCCESS
;
3392 if (UsbBusDev
->Hc2ProtocolSupported
) {
3393 Status
= UsbBusDev
->Usb2HCInterface
->BulkTransfer (
3394 UsbBusDev
->Usb2HCInterface
,
3398 MaximumPacketLength
,
3408 Status
= UsbBusDev
->UsbHCInterface
->BulkTransfer (
3409 UsbBusDev
->UsbHCInterface
,
3412 (UINT8
) MaximumPacketLength
,
3426 UsbVirtualHcAsyncInterruptTransfer (
3427 IN USB_BUS_CONTROLLER_DEVICE
* UsbBusDev
,
3428 IN UINT8 DeviceAddress
,
3429 IN UINT8 EndPointAddress
,
3430 IN UINT8 DeviceSpeed
,
3431 IN UINTN MaximumPacketLength
,
3432 IN BOOLEAN IsNewTransfer
,
3433 IN OUT UINT8
*DataToggle
,
3434 IN UINTN PollingInterval
,
3435 IN UINTN DataLength
,
3436 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
3437 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
3438 IN VOID
*Context OPTIONAL
3442 Routine Description:
3444 Virtual interface to submits an asynchronous interrupt transfer to an
3445 interrupt endpoint of a USB device for both Hc2 and Hc protocol.
3449 UsbBusDev - A pointer to bus controller of the device.
3450 DeviceAddress - Represents the address of the target device on the USB,
3451 which is assigned during USB enumeration.
3452 EndPointAddress - The combination of an endpoint number and an endpoint
3453 direction of the target USB device. Each endpoint address
3454 supports data transfer in one direction except the
3455 control endpoint (whose default endpoint address is 0).
3456 It is the caller's responsibility to make sure that
3457 the EndPointAddress represents an interrupt endpoint.
3458 DeviceSpeed - Indicates device speed.
3459 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3460 is capable of sending or receiving.
3461 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
3462 the host and the target interrupt endpoint.
3463 If FALSE, the specified asynchronous interrupt pipe
3465 DataToggle - A pointer to the data toggle value. On input, it is valid
3466 when IsNewTransfer is TRUE, and it indicates the initial
3467 data toggle value the asynchronous interrupt transfer
3469 On output, it is valid when IsNewTransfer is FALSE,
3470 and it is updated to indicate the data toggle value of
3471 the subsequent asynchronous interrupt transfer.
3472 PollingInterval - Indicates the interval, in milliseconds, that the
3473 asynchronous interrupt transfer is polled.
3474 This parameter is required when IsNewTransfer is TRUE.
3475 DataLength - Indicates the length of data to be received at the
3476 rate specified by PollingInterval from the target
3477 asynchronous interrupt endpoint. This parameter
3478 is only required when IsNewTransfer is TRUE.
3479 Translator - A pointr to the transaction translator data.
3480 CallBackFunction - The Callback function.This function is called at the
3481 rate specified by PollingInterval.This parameter is
3482 only required when IsNewTransfer is TRUE.
3483 Context - The context that is passed to the CallBackFunction.
3484 - This is an optional parameter and may be NULL.
3489 The asynchronous interrupt transfer request has been successfully
3490 submitted or canceled.
3491 EFI_INVALID_PARAMETER
3492 Some parameters are invalid.
3493 EFI_OUT_OF_RESOURCES
3494 The request could not be completed due to a lack of resources.
3501 BOOLEAN IsSlowDevice
;
3503 Status
= EFI_SUCCESS
;
3505 if (UsbBusDev
->Hc2ProtocolSupported
) {
3506 Status
= UsbBusDev
->Usb2HCInterface
->AsyncInterruptTransfer (
3507 UsbBusDev
->Usb2HCInterface
,
3511 MaximumPacketLength
,
3521 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
3522 Status
= UsbBusDev
->UsbHCInterface
->AsyncInterruptTransfer (
3523 UsbBusDev
->UsbHCInterface
,
3527 (UINT8
) MaximumPacketLength
,
3542 UsbVirtualHcSyncInterruptTransfer (
3543 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3544 IN UINT8 DeviceAddress
,
3545 IN UINT8 EndPointAddress
,
3546 IN UINT8 DeviceSpeed
,
3547 IN UINTN MaximumPacketLength
,
3549 IN OUT UINTN
*DataLength
,
3550 IN OUT UINT8
*DataToggle
,
3552 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3553 OUT UINT32
*TransferResult
3557 Routine Description:
3559 Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
3560 of a USB device for both Hc2 and Hc protocol.
3564 UsbBusDev - A pointer to bus controller of the device.
3565 DeviceAddress - Represents the address of the target device on the USB,
3566 which is assigned during USB enumeration.
3567 EndPointAddress - The combination of an endpoint number and an endpoint
3568 direction of the target USB device. Each endpoint
3569 address supports data transfer in one direction
3570 except the control endpoint (whose default
3571 endpoint address is 0). It is the caller's responsibility
3572 to make sure that the EndPointAddress represents
3573 an interrupt endpoint.
3574 DeviceSpeed - Indicates device speed.
3575 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3576 is capable of sending or receiving.
3577 Data - A pointer to the buffer of data that will be transmitted
3578 to USB device or received from USB device.
3579 DataLength - On input, the size, in bytes, of the data buffer specified
3580 by Data. On output, the number of bytes transferred.
3581 DataToggle - A pointer to the data toggle value. On input, it indicates
3582 the initial data toggle value the synchronous interrupt
3583 transfer should adopt;
3584 on output, it is updated to indicate the data toggle value
3585 of the subsequent synchronous interrupt transfer.
3586 TimeOut - Indicates the maximum time, in microseconds, which the
3587 transfer is allowed to complete.
3588 Translator - A pointr to the transaction translator data.
3589 TransferResult - A pointer to the detailed result information from
3590 the synchronous interrupt transfer.
3595 The synchronous interrupt transfer was completed successfully.
3596 EFI_OUT_OF_RESOURCES
3597 The synchronous interrupt transfer could not be submitted due
3598 to lack of resource.
3599 EFI_INVALID_PARAMETER
3600 Some parameters are invalid.
3602 The synchronous interrupt transfer failed due to timeout.
3604 The synchronous interrupt transfer failed due to host controller
3605 or device error. Caller should check TranferResult for detailed
3611 BOOLEAN IsSlowDevice
;
3613 Status
= EFI_SUCCESS
;
3615 if (UsbBusDev
->Hc2ProtocolSupported
) {
3616 Status
= UsbBusDev
->Usb2HCInterface
->SyncInterruptTransfer (
3617 UsbBusDev
->Usb2HCInterface
,
3621 MaximumPacketLength
,
3630 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
3631 Status
= UsbBusDev
->UsbHCInterface
->SyncInterruptTransfer (
3632 UsbBusDev
->UsbHCInterface
,
3636 (UINT8
) MaximumPacketLength
,
3650 UsbVirtualHcIsochronousTransfer (
3651 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3652 IN UINT8 DeviceAddress
,
3653 IN UINT8 EndPointAddress
,
3654 IN UINT8 DeviceSpeed
,
3655 IN UINTN MaximumPacketLength
,
3656 IN UINT8 DataBuffersNumber
,
3657 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3658 IN UINTN DataLength
,
3659 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3660 OUT UINT32
*TransferResult
3664 Routine Description:
3666 Virtual interface to submits isochronous transfer to a target USB device
3667 for both Hc2 and Hc protocol.
3671 UsbBusDev - A pointer to bus controller of the device.
3672 DeviceAddress - Represents the address of the target device on the USB,
3673 which is assigned during USB enumeration.
3674 EndPointAddress - End point address
3675 DeviceSpeed - Indicates device speed.
3676 MaximumPacketLength - Indicates the maximum packet size that the
3677 default control transfer endpoint is capable of
3678 sending or receiving.
3679 DataBuffersNumber - Number of data buffers prepared for the transfer.
3680 Data - Array of pointers to the buffers of data that will be
3681 transmitted to USB device or received from USB device.
3682 DataLength - Indicates the size, in bytes, of the data buffer
3684 Translator - A pointr to the transaction translator data.
3685 TransferResult - A pointer to the detailed result information generated
3686 by this control transfer.
3694 return EFI_UNSUPPORTED
;
3699 UsbVirtualHcAsyncIsochronousTransfer (
3700 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3701 IN UINT8 DeviceAddress
,
3702 IN UINT8 EndPointAddress
,
3703 IN UINT8 DeviceSpeed
,
3704 IN UINTN MaximumPacketLength
,
3705 IN UINT8 DataBuffersNumber
,
3706 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3707 IN UINTN DataLength
,
3708 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3709 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
3714 Routine Description:
3716 Vitual interface to submits Async isochronous transfer to a target USB device
3717 for both Hc2 and Hc protocol.
3721 UsbBusDev - A pointer to bus controller of the device.
3722 DeviceAddress - Represents the address of the target device on the USB,
3723 which is assigned during USB enumeration.
3724 EndPointAddress - End point address
3725 DeviceSpeed - Indicates device speed.
3726 MaximumPacketLength - Indicates the maximum packet size that the
3727 default control transfer endpoint is capable of
3728 sending or receiving.
3729 DataBuffersNumber - Number of data buffers prepared for the transfer.
3730 Data - Array of pointers to the buffers of data that will be transmitted
3731 to USB device or received from USB device.
3732 DataLength - Indicates the size, in bytes, of the data buffer
3734 Translator - A pointr to the transaction translator data.
3735 IsochronousCallBack - When the transfer complete, the call back function will be called
3736 Context - Pass to the call back function as parameter
3744 return EFI_UNSUPPORTED
;