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 ParentPortReset (FirstController
, FALSE
, 0);
1007 // First retrieve the 1st 8 bytes of
1008 // in order to get the MaxPacketSize for Endpoint 0
1010 for (Index
= 0; Index
< 3; Index
++) {
1012 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1014 gBS
->Stall (100 * 1000);
1016 Result
= UsbGetDescriptor (
1018 (USB_DT_DEVICE
<< 8),
1021 &UsbIoDevice
->DeviceDescriptor
,
1024 if (!EFI_ERROR (Result
)) {
1027 "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
1028 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
)
1036 ReportUsbStatusCode (
1038 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1039 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1041 DEBUG ((gUSBErrorLevel
, "Get Device Descriptor Fail when configing\n"));
1042 gBS
->FreePool (FirstController
);
1043 return EFI_DEVICE_ERROR
;
1046 DevAddress
= UsbAllocateAddress (UsbIoDevice
->BusController
->AddressPool
);
1047 if (DevAddress
== 0) {
1048 DEBUG ((gUSBErrorLevel
, "Cannot allocate address\n"));
1049 gBS
->FreePool (FirstController
);
1050 return EFI_OUT_OF_RESOURCES
;
1053 Result
= UsbSetDeviceAddress (UsbIo
, DevAddress
, &Status
);
1055 if (EFI_ERROR (Result
)) {
1056 DEBUG ((gUSBErrorLevel
, "Set address error\n"));
1057 ReportUsbStatusCode (
1059 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1060 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1065 UsbIoDevice
->BusController
->AddressPool
1068 gBS
->FreePool (FirstController
);
1069 return EFI_DEVICE_ERROR
;
1072 UsbIoDevice
->DeviceAddress
= DevAddress
;
1075 // SetAddress Complete Time by Spec, Max 50ms
1077 gBS
->Stall (10 * 1000);
1080 // Get the whole device descriptor
1082 Result
= UsbGetDescriptor (
1084 (USB_DT_DEVICE
<< 8),
1086 sizeof (EFI_USB_DEVICE_DESCRIPTOR
),
1087 &UsbIoDevice
->DeviceDescriptor
,
1091 if (EFI_ERROR (Result
)) {
1092 DEBUG ((gUSBErrorLevel
, "Get whole Device Descriptor error\n"));
1093 ReportUsbStatusCode (
1095 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1096 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1100 UsbIoDevice
->BusController
->AddressPool
1103 gBS
->FreePool (FirstController
);
1104 return EFI_DEVICE_ERROR
;
1107 // Get & parse all configurations for this device, including
1108 // all configuration descriptors, all interface descriptors, all
1109 // endpoint descriptors
1111 Result
= UsbGetAllConfigurations (UsbIoDevice
);
1113 if (EFI_ERROR (Result
)) {
1114 DEBUG ((gUSBErrorLevel
, "Failed to get device configuration\n"));
1115 ReportUsbStatusCode (
1117 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1118 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1122 UsbIoDevice
->BusController
->AddressPool
1125 gBS
->FreePool (FirstController
);
1126 return EFI_DEVICE_ERROR
;
1129 // Set the 1st configuration value
1131 Result
= UsbSetDefaultConfiguration (UsbIoDevice
);
1132 if (EFI_ERROR (Result
)) {
1133 DEBUG ((gUSBErrorLevel
, "Failed to set device configuration\n"));
1134 ReportUsbStatusCode (
1136 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1137 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1141 UsbIoDevice
->BusController
->AddressPool
1144 gBS
->FreePool (FirstController
);
1145 return EFI_DEVICE_ERROR
;
1148 UsbIoDevice
->IsConfigured
= TRUE
;
1151 // Get all string table if applicable
1153 Result
= UsbGetStringtable (UsbIoDevice
);
1154 if (EFI_ERROR (Result
)) {
1155 DEBUG ((gUSBDebugLevel
, "Device doesn't support string table\n"));
1158 StrManufacturer
= NULL
;
1159 UsbIo
->UsbGetStringDescriptor (
1161 UsbIoDevice
->LangID
[0],
1162 (UsbIoDevice
->DeviceDescriptor
).StrManufacturer
,
1167 UsbIo
->UsbGetStringDescriptor (
1169 UsbIoDevice
->LangID
[0],
1170 (UsbIoDevice
->DeviceDescriptor
).StrProduct
,
1174 StrSerialNumber
= NULL
;
1175 UsbIo
->UsbGetStringDescriptor (
1177 UsbIoDevice
->LangID
[0],
1178 (UsbIoDevice
->DeviceDescriptor
).StrSerialNumber
,
1182 if (StrManufacturer
) {
1183 gBS
->FreePool (StrManufacturer
);
1187 gBS
->FreePool (StrProduct
);
1190 if (StrSerialNumber
) {
1191 gBS
->FreePool (StrSerialNumber
);
1195 // Create USB_IO_CONTROLLER_DEVICE for
1196 // each detected interface
1198 FirstController
->CurrentConfigValue
=
1199 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1202 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.NumInterfaces
;
1203 UsbIoDevice
->NumOfControllers
= NumOfInterface
;
1205 Result
= InitUsbIoController (FirstController
);
1206 if (EFI_ERROR (Result
)) {
1207 ReportUsbStatusCode (
1209 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1210 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1212 gBS
->FreePool (FirstController
);
1213 UsbIoDevice
->UsbController
[0] = NULL
;
1214 return EFI_DEVICE_ERROR
;
1217 for (Index
= 1; Index
< NumOfInterface
; Index
++) {
1218 UsbIoController
= CreateUsbIoControllerDevice ();
1219 UsbIoController
->UsbDevice
= UsbIoDevice
;
1220 UsbIoController
->CurrentConfigValue
=
1221 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1222 UsbIoController
->InterfaceNumber
= Index
;
1223 UsbIoDevice
->UsbController
[Index
] = UsbIoController
;
1224 UsbIoController
->ParentPort
= ParentPort
;
1225 UsbIoController
->Parent
= ParentHubController
;
1226 UsbIoController
->HostController
= HostController
;
1229 // First copy the USB_IO Protocol instance
1232 &UsbIoController
->UsbIo
,
1234 sizeof (EFI_USB_IO_PROTOCOL
)
1237 Result
= InitUsbIoController (UsbIoController
);
1238 if (EFI_ERROR (Result
)) {
1239 ReportUsbStatusCode (
1241 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1242 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1244 gBS
->FreePool (UsbIoController
);
1245 UsbIoDevice
->UsbController
[Index
] = NULL
;
1252 // USB Device DeConfiguration
1255 UsbDeviceDeConfiguration (
1256 IN USB_IO_DEVICE
*UsbIoDevice
1260 Routine Description:
1261 Remove Device, Device Handles, Uninstall Protocols.
1264 UsbIoDevice - The device to be deconfigured.
1272 USB_IO_CONTROLLER_DEVICE
*UsbController
;
1274 USB_IO_DEVICE
*ChildDevice
;
1276 EFI_USB_IO_PROTOCOL
*UsbIo
;
1279 // Double check UsbIoDevice exists
1281 if (UsbIoDevice
== NULL
) {
1285 UsbUnsetTransactionTranslator (UsbIoDevice
);
1287 for (index
= 0; index
< UsbIoDevice
->NumOfControllers
; index
++) {
1289 // Check if it is a hub, if so, de configuration all its
1292 UsbController
= UsbIoDevice
->UsbController
[index
];
1295 // Check the controller pointer
1297 if (UsbController
== NULL
) {
1301 if (UsbController
->IsUsbHub
) {
1303 DEBUG ((gUSBDebugLevel
, "Hub Deconfig, First Deconfig its downstream ports\n"));
1306 // First Remove interrupt transfer request for the status
1309 UsbIo
= &UsbController
->UsbIo
;
1310 UsbIo
->UsbAsyncInterruptTransfer (
1312 UsbController
->HubEndpointAddress
,
1320 if (NULL
!= UsbController
->HubNotify
) {
1321 gBS
->CloseEvent (UsbController
->HubNotify
);
1324 for (Index
= 0; Index
< UsbController
->DownstreamPorts
; Index
++) {
1325 if (UsbController
->Children
[Index
]) {
1326 ChildDevice
= UsbController
->Children
[Index
];
1327 UsbDeviceDeConfiguration (ChildDevice
);
1328 UsbController
->Children
[Index
] = NULL
;
1333 // If the controller is managed by a device driver, we need to
1336 if (UsbController
->IsManagedByDriver
) {
1337 gBS
->DisconnectController (
1338 UsbController
->Handle
,
1345 // remove child handle reference to the USB_HC_PROTOCOL
1347 if (UsbIoDevice
->BusController
->Hc2ProtocolSupported
) {
1348 gBS
->CloseProtocol (
1349 UsbController
->HostController
,
1350 &gEfiUsb2HcProtocolGuid
,
1351 gUsbBusDriverBinding
.DriverBindingHandle
,
1352 UsbController
->Handle
1355 gBS
->CloseProtocol (
1356 UsbController
->HostController
,
1357 &gEfiUsbHcProtocolGuid
,
1358 gUsbBusDriverBinding
.DriverBindingHandle
,
1359 UsbController
->Handle
1363 // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
1364 // installed on this handle
1366 gBS
->UninstallMultipleProtocolInterfaces (
1367 UsbController
->Handle
,
1368 &gEfiDevicePathProtocolGuid
,
1369 UsbController
->DevicePath
,
1370 &gEfiUsbIoProtocolGuid
,
1371 &UsbController
->UsbIo
,
1375 if (UsbController
->DevicePath
!= NULL
) {
1376 gBS
->FreePool (UsbController
->DevicePath
);
1379 gBS
->FreePool (UsbController
);
1380 UsbIoDevice
->UsbController
[index
] = NULL
;
1383 // Free address for later use
1386 UsbIoDevice
->DeviceAddress
,
1387 UsbIoDevice
->BusController
->AddressPool
1391 // Free all resouces allocated for all its configurations
1393 UsbDestroyAllConfiguration (UsbIoDevice
);
1396 gBS
->FreePool (UsbIoDevice
);
1403 // After interrupt complete, this function will be called,
1404 // This function need to be well-defined later
1409 OnHubInterruptComplete (
1411 IN UINTN DataLength
,
1417 Routine Description:
1418 Whenever hub interrupt occurs, this routine will be called to check
1419 which event happens.
1422 Data - Hub interrupt transfer data.
1423 DataLength - The length of the Data.
1424 Context - Hub Controller Device.
1425 Result - Hub interrupt transfer status.
1433 USB_IO_CONTROLLER_DEVICE
*HubController
;
1436 EFI_USB_IO_PROTOCOL
*UsbIo
;
1438 BOOLEAN Disconnected
;
1441 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1442 UsbIo
= &HubController
->UsbIo
;
1445 // If something error in this interrupt transfer,
1447 if (Result
!= EFI_USB_NOERROR
) {
1448 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1449 UsbClearEndpointHalt (
1451 HubController
->HubEndpointAddress
,
1457 // Delete & Submit this interrupt again
1459 UsbIo
->UsbAsyncInterruptTransfer (
1461 HubController
->HubEndpointAddress
,
1470 // try to detect if the hub itself was disconnected or not
1472 Status
= IsDeviceDisconnected (
1477 if (!EFI_ERROR (Status
) && Disconnected
== TRUE
) {
1478 DEBUG ((gUSBErrorLevel
, "Hub is disconnected\n"));
1479 return EFI_DEVICE_ERROR
;
1484 UsbIo
->UsbAsyncInterruptTransfer (
1486 HubController
->HubEndpointAddress
,
1490 OnHubInterruptComplete
,
1494 return EFI_DEVICE_ERROR
;
1497 if (DataLength
== 0 || Data
== NULL
) {
1502 // Scan which port has status change
1503 // Bit 0 stands for hub itself, other bit stands for
1504 // the corresponding port
1506 for (Index
= 0; Index
< DataLength
* 8; Index
++) {
1507 ptr
= (UINT8
*) Data
+ Index
/ 8;
1508 if ((*ptr
) & (1 << (Index
& 0x7))) {
1509 HubController
->StatusChangePort
= Index
;
1514 // Signal hub notify event
1516 gBS
->SignalEvent (HubController
->HubNotify
);
1521 // USB Root Hub Enumerator
1526 RootHubEnumeration (
1532 Routine Description:
1534 This is USB RootHub enumerator
1538 Event - Indicating which event is signaled
1539 Context - actually it is a USB_IO_DEVICE
1547 USB_IO_CONTROLLER_DEVICE
*HubController
;
1548 EFI_USB_PORT_STATUS HubPortStatus
;
1551 USB_IO_DEVICE
*UsbIoDev
;
1552 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1553 EFI_HANDLE HostController
;
1554 USB_IO_DEVICE
*OldUsbIoDevice
;
1555 USB_IO_DEVICE
*NewDevice
;
1556 USB_IO_CONTROLLER_DEVICE
*NewController
;
1558 EFI_USB_IO_PROTOCOL
*UsbIo
;
1560 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1561 HostController
= HubController
->HostController
;
1562 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1565 // Root hub has the address 1
1567 UsbIoDev
= HubController
->UsbDevice
;
1569 for (Index
= 0; Index
< HubController
->DownstreamPorts
; Index
++) {
1571 UsbVirtualHcGetRootHubPortStatus (
1574 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1577 if (!IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1581 // Clear root hub status change status
1583 UsbVirtualHcClearRootHubPortFeature (
1586 EfiUsbPortConnectChange
1589 gBS
->Stall (100 * 1000);
1591 UsbVirtualHcGetRootHubPortStatus (
1594 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1597 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1600 // There is something connected to this port
1602 DEBUG ((gUSBDebugLevel
, "Something connected to Root Hub at Port0x%x\n", Index
));
1604 ReportUsbStatusCode (
1607 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1610 // if there is something physically detached, but still logically
1613 OldUsbIoDevice
= HubController
->Children
[Index
];
1615 if (NULL
!= OldUsbIoDevice
) {
1616 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1617 HubController
->Children
[Index
] = NULL
;
1620 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1621 if (NewDevice
== NULL
) {
1625 // Initialize some fields by copying data from
1628 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1629 NewDevice
->BusController
= UsbIoDev
->BusController
;
1632 // Process of identify device speed
1634 Status
= IdentifyDeviceSpeed (
1639 if (EFI_ERROR (Status
)) {
1640 gBS
->FreePool (NewDevice
);
1645 // Configure that device
1647 Status
= UsbDeviceConfiguration (
1653 if (EFI_ERROR (Status
)) {
1654 gBS
->FreePool (NewDevice
);
1658 // Add this device to the usb bus tree
1660 HubController
->Children
[Index
] = NewDevice
;
1662 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
1664 // If this device is hub, add to the hub index
1666 NewController
= NewDevice
->UsbController
[Index2
];
1668 Status
= gBS
->ConnectController (
1669 NewController
->Handle
,
1675 // If connect success, we need to disconnect when
1676 // stop the controller, otherwise we need not call
1677 // gBS->DisconnectController ()
1678 // This is used by those usb devices we don't plan
1679 // to support. We can allocate
1680 // controller handles for them, but we don't have
1681 // device drivers to manage them.
1683 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
1685 if (IsHub (NewController
)) {
1687 NewController
->IsUsbHub
= TRUE
;
1690 // Configure Hub Controller
1692 Status
= DoHubConfig (NewController
);
1693 if (EFI_ERROR (Status
)) {
1697 // Create an event to do hub enumeration
1700 EFI_EVENT_NOTIFY_SIGNAL
,
1704 &NewController
->HubNotify
1708 // Add request to do query hub status
1712 UsbIo
= &NewController
->UsbIo
;
1713 UsbIo
->UsbAsyncInterruptTransfer (
1715 NewController
->HubEndpointAddress
,
1719 OnHubInterruptComplete
,
1727 // Something disconnected from USB root hub
1729 DEBUG ((gUSBDebugLevel
, "Something disconnected from Root Hub at Port0x%x\n", Index
));
1731 OldUsbIoDevice
= HubController
->Children
[Index
];
1733 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1735 HubController
->Children
[Index
] = NULL
;
1737 UsbVirtualHcClearRootHubPortFeature (
1740 EfiUsbPortEnableChange
1748 // USB Root Hub Enumerator
1759 Routine Description:
1761 This is Usb Hub enumerator
1765 Event - Indicating which event is signaled
1766 Context - actually it is a USB_IO_DEVICE
1774 USB_IO_CONTROLLER_DEVICE
*HubController
;
1775 EFI_USB_PORT_STATUS HubPortStatus
;
1777 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1778 EFI_HANDLE HostController
;
1779 USB_IO_DEVICE
*OldUsbIoDevice
;
1780 USB_IO_DEVICE
*NewDevice
;
1781 USB_IO_CONTROLLER_DEVICE
*NewController
;
1783 EFI_USB_IO_PROTOCOL
*UsbIo
;
1784 UINT8 StatusChangePort
;
1787 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1788 HostController
= HubController
->HostController
;
1789 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1792 // Event from Hub, Get the hub controller handle
1795 // Get the status change endpoint
1797 StatusChangePort
= HubController
->StatusChangePort
;
1800 // Clear HubController Status Change Bit
1802 HubController
->StatusChangePort
= 0;
1804 if (StatusChangePort
== 0) {
1806 // Hub changes, we don't handle here
1811 // Check which event took place at that port
1813 UsbIo
= &HubController
->UsbIo
;
1814 Status
= HubGetPortStatus (
1817 (UINT32
*) &HubPortStatus
1820 if (EFI_ERROR (Status
)) {
1824 // Clear some change status
1826 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
1828 // Clear Hub port enable change
1830 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
1831 HubClearPortFeature (
1834 EfiUsbPortEnableChange
1840 (UINT32
*) &HubPortStatus
1844 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
1846 // Clear Hub reset change
1848 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
1849 HubClearPortFeature (
1852 EfiUsbPortResetChange
1858 (UINT32
*) &HubPortStatus
1862 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_OVERCURRENT
) {
1864 // Clear Hub overcurrent change
1866 DEBUG ((gUSBDebugLevel
, "Port Overcurrent Change\n"));
1867 HubClearPortFeature (
1870 EfiUsbPortOverCurrentChange
1876 (UINT32
*) &HubPortStatus
1880 if (IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1882 // First clear port connection change
1884 DEBUG ((gUSBDebugLevel
, "Port Connection Change\n"));
1885 HubClearPortFeature (
1888 EfiUsbPortConnectChange
1894 (UINT32
*) &HubPortStatus
1897 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1899 DEBUG ((gUSBDebugLevel
, "New Device Connect on Hub port \n"));
1901 ReportUsbStatusCode (
1904 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1908 // if there is something physically detached, but still logically
1911 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
1913 if (NULL
!= OldUsbIoDevice
) {
1914 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1915 HubController
->Children
[StatusChangePort
- 1] = NULL
;
1918 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1919 if (NewDevice
== NULL
) {
1923 // Initialize some fields
1925 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1926 NewDevice
->BusController
= HubController
->UsbDevice
->BusController
;
1929 // There is something connected to this port,
1932 // Disable the enable bit in port status
1934 HubClearPortFeature (
1940 gBS
->Stall (50 * 1000);
1943 // Wait for bit change
1950 (UINT32
*) &HubPortStatus
1952 gBS
->Stall (10 * 1000);
1954 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_ENABLE
) == 1 && Number
> 0);
1958 // Cannot disable port, return error
1960 DEBUG ((gUSBErrorLevel
, "Disable Port Failed\n"));
1961 gBS
->FreePool (NewDevice
);
1971 gBS
->Stall (50 * 1000);
1974 // Wait for port reset complete
1981 (UINT32
*) &HubPortStatus
1983 gBS
->Stall (10 * 1000);
1985 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_RESET
) == 1 && Number
> 0);
1989 // Cannot reset port, return error
1991 DEBUG ((gUSBErrorLevel
, "Reset Port Failed\n"));
1992 gBS
->FreePool (NewDevice
);
1996 // Check high speed or full speed device
1998 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
1999 DEBUG ((gUSBDebugLevel
, "Low Speed Device Attached to Hub\n"));
2000 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
2001 } else if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2002 DEBUG ((gUSBDebugLevel
, "High Speed Device Attached to Hub\n"));
2003 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2005 DEBUG ((gUSBDebugLevel
, "Full Speed Device Attached to Hub\n"));
2006 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2009 // Configure that device
2011 Status
= UsbDeviceConfiguration (
2014 (UINT8
) (StatusChangePort
- 1),
2018 if (EFI_ERROR (Status
)) {
2019 gBS
->FreePool (NewDevice
);
2023 // Add this device to the usb bus tree
2024 // StatusChangePort is begin from 1,
2026 HubController
->Children
[StatusChangePort
- 1] = NewDevice
;
2028 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
2030 // If this device is hub, add to the hub index
2032 NewController
= NewDevice
->UsbController
[Index2
];
2035 // Connect the controller to the driver image
2037 Status
= gBS
->ConnectController (
2038 NewController
->Handle
,
2044 // If connect success, we need to disconnect when
2045 // stop the controller, otherwise we need not call
2046 // gBS->DisconnectController ()
2047 // This is used by those usb devices we don't plan
2048 // to support. We can allocate
2049 // controller handles for them, but we don't have
2050 // device drivers to manage them.
2052 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
2055 // If this device is hub, add to the hub index
2057 if (IsHub (NewController
)) {
2059 NewController
->IsUsbHub
= TRUE
;
2064 Status
= DoHubConfig (NewController
);
2066 if (EFI_ERROR (Status
)) {
2070 // Create an event to do hub enumeration
2073 EFI_EVENT_NOTIFY_SIGNAL
,
2077 &NewController
->HubNotify
2081 // Add request to do query hub status
2084 UsbIo
= &NewController
->UsbIo
;
2085 UsbIo
->UsbAsyncInterruptTransfer (
2087 NewController
->HubEndpointAddress
, // Hub endpoint address
2091 OnHubInterruptComplete
,
2098 // Something disconnected from USB hub
2100 DEBUG ((gUSBDebugLevel
, "Something Device Detached on Hub port\n"));
2102 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
2104 UsbDeviceDeConfiguration (OldUsbIoDevice
);
2106 HubController
->Children
[StatusChangePort
- 1] = NULL
;
2117 USB_IO_CONTROLLER_DEVICE
*
2118 CreateUsbIoControllerDevice (
2123 Routine Description:
2124 Allocate a structure for USB_IO_CONTROLLER_DEVICE
2130 A pointer to a USB_IO_CONTROLLER_DEVICE structure,
2135 USB_IO_CONTROLLER_DEVICE
*UsbIoControllerDev
;
2138 // Allocate USB_IO_CONTROLLER_DEVICE structure
2140 UsbIoControllerDev
= NULL
;
2141 UsbIoControllerDev
= AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE
));
2143 if (UsbIoControllerDev
== NULL
) {
2147 UsbIoControllerDev
->Signature
= USB_IO_CONTROLLER_SIGNATURE
;
2149 return UsbIoControllerDev
;
2154 InitUsbIoController (
2155 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
2159 Routine Description:
2160 Init and install EFI_USB_IO_PROTOCOL onto that controller.
2163 UsbIoController - The Controller to be operated.
2171 USB_DEVICE_PATH UsbNode
;
2173 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
2174 EFI_USB_HC_PROTOCOL
*UsbHcProtocol
;
2175 EFI_USB2_HC_PROTOCOL
*Usb2HcProtocol
;
2178 // Build the child device path for each new USB_IO device
2180 ZeroMem (&UsbNode
, sizeof (UsbNode
));
2181 UsbNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
2182 UsbNode
.Header
.SubType
= MSG_USB_DP
;
2183 SetDevicePathNodeLength (&UsbNode
.Header
, sizeof (UsbNode
));
2184 UsbNode
.InterfaceNumber
= UsbIoController
->InterfaceNumber
;
2185 UsbNode
.ParentPortNumber
= UsbIoController
->ParentPort
;
2186 ParentDevicePath
= UsbIoController
->Parent
->DevicePath
;
2188 UsbIoController
->DevicePath
=
2189 AppendDevicePathNode (ParentDevicePath
, &UsbNode
.Header
);
2190 if (UsbIoController
->DevicePath
== NULL
) {
2191 return EFI_OUT_OF_RESOURCES
;
2194 Status
= gBS
->InstallMultipleProtocolInterfaces (
2195 &UsbIoController
->Handle
,
2196 &gEfiDevicePathProtocolGuid
,
2197 UsbIoController
->DevicePath
,
2198 &gEfiUsbIoProtocolGuid
,
2199 &UsbIoController
->UsbIo
,
2203 if (EFI_ERROR (Status
)) {
2207 if (UsbIoController
->UsbDevice
->BusController
->Hc2ProtocolSupported
) {
2208 Status
= gBS
->OpenProtocol (
2209 UsbIoController
->HostController
,
2210 &gEfiUsb2HcProtocolGuid
,
2211 (VOID
**)&Usb2HcProtocol
,
2212 gUsbBusDriverBinding
.DriverBindingHandle
,
2213 UsbIoController
->Handle
,
2214 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2217 Status
= gBS
->OpenProtocol (
2218 UsbIoController
->HostController
,
2219 &gEfiUsbHcProtocolGuid
,
2220 (VOID
**)&UsbHcProtocol
,
2221 gUsbBusDriverBinding
.DriverBindingHandle
,
2222 UsbIoController
->Handle
,
2223 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2233 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2234 IN BOOLEAN ReConfigure
,
2239 Routine Description:
2240 Reset parent hub port to which this device is connected.
2243 UsbIoController - Indicating the Usb Controller Device.
2244 ReConfigure - Do we need to reconfigure it.
2245 RetryTimes - Retry Times when failed
2253 USB_IO_DEVICE
*ParentIoDev
;
2254 USB_IO_DEVICE
*UsbIoDev
;
2255 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2259 EFI_USB_IO_PROTOCOL
*UsbIo
;
2262 ParentController
= UsbIoController
->Parent
;
2263 ParentIoDev
= ParentController
->UsbDevice
;
2264 UsbIoDev
= UsbIoController
->UsbDevice
;
2265 HubPort
= UsbIoController
->ParentPort
;
2267 gBS
->Stall (100 * 1000);
2269 if (ParentIoDev
->DeviceAddress
== 1) {
2270 DEBUG ((gUSBDebugLevel
, "Reset from Root Hub 0x%x\n", HubPort
));
2271 ResetRootPort (ParentIoDev
->BusController
, HubPort
, RetryTimes
);
2273 DEBUG ((gUSBDebugLevel
, "Reset from Hub, Addr 0x%x\n", ParentIoDev
->DeviceAddress
));
2274 ResetHubPort (ParentController
, HubPort
+ 1);
2277 // If we only need port reset, just return
2283 // Re-config that USB device
2285 UsbIo
= &UsbIoController
->UsbIo
;
2288 // Assign a unique address to this device
2290 Address
= UsbIoDev
->DeviceAddress
;
2291 UsbIoDev
->DeviceAddress
= 0;
2293 Result
= UsbSetDeviceAddress (UsbIo
, Address
, &Status
);
2294 UsbIoDev
->DeviceAddress
= Address
;
2296 if (EFI_ERROR (Result
)) {
2297 return EFI_DEVICE_ERROR
;
2300 // Set the device to the default configuration
2302 Result
= UsbSetDefaultConfiguration (UsbIoDev
);
2303 if (EFI_ERROR (Result
)) {
2304 return EFI_DEVICE_ERROR
;
2313 IN EFI_USB_IO_PROTOCOL
*This
2317 Routine Description:
2318 Resets and reconfigures the USB controller. This function will
2319 work for all USB devices except USB Hub Controllers.
2322 This - Indicates the calling context.
2326 EFI_INVALID_PARAMETER
2331 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
2333 UsbIoController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This
);
2335 if (IsHub (UsbIoController
)) {
2336 return EFI_INVALID_PARAMETER
;
2340 // Since at this time, this device has already been configured,
2341 // it needs to be re-configured.
2343 return ParentPortReset (UsbIoController
, TRUE
, 0);
2348 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2354 Routine Description:
2355 Reset Root Hub port.
2358 UsbBusDev - Bus controller of the device.
2359 PortNum - The given port to be reset.
2360 RetryTimes - RetryTimes when failed
2369 EFI_USB_PORT_STATUS PortStatus
;
2374 Status
= UsbVirtualHcSetRootHubPortFeature (
2379 if (EFI_ERROR (Status
)) {
2380 return EFI_DEVICE_ERROR
;
2383 gBS
->Stall (50 * 1000);
2386 // clear reset root port
2388 Status
= UsbVirtualHcClearRootHubPortFeature (
2393 if (EFI_ERROR (Status
)) {
2394 return EFI_DEVICE_ERROR
;
2399 Status
= UsbVirtualHcClearRootHubPortFeature (
2402 EfiUsbPortConnectChange
2404 if (EFI_ERROR (Status
)) {
2405 return EFI_DEVICE_ERROR
;
2408 UsbVirtualHcGetRootHubPortStatus (
2413 if (PortStatus
.PortStatus
& USB_PORT_STAT_OWNER
) {
2417 Status
= UsbVirtualHcSetRootHubPortFeature (
2422 if (EFI_ERROR (Status
)) {
2423 return EFI_DEVICE_ERROR
;
2426 Status
= UsbVirtualHcClearRootHubPortFeature (
2429 EfiUsbPortEnableChange
2433 gBS
->Stall ((1 + RetryTimes
) * 50 * 1000);
2440 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2445 Routine Description:
2449 UsbIoController - The USB_IO_CONTROLLER_DEVICE instance.
2450 PortIndex - The given port to be reset.
2458 EFI_USB_IO_PROTOCOL
*UsbIo
;
2459 EFI_USB_PORT_STATUS HubPortStatus
;
2462 ASSERT (UsbIoController
->IsUsbHub
== TRUE
);
2464 UsbIo
= &UsbIoController
->UsbIo
;
2472 gBS
->Stall (10 * 1000);
2475 // Wait for port reset complete
2482 (UINT32
*) &HubPortStatus
2484 gBS
->Stall (10 * 100);
2486 } while ((HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) == 0 && Number
> 0);
2490 // Cannot reset port, return error
2492 return EFI_DEVICE_ERROR
;
2500 (UINT32
*) &HubPortStatus
2503 // reset port will cause some bits change, clear them
2505 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
2506 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
2507 HubClearPortFeature (
2510 EfiUsbPortEnableChange
2514 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
2515 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
2516 HubClearPortFeature (
2519 EfiUsbPortResetChange
2528 ReportUsbStatusCode (
2529 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
2530 IN EFI_STATUS_CODE_TYPE Type
,
2531 IN EFI_STATUS_CODE_VALUE Code
2535 Routine Description:
2537 report a error Status code of USB bus driver controller
2540 UsbBusController - USB_BUS_CONTROLLER_DEVICE
2541 Type - EFI_STATUS_CODE_TYPE
2542 Code - EFI_STATUS_CODE_VALUE
2549 return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
2552 UsbBusController
->DevicePath
2557 IsDeviceDisconnected (
2558 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2559 IN OUT BOOLEAN
*Disconnected
2563 Routine Description:
2564 Reset if the device is disconencted or not
2567 UsbIoController - Indicating the Usb Controller Device.
2568 Disconnected - Indicate whether the device is disconencted or not
2576 USB_IO_DEVICE
*ParentIoDev
;
2577 USB_IO_DEVICE
*UsbIoDev
;
2578 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2581 EFI_USB_IO_PROTOCOL
*UsbIo
;
2582 EFI_USB_PORT_STATUS PortStatus
;
2584 ParentController
= UsbIoController
->Parent
;
2585 ParentIoDev
= ParentController
->UsbDevice
;
2586 UsbIoDev
= UsbIoController
->UsbDevice
;
2587 HubPort
= UsbIoController
->ParentPort
;
2589 if (ParentIoDev
->DeviceAddress
== 1) {
2591 // Connected to the root hub
2593 UsbVirtualHcGetRootHubPortStatus (
2594 ParentIoDev
->BusController
,
2600 UsbIo
= &UsbIoController
->UsbIo
;
2601 Status
= HubGetPortStatus (
2602 &ParentController
->UsbIo
,
2604 (UINT32
*) &PortStatus
2607 if (EFI_ERROR (Status
)) {
2608 return IsDeviceDisconnected (ParentController
, Disconnected
);
2612 *Disconnected
= FALSE
;
2614 if (!IsPortConnect (PortStatus
.PortStatus
)) {
2615 *Disconnected
= TRUE
;
2623 UsbSetTransactionTranslator (
2624 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
2625 IN UINT8 ParentPort
,
2626 IN OUT USB_IO_DEVICE
*Device
2630 Routine Description:
2632 Set Transaction Translator parameter
2636 ParentHubController - Controller structure of the parent Hub device
2637 ParentPort - Number of parent port
2638 Device - Structure of the device
2643 EFI_OUT_OF_RESOURCES Cannot allocate resources
2647 USB_IO_CONTROLLER_DEVICE
*AncestorHubController
;
2649 AncestorHubController
= ParentHubController
;
2650 Device
->Translator
= NULL
;
2652 if (EFI_USB_SPEED_HIGH
== Device
->DeviceSpeed
) {
2657 if (EFI_USB_SPEED_HIGH
== AncestorHubController
->UsbDevice
->DeviceSpeed
) {
2661 if (NULL
== AncestorHubController
->Parent
) {
2665 AncestorHubController
= AncestorHubController
->Parent
;
2668 Device
->Translator
= AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR
));
2669 if (NULL
== Device
->Translator
) {
2670 return EFI_OUT_OF_RESOURCES
;
2673 Device
->Translator
->TranslatorHubAddress
= AncestorHubController
->UsbDevice
->DeviceAddress
;
2674 Device
->Translator
->TranslatorPortNumber
= ParentPort
;
2681 UsbUnsetTransactionTranslator (
2682 USB_IO_DEVICE
*Device
2686 Routine Description:
2688 Unset Transaction Translator parameter
2692 Device - Structure of the device
2700 if (Device
->Translator
) {
2701 gBS
->FreePool (Device
->Translator
);
2702 Device
->Translator
= NULL
;
2710 IdentifyDeviceSpeed (
2711 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2712 USB_IO_DEVICE
*NewDevice
,
2717 Routine Description:
2719 Identify speed of USB device
2723 UsbBusDev - UsbBus controller structure of the device
2724 NewDevice - Devcie controller structure
2725 Index - Number of the port
2730 EFI_NOT_FOUND Device release to CHC or can't be found
2735 EFI_USB_PORT_STATUS HubPortStatus
;
2737 UsbVirtualHcGetRootHubPortStatus (
2740 (EFI_USB_PORT_STATUS
*) &HubPortStatus
2744 // Check device device
2746 if (!(HubPortStatus
.PortStatus
& USB_PORT_STAT_OWNER
)) {
2750 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2751 DEBUG ((gUSBDebugLevel
, "High Speed Device attached to EHC\n"));
2752 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2754 Status
= ReleasePortToCHC (UsbBusDev
, Index
);
2755 if (EFI_ERROR (Status
)) {
2756 DEBUG ((gUSBErrorLevel
, "Fail to release port to CHC\n"));
2758 DEBUG ((gUSBDebugLevel
, "Success to release port to CHC\n"));
2760 return EFI_DEVICE_ERROR
;
2766 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
2767 DEBUG ((gUSBDebugLevel
, "Low Speed Device attached to CHC\n"));
2768 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
2770 DEBUG ((gUSBDebugLevel
, "FULL Speed Device attached to CHC\n"));
2771 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2781 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2786 Routine Description:
2788 Set bit to release the port owner to CHC
2792 UsbBusDev - UsbBus controller structure of the device
2793 PortNum - Number of the port
2798 EFI_DEVICE_ERROR Fail
2804 Status
= UsbVirtualHcSetRootHubPortFeature (
2810 gBS
->Stall (100 * 1000);
2817 UsbVirtualHcGetCapability (
2818 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2819 OUT UINT8
*MaxSpeed
,
2820 OUT UINT8
*PortNumber
,
2821 OUT UINT8
*Is64BitCapable
2825 Routine Description:
2827 Virtual interface to Retrieves the capablility of root hub ports
2828 for both Hc2 and Hc protocol.
2832 UsbBusDev - A pointer to bus controller of the device.
2833 MaxSpeed - A pointer to the number of the host controller.
2834 PortNumber - A pointer to the number of the root hub ports.
2835 Is64BitCapable - A pointer to the flag for whether controller supports
2836 64-bit memory addressing.
2841 The host controller capability were retrieved successfully.
2842 EFI_INVALID_PARAMETER
2843 MaxSpeed or PortNumber or Is64BitCapable is NULL.
2845 An error was encountered while attempting to retrieve the capabilities.
2851 Status
= EFI_SUCCESS
;
2853 if (UsbBusDev
->Hc2ProtocolSupported
) {
2854 Status
= UsbBusDev
->Usb2HCInterface
->GetCapability (
2855 UsbBusDev
->Usb2HCInterface
,
2861 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortNumber (
2862 UsbBusDev
->UsbHCInterface
,
2865 *MaxSpeed
= EFI_USB_SPEED_FULL
;
2866 *Is64BitCapable
= (UINT8
) FALSE
;
2875 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2876 IN UINT16 Attributes
2880 Routine Description:
2882 Virtual interface to provides software reset for the USB host controller
2883 for both Hc2 and Hc protocol.
2887 UsbBusDev - A pointer to bus controller of the device.
2888 Attributes - A bit mask of the reset operation to perform.
2889 See below for a list of the supported bit mask values.
2891 #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc
2892 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
2893 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
2894 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
2896 EFI_USB_HC_RESET_GLOBAL
2897 If this bit is set, a global reset signal will be sent to the USB bus.
2898 This resets all of the USB bus logic, including the USB host
2899 controller hardware and all the devices attached on the USB bus.
2900 EFI_USB_HC_RESET_HOST_CONTROLLER
2901 If this bit is set, the USB host controller hardware will be reset.
2902 No reset signal will be sent to the USB bus.
2903 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
2904 If this bit is set, a global reset signal will be sent to the USB bus.
2905 This resets all of the USB bus logic, including the USB host
2906 controller hardware and all the devices attached on the USB bus.
2907 If this is an EHCI controller and the debug port has configured, then
2908 this is will still reset the host controller.
2909 EFI_USB_HC_RESET_HOST_WITH_DEBUG
2910 If this bit is set, the USB host controller hardware will be reset.
2911 If this is an EHCI controller and the debug port has been configured,
2912 then this will still reset the host controller.
2917 The reset operation succeeded.
2918 EFI_INVALID_PARAMETER
2919 Attributes is not valid.
2921 The type of reset specified by Attributes is not currently supported by
2922 the host controller hardware.
2924 Reset operation is rejected due to the debug port being configured and
2925 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
2926 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
2927 perform reset operation for this host controller.
2929 An error was encountered while attempting to perform
2930 the reset operation.
2936 Status
= EFI_SUCCESS
;
2938 if (UsbBusDev
->Hc2ProtocolSupported
) {
2939 Status
= UsbBusDev
->Usb2HCInterface
->Reset (
2940 UsbBusDev
->Usb2HCInterface
,
2941 EFI_USB_HC_RESET_GLOBAL
2944 Status
= UsbBusDev
->UsbHCInterface
->Reset (
2945 UsbBusDev
->UsbHCInterface
,
2946 EFI_USB_HC_RESET_GLOBAL
2955 UsbVirtualHcGetState (
2956 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2957 OUT EFI_USB_HC_STATE
*State
2961 Routine Description:
2963 Virtual interface to retrieves current state of the USB host controller
2964 for both Hc2 and Hc protocol.
2968 UsbBusDev - A pointer to bus controller of the device.
2969 State - A pointer to the EFI_USB_HC_STATE data structure that
2970 indicates current state of the USB host controller.
2971 Type EFI_USB_HC_STATE is defined below.
2975 EfiUsbHcStateOperational,
2976 EfiUsbHcStateSuspend,
2977 EfiUsbHcStateMaximum
2983 The state information of the host controller was returned in State.
2984 EFI_INVALID_PARAMETER
2987 An error was encountered while attempting to retrieve the
2988 host controller's current state.
2994 Status
= EFI_SUCCESS
;
2996 if (UsbBusDev
->Hc2ProtocolSupported
) {
2997 Status
= UsbBusDev
->Usb2HCInterface
->GetState (
2998 UsbBusDev
->Usb2HCInterface
,
3002 Status
= UsbBusDev
->UsbHCInterface
->GetState (
3003 UsbBusDev
->UsbHCInterface
,
3013 UsbVirtualHcSetState (
3014 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3015 IN EFI_USB_HC_STATE State
3019 Routine Description:
3021 Virtual interface to sets the USB host controller to a specific state
3022 for both Hc2 and Hc protocol.
3026 UsbBusDev - A pointer to bus controller of the device.
3027 State - Indicates the state of the host controller that will be set.
3032 The USB host controller was successfully placed in the state
3034 EFI_INVALID_PARAMETER
3037 Failed to set the state specified by State due to device error.
3043 Status
= EFI_SUCCESS
;
3045 if (UsbBusDev
->Hc2ProtocolSupported
) {
3046 Status
= UsbBusDev
->Usb2HCInterface
->SetState (
3047 UsbBusDev
->Usb2HCInterface
,
3051 Status
= UsbBusDev
->UsbHCInterface
->SetState (
3052 UsbBusDev
->UsbHCInterface
,
3062 UsbVirtualHcGetRootHubPortStatus (
3063 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3064 IN UINT8 PortNumber
,
3065 OUT EFI_USB_PORT_STATUS
*PortStatus
3069 Routine Description:
3071 Virtual interface to retrieves the current status of a USB root hub port
3072 both for Hc2 and Hc protocol.
3076 UsbBusDev - A pointer to bus controller of the device.
3077 PortNumber - Specifies the root hub port from which the status
3078 is to be retrieved. This value is zero-based. For example,
3079 if a root hub has two ports, then the first port is numbered 0,
3080 and the second port is numbered 1.
3081 PortStatus - A pointer to the current port status bits and
3082 port status change bits.
3086 EFI_SUCCESS The status of the USB root hub port specified by PortNumber
3087 was returned in PortStatus.
3088 EFI_INVALID_PARAMETER PortNumber is invalid.
3089 EFI_DEVICE_ERROR Can't read register
3095 Status
= EFI_SUCCESS
;
3097 if (UsbBusDev
->Hc2ProtocolSupported
) {
3098 Status
= UsbBusDev
->Usb2HCInterface
->GetRootHubPortStatus (
3099 UsbBusDev
->Usb2HCInterface
,
3104 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortStatus (
3105 UsbBusDev
->UsbHCInterface
,
3116 UsbVirtualHcSetRootHubPortFeature (
3117 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3118 IN UINT8 PortNumber
,
3119 IN EFI_USB_PORT_FEATURE PortFeature
3123 Routine Description:
3124 Virual interface to sets a feature for the specified root hub port
3125 for both Hc2 and Hc protocol.
3129 UsbBusDev - A pointer to bus controller of the device.
3130 PortNumber - Specifies the root hub port whose feature
3131 is requested to be set.
3132 PortFeature - Indicates the feature selector associated
3133 with the feature set request.
3138 The feature specified by PortFeature was set for the
3139 USB root hub port specified by PortNumber.
3140 EFI_INVALID_PARAMETER
3141 PortNumber is invalid or PortFeature is invalid.
3149 Status
= EFI_SUCCESS
;
3151 if (UsbBusDev
->Hc2ProtocolSupported
) {
3152 Status
= UsbBusDev
->Usb2HCInterface
->SetRootHubPortFeature (
3153 UsbBusDev
->Usb2HCInterface
,
3158 Status
= UsbBusDev
->UsbHCInterface
->SetRootHubPortFeature (
3159 UsbBusDev
->UsbHCInterface
,
3170 UsbVirtualHcClearRootHubPortFeature (
3171 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3172 IN UINT8 PortNumber
,
3173 IN EFI_USB_PORT_FEATURE PortFeature
3177 Routine Description:
3179 Virtual interface to clears a feature for the specified root hub port
3180 for both Hc2 and Hc protocol.
3184 UsbBusDev - A pointer to bus controller of the device.
3185 PortNumber - Specifies the root hub port whose feature
3186 is requested to be cleared.
3187 PortFeature - Indicates the feature selector associated with the
3188 feature clear request.
3193 The feature specified by PortFeature was cleared for the
3194 USB root hub port specified by PortNumber.
3195 EFI_INVALID_PARAMETER
3196 PortNumber is invalid or PortFeature is invalid.
3204 Status
= EFI_SUCCESS
;
3206 if (UsbBusDev
->Hc2ProtocolSupported
) {
3207 Status
= UsbBusDev
->Usb2HCInterface
->ClearRootHubPortFeature (
3208 UsbBusDev
->Usb2HCInterface
,
3213 Status
= UsbBusDev
->UsbHCInterface
->ClearRootHubPortFeature (
3214 UsbBusDev
->UsbHCInterface
,
3225 UsbVirtualHcControlTransfer (
3226 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3227 IN UINT8 DeviceAddress
,
3228 IN UINT8 DeviceSpeed
,
3229 IN UINTN MaximumPacketLength
,
3230 IN EFI_USB_DEVICE_REQUEST
*Request
,
3231 IN EFI_USB_DATA_DIRECTION TransferDirection
,
3233 IN OUT UINTN
*DataLength
,
3235 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3236 OUT UINT32
*TransferResult
3240 Routine Description:
3242 Virtual interface to submits control transfer to a target USB device
3243 for both Hc2 and Hc protocol.
3247 UsbBusDev - A pointer to bus controller of the device.
3248 DeviceAddress - Represents the address of the target device on the USB,
3249 which is assigned during USB enumeration.
3250 DeviceSpeed - Indicates target device speed.
3251 MaximumPacketLength - Indicates the maximum packet size that the
3252 default control transfer endpoint is capable of
3253 sending or receiving.
3254 Request - A pointer to the USB device request that will be sent
3256 TransferDirection - Specifies the data direction for the transfer.
3257 There are three values available, DataIn, DataOut
3259 Data - A pointer to the buffer of data that will be transmitted
3260 to USB device or received from USB device.
3261 DataLength - Indicates the size, in bytes, of the data buffer
3263 TimeOut - Indicates the maximum time, in microseconds,
3264 which the transfer is allowed to complete.
3265 Translator - A pointr to the transaction translator data.
3266 TransferResult - A pointer to the detailed result information generated
3267 by this control transfer.
3272 The control transfer was completed successfully.
3273 EFI_OUT_OF_RESOURCES
3274 The control transfer could not be completed due to a lack of resources.
3275 EFI_INVALID_PARAMETER
3276 Some parameters are invalid.
3278 The control transfer failed due to timeout.
3280 The control transfer failed due to host controller or device error.
3281 Caller should check TranferResult for detailed error information.
3286 BOOLEAN IsSlowDevice
;
3288 Status
= EFI_SUCCESS
;
3290 if (UsbBusDev
->Hc2ProtocolSupported
) {
3291 Status
= UsbBusDev
->Usb2HCInterface
->ControlTransfer (
3292 UsbBusDev
->Usb2HCInterface
,
3295 MaximumPacketLength
,
3305 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3306 Status
= UsbBusDev
->UsbHCInterface
->ControlTransfer (
3307 UsbBusDev
->UsbHCInterface
,
3310 (UINT8
) MaximumPacketLength
,
3325 UsbVirtualHcBulkTransfer (
3326 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3327 IN UINT8 DeviceAddress
,
3328 IN UINT8 EndPointAddress
,
3329 IN UINT8 DeviceSpeed
,
3330 IN UINTN MaximumPacketLength
,
3331 IN UINT8 DataBuffersNumber
,
3332 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
3333 IN OUT UINTN
*DataLength
,
3334 IN OUT UINT8
*DataToggle
,
3336 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3337 OUT UINT32
*TransferResult
3341 Routine Description:
3343 Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
3344 both for Hc2 and Hc protocol.
3348 UsbBusDev - A pointer to bus controller of the device.
3349 DeviceAddress - Represents the address of the target device on the USB,
3350 which is assigned during USB enumeration.
3351 EndPointAddress - The combination of an endpoint number and an
3352 endpoint direction of the target USB device.
3353 Each endpoint address supports data transfer in
3354 one direction except the control endpoint
3355 (whose default endpoint address is 0).
3356 It is the caller's responsibility to make sure that
3357 the EndPointAddress represents a bulk endpoint.
3358 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
3359 and EFI_USB_SPEED_HIGH.
3360 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3361 is capable of sending or receiving.
3362 DataBuffersNumber - Number of data buffers prepared for the transfer.
3363 Data - Array of pointers to the buffers of data that will be transmitted
3364 to USB device or received from USB device.
3365 DataLength - When input, indicates the size, in bytes, of the data buffer
3366 specified by Data. When output, indicates the actually
3367 transferred data size.
3368 DataToggle - A pointer to the data toggle value. On input, it indicates
3369 the initial data toggle value the bulk transfer should adopt;
3370 on output, it is updated to indicate the data toggle value
3371 of the subsequent bulk transfer.
3372 Translator - A pointr to the transaction translator data.
3373 TimeOut - Indicates the maximum time, in microseconds, which the
3374 transfer is allowed to complete.
3375 TransferResult - A pointer to the detailed result information of the
3381 The bulk transfer was completed successfully.
3382 EFI_OUT_OF_RESOURCES
3383 The bulk transfer could not be submitted due to lack of resource.
3384 EFI_INVALID_PARAMETER
3385 Some parameters are invalid.
3387 The bulk transfer failed due to timeout.
3389 The bulk transfer failed due to host controller or device error.
3390 Caller should check TranferResult for detailed error information.
3396 Status
= EFI_SUCCESS
;
3398 if (UsbBusDev
->Hc2ProtocolSupported
) {
3399 Status
= UsbBusDev
->Usb2HCInterface
->BulkTransfer (
3400 UsbBusDev
->Usb2HCInterface
,
3404 MaximumPacketLength
,
3414 Status
= UsbBusDev
->UsbHCInterface
->BulkTransfer (
3415 UsbBusDev
->UsbHCInterface
,
3418 (UINT8
) MaximumPacketLength
,
3432 UsbVirtualHcAsyncInterruptTransfer (
3433 IN USB_BUS_CONTROLLER_DEVICE
* UsbBusDev
,
3434 IN UINT8 DeviceAddress
,
3435 IN UINT8 EndPointAddress
,
3436 IN UINT8 DeviceSpeed
,
3437 IN UINTN MaximumPacketLength
,
3438 IN BOOLEAN IsNewTransfer
,
3439 IN OUT UINT8
*DataToggle
,
3440 IN UINTN PollingInterval
,
3441 IN UINTN DataLength
,
3442 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
3443 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
3444 IN VOID
*Context OPTIONAL
3448 Routine Description:
3450 Virtual interface to submits an asynchronous interrupt transfer to an
3451 interrupt endpoint of a USB device for both Hc2 and Hc protocol.
3455 UsbBusDev - A pointer to bus controller of the device.
3456 DeviceAddress - Represents the address of the target device on the USB,
3457 which is assigned during USB enumeration.
3458 EndPointAddress - The combination of an endpoint number and an endpoint
3459 direction of the target USB device. Each endpoint address
3460 supports data transfer in one direction except the
3461 control endpoint (whose default endpoint address is 0).
3462 It is the caller's responsibility to make sure that
3463 the EndPointAddress represents an interrupt endpoint.
3464 DeviceSpeed - Indicates device speed.
3465 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3466 is capable of sending or receiving.
3467 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
3468 the host and the target interrupt endpoint.
3469 If FALSE, the specified asynchronous interrupt pipe
3471 DataToggle - A pointer to the data toggle value. On input, it is valid
3472 when IsNewTransfer is TRUE, and it indicates the initial
3473 data toggle value the asynchronous interrupt transfer
3475 On output, it is valid when IsNewTransfer is FALSE,
3476 and it is updated to indicate the data toggle value of
3477 the subsequent asynchronous interrupt transfer.
3478 PollingInterval - Indicates the interval, in milliseconds, that the
3479 asynchronous interrupt transfer is polled.
3480 This parameter is required when IsNewTransfer is TRUE.
3481 DataLength - Indicates the length of data to be received at the
3482 rate specified by PollingInterval from the target
3483 asynchronous interrupt endpoint. This parameter
3484 is only required when IsNewTransfer is TRUE.
3485 Translator - A pointr to the transaction translator data.
3486 CallBackFunction - The Callback function.This function is called at the
3487 rate specified by PollingInterval.This parameter is
3488 only required when IsNewTransfer is TRUE.
3489 Context - The context that is passed to the CallBackFunction.
3490 - This is an optional parameter and may be NULL.
3495 The asynchronous interrupt transfer request has been successfully
3496 submitted or canceled.
3497 EFI_INVALID_PARAMETER
3498 Some parameters are invalid.
3499 EFI_OUT_OF_RESOURCES
3500 The request could not be completed due to a lack of resources.
3507 BOOLEAN IsSlowDevice
;
3509 Status
= EFI_SUCCESS
;
3511 if (UsbBusDev
->Hc2ProtocolSupported
) {
3512 Status
= UsbBusDev
->Usb2HCInterface
->AsyncInterruptTransfer (
3513 UsbBusDev
->Usb2HCInterface
,
3517 MaximumPacketLength
,
3527 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3528 Status
= UsbBusDev
->UsbHCInterface
->AsyncInterruptTransfer (
3529 UsbBusDev
->UsbHCInterface
,
3533 (UINT8
) MaximumPacketLength
,
3548 UsbVirtualHcSyncInterruptTransfer (
3549 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3550 IN UINT8 DeviceAddress
,
3551 IN UINT8 EndPointAddress
,
3552 IN UINT8 DeviceSpeed
,
3553 IN UINTN MaximumPacketLength
,
3555 IN OUT UINTN
*DataLength
,
3556 IN OUT UINT8
*DataToggle
,
3558 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3559 OUT UINT32
*TransferResult
3563 Routine Description:
3565 Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
3566 of a USB device for both Hc2 and Hc protocol.
3570 UsbBusDev - A pointer to bus controller of the device.
3571 DeviceAddress - Represents the address of the target device on the USB,
3572 which is assigned during USB enumeration.
3573 EndPointAddress - The combination of an endpoint number and an endpoint
3574 direction of the target USB device. Each endpoint
3575 address supports data transfer in one direction
3576 except the control endpoint (whose default
3577 endpoint address is 0). It is the caller's responsibility
3578 to make sure that the EndPointAddress represents
3579 an interrupt endpoint.
3580 DeviceSpeed - Indicates device speed.
3581 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3582 is capable of sending or receiving.
3583 Data - A pointer to the buffer of data that will be transmitted
3584 to USB device or received from USB device.
3585 DataLength - On input, the size, in bytes, of the data buffer specified
3586 by Data. On output, the number of bytes transferred.
3587 DataToggle - A pointer to the data toggle value. On input, it indicates
3588 the initial data toggle value the synchronous interrupt
3589 transfer should adopt;
3590 on output, it is updated to indicate the data toggle value
3591 of the subsequent synchronous interrupt transfer.
3592 TimeOut - Indicates the maximum time, in microseconds, which the
3593 transfer is allowed to complete.
3594 Translator - A pointr to the transaction translator data.
3595 TransferResult - A pointer to the detailed result information from
3596 the synchronous interrupt transfer.
3601 The synchronous interrupt transfer was completed successfully.
3602 EFI_OUT_OF_RESOURCES
3603 The synchronous interrupt transfer could not be submitted due
3604 to lack of resource.
3605 EFI_INVALID_PARAMETER
3606 Some parameters are invalid.
3608 The synchronous interrupt transfer failed due to timeout.
3610 The synchronous interrupt transfer failed due to host controller
3611 or device error. Caller should check TranferResult for detailed
3617 BOOLEAN IsSlowDevice
;
3619 Status
= EFI_SUCCESS
;
3621 if (UsbBusDev
->Hc2ProtocolSupported
) {
3622 Status
= UsbBusDev
->Usb2HCInterface
->SyncInterruptTransfer (
3623 UsbBusDev
->Usb2HCInterface
,
3627 MaximumPacketLength
,
3636 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3637 Status
= UsbBusDev
->UsbHCInterface
->SyncInterruptTransfer (
3638 UsbBusDev
->UsbHCInterface
,
3642 (UINT8
) MaximumPacketLength
,
3656 UsbVirtualHcIsochronousTransfer (
3657 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3658 IN UINT8 DeviceAddress
,
3659 IN UINT8 EndPointAddress
,
3660 IN UINT8 DeviceSpeed
,
3661 IN UINTN MaximumPacketLength
,
3662 IN UINT8 DataBuffersNumber
,
3663 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3664 IN UINTN DataLength
,
3665 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3666 OUT UINT32
*TransferResult
3670 Routine Description:
3672 Virtual interface to submits isochronous transfer to a target USB device
3673 for both Hc2 and Hc protocol.
3677 UsbBusDev - A pointer to bus controller of the device.
3678 DeviceAddress - Represents the address of the target device on the USB,
3679 which is assigned during USB enumeration.
3680 EndPointAddress - End point address
3681 DeviceSpeed - Indicates device speed.
3682 MaximumPacketLength - Indicates the maximum packet size that the
3683 default control transfer endpoint is capable of
3684 sending or receiving.
3685 DataBuffersNumber - Number of data buffers prepared for the transfer.
3686 Data - Array of pointers to the buffers of data that will be
3687 transmitted to USB device or received from USB device.
3688 DataLength - Indicates the size, in bytes, of the data buffer
3690 Translator - A pointr to the transaction translator data.
3691 TransferResult - A pointer to the detailed result information generated
3692 by this control transfer.
3700 return EFI_UNSUPPORTED
;
3705 UsbVirtualHcAsyncIsochronousTransfer (
3706 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3707 IN UINT8 DeviceAddress
,
3708 IN UINT8 EndPointAddress
,
3709 IN UINT8 DeviceSpeed
,
3710 IN UINTN MaximumPacketLength
,
3711 IN UINT8 DataBuffersNumber
,
3712 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3713 IN UINTN DataLength
,
3714 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3715 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
3720 Routine Description:
3722 Vitual interface to submits Async isochronous transfer to a target USB device
3723 for both Hc2 and Hc protocol.
3727 UsbBusDev - A pointer to bus controller of the device.
3728 DeviceAddress - Represents the address of the target device on the USB,
3729 which is assigned during USB enumeration.
3730 EndPointAddress - End point address
3731 DeviceSpeed - Indicates device speed.
3732 MaximumPacketLength - Indicates the maximum packet size that the
3733 default control transfer endpoint is capable of
3734 sending or receiving.
3735 DataBuffersNumber - Number of data buffers prepared for the transfer.
3736 Data - Array of pointers to the buffers of data that will be transmitted
3737 to USB device or received from USB device.
3738 DataLength - Indicates the size, in bytes, of the data buffer
3740 Translator - A pointr to the transaction translator data.
3741 IsochronousCallBack - When the transfer complete, the call back function will be called
3742 Context - Pass to the call back function as parameter
3750 return EFI_UNSUPPORTED
;