2 Supporting functions implementaion for PCI devices management.
4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2018 Hewlett Packard Enterprise Development LP<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.
19 // This device structure is serviced as a header.
20 // Its next field points to the first root bridge device node.
22 LIST_ENTRY mPciDevicePool
;
25 Initialize the PCI devices pool.
29 InitializePciDevicePool (
33 InitializeListHead (&mPciDevicePool
);
37 Insert a root bridge into PCI device pool.
39 @param RootBridge A pointer to the PCI_IO_DEVICE.
44 IN PCI_IO_DEVICE
*RootBridge
47 InsertTailList (&mPciDevicePool
, &(RootBridge
->Link
));
51 This function is used to insert a PCI device node under
54 @param Bridge The PCI bridge.
55 @param PciDeviceNode The PCI device needs inserting.
60 IN PCI_IO_DEVICE
*Bridge
,
61 IN PCI_IO_DEVICE
*PciDeviceNode
64 InsertTailList (&Bridge
->ChildList
, &(PciDeviceNode
->Link
));
65 PciDeviceNode
->Parent
= Bridge
;
69 Destroy root bridge and remove it from deivce tree.
71 @param RootBridge The bridge want to be removed.
76 IN PCI_IO_DEVICE
*RootBridge
79 DestroyPciDeviceTree (RootBridge
);
81 FreePciDevice (RootBridge
);
85 Destroy a pci device node.
87 All direct or indirect allocated resource for this node will be freed.
89 @param PciIoDevice A pointer to the PCI_IO_DEVICE to be destoried.
94 IN PCI_IO_DEVICE
*PciIoDevice
97 ASSERT (PciIoDevice
!= NULL
);
99 // Assume all children have been removed underneath this device
101 if (PciIoDevice
->ResourcePaddingDescriptors
!= NULL
) {
102 FreePool (PciIoDevice
->ResourcePaddingDescriptors
);
105 if (PciIoDevice
->DevicePath
!= NULL
) {
106 FreePool (PciIoDevice
->DevicePath
);
109 if (PciIoDevice
->BusNumberRanges
!= NULL
) {
110 FreePool (PciIoDevice
->BusNumberRanges
);
113 FreePool (PciIoDevice
);
117 Destroy all the pci device node under the bridge.
118 Bridge itself is not included.
120 @param Bridge A pointer to the PCI_IO_DEVICE.
124 DestroyPciDeviceTree (
125 IN PCI_IO_DEVICE
*Bridge
128 LIST_ENTRY
*CurrentLink
;
131 while (!IsListEmpty (&Bridge
->ChildList
)) {
133 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
136 // Remove this node from the linked list
138 RemoveEntryList (CurrentLink
);
140 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
142 if (!IsListEmpty (&Temp
->ChildList
)) {
143 DestroyPciDeviceTree (Temp
);
146 FreePciDevice (Temp
);
151 Destroy all device nodes under the root bridge
152 specified by Controller.
154 The root bridge itself is also included.
156 @param Controller Root bridge handle.
158 @retval EFI_SUCCESS Destory all devcie nodes successfully.
159 @retval EFI_NOT_FOUND Cannot find any PCI device under specified
164 DestroyRootBridgeByHandle (
165 IN EFI_HANDLE Controller
169 LIST_ENTRY
*CurrentLink
;
172 CurrentLink
= mPciDevicePool
.ForwardLink
;
174 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
175 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
177 if (Temp
->Handle
== Controller
) {
179 RemoveEntryList (CurrentLink
);
181 DestroyPciDeviceTree (Temp
);
183 FreePciDevice (Temp
);
188 CurrentLink
= CurrentLink
->ForwardLink
;
191 return EFI_NOT_FOUND
;
195 This function registers the PCI IO device.
197 It creates a handle for this PCI IO device (if the handle does not exist), attaches
198 appropriate protocols onto the handle, does necessary initialization, and sets up
199 parent/child relationship with its bus controller.
201 @param Controller An EFI handle for the PCI bus controller.
202 @param PciIoDevice A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
203 @param Handle A pointer to hold the returned EFI handle for the PCI IO device.
205 @retval EFI_SUCCESS The PCI device is successfully registered.
206 @retval other An error occurred when registering the PCI device.
211 IN EFI_HANDLE Controller
,
212 IN PCI_IO_DEVICE
*PciIoDevice
,
213 OUT EFI_HANDLE
*Handle OPTIONAL
217 VOID
*PlatformOpRomBuffer
;
218 UINTN PlatformOpRomSize
;
219 EFI_PCI_IO_PROTOCOL
*PciIo
;
224 // Install the pciio protocol, device path protocol
226 Status
= gBS
->InstallMultipleProtocolInterfaces (
227 &PciIoDevice
->Handle
,
228 &gEfiDevicePathProtocolGuid
,
229 PciIoDevice
->DevicePath
,
230 &gEfiPciIoProtocolGuid
,
234 if (EFI_ERROR (Status
)) {
239 // Force Interrupt line to "Unknown" or "No Connection"
241 PciIo
= &(PciIoDevice
->PciIo
);
242 Data8
= PCI_INT_LINE_UNKNOWN
;
243 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &Data8
);
248 if (!PciIoDevice
->AllOpRomProcessed
) {
251 // Get the OpRom provided by platform
253 if (gPciPlatformProtocol
!= NULL
) {
254 Status
= gPciPlatformProtocol
->GetPciRom (
255 gPciPlatformProtocol
,
257 &PlatformOpRomBuffer
,
260 if (!EFI_ERROR (Status
)) {
261 PciIoDevice
->EmbeddedRom
= FALSE
;
262 PciIoDevice
->RomSize
= (UINT32
) PlatformOpRomSize
;
263 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
264 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
266 // For OpROM read from gPciPlatformProtocol:
267 // Add the Rom Image to internal database for later PCI light enumeration
269 PciRomAddImageMapping (
271 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
272 PciIoDevice
->BusNumber
,
273 PciIoDevice
->DeviceNumber
,
274 PciIoDevice
->FunctionNumber
,
275 PciIoDevice
->PciIo
.RomImage
,
276 PciIoDevice
->PciIo
.RomSize
279 } else if (gPciOverrideProtocol
!= NULL
) {
280 Status
= gPciOverrideProtocol
->GetPciRom (
281 gPciOverrideProtocol
,
283 &PlatformOpRomBuffer
,
286 if (!EFI_ERROR (Status
)) {
287 PciIoDevice
->EmbeddedRom
= FALSE
;
288 PciIoDevice
->RomSize
= (UINT32
) PlatformOpRomSize
;
289 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
290 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
292 // For OpROM read from gPciOverrideProtocol:
293 // Add the Rom Image to internal database for later PCI light enumeration
295 PciRomAddImageMapping (
297 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
298 PciIoDevice
->BusNumber
,
299 PciIoDevice
->DeviceNumber
,
300 PciIoDevice
->FunctionNumber
,
301 PciIoDevice
->PciIo
.RomImage
,
302 PciIoDevice
->PciIo
.RomSize
309 // Determine if there are EFI images in the option rom
311 HasEfiImage
= ContainEfiImage (PciIoDevice
->PciIo
.RomImage
, PciIoDevice
->PciIo
.RomSize
);
314 Status
= gBS
->InstallMultipleProtocolInterfaces (
315 &PciIoDevice
->Handle
,
316 &gEfiLoadFile2ProtocolGuid
,
317 &PciIoDevice
->LoadFile2
,
320 if (EFI_ERROR (Status
)) {
321 gBS
->UninstallMultipleProtocolInterfaces (
322 &PciIoDevice
->Handle
,
323 &gEfiDevicePathProtocolGuid
,
324 PciIoDevice
->DevicePath
,
325 &gEfiPciIoProtocolGuid
,
334 if (!PciIoDevice
->AllOpRomProcessed
) {
336 PciIoDevice
->AllOpRomProcessed
= TRUE
;
339 // Dispatch the EFI OpRom for the PCI device.
340 // The OpRom is got from platform in the above code
341 // or loaded from device in the previous round of bus enumeration
344 ProcessOpRomImage (PciIoDevice
);
348 if (PciIoDevice
->BusOverride
) {
350 // Install Bus Specific Driver Override Protocol
352 Status
= gBS
->InstallMultipleProtocolInterfaces (
353 &PciIoDevice
->Handle
,
354 &gEfiBusSpecificDriverOverrideProtocolGuid
,
355 &PciIoDevice
->PciDriverOverride
,
358 if (EFI_ERROR (Status
)) {
359 gBS
->UninstallMultipleProtocolInterfaces (
360 &PciIoDevice
->Handle
,
361 &gEfiDevicePathProtocolGuid
,
362 PciIoDevice
->DevicePath
,
363 &gEfiPciIoProtocolGuid
,
368 gBS
->UninstallMultipleProtocolInterfaces (
369 &PciIoDevice
->Handle
,
370 &gEfiLoadFile2ProtocolGuid
,
371 &PciIoDevice
->LoadFile2
,
380 Status
= gBS
->OpenProtocol (
382 &gEfiPciRootBridgeIoProtocolGuid
,
383 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
384 gPciBusDriverBinding
.DriverBindingHandle
,
386 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
388 if (EFI_ERROR (Status
)) {
392 if (Handle
!= NULL
) {
393 *Handle
= PciIoDevice
->Handle
;
397 // Indicate the pci device is registered
399 PciIoDevice
->Registered
= TRUE
;
405 This function is used to remove the whole PCI devices on the specified bridge from
408 @param RootBridgeHandle The root bridge device handle.
409 @param Bridge The bridge device to be removed.
413 RemoveAllPciDeviceOnBridge (
414 EFI_HANDLE RootBridgeHandle
,
415 PCI_IO_DEVICE
*Bridge
418 LIST_ENTRY
*CurrentLink
;
421 while (!IsListEmpty (&Bridge
->ChildList
)) {
423 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
424 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
427 // Check if the current node has been deregistered before
428 // If it is not, then deregister it
430 if (Temp
->Registered
) {
431 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
435 // Remove this node from the linked list
437 RemoveEntryList (CurrentLink
);
439 if (!IsListEmpty (&Temp
->ChildList
)) {
440 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
443 FreePciDevice (Temp
);
448 This function is used to de-register the PCI IO device.
450 That includes un-installing PciIo protocol from the specified PCI
453 @param Controller An EFI handle for the PCI bus controller.
454 @param Handle PCI device handle.
456 @retval EFI_SUCCESS The PCI device is successfully de-registered.
457 @retval other An error occurred when de-registering the PCI device.
461 DeRegisterPciDevice (
462 IN EFI_HANDLE Controller
,
467 EFI_PCI_IO_PROTOCOL
*PciIo
;
469 PCI_IO_DEVICE
*PciIoDevice
;
471 LIST_ENTRY
*CurrentLink
;
472 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
474 Status
= gBS
->OpenProtocol (
476 &gEfiPciIoProtocolGuid
,
478 gPciBusDriverBinding
.DriverBindingHandle
,
480 EFI_OPEN_PROTOCOL_GET_PROTOCOL
482 if (!EFI_ERROR (Status
)) {
483 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
486 // If it is already de-registered
488 if (!PciIoDevice
->Registered
) {
493 // If it is PPB, first de-register its children
496 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
498 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
500 while (CurrentLink
!= NULL
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
501 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
502 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
504 if (EFI_ERROR (Status
)) {
508 CurrentLink
= CurrentLink
->ForwardLink
;
513 // Close the child handle
515 Status
= gBS
->CloseProtocol (
517 &gEfiPciRootBridgeIoProtocolGuid
,
518 gPciBusDriverBinding
.DriverBindingHandle
,
523 // Un-install the Device Path protocol and PCI I/O protocol
524 // and Bus Specific Driver Override protocol if needed.
526 if (PciIoDevice
->BusOverride
) {
527 Status
= gBS
->UninstallMultipleProtocolInterfaces (
529 &gEfiDevicePathProtocolGuid
,
530 PciIoDevice
->DevicePath
,
531 &gEfiPciIoProtocolGuid
,
533 &gEfiBusSpecificDriverOverrideProtocolGuid
,
534 &PciIoDevice
->PciDriverOverride
,
538 Status
= gBS
->UninstallMultipleProtocolInterfaces (
540 &gEfiDevicePathProtocolGuid
,
541 PciIoDevice
->DevicePath
,
542 &gEfiPciIoProtocolGuid
,
548 if (!EFI_ERROR (Status
)) {
550 // Try to uninstall LoadFile2 protocol if exists
552 Status
= gBS
->OpenProtocol (
554 &gEfiLoadFile2ProtocolGuid
,
556 gPciBusDriverBinding
.DriverBindingHandle
,
558 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
560 if (!EFI_ERROR (Status
)) {
561 Status
= gBS
->UninstallMultipleProtocolInterfaces (
563 &gEfiLoadFile2ProtocolGuid
,
564 &PciIoDevice
->LoadFile2
,
571 Status
= EFI_SUCCESS
;
575 if (EFI_ERROR (Status
)) {
578 &gEfiPciRootBridgeIoProtocolGuid
,
579 (VOID
**) &PciRootBridgeIo
,
580 gPciBusDriverBinding
.DriverBindingHandle
,
582 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
588 // The Device Driver should disable this device after disconnect
589 // so the Pci Bus driver will not touch this device any more.
590 // Restore the register field to the original value
592 PciIoDevice
->Registered
= FALSE
;
593 PciIoDevice
->Handle
= NULL
;
597 // Handle may be closed before
606 Start to manage the PCI device on the specified root bridge or PCI-PCI Bridge.
608 @param Controller The root bridge handle.
609 @param RootBridge A pointer to the PCI_IO_DEVICE.
610 @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.
611 @param NumberOfChildren Children number.
612 @param ChildHandleBuffer A pointer to the child handle buffer.
614 @retval EFI_NOT_READY Device is not allocated.
615 @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.
616 @retval EFI_NOT_FOUND Can not find the specific device.
617 @retval EFI_SUCCESS Success to start Pci devices on bridge.
621 StartPciDevicesOnBridge (
622 IN EFI_HANDLE Controller
,
623 IN PCI_IO_DEVICE
*RootBridge
,
624 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
625 IN OUT UINT8
*NumberOfChildren
,
626 IN OUT EFI_HANDLE
*ChildHandleBuffer
630 PCI_IO_DEVICE
*PciIoDevice
;
631 EFI_DEV_PATH_PTR Node
;
632 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
634 LIST_ENTRY
*CurrentLink
;
638 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
640 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
642 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
643 if (RemainingDevicePath
!= NULL
) {
645 Node
.DevPath
= RemainingDevicePath
;
647 if (Node
.Pci
->Device
!= PciIoDevice
->DeviceNumber
||
648 Node
.Pci
->Function
!= PciIoDevice
->FunctionNumber
) {
649 CurrentLink
= CurrentLink
->ForwardLink
;
654 // Check if the device has been assigned with required resource
656 if (!PciIoDevice
->Allocated
) {
657 return EFI_NOT_READY
;
661 // Check if the current node has been registered before
662 // If it is not, register it
664 if (!PciIoDevice
->Registered
) {
665 Status
= RegisterPciDevice (
673 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
674 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
675 (*NumberOfChildren
)++;
679 // Get the next device path
681 CurrentDevicePath
= NextDevicePathNode (RemainingDevicePath
);
682 if (IsDevicePathEnd (CurrentDevicePath
)) {
689 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
690 Status
= StartPciDevicesOnBridge (
698 PciIoDevice
->PciIo
.Attributes (
699 &(PciIoDevice
->PciIo
),
700 EfiPciIoAttributeOperationSupported
,
704 Supports
&= (UINT64
)EFI_PCI_DEVICE_ENABLE
;
705 PciIoDevice
->PciIo
.Attributes (
706 &(PciIoDevice
->PciIo
),
707 EfiPciIoAttributeOperationEnable
,
716 // Currently, the PCI bus driver only support PCI-PCI bridge
718 return EFI_UNSUPPORTED
;
724 // If remaining device path is NULL,
725 // try to enable all the pci devices under this bridge
727 if (!PciIoDevice
->Registered
&& PciIoDevice
->Allocated
) {
728 Status
= RegisterPciDevice (
736 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
737 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
738 (*NumberOfChildren
)++;
741 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
742 Status
= StartPciDevicesOnBridge (
750 PciIoDevice
->PciIo
.Attributes (
751 &(PciIoDevice
->PciIo
),
752 EfiPciIoAttributeOperationSupported
,
756 Supports
&= (UINT64
)EFI_PCI_DEVICE_ENABLE
;
757 PciIoDevice
->PciIo
.Attributes (
758 &(PciIoDevice
->PciIo
),
759 EfiPciIoAttributeOperationEnable
,
766 CurrentLink
= CurrentLink
->ForwardLink
;
770 if (PciIoDevice
== NULL
) {
771 return EFI_NOT_FOUND
;
778 Start to manage all the PCI devices it found previously under
779 the entire host bridge.
781 @param Controller The root bridge handle.
783 @retval EFI_NOT_READY Device is not allocated.
784 @retval EFI_SUCCESS Success to start Pci device on host bridge.
789 IN EFI_HANDLE Controller
792 PCI_IO_DEVICE
*RootBridge
;
793 EFI_HANDLE ThisHostBridge
;
794 LIST_ENTRY
*CurrentLink
;
796 RootBridge
= GetRootBridgeByHandle (Controller
);
797 ASSERT (RootBridge
!= NULL
);
798 ThisHostBridge
= RootBridge
->PciRootBridgeIo
->ParentHandle
;
800 CurrentLink
= mPciDevicePool
.ForwardLink
;
802 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
804 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
806 // Locate the right root bridge to start
808 if (RootBridge
->PciRootBridgeIo
->ParentHandle
== ThisHostBridge
) {
809 StartPciDevicesOnBridge (
818 CurrentLink
= CurrentLink
->ForwardLink
;
825 Create root bridge device.
827 @param RootBridgeHandle Specified root bridge hanle.
829 @return The crated root bridge device instance, NULL means no
830 root bridge device instance created.
835 IN EFI_HANDLE RootBridgeHandle
840 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
841 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
843 Dev
= AllocateZeroPool (sizeof (PCI_IO_DEVICE
));
848 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
849 Dev
->Handle
= RootBridgeHandle
;
850 InitializeListHead (&Dev
->ChildList
);
852 Status
= gBS
->OpenProtocol (
854 &gEfiDevicePathProtocolGuid
,
855 (VOID
**) &ParentDevicePath
,
856 gPciBusDriverBinding
.DriverBindingHandle
,
858 EFI_OPEN_PROTOCOL_GET_PROTOCOL
861 if (EFI_ERROR (Status
)) {
867 // Record the root bridge parent device path
869 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
872 // Get the pci root bridge io protocol
874 Status
= gBS
->OpenProtocol (
876 &gEfiPciRootBridgeIoProtocolGuid
,
877 (VOID
**) &PciRootBridgeIo
,
878 gPciBusDriverBinding
.DriverBindingHandle
,
880 EFI_OPEN_PROTOCOL_GET_PROTOCOL
883 if (EFI_ERROR (Status
)) {
888 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
891 // Initialize the PCI I/O instance structure
893 InitializePciIoInstance (Dev
);
894 InitializePciDriverOverrideInstance (Dev
);
895 InitializePciLoadFile2 (Dev
);
898 // Initialize reserved resource list and
899 // option rom driver list
901 InitializeListHead (&Dev
->ReservedResourceList
);
902 InitializeListHead (&Dev
->OptionRomDriverList
);
908 Get root bridge device instance by specific root bridge handle.
910 @param RootBridgeHandle Given root bridge handle.
912 @return The root bridge device instance, NULL means no root bridge
913 device instance found.
917 GetRootBridgeByHandle (
918 EFI_HANDLE RootBridgeHandle
921 PCI_IO_DEVICE
*RootBridgeDev
;
922 LIST_ENTRY
*CurrentLink
;
924 CurrentLink
= mPciDevicePool
.ForwardLink
;
926 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
928 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
929 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
930 return RootBridgeDev
;
933 CurrentLink
= CurrentLink
->ForwardLink
;
940 Judege whether Pci device existed.
942 @param Bridge Parent bridege instance.
943 @param PciIoDevice Device instance.
945 @retval TRUE Pci device existed.
946 @retval FALSE Pci device did not exist.
951 IN PCI_IO_DEVICE
*Bridge
,
952 IN PCI_IO_DEVICE
*PciIoDevice
957 LIST_ENTRY
*CurrentLink
;
959 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
961 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
963 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
965 if (Temp
== PciIoDevice
) {
969 if (!IsListEmpty (&Temp
->ChildList
)) {
970 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
975 CurrentLink
= CurrentLink
->ForwardLink
;
982 Get the active VGA device on the specified Host Bridge.
984 @param HostBridgeHandle Host Bridge handle.
986 @return The active VGA device on the specified Host Bridge.
990 LocateVgaDeviceOnHostBridge (
991 IN EFI_HANDLE HostBridgeHandle
994 LIST_ENTRY
*CurrentLink
;
995 PCI_IO_DEVICE
*PciIoDevice
;
997 CurrentLink
= mPciDevicePool
.ForwardLink
;
999 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
1001 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1003 if (PciIoDevice
->PciRootBridgeIo
->ParentHandle
== HostBridgeHandle
) {
1005 PciIoDevice
= LocateVgaDevice (PciIoDevice
);
1007 if (PciIoDevice
!= NULL
) {
1012 CurrentLink
= CurrentLink
->ForwardLink
;
1019 Locate the active VGA device under the bridge.
1021 @param Bridge PCI IO instance for the bridge.
1023 @return The active VGA device.
1028 IN PCI_IO_DEVICE
*Bridge
1031 LIST_ENTRY
*CurrentLink
;
1032 PCI_IO_DEVICE
*PciIoDevice
;
1034 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1036 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
1038 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1040 if (IS_PCI_VGA(&PciIoDevice
->Pci
) &&
1041 (PciIoDevice
->Attributes
&
1042 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1043 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1044 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
)) != 0) {
1048 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
1050 PciIoDevice
= LocateVgaDevice (PciIoDevice
);
1052 if (PciIoDevice
!= NULL
) {
1057 CurrentLink
= CurrentLink
->ForwardLink
;