TianoCore EDK2 master
Loading...
Searching...
No Matches
UsbUtility.c
Go to the documentation of this file.
1
10#include "UsbBus.h"
11
12//
13// if RemainingDevicePath== NULL, then all Usb child devices in this bus are wanted.
14// Use a shor form Usb class Device Path, which could match any usb device, in WantedUsbIoDPList to indicate all Usb devices
15// are wanted Usb devices
16//
17USB_CLASS_FORMAT_DEVICE_PATH mAllUsbClassDevicePath = {
18 {
19 {
22 {
23 (UINT8)(sizeof (USB_CLASS_DEVICE_PATH)),
24 (UINT8)((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
25 }
26 },
27 0xffff, // VendorId
28 0xffff, // ProductId
29 0xff, // DeviceClass
30 0xff, // DeviceSubClass
31 0xff // DeviceProtocol
32 },
33
34 {
35 END_DEVICE_PATH_TYPE,
36 END_ENTIRE_DEVICE_PATH_SUBTYPE,
37 {
38 END_DEVICE_PATH_LENGTH,
39 0
40 }
41 }
42};
43
58 IN USB_BUS *UsbBus,
59 OUT UINT8 *MaxSpeed,
60 OUT UINT8 *NumOfPort,
61 OUT UINT8 *Is64BitCapable
62 )
63{
64 EFI_STATUS Status;
65
66 if (UsbBus->Usb2Hc != NULL) {
67 Status = UsbBus->Usb2Hc->GetCapability (
68 UsbBus->Usb2Hc,
69 MaxSpeed,
70 NumOfPort,
71 Is64BitCapable
72 );
73 } else {
74 Status = UsbBus->UsbHc->GetRootHubPortNumber (UsbBus->UsbHc, NumOfPort);
75
76 *MaxSpeed = EFI_USB_SPEED_FULL;
77 *Is64BitCapable = (UINT8)FALSE;
78 }
79
80 return Status;
81}
82
96 IN USB_BUS *UsbBus,
97 IN UINT8 PortIndex,
98 OUT EFI_USB_PORT_STATUS *PortStatus
99 )
100{
101 EFI_STATUS Status;
102
103 if (UsbBus->Usb2Hc != NULL) {
104 Status = UsbBus->Usb2Hc->GetRootHubPortStatus (UsbBus->Usb2Hc, PortIndex, PortStatus);
105 } else {
106 Status = UsbBus->UsbHc->GetRootHubPortStatus (UsbBus->UsbHc, PortIndex, PortStatus);
107 }
108
109 return Status;
110}
111
125 IN USB_BUS *UsbBus,
126 IN UINT8 PortIndex,
128 )
129{
130 EFI_STATUS Status;
131
132 if (UsbBus->Usb2Hc != NULL) {
133 Status = UsbBus->Usb2Hc->SetRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature);
134 } else {
135 Status = UsbBus->UsbHc->SetRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature);
136 }
137
138 return Status;
139}
140
154 IN USB_BUS *UsbBus,
155 IN UINT8 PortIndex,
157 )
158{
159 EFI_STATUS Status;
160
161 if (UsbBus->Usb2Hc != NULL) {
162 Status = UsbBus->Usb2Hc->ClearRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature);
163 } else {
164 Status = UsbBus->UsbHc->ClearRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature);
165 }
166
167 return Status;
168}
169
191 IN USB_BUS *UsbBus,
192 IN UINT8 DevAddr,
193 IN UINT8 DevSpeed,
194 IN UINTN MaxPacket,
195 IN EFI_USB_DEVICE_REQUEST *Request,
196 IN EFI_USB_DATA_DIRECTION Direction,
197 IN OUT VOID *Data,
198 IN OUT UINTN *DataLength,
199 IN UINTN TimeOut,
201 OUT UINT32 *UsbResult
202 )
203{
204 EFI_STATUS Status;
205 BOOLEAN IsSlowDevice;
206
207 if (UsbBus->Usb2Hc != NULL) {
208 Status = UsbBus->Usb2Hc->ControlTransfer (
209 UsbBus->Usb2Hc,
210 DevAddr,
211 DevSpeed,
212 MaxPacket,
213 Request,
214 Direction,
215 Data,
216 DataLength,
217 TimeOut,
218 Translator,
219 UsbResult
220 );
221 } else {
222 IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed);
223 Status = UsbBus->UsbHc->ControlTransfer (
224 UsbBus->UsbHc,
225 DevAddr,
226 IsSlowDevice,
227 (UINT8)MaxPacket,
228 Request,
229 Direction,
230 Data,
231 DataLength,
232 TimeOut,
233 UsbResult
234 );
235 }
236
237 return Status;
238}
239
264 IN USB_BUS *UsbBus,
265 IN UINT8 DevAddr,
266 IN UINT8 EpAddr,
267 IN UINT8 DevSpeed,
268 IN UINTN MaxPacket,
269 IN UINT8 BufferNum,
270 IN OUT VOID *Data[],
271 IN OUT UINTN *DataLength,
272 IN OUT UINT8 *DataToggle,
273 IN UINTN TimeOut,
275 OUT UINT32 *UsbResult
276 )
277{
278 EFI_STATUS Status;
279
280 if (UsbBus->Usb2Hc != NULL) {
281 Status = UsbBus->Usb2Hc->BulkTransfer (
282 UsbBus->Usb2Hc,
283 DevAddr,
284 EpAddr,
285 DevSpeed,
286 MaxPacket,
287 BufferNum,
288 Data,
289 DataLength,
290 DataToggle,
291 TimeOut,
292 Translator,
293 UsbResult
294 );
295 } else {
296 Status = UsbBus->UsbHc->BulkTransfer (
297 UsbBus->UsbHc,
298 DevAddr,
299 EpAddr,
300 (UINT8)MaxPacket,
301 *Data,
302 DataLength,
303 DataToggle,
304 TimeOut,
305 UsbResult
306 );
307 }
308
309 return Status;
310}
311
336 IN USB_BUS *UsbBus,
337 IN UINT8 DevAddr,
338 IN UINT8 EpAddr,
339 IN UINT8 DevSpeed,
340 IN UINTN MaxPacket,
341 IN BOOLEAN IsNewTransfer,
342 IN OUT UINT8 *DataToggle,
343 IN UINTN PollingInterval,
344 IN UINTN DataLength,
347 IN VOID *Context OPTIONAL
348 )
349{
350 EFI_STATUS Status;
351 BOOLEAN IsSlowDevice;
352
353 if (UsbBus->Usb2Hc != NULL) {
354 Status = UsbBus->Usb2Hc->AsyncInterruptTransfer (
355 UsbBus->Usb2Hc,
356 DevAddr,
357 EpAddr,
358 DevSpeed,
359 MaxPacket,
360 IsNewTransfer,
361 DataToggle,
362 PollingInterval,
363 DataLength,
364 Translator,
365 Callback,
366 Context
367 );
368 } else {
369 IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed);
370
371 Status = UsbBus->UsbHc->AsyncInterruptTransfer (
372 UsbBus->UsbHc,
373 DevAddr,
374 EpAddr,
375 IsSlowDevice,
376 (UINT8)MaxPacket,
377 IsNewTransfer,
378 DataToggle,
379 PollingInterval,
380 DataLength,
381 Callback,
382 Context
383 );
384 }
385
386 return Status;
387}
388
412 IN USB_BUS *UsbBus,
413 IN UINT8 DevAddr,
414 IN UINT8 EpAddr,
415 IN UINT8 DevSpeed,
416 IN UINTN MaxPacket,
417 IN OUT VOID *Data,
418 IN OUT UINTN *DataLength,
419 IN OUT UINT8 *DataToggle,
420 IN UINTN TimeOut,
422 OUT UINT32 *UsbResult
423 )
424{
425 EFI_STATUS Status;
426 BOOLEAN IsSlowDevice;
427
428 if (UsbBus->Usb2Hc != NULL) {
429 Status = UsbBus->Usb2Hc->SyncInterruptTransfer (
430 UsbBus->Usb2Hc,
431 DevAddr,
432 EpAddr,
433 DevSpeed,
434 MaxPacket,
435 Data,
436 DataLength,
437 DataToggle,
438 TimeOut,
439 Translator,
440 UsbResult
441 );
442 } else {
443 IsSlowDevice = (BOOLEAN)((EFI_USB_SPEED_LOW == DevSpeed) ? TRUE : FALSE);
444 Status = UsbBus->UsbHc->SyncInterruptTransfer (
445 UsbBus->UsbHc,
446 DevAddr,
447 EpAddr,
448 IsSlowDevice,
449 (UINT8)MaxPacket,
450 Data,
451 DataLength,
452 DataToggle,
453 TimeOut,
454 UsbResult
455 );
456 }
457
458 return Status;
459}
460
472 IN USB_BUS *Bus,
474 )
475{
476 EFI_USB_HC_PROTOCOL *UsbHc;
477 EFI_USB2_HC_PROTOCOL *Usb2Hc;
478 EFI_STATUS Status;
479
480 if (Bus->Usb2Hc != NULL) {
481 Status = gBS->OpenProtocol (
482 Bus->HostHandle,
483 &gEfiUsb2HcProtocolGuid,
484 (VOID **)&Usb2Hc,
485 mUsbBusDriverBinding.DriverBindingHandle,
486 Child,
487 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
488 );
489 } else {
490 Status = gBS->OpenProtocol (
491 Bus->HostHandle,
492 &gEfiUsbHcProtocolGuid,
493 (VOID **)&UsbHc,
494 mUsbBusDriverBinding.DriverBindingHandle,
495 Child,
496 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
497 );
498 }
499
500 return Status;
501}
502
510VOID
512 IN USB_BUS *Bus,
514 )
515{
516 if (Bus->Usb2Hc != NULL) {
517 gBS->CloseProtocol (
518 Bus->HostHandle,
519 &gEfiUsb2HcProtocolGuid,
520 mUsbBusDriverBinding.DriverBindingHandle,
521 Child
522 );
523 } else {
524 gBS->CloseProtocol (
525 Bus->HostHandle,
526 &gEfiUsbHcProtocolGuid,
527 mUsbBusDriverBinding.DriverBindingHandle,
528 Child
529 );
530 }
531}
532
543 VOID
544 )
545{
546 EFI_TPL Tpl;
547
548 Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
549 gBS->RestoreTPL (Tpl);
550
551 return Tpl;
552}
553
563EFIAPI
565 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
566 )
567{
568 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathPtr;
569 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathBeginPtr;
570 EFI_DEVICE_PATH_PROTOCOL *UsbDevicePathEndPtr;
571 UINTN Size;
572
573 //
574 // Get the Usb part first Begin node in full device path
575 //
576 UsbDevicePathBeginPtr = DevicePath;
577 while ((!IsDevicePathEnd (UsbDevicePathBeginPtr)) &&
578 ((UsbDevicePathBeginPtr->Type != MESSAGING_DEVICE_PATH) ||
579 ( UsbDevicePathBeginPtr->SubType != MSG_USB_DP &&
580 UsbDevicePathBeginPtr->SubType != MSG_USB_CLASS_DP
581 && UsbDevicePathBeginPtr->SubType != MSG_USB_WWID_DP
582 )))
583 {
584 UsbDevicePathBeginPtr = NextDevicePathNode (UsbDevicePathBeginPtr);
585 }
586
587 //
588 // Get the Usb part first End node in full device path
589 //
590 UsbDevicePathEndPtr = UsbDevicePathBeginPtr;
591 while ((!IsDevicePathEnd (UsbDevicePathEndPtr)) &&
592 (UsbDevicePathEndPtr->Type == MESSAGING_DEVICE_PATH) &&
593 ( UsbDevicePathEndPtr->SubType == MSG_USB_DP ||
594 UsbDevicePathEndPtr->SubType == MSG_USB_CLASS_DP
595 || UsbDevicePathEndPtr->SubType == MSG_USB_WWID_DP
596 ))
597 {
598 UsbDevicePathEndPtr = NextDevicePathNode (UsbDevicePathEndPtr);
599 }
600
601 Size = GetDevicePathSize (UsbDevicePathBeginPtr);
602 Size -= GetDevicePathSize (UsbDevicePathEndPtr);
603 if (Size == 0) {
604 //
605 // The passed in DevicePath does not contain the usb nodes
606 //
607 return NULL;
608 }
609
610 //
611 // Create a new device path which only contain the above Usb part
612 //
613 UsbDevicePathPtr = AllocateZeroPool (Size + sizeof (EFI_DEVICE_PATH_PROTOCOL));
614 ASSERT (UsbDevicePathPtr != NULL);
615 CopyMem (UsbDevicePathPtr, UsbDevicePathBeginPtr, Size);
616 //
617 // Append end device path node
618 //
619 UsbDevicePathEndPtr = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)UsbDevicePathPtr + Size);
620 SetDevicePathEndNode (UsbDevicePathEndPtr);
621 return UsbDevicePathPtr;
622}
623
634BOOLEAN
635EFIAPI
638 IN LIST_ENTRY *UsbIoDPList
639 )
640{
641 LIST_ENTRY *ListIndex;
642 DEVICE_PATH_LIST_ITEM *ListItem;
643 BOOLEAN Found;
644 UINTN UsbDpDevicePathSize;
645
646 //
647 // Check that UsbDP and UsbIoDPList are valid
648 //
649 if ((UsbIoDPList == NULL) || (UsbDP == NULL)) {
650 return FALSE;
651 }
652
653 Found = FALSE;
654 ListIndex = UsbIoDPList->ForwardLink;
655 while (ListIndex != UsbIoDPList) {
656 ListItem = CR (ListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE);
657 //
658 // Compare DEVICE_PATH_LIST_ITEM.DevicePath[]
659 //
660 ASSERT (ListItem->DevicePath != NULL);
661
662 UsbDpDevicePathSize = GetDevicePathSize (UsbDP);
663 if (UsbDpDevicePathSize == GetDevicePathSize (ListItem->DevicePath)) {
664 if ((CompareMem (UsbDP, ListItem->DevicePath, UsbDpDevicePathSize)) == 0) {
665 Found = TRUE;
666 break;
667 }
668 }
669
670 ListIndex = ListIndex->ForwardLink;
671 }
672
673 return Found;
674}
675
687EFIAPI
690 IN LIST_ENTRY *UsbIoDPList
691 )
692{
693 DEVICE_PATH_LIST_ITEM *ListItem;
694
695 //
696 // Check that UsbDP and UsbIoDPList are valid
697 //
698 if ((UsbIoDPList == NULL) || (UsbDP == NULL)) {
699 return EFI_INVALID_PARAMETER;
700 }
701
702 if (SearchUsbDPInList (UsbDP, UsbIoDPList)) {
703 return EFI_SUCCESS;
704 }
705
706 //
707 // Prepare the usbio device path DEVICE_PATH_LIST_ITEM structure.
708 //
709 ListItem = AllocateZeroPool (sizeof (DEVICE_PATH_LIST_ITEM));
710 ASSERT (ListItem != NULL);
711 ListItem->Signature = DEVICE_PATH_LIST_ITEM_SIGNATURE;
712 ListItem->DevicePath = DuplicateDevicePath (UsbDP);
713
714 InsertTailList (UsbIoDPList, &ListItem->Link);
715
716 return EFI_SUCCESS;
717}
718
730BOOLEAN
731EFIAPI
733 IN USB_CLASS_DEVICE_PATH *UsbClassDevicePathPtr,
734 IN USB_INTERFACE *UsbIf
735 )
736{
737 USB_INTERFACE_DESC *IfDesc;
740
741 if ((UsbClassDevicePathPtr->Header.Type != MESSAGING_DEVICE_PATH) ||
742 (UsbClassDevicePathPtr->Header.SubType != MSG_USB_CLASS_DP))
743 {
744 ASSERT (0);
745 return FALSE;
746 }
747
748 IfDesc = UsbIf->IfDesc;
749 ASSERT (IfDesc->ActiveIndex < USB_MAX_INTERFACE_SETTING);
750 ActIfDesc = &(IfDesc->Settings[IfDesc->ActiveIndex]->Desc);
751 DevDesc = &(UsbIf->Device->DevDesc->Desc);
752
753 //
754 // If connect class policy, determine whether to create device handle by the five fields
755 // in class device path node.
756 //
757 // In addition, hub interface is always matched for this policy.
758 //
759 if ((ActIfDesc->InterfaceClass == USB_HUB_CLASS_CODE) &&
760 (ActIfDesc->InterfaceSubClass == USB_HUB_SUBCLASS_CODE))
761 {
762 return TRUE;
763 }
764
765 //
766 // If vendor id or product id is 0xffff, they will be ignored.
767 //
768 if (((UsbClassDevicePathPtr->VendorId == 0xffff) || (UsbClassDevicePathPtr->VendorId == DevDesc->IdVendor)) &&
769 ((UsbClassDevicePathPtr->ProductId == 0xffff) || (UsbClassDevicePathPtr->ProductId == DevDesc->IdProduct)))
770 {
771 //
772 // If Class in Device Descriptor is set to 0, the counterparts in interface should be checked.
773 //
774 if (DevDesc->DeviceClass == 0) {
775 if (((UsbClassDevicePathPtr->DeviceClass == ActIfDesc->InterfaceClass) ||
776 (UsbClassDevicePathPtr->DeviceClass == 0xff)) &&
777 ((UsbClassDevicePathPtr->DeviceSubClass == ActIfDesc->InterfaceSubClass) ||
778 (UsbClassDevicePathPtr->DeviceSubClass == 0xff)) &&
779 ((UsbClassDevicePathPtr->DeviceProtocol == ActIfDesc->InterfaceProtocol) ||
780 (UsbClassDevicePathPtr->DeviceProtocol == 0xff)))
781 {
782 return TRUE;
783 }
784 } else if (((UsbClassDevicePathPtr->DeviceClass == DevDesc->DeviceClass) ||
785 (UsbClassDevicePathPtr->DeviceClass == 0xff)) &&
786 ((UsbClassDevicePathPtr->DeviceSubClass == DevDesc->DeviceSubClass) ||
787 (UsbClassDevicePathPtr->DeviceSubClass == 0xff)) &&
788 ((UsbClassDevicePathPtr->DeviceProtocol == DevDesc->DeviceProtocol) ||
789 (UsbClassDevicePathPtr->DeviceProtocol == 0xff)))
790 {
791 return TRUE;
792 }
793 }
794
795 return FALSE;
796}
797
809BOOLEAN
811 IN USB_WWID_DEVICE_PATH *UsbWWIDDevicePathPtr,
812 IN USB_INTERFACE *UsbIf
813 )
814{
815 USB_INTERFACE_DESC *IfDesc;
819 UINT16 Index;
820 CHAR16 *CompareStr;
821 UINTN CompareLen;
822 UINTN Length;
823
824 if ((UsbWWIDDevicePathPtr->Header.Type != MESSAGING_DEVICE_PATH) ||
825 (UsbWWIDDevicePathPtr->Header.SubType != MSG_USB_WWID_DP))
826 {
827 ASSERT (0);
828 return FALSE;
829 }
830
831 IfDesc = UsbIf->IfDesc;
832 ASSERT (IfDesc->ActiveIndex < USB_MAX_INTERFACE_SETTING);
833 ActIfDesc = &(IfDesc->Settings[IfDesc->ActiveIndex]->Desc);
834 DevDesc = &(UsbIf->Device->DevDesc->Desc);
835
836 //
837 // In addition, Hub interface is always matched for this policy.
838 //
839 if ((ActIfDesc->InterfaceClass == USB_HUB_CLASS_CODE) &&
840 (ActIfDesc->InterfaceSubClass == USB_HUB_SUBCLASS_CODE))
841 {
842 return TRUE;
843 }
844
845 //
846 // Check Vendor Id, Product Id and Interface Number.
847 //
848 if ((DevDesc->IdVendor != UsbWWIDDevicePathPtr->VendorId) ||
849 (DevDesc->IdProduct != UsbWWIDDevicePathPtr->ProductId) ||
850 (ActIfDesc->InterfaceNumber != UsbWWIDDevicePathPtr->InterfaceNumber))
851 {
852 return FALSE;
853 }
854
855 //
856 // Check SerialNumber.
857 //
858 if (DevDesc->StrSerialNumber == 0) {
859 return FALSE;
860 }
861
862 //
863 // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters.
864 //
865 CompareStr = (CHAR16 *)(UINTN)(UsbWWIDDevicePathPtr + 1);
866 CompareLen = (DevicePathNodeLength (UsbWWIDDevicePathPtr) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16);
867 if (CompareStr[CompareLen - 1] == L'\0') {
868 CompareLen--;
869 }
870
871 //
872 // Compare serial number in each supported language.
873 //
874 for (Index = 0; Index < UsbIf->Device->TotalLangId; Index++) {
875 StrDesc = UsbGetOneString (UsbIf->Device, DevDesc->StrSerialNumber, UsbIf->Device->LangId[Index]);
876 if (StrDesc == NULL) {
877 continue;
878 }
879
880 Length = (StrDesc->Length - 2) / sizeof (CHAR16);
881 if ((Length >= CompareLen) &&
882 (CompareMem (StrDesc->String + Length - CompareLen, CompareStr, CompareLen * sizeof (CHAR16)) == 0))
883 {
884 return TRUE;
885 }
886 }
887
888 return FALSE;
889}
890
901EFIAPI
903 IN LIST_ENTRY *UsbIoDPList
904 )
905{
906 LIST_ENTRY *ListIndex;
907 DEVICE_PATH_LIST_ITEM *ListItem;
908
909 //
910 // Check that ControllerHandle is a valid handle
911 //
912 if (UsbIoDPList == NULL) {
913 return EFI_INVALID_PARAMETER;
914 }
915
916 ListIndex = UsbIoDPList->ForwardLink;
917 while (ListIndex != UsbIoDPList) {
918 ListItem = CR (ListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE);
919 //
920 // Free DEVICE_PATH_LIST_ITEM.DevicePath[]
921 //
922 if (ListItem->DevicePath != NULL) {
923 FreePool (ListItem->DevicePath);
924 }
925
926 //
927 // Free DEVICE_PATH_LIST_ITEM itself
928 //
929 ListIndex = ListIndex->ForwardLink;
930 RemoveEntryList (&ListItem->Link);
931 FreePool (ListItem);
932 }
933
934 InitializeListHead (UsbIoDPList);
935 return EFI_SUCCESS;
936}
937
950EFIAPI
952 IN EFI_USB_BUS_PROTOCOL *UsbBusId,
953 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
954 )
955{
956 USB_BUS *Bus;
957 EFI_STATUS Status;
958 EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr;
959
960 //
961 // Check whether remaining device path is valid
962 //
963 if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
964 if ((RemainingDevicePath->Type != MESSAGING_DEVICE_PATH) ||
965 ( (RemainingDevicePath->SubType != MSG_USB_DP) &&
966 (RemainingDevicePath->SubType != MSG_USB_CLASS_DP)
967 && (RemainingDevicePath->SubType != MSG_USB_WWID_DP)
968 ))
969 {
970 return EFI_INVALID_PARAMETER;
971 }
972 }
973
974 if (UsbBusId == NULL) {
975 return EFI_INVALID_PARAMETER;
976 }
977
978 Bus = USB_BUS_FROM_THIS (UsbBusId);
979
980 if (RemainingDevicePath == NULL) {
981 //
982 // RemainingDevicePath == NULL means all Usb devices in this bus are wanted.
983 // Here use a Usb class Device Path in WantedUsbIoDPList to indicate all Usb devices
984 // are wanted Usb devices
985 //
986 Status = UsbBusFreeUsbDPList (&Bus->WantedUsbIoDPList);
987 ASSERT (!EFI_ERROR (Status));
988 DevicePathPtr = DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL *)&mAllUsbClassDevicePath);
989 } else if (!IsDevicePathEnd (RemainingDevicePath)) {
990 //
991 // If RemainingDevicePath isn't the End of Device Path Node,
992 // Create new Usb device path according to the usb part in remaining device path
993 //
994 DevicePathPtr = GetUsbDPFromFullDP (RemainingDevicePath);
995 } else {
996 //
997 // If RemainingDevicePath is the End of Device Path Node,
998 // skip enumerate any device and return EFI_SUCCESS
999 //
1000 return EFI_SUCCESS;
1001 }
1002
1003 ASSERT (DevicePathPtr != NULL);
1004 Status = AddUsbDPToList (DevicePathPtr, &Bus->WantedUsbIoDPList);
1005 ASSERT (!EFI_ERROR (Status));
1006 FreePool (DevicePathPtr);
1007 return EFI_SUCCESS;
1008}
1009
1020BOOLEAN
1021EFIAPI
1023 IN USB_BUS *Bus,
1024 IN USB_INTERFACE *UsbIf
1025 )
1026{
1027 EFI_DEVICE_PATH_PROTOCOL *DevicePathPtr;
1028 LIST_ENTRY *WantedUsbIoDPListPtr;
1029 LIST_ENTRY *WantedListIndex;
1030 DEVICE_PATH_LIST_ITEM *WantedListItem;
1031 BOOLEAN DoConvert;
1032 UINTN FirstDevicePathSize;
1033
1034 //
1035 // Check whether passed in parameters are valid
1036 //
1037 if ((UsbIf == NULL) || (Bus == NULL)) {
1038 return FALSE;
1039 }
1040
1041 //
1042 // Check whether UsbIf is Hub
1043 //
1044 if (UsbIf->IsHub) {
1045 return TRUE;
1046 }
1047
1048 //
1049 // Check whether all Usb devices in this bus are wanted
1050 //
1051 if (SearchUsbDPInList ((EFI_DEVICE_PATH_PROTOCOL *)&mAllUsbClassDevicePath, &Bus->WantedUsbIoDPList)) {
1052 return TRUE;
1053 }
1054
1055 //
1056 // Check whether the Usb device match any item in WantedUsbIoDPList
1057 //
1058 WantedUsbIoDPListPtr = &Bus->WantedUsbIoDPList;
1059 //
1060 // Create new Usb device path according to the usb part in UsbIo full device path
1061 //
1062 DevicePathPtr = GetUsbDPFromFullDP (UsbIf->DevicePath);
1063 ASSERT (DevicePathPtr != NULL);
1064
1065 DoConvert = FALSE;
1066 WantedListIndex = WantedUsbIoDPListPtr->ForwardLink;
1067 while (WantedListIndex != WantedUsbIoDPListPtr) {
1068 WantedListItem = CR (WantedListIndex, DEVICE_PATH_LIST_ITEM, Link, DEVICE_PATH_LIST_ITEM_SIGNATURE);
1069 ASSERT (WantedListItem->DevicePath->Type == MESSAGING_DEVICE_PATH);
1070 switch (WantedListItem->DevicePath->SubType) {
1071 case MSG_USB_DP:
1072 FirstDevicePathSize = GetDevicePathSize (WantedListItem->DevicePath);
1073 if (FirstDevicePathSize == GetDevicePathSize (DevicePathPtr)) {
1074 if (CompareMem (
1075 WantedListItem->DevicePath,
1076 DevicePathPtr,
1077 GetDevicePathSize (DevicePathPtr)
1078 ) == 0
1079 )
1080 {
1081 DoConvert = TRUE;
1082 }
1083 }
1084
1085 break;
1086 case MSG_USB_CLASS_DP:
1087 if (MatchUsbClass ((USB_CLASS_DEVICE_PATH *)WantedListItem->DevicePath, UsbIf)) {
1088 DoConvert = TRUE;
1089 }
1090
1091 break;
1092 case MSG_USB_WWID_DP:
1093 if (MatchUsbWwid ((USB_WWID_DEVICE_PATH *)WantedListItem->DevicePath, UsbIf)) {
1094 DoConvert = TRUE;
1095 }
1096
1097 break;
1098 default:
1099 ASSERT (0);
1100 break;
1101 }
1102
1103 if (DoConvert) {
1104 break;
1105 }
1106
1107 WantedListIndex = WantedListIndex->ForwardLink;
1108 }
1109
1110 gBS->FreePool (DevicePathPtr);
1111
1112 //
1113 // Check whether the new Usb device path is wanted
1114 //
1115 if (DoConvert) {
1116 return TRUE;
1117 } else {
1118 return FALSE;
1119 }
1120}
1121
1133EFIAPI
1135 IN EFI_USB_BUS_PROTOCOL *UsbBusId
1136 )
1137{
1138 USB_BUS *Bus;
1139 EFI_STATUS Status;
1140 UINTN Index;
1141 EFI_USB_IO_PROTOCOL *UsbIo;
1142 USB_INTERFACE *UsbIf;
1143 UINTN UsbIoHandleCount;
1144 EFI_HANDLE *UsbIoBuffer;
1145 EFI_DEVICE_PATH_PROTOCOL *UsbIoDevicePath;
1146
1147 if (UsbBusId == NULL) {
1148 return EFI_INVALID_PARAMETER;
1149 }
1150
1151 Bus = USB_BUS_FROM_THIS (UsbBusId);
1152
1153 //
1154 // Get all Usb IO handles in system
1155 //
1156 UsbIoHandleCount = 0;
1157 Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiUsbIoProtocolGuid, NULL, &UsbIoHandleCount, &UsbIoBuffer);
1158 if ((Status == EFI_NOT_FOUND) || (UsbIoHandleCount == 0)) {
1159 return EFI_SUCCESS;
1160 }
1161
1162 ASSERT (!EFI_ERROR (Status));
1163
1164 for (Index = 0; Index < UsbIoHandleCount; Index++) {
1165 //
1166 // Check whether the USB IO handle is a child of this bus
1167 // Note: The usb child handle maybe invalid because of hot plugged out during the loop
1168 //
1169 UsbIoDevicePath = NULL;
1170 Status = gBS->HandleProtocol (UsbIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *)&UsbIoDevicePath);
1171 if (EFI_ERROR (Status) || (UsbIoDevicePath == NULL)) {
1172 continue;
1173 }
1174
1175 if (CompareMem (
1176 UsbIoDevicePath,
1177 Bus->DevicePath,
1178 (GetDevicePathSize (Bus->DevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL))
1179 ) != 0)
1180 {
1181 continue;
1182 }
1183
1184 //
1185 // Get the child Usb IO interface
1186 //
1187 Status = gBS->HandleProtocol (
1188 UsbIoBuffer[Index],
1189 &gEfiUsbIoProtocolGuid,
1190 (VOID **)&UsbIo
1191 );
1192 if (EFI_ERROR (Status)) {
1193 continue;
1194 }
1195
1196 UsbIf = USB_INTERFACE_FROM_USBIO (UsbIo);
1197
1198 if (UsbBusIsWantedUsbIO (Bus, UsbIf)) {
1199 if (!UsbIf->IsManaged) {
1200 //
1201 // Recursively connect the wanted Usb Io handle
1202 //
1203 DEBUG ((DEBUG_INFO, "UsbBusRecursivelyConnectWantedUsbIo: TPL before connect is %d\n", (UINT32)UsbGetCurrentTpl ()));
1204 Status = gBS->ConnectController (UsbIf->Handle, NULL, NULL, TRUE);
1205 UsbIf->IsManaged = (BOOLEAN) !EFI_ERROR (Status);
1206 DEBUG ((DEBUG_INFO, "UsbBusRecursivelyConnectWantedUsbIo: TPL after connect is %d\n", (UINT32)UsbGetCurrentTpl ()));
1207 }
1208 }
1209 }
1210
1211 FreePool (UsbIoBuffer);
1212
1213 return EFI_SUCCESS;
1214}
UINT64 UINTN
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
NODE Child(IN NODE LoopVar6, IN UINT8 LoopVar5)
Definition: Compress.c:265
#define MSG_USB_WWID_DP
Definition: DevicePath.h:467
#define MSG_USB_DP
Definition: DevicePath.h:418
#define MSG_USB_CLASS_DP
Definition: DevicePath.h:434
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
UINTN EFIAPI DevicePathNodeLength(IN CONST VOID *Node)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID EFIAPI SetDevicePathEndNode(OUT VOID *Node)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
EFI_USB_PORT_FEATURE
EFI_USB_DATA_DIRECTION
Definition: UsbIo.h:44
EFI_STATUS(EFIAPI * EFI_ASYNC_USB_TRANSFER_CALLBACK)(IN VOID *Data, IN UINTN DataLength, IN VOID *Context, IN UINT32 Status)
Definition: UsbIo.h:80
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ ByProtocol
Definition: UefiSpec.h:1518
EFI_USB_STRING_DESCRIPTOR * UsbGetOneString(IN USB_DEVICE *UsbDev, IN UINT8 Index, IN UINT16 LangId)
Definition: UsbDesc.c:633
EFI_STATUS UsbHcSyncInterruptTransfer(IN USB_BUS *UsbBus, IN UINT8 DevAddr, IN UINT8 EpAddr, IN UINT8 DevSpeed, IN UINTN MaxPacket, IN OUT VOID *Data, IN OUT UINTN *DataLength, IN OUT UINT8 *DataToggle, IN UINTN TimeOut, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *UsbResult)
Definition: UsbUtility.c:411
EFI_STATUS UsbHcGetRootHubPortStatus(IN USB_BUS *UsbBus, IN UINT8 PortIndex, OUT EFI_USB_PORT_STATUS *PortStatus)
Definition: UsbUtility.c:95
EFI_STATUS UsbOpenHostProtoByChild(IN USB_BUS *Bus, IN EFI_HANDLE Child)
Definition: UsbUtility.c:471
BOOLEAN MatchUsbWwid(IN USB_WWID_DEVICE_PATH *UsbWWIDDevicePathPtr, IN USB_INTERFACE *UsbIf)
Definition: UsbUtility.c:810
EFI_TPL UsbGetCurrentTpl(VOID)
Definition: UsbUtility.c:542
EFI_STATUS EFIAPI UsbBusAddWantedUsbIoDP(IN EFI_USB_BUS_PROTOCOL *UsbBusId, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
Definition: UsbUtility.c:951
EFI_STATUS EFIAPI AddUsbDPToList(IN EFI_DEVICE_PATH_PROTOCOL *UsbDP, IN LIST_ENTRY *UsbIoDPList)
Definition: UsbUtility.c:688
EFI_STATUS UsbHcClearRootHubPortFeature(IN USB_BUS *UsbBus, IN UINT8 PortIndex, IN EFI_USB_PORT_FEATURE Feature)
Definition: UsbUtility.c:153
EFI_STATUS UsbHcAsyncInterruptTransfer(IN USB_BUS *UsbBus, IN UINT8 DevAddr, IN UINT8 EpAddr, IN UINT8 DevSpeed, IN UINTN MaxPacket, IN BOOLEAN IsNewTransfer, IN OUT UINT8 *DataToggle, IN UINTN PollingInterval, IN UINTN DataLength, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, IN VOID *Context OPTIONAL)
Definition: UsbUtility.c:335
EFI_STATUS UsbHcSetRootHubPortFeature(IN USB_BUS *UsbBus, IN UINT8 PortIndex, IN EFI_USB_PORT_FEATURE Feature)
Definition: UsbUtility.c:124
BOOLEAN EFIAPI MatchUsbClass(IN USB_CLASS_DEVICE_PATH *UsbClassDevicePathPtr, IN USB_INTERFACE *UsbIf)
Definition: UsbUtility.c:732
EFI_STATUS UsbHcBulkTransfer(IN USB_BUS *UsbBus, IN UINT8 DevAddr, IN UINT8 EpAddr, IN UINT8 DevSpeed, IN UINTN MaxPacket, IN UINT8 BufferNum, IN OUT VOID *Data[], IN OUT UINTN *DataLength, IN OUT UINT8 *DataToggle, IN UINTN TimeOut, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *UsbResult)
Definition: UsbUtility.c:263
BOOLEAN EFIAPI SearchUsbDPInList(IN EFI_DEVICE_PATH_PROTOCOL *UsbDP, IN LIST_ENTRY *UsbIoDPList)
Definition: UsbUtility.c:636
EFI_DEVICE_PATH_PROTOCOL *EFIAPI GetUsbDPFromFullDP(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
Definition: UsbUtility.c:564
EFI_STATUS EFIAPI UsbBusFreeUsbDPList(IN LIST_ENTRY *UsbIoDPList)
Definition: UsbUtility.c:902
BOOLEAN EFIAPI UsbBusIsWantedUsbIO(IN USB_BUS *Bus, IN USB_INTERFACE *UsbIf)
Definition: UsbUtility.c:1022
VOID UsbCloseHostProtoByChild(IN USB_BUS *Bus, IN EFI_HANDLE Child)
Definition: UsbUtility.c:511
EFI_STATUS UsbHcControlTransfer(IN USB_BUS *UsbBus, IN UINT8 DevAddr, IN UINT8 DevSpeed, IN UINTN MaxPacket, IN EFI_USB_DEVICE_REQUEST *Request, IN EFI_USB_DATA_DIRECTION Direction, IN OUT VOID *Data, IN OUT UINTN *DataLength, IN UINTN TimeOut, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator, OUT UINT32 *UsbResult)
Definition: UsbUtility.c:190
EFI_STATUS EFIAPI UsbBusRecursivelyConnectWantedUsbIo(IN EFI_USB_BUS_PROTOCOL *UsbBusId)
Definition: UsbUtility.c:1134
EFI_STATUS UsbHcGetCapability(IN USB_BUS *UsbBus, OUT UINT8 *MaxSpeed, OUT UINT8 *NumOfPort, OUT UINT8 *Is64BitCapable)
Definition: UsbUtility.c:57