3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27 GLOBAL_REMOVE_IF_UNREFERENCED UINTN gUSBDebugLevel
= EFI_D_INFO
;
28 GLOBAL_REMOVE_IF_UNREFERENCED UINTN gUSBErrorLevel
= EFI_D_ERROR
;
31 // The UsbBusProtocol is just used to locate USB_BUS_CONTROLLER
32 // structure in the UsbBusDriverControllerDriverStop(). Then we can
33 // Close all opened protocols and release this structure.
35 STATIC EFI_GUID mUsbBusProtocolGuid
= EFI_USB_BUS_PROTOCOL_GUID
;
40 // EFI_DRIVER_BINDING_PROTOCOL Protocol Interface
44 UsbBusControllerDriverSupported (
45 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
46 IN EFI_HANDLE Controller
,
47 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
52 UsbBusControllerDriverStart (
53 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
54 IN EFI_HANDLE Controller
,
55 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
60 UsbBusControllerDriverStop (
61 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
62 IN EFI_HANDLE Controller
,
63 IN UINTN NumberOfChildren
,
64 IN EFI_HANDLE
*ChildHandleBuffer
67 EFI_DRIVER_BINDING_PROTOCOL gUsbBusDriverBinding
= {
68 UsbBusControllerDriverSupported
,
69 UsbBusControllerDriverStart
,
70 UsbBusControllerDriverStop
,
82 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
83 IN EFI_STATUS_CODE_TYPE Type
,
84 IN EFI_STATUS_CODE_VALUE Code
91 InitializeUsbIoInstance (
92 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
96 USB_IO_CONTROLLER_DEVICE
*
97 CreateUsbIoControllerDevice (
103 InitUsbIoController (
104 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
108 // USB Device Configuration / Deconfiguration
112 UsbDeviceConfiguration (
113 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
114 IN EFI_HANDLE HostController
,
116 IN USB_IO_DEVICE
*UsbIoDevice
120 // Usb Bus enumeration function
138 UsbSetTransactionTranslator (
139 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
141 IN OUT USB_IO_DEVICE
*Device
146 UsbUnsetTransactionTranslator (
147 USB_IO_DEVICE
*Device
152 IdentifyDeviceSpeed (
153 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
154 USB_IO_DEVICE
*NewDevice
,
161 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
167 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
174 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
181 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
182 IN BOOLEAN ReConfigure
,
187 // Following are address allocate and free functions
192 IN UINT8
*AddressPool
197 Allocate address for usb device
200 AddressPool - Pool of usb device address
210 for (ByteIndex
= 0; ByteIndex
< 16; ByteIndex
++) {
211 for (BitIndex
= 0; BitIndex
< 8; BitIndex
++) {
212 if ((AddressPool
[ByteIndex
] & (1 << BitIndex
)) == 0) {
214 // Found one, covert to address, and mark it use
216 AddressPool
[ByteIndex
] |= (1 << BitIndex
);
217 return (UINT8
) (ByteIndex
* 8 + BitIndex
);
230 IN UINT8
*AddressPool
235 Free address for usb device
238 DevAddress - Usb device address
239 AddressPool - Pool of usb device address
249 // Locate the position
251 WhichByte
= (UINT8
) (DevAddress
/ 8);
252 WhichBit
= (UINT8
) (DevAddress
& 0x7);
254 AddressPool
[WhichByte
] &= (~(1 << WhichBit
));
259 UsbBusControllerDriverSupported (
260 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
261 IN EFI_HANDLE Controller
,
262 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
267 Test to see if this driver supports ControllerHandle. Any ControllerHandle
268 that has UsbHcProtocol installed will be supported.
271 This - Protocol instance pointer.
272 Controller - Handle of device to test
273 RemainingDevicePath - Device Path Protocol instance pointer
276 EFI_SUCCESS - This driver supports this device.
277 EFI_UNSUPPORTED - This driver does not support this device.
282 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
283 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
284 EFI_USB_HC_PROTOCOL
*UsbHc
;
285 EFI_DEV_PATH_PTR Node
;
290 if (RemainingDevicePath
!= NULL
) {
291 Node
.DevPath
= RemainingDevicePath
;
292 if (Node
.DevPath
->Type
!= MESSAGING_DEVICE_PATH
||
293 Node
.DevPath
->SubType
!= MSG_USB_DP
||
294 DevicePathNodeLength(Node
.DevPath
) != sizeof(USB_DEVICE_PATH
)) {
295 return EFI_UNSUPPORTED
;
300 // Open the IO Abstraction(s) needed to perform the supported test
302 Status
= gBS
->OpenProtocol (
304 &gEfiDevicePathProtocolGuid
,
305 (VOID
**) &ParentDevicePath
,
306 This
->DriverBindingHandle
,
308 EFI_OPEN_PROTOCOL_BY_DRIVER
310 if (Status
== EFI_ALREADY_STARTED
) {
314 if (EFI_ERROR (Status
)) {
320 &gEfiDevicePathProtocolGuid
,
321 This
->DriverBindingHandle
,
326 // Check whether USB Host Controller Protocol is already
327 // installed on this handle. If it is installed, we can start
328 // USB Bus Driver now.
330 Status
= gBS
->OpenProtocol (
332 &gEfiUsb2HcProtocolGuid
,
334 This
->DriverBindingHandle
,
336 EFI_OPEN_PROTOCOL_BY_DRIVER
338 if (Status
== EFI_ALREADY_STARTED
) {
342 if (EFI_ERROR (Status
)) {
343 Status
= gBS
->OpenProtocol (
345 &gEfiUsbHcProtocolGuid
,
347 This
->DriverBindingHandle
,
349 EFI_OPEN_PROTOCOL_BY_DRIVER
351 if (Status
== EFI_ALREADY_STARTED
) {
355 if (EFI_ERROR (Status
)) {
361 &gEfiUsbHcProtocolGuid
,
362 This
->DriverBindingHandle
,
370 &gEfiUsb2HcProtocolGuid
,
371 This
->DriverBindingHandle
,
380 UsbBusControllerDriverStart (
381 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
382 IN EFI_HANDLE Controller
,
383 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
389 Starting the Usb Bus Driver
393 This - Protocol instance pointer.
394 Controller - Handle of device to test
395 RemainingDevicePath - Not used
399 EFI_SUCCESS - This driver supports this device.
400 EFI_DEVICE_ERROR - This driver cannot be started due to device
401 EFI_OUT_OF_RESOURCES- Can't allocate memory resources
406 EFI_STATUS OpenStatus
;
407 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
408 USB_IO_DEVICE
*RootHub
;
409 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
412 UINT8 Is64BitCapable
;
415 // Allocate USB_BUS_CONTROLLER_DEVICE structure
418 UsbBusDev
= AllocateZeroPool (sizeof (USB_BUS_CONTROLLER_DEVICE
));
419 if (UsbBusDev
== NULL
) {
420 return EFI_OUT_OF_RESOURCES
;
423 UsbBusDev
->Signature
= USB_BUS_DEVICE_SIGNATURE
;
424 UsbBusDev
->AddressPool
[0] = 1;
427 // Get the Device Path Protocol on Controller's handle
429 OpenStatus
= gBS
->OpenProtocol (
431 &gEfiDevicePathProtocolGuid
,
432 (VOID
**) &UsbBusDev
->DevicePath
,
433 This
->DriverBindingHandle
,
435 EFI_OPEN_PROTOCOL_BY_DRIVER
438 if (EFI_ERROR (OpenStatus
)) {
439 gBS
->FreePool (UsbBusDev
);
443 // Locate the Host Controller Interface
445 OpenStatus
= gBS
->OpenProtocol (
447 &gEfiUsb2HcProtocolGuid
,
448 (VOID
**) &(UsbBusDev
->Usb2HCInterface
),
449 This
->DriverBindingHandle
,
451 EFI_OPEN_PROTOCOL_BY_DRIVER
453 if (EFI_ERROR (OpenStatus
)) {
455 UsbBusDev
->Hc2ProtocolSupported
= FALSE
;
456 OpenStatus
= gBS
->OpenProtocol (
458 &gEfiUsbHcProtocolGuid
,
459 (VOID
**) &(UsbBusDev
->UsbHCInterface
),
460 This
->DriverBindingHandle
,
462 EFI_OPEN_PROTOCOL_BY_DRIVER
464 if (EFI_ERROR (OpenStatus
)) {
466 // Report Status Code here since we will reset the host controller
468 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
469 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
470 EFI_IO_BUS_USB
| EFI_IOB_EC_CONTROLLER_ERROR
,
471 UsbBusDev
->DevicePath
476 &gEfiDevicePathProtocolGuid
,
477 This
->DriverBindingHandle
,
480 gBS
->FreePool (UsbBusDev
);
484 DEBUG ((gUSBDebugLevel
, "UsbHcProtocol Opened.\n"));
486 DEBUG ((gUSBDebugLevel
, "Usb2HcProtocol Opened.\n"));
487 UsbBusDev
->Hc2ProtocolSupported
= TRUE
;
491 // Attach EFI_USB_BUS_PROTOCOL to controller handle,
492 // for locate UsbBusDev later
494 Status
= gBS
->InstallProtocolInterface (
496 &mUsbBusProtocolGuid
,
497 EFI_NATIVE_INTERFACE
,
498 &UsbBusDev
->BusIdentify
501 if (EFI_ERROR (Status
)) {
505 &gEfiDevicePathProtocolGuid
,
506 This
->DriverBindingHandle
,
509 if (UsbBusDev
->Hc2ProtocolSupported
) {
512 &gEfiUsb2HcProtocolGuid
,
513 This
->DriverBindingHandle
,
519 &gEfiUsbHcProtocolGuid
,
520 This
->DriverBindingHandle
,
525 gBS
->FreePool (UsbBusDev
);
529 // Add root hub to the tree
532 RootHub
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
533 if (RootHub
== NULL
) {
534 gBS
->UninstallProtocolInterface (
536 &mUsbBusProtocolGuid
,
537 &UsbBusDev
->BusIdentify
541 &gEfiDevicePathProtocolGuid
,
542 This
->DriverBindingHandle
,
545 if (UsbBusDev
->Hc2ProtocolSupported
) {
548 &gEfiUsb2HcProtocolGuid
,
549 This
->DriverBindingHandle
,
555 &gEfiUsbHcProtocolGuid
,
556 This
->DriverBindingHandle
,
561 gBS
->FreePool (UsbBusDev
);
562 return EFI_OUT_OF_RESOURCES
;
565 RootHub
->BusController
= UsbBusDev
;
566 RootHub
->DeviceAddress
= UsbAllocateAddress (UsbBusDev
->AddressPool
);
568 UsbBusDev
->Root
= RootHub
;
571 // Allocate Root Hub Controller
573 RootHubController
= CreateUsbIoControllerDevice ();
574 if (RootHubController
== NULL
) {
575 gBS
->UninstallProtocolInterface (
577 &mUsbBusProtocolGuid
,
578 &UsbBusDev
->BusIdentify
582 &gEfiDevicePathProtocolGuid
,
583 This
->DriverBindingHandle
,
586 if (UsbBusDev
->Hc2ProtocolSupported
) {
589 &gEfiUsb2HcProtocolGuid
,
590 This
->DriverBindingHandle
,
596 &gEfiUsbHcProtocolGuid
,
597 This
->DriverBindingHandle
,
601 gBS
->FreePool (UsbBusDev
);
602 gBS
->FreePool (RootHub
);
603 return EFI_OUT_OF_RESOURCES
;
606 UsbVirtualHcGetCapability (
612 RootHubController
->DownstreamPorts
= PortNumber
;
613 RootHubController
->UsbDevice
= RootHub
;
614 RootHubController
->IsUsbHub
= TRUE
;
615 RootHubController
->DevicePath
= UsbBusDev
->DevicePath
;
616 RootHubController
->HostController
= Controller
;
618 RootHub
->NumOfControllers
= 1;
619 RootHub
->UsbController
[0] = RootHubController
;
620 RootHub
->DeviceSpeed
= MaxSpeed
;
623 // Report Status Code here since we will reset the host controller
625 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
627 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
,
628 UsbBusDev
->DevicePath
632 // Reset USB Host Controller
636 EFI_USB_HC_RESET_GLOBAL
640 // Report Status Code while we are going to bring up the Host Controller
641 // and start bus enumeration
643 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
645 EFI_IO_BUS_USB
| EFI_IOB_PC_ENABLE
,
646 UsbBusDev
->DevicePath
650 // Start USB Host Controller
652 UsbVirtualHcSetState (
654 EfiUsbHcStateOperational
658 // Create a timer to query root ports periodically
660 Status
= gBS
->CreateEvent (
661 EFI_EVENT_TIMER
| EFI_EVENT_NOTIFY_SIGNAL
,
665 &RootHubController
->HubNotify
667 if (EFI_ERROR (Status
)) {
668 gBS
->UninstallProtocolInterface (
670 &mUsbBusProtocolGuid
,
671 &UsbBusDev
->BusIdentify
676 &gEfiDevicePathProtocolGuid
,
677 This
->DriverBindingHandle
,
681 if (UsbBusDev
->Hc2ProtocolSupported
) {
684 &gEfiUsb2HcProtocolGuid
,
685 This
->DriverBindingHandle
,
691 &gEfiUsbHcProtocolGuid
,
692 This
->DriverBindingHandle
,
697 gBS
->FreePool (RootHubController
);
698 gBS
->FreePool (RootHub
);
699 gBS
->FreePool (UsbBusDev
);
700 return EFI_OUT_OF_RESOURCES
;
704 // Before depending on the timer to check root ports periodically,
705 // here we should check them immediately for the first time, or
706 // there will be an interval between bus start and devices start.
708 gBS
->SignalEvent (RootHubController
->HubNotify
);
710 Status
= gBS
->SetTimer (
711 RootHubController
->HubNotify
,
715 if (EFI_ERROR (Status
)) {
716 gBS
->UninstallProtocolInterface (
718 &mUsbBusProtocolGuid
,
719 &UsbBusDev
->BusIdentify
724 &gEfiDevicePathProtocolGuid
,
725 This
->DriverBindingHandle
,
729 if (UsbBusDev
->Hc2ProtocolSupported
) {
732 &gEfiUsb2HcProtocolGuid
,
733 This
->DriverBindingHandle
,
739 &gEfiUsbHcProtocolGuid
,
740 This
->DriverBindingHandle
,
745 gBS
->CloseEvent (RootHubController
->HubNotify
);
746 gBS
->FreePool (RootHubController
);
747 gBS
->FreePool (RootHub
);
748 gBS
->FreePool (UsbBusDev
);
749 return EFI_DEVICE_ERROR
;
756 // Stop the bus controller
760 UsbBusControllerDriverStop (
761 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
762 IN EFI_HANDLE Controller
,
763 IN UINTN NumberOfChildren
,
764 IN EFI_HANDLE
*ChildHandleBuffer
769 Stop this driver on ControllerHandle. Support stoping any child handles
770 created by this driver.
773 This - Protocol instance pointer.
774 Controller - Handle of device to stop driver on
775 NumberOfChildren - Number of Children in the ChildHandleBuffer
776 ChildHandleBuffer - List of handles for the children we need to stop.
787 USB_IO_CONTROLLER_DEVICE
*RootHubController
;
788 USB_BUS_CONTROLLER_DEVICE
*UsbBusController
;
789 EFI_USB_BUS_PROTOCOL
*UsbIdentifier
;
791 USB_IO_CONTROLLER_DEVICE
*UsbController
;
792 USB_IO_DEVICE
*UsbIoDevice
;
793 USB_IO_CONTROLLER_DEVICE
*HubController
;
795 EFI_USB_IO_PROTOCOL
*UsbIo
;
797 if (NumberOfChildren
> 0) {
799 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
800 Status
= gBS
->OpenProtocol (
801 ChildHandleBuffer
[Index
],
802 &gEfiUsbIoProtocolGuid
,
804 This
->DriverBindingHandle
,
806 EFI_OPEN_PROTOCOL_GET_PROTOCOL
808 if (EFI_ERROR (Status
)) {
810 // We are here since the handle passed in does not support
811 // UsbIo protocol. There are several reasons that will cause
813 // For combo device such as keyboard, it may have 2 devices
814 // in one, namely, keyboard and mouse. If we deconfigure one
815 // of them, the other will be freed at the same time. This will
816 // cause the status error. But this is the correct behavior.
817 // For hub device, if we deconfigure hub first, the other chile
818 // device will be disconnected also, this will also provide us
819 // a status error. Now we will only report EFI_SUCCESS since Uhc
820 // driver will be disconnected at the second time.(pls see
821 // CoreDisconnectController for details)
826 UsbController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (UsbIo
);
827 UsbIoDevice
= UsbController
->UsbDevice
;
828 HubController
= UsbController
->Parent
;
829 UsbDeviceDeConfiguration (UsbIoDevice
);
830 for (Index2
= 0; Index2
< HubController
->DownstreamPorts
; Index2
++) {
831 if (HubController
->Children
[Index2
] == UsbIoDevice
) {
832 HubController
->Children
[Index2
] = NULL
;
840 // Get the USB_BUS_CONTROLLER_DEVICE
842 Status
= gBS
->OpenProtocol (
844 &mUsbBusProtocolGuid
,
845 (VOID
**) &UsbIdentifier
,
846 This
->DriverBindingHandle
,
848 EFI_OPEN_PROTOCOL_GET_PROTOCOL
851 if (EFI_ERROR (Status
)) {
852 return EFI_DEVICE_ERROR
;
855 UsbBusController
= USB_BUS_CONTROLLER_DEVICE_FROM_THIS (UsbIdentifier
);
858 // Stop USB Host Controller
862 // Report Status Code here since we will reset the host controller
864 ReportUsbStatusCode (
867 EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
870 UsbVirtualHcSetState (
876 // Deconfiguration all its devices
878 Root
= UsbBusController
->Root
;
879 RootHubController
= Root
->UsbController
[0];
881 gBS
->CloseEvent (RootHubController
->HubNotify
);
883 for (Index2
= 0; Index2
< RootHubController
->DownstreamPorts
; Index2
++) {
884 if (RootHubController
->Children
[Index2
]) {
885 UsbDeviceDeConfiguration (RootHubController
->Children
[Index2
]);
886 RootHubController
->Children
[Index2
] = NULL
;
890 gBS
->FreePool (RootHubController
);
891 gBS
->FreePool (Root
);
894 // Uninstall USB Bus Protocol
896 gBS
->UninstallProtocolInterface (
898 &mUsbBusProtocolGuid
,
899 &UsbBusController
->BusIdentify
903 // Close USB_HC_PROTOCOL & DEVICE_PATH_PROTOCOL
904 // Opened by this Controller
906 if (UsbBusController
->Hc2ProtocolSupported
) {
909 &gEfiUsb2HcProtocolGuid
,
910 This
->DriverBindingHandle
,
916 &gEfiUsbHcProtocolGuid
,
917 This
->DriverBindingHandle
,
924 &gEfiDevicePathProtocolGuid
,
925 This
->DriverBindingHandle
,
929 gBS
->FreePool (UsbBusController
);
934 // USB Device Configuration
938 UsbDeviceConfiguration (
939 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
940 IN EFI_HANDLE HostController
,
942 IN USB_IO_DEVICE
*UsbIoDevice
947 Configurate a new device attached to the usb bus
950 ParentHubController - Parent Hub which this device is connected.
951 HostController - Host Controller handle
952 ParentPort - Parent Hub port which this device is connected.
953 UsbIoDevice - The device to be configured.
966 CHAR16
*StrManufacturer
;
968 CHAR16
*StrSerialNumber
;
969 EFI_USB_IO_PROTOCOL
*UsbIo
;
970 UINT8 NumOfInterface
;
971 USB_IO_CONTROLLER_DEVICE
*FirstController
;
972 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
973 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
975 UsbBusDev
= UsbIoDevice
->BusController
;
977 UsbSetTransactionTranslator (
984 // Since a USB device must have at least on interface,
985 // so create this instance first
987 FirstController
= CreateUsbIoControllerDevice ();
988 FirstController
->UsbDevice
= UsbIoDevice
;
989 UsbIoDevice
->UsbController
[0] = FirstController
;
990 FirstController
->InterfaceNumber
= 0;
991 FirstController
->ParentPort
= ParentPort
;
992 FirstController
->Parent
= ParentHubController
;
993 FirstController
->HostController
= HostController
;
995 InitializeUsbIoInstance (FirstController
);
997 DEBUG ((gUSBDebugLevel
, "Configuration Usb Device at 0x%x...\n", ParentPort
));
1000 // Ensure we used the correctly USB I/O instance
1002 UsbIo
= &FirstController
->UsbIo
;
1004 if (UsbIoDevice
->DeviceSpeed
!= EFI_USB_SPEED_HIGH
) {
1005 ParentPortReset (FirstController
, FALSE
, 0);
1009 // First retrieve the 1st 8 bytes of
1010 // in order to get the MaxPacketSize for Endpoint 0
1012 for (Index
= 0; Index
< 3; Index
++) {
1014 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1016 gBS
->Stall (100 * 1000);
1018 Result
= UsbGetDescriptor (
1020 (USB_DT_DEVICE
<< 8),
1023 &UsbIoDevice
->DeviceDescriptor
,
1026 if (!EFI_ERROR (Result
)) {
1029 "Get Device Descriptor Success, MaxPacketSize0 = 0x%x\n",
1030 UsbIoDevice
->DeviceDescriptor
.MaxPacketSize0
)
1038 ReportUsbStatusCode (
1040 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1041 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1043 DEBUG ((gUSBErrorLevel
, "Get Device Descriptor Fail when configing\n"));
1044 gBS
->FreePool (FirstController
);
1045 return EFI_DEVICE_ERROR
;
1048 DevAddress
= UsbAllocateAddress (UsbIoDevice
->BusController
->AddressPool
);
1049 if (DevAddress
== 0) {
1050 DEBUG ((gUSBErrorLevel
, "Cannot allocate address\n"));
1051 gBS
->FreePool (FirstController
);
1052 return EFI_OUT_OF_RESOURCES
;
1055 Result
= UsbSetDeviceAddress (UsbIo
, DevAddress
, &Status
);
1057 if (EFI_ERROR (Result
)) {
1058 DEBUG ((gUSBErrorLevel
, "Set address error\n"));
1059 ReportUsbStatusCode (
1061 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1062 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1067 UsbIoDevice
->BusController
->AddressPool
1070 gBS
->FreePool (FirstController
);
1071 return EFI_DEVICE_ERROR
;
1074 UsbIoDevice
->DeviceAddress
= DevAddress
;
1077 // SetAddress Complete Time by Spec, Max 50ms
1079 gBS
->Stall (10 * 1000);
1082 // Get the whole device descriptor
1084 Result
= UsbGetDescriptor (
1086 (USB_DT_DEVICE
<< 8),
1088 sizeof (EFI_USB_DEVICE_DESCRIPTOR
),
1089 &UsbIoDevice
->DeviceDescriptor
,
1093 if (EFI_ERROR (Result
)) {
1094 DEBUG ((gUSBErrorLevel
, "Get whole Device Descriptor error\n"));
1095 ReportUsbStatusCode (
1097 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1098 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1102 UsbIoDevice
->BusController
->AddressPool
1105 gBS
->FreePool (FirstController
);
1106 return EFI_DEVICE_ERROR
;
1109 // Get & parse all configurations for this device, including
1110 // all configuration descriptors, all interface descriptors, all
1111 // endpoint descriptors
1113 Result
= UsbGetAllConfigurations (UsbIoDevice
);
1115 if (EFI_ERROR (Result
)) {
1116 DEBUG ((gUSBErrorLevel
, "Failed to get device configuration\n"));
1117 ReportUsbStatusCode (
1119 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1120 EFI_IO_BUS_USB
| EFI_IOB_EC_READ_ERROR
1124 UsbIoDevice
->BusController
->AddressPool
1127 gBS
->FreePool (FirstController
);
1128 return EFI_DEVICE_ERROR
;
1131 // Set the 1st configuration value
1133 Result
= UsbSetDefaultConfiguration (UsbIoDevice
);
1134 if (EFI_ERROR (Result
)) {
1135 DEBUG ((gUSBErrorLevel
, "Failed to set device configuration\n"));
1136 ReportUsbStatusCode (
1138 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1139 EFI_IO_BUS_USB
| EFI_IOB_EC_WRITE_ERROR
1143 UsbIoDevice
->BusController
->AddressPool
1146 gBS
->FreePool (FirstController
);
1147 return EFI_DEVICE_ERROR
;
1150 UsbIoDevice
->IsConfigured
= TRUE
;
1153 // Get all string table if applicable
1155 Result
= UsbGetStringtable (UsbIoDevice
);
1156 if (EFI_ERROR (Result
)) {
1157 DEBUG ((gUSBDebugLevel
, "Device doesn't support string table\n"));
1160 StrManufacturer
= NULL
;
1161 UsbIo
->UsbGetStringDescriptor (
1163 UsbIoDevice
->LangID
[0],
1164 (UsbIoDevice
->DeviceDescriptor
).StrManufacturer
,
1169 UsbIo
->UsbGetStringDescriptor (
1171 UsbIoDevice
->LangID
[0],
1172 (UsbIoDevice
->DeviceDescriptor
).StrProduct
,
1176 StrSerialNumber
= NULL
;
1177 UsbIo
->UsbGetStringDescriptor (
1179 UsbIoDevice
->LangID
[0],
1180 (UsbIoDevice
->DeviceDescriptor
).StrSerialNumber
,
1184 if (StrManufacturer
) {
1185 gBS
->FreePool (StrManufacturer
);
1189 gBS
->FreePool (StrProduct
);
1192 if (StrSerialNumber
) {
1193 gBS
->FreePool (StrSerialNumber
);
1197 // Create USB_IO_CONTROLLER_DEVICE for
1198 // each detected interface
1200 FirstController
->CurrentConfigValue
=
1201 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1204 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.NumInterfaces
;
1205 UsbIoDevice
->NumOfControllers
= NumOfInterface
;
1207 Result
= InitUsbIoController (FirstController
);
1208 if (EFI_ERROR (Result
)) {
1209 ReportUsbStatusCode (
1211 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1212 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1214 gBS
->FreePool (FirstController
);
1215 UsbIoDevice
->UsbController
[0] = NULL
;
1216 return EFI_DEVICE_ERROR
;
1219 for (Index
= 1; Index
< NumOfInterface
; Index
++) {
1220 UsbIoController
= CreateUsbIoControllerDevice ();
1221 UsbIoController
->UsbDevice
= UsbIoDevice
;
1222 UsbIoController
->CurrentConfigValue
=
1223 UsbIoDevice
->ActiveConfig
->CongfigDescriptor
.ConfigurationValue
;
1224 UsbIoController
->InterfaceNumber
= Index
;
1225 UsbIoDevice
->UsbController
[Index
] = UsbIoController
;
1226 UsbIoController
->ParentPort
= ParentPort
;
1227 UsbIoController
->Parent
= ParentHubController
;
1228 UsbIoController
->HostController
= HostController
;
1231 // First copy the USB_IO Protocol instance
1234 &UsbIoController
->UsbIo
,
1236 sizeof (EFI_USB_IO_PROTOCOL
)
1239 Result
= InitUsbIoController (UsbIoController
);
1240 if (EFI_ERROR (Result
)) {
1241 ReportUsbStatusCode (
1243 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1244 EFI_IO_BUS_USB
| EFI_IOB_EC_INTERFACE_ERROR
1246 gBS
->FreePool (UsbIoController
);
1247 UsbIoDevice
->UsbController
[Index
] = NULL
;
1254 // USB Device DeConfiguration
1257 UsbDeviceDeConfiguration (
1258 IN USB_IO_DEVICE
*UsbIoDevice
1262 Routine Description:
1263 Remove Device, Device Handles, Uninstall Protocols.
1266 UsbIoDevice - The device to be deconfigured.
1274 USB_IO_CONTROLLER_DEVICE
*UsbController
;
1276 USB_IO_DEVICE
*ChildDevice
;
1278 EFI_USB_IO_PROTOCOL
*UsbIo
;
1281 // Double check UsbIoDevice exists
1283 if (UsbIoDevice
== NULL
) {
1287 UsbUnsetTransactionTranslator (UsbIoDevice
);
1289 for (index
= 0; index
< UsbIoDevice
->NumOfControllers
; index
++) {
1291 // Check if it is a hub, if so, de configuration all its
1294 UsbController
= UsbIoDevice
->UsbController
[index
];
1297 // Check the controller pointer
1299 if (UsbController
== NULL
) {
1303 if (UsbController
->IsUsbHub
) {
1305 DEBUG ((gUSBDebugLevel
, "Hub Deconfig, First Deconfig its downstream ports\n"));
1308 // First Remove interrupt transfer request for the status
1311 UsbIo
= &UsbController
->UsbIo
;
1312 UsbIo
->UsbAsyncInterruptTransfer (
1314 UsbController
->HubEndpointAddress
,
1322 if (NULL
!= UsbController
->HubNotify
) {
1323 gBS
->CloseEvent (UsbController
->HubNotify
);
1326 for (Index
= 0; Index
< UsbController
->DownstreamPorts
; Index
++) {
1327 if (UsbController
->Children
[Index
]) {
1328 ChildDevice
= UsbController
->Children
[Index
];
1329 UsbDeviceDeConfiguration (ChildDevice
);
1330 UsbController
->Children
[Index
] = NULL
;
1335 // If the controller is managed by a device driver, we need to
1338 if (UsbController
->IsManagedByDriver
) {
1339 gBS
->DisconnectController (
1340 UsbController
->Handle
,
1347 // remove child handle reference to the USB_HC_PROTOCOL
1349 if (UsbIoDevice
->BusController
->Hc2ProtocolSupported
) {
1350 gBS
->CloseProtocol (
1351 UsbController
->HostController
,
1352 &gEfiUsb2HcProtocolGuid
,
1353 gUsbBusDriverBinding
.DriverBindingHandle
,
1354 UsbController
->Handle
1357 gBS
->CloseProtocol (
1358 UsbController
->HostController
,
1359 &gEfiUsbHcProtocolGuid
,
1360 gUsbBusDriverBinding
.DriverBindingHandle
,
1361 UsbController
->Handle
1365 // Uninstall EFI_USB_IO_PROTOCOL & DEVICE_PATH_PROTOCOL
1366 // installed on this handle
1368 gBS
->UninstallMultipleProtocolInterfaces (
1369 UsbController
->Handle
,
1370 &gEfiDevicePathProtocolGuid
,
1371 UsbController
->DevicePath
,
1372 &gEfiUsbIoProtocolGuid
,
1373 &UsbController
->UsbIo
,
1377 if (UsbController
->DevicePath
!= NULL
) {
1378 gBS
->FreePool (UsbController
->DevicePath
);
1381 gBS
->FreePool (UsbController
);
1382 UsbIoDevice
->UsbController
[index
] = NULL
;
1385 // Free address for later use
1388 UsbIoDevice
->DeviceAddress
,
1389 UsbIoDevice
->BusController
->AddressPool
1393 // Free all resouces allocated for all its configurations
1395 UsbDestroyAllConfiguration (UsbIoDevice
);
1398 gBS
->FreePool (UsbIoDevice
);
1405 // After interrupt complete, this function will be called,
1406 // This function need to be well-defined later
1411 OnHubInterruptComplete (
1413 IN UINTN DataLength
,
1419 Routine Description:
1420 Whenever hub interrupt occurs, this routine will be called to check
1421 which event happens.
1424 Data - Hub interrupt transfer data.
1425 DataLength - The length of the Data.
1426 Context - Hub Controller Device.
1427 Result - Hub interrupt transfer status.
1435 USB_IO_CONTROLLER_DEVICE
*HubController
;
1438 EFI_USB_IO_PROTOCOL
*UsbIo
;
1440 BOOLEAN Disconnected
;
1443 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1444 UsbIo
= &HubController
->UsbIo
;
1447 // If something error in this interrupt transfer,
1449 if (Result
!= EFI_USB_NOERROR
) {
1450 if ((Result
& EFI_USB_ERR_STALL
) == EFI_USB_ERR_STALL
) {
1451 UsbClearEndpointHalt (
1453 HubController
->HubEndpointAddress
,
1459 // Delete & Submit this interrupt again
1461 UsbIo
->UsbAsyncInterruptTransfer (
1463 HubController
->HubEndpointAddress
,
1472 // try to detect if the hub itself was disconnected or not
1474 Status
= IsDeviceDisconnected (
1479 if (!EFI_ERROR (Status
) && Disconnected
== TRUE
) {
1480 DEBUG ((gUSBErrorLevel
, "Hub is disconnected\n"));
1481 return EFI_DEVICE_ERROR
;
1486 UsbIo
->UsbAsyncInterruptTransfer (
1488 HubController
->HubEndpointAddress
,
1492 OnHubInterruptComplete
,
1496 return EFI_DEVICE_ERROR
;
1499 if (DataLength
== 0 || Data
== NULL
) {
1504 // Scan which port has status change
1505 // Bit 0 stands for hub itself, other bit stands for
1506 // the corresponding port
1508 for (Index
= 0; Index
< DataLength
* 8; Index
++) {
1509 ptr
= (UINT8
*) Data
+ Index
/ 8;
1510 if ((*ptr
) & (1 << (Index
& 0x7))) {
1511 HubController
->StatusChangePort
= Index
;
1516 // Signal hub notify event
1518 gBS
->SignalEvent (HubController
->HubNotify
);
1523 // USB Root Hub Enumerator
1528 RootHubEnumeration (
1534 Routine Description:
1536 This is USB RootHub enumerator
1540 Event - Indicating which event is signaled
1541 Context - actually it is a USB_IO_DEVICE
1549 USB_IO_CONTROLLER_DEVICE
*HubController
;
1550 EFI_USB_PORT_STATUS HubPortStatus
;
1553 USB_IO_DEVICE
*UsbIoDev
;
1554 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1555 EFI_HANDLE HostController
;
1556 USB_IO_DEVICE
*OldUsbIoDevice
;
1557 USB_IO_DEVICE
*NewDevice
;
1558 USB_IO_CONTROLLER_DEVICE
*NewController
;
1560 EFI_USB_IO_PROTOCOL
*UsbIo
;
1562 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1563 HostController
= HubController
->HostController
;
1564 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1567 // Root hub has the address 1
1569 UsbIoDev
= HubController
->UsbDevice
;
1571 for (Index
= 0; Index
< HubController
->DownstreamPorts
; Index
++) {
1573 UsbVirtualHcGetRootHubPortStatus (
1576 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1579 if (!IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1583 // Clear root hub status change status
1585 UsbVirtualHcClearRootHubPortFeature (
1588 EfiUsbPortConnectChange
1591 gBS
->Stall (100 * 1000);
1593 UsbVirtualHcGetRootHubPortStatus (
1596 (EFI_USB_PORT_STATUS
*) &HubPortStatus
1599 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1602 // There is something connected to this port
1604 DEBUG ((gUSBDebugLevel
, "Something connected to Root Hub at Port0x%x\n", Index
));
1606 ReportUsbStatusCode (
1609 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1612 // if there is something physically detached, but still logically
1615 OldUsbIoDevice
= HubController
->Children
[Index
];
1617 if (NULL
!= OldUsbIoDevice
) {
1618 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1619 HubController
->Children
[Index
] = NULL
;
1622 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1623 if (NewDevice
== NULL
) {
1627 // Initialize some fields by copying data from
1630 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1631 NewDevice
->BusController
= UsbIoDev
->BusController
;
1634 // Process of identify device speed
1636 Status
= IdentifyDeviceSpeed (
1641 if (EFI_ERROR (Status
)) {
1642 gBS
->FreePool (NewDevice
);
1647 // Configure that device
1649 Status
= UsbDeviceConfiguration (
1655 if (EFI_ERROR (Status
)) {
1656 gBS
->FreePool (NewDevice
);
1660 // Add this device to the usb bus tree
1662 HubController
->Children
[Index
] = NewDevice
;
1664 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
1666 // If this device is hub, add to the hub index
1668 NewController
= NewDevice
->UsbController
[Index2
];
1670 Status
= gBS
->ConnectController (
1671 NewController
->Handle
,
1677 // If connect success, we need to disconnect when
1678 // stop the controller, otherwise we need not call
1679 // gBS->DisconnectController ()
1680 // This is used by those usb devices we don't plan
1681 // to support. We can allocate
1682 // controller handles for them, but we don't have
1683 // device drivers to manage them.
1685 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
1687 if (IsHub (NewController
)) {
1689 NewController
->IsUsbHub
= TRUE
;
1692 // Configure Hub Controller
1694 Status
= DoHubConfig (NewController
);
1695 if (EFI_ERROR (Status
)) {
1699 // Create an event to do hub enumeration
1702 EFI_EVENT_NOTIFY_SIGNAL
,
1706 &NewController
->HubNotify
1710 // Add request to do query hub status
1714 UsbIo
= &NewController
->UsbIo
;
1715 UsbIo
->UsbAsyncInterruptTransfer (
1717 NewController
->HubEndpointAddress
,
1721 OnHubInterruptComplete
,
1729 // Something disconnected from USB root hub
1731 DEBUG ((gUSBDebugLevel
, "Something disconnected from Root Hub at Port0x%x\n", Index
));
1733 OldUsbIoDevice
= HubController
->Children
[Index
];
1735 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1737 HubController
->Children
[Index
] = NULL
;
1739 UsbVirtualHcClearRootHubPortFeature (
1742 EfiUsbPortEnableChange
1750 // USB Root Hub Enumerator
1761 Routine Description:
1763 This is Usb Hub enumerator
1767 Event - Indicating which event is signaled
1768 Context - actually it is a USB_IO_DEVICE
1776 USB_IO_CONTROLLER_DEVICE
*HubController
;
1777 EFI_USB_PORT_STATUS HubPortStatus
;
1779 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
;
1780 EFI_HANDLE HostController
;
1781 USB_IO_DEVICE
*OldUsbIoDevice
;
1782 USB_IO_DEVICE
*NewDevice
;
1783 USB_IO_CONTROLLER_DEVICE
*NewController
;
1785 EFI_USB_IO_PROTOCOL
*UsbIo
;
1786 UINT8 StatusChangePort
;
1789 HubController
= (USB_IO_CONTROLLER_DEVICE
*) Context
;
1790 HostController
= HubController
->HostController
;
1791 UsbBusDev
= HubController
->UsbDevice
->BusController
;
1794 // Event from Hub, Get the hub controller handle
1797 // Get the status change endpoint
1799 StatusChangePort
= HubController
->StatusChangePort
;
1802 // Clear HubController Status Change Bit
1804 HubController
->StatusChangePort
= 0;
1806 if (StatusChangePort
== 0) {
1808 // Hub changes, we don't handle here
1813 // Check which event took place at that port
1815 UsbIo
= &HubController
->UsbIo
;
1816 Status
= HubGetPortStatus (
1819 (UINT32
*) &HubPortStatus
1822 if (EFI_ERROR (Status
)) {
1826 // Clear some change status
1828 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
1830 // Clear Hub port enable change
1832 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
1833 HubClearPortFeature (
1836 EfiUsbPortEnableChange
1842 (UINT32
*) &HubPortStatus
1846 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
1848 // Clear Hub reset change
1850 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
1851 HubClearPortFeature (
1854 EfiUsbPortResetChange
1860 (UINT32
*) &HubPortStatus
1864 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_OVERCURRENT
) {
1866 // Clear Hub overcurrent change
1868 DEBUG ((gUSBDebugLevel
, "Port Overcurrent Change\n"));
1869 HubClearPortFeature (
1872 EfiUsbPortOverCurrentChange
1878 (UINT32
*) &HubPortStatus
1882 if (IsPortConnectChange (HubPortStatus
.PortChangeStatus
)) {
1884 // First clear port connection change
1886 DEBUG ((gUSBDebugLevel
, "Port Connection Change\n"));
1887 HubClearPortFeature (
1890 EfiUsbPortConnectChange
1896 (UINT32
*) &HubPortStatus
1899 if (IsPortConnect (HubPortStatus
.PortStatus
)) {
1901 DEBUG ((gUSBDebugLevel
, "New Device Connect on Hub port \n"));
1903 ReportUsbStatusCode (
1906 EFI_IO_BUS_USB
| EFI_IOB_PC_HOTPLUG
1910 // if there is something physically detached, but still logically
1913 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
1915 if (NULL
!= OldUsbIoDevice
) {
1916 UsbDeviceDeConfiguration (OldUsbIoDevice
);
1917 HubController
->Children
[StatusChangePort
- 1] = NULL
;
1920 NewDevice
= AllocateZeroPool (sizeof (USB_IO_DEVICE
));
1921 if (NewDevice
== NULL
) {
1925 // Initialize some fields
1927 NewDevice
->DeviceDescriptor
.MaxPacketSize0
= 8;
1928 NewDevice
->BusController
= HubController
->UsbDevice
->BusController
;
1931 // There is something connected to this port,
1934 // Disable the enable bit in port status
1936 HubClearPortFeature (
1942 gBS
->Stall (50 * 1000);
1945 // Wait for bit change
1952 (UINT32
*) &HubPortStatus
1954 gBS
->Stall (10 * 1000);
1956 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_ENABLE
) == 1 && Number
> 0);
1960 // Cannot disable port, return error
1962 DEBUG ((gUSBErrorLevel
, "Disable Port Failed\n"));
1963 gBS
->FreePool (NewDevice
);
1973 gBS
->Stall (50 * 1000);
1976 // Wait for port reset complete
1983 (UINT32
*) &HubPortStatus
1985 gBS
->Stall (10 * 1000);
1987 } while ((HubPortStatus
.PortStatus
& USB_PORT_STAT_RESET
) == 1 && Number
> 0);
1991 // Cannot reset port, return error
1993 DEBUG ((gUSBErrorLevel
, "Reset Port Failed\n"));
1994 gBS
->FreePool (NewDevice
);
1998 // Check high speed or full speed device
2000 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
2001 DEBUG ((gUSBDebugLevel
, "Low Speed Device Attached to Hub\n"));
2002 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
2003 } else if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2004 DEBUG ((gUSBDebugLevel
, "High Speed Device Attached to Hub\n"));
2005 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2007 DEBUG ((gUSBDebugLevel
, "Full Speed Device Attached to Hub\n"));
2008 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2011 // Configure that device
2013 Status
= UsbDeviceConfiguration (
2016 (UINT8
) (StatusChangePort
- 1),
2020 if (EFI_ERROR (Status
)) {
2021 gBS
->FreePool (NewDevice
);
2025 // Add this device to the usb bus tree
2026 // StatusChangePort is begin from 1,
2028 HubController
->Children
[StatusChangePort
- 1] = NewDevice
;
2030 for (Index2
= 0; Index2
< NewDevice
->NumOfControllers
; Index2
++) {
2032 // If this device is hub, add to the hub index
2034 NewController
= NewDevice
->UsbController
[Index2
];
2037 // Connect the controller to the driver image
2039 Status
= gBS
->ConnectController (
2040 NewController
->Handle
,
2046 // If connect success, we need to disconnect when
2047 // stop the controller, otherwise we need not call
2048 // gBS->DisconnectController ()
2049 // This is used by those usb devices we don't plan
2050 // to support. We can allocate
2051 // controller handles for them, but we don't have
2052 // device drivers to manage them.
2054 NewController
->IsManagedByDriver
= (BOOLEAN
) (!EFI_ERROR (Status
));
2057 // If this device is hub, add to the hub index
2059 if (IsHub (NewController
)) {
2061 NewController
->IsUsbHub
= TRUE
;
2066 Status
= DoHubConfig (NewController
);
2068 if (EFI_ERROR (Status
)) {
2072 // Create an event to do hub enumeration
2075 EFI_EVENT_NOTIFY_SIGNAL
,
2079 &NewController
->HubNotify
2083 // Add request to do query hub status
2086 UsbIo
= &NewController
->UsbIo
;
2087 UsbIo
->UsbAsyncInterruptTransfer (
2089 NewController
->HubEndpointAddress
, // Hub endpoint address
2093 OnHubInterruptComplete
,
2100 // Something disconnected from USB hub
2102 DEBUG ((gUSBDebugLevel
, "Something Device Detached on Hub port\n"));
2104 OldUsbIoDevice
= HubController
->Children
[StatusChangePort
- 1];
2106 UsbDeviceDeConfiguration (OldUsbIoDevice
);
2108 HubController
->Children
[StatusChangePort
- 1] = NULL
;
2119 USB_IO_CONTROLLER_DEVICE
*
2120 CreateUsbIoControllerDevice (
2125 Routine Description:
2126 Allocate a structure for USB_IO_CONTROLLER_DEVICE
2132 A pointer to a USB_IO_CONTROLLER_DEVICE structure,
2137 USB_IO_CONTROLLER_DEVICE
*UsbIoControllerDev
;
2140 // Allocate USB_IO_CONTROLLER_DEVICE structure
2142 UsbIoControllerDev
= NULL
;
2143 UsbIoControllerDev
= AllocateZeroPool (sizeof (USB_IO_CONTROLLER_DEVICE
));
2145 if (UsbIoControllerDev
== NULL
) {
2149 UsbIoControllerDev
->Signature
= USB_IO_CONTROLLER_SIGNATURE
;
2151 return UsbIoControllerDev
;
2156 InitUsbIoController (
2157 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
2161 Routine Description:
2162 Init and install EFI_USB_IO_PROTOCOL onto that controller.
2165 UsbIoController - The Controller to be operated.
2173 USB_DEVICE_PATH UsbNode
;
2175 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
2176 EFI_USB_HC_PROTOCOL
*UsbHcProtocol
;
2177 EFI_USB2_HC_PROTOCOL
*Usb2HcProtocol
;
2180 // Build the child device path for each new USB_IO device
2182 ZeroMem (&UsbNode
, sizeof (UsbNode
));
2183 UsbNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
2184 UsbNode
.Header
.SubType
= MSG_USB_DP
;
2185 SetDevicePathNodeLength (&UsbNode
.Header
, sizeof (UsbNode
));
2186 UsbNode
.InterfaceNumber
= UsbIoController
->InterfaceNumber
;
2187 UsbNode
.ParentPortNumber
= UsbIoController
->ParentPort
;
2188 ParentDevicePath
= UsbIoController
->Parent
->DevicePath
;
2190 UsbIoController
->DevicePath
=
2191 AppendDevicePathNode (ParentDevicePath
, &UsbNode
.Header
);
2192 if (UsbIoController
->DevicePath
== NULL
) {
2193 return EFI_OUT_OF_RESOURCES
;
2196 Status
= gBS
->InstallMultipleProtocolInterfaces (
2197 &UsbIoController
->Handle
,
2198 &gEfiDevicePathProtocolGuid
,
2199 UsbIoController
->DevicePath
,
2200 &gEfiUsbIoProtocolGuid
,
2201 &UsbIoController
->UsbIo
,
2205 if (EFI_ERROR (Status
)) {
2209 if (UsbIoController
->UsbDevice
->BusController
->Hc2ProtocolSupported
) {
2210 Status
= gBS
->OpenProtocol (
2211 UsbIoController
->HostController
,
2212 &gEfiUsb2HcProtocolGuid
,
2213 (VOID
**)&Usb2HcProtocol
,
2214 gUsbBusDriverBinding
.DriverBindingHandle
,
2215 UsbIoController
->Handle
,
2216 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2219 Status
= gBS
->OpenProtocol (
2220 UsbIoController
->HostController
,
2221 &gEfiUsbHcProtocolGuid
,
2222 (VOID
**)&UsbHcProtocol
,
2223 gUsbBusDriverBinding
.DriverBindingHandle
,
2224 UsbIoController
->Handle
,
2225 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
2235 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2236 IN BOOLEAN ReConfigure
,
2241 Routine Description:
2242 Reset parent hub port to which this device is connected.
2245 UsbIoController - Indicating the Usb Controller Device.
2246 ReConfigure - Do we need to reconfigure it.
2247 RetryTimes - Retry Times when failed
2255 USB_IO_DEVICE
*ParentIoDev
;
2256 USB_IO_DEVICE
*UsbIoDev
;
2257 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2261 EFI_USB_IO_PROTOCOL
*UsbIo
;
2264 ParentController
= UsbIoController
->Parent
;
2265 ParentIoDev
= ParentController
->UsbDevice
;
2266 UsbIoDev
= UsbIoController
->UsbDevice
;
2267 HubPort
= UsbIoController
->ParentPort
;
2269 gBS
->Stall (100 * 1000);
2271 if (ParentIoDev
->DeviceAddress
== 1) {
2272 DEBUG ((gUSBDebugLevel
, "Reset from Root Hub 0x%x\n", HubPort
));
2273 ResetRootPort (ParentIoDev
->BusController
, HubPort
, RetryTimes
);
2275 DEBUG ((gUSBDebugLevel
, "Reset from Hub, Addr 0x%x\n", ParentIoDev
->DeviceAddress
));
2276 ResetHubPort (ParentController
, HubPort
+ 1);
2279 // If we only need port reset, just return
2285 // Re-config that USB device
2287 UsbIo
= &UsbIoController
->UsbIo
;
2290 // Assign a unique address to this device
2292 Address
= UsbIoDev
->DeviceAddress
;
2293 UsbIoDev
->DeviceAddress
= 0;
2295 Result
= UsbSetDeviceAddress (UsbIo
, Address
, &Status
);
2296 UsbIoDev
->DeviceAddress
= Address
;
2298 if (EFI_ERROR (Result
)) {
2299 return EFI_DEVICE_ERROR
;
2302 // Set the device to the default configuration
2304 Result
= UsbSetDefaultConfiguration (UsbIoDev
);
2305 if (EFI_ERROR (Result
)) {
2306 return EFI_DEVICE_ERROR
;
2315 IN EFI_USB_IO_PROTOCOL
*This
2319 Routine Description:
2320 Resets and reconfigures the USB controller. This function will
2321 work for all USB devices except USB Hub Controllers.
2324 This - Indicates the calling context.
2328 EFI_INVALID_PARAMETER
2333 USB_IO_CONTROLLER_DEVICE
*UsbIoController
;
2335 UsbIoController
= USB_IO_CONTROLLER_DEVICE_FROM_USB_IO_THIS (This
);
2337 if (IsHub (UsbIoController
)) {
2338 return EFI_INVALID_PARAMETER
;
2342 // Since at this time, this device has already been configured,
2343 // it needs to be re-configured.
2345 return ParentPortReset (UsbIoController
, TRUE
, 0);
2350 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2356 Routine Description:
2357 Reset Root Hub port.
2360 UsbBusDev - Bus controller of the device.
2361 PortNum - The given port to be reset.
2362 RetryTimes - RetryTimes when failed
2371 EFI_USB_PORT_STATUS PortStatus
;
2376 Status
= UsbVirtualHcSetRootHubPortFeature (
2381 if (EFI_ERROR (Status
)) {
2382 return EFI_DEVICE_ERROR
;
2385 gBS
->Stall (50 * 1000);
2388 // clear reset root port
2390 Status
= UsbVirtualHcClearRootHubPortFeature (
2395 if (EFI_ERROR (Status
)) {
2396 return EFI_DEVICE_ERROR
;
2401 Status
= UsbVirtualHcClearRootHubPortFeature (
2404 EfiUsbPortConnectChange
2406 if (EFI_ERROR (Status
)) {
2407 return EFI_DEVICE_ERROR
;
2410 UsbVirtualHcGetRootHubPortStatus (
2415 if (PortStatus
.PortStatus
& USB_PORT_STAT_OWNER
) {
2419 Status
= UsbVirtualHcSetRootHubPortFeature (
2424 if (EFI_ERROR (Status
)) {
2425 return EFI_DEVICE_ERROR
;
2428 Status
= UsbVirtualHcClearRootHubPortFeature (
2431 EfiUsbPortEnableChange
2435 gBS
->Stall ((1 + RetryTimes
) * 50 * 1000);
2442 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2447 Routine Description:
2451 UsbIoController - The USB_IO_CONTROLLER_DEVICE instance.
2452 PortIndex - The given port to be reset.
2460 EFI_USB_IO_PROTOCOL
*UsbIo
;
2461 EFI_USB_PORT_STATUS HubPortStatus
;
2464 ASSERT (UsbIoController
->IsUsbHub
== TRUE
);
2466 UsbIo
= &UsbIoController
->UsbIo
;
2474 gBS
->Stall (10 * 1000);
2477 // Wait for port reset complete
2484 (UINT32
*) &HubPortStatus
2486 gBS
->Stall (10 * 100);
2488 } while ((HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) == 0 && Number
> 0);
2492 // Cannot reset port, return error
2494 return EFI_DEVICE_ERROR
;
2502 (UINT32
*) &HubPortStatus
2505 // reset port will cause some bits change, clear them
2507 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_ENABLE
) {
2508 DEBUG ((gUSBDebugLevel
, "Port Enable Change\n"));
2509 HubClearPortFeature (
2512 EfiUsbPortEnableChange
2516 if (HubPortStatus
.PortChangeStatus
& USB_PORT_STAT_C_RESET
) {
2517 DEBUG ((gUSBDebugLevel
, "Port Reset Change\n"));
2518 HubClearPortFeature (
2521 EfiUsbPortResetChange
2530 ReportUsbStatusCode (
2531 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusController
,
2532 IN EFI_STATUS_CODE_TYPE Type
,
2533 IN EFI_STATUS_CODE_VALUE Code
2537 Routine Description:
2539 report a error Status code of USB bus driver controller
2542 UsbBusController - USB_BUS_CONTROLLER_DEVICE
2543 Type - EFI_STATUS_CODE_TYPE
2544 Code - EFI_STATUS_CODE_VALUE
2551 return REPORT_STATUS_CODE_WITH_DEVICE_PATH (
2554 UsbBusController
->DevicePath
2559 IsDeviceDisconnected (
2560 IN USB_IO_CONTROLLER_DEVICE
*UsbIoController
,
2561 IN OUT BOOLEAN
*Disconnected
2565 Routine Description:
2566 Reset if the device is disconencted or not
2569 UsbIoController - Indicating the Usb Controller Device.
2570 Disconnected - Indicate whether the device is disconencted or not
2578 USB_IO_DEVICE
*ParentIoDev
;
2579 USB_IO_DEVICE
*UsbIoDev
;
2580 USB_IO_CONTROLLER_DEVICE
*ParentController
;
2583 EFI_USB_IO_PROTOCOL
*UsbIo
;
2584 EFI_USB_PORT_STATUS PortStatus
;
2586 ParentController
= UsbIoController
->Parent
;
2587 ParentIoDev
= ParentController
->UsbDevice
;
2588 UsbIoDev
= UsbIoController
->UsbDevice
;
2589 HubPort
= UsbIoController
->ParentPort
;
2591 if (ParentIoDev
->DeviceAddress
== 1) {
2593 // Connected to the root hub
2595 UsbVirtualHcGetRootHubPortStatus (
2596 ParentIoDev
->BusController
,
2602 UsbIo
= &UsbIoController
->UsbIo
;
2603 Status
= HubGetPortStatus (
2604 &ParentController
->UsbIo
,
2606 (UINT32
*) &PortStatus
2609 if (EFI_ERROR (Status
)) {
2610 return IsDeviceDisconnected (ParentController
, Disconnected
);
2614 *Disconnected
= FALSE
;
2616 if (!IsPortConnect (PortStatus
.PortStatus
)) {
2617 *Disconnected
= TRUE
;
2625 UsbSetTransactionTranslator (
2626 IN USB_IO_CONTROLLER_DEVICE
*ParentHubController
,
2627 IN UINT8 ParentPort
,
2628 IN OUT USB_IO_DEVICE
*Device
2632 Routine Description:
2634 Set Transaction Translator parameter
2638 ParentHubController - Controller structure of the parent Hub device
2639 ParentPort - Number of parent port
2640 Device - Structure of the device
2645 EFI_OUT_OF_RESOURCES Cannot allocate resources
2649 USB_IO_CONTROLLER_DEVICE
*AncestorHubController
;
2651 AncestorHubController
= ParentHubController
;
2652 Device
->Translator
= NULL
;
2654 if (EFI_USB_SPEED_HIGH
== Device
->DeviceSpeed
) {
2659 if (EFI_USB_SPEED_HIGH
== AncestorHubController
->UsbDevice
->DeviceSpeed
) {
2663 if (NULL
== AncestorHubController
->Parent
) {
2667 AncestorHubController
= AncestorHubController
->Parent
;
2670 Device
->Translator
= AllocatePool (sizeof (EFI_USB2_HC_TRANSACTION_TRANSLATOR
));
2671 if (NULL
== Device
->Translator
) {
2672 return EFI_OUT_OF_RESOURCES
;
2675 Device
->Translator
->TranslatorHubAddress
= AncestorHubController
->UsbDevice
->DeviceAddress
;
2676 Device
->Translator
->TranslatorPortNumber
= ParentPort
;
2683 UsbUnsetTransactionTranslator (
2684 USB_IO_DEVICE
*Device
2688 Routine Description:
2690 Unset Transaction Translator parameter
2694 Device - Structure of the device
2702 if (Device
->Translator
) {
2703 gBS
->FreePool (Device
->Translator
);
2704 Device
->Translator
= NULL
;
2712 IdentifyDeviceSpeed (
2713 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2714 USB_IO_DEVICE
*NewDevice
,
2719 Routine Description:
2721 Identify speed of USB device
2725 UsbBusDev - UsbBus controller structure of the device
2726 NewDevice - Devcie controller structure
2727 Index - Number of the port
2732 EFI_NOT_FOUND Device release to CHC or can't be found
2737 EFI_USB_PORT_STATUS HubPortStatus
;
2739 UsbVirtualHcGetRootHubPortStatus (
2742 (EFI_USB_PORT_STATUS
*) &HubPortStatus
2746 // Check device device
2748 if (!(HubPortStatus
.PortStatus
& USB_PORT_STAT_OWNER
)) {
2752 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_HIGH_SPEED
) {
2753 DEBUG ((gUSBDebugLevel
, "High Speed Device attached to EHC\n"));
2754 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_HIGH
;
2756 Status
= ReleasePortToCHC (UsbBusDev
, Index
);
2757 if (EFI_ERROR (Status
)) {
2758 DEBUG ((gUSBErrorLevel
, "Fail to release port to CHC\n"));
2760 DEBUG ((gUSBDebugLevel
, "Success to release port to CHC\n"));
2762 return EFI_DEVICE_ERROR
;
2768 if (HubPortStatus
.PortStatus
& USB_PORT_STAT_LOW_SPEED
) {
2769 DEBUG ((gUSBDebugLevel
, "Low Speed Device attached to CHC\n"));
2770 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_LOW
;
2772 DEBUG ((gUSBDebugLevel
, "FULL Speed Device attached to CHC\n"));
2773 NewDevice
->DeviceSpeed
= EFI_USB_SPEED_FULL
;
2783 USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2788 Routine Description:
2790 Set bit to release the port owner to CHC
2794 UsbBusDev - UsbBus controller structure of the device
2795 PortNum - Number of the port
2800 EFI_DEVICE_ERROR Fail
2806 Status
= UsbVirtualHcSetRootHubPortFeature (
2812 gBS
->Stall (100 * 1000);
2819 UsbVirtualHcGetCapability (
2820 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2821 OUT UINT8
*MaxSpeed
,
2822 OUT UINT8
*PortNumber
,
2823 OUT UINT8
*Is64BitCapable
2827 Routine Description:
2829 Virtual interface to Retrieves the capablility of root hub ports
2830 for both Hc2 and Hc protocol.
2834 UsbBusDev - A pointer to bus controller of the device.
2835 MaxSpeed - A pointer to the number of the host controller.
2836 PortNumber - A pointer to the number of the root hub ports.
2837 Is64BitCapable - A pointer to the flag for whether controller supports
2838 64-bit memory addressing.
2843 The host controller capability were retrieved successfully.
2844 EFI_INVALID_PARAMETER
2845 MaxSpeed or PortNumber or Is64BitCapable is NULL.
2847 An error was encountered while attempting to retrieve the capabilities.
2853 Status
= EFI_SUCCESS
;
2855 if (UsbBusDev
->Hc2ProtocolSupported
) {
2856 Status
= UsbBusDev
->Usb2HCInterface
->GetCapability (
2857 UsbBusDev
->Usb2HCInterface
,
2863 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortNumber (
2864 UsbBusDev
->UsbHCInterface
,
2867 *MaxSpeed
= EFI_USB_SPEED_FULL
;
2868 *Is64BitCapable
= (UINT8
) FALSE
;
2877 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2878 IN UINT16 Attributes
2882 Routine Description:
2884 Virtual interface to provides software reset for the USB host controller
2885 for both Hc2 and Hc protocol.
2889 UsbBusDev - A pointer to bus controller of the device.
2890 Attributes - A bit mask of the reset operation to perform.
2891 See below for a list of the supported bit mask values.
2893 #define EFI_USB_HC_RESET_GLOBAL 0x0001 // Hc2 and Hc
2894 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002 // Hc2 and Hc
2895 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004 // Hc2
2896 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008 // Hc2
2898 EFI_USB_HC_RESET_GLOBAL
2899 If this bit is set, a global reset signal will be sent to the USB bus.
2900 This resets all of the USB bus logic, including the USB host
2901 controller hardware and all the devices attached on the USB bus.
2902 EFI_USB_HC_RESET_HOST_CONTROLLER
2903 If this bit is set, the USB host controller hardware will be reset.
2904 No reset signal will be sent to the USB bus.
2905 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
2906 If this bit is set, a global reset signal will be sent to the USB bus.
2907 This resets all of the USB bus logic, including the USB host
2908 controller hardware and all the devices attached on the USB bus.
2909 If this is an EHCI controller and the debug port has configured, then
2910 this is will still reset the host controller.
2911 EFI_USB_HC_RESET_HOST_WITH_DEBUG
2912 If this bit is set, the USB host controller hardware will be reset.
2913 If this is an EHCI controller and the debug port has been configured,
2914 then this will still reset the host controller.
2919 The reset operation succeeded.
2920 EFI_INVALID_PARAMETER
2921 Attributes is not valid.
2923 The type of reset specified by Attributes is not currently supported by
2924 the host controller hardware.
2926 Reset operation is rejected due to the debug port being configured and
2927 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
2928 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
2929 perform reset operation for this host controller.
2931 An error was encountered while attempting to perform
2932 the reset operation.
2938 Status
= EFI_SUCCESS
;
2940 if (UsbBusDev
->Hc2ProtocolSupported
) {
2941 Status
= UsbBusDev
->Usb2HCInterface
->Reset (
2942 UsbBusDev
->Usb2HCInterface
,
2943 EFI_USB_HC_RESET_GLOBAL
2946 Status
= UsbBusDev
->UsbHCInterface
->Reset (
2947 UsbBusDev
->UsbHCInterface
,
2948 EFI_USB_HC_RESET_GLOBAL
2957 UsbVirtualHcGetState (
2958 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
2959 OUT EFI_USB_HC_STATE
*State
2963 Routine Description:
2965 Virtual interface to retrieves current state of the USB host controller
2966 for both Hc2 and Hc protocol.
2970 UsbBusDev - A pointer to bus controller of the device.
2971 State - A pointer to the EFI_USB_HC_STATE data structure that
2972 indicates current state of the USB host controller.
2973 Type EFI_USB_HC_STATE is defined below.
2977 EfiUsbHcStateOperational,
2978 EfiUsbHcStateSuspend,
2979 EfiUsbHcStateMaximum
2985 The state information of the host controller was returned in State.
2986 EFI_INVALID_PARAMETER
2989 An error was encountered while attempting to retrieve the
2990 host controller's current state.
2996 Status
= EFI_SUCCESS
;
2998 if (UsbBusDev
->Hc2ProtocolSupported
) {
2999 Status
= UsbBusDev
->Usb2HCInterface
->GetState (
3000 UsbBusDev
->Usb2HCInterface
,
3004 Status
= UsbBusDev
->UsbHCInterface
->GetState (
3005 UsbBusDev
->UsbHCInterface
,
3015 UsbVirtualHcSetState (
3016 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3017 IN EFI_USB_HC_STATE State
3021 Routine Description:
3023 Virtual interface to sets the USB host controller to a specific state
3024 for both Hc2 and Hc protocol.
3028 UsbBusDev - A pointer to bus controller of the device.
3029 State - Indicates the state of the host controller that will be set.
3034 The USB host controller was successfully placed in the state
3036 EFI_INVALID_PARAMETER
3039 Failed to set the state specified by State due to device error.
3045 Status
= EFI_SUCCESS
;
3047 if (UsbBusDev
->Hc2ProtocolSupported
) {
3048 Status
= UsbBusDev
->Usb2HCInterface
->SetState (
3049 UsbBusDev
->Usb2HCInterface
,
3053 Status
= UsbBusDev
->UsbHCInterface
->SetState (
3054 UsbBusDev
->UsbHCInterface
,
3064 UsbVirtualHcGetRootHubPortStatus (
3065 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3066 IN UINT8 PortNumber
,
3067 OUT EFI_USB_PORT_STATUS
*PortStatus
3071 Routine Description:
3073 Virtual interface to retrieves the current status of a USB root hub port
3074 both for Hc2 and Hc protocol.
3078 UsbBusDev - A pointer to bus controller of the device.
3079 PortNumber - Specifies the root hub port from which the status
3080 is to be retrieved. This value is zero-based. For example,
3081 if a root hub has two ports, then the first port is numbered 0,
3082 and the second port is numbered 1.
3083 PortStatus - A pointer to the current port status bits and
3084 port status change bits.
3088 EFI_SUCCESS The status of the USB root hub port specified by PortNumber
3089 was returned in PortStatus.
3090 EFI_INVALID_PARAMETER PortNumber is invalid.
3091 EFI_DEVICE_ERROR Can't read register
3097 Status
= EFI_SUCCESS
;
3099 if (UsbBusDev
->Hc2ProtocolSupported
) {
3100 Status
= UsbBusDev
->Usb2HCInterface
->GetRootHubPortStatus (
3101 UsbBusDev
->Usb2HCInterface
,
3106 Status
= UsbBusDev
->UsbHCInterface
->GetRootHubPortStatus (
3107 UsbBusDev
->UsbHCInterface
,
3118 UsbVirtualHcSetRootHubPortFeature (
3119 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3120 IN UINT8 PortNumber
,
3121 IN EFI_USB_PORT_FEATURE PortFeature
3125 Routine Description:
3126 Virual interface to sets a feature for the specified root hub port
3127 for both Hc2 and Hc protocol.
3131 UsbBusDev - A pointer to bus controller of the device.
3132 PortNumber - Specifies the root hub port whose feature
3133 is requested to be set.
3134 PortFeature - Indicates the feature selector associated
3135 with the feature set request.
3140 The feature specified by PortFeature was set for the
3141 USB root hub port specified by PortNumber.
3142 EFI_INVALID_PARAMETER
3143 PortNumber is invalid or PortFeature is invalid.
3151 Status
= EFI_SUCCESS
;
3153 if (UsbBusDev
->Hc2ProtocolSupported
) {
3154 Status
= UsbBusDev
->Usb2HCInterface
->SetRootHubPortFeature (
3155 UsbBusDev
->Usb2HCInterface
,
3160 Status
= UsbBusDev
->UsbHCInterface
->SetRootHubPortFeature (
3161 UsbBusDev
->UsbHCInterface
,
3172 UsbVirtualHcClearRootHubPortFeature (
3173 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3174 IN UINT8 PortNumber
,
3175 IN EFI_USB_PORT_FEATURE PortFeature
3179 Routine Description:
3181 Virtual interface to clears a feature for the specified root hub port
3182 for both Hc2 and Hc protocol.
3186 UsbBusDev - A pointer to bus controller of the device.
3187 PortNumber - Specifies the root hub port whose feature
3188 is requested to be cleared.
3189 PortFeature - Indicates the feature selector associated with the
3190 feature clear request.
3195 The feature specified by PortFeature was cleared for the
3196 USB root hub port specified by PortNumber.
3197 EFI_INVALID_PARAMETER
3198 PortNumber is invalid or PortFeature is invalid.
3206 Status
= EFI_SUCCESS
;
3208 if (UsbBusDev
->Hc2ProtocolSupported
) {
3209 Status
= UsbBusDev
->Usb2HCInterface
->ClearRootHubPortFeature (
3210 UsbBusDev
->Usb2HCInterface
,
3215 Status
= UsbBusDev
->UsbHCInterface
->ClearRootHubPortFeature (
3216 UsbBusDev
->UsbHCInterface
,
3227 UsbVirtualHcControlTransfer (
3228 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3229 IN UINT8 DeviceAddress
,
3230 IN UINT8 DeviceSpeed
,
3231 IN UINTN MaximumPacketLength
,
3232 IN EFI_USB_DEVICE_REQUEST
*Request
,
3233 IN EFI_USB_DATA_DIRECTION TransferDirection
,
3235 IN OUT UINTN
*DataLength
,
3237 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3238 OUT UINT32
*TransferResult
3242 Routine Description:
3244 Virtual interface to submits control transfer to a target USB device
3245 for both Hc2 and Hc protocol.
3249 UsbBusDev - A pointer to bus controller of the device.
3250 DeviceAddress - Represents the address of the target device on the USB,
3251 which is assigned during USB enumeration.
3252 DeviceSpeed - Indicates target device speed.
3253 MaximumPacketLength - Indicates the maximum packet size that the
3254 default control transfer endpoint is capable of
3255 sending or receiving.
3256 Request - A pointer to the USB device request that will be sent
3258 TransferDirection - Specifies the data direction for the transfer.
3259 There are three values available, DataIn, DataOut
3261 Data - A pointer to the buffer of data that will be transmitted
3262 to USB device or received from USB device.
3263 DataLength - Indicates the size, in bytes, of the data buffer
3265 TimeOut - Indicates the maximum time, in microseconds,
3266 which the transfer is allowed to complete.
3267 Translator - A pointr to the transaction translator data.
3268 TransferResult - A pointer to the detailed result information generated
3269 by this control transfer.
3274 The control transfer was completed successfully.
3275 EFI_OUT_OF_RESOURCES
3276 The control transfer could not be completed due to a lack of resources.
3277 EFI_INVALID_PARAMETER
3278 Some parameters are invalid.
3280 The control transfer failed due to timeout.
3282 The control transfer failed due to host controller or device error.
3283 Caller should check TranferResult for detailed error information.
3288 BOOLEAN IsSlowDevice
;
3290 Status
= EFI_SUCCESS
;
3292 if (UsbBusDev
->Hc2ProtocolSupported
) {
3293 Status
= UsbBusDev
->Usb2HCInterface
->ControlTransfer (
3294 UsbBusDev
->Usb2HCInterface
,
3297 MaximumPacketLength
,
3307 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3308 Status
= UsbBusDev
->UsbHCInterface
->ControlTransfer (
3309 UsbBusDev
->UsbHCInterface
,
3312 (UINT8
) MaximumPacketLength
,
3327 UsbVirtualHcBulkTransfer (
3328 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3329 IN UINT8 DeviceAddress
,
3330 IN UINT8 EndPointAddress
,
3331 IN UINT8 DeviceSpeed
,
3332 IN UINTN MaximumPacketLength
,
3333 IN UINT8 DataBuffersNumber
,
3334 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
3335 IN OUT UINTN
*DataLength
,
3336 IN OUT UINT8
*DataToggle
,
3338 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3339 OUT UINT32
*TransferResult
3343 Routine Description:
3345 Virtual interface to submits bulk transfer to a bulk endpoint of a USB device
3346 both for Hc2 and Hc protocol.
3350 UsbBusDev - A pointer to bus controller of the device.
3351 DeviceAddress - Represents the address of the target device on the USB,
3352 which is assigned during USB enumeration.
3353 EndPointAddress - The combination of an endpoint number and an
3354 endpoint direction of the target USB device.
3355 Each endpoint address supports data transfer in
3356 one direction except the control endpoint
3357 (whose default endpoint address is 0).
3358 It is the caller's responsibility to make sure that
3359 the EndPointAddress represents a bulk endpoint.
3360 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
3361 and EFI_USB_SPEED_HIGH.
3362 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3363 is capable of sending or receiving.
3364 DataBuffersNumber - Number of data buffers prepared for the transfer.
3365 Data - Array of pointers to the buffers of data that will be transmitted
3366 to USB device or received from USB device.
3367 DataLength - When input, indicates the size, in bytes, of the data buffer
3368 specified by Data. When output, indicates the actually
3369 transferred data size.
3370 DataToggle - A pointer to the data toggle value. On input, it indicates
3371 the initial data toggle value the bulk transfer should adopt;
3372 on output, it is updated to indicate the data toggle value
3373 of the subsequent bulk transfer.
3374 Translator - A pointr to the transaction translator data.
3375 TimeOut - Indicates the maximum time, in microseconds, which the
3376 transfer is allowed to complete.
3377 TransferResult - A pointer to the detailed result information of the
3383 The bulk transfer was completed successfully.
3384 EFI_OUT_OF_RESOURCES
3385 The bulk transfer could not be submitted due to lack of resource.
3386 EFI_INVALID_PARAMETER
3387 Some parameters are invalid.
3389 The bulk transfer failed due to timeout.
3391 The bulk transfer failed due to host controller or device error.
3392 Caller should check TranferResult for detailed error information.
3398 Status
= EFI_SUCCESS
;
3400 if (UsbBusDev
->Hc2ProtocolSupported
) {
3401 Status
= UsbBusDev
->Usb2HCInterface
->BulkTransfer (
3402 UsbBusDev
->Usb2HCInterface
,
3406 MaximumPacketLength
,
3416 Status
= UsbBusDev
->UsbHCInterface
->BulkTransfer (
3417 UsbBusDev
->UsbHCInterface
,
3420 (UINT8
) MaximumPacketLength
,
3434 UsbVirtualHcAsyncInterruptTransfer (
3435 IN USB_BUS_CONTROLLER_DEVICE
* UsbBusDev
,
3436 IN UINT8 DeviceAddress
,
3437 IN UINT8 EndPointAddress
,
3438 IN UINT8 DeviceSpeed
,
3439 IN UINTN MaximumPacketLength
,
3440 IN BOOLEAN IsNewTransfer
,
3441 IN OUT UINT8
*DataToggle
,
3442 IN UINTN PollingInterval
,
3443 IN UINTN DataLength
,
3444 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
3445 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
3446 IN VOID
*Context OPTIONAL
3450 Routine Description:
3452 Virtual interface to submits an asynchronous interrupt transfer to an
3453 interrupt endpoint of a USB device for both Hc2 and Hc protocol.
3457 UsbBusDev - A pointer to bus controller of the device.
3458 DeviceAddress - Represents the address of the target device on the USB,
3459 which is assigned during USB enumeration.
3460 EndPointAddress - The combination of an endpoint number and an endpoint
3461 direction of the target USB device. Each endpoint address
3462 supports data transfer in one direction except the
3463 control endpoint (whose default endpoint address is 0).
3464 It is the caller's responsibility to make sure that
3465 the EndPointAddress represents an interrupt endpoint.
3466 DeviceSpeed - Indicates device speed.
3467 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3468 is capable of sending or receiving.
3469 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
3470 the host and the target interrupt endpoint.
3471 If FALSE, the specified asynchronous interrupt pipe
3473 DataToggle - A pointer to the data toggle value. On input, it is valid
3474 when IsNewTransfer is TRUE, and it indicates the initial
3475 data toggle value the asynchronous interrupt transfer
3477 On output, it is valid when IsNewTransfer is FALSE,
3478 and it is updated to indicate the data toggle value of
3479 the subsequent asynchronous interrupt transfer.
3480 PollingInterval - Indicates the interval, in milliseconds, that the
3481 asynchronous interrupt transfer is polled.
3482 This parameter is required when IsNewTransfer is TRUE.
3483 DataLength - Indicates the length of data to be received at the
3484 rate specified by PollingInterval from the target
3485 asynchronous interrupt endpoint. This parameter
3486 is only required when IsNewTransfer is TRUE.
3487 Translator - A pointr to the transaction translator data.
3488 CallBackFunction - The Callback function.This function is called at the
3489 rate specified by PollingInterval.This parameter is
3490 only required when IsNewTransfer is TRUE.
3491 Context - The context that is passed to the CallBackFunction.
3492 - This is an optional parameter and may be NULL.
3497 The asynchronous interrupt transfer request has been successfully
3498 submitted or canceled.
3499 EFI_INVALID_PARAMETER
3500 Some parameters are invalid.
3501 EFI_OUT_OF_RESOURCES
3502 The request could not be completed due to a lack of resources.
3509 BOOLEAN IsSlowDevice
;
3511 Status
= EFI_SUCCESS
;
3513 if (UsbBusDev
->Hc2ProtocolSupported
) {
3514 Status
= UsbBusDev
->Usb2HCInterface
->AsyncInterruptTransfer (
3515 UsbBusDev
->Usb2HCInterface
,
3519 MaximumPacketLength
,
3529 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3530 Status
= UsbBusDev
->UsbHCInterface
->AsyncInterruptTransfer (
3531 UsbBusDev
->UsbHCInterface
,
3535 (UINT8
) MaximumPacketLength
,
3550 UsbVirtualHcSyncInterruptTransfer (
3551 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3552 IN UINT8 DeviceAddress
,
3553 IN UINT8 EndPointAddress
,
3554 IN UINT8 DeviceSpeed
,
3555 IN UINTN MaximumPacketLength
,
3557 IN OUT UINTN
*DataLength
,
3558 IN OUT UINT8
*DataToggle
,
3560 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3561 OUT UINT32
*TransferResult
3565 Routine Description:
3567 Vitual interface to submits synchronous interrupt transfer to an interrupt endpoint
3568 of a USB device for both Hc2 and Hc protocol.
3572 UsbBusDev - A pointer to bus controller of the device.
3573 DeviceAddress - Represents the address of the target device on the USB,
3574 which is assigned during USB enumeration.
3575 EndPointAddress - The combination of an endpoint number and an endpoint
3576 direction of the target USB device. Each endpoint
3577 address supports data transfer in one direction
3578 except the control endpoint (whose default
3579 endpoint address is 0). It is the caller's responsibility
3580 to make sure that the EndPointAddress represents
3581 an interrupt endpoint.
3582 DeviceSpeed - Indicates device speed.
3583 MaximumPacketLength - Indicates the maximum packet size the target endpoint
3584 is capable of sending or receiving.
3585 Data - A pointer to the buffer of data that will be transmitted
3586 to USB device or received from USB device.
3587 DataLength - On input, the size, in bytes, of the data buffer specified
3588 by Data. On output, the number of bytes transferred.
3589 DataToggle - A pointer to the data toggle value. On input, it indicates
3590 the initial data toggle value the synchronous interrupt
3591 transfer should adopt;
3592 on output, it is updated to indicate the data toggle value
3593 of the subsequent synchronous interrupt transfer.
3594 TimeOut - Indicates the maximum time, in microseconds, which the
3595 transfer is allowed to complete.
3596 Translator - A pointr to the transaction translator data.
3597 TransferResult - A pointer to the detailed result information from
3598 the synchronous interrupt transfer.
3603 The synchronous interrupt transfer was completed successfully.
3604 EFI_OUT_OF_RESOURCES
3605 The synchronous interrupt transfer could not be submitted due
3606 to lack of resource.
3607 EFI_INVALID_PARAMETER
3608 Some parameters are invalid.
3610 The synchronous interrupt transfer failed due to timeout.
3612 The synchronous interrupt transfer failed due to host controller
3613 or device error. Caller should check TranferResult for detailed
3619 BOOLEAN IsSlowDevice
;
3621 Status
= EFI_SUCCESS
;
3623 if (UsbBusDev
->Hc2ProtocolSupported
) {
3624 Status
= UsbBusDev
->Usb2HCInterface
->SyncInterruptTransfer (
3625 UsbBusDev
->Usb2HCInterface
,
3629 MaximumPacketLength
,
3638 IsSlowDevice
= (EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
;
3639 Status
= UsbBusDev
->UsbHCInterface
->SyncInterruptTransfer (
3640 UsbBusDev
->UsbHCInterface
,
3644 (UINT8
) MaximumPacketLength
,
3658 UsbVirtualHcIsochronousTransfer (
3659 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3660 IN UINT8 DeviceAddress
,
3661 IN UINT8 EndPointAddress
,
3662 IN UINT8 DeviceSpeed
,
3663 IN UINTN MaximumPacketLength
,
3664 IN UINT8 DataBuffersNumber
,
3665 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3666 IN UINTN DataLength
,
3667 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3668 OUT UINT32
*TransferResult
3672 Routine Description:
3674 Virtual interface to submits isochronous transfer to a target USB device
3675 for both Hc2 and Hc protocol.
3679 UsbBusDev - A pointer to bus controller of the device.
3680 DeviceAddress - Represents the address of the target device on the USB,
3681 which is assigned during USB enumeration.
3682 EndPointAddress - End point address
3683 DeviceSpeed - Indicates device speed.
3684 MaximumPacketLength - Indicates the maximum packet size that the
3685 default control transfer endpoint is capable of
3686 sending or receiving.
3687 DataBuffersNumber - Number of data buffers prepared for the transfer.
3688 Data - Array of pointers to the buffers of data that will be
3689 transmitted to USB device or received from USB device.
3690 DataLength - Indicates the size, in bytes, of the data buffer
3692 Translator - A pointr to the transaction translator data.
3693 TransferResult - A pointer to the detailed result information generated
3694 by this control transfer.
3702 return EFI_UNSUPPORTED
;
3707 UsbVirtualHcAsyncIsochronousTransfer (
3708 IN USB_BUS_CONTROLLER_DEVICE
*UsbBusDev
,
3709 IN UINT8 DeviceAddress
,
3710 IN UINT8 EndPointAddress
,
3711 IN UINT8 DeviceSpeed
,
3712 IN UINTN MaximumPacketLength
,
3713 IN UINT8 DataBuffersNumber
,
3714 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
3715 IN UINTN DataLength
,
3716 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
3717 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
3722 Routine Description:
3724 Vitual interface to submits Async isochronous transfer to a target USB device
3725 for both Hc2 and Hc protocol.
3729 UsbBusDev - A pointer to bus controller of the device.
3730 DeviceAddress - Represents the address of the target device on the USB,
3731 which is assigned during USB enumeration.
3732 EndPointAddress - End point address
3733 DeviceSpeed - Indicates device speed.
3734 MaximumPacketLength - Indicates the maximum packet size that the
3735 default control transfer endpoint is capable of
3736 sending or receiving.
3737 DataBuffersNumber - Number of data buffers prepared for the transfer.
3738 Data - Array of pointers to the buffers of data that will be transmitted
3739 to USB device or received from USB device.
3740 DataLength - Indicates the size, in bytes, of the data buffer
3742 Translator - A pointr to the transaction translator data.
3743 IsochronousCallBack - When the transfer complete, the call back function will be called
3744 Context - Pass to the call back function as parameter
3752 return EFI_UNSUPPORTED
;