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 ASSERT (IfDesc
->ActiveIndex
< USB_MAX_INTERFACE_SETTING
);
932 ActIfDesc
= &(IfDesc
->Settings
[IfDesc
->ActiveIndex
]->Desc
);
933 DevDesc
= &(UsbIf
->Device
->DevDesc
->Desc
);
936 // If connect class policy, determine whether to create device handle by the five fields
937 // in class device path node.
939 // In addtion, hub interface is always matched for this policy.
941 if ((ActIfDesc
->InterfaceClass
== USB_HUB_CLASS_CODE
) &&
942 (ActIfDesc
->InterfaceSubClass
== USB_HUB_SUBCLASS_CODE
)) {
947 // If vendor id or product id is 0xffff, they will be ignored.
949 if ((UsbClassDevicePathPtr
->VendorId
== 0xffff || UsbClassDevicePathPtr
->VendorId
== DevDesc
->IdVendor
) &&
950 (UsbClassDevicePathPtr
->ProductId
== 0xffff || UsbClassDevicePathPtr
->ProductId
== DevDesc
->IdProduct
)) {
953 // If class or subclass or protocol is 0, the counterparts in interface should be checked.
955 if (DevDesc
->DeviceClass
== 0 ||
956 DevDesc
->DeviceSubClass
== 0 ||
957 DevDesc
->DeviceProtocol
== 0) {
959 if ((UsbClassDevicePathPtr
->DeviceClass
== ActIfDesc
->InterfaceClass
||
960 UsbClassDevicePathPtr
->DeviceClass
== 0xff) &&
961 (UsbClassDevicePathPtr
->DeviceSubClass
== ActIfDesc
->InterfaceSubClass
||
962 UsbClassDevicePathPtr
->DeviceSubClass
== 0xff) &&
963 (UsbClassDevicePathPtr
->DeviceProtocol
== ActIfDesc
->InterfaceProtocol
||
964 UsbClassDevicePathPtr
->DeviceProtocol
== 0xff)) {
968 } else if ((UsbClassDevicePathPtr
->DeviceClass
== DevDesc
->DeviceClass
||
969 UsbClassDevicePathPtr
->DeviceClass
== 0xff) &&
970 (UsbClassDevicePathPtr
->DeviceSubClass
== DevDesc
->DeviceSubClass
||
971 UsbClassDevicePathPtr
->DeviceSubClass
== 0xff) &&
972 (UsbClassDevicePathPtr
->DeviceProtocol
== DevDesc
->DeviceProtocol
||
973 UsbClassDevicePathPtr
->DeviceProtocol
== 0xff)) {
983 Check whether usb device, whose interface is UsbIf, matches the usb WWID requirement which indicated by
984 UsbWWIDDevicePathPtr whose is a short form usb WWID device path.
986 @param UsbWWIDDevicePathPtr a short form usb WWID device path.
987 @param UsbIf a usb device interface.
989 @retval TRUE the usb device match the usb WWID requirement.
990 @retval FALSE the usb device does not match the usb WWID requirement.
995 IN USB_WWID_DEVICE_PATH
*UsbWWIDDevicePathPtr
,
996 IN USB_INTERFACE
*UsbIf
999 USB_INTERFACE_DESC
*IfDesc
;
1000 EFI_USB_INTERFACE_DESCRIPTOR
*ActIfDesc
;
1001 EFI_USB_DEVICE_DESCRIPTOR
*DevDesc
;
1002 EFI_USB_STRING_DESCRIPTOR
*StrDesc
;
1005 if ((UsbWWIDDevicePathPtr
->Header
.Type
!= MESSAGING_DEVICE_PATH
) ||
1006 (UsbWWIDDevicePathPtr
->Header
.SubType
!= MSG_USB_WWID_DP
)){
1011 IfDesc
= UsbIf
->IfDesc
;
1012 ASSERT (IfDesc
->ActiveIndex
< USB_MAX_INTERFACE_SETTING
);
1013 ActIfDesc
= &(IfDesc
->Settings
[IfDesc
->ActiveIndex
]->Desc
);
1014 DevDesc
= &(UsbIf
->Device
->DevDesc
->Desc
);
1015 StrDesc
= UsbGetOneString (UsbIf
->Device
, DevDesc
->StrSerialNumber
, USB_US_LAND_ID
);
1016 SnString
= (UINT16
*) ((UINT8
*)UsbWWIDDevicePathPtr
+ 10);
1019 //In addtion, hub interface is always matched for this policy.
1021 if ((ActIfDesc
->InterfaceClass
== USB_HUB_CLASS_CODE
) &&
1022 (ActIfDesc
->InterfaceSubClass
== USB_HUB_SUBCLASS_CODE
)) {
1026 // If connect wwid policy, determine the objective device by the serial number of
1027 // device descriptor.
1028 // Get serial number index from device descriptor, then get serial number by index
1029 // and land id, compare the serial number with wwid device path node at last
1031 // BugBug: only check serial number here, should check Interface Number, Device Vendor Id, Device Product Id in later version
1033 if (StrDesc
!= NULL
&& (StrnCmp (StrDesc
->String
, SnString
, StrDesc
->Length
) == 0)) {
1042 Free a DEVICE_PATH_LIST_ITEM list.
1044 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list pointer.
1046 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value.
1047 @retval EFI_SUCCESS If free operation is successful, return this value.
1052 UsbBusFreeUsbDPList (
1053 IN LIST_ENTRY
*UsbIoDPList
1056 LIST_ENTRY
*ListIndex
;
1057 DEVICE_PATH_LIST_ITEM
*ListItem
;
1060 // Check that ControllerHandle is a valid handle
1062 if (UsbIoDPList
== NULL
) {
1063 return EFI_INVALID_PARAMETER
;
1066 ListIndex
= UsbIoDPList
->ForwardLink
;
1067 while (ListIndex
!= UsbIoDPList
){
1068 ListItem
= CR(ListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
1070 // Free DEVICE_PATH_LIST_ITEM.DevicePath[]
1072 if (ListItem
->DevicePath
!= NULL
){
1073 FreePool(ListItem
->DevicePath
);
1076 // Free DEVICE_PATH_LIST_ITEM itself
1078 ListIndex
= ListIndex
->ForwardLink
;
1079 RemoveEntryList (&ListItem
->Link
);
1080 FreePool (ListItem
);
1083 InitializeListHead (UsbIoDPList
);
1088 Store a wanted usb child device info (its Usb part of device path) which is indicated by
1089 RemainingDevicePath in a Usb bus which is indicated by UsbBusId.
1091 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.
1092 @param RemainingDevicePath The remaining device patch.
1094 @retval EFI_SUCCESS Add operation is successful.
1095 @retval EFI_INVALID_PARAMETER The parameters are invalid.
1100 UsbBusAddWantedUsbIoDP (
1101 IN EFI_USB_BUS_PROTOCOL
*UsbBusId
,
1102 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1107 EFI_DEVICE_PATH_PROTOCOL
*DevicePathPtr
;
1110 // Check whether remaining device path is valid
1112 if (RemainingDevicePath
!= NULL
) {
1113 if ((RemainingDevicePath
->Type
!= MESSAGING_DEVICE_PATH
) ||
1114 (RemainingDevicePath
->SubType
!= MSG_USB_DP
&&
1115 RemainingDevicePath
->SubType
!= MSG_USB_CLASS_DP
1116 && RemainingDevicePath
->SubType
!= MSG_USB_WWID_DP
1118 return EFI_INVALID_PARAMETER
;
1122 if (UsbBusId
== NULL
){
1123 return EFI_INVALID_PARAMETER
;
1126 Bus
= USB_BUS_FROM_THIS (UsbBusId
);
1128 if (RemainingDevicePath
== NULL
) {
1130 // RemainingDevicePath== NULL means all Usb devices in this bus are wanted.
1131 // Here use a Usb class Device Path in WantedUsbIoDPList to indicate all Usb devices
1132 // are wanted Usb devices
1134 Status
= UsbBusFreeUsbDPList (&Bus
->WantedUsbIoDPList
);
1135 ASSERT (!EFI_ERROR (Status
));
1136 DevicePathPtr
= DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) &mAllUsbClassDevicePath
);
1139 // Create new Usb device path according to the usb part in remaining device path
1141 DevicePathPtr
= GetUsbDPFromFullDP (RemainingDevicePath
);
1144 ASSERT (DevicePathPtr
!= NULL
);
1145 Status
= AddUsbDPToList (DevicePathPtr
, &Bus
->WantedUsbIoDPList
);
1146 ASSERT (!EFI_ERROR (Status
));
1147 gBS
->FreePool (DevicePathPtr
);
1152 Check whether a usb child device is the wanted device in a bus.
1154 @param Bus The Usb bus's private data pointer.
1155 @param UsbIf The usb child device inferface.
1157 @retval True If a usb child device is the wanted device in a bus.
1158 @retval False If a usb child device is *NOT* the wanted device in a bus.
1163 UsbBusIsWantedUsbIO (
1165 IN USB_INTERFACE
*UsbIf
1168 EFI_DEVICE_PATH_PROTOCOL
*DevicePathPtr
;
1169 LIST_ENTRY
*WantedUsbIoDPListPtr
;
1170 LIST_ENTRY
*WantedListIndex
;
1171 DEVICE_PATH_LIST_ITEM
*WantedListItem
;
1173 UINTN FirstDevicePathSize
;
1176 // Check whether passed in parameters are valid
1178 if ((UsbIf
== NULL
) || (Bus
== NULL
)) {
1182 // Check whether UsbIf is Hub
1189 // Check whether all Usb devices in this bus are wanted
1191 if (SearchUsbDPInList ((EFI_DEVICE_PATH_PROTOCOL
*)&mAllUsbClassDevicePath
, &Bus
->WantedUsbIoDPList
)){
1196 // Check whether the Usb device match any item in WantedUsbIoDPList
1198 WantedUsbIoDPListPtr
= &Bus
->WantedUsbIoDPList
;
1200 // Create new Usb device path according to the usb part in UsbIo full device path
1202 DevicePathPtr
= GetUsbDPFromFullDP (UsbIf
->DevicePath
);
1203 ASSERT (DevicePathPtr
!= NULL
);
1206 WantedListIndex
= WantedUsbIoDPListPtr
->ForwardLink
;
1207 while (WantedListIndex
!= WantedUsbIoDPListPtr
){
1208 WantedListItem
= CR(WantedListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
1209 ASSERT (WantedListItem
->DevicePath
->Type
== MESSAGING_DEVICE_PATH
);
1210 switch (WantedListItem
->DevicePath
->SubType
) {
1212 FirstDevicePathSize
= GetDevicePathSize (WantedListItem
->DevicePath
);
1213 if (FirstDevicePathSize
== GetDevicePathSize (DevicePathPtr
)) {
1215 WantedListItem
->DevicePath
,
1217 GetDevicePathSize (DevicePathPtr
)) == 0
1223 case MSG_USB_CLASS_DP
:
1224 if (MatchUsbClass((USB_CLASS_DEVICE_PATH
*)WantedListItem
->DevicePath
, UsbIf
)) {
1228 case MSG_USB_WWID_DP
:
1229 if (MatchUsbWwid((USB_WWID_DEVICE_PATH
*)WantedListItem
->DevicePath
, UsbIf
)) {
1242 WantedListIndex
= WantedListIndex
->ForwardLink
;
1244 gBS
->FreePool (DevicePathPtr
);
1247 // Check whether the new Usb device path is wanted
1257 Recursively connnect every wanted usb child device to ensure they all fully connected.
1258 Check all the child Usb IO handles in this bus, recursively connecte if it is wanted usb child device.
1260 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.
1262 @retval EFI_SUCCESS Connect is done successfully.
1263 @retval EFI_INVALID_PARAMETER The parameter is invalid.
1268 UsbBusRecursivelyConnectWantedUsbIo (
1269 IN EFI_USB_BUS_PROTOCOL
*UsbBusId
1275 EFI_USB_IO_PROTOCOL
*UsbIo
;
1276 USB_INTERFACE
*UsbIf
;
1277 UINTN UsbIoHandleCount
;
1278 EFI_HANDLE
*UsbIoBuffer
;
1279 EFI_DEVICE_PATH_PROTOCOL
*UsbIoDevicePath
;
1281 if (UsbBusId
== NULL
){
1282 return EFI_INVALID_PARAMETER
;
1285 Bus
= USB_BUS_FROM_THIS (UsbBusId
);
1288 // Get all Usb IO handles in system
1290 UsbIoHandleCount
= 0;
1291 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiUsbIoProtocolGuid
, NULL
, &UsbIoHandleCount
, &UsbIoBuffer
);
1292 if (Status
== EFI_NOT_FOUND
|| UsbIoHandleCount
== 0) {
1295 ASSERT (!EFI_ERROR (Status
));
1297 for (Index
= 0; Index
< UsbIoHandleCount
; Index
++) {
1299 // Check whether the USB IO handle is a child of this bus
1300 // Note: The usb child handle maybe invalid because of hot plugged out during the loop
1302 UsbIoDevicePath
= NULL
;
1303 Status
= gBS
->HandleProtocol (UsbIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &UsbIoDevicePath
);
1304 if (EFI_ERROR (Status
) || UsbIoDevicePath
== NULL
) {
1310 (GetDevicePathSize (Bus
->DevicePath
) - sizeof (EFI_DEVICE_PATH_PROTOCOL
))
1316 // Get the child Usb IO interface
1318 Status
= gBS
->HandleProtocol(
1320 &gEfiUsbIoProtocolGuid
,
1323 if (EFI_ERROR (Status
)) {
1326 UsbIf
= USB_INTERFACE_FROM_USBIO (UsbIo
);
1328 if (UsbBusIsWantedUsbIO (Bus
, UsbIf
)) {
1329 if (!UsbIf
->IsManaged
) {
1331 // Recursively connect the wanted Usb Io handle
1333 DEBUG ((EFI_D_INFO
, "UsbConnectDriver: TPL before connect is %d\n", (UINT32
)UsbGetCurrentTpl ()));
1334 Status
= gBS
->ConnectController (UsbIf
->Handle
, NULL
, NULL
, TRUE
);
1335 UsbIf
->IsManaged
= (BOOLEAN
)!EFI_ERROR (Status
);
1336 DEBUG ((EFI_D_INFO
, "UsbConnectDriver: TPL after connect is %d\n", (UINT32
)UsbGetCurrentTpl()));