3 Wrapper function for usb host controller interface.
5 Copyright (c) 2007 - 2010, 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
;
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 in Device Descriptor is set to 0, the counterparts in interface should be checked.
955 if (DevDesc
->DeviceClass
== 0) {
956 if ((UsbClassDevicePathPtr
->DeviceClass
== ActIfDesc
->InterfaceClass
||
957 UsbClassDevicePathPtr
->DeviceClass
== 0xff) &&
958 (UsbClassDevicePathPtr
->DeviceSubClass
== ActIfDesc
->InterfaceSubClass
||
959 UsbClassDevicePathPtr
->DeviceSubClass
== 0xff) &&
960 (UsbClassDevicePathPtr
->DeviceProtocol
== ActIfDesc
->InterfaceProtocol
||
961 UsbClassDevicePathPtr
->DeviceProtocol
== 0xff)) {
965 } else if ((UsbClassDevicePathPtr
->DeviceClass
== DevDesc
->DeviceClass
||
966 UsbClassDevicePathPtr
->DeviceClass
== 0xff) &&
967 (UsbClassDevicePathPtr
->DeviceSubClass
== DevDesc
->DeviceSubClass
||
968 UsbClassDevicePathPtr
->DeviceSubClass
== 0xff) &&
969 (UsbClassDevicePathPtr
->DeviceProtocol
== DevDesc
->DeviceProtocol
||
970 UsbClassDevicePathPtr
->DeviceProtocol
== 0xff)) {
980 Check whether usb device, whose interface is UsbIf, matches the usb WWID requirement which indicated by
981 UsbWWIDDevicePathPtr whose is a short form usb WWID device path.
983 @param UsbWWIDDevicePathPtr a short form usb WWID device path.
984 @param UsbIf a usb device interface.
986 @retval TRUE the usb device match the usb WWID requirement.
987 @retval FALSE the usb device does not match the usb WWID requirement.
992 IN USB_WWID_DEVICE_PATH
*UsbWWIDDevicePathPtr
,
993 IN USB_INTERFACE
*UsbIf
996 USB_INTERFACE_DESC
*IfDesc
;
997 EFI_USB_INTERFACE_DESCRIPTOR
*ActIfDesc
;
998 EFI_USB_DEVICE_DESCRIPTOR
*DevDesc
;
999 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
);
1017 // In addition, Hub interface is always matched for this policy.
1019 if ((ActIfDesc
->InterfaceClass
== USB_HUB_CLASS_CODE
) &&
1020 (ActIfDesc
->InterfaceSubClass
== USB_HUB_SUBCLASS_CODE
)) {
1025 // Check Vendor Id, Product Id and Interface Number.
1027 if ((DevDesc
->IdVendor
!= UsbWWIDDevicePathPtr
->VendorId
) ||
1028 (DevDesc
->IdProduct
!= UsbWWIDDevicePathPtr
->ProductId
) ||
1029 (ActIfDesc
->InterfaceNumber
!= UsbWWIDDevicePathPtr
->InterfaceNumber
)) {
1034 // Check SerialNumber.
1036 if (DevDesc
->StrSerialNumber
== 0) {
1041 // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters.
1043 CompareStr
= (CHAR16
*) (UINTN
) (UsbWWIDDevicePathPtr
+ 1);
1044 CompareLen
= (DevicePathNodeLength (UsbWWIDDevicePathPtr
) - sizeof (USB_WWID_DEVICE_PATH
)) / sizeof (CHAR16
);
1045 if (CompareStr
[CompareLen
- 1] == L
'\0') {
1050 // Compare serial number in each supported language.
1052 for (Index
= 0; Index
< UsbIf
->Device
->TotalLangId
; Index
++) {
1053 StrDesc
= UsbGetOneString (UsbIf
->Device
, DevDesc
->StrSerialNumber
, UsbIf
->Device
->LangId
[Index
]);
1054 if (StrDesc
== NULL
) {
1058 Length
= (StrDesc
->Length
- 2) / sizeof (CHAR16
);
1059 if ((Length
>= CompareLen
) &&
1060 (CompareMem (StrDesc
->String
+ Length
- CompareLen
, CompareStr
, CompareLen
* sizeof (CHAR16
)) == 0)) {
1069 Free a DEVICE_PATH_LIST_ITEM list.
1071 @param UsbIoDPList a DEVICE_PATH_LIST_ITEM list pointer.
1073 @retval EFI_INVALID_PARAMETER If parameters are invalid, return this value.
1074 @retval EFI_SUCCESS If free operation is successful, return this value.
1079 UsbBusFreeUsbDPList (
1080 IN LIST_ENTRY
*UsbIoDPList
1083 LIST_ENTRY
*ListIndex
;
1084 DEVICE_PATH_LIST_ITEM
*ListItem
;
1087 // Check that ControllerHandle is a valid handle
1089 if (UsbIoDPList
== NULL
) {
1090 return EFI_INVALID_PARAMETER
;
1093 ListIndex
= UsbIoDPList
->ForwardLink
;
1094 while (ListIndex
!= UsbIoDPList
){
1095 ListItem
= CR(ListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
1097 // Free DEVICE_PATH_LIST_ITEM.DevicePath[]
1099 if (ListItem
->DevicePath
!= NULL
){
1100 FreePool(ListItem
->DevicePath
);
1103 // Free DEVICE_PATH_LIST_ITEM itself
1105 ListIndex
= ListIndex
->ForwardLink
;
1106 RemoveEntryList (&ListItem
->Link
);
1107 FreePool (ListItem
);
1110 InitializeListHead (UsbIoDPList
);
1115 Store a wanted usb child device info (its Usb part of device path) which is indicated by
1116 RemainingDevicePath in a Usb bus which is indicated by UsbBusId.
1118 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.
1119 @param RemainingDevicePath The remaining device patch.
1121 @retval EFI_SUCCESS Add operation is successful.
1122 @retval EFI_INVALID_PARAMETER The parameters are invalid.
1127 UsbBusAddWantedUsbIoDP (
1128 IN EFI_USB_BUS_PROTOCOL
*UsbBusId
,
1129 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1134 EFI_DEVICE_PATH_PROTOCOL
*DevicePathPtr
;
1137 // Check whether remaining device path is valid
1139 if (RemainingDevicePath
!= NULL
&& !IsDevicePathEnd (RemainingDevicePath
)) {
1140 if ((RemainingDevicePath
->Type
!= MESSAGING_DEVICE_PATH
) ||
1141 (RemainingDevicePath
->SubType
!= MSG_USB_DP
&&
1142 RemainingDevicePath
->SubType
!= MSG_USB_CLASS_DP
1143 && RemainingDevicePath
->SubType
!= MSG_USB_WWID_DP
1145 return EFI_INVALID_PARAMETER
;
1149 if (UsbBusId
== NULL
){
1150 return EFI_INVALID_PARAMETER
;
1153 Bus
= USB_BUS_FROM_THIS (UsbBusId
);
1155 if (RemainingDevicePath
== NULL
) {
1157 // RemainingDevicePath == NULL means all Usb devices in this bus are wanted.
1158 // Here use a Usb class Device Path in WantedUsbIoDPList to indicate all Usb devices
1159 // are wanted Usb devices
1161 Status
= UsbBusFreeUsbDPList (&Bus
->WantedUsbIoDPList
);
1162 ASSERT (!EFI_ERROR (Status
));
1163 DevicePathPtr
= DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL
*) &mAllUsbClassDevicePath
);
1164 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
1166 // If RemainingDevicePath isn't the End of Device Path Node,
1167 // Create new Usb device path according to the usb part in remaining device path
1169 DevicePathPtr
= GetUsbDPFromFullDP (RemainingDevicePath
);
1172 // If RemainingDevicePath is the End of Device Path Node,
1173 // skip enumerate any device and return EFI_SUCESSS
1178 ASSERT (DevicePathPtr
!= NULL
);
1179 Status
= AddUsbDPToList (DevicePathPtr
, &Bus
->WantedUsbIoDPList
);
1180 ASSERT (!EFI_ERROR (Status
));
1181 FreePool (DevicePathPtr
);
1186 Check whether a usb child device is the wanted device in a bus.
1188 @param Bus The Usb bus's private data pointer.
1189 @param UsbIf The usb child device inferface.
1191 @retval True If a usb child device is the wanted device in a bus.
1192 @retval False If a usb child device is *NOT* the wanted device in a bus.
1197 UsbBusIsWantedUsbIO (
1199 IN USB_INTERFACE
*UsbIf
1202 EFI_DEVICE_PATH_PROTOCOL
*DevicePathPtr
;
1203 LIST_ENTRY
*WantedUsbIoDPListPtr
;
1204 LIST_ENTRY
*WantedListIndex
;
1205 DEVICE_PATH_LIST_ITEM
*WantedListItem
;
1207 UINTN FirstDevicePathSize
;
1210 // Check whether passed in parameters are valid
1212 if ((UsbIf
== NULL
) || (Bus
== NULL
)) {
1216 // Check whether UsbIf is Hub
1223 // Check whether all Usb devices in this bus are wanted
1225 if (SearchUsbDPInList ((EFI_DEVICE_PATH_PROTOCOL
*)&mAllUsbClassDevicePath
, &Bus
->WantedUsbIoDPList
)){
1230 // Check whether the Usb device match any item in WantedUsbIoDPList
1232 WantedUsbIoDPListPtr
= &Bus
->WantedUsbIoDPList
;
1234 // Create new Usb device path according to the usb part in UsbIo full device path
1236 DevicePathPtr
= GetUsbDPFromFullDP (UsbIf
->DevicePath
);
1237 ASSERT (DevicePathPtr
!= NULL
);
1240 WantedListIndex
= WantedUsbIoDPListPtr
->ForwardLink
;
1241 while (WantedListIndex
!= WantedUsbIoDPListPtr
){
1242 WantedListItem
= CR(WantedListIndex
, DEVICE_PATH_LIST_ITEM
, Link
, DEVICE_PATH_LIST_ITEM_SIGNATURE
);
1243 ASSERT (WantedListItem
->DevicePath
->Type
== MESSAGING_DEVICE_PATH
);
1244 switch (WantedListItem
->DevicePath
->SubType
) {
1246 FirstDevicePathSize
= GetDevicePathSize (WantedListItem
->DevicePath
);
1247 if (FirstDevicePathSize
== GetDevicePathSize (DevicePathPtr
)) {
1249 WantedListItem
->DevicePath
,
1251 GetDevicePathSize (DevicePathPtr
)) == 0
1257 case MSG_USB_CLASS_DP
:
1258 if (MatchUsbClass((USB_CLASS_DEVICE_PATH
*)WantedListItem
->DevicePath
, UsbIf
)) {
1262 case MSG_USB_WWID_DP
:
1263 if (MatchUsbWwid((USB_WWID_DEVICE_PATH
*)WantedListItem
->DevicePath
, UsbIf
)) {
1276 WantedListIndex
= WantedListIndex
->ForwardLink
;
1278 gBS
->FreePool (DevicePathPtr
);
1281 // Check whether the new Usb device path is wanted
1291 Recursively connnect every wanted usb child device to ensure they all fully connected.
1292 Check all the child Usb IO handles in this bus, recursively connecte if it is wanted usb child device.
1294 @param UsbBusId Point to EFI_USB_BUS_PROTOCOL interface.
1296 @retval EFI_SUCCESS Connect is done successfully.
1297 @retval EFI_INVALID_PARAMETER The parameter is invalid.
1302 UsbBusRecursivelyConnectWantedUsbIo (
1303 IN EFI_USB_BUS_PROTOCOL
*UsbBusId
1309 EFI_USB_IO_PROTOCOL
*UsbIo
;
1310 USB_INTERFACE
*UsbIf
;
1311 UINTN UsbIoHandleCount
;
1312 EFI_HANDLE
*UsbIoBuffer
;
1313 EFI_DEVICE_PATH_PROTOCOL
*UsbIoDevicePath
;
1315 if (UsbBusId
== NULL
){
1316 return EFI_INVALID_PARAMETER
;
1319 Bus
= USB_BUS_FROM_THIS (UsbBusId
);
1322 // Get all Usb IO handles in system
1324 UsbIoHandleCount
= 0;
1325 Status
= gBS
->LocateHandleBuffer (ByProtocol
, &gEfiUsbIoProtocolGuid
, NULL
, &UsbIoHandleCount
, &UsbIoBuffer
);
1326 if (Status
== EFI_NOT_FOUND
|| UsbIoHandleCount
== 0) {
1329 ASSERT (!EFI_ERROR (Status
));
1331 for (Index
= 0; Index
< UsbIoHandleCount
; Index
++) {
1333 // Check whether the USB IO handle is a child of this bus
1334 // Note: The usb child handle maybe invalid because of hot plugged out during the loop
1336 UsbIoDevicePath
= NULL
;
1337 Status
= gBS
->HandleProtocol (UsbIoBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*) &UsbIoDevicePath
);
1338 if (EFI_ERROR (Status
) || UsbIoDevicePath
== NULL
) {
1344 (GetDevicePathSize (Bus
->DevicePath
) - sizeof (EFI_DEVICE_PATH_PROTOCOL
))
1350 // Get the child Usb IO interface
1352 Status
= gBS
->HandleProtocol(
1354 &gEfiUsbIoProtocolGuid
,
1357 if (EFI_ERROR (Status
)) {
1360 UsbIf
= USB_INTERFACE_FROM_USBIO (UsbIo
);
1362 if (UsbBusIsWantedUsbIO (Bus
, UsbIf
)) {
1363 if (!UsbIf
->IsManaged
) {
1365 // Recursively connect the wanted Usb Io handle
1367 DEBUG ((EFI_D_INFO
, "UsbConnectDriver: TPL before connect is %d\n", (UINT32
)UsbGetCurrentTpl ()));
1368 Status
= gBS
->ConnectController (UsbIf
->Handle
, NULL
, NULL
, TRUE
);
1369 UsbIf
->IsManaged
= (BOOLEAN
)!EFI_ERROR (Status
);
1370 DEBUG ((EFI_D_INFO
, "UsbConnectDriver: TPL after connect is %d\n", (UINT32
)UsbGetCurrentTpl()));
1375 FreePool (UsbIoBuffer
);