2 Supporting functions implementation 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 SPDX-License-Identifier: BSD-2-Clause-Patent
13 // This device structure is serviced as a header.
14 // Its next field points to the first root bridge device node.
16 LIST_ENTRY mPciDevicePool
;
19 Initialize the PCI devices pool.
23 InitializePciDevicePool (
27 InitializeListHead (&mPciDevicePool
);
31 Insert a root bridge into PCI device pool.
33 @param RootBridge A pointer to the PCI_IO_DEVICE.
38 IN PCI_IO_DEVICE
*RootBridge
41 InsertTailList (&mPciDevicePool
, &(RootBridge
->Link
));
45 This function is used to insert a PCI device node under
48 @param Bridge The PCI bridge.
49 @param PciDeviceNode The PCI device needs inserting.
54 IN PCI_IO_DEVICE
*Bridge
,
55 IN PCI_IO_DEVICE
*PciDeviceNode
58 InsertTailList (&Bridge
->ChildList
, &(PciDeviceNode
->Link
));
59 PciDeviceNode
->Parent
= Bridge
;
63 Destroy root bridge and remove it from device tree.
65 @param RootBridge The bridge want to be removed.
70 IN PCI_IO_DEVICE
*RootBridge
73 DestroyPciDeviceTree (RootBridge
);
75 FreePciDevice (RootBridge
);
79 Destroy a pci device node.
81 All direct or indirect allocated resource for this node will be freed.
83 @param PciIoDevice A pointer to the PCI_IO_DEVICE to be destroyed.
88 IN PCI_IO_DEVICE
*PciIoDevice
91 ASSERT (PciIoDevice
!= NULL
);
93 // Assume all children have been removed underneath this device
95 if (PciIoDevice
->ResourcePaddingDescriptors
!= NULL
) {
96 FreePool (PciIoDevice
->ResourcePaddingDescriptors
);
99 if (PciIoDevice
->DevicePath
!= NULL
) {
100 FreePool (PciIoDevice
->DevicePath
);
103 if (PciIoDevice
->BusNumberRanges
!= NULL
) {
104 FreePool (PciIoDevice
->BusNumberRanges
);
107 FreePool (PciIoDevice
);
111 Destroy all the pci device node under the bridge.
112 Bridge itself is not included.
114 @param Bridge A pointer to the PCI_IO_DEVICE.
118 DestroyPciDeviceTree (
119 IN PCI_IO_DEVICE
*Bridge
122 LIST_ENTRY
*CurrentLink
;
125 while (!IsListEmpty (&Bridge
->ChildList
)) {
127 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
130 // Remove this node from the linked list
132 RemoveEntryList (CurrentLink
);
134 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
136 if (!IsListEmpty (&Temp
->ChildList
)) {
137 DestroyPciDeviceTree (Temp
);
140 FreePciDevice (Temp
);
145 Destroy all device nodes under the root bridge
146 specified by Controller.
148 The root bridge itself is also included.
150 @param Controller Root bridge handle.
152 @retval EFI_SUCCESS Destroy all device nodes successfully.
153 @retval EFI_NOT_FOUND Cannot find any PCI device under specified
158 DestroyRootBridgeByHandle (
159 IN EFI_HANDLE Controller
163 LIST_ENTRY
*CurrentLink
;
166 CurrentLink
= mPciDevicePool
.ForwardLink
;
168 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
169 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
171 if (Temp
->Handle
== Controller
) {
173 RemoveEntryList (CurrentLink
);
175 DestroyPciDeviceTree (Temp
);
177 FreePciDevice (Temp
);
182 CurrentLink
= CurrentLink
->ForwardLink
;
185 return EFI_NOT_FOUND
;
189 This function registers the PCI IO device.
191 It creates a handle for this PCI IO device (if the handle does not exist), attaches
192 appropriate protocols onto the handle, does necessary initialization, and sets up
193 parent/child relationship with its bus controller.
195 @param Controller An EFI handle for the PCI bus controller.
196 @param PciIoDevice A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
197 @param Handle A pointer to hold the returned EFI handle for the PCI IO device.
199 @retval EFI_SUCCESS The PCI device is successfully registered.
200 @retval other An error occurred when registering the PCI device.
205 IN EFI_HANDLE Controller
,
206 IN PCI_IO_DEVICE
*PciIoDevice
,
207 OUT EFI_HANDLE
*Handle OPTIONAL
211 VOID
*PlatformOpRomBuffer
;
212 UINTN PlatformOpRomSize
;
213 EFI_PCI_IO_PROTOCOL
*PciIo
;
218 // Install the pciio protocol, device path protocol
220 Status
= gBS
->InstallMultipleProtocolInterfaces (
221 &PciIoDevice
->Handle
,
222 &gEfiDevicePathProtocolGuid
,
223 PciIoDevice
->DevicePath
,
224 &gEfiPciIoProtocolGuid
,
228 if (EFI_ERROR (Status
)) {
233 // Force Interrupt line to "Unknown" or "No Connection"
235 PciIo
= &(PciIoDevice
->PciIo
);
236 Data8
= PCI_INT_LINE_UNKNOWN
;
237 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &Data8
);
242 if (!PciIoDevice
->AllOpRomProcessed
) {
245 // Get the OpRom provided by platform
247 if (gPciPlatformProtocol
!= NULL
) {
248 Status
= gPciPlatformProtocol
->GetPciRom (
249 gPciPlatformProtocol
,
251 &PlatformOpRomBuffer
,
254 if (!EFI_ERROR (Status
)) {
255 PciIoDevice
->EmbeddedRom
= FALSE
;
256 PciIoDevice
->RomSize
= (UINT32
) PlatformOpRomSize
;
257 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
258 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
260 // For OpROM read from gPciPlatformProtocol:
261 // Add the Rom Image to internal database for later PCI light enumeration
263 PciRomAddImageMapping (
265 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
266 PciIoDevice
->BusNumber
,
267 PciIoDevice
->DeviceNumber
,
268 PciIoDevice
->FunctionNumber
,
269 PciIoDevice
->PciIo
.RomImage
,
270 PciIoDevice
->PciIo
.RomSize
273 } else if (gPciOverrideProtocol
!= NULL
) {
274 Status
= gPciOverrideProtocol
->GetPciRom (
275 gPciOverrideProtocol
,
277 &PlatformOpRomBuffer
,
280 if (!EFI_ERROR (Status
)) {
281 PciIoDevice
->EmbeddedRom
= FALSE
;
282 PciIoDevice
->RomSize
= (UINT32
) PlatformOpRomSize
;
283 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
284 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
286 // For OpROM read from gPciOverrideProtocol:
287 // Add the Rom Image to internal database for later PCI light enumeration
289 PciRomAddImageMapping (
291 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
292 PciIoDevice
->BusNumber
,
293 PciIoDevice
->DeviceNumber
,
294 PciIoDevice
->FunctionNumber
,
295 PciIoDevice
->PciIo
.RomImage
,
296 PciIoDevice
->PciIo
.RomSize
303 // Determine if there are EFI images in the option rom
305 HasEfiImage
= ContainEfiImage (PciIoDevice
->PciIo
.RomImage
, PciIoDevice
->PciIo
.RomSize
);
308 Status
= gBS
->InstallMultipleProtocolInterfaces (
309 &PciIoDevice
->Handle
,
310 &gEfiLoadFile2ProtocolGuid
,
311 &PciIoDevice
->LoadFile2
,
314 if (EFI_ERROR (Status
)) {
315 gBS
->UninstallMultipleProtocolInterfaces (
316 &PciIoDevice
->Handle
,
317 &gEfiDevicePathProtocolGuid
,
318 PciIoDevice
->DevicePath
,
319 &gEfiPciIoProtocolGuid
,
328 if (!PciIoDevice
->AllOpRomProcessed
) {
330 PciIoDevice
->AllOpRomProcessed
= TRUE
;
333 // Dispatch the EFI OpRom for the PCI device.
334 // The OpRom is got from platform in the above code
335 // or loaded from device in the previous round of bus enumeration
338 ProcessOpRomImage (PciIoDevice
);
342 if (PciIoDevice
->BusOverride
) {
344 // Install Bus Specific Driver Override Protocol
346 Status
= gBS
->InstallMultipleProtocolInterfaces (
347 &PciIoDevice
->Handle
,
348 &gEfiBusSpecificDriverOverrideProtocolGuid
,
349 &PciIoDevice
->PciDriverOverride
,
352 if (EFI_ERROR (Status
)) {
353 gBS
->UninstallMultipleProtocolInterfaces (
354 &PciIoDevice
->Handle
,
355 &gEfiDevicePathProtocolGuid
,
356 PciIoDevice
->DevicePath
,
357 &gEfiPciIoProtocolGuid
,
362 gBS
->UninstallMultipleProtocolInterfaces (
363 &PciIoDevice
->Handle
,
364 &gEfiLoadFile2ProtocolGuid
,
365 &PciIoDevice
->LoadFile2
,
374 Status
= gBS
->OpenProtocol (
376 &gEfiPciRootBridgeIoProtocolGuid
,
377 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
378 gPciBusDriverBinding
.DriverBindingHandle
,
380 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
382 if (EFI_ERROR (Status
)) {
386 if (Handle
!= NULL
) {
387 *Handle
= PciIoDevice
->Handle
;
391 // Indicate the pci device is registered
393 PciIoDevice
->Registered
= TRUE
;
399 This function is used to remove the whole PCI devices on the specified bridge from
402 @param RootBridgeHandle The root bridge device handle.
403 @param Bridge The bridge device to be removed.
407 RemoveAllPciDeviceOnBridge (
408 EFI_HANDLE RootBridgeHandle
,
409 PCI_IO_DEVICE
*Bridge
412 LIST_ENTRY
*CurrentLink
;
415 while (!IsListEmpty (&Bridge
->ChildList
)) {
417 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
418 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
421 // Check if the current node has been deregistered before
422 // If it is not, then deregister it
424 if (Temp
->Registered
) {
425 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
429 // Remove this node from the linked list
431 RemoveEntryList (CurrentLink
);
433 if (!IsListEmpty (&Temp
->ChildList
)) {
434 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
437 FreePciDevice (Temp
);
442 This function is used to de-register the PCI IO device.
444 That includes un-installing PciIo protocol from the specified PCI
447 @param Controller An EFI handle for the PCI bus controller.
448 @param Handle PCI device handle.
450 @retval EFI_SUCCESS The PCI device is successfully de-registered.
451 @retval other An error occurred when de-registering the PCI device.
455 DeRegisterPciDevice (
456 IN EFI_HANDLE Controller
,
461 EFI_PCI_IO_PROTOCOL
*PciIo
;
463 PCI_IO_DEVICE
*PciIoDevice
;
465 LIST_ENTRY
*CurrentLink
;
466 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
468 Status
= gBS
->OpenProtocol (
470 &gEfiPciIoProtocolGuid
,
472 gPciBusDriverBinding
.DriverBindingHandle
,
474 EFI_OPEN_PROTOCOL_GET_PROTOCOL
476 if (!EFI_ERROR (Status
)) {
477 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
480 // If it is already de-registered
482 if (!PciIoDevice
->Registered
) {
487 // If it is PPB, first de-register its children
490 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
492 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
494 while (CurrentLink
!= NULL
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
495 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
496 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
498 if (EFI_ERROR (Status
)) {
502 CurrentLink
= CurrentLink
->ForwardLink
;
507 // Close the child handle
509 Status
= gBS
->CloseProtocol (
511 &gEfiPciRootBridgeIoProtocolGuid
,
512 gPciBusDriverBinding
.DriverBindingHandle
,
517 // Un-install the Device Path protocol and PCI I/O protocol
518 // and Bus Specific Driver Override protocol if needed.
520 if (PciIoDevice
->BusOverride
) {
521 Status
= gBS
->UninstallMultipleProtocolInterfaces (
523 &gEfiDevicePathProtocolGuid
,
524 PciIoDevice
->DevicePath
,
525 &gEfiPciIoProtocolGuid
,
527 &gEfiBusSpecificDriverOverrideProtocolGuid
,
528 &PciIoDevice
->PciDriverOverride
,
532 Status
= gBS
->UninstallMultipleProtocolInterfaces (
534 &gEfiDevicePathProtocolGuid
,
535 PciIoDevice
->DevicePath
,
536 &gEfiPciIoProtocolGuid
,
542 if (!EFI_ERROR (Status
)) {
544 // Try to uninstall LoadFile2 protocol if exists
546 Status
= gBS
->OpenProtocol (
548 &gEfiLoadFile2ProtocolGuid
,
550 gPciBusDriverBinding
.DriverBindingHandle
,
552 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
554 if (!EFI_ERROR (Status
)) {
555 Status
= gBS
->UninstallMultipleProtocolInterfaces (
557 &gEfiLoadFile2ProtocolGuid
,
558 &PciIoDevice
->LoadFile2
,
565 Status
= EFI_SUCCESS
;
569 if (EFI_ERROR (Status
)) {
572 &gEfiPciRootBridgeIoProtocolGuid
,
573 (VOID
**) &PciRootBridgeIo
,
574 gPciBusDriverBinding
.DriverBindingHandle
,
576 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
582 // The Device Driver should disable this device after disconnect
583 // so the Pci Bus driver will not touch this device any more.
584 // Restore the register field to the original value
586 PciIoDevice
->Registered
= FALSE
;
587 PciIoDevice
->Handle
= NULL
;
591 // Handle may be closed before
600 Start to manage the PCI device on the specified root bridge or PCI-PCI Bridge.
602 @param Controller The root bridge handle.
603 @param RootBridge A pointer to the PCI_IO_DEVICE.
604 @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.
605 @param NumberOfChildren Children number.
606 @param ChildHandleBuffer A pointer to the child handle buffer.
608 @retval EFI_NOT_READY Device is not allocated.
609 @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.
610 @retval EFI_NOT_FOUND Can not find the specific device.
611 @retval EFI_SUCCESS Success to start Pci devices on bridge.
615 StartPciDevicesOnBridge (
616 IN EFI_HANDLE Controller
,
617 IN PCI_IO_DEVICE
*RootBridge
,
618 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
619 IN OUT UINT8
*NumberOfChildren
,
620 IN OUT EFI_HANDLE
*ChildHandleBuffer
624 PCI_IO_DEVICE
*PciIoDevice
;
625 EFI_DEV_PATH_PTR Node
;
626 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
628 LIST_ENTRY
*CurrentLink
;
632 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
634 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
636 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
637 if (RemainingDevicePath
!= NULL
) {
639 Node
.DevPath
= RemainingDevicePath
;
641 if (Node
.Pci
->Device
!= PciIoDevice
->DeviceNumber
||
642 Node
.Pci
->Function
!= PciIoDevice
->FunctionNumber
) {
643 CurrentLink
= CurrentLink
->ForwardLink
;
648 // Check if the device has been assigned with required resource
650 if (!PciIoDevice
->Allocated
) {
651 return EFI_NOT_READY
;
655 // Check if the current node has been registered before
656 // If it is not, register it
658 if (!PciIoDevice
->Registered
) {
659 Status
= RegisterPciDevice (
667 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
668 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
669 (*NumberOfChildren
)++;
673 // Get the next device path
675 CurrentDevicePath
= NextDevicePathNode (RemainingDevicePath
);
676 if (IsDevicePathEnd (CurrentDevicePath
)) {
683 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
684 Status
= StartPciDevicesOnBridge (
692 PciIoDevice
->PciIo
.Attributes (
693 &(PciIoDevice
->PciIo
),
694 EfiPciIoAttributeOperationSupported
,
698 Supports
&= (UINT64
)EFI_PCI_DEVICE_ENABLE
;
699 PciIoDevice
->PciIo
.Attributes (
700 &(PciIoDevice
->PciIo
),
701 EfiPciIoAttributeOperationEnable
,
710 // Currently, the PCI bus driver only support PCI-PCI bridge
712 return EFI_UNSUPPORTED
;
718 // If remaining device path is NULL,
719 // try to enable all the pci devices under this bridge
721 if (!PciIoDevice
->Registered
&& PciIoDevice
->Allocated
) {
722 Status
= RegisterPciDevice (
730 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
731 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
732 (*NumberOfChildren
)++;
735 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
736 Status
= StartPciDevicesOnBridge (
744 PciIoDevice
->PciIo
.Attributes (
745 &(PciIoDevice
->PciIo
),
746 EfiPciIoAttributeOperationSupported
,
750 Supports
&= (UINT64
)EFI_PCI_DEVICE_ENABLE
;
751 PciIoDevice
->PciIo
.Attributes (
752 &(PciIoDevice
->PciIo
),
753 EfiPciIoAttributeOperationEnable
,
760 CurrentLink
= CurrentLink
->ForwardLink
;
764 if (PciIoDevice
== NULL
) {
765 return EFI_NOT_FOUND
;
772 Start to manage all the PCI devices it found previously under
773 the entire host bridge.
775 @param Controller The root bridge handle.
777 @retval EFI_NOT_READY Device is not allocated.
778 @retval EFI_SUCCESS Success to start Pci device on host bridge.
783 IN EFI_HANDLE Controller
786 PCI_IO_DEVICE
*RootBridge
;
787 EFI_HANDLE ThisHostBridge
;
788 LIST_ENTRY
*CurrentLink
;
790 RootBridge
= GetRootBridgeByHandle (Controller
);
791 ASSERT (RootBridge
!= NULL
);
792 ThisHostBridge
= RootBridge
->PciRootBridgeIo
->ParentHandle
;
794 CurrentLink
= mPciDevicePool
.ForwardLink
;
796 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
798 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
800 // Locate the right root bridge to start
802 if (RootBridge
->PciRootBridgeIo
->ParentHandle
== ThisHostBridge
) {
803 StartPciDevicesOnBridge (
812 CurrentLink
= CurrentLink
->ForwardLink
;
819 Create root bridge device.
821 @param RootBridgeHandle Specified root bridge handle.
823 @return The crated root bridge device instance, NULL means no
824 root bridge device instance created.
829 IN EFI_HANDLE RootBridgeHandle
834 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
835 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
837 Dev
= AllocateZeroPool (sizeof (PCI_IO_DEVICE
));
842 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
843 Dev
->Handle
= RootBridgeHandle
;
844 InitializeListHead (&Dev
->ChildList
);
846 Status
= gBS
->OpenProtocol (
848 &gEfiDevicePathProtocolGuid
,
849 (VOID
**) &ParentDevicePath
,
850 gPciBusDriverBinding
.DriverBindingHandle
,
852 EFI_OPEN_PROTOCOL_GET_PROTOCOL
855 if (EFI_ERROR (Status
)) {
861 // Record the root bridge parent device path
863 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
866 // Get the pci root bridge io protocol
868 Status
= gBS
->OpenProtocol (
870 &gEfiPciRootBridgeIoProtocolGuid
,
871 (VOID
**) &PciRootBridgeIo
,
872 gPciBusDriverBinding
.DriverBindingHandle
,
874 EFI_OPEN_PROTOCOL_GET_PROTOCOL
877 if (EFI_ERROR (Status
)) {
882 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
885 // Initialize the PCI I/O instance structure
887 InitializePciIoInstance (Dev
);
888 InitializePciDriverOverrideInstance (Dev
);
889 InitializePciLoadFile2 (Dev
);
892 // Initialize reserved resource list and
893 // option rom driver list
895 InitializeListHead (&Dev
->ReservedResourceList
);
896 InitializeListHead (&Dev
->OptionRomDriverList
);
902 Get root bridge device instance by specific root bridge handle.
904 @param RootBridgeHandle Given root bridge handle.
906 @return The root bridge device instance, NULL means no root bridge
907 device instance found.
911 GetRootBridgeByHandle (
912 EFI_HANDLE RootBridgeHandle
915 PCI_IO_DEVICE
*RootBridgeDev
;
916 LIST_ENTRY
*CurrentLink
;
918 CurrentLink
= mPciDevicePool
.ForwardLink
;
920 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
922 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
923 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
924 return RootBridgeDev
;
927 CurrentLink
= CurrentLink
->ForwardLink
;
934 Judge whether Pci device existed.
936 @param Bridge Parent bridge instance.
937 @param PciIoDevice Device instance.
939 @retval TRUE Pci device existed.
940 @retval FALSE Pci device did not exist.
945 IN PCI_IO_DEVICE
*Bridge
,
946 IN PCI_IO_DEVICE
*PciIoDevice
951 LIST_ENTRY
*CurrentLink
;
953 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
955 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
957 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
959 if (Temp
== PciIoDevice
) {
963 if (!IsListEmpty (&Temp
->ChildList
)) {
964 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
969 CurrentLink
= CurrentLink
->ForwardLink
;
976 Get the active VGA device on the specified Host Bridge.
978 @param HostBridgeHandle Host Bridge handle.
980 @return The active VGA device on the specified Host Bridge.
984 LocateVgaDeviceOnHostBridge (
985 IN EFI_HANDLE HostBridgeHandle
988 LIST_ENTRY
*CurrentLink
;
989 PCI_IO_DEVICE
*PciIoDevice
;
991 CurrentLink
= mPciDevicePool
.ForwardLink
;
993 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
995 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
997 if (PciIoDevice
->PciRootBridgeIo
->ParentHandle
== HostBridgeHandle
) {
999 PciIoDevice
= LocateVgaDevice (PciIoDevice
);
1001 if (PciIoDevice
!= NULL
) {
1006 CurrentLink
= CurrentLink
->ForwardLink
;
1013 Locate the active VGA device under the bridge.
1015 @param Bridge PCI IO instance for the bridge.
1017 @return The active VGA device.
1022 IN PCI_IO_DEVICE
*Bridge
1025 LIST_ENTRY
*CurrentLink
;
1026 PCI_IO_DEVICE
*PciIoDevice
;
1028 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1030 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
1032 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1034 if (IS_PCI_VGA(&PciIoDevice
->Pci
) &&
1035 (PciIoDevice
->Attributes
&
1036 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1037 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1038 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
)) != 0) {
1042 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
1044 PciIoDevice
= LocateVgaDevice (PciIoDevice
);
1046 if (PciIoDevice
!= NULL
) {
1051 CurrentLink
= CurrentLink
->ForwardLink
;