3 Wrapper function for usb host controller interface.
5 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
20 // if RemainingDevicePath== NULL, then all Usb child devices in this bus are wanted.
21 // Use a shor form Usb class Device Path, which could match any usb device, in WantedUsbIoDPList to indicate all Usb devices
22 // are wanted Usb devices
24 USB_CLASS_FORMAT_DEVICE_PATH mAllUsbClassDevicePath
= {
27 MESSAGING_DEVICE_PATH
,
30 (UINT8
) (sizeof (USB_CLASS_DEVICE_PATH
)),
31 (UINT8
) ((sizeof (USB_CLASS_DEVICE_PATH
)) >> 8)
37 0xff, // DeviceSubClass
38 0xff // DeviceProtocol
43 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
45 END_DEVICE_PATH_LENGTH
,
53 Get the capability of the host controller.
55 @param UsbBus The usb driver.
56 @param MaxSpeed The maximum speed this host controller supports.
57 @param NumOfPort The number of the root hub port.
58 @param Is64BitCapable Whether this controller support 64 bit addressing.
60 @retval EFI_SUCCESS The host controller capability is returned.
61 @retval Others Failed to retrieve the host controller capability.
69 OUT UINT8
*Is64BitCapable
74 if (UsbBus
->Usb2Hc
!= NULL
) {
75 Status
= UsbBus
->Usb2Hc
->GetCapability (
83 Status
= UsbBus
->UsbHc
->GetRootHubPortNumber (UsbBus
->UsbHc
, NumOfPort
);
85 *MaxSpeed
= EFI_USB_SPEED_FULL
;
86 *Is64BitCapable
= (UINT8
) FALSE
;
102 Get the root hub port state.
104 @param UsbBus The USB bus driver.
105 @param PortIndex The index of port.
106 @param PortStatus The variable to save port state.
108 @retval EFI_SUCCESS The root port state is returned in.
109 @retval Others Failed to get the root hub port state.
113 UsbHcGetRootHubPortStatus (
116 OUT EFI_USB_PORT_STATUS
*PortStatus
121 if (UsbBus
->Usb2Hc
!= NULL
) {
122 Status
= UsbBus
->Usb2Hc
->GetRootHubPortStatus (UsbBus
->Usb2Hc
, PortIndex
, PortStatus
);
124 Status
= UsbBus
->UsbHc
->GetRootHubPortStatus (UsbBus
->UsbHc
, PortIndex
, PortStatus
);
132 Set the root hub port feature.
134 @param UsbBus The USB bus driver.
135 @param PortIndex The port index.
136 @param Feature The port feature to set.
138 @retval EFI_SUCCESS The port feature is set.
139 @retval Others Failed to set port feature.
143 UsbHcSetRootHubPortFeature (
146 IN EFI_USB_PORT_FEATURE Feature
152 if (UsbBus
->Usb2Hc
!= NULL
) {
153 Status
= UsbBus
->Usb2Hc
->SetRootHubPortFeature (UsbBus
->Usb2Hc
, PortIndex
, Feature
);
155 Status
= UsbBus
->UsbHc
->SetRootHubPortFeature (UsbBus
->UsbHc
, PortIndex
, Feature
);
163 Clear the root hub port feature.
165 @param UsbBus The USB bus driver.
166 @param PortIndex The port index.
167 @param Feature The port feature to clear.
169 @retval EFI_SUCCESS The port feature is clear.
170 @retval Others Failed to clear port feature.
174 UsbHcClearRootHubPortFeature (
177 IN EFI_USB_PORT_FEATURE Feature
182 if (UsbBus
->Usb2Hc
!= NULL
) {
183 Status
= UsbBus
->Usb2Hc
->ClearRootHubPortFeature (UsbBus
->Usb2Hc
, PortIndex
, Feature
);
185 Status
= UsbBus
->UsbHc
->ClearRootHubPortFeature (UsbBus
->UsbHc
, PortIndex
, Feature
);
193 Execute a control transfer to the device.
195 @param UsbBus The USB bus driver.
196 @param DevAddr The device address.
197 @param DevSpeed The device speed.
198 @param MaxPacket Maximum packet size of endpoint 0.
199 @param Request The control transfer request.
200 @param Direction The direction of data stage.
201 @param Data The buffer holding data.
202 @param DataLength The length of the data.
203 @param TimeOut Timeout (in ms) to wait until timeout.
204 @param Translator The transaction translator for low/full speed device.
205 @param UsbResult The result of transfer.
207 @retval EFI_SUCCESS The control transfer finished without error.
208 @retval Others The control transfer failed, reason returned in UsbReslt.
212 UsbHcControlTransfer (
217 IN EFI_USB_DEVICE_REQUEST
*Request
,
218 IN EFI_USB_DATA_DIRECTION Direction
,
220 IN OUT UINTN
*DataLength
,
222 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
223 OUT UINT32
*UsbResult
227 BOOLEAN IsSlowDevice
;
229 if (UsbBus
->Usb2Hc
!= NULL
) {
230 Status
= UsbBus
->Usb2Hc
->ControlTransfer (
245 IsSlowDevice
= (BOOLEAN
)(EFI_USB_SPEED_LOW
== DevSpeed
);
246 Status
= UsbBus
->UsbHc
->ControlTransfer (
265 Execute a bulk transfer to the device's endpoint.
267 @param UsbBus The USB bus driver.
268 @param DevAddr The target device address.
269 @param EpAddr The target endpoint address, with direction encoded in
271 @param DevSpeed The device's speed.
272 @param MaxPacket The endpoint's max packet size.
273 @param BufferNum The number of data buffer.
274 @param Data Array of pointers to data buffer.
275 @param DataLength The length of data buffer.
276 @param DataToggle On input, the initial data toggle to use, also return
277 the next toggle on output.
278 @param TimeOut The time to wait until timeout.
279 @param Translator The transaction translator for low/full speed device.
280 @param UsbResult The result of USB execution.
282 @retval EFI_SUCCESS The bulk transfer is finished without error.
283 @retval Others Failed to execute bulk transfer, result in UsbResult.
294 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
295 IN OUT UINTN
*DataLength
,
296 IN OUT UINT8
*DataToggle
,
298 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
299 OUT UINT32
*UsbResult
304 if (UsbBus
->Usb2Hc
!= NULL
) {
305 Status
= UsbBus
->Usb2Hc
->BulkTransfer (
320 Status
= UsbBus
->UsbHc
->BulkTransfer (
338 Queue or cancel an asynchronous interrupt transfer.
340 @param UsbBus The USB bus driver.
341 @param DevAddr The target device address.
342 @param EpAddr The target endpoint address, with direction encoded in
344 @param DevSpeed The device's speed.
345 @param MaxPacket The endpoint's max packet size.
346 @param IsNewTransfer Whether this is a new request. If not, cancel the old
348 @param DataToggle Data toggle to use on input, next toggle on output.
349 @param PollingInterval The interval to poll the interrupt transfer (in ms).
350 @param DataLength The length of periodical data receive.
351 @param Translator The transaction translator for low/full speed device.
352 @param Callback Function to call when data is received.
353 @param Context The context to the callback.
355 @retval EFI_SUCCESS The asynchronous transfer is queued.
356 @retval Others Failed to queue the transfer.
360 UsbHcAsyncInterruptTransfer (
366 IN BOOLEAN IsNewTransfer
,
367 IN OUT UINT8
*DataToggle
,
368 IN UINTN PollingInterval
,
370 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
371 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback
,
372 IN VOID
*Context OPTIONAL
376 BOOLEAN IsSlowDevice
;
378 if (UsbBus
->Usb2Hc
!= NULL
) {
379 Status
= UsbBus
->Usb2Hc
->AsyncInterruptTransfer (
394 IsSlowDevice
= (BOOLEAN
)(EFI_USB_SPEED_LOW
== DevSpeed
);
396 Status
= UsbBus
->UsbHc
->AsyncInterruptTransfer (
416 Execute a synchronous interrupt transfer to the target endpoint.
418 @param UsbBus The USB bus driver.
419 @param DevAddr The target device address.
420 @param EpAddr The target endpoint address, with direction encoded in
422 @param DevSpeed The device's speed.
423 @param MaxPacket The endpoint's max packet size.
424 @param Data Pointer to data buffer.
425 @param DataLength The length of data buffer.
426 @param DataToggle On input, the initial data toggle to use, also return
427 the next toggle on output.
428 @param TimeOut The time to wait until timeout.
429 @param Translator The transaction translator for low/full speed device.
430 @param UsbResult The result of USB execution.
432 @retval EFI_SUCCESS The synchronous interrupt transfer is OK.
433 @retval Others Failed to execute the synchronous interrupt transfer.
437 UsbHcSyncInterruptTransfer (
444 IN OUT UINTN
*DataLength
,
445 IN OUT UINT8
*DataToggle
,
447 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
448 OUT UINT32
*UsbResult
452 BOOLEAN IsSlowDevice
;
454 if (UsbBus
->Usb2Hc
!= NULL
) {
455 Status
= UsbBus
->Usb2Hc
->SyncInterruptTransfer (
469 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DevSpeed
) ? TRUE
: FALSE
);
470 Status
= UsbBus
->UsbHc
->SyncInterruptTransfer (
495 Open the USB host controller protocol BY_CHILD.
497 @param Bus The USB bus driver.
498 @param Child The child handle.
500 @return The open protocol return.
504 UsbOpenHostProtoByChild (
509 EFI_USB_HC_PROTOCOL
*UsbHc
;
510 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
513 if (Bus
->Usb2Hc
!= NULL
) {
514 Status
= gBS
->OpenProtocol (
516 &gEfiUsb2HcProtocolGuid
,
518 mUsbBusDriverBinding
.DriverBindingHandle
,
520 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
524 Status
= gBS
->OpenProtocol (
526 &gEfiUsbHcProtocolGuid
,
528 mUsbBusDriverBinding
.DriverBindingHandle
,
530 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
539 Close the USB host controller protocol BY_CHILD.
541 @param Bus The USB bus driver.
542 @param Child The child handle.
546 UsbCloseHostProtoByChild (
551 if (Bus
->Usb2Hc
!= NULL
) {
554 &gEfiUsb2HcProtocolGuid
,
555 mUsbBusDriverBinding
.DriverBindingHandle
,
562 &gEfiUsbHcProtocolGuid
,
563 mUsbBusDriverBinding
.DriverBindingHandle
,
571 return the current TPL, copied from the EDKII glue lib.
585 Tpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
586 gBS
->RestoreTPL (Tpl
);
592 Create a new device path which only contain the first Usb part of the DevicePath.
594 @param DevicePath A full device path which contain the usb nodes.
596 @return A new device path which only contain the Usb part of the DevicePath.
599 EFI_DEVICE_PATH_PROTOCOL
*
602 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
605 EFI_DEVICE_PATH_PROTOCOL
*UsbDevicePathPtr
;
606 EFI_DEVICE_PATH_PROTOCOL
*UsbDevicePathBeginPtr
;
607 EFI_DEVICE_PATH_PROTOCOL
*UsbDevicePathEndPtr
;
611 // Get the Usb part first Begin node in full device path
613 UsbDevicePathBeginPtr
= DevicePath
;
614 while ( (!IsDevicePathEnd (UsbDevicePathBeginPtr
))&&
615 ((UsbDevicePathBeginPtr
->Type
!= MESSAGING_DEVICE_PATH
) ||
616 (UsbDevicePathBeginPtr
->SubType
!= MSG_USB_DP
&&
617 UsbDevicePathBeginPtr
->SubType
!= MSG_USB_CLASS_DP
618 && UsbDevicePathBeginPtr
->SubType
!= MSG_USB_WWID_DP
621 UsbDevicePathBeginPtr
= NextDevicePathNode(UsbDevicePathBeginPtr
);
625 // Get the Usb part first End node in full device path
627 UsbDevicePathEndPtr
= UsbDevicePathBeginPtr
;
628 while ((!IsDevicePathEnd (UsbDevicePathEndPtr
))&&
629 (UsbDevicePathEndPtr
->Type
== MESSAGING_DEVICE_PATH
) &&
630 (UsbDevicePathEndPtr
->SubType
== MSG_USB_DP
||
631 UsbDevicePathEndPtr
->SubType
== MSG_USB_CLASS_DP
632 || UsbDevicePathEndPtr
->SubType
== MSG_USB_WWID_DP
635 UsbDevicePathEndPtr
= NextDevicePathNode(UsbDevicePathEndPtr
);
638 Size
= GetDevicePathSize (UsbDevicePathBeginPtr
);
639 Size
-= GetDevicePathSize (UsbDevicePathEndPtr
);
642 // The passed in DevicePath does not contain the usb nodes
648 // Create a new device path which only contain the above Usb part
650 UsbDevicePathPtr
= AllocateZeroPool (Size
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
));
651 ASSERT (UsbDevicePathPtr
!= NULL
);
652 CopyMem (UsbDevicePathPtr
, UsbDevicePathBeginPtr
, Size
);
654 // Append end device path node
656 UsbDevicePathEndPtr
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) UsbDevicePathPtr
+ Size
);
657 SetDevicePathEndNode (UsbDevicePathEndPtr
);
658 return UsbDevicePathPtr
;
662 Check whether a usb device path is in a DEVICE_PATH_LIST_ITEM list.
664 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM.
665 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list.
667 @retval TRUE there is a DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP.
668 @retval FALSE there is no DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP.
674 IN EFI_DEVICE_PATH_PROTOCOL
*UsbDP
,
675 IN LIST_ENTRY
*UsbIoDPList
678 LIST_ENTRY
*ListIndex
;
679 DEVICE_PATH_LIST_ITEM
*ListItem
;
681 UINTN UsbDpDevicePathSize
;
684 // Check that UsbDP and UsbIoDPList are valid
686 if ((UsbIoDPList
== NULL
) || (UsbDP
== NULL
)) {
691 ListIndex
= UsbIoDPList
->ForwardLink
;
692 while (ListIndex
!= UsbIoDPList
){
693 ListItem
= CR(ListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
695 // Compare DEVICE_PATH_LIST_ITEM.DevicePath[]
697 ASSERT (ListItem
->DevicePath
!= NULL
);
699 UsbDpDevicePathSize
= GetDevicePathSize (UsbDP
);
700 if (UsbDpDevicePathSize
== GetDevicePathSize (ListItem
->DevicePath
)) {
701 if ((CompareMem (UsbDP
, ListItem
->DevicePath
, UsbDpDevicePathSize
)) == 0) {
706 ListIndex
= ListIndex
->ForwardLink
;
713 Add a usb device path into the DEVICE_PATH_LIST_ITEM list.
715 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM.
716 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list.
718 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value.
719 @retval EFI_SUCCESS If Add operation is successful, return this value.
725 IN EFI_DEVICE_PATH_PROTOCOL
*UsbDP
,
726 IN LIST_ENTRY
*UsbIoDPList
729 DEVICE_PATH_LIST_ITEM
*ListItem
;
732 // Check that UsbDP and UsbIoDPList are valid
734 if ((UsbIoDPList
== NULL
) || (UsbDP
== NULL
)) {
735 return EFI_INVALID_PARAMETER
;
738 if (SearchUsbDPInList (UsbDP
, UsbIoDPList
)){
743 // Prepare the usbio device path DEVICE_PATH_LIST_ITEM structure.
745 ListItem
= AllocateZeroPool (sizeof (DEVICE_PATH_LIST_ITEM
));
746 ASSERT (ListItem
!= NULL
);
747 ListItem
->Signature
= DEVICE_PATH_LIST_ITEM_SIGNATURE
;
748 ListItem
->DevicePath
= DuplicateDevicePath (UsbDP
);
750 InsertTailList (UsbIoDPList
, &ListItem
->Link
);
756 Check whether usb device, whose interface is UsbIf, matches the usb class which indicated by
757 UsbClassDevicePathPtr whose is a short form usb class device path.
759 @param UsbClassDevicePathPtr a short form usb class device path.
760 @param UsbIf a usb device interface.
762 @retval TRUE the usb device match the usb class.
763 @retval FALSE the usb device does not match the usb class.
769 IN USB_CLASS_DEVICE_PATH
*UsbClassDevicePathPtr
,
770 IN USB_INTERFACE
*UsbIf
773 USB_INTERFACE_DESC
*IfDesc
;
774 EFI_USB_INTERFACE_DESCRIPTOR
*ActIfDesc
;
775 EFI_USB_DEVICE_DESCRIPTOR
*DevDesc
;
778 if ((UsbClassDevicePathPtr
->Header
.Type
!= MESSAGING_DEVICE_PATH
) ||
779 (UsbClassDevicePathPtr
->Header
.SubType
!= MSG_USB_CLASS_DP
)){
784 IfDesc
= UsbIf
->IfDesc
;
785 ASSERT (IfDesc
->ActiveIndex
< USB_MAX_INTERFACE_SETTING
);
786 ActIfDesc
= &(IfDesc
->Settings
[IfDesc
->ActiveIndex
]->Desc
);
787 DevDesc
= &(UsbIf
->Device
->DevDesc
->Desc
);
790 // If connect class policy, determine whether to create device handle by the five fields
791 // in class device path node.
793 // In addtion, hub interface is always matched for this policy.
795 if ((ActIfDesc
->InterfaceClass
== USB_HUB_CLASS_CODE
) &&
796 (ActIfDesc
->InterfaceSubClass
== USB_HUB_SUBCLASS_CODE
)) {
801 // If vendor id or product id is 0xffff, they will be ignored.
803 if ((UsbClassDevicePathPtr
->VendorId
== 0xffff || UsbClassDevicePathPtr
->VendorId
== DevDesc
->IdVendor
) &&
804 (UsbClassDevicePathPtr
->ProductId
== 0xffff || UsbClassDevicePathPtr
->ProductId
== DevDesc
->IdProduct
)) {
807 // If Class in Device Descriptor is set to 0, the counterparts in interface should be checked.
809 if (DevDesc
->DeviceClass
== 0) {
810 if ((UsbClassDevicePathPtr
->DeviceClass
== ActIfDesc
->InterfaceClass
||
811 UsbClassDevicePathPtr
->DeviceClass
== 0xff) &&
812 (UsbClassDevicePathPtr
->DeviceSubClass
== ActIfDesc
->InterfaceSubClass
||
813 UsbClassDevicePathPtr
->DeviceSubClass
== 0xff) &&
814 (UsbClassDevicePathPtr
->DeviceProtocol
== ActIfDesc
->InterfaceProtocol
||
815 UsbClassDevicePathPtr
->DeviceProtocol
== 0xff)) {
819 } else if ((UsbClassDevicePathPtr
->DeviceClass
== DevDesc
->DeviceClass
||
820 UsbClassDevicePathPtr
->DeviceClass
== 0xff) &&
821 (UsbClassDevicePathPtr
->DeviceSubClass
== DevDesc
->DeviceSubClass
||
822 UsbClassDevicePathPtr
->DeviceSubClass
== 0xff) &&
823 (UsbClassDevicePathPtr
->DeviceProtocol
== DevDesc
->DeviceProtocol
||
824 UsbClassDevicePathPtr
->DeviceProtocol
== 0xff)) {
834 Check whether usb device, whose interface is UsbIf, matches the usb WWID requirement which indicated by
835 UsbWWIDDevicePathPtr whose is a short form usb WWID device path.
837 @param UsbWWIDDevicePathPtr a short form usb WWID device path.
838 @param UsbIf a usb device interface.
840 @retval TRUE the usb device match the usb WWID requirement.
841 @retval FALSE the usb device does not match the usb WWID requirement.
846 IN USB_WWID_DEVICE_PATH
*UsbWWIDDevicePathPtr
,
847 IN USB_INTERFACE
*UsbIf
850 USB_INTERFACE_DESC
*IfDesc
;
851 EFI_USB_INTERFACE_DESCRIPTOR
*ActIfDesc
;
852 EFI_USB_DEVICE_DESCRIPTOR
*DevDesc
;
853 EFI_USB_STRING_DESCRIPTOR
*StrDesc
;
859 if ((UsbWWIDDevicePathPtr
->Header
.Type
!= MESSAGING_DEVICE_PATH
) ||
860 (UsbWWIDDevicePathPtr
->Header
.SubType
!= MSG_USB_WWID_DP
)){
865 IfDesc
= UsbIf
->IfDesc
;
866 ASSERT (IfDesc
->ActiveIndex
< USB_MAX_INTERFACE_SETTING
);
867 ActIfDesc
= &(IfDesc
->Settings
[IfDesc
->ActiveIndex
]->Desc
);
868 DevDesc
= &(UsbIf
->Device
->DevDesc
->Desc
);
871 // In addition, Hub interface is always matched for this policy.
873 if ((ActIfDesc
->InterfaceClass
== USB_HUB_CLASS_CODE
) &&
874 (ActIfDesc
->InterfaceSubClass
== USB_HUB_SUBCLASS_CODE
)) {
879 // Check Vendor Id, Product Id and Interface Number.
881 if ((DevDesc
->IdVendor
!= UsbWWIDDevicePathPtr
->VendorId
) ||
882 (DevDesc
->IdProduct
!= UsbWWIDDevicePathPtr
->ProductId
) ||
883 (ActIfDesc
->InterfaceNumber
!= UsbWWIDDevicePathPtr
->InterfaceNumber
)) {
888 // Check SerialNumber.
890 if (DevDesc
->StrSerialNumber
== 0) {
895 // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters.
897 CompareStr
= (CHAR16
*) (UINTN
) (UsbWWIDDevicePathPtr
+ 1);
898 CompareLen
= (DevicePathNodeLength (UsbWWIDDevicePathPtr
) - sizeof (USB_WWID_DEVICE_PATH
)) / sizeof (CHAR16
);
899 if (CompareStr
[CompareLen
- 1] == L
'\0') {
904 // Compare serial number in each supported language.
906 for (Index
= 0; Index
< UsbIf
->Device
->TotalLangId
; Index
++) {
907 StrDesc
= UsbGetOneString (UsbIf
->Device
, DevDesc
->StrSerialNumber
, UsbIf
->Device
->LangId
[Index
]);
908 if (StrDesc
== NULL
) {
912 Length
= (StrDesc
->Length
- 2) / sizeof (CHAR16
);
913 if ((Length
>= CompareLen
) &&
914 (CompareMem (StrDesc
->String
+ Length
- CompareLen
, CompareStr
, CompareLen
* sizeof (CHAR16
)) == 0)) {
923 Free a DEVICE_PATH_LIST_ITEM list.
925 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list pointer.
927 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value.
928 @retval EFI_SUCCESS If free operation is successful, return this value.
933 UsbBusFreeUsbDPList (
934 IN LIST_ENTRY
*UsbIoDPList
937 LIST_ENTRY
*ListIndex
;
938 DEVICE_PATH_LIST_ITEM
*ListItem
;
941 // Check that ControllerHandle is a valid handle
943 if (UsbIoDPList
== NULL
) {
944 return EFI_INVALID_PARAMETER
;
947 ListIndex
= UsbIoDPList
->ForwardLink
;
948 while (ListIndex
!= UsbIoDPList
){
949 ListItem
= CR(ListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
951 // Free DEVICE_PATH_LIST_ITEM.DevicePath[]
953 if (ListItem
->DevicePath
!= NULL
){
954 FreePool(ListItem
->DevicePath
);
957 // Free DEVICE_PATH_LIST_ITEM itself
959 ListIndex
= ListIndex
->ForwardLink
;
960 RemoveEntryList (&ListItem
->Link
);
964 InitializeListHead (UsbIoDPList
);
969 Store a wanted usb child device info (its Usb part of device path) which is indicated by
970 RemainingDevicePath in a Usb bus which is indicated by UsbBusId.
972 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.
973 @param RemainingDevicePath The remaining device patch.
975 @retval EFI_SUCCESS Add operation is successful.
976 @retval EFI_INVALID_PARAMETER The parameters are invalid.
981 UsbBusAddWantedUsbIoDP (
982 IN EFI_USB_BUS_PROTOCOL
*UsbBusId
,
983 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
988 EFI_DEVICE_PATH_PROTOCOL
*DevicePathPtr
;
991 // Check whether remaining device path is valid
993 if (RemainingDevicePath
!= NULL
&& !IsDevicePathEnd (RemainingDevicePath
)) {
994 if ((RemainingDevicePath
->Type
!= MESSAGING_DEVICE_PATH
) ||
995 (RemainingDevicePath
->SubType
!= MSG_USB_DP
&&
996 RemainingDevicePath
->SubType
!= MSG_USB_CLASS_DP
997 && RemainingDevicePath
->SubType
!= MSG_USB_WWID_DP
999 return EFI_INVALID_PARAMETER
;
1003 if (UsbBusId
== NULL
){
1004 return EFI_INVALID_PARAMETER
;
1007 Bus
= USB_BUS_FROM_THIS (UsbBusId
);
1009 if (RemainingDevicePath
== NULL
) {
1011 // RemainingDevicePath == NULL means all Usb devices in this bus are wanted.
1012 // Here use a Usb class Device Path in WantedUsbIoDPList to indicate all Usb devices
1013 // are wanted Usb devices
1015 Status
= UsbBusFreeUsbDPList (&Bus
->WantedUsbIoDPList
);
1016 ASSERT (!EFI_ERROR (Status
));
1017 DevicePathPtr
= DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) &mAllUsbClassDevicePath
);
1018 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
1020 // If RemainingDevicePath isn't the End of Device Path Node,
1021 // Create new Usb device path according to the usb part in remaining device path
1023 DevicePathPtr
= GetUsbDPFromFullDP (RemainingDevicePath
);
1026 // If RemainingDevicePath is the End of Device Path Node,
1027 // skip enumerate any device and return EFI_SUCESSS
1032 ASSERT (DevicePathPtr
!= NULL
);
1033 Status
= AddUsbDPToList (DevicePathPtr
, &Bus
->WantedUsbIoDPList
);
1034 ASSERT (!EFI_ERROR (Status
));
1035 FreePool (DevicePathPtr
);
1040 Check whether a usb child device is the wanted device in a bus.
1042 @param Bus The Usb bus's private data pointer.
1043 @param UsbIf The usb child device inferface.
1045 @retval True If a usb child device is the wanted device in a bus.
1046 @retval False If a usb child device is *NOT* the wanted device in a bus.
1051 UsbBusIsWantedUsbIO (
1053 IN USB_INTERFACE
*UsbIf
1056 EFI_DEVICE_PATH_PROTOCOL
*DevicePathPtr
;
1057 LIST_ENTRY
*WantedUsbIoDPListPtr
;
1058 LIST_ENTRY
*WantedListIndex
;
1059 DEVICE_PATH_LIST_ITEM
*WantedListItem
;
1061 UINTN FirstDevicePathSize
;
1064 // Check whether passed in parameters are valid
1066 if ((UsbIf
== NULL
) || (Bus
== NULL
)) {
1070 // Check whether UsbIf is Hub
1077 // Check whether all Usb devices in this bus are wanted
1079 if (SearchUsbDPInList ((EFI_DEVICE_PATH_PROTOCOL
*)&mAllUsbClassDevicePath
, &Bus
->WantedUsbIoDPList
)){
1084 // Check whether the Usb device match any item in WantedUsbIoDPList
1086 WantedUsbIoDPListPtr
= &Bus
->WantedUsbIoDPList
;
1088 // Create new Usb device path according to the usb part in UsbIo full device path
1090 DevicePathPtr
= GetUsbDPFromFullDP (UsbIf
->DevicePath
);
1091 ASSERT (DevicePathPtr
!= NULL
);
1094 WantedListIndex
= WantedUsbIoDPListPtr
->ForwardLink
;
1095 while (WantedListIndex
!= WantedUsbIoDPListPtr
){
1096 WantedListItem
= CR(WantedListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
1097 ASSERT (WantedListItem
->DevicePath
->Type
== MESSAGING_DEVICE_PATH
);
1098 switch (WantedListItem
->DevicePath
->SubType
) {
1100 FirstDevicePathSize
= GetDevicePathSize (WantedListItem
->DevicePath
);
1101 if (FirstDevicePathSize
== GetDevicePathSize (DevicePathPtr
)) {
1103 WantedListItem
->DevicePath
,
1105 GetDevicePathSize (DevicePathPtr
)) == 0
1111 case MSG_USB_CLASS_DP
:
1112 if (MatchUsbClass((USB_CLASS_DEVICE_PATH
*)WantedListItem
->DevicePath
, UsbIf
)) {
1116 case MSG_USB_WWID_DP
:
1117 if (MatchUsbWwid((USB_WWID_DEVICE_PATH
*)WantedListItem
->DevicePath
, UsbIf
)) {
1130 WantedListIndex
= WantedListIndex
->ForwardLink
;
1132 gBS
->FreePool (DevicePathPtr
);
1135 // Check whether the new Usb device path is wanted
1145 Recursively connnect every wanted usb child device to ensure they all fully connected.
1146 Check all the child Usb IO handles in this bus, recursively connecte if it is wanted usb child device.
1148 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.
1150 @retval EFI_SUCCESS Connect is done successfully.
1151 @retval EFI_INVALID_PARAMETER The parameter is invalid.
1156 UsbBusRecursivelyConnectWantedUsbIo (
1157 IN EFI_USB_BUS_PROTOCOL
*UsbBusId
1163 EFI_USB_IO_PROTOCOL
*UsbIo
;
1164 USB_INTERFACE
*UsbIf
;
1165 UINTN UsbIoHandleCount
;
1166 EFI_HANDLE
*UsbIoBuffer
;
1167 EFI_DEVICE_PATH_PROTOCOL
*UsbIoDevicePath
;
1169 if (UsbBusId
== NULL
){
1170 return EFI_INVALID_PARAMETER
;
1173 Bus
= USB_BUS_FROM_THIS (UsbBusId
);
1176 // Get all Usb IO handles in system
1178 UsbIoHandleCount
= 0;
1179 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiUsbIoProtocolGuid
, NULL
, &UsbIoHandleCount
, &UsbIoBuffer
);
1180 if (Status
== EFI_NOT_FOUND
|| UsbIoHandleCount
== 0) {
1183 ASSERT (!EFI_ERROR (Status
));
1185 for (Index
= 0; Index
< UsbIoHandleCount
; Index
++) {
1187 // Check whether the USB IO handle is a child of this bus
1188 // Note: The usb child handle maybe invalid because of hot plugged out during the loop
1190 UsbIoDevicePath
= NULL
;
1191 Status
= gBS
->HandleProtocol (UsbIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &UsbIoDevicePath
);
1192 if (EFI_ERROR (Status
) || UsbIoDevicePath
== NULL
) {
1198 (GetDevicePathSize (Bus
->DevicePath
) - sizeof (EFI_DEVICE_PATH_PROTOCOL
))
1204 // Get the child Usb IO interface
1206 Status
= gBS
->HandleProtocol(
1208 &gEfiUsbIoProtocolGuid
,
1211 if (EFI_ERROR (Status
)) {
1214 UsbIf
= USB_INTERFACE_FROM_USBIO (UsbIo
);
1216 if (UsbBusIsWantedUsbIO (Bus
, UsbIf
)) {
1217 if (!UsbIf
->IsManaged
) {
1219 // Recursively connect the wanted Usb Io handle
1221 DEBUG ((EFI_D_INFO
, "UsbBusRecursivelyConnectWantedUsbIo: TPL before connect is %d\n", (UINT32
)UsbGetCurrentTpl ()));
1222 Status
= gBS
->ConnectController (UsbIf
->Handle
, NULL
, NULL
, TRUE
);
1223 UsbIf
->IsManaged
= (BOOLEAN
)!EFI_ERROR (Status
);
1224 DEBUG ((EFI_D_INFO
, "UsbBusRecursivelyConnectWantedUsbIo: TPL after connect is %d\n", (UINT32
)UsbGetCurrentTpl()));
1229 FreePool (UsbIoBuffer
);