3 Wrapper function for usb host controller interface.
5 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
14 // if RemainingDevicePath== NULL, then all Usb child devices in this bus are wanted.
15 // Use a shor form Usb class Device Path, which could match any usb device, in WantedUsbIoDPList to indicate all Usb devices
16 // are wanted Usb devices
18 USB_CLASS_FORMAT_DEVICE_PATH mAllUsbClassDevicePath
= {
21 MESSAGING_DEVICE_PATH
,
24 (UINT8
) (sizeof (USB_CLASS_DEVICE_PATH
)),
25 (UINT8
) ((sizeof (USB_CLASS_DEVICE_PATH
)) >> 8)
31 0xff, // DeviceSubClass
32 0xff // DeviceProtocol
37 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
39 END_DEVICE_PATH_LENGTH
,
47 Get the capability of the host controller.
49 @param UsbBus The usb driver.
50 @param MaxSpeed The maximum speed this host controller supports.
51 @param NumOfPort The number of the root hub port.
52 @param Is64BitCapable Whether this controller support 64 bit addressing.
54 @retval EFI_SUCCESS The host controller capability is returned.
55 @retval Others Failed to retrieve the host controller capability.
63 OUT UINT8
*Is64BitCapable
68 if (UsbBus
->Usb2Hc
!= NULL
) {
69 Status
= UsbBus
->Usb2Hc
->GetCapability (
77 Status
= UsbBus
->UsbHc
->GetRootHubPortNumber (UsbBus
->UsbHc
, NumOfPort
);
79 *MaxSpeed
= EFI_USB_SPEED_FULL
;
80 *Is64BitCapable
= (UINT8
) FALSE
;
96 Get the root hub port state.
98 @param UsbBus The USB bus driver.
99 @param PortIndex The index of port.
100 @param PortStatus The variable to save port state.
102 @retval EFI_SUCCESS The root port state is returned in.
103 @retval Others Failed to get the root hub port state.
107 UsbHcGetRootHubPortStatus (
110 OUT EFI_USB_PORT_STATUS
*PortStatus
115 if (UsbBus
->Usb2Hc
!= NULL
) {
116 Status
= UsbBus
->Usb2Hc
->GetRootHubPortStatus (UsbBus
->Usb2Hc
, PortIndex
, PortStatus
);
118 Status
= UsbBus
->UsbHc
->GetRootHubPortStatus (UsbBus
->UsbHc
, PortIndex
, PortStatus
);
126 Set the root hub port feature.
128 @param UsbBus The USB bus driver.
129 @param PortIndex The port index.
130 @param Feature The port feature to set.
132 @retval EFI_SUCCESS The port feature is set.
133 @retval Others Failed to set port feature.
137 UsbHcSetRootHubPortFeature (
140 IN EFI_USB_PORT_FEATURE Feature
146 if (UsbBus
->Usb2Hc
!= NULL
) {
147 Status
= UsbBus
->Usb2Hc
->SetRootHubPortFeature (UsbBus
->Usb2Hc
, PortIndex
, Feature
);
149 Status
= UsbBus
->UsbHc
->SetRootHubPortFeature (UsbBus
->UsbHc
, PortIndex
, Feature
);
157 Clear the root hub port feature.
159 @param UsbBus The USB bus driver.
160 @param PortIndex The port index.
161 @param Feature The port feature to clear.
163 @retval EFI_SUCCESS The port feature is clear.
164 @retval Others Failed to clear port feature.
168 UsbHcClearRootHubPortFeature (
171 IN EFI_USB_PORT_FEATURE Feature
176 if (UsbBus
->Usb2Hc
!= NULL
) {
177 Status
= UsbBus
->Usb2Hc
->ClearRootHubPortFeature (UsbBus
->Usb2Hc
, PortIndex
, Feature
);
179 Status
= UsbBus
->UsbHc
->ClearRootHubPortFeature (UsbBus
->UsbHc
, PortIndex
, Feature
);
187 Execute a control transfer to the device.
189 @param UsbBus The USB bus driver.
190 @param DevAddr The device address.
191 @param DevSpeed The device speed.
192 @param MaxPacket Maximum packet size of endpoint 0.
193 @param Request The control transfer request.
194 @param Direction The direction of data stage.
195 @param Data The buffer holding data.
196 @param DataLength The length of the data.
197 @param TimeOut Timeout (in ms) to wait until timeout.
198 @param Translator The transaction translator for low/full speed device.
199 @param UsbResult The result of transfer.
201 @retval EFI_SUCCESS The control transfer finished without error.
202 @retval Others The control transfer failed, reason returned in UsbReslt.
206 UsbHcControlTransfer (
211 IN EFI_USB_DEVICE_REQUEST
*Request
,
212 IN EFI_USB_DATA_DIRECTION Direction
,
214 IN OUT UINTN
*DataLength
,
216 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
217 OUT UINT32
*UsbResult
221 BOOLEAN IsSlowDevice
;
223 if (UsbBus
->Usb2Hc
!= NULL
) {
224 Status
= UsbBus
->Usb2Hc
->ControlTransfer (
239 IsSlowDevice
= (BOOLEAN
)(EFI_USB_SPEED_LOW
== DevSpeed
);
240 Status
= UsbBus
->UsbHc
->ControlTransfer (
259 Execute a bulk transfer to the device's endpoint.
261 @param UsbBus The USB bus driver.
262 @param DevAddr The target device address.
263 @param EpAddr The target endpoint address, with direction encoded in
265 @param DevSpeed The device's speed.
266 @param MaxPacket The endpoint's max packet size.
267 @param BufferNum The number of data buffer.
268 @param Data Array of pointers to data buffer.
269 @param DataLength The length of data buffer.
270 @param DataToggle On input, the initial data toggle to use, also return
271 the next toggle on output.
272 @param TimeOut The time to wait until timeout.
273 @param Translator The transaction translator for low/full speed device.
274 @param UsbResult The result of USB execution.
276 @retval EFI_SUCCESS The bulk transfer is finished without error.
277 @retval Others Failed to execute bulk transfer, result in UsbResult.
288 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
289 IN OUT UINTN
*DataLength
,
290 IN OUT UINT8
*DataToggle
,
292 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
293 OUT UINT32
*UsbResult
298 if (UsbBus
->Usb2Hc
!= NULL
) {
299 Status
= UsbBus
->Usb2Hc
->BulkTransfer (
314 Status
= UsbBus
->UsbHc
->BulkTransfer (
332 Queue or cancel an asynchronous interrupt transfer.
334 @param UsbBus The USB bus driver.
335 @param DevAddr The target device address.
336 @param EpAddr The target endpoint address, with direction encoded in
338 @param DevSpeed The device's speed.
339 @param MaxPacket The endpoint's max packet size.
340 @param IsNewTransfer Whether this is a new request. If not, cancel the old
342 @param DataToggle Data toggle to use on input, next toggle on output.
343 @param PollingInterval The interval to poll the interrupt transfer (in ms).
344 @param DataLength The length of periodical data receive.
345 @param Translator The transaction translator for low/full speed device.
346 @param Callback Function to call when data is received.
347 @param Context The context to the callback.
349 @retval EFI_SUCCESS The asynchronous transfer is queued.
350 @retval Others Failed to queue the transfer.
354 UsbHcAsyncInterruptTransfer (
360 IN BOOLEAN IsNewTransfer
,
361 IN OUT UINT8
*DataToggle
,
362 IN UINTN PollingInterval
,
364 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
365 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback
,
366 IN VOID
*Context OPTIONAL
370 BOOLEAN IsSlowDevice
;
372 if (UsbBus
->Usb2Hc
!= NULL
) {
373 Status
= UsbBus
->Usb2Hc
->AsyncInterruptTransfer (
388 IsSlowDevice
= (BOOLEAN
)(EFI_USB_SPEED_LOW
== DevSpeed
);
390 Status
= UsbBus
->UsbHc
->AsyncInterruptTransfer (
410 Execute a synchronous interrupt transfer to the target endpoint.
412 @param UsbBus The USB bus driver.
413 @param DevAddr The target device address.
414 @param EpAddr The target endpoint address, with direction encoded in
416 @param DevSpeed The device's speed.
417 @param MaxPacket The endpoint's max packet size.
418 @param Data Pointer to data buffer.
419 @param DataLength The length of data buffer.
420 @param DataToggle On input, the initial data toggle to use, also return
421 the next toggle on output.
422 @param TimeOut The time to wait until timeout.
423 @param Translator The transaction translator for low/full speed device.
424 @param UsbResult The result of USB execution.
426 @retval EFI_SUCCESS The synchronous interrupt transfer is OK.
427 @retval Others Failed to execute the synchronous interrupt transfer.
431 UsbHcSyncInterruptTransfer (
438 IN OUT UINTN
*DataLength
,
439 IN OUT UINT8
*DataToggle
,
441 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
442 OUT UINT32
*UsbResult
446 BOOLEAN IsSlowDevice
;
448 if (UsbBus
->Usb2Hc
!= NULL
) {
449 Status
= UsbBus
->Usb2Hc
->SyncInterruptTransfer (
463 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DevSpeed
) ? TRUE
: FALSE
);
464 Status
= UsbBus
->UsbHc
->SyncInterruptTransfer (
489 Open the USB host controller protocol BY_CHILD.
491 @param Bus The USB bus driver.
492 @param Child The child handle.
494 @return The open protocol return.
498 UsbOpenHostProtoByChild (
503 EFI_USB_HC_PROTOCOL
*UsbHc
;
504 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
507 if (Bus
->Usb2Hc
!= NULL
) {
508 Status
= gBS
->OpenProtocol (
510 &gEfiUsb2HcProtocolGuid
,
512 mUsbBusDriverBinding
.DriverBindingHandle
,
514 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
518 Status
= gBS
->OpenProtocol (
520 &gEfiUsbHcProtocolGuid
,
522 mUsbBusDriverBinding
.DriverBindingHandle
,
524 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
533 Close the USB host controller protocol BY_CHILD.
535 @param Bus The USB bus driver.
536 @param Child The child handle.
540 UsbCloseHostProtoByChild (
545 if (Bus
->Usb2Hc
!= NULL
) {
548 &gEfiUsb2HcProtocolGuid
,
549 mUsbBusDriverBinding
.DriverBindingHandle
,
556 &gEfiUsbHcProtocolGuid
,
557 mUsbBusDriverBinding
.DriverBindingHandle
,
565 return the current TPL, copied from the EDKII glue lib.
579 Tpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
580 gBS
->RestoreTPL (Tpl
);
586 Create a new device path which only contain the first Usb part of the DevicePath.
588 @param DevicePath A full device path which contain the usb nodes.
590 @return A new device path which only contain the Usb part of the DevicePath.
593 EFI_DEVICE_PATH_PROTOCOL
*
596 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
599 EFI_DEVICE_PATH_PROTOCOL
*UsbDevicePathPtr
;
600 EFI_DEVICE_PATH_PROTOCOL
*UsbDevicePathBeginPtr
;
601 EFI_DEVICE_PATH_PROTOCOL
*UsbDevicePathEndPtr
;
605 // Get the Usb part first Begin node in full device path
607 UsbDevicePathBeginPtr
= DevicePath
;
608 while ( (!IsDevicePathEnd (UsbDevicePathBeginPtr
))&&
609 ((UsbDevicePathBeginPtr
->Type
!= MESSAGING_DEVICE_PATH
) ||
610 (UsbDevicePathBeginPtr
->SubType
!= MSG_USB_DP
&&
611 UsbDevicePathBeginPtr
->SubType
!= MSG_USB_CLASS_DP
612 && UsbDevicePathBeginPtr
->SubType
!= MSG_USB_WWID_DP
615 UsbDevicePathBeginPtr
= NextDevicePathNode(UsbDevicePathBeginPtr
);
619 // Get the Usb part first End node in full device path
621 UsbDevicePathEndPtr
= UsbDevicePathBeginPtr
;
622 while ((!IsDevicePathEnd (UsbDevicePathEndPtr
))&&
623 (UsbDevicePathEndPtr
->Type
== MESSAGING_DEVICE_PATH
) &&
624 (UsbDevicePathEndPtr
->SubType
== MSG_USB_DP
||
625 UsbDevicePathEndPtr
->SubType
== MSG_USB_CLASS_DP
626 || UsbDevicePathEndPtr
->SubType
== MSG_USB_WWID_DP
629 UsbDevicePathEndPtr
= NextDevicePathNode(UsbDevicePathEndPtr
);
632 Size
= GetDevicePathSize (UsbDevicePathBeginPtr
);
633 Size
-= GetDevicePathSize (UsbDevicePathEndPtr
);
636 // The passed in DevicePath does not contain the usb nodes
642 // Create a new device path which only contain the above Usb part
644 UsbDevicePathPtr
= AllocateZeroPool (Size
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
));
645 ASSERT (UsbDevicePathPtr
!= NULL
);
646 CopyMem (UsbDevicePathPtr
, UsbDevicePathBeginPtr
, Size
);
648 // Append end device path node
650 UsbDevicePathEndPtr
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) UsbDevicePathPtr
+ Size
);
651 SetDevicePathEndNode (UsbDevicePathEndPtr
);
652 return UsbDevicePathPtr
;
656 Check whether a usb device path is in a DEVICE_PATH_LIST_ITEM list.
658 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM.
659 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list.
661 @retval TRUE there is a DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP.
662 @retval FALSE there is no DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP.
668 IN EFI_DEVICE_PATH_PROTOCOL
*UsbDP
,
669 IN LIST_ENTRY
*UsbIoDPList
672 LIST_ENTRY
*ListIndex
;
673 DEVICE_PATH_LIST_ITEM
*ListItem
;
675 UINTN UsbDpDevicePathSize
;
678 // Check that UsbDP and UsbIoDPList are valid
680 if ((UsbIoDPList
== NULL
) || (UsbDP
== NULL
)) {
685 ListIndex
= UsbIoDPList
->ForwardLink
;
686 while (ListIndex
!= UsbIoDPList
){
687 ListItem
= CR(ListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
689 // Compare DEVICE_PATH_LIST_ITEM.DevicePath[]
691 ASSERT (ListItem
->DevicePath
!= NULL
);
693 UsbDpDevicePathSize
= GetDevicePathSize (UsbDP
);
694 if (UsbDpDevicePathSize
== GetDevicePathSize (ListItem
->DevicePath
)) {
695 if ((CompareMem (UsbDP
, ListItem
->DevicePath
, UsbDpDevicePathSize
)) == 0) {
700 ListIndex
= ListIndex
->ForwardLink
;
707 Add a usb device path into the DEVICE_PATH_LIST_ITEM list.
709 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM.
710 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list.
712 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value.
713 @retval EFI_SUCCESS If Add operation is successful, return this value.
719 IN EFI_DEVICE_PATH_PROTOCOL
*UsbDP
,
720 IN LIST_ENTRY
*UsbIoDPList
723 DEVICE_PATH_LIST_ITEM
*ListItem
;
726 // Check that UsbDP and UsbIoDPList are valid
728 if ((UsbIoDPList
== NULL
) || (UsbDP
== NULL
)) {
729 return EFI_INVALID_PARAMETER
;
732 if (SearchUsbDPInList (UsbDP
, UsbIoDPList
)){
737 // Prepare the usbio device path DEVICE_PATH_LIST_ITEM structure.
739 ListItem
= AllocateZeroPool (sizeof (DEVICE_PATH_LIST_ITEM
));
740 ASSERT (ListItem
!= NULL
);
741 ListItem
->Signature
= DEVICE_PATH_LIST_ITEM_SIGNATURE
;
742 ListItem
->DevicePath
= DuplicateDevicePath (UsbDP
);
744 InsertTailList (UsbIoDPList
, &ListItem
->Link
);
750 Check whether usb device, whose interface is UsbIf, matches the usb class which indicated by
751 UsbClassDevicePathPtr whose is a short form usb class device path.
753 @param UsbClassDevicePathPtr a short form usb class device path.
754 @param UsbIf a usb device interface.
756 @retval TRUE the usb device match the usb class.
757 @retval FALSE the usb device does not match the usb class.
763 IN USB_CLASS_DEVICE_PATH
*UsbClassDevicePathPtr
,
764 IN USB_INTERFACE
*UsbIf
767 USB_INTERFACE_DESC
*IfDesc
;
768 EFI_USB_INTERFACE_DESCRIPTOR
*ActIfDesc
;
769 EFI_USB_DEVICE_DESCRIPTOR
*DevDesc
;
772 if ((UsbClassDevicePathPtr
->Header
.Type
!= MESSAGING_DEVICE_PATH
) ||
773 (UsbClassDevicePathPtr
->Header
.SubType
!= MSG_USB_CLASS_DP
)){
778 IfDesc
= UsbIf
->IfDesc
;
779 ASSERT (IfDesc
->ActiveIndex
< USB_MAX_INTERFACE_SETTING
);
780 ActIfDesc
= &(IfDesc
->Settings
[IfDesc
->ActiveIndex
]->Desc
);
781 DevDesc
= &(UsbIf
->Device
->DevDesc
->Desc
);
784 // If connect class policy, determine whether to create device handle by the five fields
785 // in class device path node.
787 // In addtion, hub interface is always matched for this policy.
789 if ((ActIfDesc
->InterfaceClass
== USB_HUB_CLASS_CODE
) &&
790 (ActIfDesc
->InterfaceSubClass
== USB_HUB_SUBCLASS_CODE
)) {
795 // If vendor id or product id is 0xffff, they will be ignored.
797 if ((UsbClassDevicePathPtr
->VendorId
== 0xffff || UsbClassDevicePathPtr
->VendorId
== DevDesc
->IdVendor
) &&
798 (UsbClassDevicePathPtr
->ProductId
== 0xffff || UsbClassDevicePathPtr
->ProductId
== DevDesc
->IdProduct
)) {
801 // If Class in Device Descriptor is set to 0, the counterparts in interface should be checked.
803 if (DevDesc
->DeviceClass
== 0) {
804 if ((UsbClassDevicePathPtr
->DeviceClass
== ActIfDesc
->InterfaceClass
||
805 UsbClassDevicePathPtr
->DeviceClass
== 0xff) &&
806 (UsbClassDevicePathPtr
->DeviceSubClass
== ActIfDesc
->InterfaceSubClass
||
807 UsbClassDevicePathPtr
->DeviceSubClass
== 0xff) &&
808 (UsbClassDevicePathPtr
->DeviceProtocol
== ActIfDesc
->InterfaceProtocol
||
809 UsbClassDevicePathPtr
->DeviceProtocol
== 0xff)) {
813 } else if ((UsbClassDevicePathPtr
->DeviceClass
== DevDesc
->DeviceClass
||
814 UsbClassDevicePathPtr
->DeviceClass
== 0xff) &&
815 (UsbClassDevicePathPtr
->DeviceSubClass
== DevDesc
->DeviceSubClass
||
816 UsbClassDevicePathPtr
->DeviceSubClass
== 0xff) &&
817 (UsbClassDevicePathPtr
->DeviceProtocol
== DevDesc
->DeviceProtocol
||
818 UsbClassDevicePathPtr
->DeviceProtocol
== 0xff)) {
828 Check whether usb device, whose interface is UsbIf, matches the usb WWID requirement which indicated by
829 UsbWWIDDevicePathPtr whose is a short form usb WWID device path.
831 @param UsbWWIDDevicePathPtr a short form usb WWID device path.
832 @param UsbIf a usb device interface.
834 @retval TRUE the usb device match the usb WWID requirement.
835 @retval FALSE the usb device does not match the usb WWID requirement.
840 IN USB_WWID_DEVICE_PATH
*UsbWWIDDevicePathPtr
,
841 IN USB_INTERFACE
*UsbIf
844 USB_INTERFACE_DESC
*IfDesc
;
845 EFI_USB_INTERFACE_DESCRIPTOR
*ActIfDesc
;
846 EFI_USB_DEVICE_DESCRIPTOR
*DevDesc
;
847 EFI_USB_STRING_DESCRIPTOR
*StrDesc
;
853 if ((UsbWWIDDevicePathPtr
->Header
.Type
!= MESSAGING_DEVICE_PATH
) ||
854 (UsbWWIDDevicePathPtr
->Header
.SubType
!= MSG_USB_WWID_DP
)){
859 IfDesc
= UsbIf
->IfDesc
;
860 ASSERT (IfDesc
->ActiveIndex
< USB_MAX_INTERFACE_SETTING
);
861 ActIfDesc
= &(IfDesc
->Settings
[IfDesc
->ActiveIndex
]->Desc
);
862 DevDesc
= &(UsbIf
->Device
->DevDesc
->Desc
);
865 // In addition, Hub interface is always matched for this policy.
867 if ((ActIfDesc
->InterfaceClass
== USB_HUB_CLASS_CODE
) &&
868 (ActIfDesc
->InterfaceSubClass
== USB_HUB_SUBCLASS_CODE
)) {
873 // Check Vendor Id, Product Id and Interface Number.
875 if ((DevDesc
->IdVendor
!= UsbWWIDDevicePathPtr
->VendorId
) ||
876 (DevDesc
->IdProduct
!= UsbWWIDDevicePathPtr
->ProductId
) ||
877 (ActIfDesc
->InterfaceNumber
!= UsbWWIDDevicePathPtr
->InterfaceNumber
)) {
882 // Check SerialNumber.
884 if (DevDesc
->StrSerialNumber
== 0) {
889 // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters.
891 CompareStr
= (CHAR16
*) (UINTN
) (UsbWWIDDevicePathPtr
+ 1);
892 CompareLen
= (DevicePathNodeLength (UsbWWIDDevicePathPtr
) - sizeof (USB_WWID_DEVICE_PATH
)) / sizeof (CHAR16
);
893 if (CompareStr
[CompareLen
- 1] == L
'\0') {
898 // Compare serial number in each supported language.
900 for (Index
= 0; Index
< UsbIf
->Device
->TotalLangId
; Index
++) {
901 StrDesc
= UsbGetOneString (UsbIf
->Device
, DevDesc
->StrSerialNumber
, UsbIf
->Device
->LangId
[Index
]);
902 if (StrDesc
== NULL
) {
906 Length
= (StrDesc
->Length
- 2) / sizeof (CHAR16
);
907 if ((Length
>= CompareLen
) &&
908 (CompareMem (StrDesc
->String
+ Length
- CompareLen
, CompareStr
, CompareLen
* sizeof (CHAR16
)) == 0)) {
917 Free a DEVICE_PATH_LIST_ITEM list.
919 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list pointer.
921 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value.
922 @retval EFI_SUCCESS If free operation is successful, return this value.
927 UsbBusFreeUsbDPList (
928 IN LIST_ENTRY
*UsbIoDPList
931 LIST_ENTRY
*ListIndex
;
932 DEVICE_PATH_LIST_ITEM
*ListItem
;
935 // Check that ControllerHandle is a valid handle
937 if (UsbIoDPList
== NULL
) {
938 return EFI_INVALID_PARAMETER
;
941 ListIndex
= UsbIoDPList
->ForwardLink
;
942 while (ListIndex
!= UsbIoDPList
){
943 ListItem
= CR(ListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
945 // Free DEVICE_PATH_LIST_ITEM.DevicePath[]
947 if (ListItem
->DevicePath
!= NULL
){
948 FreePool(ListItem
->DevicePath
);
951 // Free DEVICE_PATH_LIST_ITEM itself
953 ListIndex
= ListIndex
->ForwardLink
;
954 RemoveEntryList (&ListItem
->Link
);
958 InitializeListHead (UsbIoDPList
);
963 Store a wanted usb child device info (its Usb part of device path) which is indicated by
964 RemainingDevicePath in a Usb bus which is indicated by UsbBusId.
966 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.
967 @param RemainingDevicePath The remaining device patch.
969 @retval EFI_SUCCESS Add operation is successful.
970 @retval EFI_INVALID_PARAMETER The parameters are invalid.
975 UsbBusAddWantedUsbIoDP (
976 IN EFI_USB_BUS_PROTOCOL
*UsbBusId
,
977 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
982 EFI_DEVICE_PATH_PROTOCOL
*DevicePathPtr
;
985 // Check whether remaining device path is valid
987 if (RemainingDevicePath
!= NULL
&& !IsDevicePathEnd (RemainingDevicePath
)) {
988 if ((RemainingDevicePath
->Type
!= MESSAGING_DEVICE_PATH
) ||
989 (RemainingDevicePath
->SubType
!= MSG_USB_DP
&&
990 RemainingDevicePath
->SubType
!= MSG_USB_CLASS_DP
991 && RemainingDevicePath
->SubType
!= MSG_USB_WWID_DP
993 return EFI_INVALID_PARAMETER
;
997 if (UsbBusId
== NULL
){
998 return EFI_INVALID_PARAMETER
;
1001 Bus
= USB_BUS_FROM_THIS (UsbBusId
);
1003 if (RemainingDevicePath
== NULL
) {
1005 // RemainingDevicePath == NULL means all Usb devices in this bus are wanted.
1006 // Here use a Usb class Device Path in WantedUsbIoDPList to indicate all Usb devices
1007 // are wanted Usb devices
1009 Status
= UsbBusFreeUsbDPList (&Bus
->WantedUsbIoDPList
);
1010 ASSERT (!EFI_ERROR (Status
));
1011 DevicePathPtr
= DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) &mAllUsbClassDevicePath
);
1012 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
1014 // If RemainingDevicePath isn't the End of Device Path Node,
1015 // Create new Usb device path according to the usb part in remaining device path
1017 DevicePathPtr
= GetUsbDPFromFullDP (RemainingDevicePath
);
1020 // If RemainingDevicePath is the End of Device Path Node,
1021 // skip enumerate any device and return EFI_SUCESSS
1026 ASSERT (DevicePathPtr
!= NULL
);
1027 Status
= AddUsbDPToList (DevicePathPtr
, &Bus
->WantedUsbIoDPList
);
1028 ASSERT (!EFI_ERROR (Status
));
1029 FreePool (DevicePathPtr
);
1034 Check whether a usb child device is the wanted device in a bus.
1036 @param Bus The Usb bus's private data pointer.
1037 @param UsbIf The usb child device inferface.
1039 @retval True If a usb child device is the wanted device in a bus.
1040 @retval False If a usb child device is *NOT* the wanted device in a bus.
1045 UsbBusIsWantedUsbIO (
1047 IN USB_INTERFACE
*UsbIf
1050 EFI_DEVICE_PATH_PROTOCOL
*DevicePathPtr
;
1051 LIST_ENTRY
*WantedUsbIoDPListPtr
;
1052 LIST_ENTRY
*WantedListIndex
;
1053 DEVICE_PATH_LIST_ITEM
*WantedListItem
;
1055 UINTN FirstDevicePathSize
;
1058 // Check whether passed in parameters are valid
1060 if ((UsbIf
== NULL
) || (Bus
== NULL
)) {
1064 // Check whether UsbIf is Hub
1071 // Check whether all Usb devices in this bus are wanted
1073 if (SearchUsbDPInList ((EFI_DEVICE_PATH_PROTOCOL
*)&mAllUsbClassDevicePath
, &Bus
->WantedUsbIoDPList
)){
1078 // Check whether the Usb device match any item in WantedUsbIoDPList
1080 WantedUsbIoDPListPtr
= &Bus
->WantedUsbIoDPList
;
1082 // Create new Usb device path according to the usb part in UsbIo full device path
1084 DevicePathPtr
= GetUsbDPFromFullDP (UsbIf
->DevicePath
);
1085 ASSERT (DevicePathPtr
!= NULL
);
1088 WantedListIndex
= WantedUsbIoDPListPtr
->ForwardLink
;
1089 while (WantedListIndex
!= WantedUsbIoDPListPtr
){
1090 WantedListItem
= CR(WantedListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
1091 ASSERT (WantedListItem
->DevicePath
->Type
== MESSAGING_DEVICE_PATH
);
1092 switch (WantedListItem
->DevicePath
->SubType
) {
1094 FirstDevicePathSize
= GetDevicePathSize (WantedListItem
->DevicePath
);
1095 if (FirstDevicePathSize
== GetDevicePathSize (DevicePathPtr
)) {
1097 WantedListItem
->DevicePath
,
1099 GetDevicePathSize (DevicePathPtr
)) == 0
1105 case MSG_USB_CLASS_DP
:
1106 if (MatchUsbClass((USB_CLASS_DEVICE_PATH
*)WantedListItem
->DevicePath
, UsbIf
)) {
1110 case MSG_USB_WWID_DP
:
1111 if (MatchUsbWwid((USB_WWID_DEVICE_PATH
*)WantedListItem
->DevicePath
, UsbIf
)) {
1124 WantedListIndex
= WantedListIndex
->ForwardLink
;
1126 gBS
->FreePool (DevicePathPtr
);
1129 // Check whether the new Usb device path is wanted
1139 Recursively connnect every wanted usb child device to ensure they all fully connected.
1140 Check all the child Usb IO handles in this bus, recursively connecte if it is wanted usb child device.
1142 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.
1144 @retval EFI_SUCCESS Connect is done successfully.
1145 @retval EFI_INVALID_PARAMETER The parameter is invalid.
1150 UsbBusRecursivelyConnectWantedUsbIo (
1151 IN EFI_USB_BUS_PROTOCOL
*UsbBusId
1157 EFI_USB_IO_PROTOCOL
*UsbIo
;
1158 USB_INTERFACE
*UsbIf
;
1159 UINTN UsbIoHandleCount
;
1160 EFI_HANDLE
*UsbIoBuffer
;
1161 EFI_DEVICE_PATH_PROTOCOL
*UsbIoDevicePath
;
1163 if (UsbBusId
== NULL
){
1164 return EFI_INVALID_PARAMETER
;
1167 Bus
= USB_BUS_FROM_THIS (UsbBusId
);
1170 // Get all Usb IO handles in system
1172 UsbIoHandleCount
= 0;
1173 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiUsbIoProtocolGuid
, NULL
, &UsbIoHandleCount
, &UsbIoBuffer
);
1174 if (Status
== EFI_NOT_FOUND
|| UsbIoHandleCount
== 0) {
1177 ASSERT (!EFI_ERROR (Status
));
1179 for (Index
= 0; Index
< UsbIoHandleCount
; Index
++) {
1181 // Check whether the USB IO handle is a child of this bus
1182 // Note: The usb child handle maybe invalid because of hot plugged out during the loop
1184 UsbIoDevicePath
= NULL
;
1185 Status
= gBS
->HandleProtocol (UsbIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &UsbIoDevicePath
);
1186 if (EFI_ERROR (Status
) || UsbIoDevicePath
== NULL
) {
1192 (GetDevicePathSize (Bus
->DevicePath
) - sizeof (EFI_DEVICE_PATH_PROTOCOL
))
1198 // Get the child Usb IO interface
1200 Status
= gBS
->HandleProtocol(
1202 &gEfiUsbIoProtocolGuid
,
1205 if (EFI_ERROR (Status
)) {
1208 UsbIf
= USB_INTERFACE_FROM_USBIO (UsbIo
);
1210 if (UsbBusIsWantedUsbIO (Bus
, UsbIf
)) {
1211 if (!UsbIf
->IsManaged
) {
1213 // Recursively connect the wanted Usb Io handle
1215 DEBUG ((EFI_D_INFO
, "UsbBusRecursivelyConnectWantedUsbIo: TPL before connect is %d\n", (UINT32
)UsbGetCurrentTpl ()));
1216 Status
= gBS
->ConnectController (UsbIf
->Handle
, NULL
, NULL
, TRUE
);
1217 UsbIf
->IsManaged
= (BOOLEAN
)!EFI_ERROR (Status
);
1218 DEBUG ((EFI_D_INFO
, "UsbBusRecursivelyConnectWantedUsbIo: TPL after connect is %d\n", (UINT32
)UsbGetCurrentTpl()));
1223 FreePool (UsbIoBuffer
);