3 Wrapper function for usb host controller interface.
5 Copyright (c) 2007, Intel Corporation
6 All rights reserved. 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
;
94 Reset the host controller.
96 @param UsbBus The usb bus driver.
97 @param Attributes The reset type, only global reset is used by this driver.
99 @retval EFI_SUCCESS The reset operation succeeded.
100 @retval EFI_INVALID_PARAMETER Attributes is not valid.
101 @retval EFI_UNSUPPOURTED The type of reset specified by Attributes is
102 not currently supported by the host controller.
103 @retval EFI_DEVICE_ERROR Host controller isn't halted to reset.
113 if (UsbBus
->Usb2Hc
!= NULL
) {
114 Status
= UsbBus
->Usb2Hc
->Reset (UsbBus
->Usb2Hc
, Attributes
);
116 Status
= UsbBus
->UsbHc
->Reset (UsbBus
->UsbHc
, Attributes
);
124 Get the current operation state of the host controller.
126 @param UsbBus The USB bus driver.
127 @param State The host controller operation state.
129 @retval EFI_SUCCESS The operation state is returned in State.
130 @retval Others Failed to get the host controller state.
136 OUT EFI_USB_HC_STATE
*State
141 if (UsbBus
->Usb2Hc
!= NULL
) {
142 Status
= UsbBus
->Usb2Hc
->GetState (UsbBus
->Usb2Hc
, State
);
144 Status
= UsbBus
->UsbHc
->GetState (UsbBus
->UsbHc
, State
);
152 Set the host controller operation state.
154 @param UsbBus The USB bus driver.
155 @param State The state to set.
157 @retval EFI_SUCCESS The host controller is now working at State.
158 @retval Others Failed to set operation state.
164 IN EFI_USB_HC_STATE State
169 if (UsbBus
->Usb2Hc
!= NULL
) {
170 Status
= UsbBus
->Usb2Hc
->SetState (UsbBus
->Usb2Hc
, State
);
172 Status
= UsbBus
->UsbHc
->SetState (UsbBus
->UsbHc
, State
);
180 Get the root hub port state.
182 @param UsbBus The USB bus driver.
183 @param PortIndex The index of port.
184 @param PortStatus The variable to save port state.
186 @retval EFI_SUCCESS The root port state is returned in.
187 @retval Others Failed to get the root hub port state.
191 UsbHcGetRootHubPortStatus (
194 OUT EFI_USB_PORT_STATUS
*PortStatus
199 if (UsbBus
->Usb2Hc
!= NULL
) {
200 Status
= UsbBus
->Usb2Hc
->GetRootHubPortStatus (UsbBus
->Usb2Hc
, PortIndex
, PortStatus
);
202 Status
= UsbBus
->UsbHc
->GetRootHubPortStatus (UsbBus
->UsbHc
, PortIndex
, PortStatus
);
210 Set the root hub port feature.
212 @param UsbBus The USB bus driver.
213 @param PortIndex The port index.
214 @param Feature The port feature to set.
216 @retval EFI_SUCCESS The port feature is set.
217 @retval Others Failed to set port feature.
221 UsbHcSetRootHubPortFeature (
224 IN EFI_USB_PORT_FEATURE Feature
230 if (UsbBus
->Usb2Hc
!= NULL
) {
231 Status
= UsbBus
->Usb2Hc
->SetRootHubPortFeature (UsbBus
->Usb2Hc
, PortIndex
, Feature
);
233 Status
= UsbBus
->UsbHc
->SetRootHubPortFeature (UsbBus
->UsbHc
, PortIndex
, Feature
);
241 Clear the root hub port feature.
243 @param UsbBus The USB bus driver.
244 @param PortIndex The port index.
245 @param Feature The port feature to clear.
247 @retval EFI_SUCCESS The port feature is clear.
248 @retval Others Failed to clear port feature.
252 UsbHcClearRootHubPortFeature (
255 IN EFI_USB_PORT_FEATURE Feature
260 if (UsbBus
->Usb2Hc
!= NULL
) {
261 Status
= UsbBus
->Usb2Hc
->ClearRootHubPortFeature (UsbBus
->Usb2Hc
, PortIndex
, Feature
);
263 Status
= UsbBus
->UsbHc
->ClearRootHubPortFeature (UsbBus
->UsbHc
, PortIndex
, Feature
);
271 Execute a control transfer to the device.
273 @param UsbBus The USB bus driver.
274 @param DevAddr The device address.
275 @param DevSpeed The device speed.
276 @param MaxPacket Maximum packet size of endpoint 0.
277 @param Request The control transfer request.
278 @param Direction The direction of data stage.
279 @param Data The buffer holding data.
280 @param DataLength The length of the data.
281 @param TimeOut Timeout (in ms) to wait until timeout.
282 @param Translator The transaction translator for low/full speed device.
283 @param UsbResult The result of transfer.
285 @retval EFI_SUCCESS The control transfer finished without error.
286 @retval Others The control transfer failed, reason returned in UsbReslt.
290 UsbHcControlTransfer (
295 IN EFI_USB_DEVICE_REQUEST
*Request
,
296 IN EFI_USB_DATA_DIRECTION Direction
,
298 IN OUT UINTN
*DataLength
,
300 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
301 OUT UINT32
*UsbResult
305 BOOLEAN IsSlowDevice
;
307 if (UsbBus
->Usb2Hc
!= NULL
) {
308 Status
= UsbBus
->Usb2Hc
->ControlTransfer (
323 IsSlowDevice
= (BOOLEAN
)(EFI_USB_SPEED_LOW
== DevSpeed
);
324 Status
= UsbBus
->UsbHc
->ControlTransfer (
343 Execute a bulk transfer to the device's endpoint.
345 @param UsbBus The USB bus driver.
346 @param DevAddr The target device address.
347 @param EpAddr The target endpoint address, with direction encoded in
349 @param DevSpeed The device's speed.
350 @param MaxPacket The endpoint's max packet size.
351 @param BufferNum The number of data buffer.
352 @param Data Array of pointers to data buffer.
353 @param DataLength The length of data buffer.
354 @param DataToggle On input, the initial data toggle to use, also return
355 the next toggle on output.
356 @param TimeOut The time to wait until timeout.
357 @param Translator The transaction translator for low/full speed device.
358 @param UsbResult The result of USB execution.
360 @retval EFI_SUCCESS The bulk transfer is finished without error.
361 @retval Others Failed to execute bulk transfer, result in UsbResult.
372 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
373 IN OUT UINTN
*DataLength
,
374 IN OUT UINT8
*DataToggle
,
376 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
377 OUT UINT32
*UsbResult
382 if (UsbBus
->Usb2Hc
!= NULL
) {
383 Status
= UsbBus
->Usb2Hc
->BulkTransfer (
398 Status
= UsbBus
->UsbHc
->BulkTransfer (
416 Queue or cancel an asynchronous interrupt transfer.
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 IsNewTransfer Whether this is a new request. If not, cancel the old
426 @param DataToggle Data toggle to use on input, next toggle on output.
427 @param PollingInterval The interval to poll the interrupt transfer (in ms).
428 @param DataLength The length of periodical data receive.
429 @param Translator The transaction translator for low/full speed device.
430 @param Callback Function to call when data is received.
431 @param Context The context to the callback.
433 @retval EFI_SUCCESS The asynchronous transfer is queued.
434 @retval Others Failed to queue the transfer.
438 UsbHcAsyncInterruptTransfer (
444 IN BOOLEAN IsNewTransfer
,
445 IN OUT UINT8
*DataToggle
,
446 IN UINTN PollingInterval
,
448 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
449 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback
,
450 IN VOID
*Context OPTIONAL
454 BOOLEAN IsSlowDevice
;
456 if (UsbBus
->Usb2Hc
!= NULL
) {
457 Status
= UsbBus
->Usb2Hc
->AsyncInterruptTransfer (
472 IsSlowDevice
= (BOOLEAN
)(EFI_USB_SPEED_LOW
== DevSpeed
);
474 Status
= UsbBus
->UsbHc
->AsyncInterruptTransfer (
494 Execute a synchronous interrupt transfer to the target endpoint.
496 @param UsbBus The USB bus driver.
497 @param DevAddr The target device address.
498 @param EpAddr The target endpoint address, with direction encoded in
500 @param DevSpeed The device's speed.
501 @param MaxPacket The endpoint's max packet size.
502 @param Data Pointer to data buffer.
503 @param DataLength The length of data buffer.
504 @param DataToggle On input, the initial data toggle to use, also return
505 the next toggle on output.
506 @param TimeOut The time to wait until timeout.
507 @param Translator The transaction translator for low/full speed device.
508 @param UsbResult The result of USB execution.
510 @retval EFI_SUCCESS The synchronous interrupt transfer is OK.
511 @retval Others Failed to execute the synchronous interrupt transfer.
515 UsbHcSyncInterruptTransfer (
522 IN OUT UINTN
*DataLength
,
523 IN OUT UINT8
*DataToggle
,
525 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
526 OUT UINT32
*UsbResult
530 BOOLEAN IsSlowDevice
;
532 if (UsbBus
->Usb2Hc
!= NULL
) {
533 Status
= UsbBus
->Usb2Hc
->SyncInterruptTransfer (
547 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DevSpeed
) ? TRUE
: FALSE
);
548 Status
= UsbBus
->UsbHc
->SyncInterruptTransfer (
567 Execute a synchronous Isochronous USB transfer.
569 @param UsbBus The USB bus driver.
570 @param DevAddr The target device address.
571 @param EpAddr The target endpoint address, with direction encoded in
573 @param DevSpeed The device's speed.
574 @param MaxPacket The endpoint's max packet size.
575 @param BufferNum The number of data buffer.
576 @param Data Array of pointers to data buffer.
577 @param DataLength The length of data buffer.
578 @param Translator The transaction translator for low/full speed device.
579 @param UsbResult The result of USB execution.
581 @retval EFI_UNSUPPORTED The isochronous transfer isn't supported now.
585 UsbHcIsochronousTransfer (
592 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
594 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
595 OUT UINT32
*UsbResult
598 return EFI_UNSUPPORTED
;
603 Queue an asynchronous isochronous transfer.
605 @param UsbBus The USB bus driver.
606 @param DevAddr The target device address.
607 @param EpAddr The target endpoint address, with direction encoded in
609 @param DevSpeed The device's speed.
610 @param MaxPacket The endpoint's max packet size.
611 @param BufferNum The number of data buffer.
612 @param Data Array of pointers to data buffer.
613 @param DataLength The length of data buffer.
614 @param Translator The transaction translator for low/full speed device.
615 @param Callback The function to call when data is transferred.
616 @param Context The context to the callback function.
618 @retval EFI_UNSUPPORTED The asynchronous isochronous transfer isn't supported.
622 UsbHcAsyncIsochronousTransfer (
629 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
631 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
632 IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback
,
636 return EFI_UNSUPPORTED
;
641 Open the USB host controller protocol BY_CHILD.
643 @param Bus The USB bus driver.
644 @param Child The child handle.
646 @return The open protocol return.
650 UsbOpenHostProtoByChild (
655 EFI_USB_HC_PROTOCOL
*UsbHc
;
656 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
659 if (Bus
->Usb2Hc
!= NULL
) {
660 Status
= gBS
->OpenProtocol (
662 &gEfiUsb2HcProtocolGuid
,
664 mUsbBusDriverBinding
.DriverBindingHandle
,
666 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
670 Status
= gBS
->OpenProtocol (
672 &gEfiUsbHcProtocolGuid
,
674 mUsbBusDriverBinding
.DriverBindingHandle
,
676 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
685 Close the USB host controller protocol BY_CHILD.
687 @param Bus The USB bus driver.
688 @param Child The child handle.
692 UsbCloseHostProtoByChild (
697 if (Bus
->Usb2Hc
!= NULL
) {
700 &gEfiUsb2HcProtocolGuid
,
701 mUsbBusDriverBinding
.DriverBindingHandle
,
708 &gEfiUsbHcProtocolGuid
,
709 mUsbBusDriverBinding
.DriverBindingHandle
,
717 return the current TPL, copied from the EDKII glue lib.
731 Tpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
732 gBS
->RestoreTPL (Tpl
);
738 Create a new device path which only contain the first Usb part of the DevicePath.
740 @param DevicePath A full device path which contain the usb nodes.
742 @return A new device path which only contain the Usb part of the DevicePath.
745 EFI_DEVICE_PATH_PROTOCOL
*
748 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
751 EFI_DEVICE_PATH_PROTOCOL
*UsbDevicePathPtr
;
752 EFI_DEVICE_PATH_PROTOCOL
*UsbDevicePathBeginPtr
;
753 EFI_DEVICE_PATH_PROTOCOL
*UsbDevicePathEndPtr
;
757 // Get the Usb part first Begin node in full device path
759 UsbDevicePathBeginPtr
= DevicePath
;
760 while ( (!IsDevicePathEnd (UsbDevicePathBeginPtr
))&&
761 ((UsbDevicePathBeginPtr
->Type
!= MESSAGING_DEVICE_PATH
) ||
762 (UsbDevicePathBeginPtr
->SubType
!= MSG_USB_DP
&&
763 UsbDevicePathBeginPtr
->SubType
!= MSG_USB_CLASS_DP
764 && UsbDevicePathBeginPtr
->SubType
!= MSG_USB_WWID_DP
767 UsbDevicePathBeginPtr
= NextDevicePathNode(UsbDevicePathBeginPtr
);
771 // Get the Usb part first End node in full device path
773 UsbDevicePathEndPtr
= UsbDevicePathBeginPtr
;
774 while ((!IsDevicePathEnd (UsbDevicePathEndPtr
))&&
775 (UsbDevicePathEndPtr
->Type
== MESSAGING_DEVICE_PATH
) &&
776 (UsbDevicePathEndPtr
->SubType
== MSG_USB_DP
||
777 UsbDevicePathEndPtr
->SubType
== MSG_USB_CLASS_DP
778 || UsbDevicePathEndPtr
->SubType
== MSG_USB_WWID_DP
781 UsbDevicePathEndPtr
= NextDevicePathNode(UsbDevicePathEndPtr
);
784 Size
= GetDevicePathSize (UsbDevicePathBeginPtr
);
785 Size
-= GetDevicePathSize (UsbDevicePathEndPtr
);
788 // The passed in DevicePath does not contain the usb nodes
794 // Create a new device path which only contain the above Usb part
796 UsbDevicePathPtr
= AllocateZeroPool (Size
+ sizeof (EFI_DEVICE_PATH_PROTOCOL
));
797 ASSERT (UsbDevicePathPtr
!= NULL
);
798 CopyMem (UsbDevicePathPtr
, UsbDevicePathBeginPtr
, Size
);
800 // Append end device path node
802 UsbDevicePathEndPtr
= (EFI_DEVICE_PATH_PROTOCOL
*) ((UINTN
) UsbDevicePathPtr
+ Size
);
803 SetDevicePathEndNode (UsbDevicePathEndPtr
);
804 return UsbDevicePathPtr
;
808 Check whether a usb device path is in a DEVICE_PATH_LIST_ITEM list.
810 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM.
811 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list.
813 @retval TRUE there is a DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP.
814 @retval FALSE there is no DEVICE_PATH_LIST_ITEM in UsbIoDPList which contains the passed in UsbDP.
820 IN EFI_DEVICE_PATH_PROTOCOL
*UsbDP
,
821 IN LIST_ENTRY
*UsbIoDPList
824 LIST_ENTRY
*ListIndex
;
825 DEVICE_PATH_LIST_ITEM
*ListItem
;
827 UINTN UsbDpDevicePathSize
;
830 // Check that UsbDP and UsbIoDPList are valid
832 if ((UsbIoDPList
== NULL
) || (UsbDP
== NULL
)) {
837 ListIndex
= UsbIoDPList
->ForwardLink
;
838 while (ListIndex
!= UsbIoDPList
){
839 ListItem
= CR(ListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
841 // Compare DEVICE_PATH_LIST_ITEM.DevicePath[]
843 ASSERT (ListItem
->DevicePath
!= NULL
);
845 UsbDpDevicePathSize
= GetDevicePathSize (UsbDP
);
846 if (UsbDpDevicePathSize
== GetDevicePathSize (ListItem
->DevicePath
)) {
847 if ((CompareMem (UsbDP
, ListItem
->DevicePath
, UsbDpDevicePathSize
)) == 0) {
852 ListIndex
= ListIndex
->ForwardLink
;
859 Add a usb device path into the DEVICE_PATH_LIST_ITEM list.
861 @param UsbDP a usb device path of DEVICE_PATH_LIST_ITEM.
862 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list.
864 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value.
865 @retval EFI_SUCCESS If Add operation is successful, return this value.
871 IN EFI_DEVICE_PATH_PROTOCOL
*UsbDP
,
872 IN LIST_ENTRY
*UsbIoDPList
875 DEVICE_PATH_LIST_ITEM
*ListItem
;
878 // Check that UsbDP and UsbIoDPList are valid
880 if ((UsbIoDPList
== NULL
) || (UsbDP
== NULL
)) {
881 return EFI_INVALID_PARAMETER
;
884 if (SearchUsbDPInList (UsbDP
, UsbIoDPList
)){
889 // Prepare the usbio device path DEVICE_PATH_LIST_ITEM structure.
891 ListItem
= AllocateZeroPool (sizeof (DEVICE_PATH_LIST_ITEM
));
892 ASSERT (ListItem
!= NULL
);
893 ListItem
->Signature
= DEVICE_PATH_LIST_ITEM_SIGNATURE
;
894 ListItem
->DevicePath
= DuplicateDevicePath (UsbDP
);
896 InsertTailList (UsbIoDPList
, &ListItem
->Link
);
902 Check whether usb device, whose interface is UsbIf, matches the usb class which indicated by
903 UsbClassDevicePathPtr whose is a short form usb class device path.
905 @param UsbClassDevicePathPtr a short form usb class device path.
906 @param UsbIf a usb device interface.
908 @retval TRUE the usb device match the usb class.
909 @retval FALSE the usb device does not match the usb class.
915 IN USB_CLASS_DEVICE_PATH
*UsbClassDevicePathPtr
,
916 IN USB_INTERFACE
*UsbIf
919 USB_INTERFACE_DESC
*IfDesc
;
920 EFI_USB_INTERFACE_DESCRIPTOR
*ActIfDesc
;
921 EFI_USB_DEVICE_DESCRIPTOR
*DevDesc
;
924 if ((UsbClassDevicePathPtr
->Header
.Type
!= MESSAGING_DEVICE_PATH
) ||
925 (UsbClassDevicePathPtr
->Header
.SubType
!= MSG_USB_CLASS_DP
)){
930 IfDesc
= UsbIf
->IfDesc
;
931 ActIfDesc
= &(IfDesc
->Settings
[IfDesc
->ActiveIndex
]->Desc
);
932 DevDesc
= &(UsbIf
->Device
->DevDesc
->Desc
);
935 // If connect class policy, determine whether to create device handle by the five fields
936 // in class device path node.
938 // In addtion, hub interface is always matched for this policy.
940 if ((ActIfDesc
->InterfaceClass
== USB_HUB_CLASS_CODE
) &&
941 (ActIfDesc
->InterfaceSubClass
== USB_HUB_SUBCLASS_CODE
)) {
946 // If vendor id or product id is 0xffff, they will be ignored.
948 if ((UsbClassDevicePathPtr
->VendorId
== 0xffff || UsbClassDevicePathPtr
->VendorId
== DevDesc
->IdVendor
) &&
949 (UsbClassDevicePathPtr
->ProductId
== 0xffff || UsbClassDevicePathPtr
->ProductId
== DevDesc
->IdProduct
)) {
952 // If class or subclass or protocol is 0, the counterparts in interface should be checked.
954 if (DevDesc
->DeviceClass
== 0 ||
955 DevDesc
->DeviceSubClass
== 0 ||
956 DevDesc
->DeviceProtocol
== 0) {
958 if ((UsbClassDevicePathPtr
->DeviceClass
== ActIfDesc
->InterfaceClass
||
959 UsbClassDevicePathPtr
->DeviceClass
== 0xff) &&
960 (UsbClassDevicePathPtr
->DeviceSubClass
== ActIfDesc
->InterfaceSubClass
||
961 UsbClassDevicePathPtr
->DeviceSubClass
== 0xff) &&
962 (UsbClassDevicePathPtr
->DeviceProtocol
== ActIfDesc
->InterfaceProtocol
||
963 UsbClassDevicePathPtr
->DeviceProtocol
== 0xff)) {
967 } else if ((UsbClassDevicePathPtr
->DeviceClass
== DevDesc
->DeviceClass
||
968 UsbClassDevicePathPtr
->DeviceClass
== 0xff) &&
969 (UsbClassDevicePathPtr
->DeviceSubClass
== DevDesc
->DeviceSubClass
||
970 UsbClassDevicePathPtr
->DeviceSubClass
== 0xff) &&
971 (UsbClassDevicePathPtr
->DeviceProtocol
== DevDesc
->DeviceProtocol
||
972 UsbClassDevicePathPtr
->DeviceProtocol
== 0xff)) {
982 Check whether usb device, whose interface is UsbIf, matches the usb WWID requirement which indicated by
983 UsbWWIDDevicePathPtr whose is a short form usb WWID device path.
985 @param UsbWWIDDevicePathPtr a short form usb WWID device path.
986 @param UsbIf a usb device interface.
988 @retval TRUE the usb device match the usb WWID requirement.
989 @retval FALSE the usb device does not match the usb WWID requirement.
994 IN USB_WWID_DEVICE_PATH
*UsbWWIDDevicePathPtr
,
995 IN USB_INTERFACE
*UsbIf
998 USB_INTERFACE_DESC
*IfDesc
;
999 EFI_USB_INTERFACE_DESCRIPTOR
*ActIfDesc
;
1000 EFI_USB_DEVICE_DESCRIPTOR
*DevDesc
;
1001 EFI_USB_STRING_DESCRIPTOR
*StrDesc
;
1004 if ((UsbWWIDDevicePathPtr
->Header
.Type
!= MESSAGING_DEVICE_PATH
) ||
1005 (UsbWWIDDevicePathPtr
->Header
.SubType
!= MSG_USB_WWID_DP
)){
1010 IfDesc
= UsbIf
->IfDesc
;
1011 ActIfDesc
= &(IfDesc
->Settings
[IfDesc
->ActiveIndex
]->Desc
);
1012 DevDesc
= &(UsbIf
->Device
->DevDesc
->Desc
);
1013 StrDesc
= UsbGetOneString (UsbIf
->Device
, DevDesc
->StrSerialNumber
, USB_US_LAND_ID
);
1014 SnString
= (UINT16
*) ((UINT8
*)UsbWWIDDevicePathPtr
+ 10);
1017 //In addtion, hub interface is always matched for this policy.
1019 if ((ActIfDesc
->InterfaceClass
== USB_HUB_CLASS_CODE
) &&
1020 (ActIfDesc
->InterfaceSubClass
== USB_HUB_SUBCLASS_CODE
)) {
1024 // If connect wwid policy, determine the objective device by the serial number of
1025 // device descriptor.
1026 // Get serial number index from device descriptor, then get serial number by index
1027 // and land id, compare the serial number with wwid device path node at last
1029 // BugBug: only check serial number here, should check Interface Number, Device Vendor Id, Device Product Id in later version
1031 if (StrDesc
!= NULL
&& !StrnCmp (StrDesc
->String
, SnString
, StrDesc
->Length
)) {
1040 Free a DEVICE_PATH_LIST_ITEM list.
1042 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list pointer.
1044 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value.
1045 @retval EFI_SUCCESS If free operation is successful, return this value.
1050 UsbBusFreeUsbDPList (
1051 IN LIST_ENTRY
*UsbIoDPList
1054 LIST_ENTRY
*ListIndex
;
1055 DEVICE_PATH_LIST_ITEM
*ListItem
;
1058 // Check that ControllerHandle is a valid handle
1060 if (UsbIoDPList
== NULL
) {
1061 return EFI_INVALID_PARAMETER
;
1064 ListIndex
= UsbIoDPList
->ForwardLink
;
1065 while (ListIndex
!= UsbIoDPList
){
1066 ListItem
= CR(ListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
1068 // Free DEVICE_PATH_LIST_ITEM.DevicePath[]
1070 if (ListItem
->DevicePath
!= NULL
){
1071 FreePool(ListItem
->DevicePath
);
1074 // Free DEVICE_PATH_LIST_ITEM itself
1076 ListIndex
= ListIndex
->ForwardLink
;
1077 RemoveEntryList (&ListItem
->Link
);
1078 FreePool (ListItem
);
1081 InitializeListHead (UsbIoDPList
);
1086 Store a wanted usb child device info (its Usb part of device path) which is indicated by
1087 RemainingDevicePath in a Usb bus which is indicated by UsbBusId.
1089 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.
1090 @param RemainingDevicePath The remaining device patch.
1092 @retval EFI_SUCCESS Add operation is successful.
1093 @retval EFI_INVALID_PARAMETER The parameters are invalid.
1098 UsbBusAddWantedUsbIoDP (
1099 IN EFI_USB_BUS_PROTOCOL
*UsbBusId
,
1100 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1105 EFI_DEVICE_PATH_PROTOCOL
*DevicePathPtr
;
1108 // Check whether remaining device path is valid
1110 if (RemainingDevicePath
!= NULL
) {
1111 if ((RemainingDevicePath
->Type
!= MESSAGING_DEVICE_PATH
) ||
1112 (RemainingDevicePath
->SubType
!= MSG_USB_DP
&&
1113 RemainingDevicePath
->SubType
!= MSG_USB_CLASS_DP
1114 && RemainingDevicePath
->SubType
!= MSG_USB_WWID_DP
1116 return EFI_INVALID_PARAMETER
;
1120 if (UsbBusId
== NULL
){
1121 return EFI_INVALID_PARAMETER
;
1124 Bus
= USB_BUS_FROM_THIS (UsbBusId
);
1126 if (RemainingDevicePath
== NULL
) {
1128 // RemainingDevicePath== NULL means all Usb devices in this bus are wanted.
1129 // Here use a Usb class Device Path in WantedUsbIoDPList to indicate all Usb devices
1130 // are wanted Usb devices
1132 Status
= UsbBusFreeUsbDPList (&Bus
->WantedUsbIoDPList
);
1133 ASSERT (!EFI_ERROR (Status
));
1134 DevicePathPtr
= DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) &mAllUsbClassDevicePath
);
1137 // Create new Usb device path according to the usb part in remaining device path
1139 DevicePathPtr
= GetUsbDPFromFullDP (RemainingDevicePath
);
1142 ASSERT (DevicePathPtr
!= NULL
);
1143 Status
= AddUsbDPToList (DevicePathPtr
, &Bus
->WantedUsbIoDPList
);
1144 ASSERT (!EFI_ERROR (Status
));
1145 gBS
->FreePool (DevicePathPtr
);
1150 Check whether a usb child device is the wanted device in a bus.
1152 @param Bus The Usb bus's private data pointer.
1153 @param UsbIf The usb child device inferface.
1155 @retval True If a usb child device is the wanted device in a bus.
1156 @retval False If a usb child device is *NOT* the wanted device in a bus.
1161 UsbBusIsWantedUsbIO (
1163 IN USB_INTERFACE
*UsbIf
1166 EFI_DEVICE_PATH_PROTOCOL
*DevicePathPtr
;
1167 LIST_ENTRY
*WantedUsbIoDPListPtr
;
1168 LIST_ENTRY
*WantedListIndex
;
1169 DEVICE_PATH_LIST_ITEM
*WantedListItem
;
1171 UINTN FirstDevicePathSize
;
1174 // Check whether passed in parameters are valid
1176 if ((UsbIf
== NULL
) || (Bus
== NULL
)) {
1180 // Check whether UsbIf is Hub
1187 // Check whether all Usb devices in this bus are wanted
1189 if (SearchUsbDPInList ((EFI_DEVICE_PATH_PROTOCOL
*)&mAllUsbClassDevicePath
, &Bus
->WantedUsbIoDPList
)){
1194 // Check whether the Usb device match any item in WantedUsbIoDPList
1196 WantedUsbIoDPListPtr
= &Bus
->WantedUsbIoDPList
;
1198 // Create new Usb device path according to the usb part in UsbIo full device path
1200 DevicePathPtr
= GetUsbDPFromFullDP (UsbIf
->DevicePath
);
1201 ASSERT (DevicePathPtr
!= NULL
);
1204 WantedListIndex
= WantedUsbIoDPListPtr
->ForwardLink
;
1205 while (WantedListIndex
!= WantedUsbIoDPListPtr
){
1206 WantedListItem
= CR(WantedListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
1207 ASSERT (WantedListItem
->DevicePath
->Type
== MESSAGING_DEVICE_PATH
);
1208 switch (WantedListItem
->DevicePath
->SubType
) {
1210 FirstDevicePathSize
= GetDevicePathSize (WantedListItem
->DevicePath
);
1211 if (FirstDevicePathSize
== GetDevicePathSize (DevicePathPtr
)) {
1213 WantedListItem
->DevicePath
,
1215 GetDevicePathSize (DevicePathPtr
)) == 0
1221 case MSG_USB_CLASS_DP
:
1222 if (MatchUsbClass((USB_CLASS_DEVICE_PATH
*)WantedListItem
->DevicePath
, UsbIf
)) {
1226 case MSG_USB_WWID_DP
:
1227 if (MatchUsbWwid((USB_WWID_DEVICE_PATH
*)WantedListItem
->DevicePath
, UsbIf
)) {
1240 WantedListIndex
= WantedListIndex
->ForwardLink
;
1242 gBS
->FreePool (DevicePathPtr
);
1245 // Check whether the new Usb device path is wanted
1255 Recursively connnect every wanted usb child device to ensure they all fully connected.
1256 Check all the child Usb IO handles in this bus, recursively connecte if it is wanted usb child device.
1258 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.
1260 @retval EFI_SUCCESS Connect is done successfully.
1261 @retval EFI_INVALID_PARAMETER The parameter is invalid.
1266 UsbBusRecursivelyConnectWantedUsbIo (
1267 IN EFI_USB_BUS_PROTOCOL
*UsbBusId
1273 EFI_USB_IO_PROTOCOL
*UsbIo
;
1274 USB_INTERFACE
*UsbIf
;
1275 UINTN UsbIoHandleCount
;
1276 EFI_HANDLE
*UsbIoBuffer
;
1277 EFI_DEVICE_PATH_PROTOCOL
*UsbIoDevicePath
;
1279 if (UsbBusId
== NULL
){
1280 return EFI_INVALID_PARAMETER
;
1283 Bus
= USB_BUS_FROM_THIS (UsbBusId
);
1286 // Get all Usb IO handles in system
1288 UsbIoHandleCount
= 0;
1289 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiUsbIoProtocolGuid
, NULL
, &UsbIoHandleCount
, &UsbIoBuffer
);
1290 if (Status
== EFI_NOT_FOUND
|| UsbIoHandleCount
== 0) {
1293 ASSERT (!EFI_ERROR (Status
));
1295 for (Index
= 0; Index
< UsbIoHandleCount
; Index
++) {
1297 // Check whether the USB IO handle is a child of this bus
1298 // Note: The usb child handle maybe invalid because of hot plugged out during the loop
1300 UsbIoDevicePath
= NULL
;
1301 Status
= gBS
->HandleProtocol (UsbIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &UsbIoDevicePath
);
1302 if (EFI_ERROR (Status
) || UsbIoDevicePath
== NULL
) {
1308 (GetDevicePathSize (Bus
->DevicePath
) - sizeof (EFI_DEVICE_PATH_PROTOCOL
))
1314 // Get the child Usb IO interface
1316 Status
= gBS
->HandleProtocol(
1318 &gEfiUsbIoProtocolGuid
,
1321 if (EFI_ERROR (Status
)) {
1324 UsbIf
= USB_INTERFACE_FROM_USBIO (UsbIo
);
1326 if (UsbBusIsWantedUsbIO (Bus
, UsbIf
)) {
1327 if (!UsbIf
->IsManaged
) {
1329 // Recursively connect the wanted Usb Io handle
1331 DEBUG ((EFI_D_INFO
, "UsbConnectDriver: TPL before connect is %d\n", (UINT32
)UsbGetCurrentTpl ()));
1332 Status
= gBS
->ConnectController (UsbIf
->Handle
, NULL
, NULL
, TRUE
);
1333 UsbIf
->IsManaged
= (BOOLEAN
)!EFI_ERROR (Status
);
1334 DEBUG ((EFI_D_INFO
, "UsbConnectDriver: TPL after connect is %d\n", (UINT32
)UsbGetCurrentTpl()));