3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "PciDeviceSupport.h"
19 // This device structure is serviced as a header.
20 // Its Next field points to the first root bridge device node
22 LIST_ENTRY gPciDevicePool
;
25 InitializePciDevicePool (
32 Initialize the gPciDevicePool
41 // TODO: EFI_SUCCESS - add return value to function comment
43 InitializeListHead (&gPciDevicePool
);
50 PCI_IO_DEVICE
*RootBridge
56 Insert a root bridge into PCI device pool
60 RootBridge - A pointer to the PCI_IO_DEVICE.
67 // TODO: EFI_SUCCESS - add return value to function comment
70 InsertTailList (&gPciDevicePool
, &(RootBridge
->Link
));
77 PCI_IO_DEVICE
*Bridge
,
78 PCI_IO_DEVICE
*PciDeviceNode
84 This function is used to insert a PCI device node under
88 Bridge - A pointer to the PCI_IO_DEVICE.
89 PciDeviceNode - A pointer to the PCI_IO_DEVICE.
96 // TODO: EFI_SUCCESS - add return value to function comment
99 InsertTailList (&Bridge
->ChildList
, &(PciDeviceNode
->Link
));
100 PciDeviceNode
->Parent
= Bridge
;
107 IN PCI_IO_DEVICE
*RootBridge
116 RootBridge - A pointer to the PCI_IO_DEVICE.
123 // TODO: EFI_SUCCESS - add return value to function comment
125 DestroyPciDeviceTree (RootBridge
);
127 FreePciDevice (RootBridge
);
134 IN PCI_IO_DEVICE
*PciIoDevice
140 Destroy a pci device node.
141 Also all direct or indirect allocated resource for this node will be freed.
145 PciIoDevice - A pointer to the PCI_IO_DEVICE.
152 // TODO: EFI_SUCCESS - add return value to function comment
156 // Assume all children have been removed underneath this device
158 if (PciIoDevice
->ResourcePaddingDescriptors
!= NULL
) {
159 gBS
->FreePool (PciIoDevice
->ResourcePaddingDescriptors
);
162 if (PciIoDevice
->DevicePath
!= NULL
) {
163 gBS
->FreePool (PciIoDevice
->DevicePath
);
166 gBS
->FreePool (PciIoDevice
);
172 DestroyPciDeviceTree (
173 IN PCI_IO_DEVICE
*Bridge
179 Destroy all the pci device node under the bridge.
180 Bridge itself is not included.
184 Bridge - A pointer to the PCI_IO_DEVICE.
191 // TODO: EFI_SUCCESS - add return value to function comment
193 LIST_ENTRY
*CurrentLink
;
196 while (!IsListEmpty (&Bridge
->ChildList
)) {
198 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
201 // Remove this node from the linked list
203 RemoveEntryList (CurrentLink
);
205 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
207 if (!IsListEmpty (&Temp
->ChildList
)) {
208 DestroyPciDeviceTree (Temp
);
211 FreePciDevice (Temp
);
218 DestroyRootBridgeByHandle (
219 EFI_HANDLE Controller
225 Destroy all device nodes under the root bridge
226 specified by Controller.
227 The root bridge itself is also included.
231 Controller - An efi handle.
238 // TODO: EFI_SUCCESS - add return value to function comment
239 // TODO: EFI_NOT_FOUND - add return value to function comment
242 LIST_ENTRY
*CurrentLink
;
245 CurrentLink
= gPciDevicePool
.ForwardLink
;
247 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
248 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
250 if (Temp
->Handle
== Controller
) {
252 RemoveEntryList (CurrentLink
);
254 DestroyPciDeviceTree (Temp
);
256 FreePciDevice (Temp
);
261 CurrentLink
= CurrentLink
->ForwardLink
;
264 return EFI_NOT_FOUND
;
269 IN EFI_HANDLE Controller
,
270 IN PCI_IO_DEVICE
*PciIoDevice
,
271 OUT EFI_HANDLE
*Handle OPTIONAL
277 This function registers the PCI IO device. It creates a handle for this PCI IO device
278 (if the handle does not exist), attaches appropriate protocols onto the handle, does
279 necessary initialization, and sets up parent/child relationship with its bus controller.
283 Controller - An EFI handle for the PCI bus controller.
284 PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
285 Handle - A pointer to hold the EFI handle for the PCI IO device.
289 EFI_SUCCESS - The PCI device is successfully registered.
290 Others - An error occurred when registering the PCI device.
295 VOID
*PlatformOpRomBuffer
;
296 UINTN PlatformOpRomSize
;
297 UINT8 PciExpressCapRegOffset
;
298 EFI_PCI_IO_PROTOCOL
*PciIo
;
302 // Install the pciio protocol, device path protocol
304 Status
= gBS
->InstallMultipleProtocolInterfaces (
305 &PciIoDevice
->Handle
,
306 &gEfiDevicePathProtocolGuid
,
307 PciIoDevice
->DevicePath
,
308 &gEfiPciIoProtocolGuid
,
312 if (EFI_ERROR (Status
)) {
317 // Detect if PCI Express Device
319 PciExpressCapRegOffset
= 0;
320 Status
= LocateCapabilityRegBlock (
322 EFI_PCI_CAPABILITY_ID_PCIEXP
,
323 &PciExpressCapRegOffset
,
326 if (!EFI_ERROR (Status
)) {
327 PciIoDevice
->IsPciExp
= TRUE
;
331 // Force Interrupt line to "Unknown" or "No Connection"
333 PciIo
= &(PciIoDevice
->PciIo
);
334 Data8
= PCI_INT_LINE_UNKNOWN
;
335 PciIoWrite (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &Data8
);
338 // Process Platform OpRom
340 if (gPciPlatformProtocol
!= NULL
&& !PciIoDevice
->AllOpRomProcessed
) {
341 PciIoDevice
->AllOpRomProcessed
= TRUE
;
343 Status
= gPciPlatformProtocol
->GetPciRom (
344 gPciPlatformProtocol
,
346 &PlatformOpRomBuffer
,
350 if (!EFI_ERROR (Status
)) {
353 // Have Platform OpRom
355 PciIoDevice
->RomSize
= PlatformOpRomSize
;
356 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
357 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
362 ProcessOpRomImage (PciIoDevice
);
366 if (PciIoDevice
->BusOverride
) {
368 // Install BusSpecificDriverOverride Protocol
370 Status
= gBS
->InstallMultipleProtocolInterfaces (
371 &PciIoDevice
->Handle
,
372 &gEfiBusSpecificDriverOverrideProtocolGuid
,
373 &PciIoDevice
->PciDriverOverride
,
376 if (EFI_ERROR (Status
)) {
377 gBS
->UninstallMultipleProtocolInterfaces (
378 &PciIoDevice
->Handle
,
379 &gEfiDevicePathProtocolGuid
,
380 PciIoDevice
->DevicePath
,
381 &gEfiPciIoProtocolGuid
,
390 Status
= gBS
->OpenProtocol (
392 &gEfiPciRootBridgeIoProtocolGuid
,
393 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
394 gPciBusDriverBinding
.DriverBindingHandle
,
396 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
398 if (EFI_ERROR (Status
)) {
403 // Install Pccard Hotplug GUID for Pccard device so that
404 // to notify CardBus driver to stop the device when de-register happens
406 InstallPciHotplugGuid (PciIoDevice
);
408 if (Handle
!= NULL
) {
409 *Handle
= PciIoDevice
->Handle
;
413 // Indicate the pci device is registered
415 PciIoDevice
->Registered
= TRUE
;
421 RemoveAllPciDeviceOnBridge (
422 EFI_HANDLE RootBridgeHandle
,
423 PCI_IO_DEVICE
*Bridge
429 This function is used to remove the whole PCI devices from the bridge.
433 RootBridgeHandle - An efi handle.
434 Bridge - A pointer to the PCI_IO_DEVICE.
441 // TODO: EFI_SUCCESS - add return value to function comment
444 LIST_ENTRY
*CurrentLink
;
447 while (!IsListEmpty (&Bridge
->ChildList
)) {
449 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
450 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
453 // Check if the current node has been deregistered before
454 // If it is not, then deregister it
456 if (Temp
->Registered
) {
457 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
461 // Remove this node from the linked list
463 RemoveEntryList (CurrentLink
);
465 if (!IsListEmpty (&Temp
->ChildList
)) {
466 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
469 FreePciDevice (Temp
);
476 DeRegisterPciDevice (
477 IN EFI_HANDLE Controller
,
484 This function is used to de-register the PCI device from the EFI,
485 That includes un-installing PciIo protocol from the specified PCI
490 Controller - An efi handle.
491 Handle - An efi handle.
498 // TODO: EFI_SUCCESS - add return value to function comment
499 // TODO: EFI_SUCCESS - add return value to function comment
500 // TODO: EFI_SUCCESS - add return value to function comment
502 EFI_PCI_IO_PROTOCOL
*PciIo
;
504 PCI_IO_DEVICE
*PciIoDevice
;
506 LIST_ENTRY
*CurrentLink
;
507 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
509 Status
= gBS
->OpenProtocol (
511 &gEfiPciIoProtocolGuid
,
513 gPciBusDriverBinding
.DriverBindingHandle
,
515 EFI_OPEN_PROTOCOL_GET_PROTOCOL
517 if (!EFI_ERROR (Status
)) {
518 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
521 // If it is already de-registered
523 if (!PciIoDevice
->Registered
) {
528 // If it is PPB, first de-register its children
531 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
533 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
535 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
536 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
537 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
539 if (EFI_ERROR (Status
)) {
543 CurrentLink
= CurrentLink
->ForwardLink
;
547 // Uninstall Pccard Hotplug GUID for Pccard device
549 UninstallPciHotplugGuid (PciIoDevice
);
552 // Close the child handle
554 Status
= gBS
->CloseProtocol (
556 &gEfiPciRootBridgeIoProtocolGuid
,
557 gPciBusDriverBinding
.DriverBindingHandle
,
562 // Un-install the device path protocol and pci io protocol
564 if (PciIoDevice
->BusOverride
) {
565 Status
= gBS
->UninstallMultipleProtocolInterfaces (
567 &gEfiDevicePathProtocolGuid
,
568 PciIoDevice
->DevicePath
,
569 &gEfiPciIoProtocolGuid
,
571 &gEfiBusSpecificDriverOverrideProtocolGuid
,
572 &PciIoDevice
->PciDriverOverride
,
576 Status
= gBS
->UninstallMultipleProtocolInterfaces (
578 &gEfiDevicePathProtocolGuid
,
579 PciIoDevice
->DevicePath
,
580 &gEfiPciIoProtocolGuid
,
586 if (EFI_ERROR (Status
)) {
589 &gEfiPciRootBridgeIoProtocolGuid
,
590 (VOID
**) &PciRootBridgeIo
,
591 gPciBusDriverBinding
.DriverBindingHandle
,
593 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
599 // The Device Driver should disable this device after disconnect
600 // so the Pci Bus driver will not touch this device any more.
601 // Restore the register field to the original value
603 PciIoDevice
->Registered
= FALSE
;
604 PciIoDevice
->Handle
= NULL
;
608 // Handle may be closed before
617 StartPciDevicesOnBridge (
618 IN EFI_HANDLE Controller
,
619 IN PCI_IO_DEVICE
*RootBridge
,
620 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
621 IN OUT UINT8
*NumberOfChildren
,
622 IN OUT EFI_HANDLE
*ChildHandleBuffer
628 Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge
632 Controller - An efi handle.
633 RootBridge - A pointer to the PCI_IO_DEVICE.
634 RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
635 NumberOfChildren - Children number.
636 ChildHandleBuffer - A pointer to the child handle buffer.
643 // TODO: EFI_NOT_READY - add return value to function comment
644 // TODO: EFI_SUCCESS - add return value to function comment
645 // TODO: EFI_UNSUPPORTED - add return value to function comment
646 // TODO: EFI_NOT_FOUND - add return value to function comment
649 PCI_IO_DEVICE
*PciIoDevice
;
650 EFI_DEV_PATH_PTR Node
;
651 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
653 LIST_ENTRY
*CurrentLink
;
656 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
658 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
660 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
661 if (RemainingDevicePath
!= NULL
) {
663 Node
.DevPath
= RemainingDevicePath
;
665 if (Node
.Pci
->Device
!= Temp
->DeviceNumber
||
666 Node
.Pci
->Function
!= Temp
->FunctionNumber
) {
667 CurrentLink
= CurrentLink
->ForwardLink
;
672 // Check if the device has been assigned with required resource
674 if (!Temp
->Allocated
) {
675 return EFI_NOT_READY
;
679 // Check if the current node has been registered before
680 // If it is not, register it
682 if (!Temp
->Registered
) {
685 Status
= RegisterPciDevice (
693 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& Temp
->Registered
) {
694 ChildHandleBuffer
[*NumberOfChildren
] = Temp
->Handle
;
695 (*NumberOfChildren
)++;
699 // Get the next device path
701 CurrentDevicePath
= EfiNextDevicePathNode (RemainingDevicePath
);
702 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
709 if (!IsListEmpty (&Temp
->ChildList
)) {
710 Status
= StartPciDevicesOnBridge (
718 Temp
->PciIo
.Attributes (
720 EfiPciIoAttributeOperationSupported
,
724 Supports
&= EFI_PCI_DEVICE_ENABLE
;
725 Temp
->PciIo
.Attributes (
727 EfiPciIoAttributeOperationEnable
,
736 // Currently, the PCI bus driver only support PCI-PCI bridge
738 return EFI_UNSUPPORTED
;
744 // If remaining device path is NULL,
745 // try to enable all the pci devices under this bridge
748 if (!Temp
->Registered
&& Temp
->Allocated
) {
752 Status
= RegisterPciDevice (
760 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& Temp
->Registered
) {
761 ChildHandleBuffer
[*NumberOfChildren
] = Temp
->Handle
;
762 (*NumberOfChildren
)++;
765 if (!IsListEmpty (&Temp
->ChildList
)) {
766 Status
= StartPciDevicesOnBridge (
774 Temp
->PciIo
.Attributes (
776 EfiPciIoAttributeOperationSupported
,
780 Supports
&= EFI_PCI_DEVICE_ENABLE
;
781 Temp
->PciIo
.Attributes (
783 EfiPciIoAttributeOperationEnable
,
790 CurrentLink
= CurrentLink
->ForwardLink
;
795 return EFI_NOT_FOUND
;
800 IN EFI_HANDLE Controller
,
801 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
807 Start to manage the PCI device according to RemainingDevicePath
808 If RemainingDevicePath == NULL, the PCI bus driver will start
809 to manage all the PCI devices it found previously
812 Controller - An efi handle.
813 RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
820 // TODO: EFI_UNSUPPORTED - add return value to function comment
821 // TODO: EFI_SUCCESS - add return value to function comment
823 EFI_DEV_PATH_PTR Node
;
824 PCI_IO_DEVICE
*RootBridge
;
825 LIST_ENTRY
*CurrentLink
;
827 if (RemainingDevicePath
!= NULL
) {
830 // Check if the RemainingDevicePath is valid
832 Node
.DevPath
= RemainingDevicePath
;
833 if ((Node
.DevPath
->Type
!= HARDWARE_DEVICE_PATH
) ||
834 ((Node
.DevPath
->SubType
!= HW_PCI_DP
) &&
835 (DevicePathNodeLength (Node
.DevPath
) != sizeof (PCI_DEVICE_PATH
)))
837 return EFI_UNSUPPORTED
;
841 CurrentLink
= gPciDevicePool
.ForwardLink
;
843 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
845 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
847 // Locate the right root bridge to start
849 if (RootBridge
->Handle
== Controller
) {
850 StartPciDevicesOnBridge (
859 CurrentLink
= CurrentLink
->ForwardLink
;
867 IN EFI_HANDLE RootBridgeHandle
875 RootBridgeHandle - An efi handle.
886 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
887 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
890 Status
= gBS
->AllocatePool (
892 sizeof (PCI_IO_DEVICE
),
896 if (EFI_ERROR (Status
)) {
900 ZeroMem (Dev
, sizeof (PCI_IO_DEVICE
));
901 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
902 Dev
->Handle
= RootBridgeHandle
;
903 InitializeListHead (&Dev
->ChildList
);
905 Status
= gBS
->OpenProtocol (
907 &gEfiDevicePathProtocolGuid
,
908 (VOID
**) &ParentDevicePath
,
909 gPciBusDriverBinding
.DriverBindingHandle
,
911 EFI_OPEN_PROTOCOL_GET_PROTOCOL
914 if (EFI_ERROR (Status
)) {
920 // Record the root bridge parent device path
922 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
925 // Get the pci root bridge io protocol
927 Status
= gBS
->OpenProtocol (
929 &gEfiPciRootBridgeIoProtocolGuid
,
930 (VOID
**) &PciRootBridgeIo
,
931 gPciBusDriverBinding
.DriverBindingHandle
,
933 EFI_OPEN_PROTOCOL_GET_PROTOCOL
936 if (EFI_ERROR (Status
)) {
941 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
944 // Initialize the PCI I/O instance structure
946 Status
= InitializePciIoInstance (Dev
);
947 Status
= InitializePciDriverOverrideInstance (Dev
);
950 // Initialize reserved resource list and
951 // option rom driver list
953 InitializeListHead (&Dev
->ReservedResourceList
);
954 InitializeListHead (&Dev
->OptionRomDriverList
);
960 GetRootBridgeByHandle (
961 EFI_HANDLE RootBridgeHandle
970 RootBridgeHandle - An efi handle.
978 PCI_IO_DEVICE
*RootBridgeDev
;
979 LIST_ENTRY
*CurrentLink
;
981 CurrentLink
= gPciDevicePool
.ForwardLink
;
983 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
985 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
986 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
987 return RootBridgeDev
;
990 CurrentLink
= CurrentLink
->ForwardLink
;
998 IN EFI_HANDLE RootBridgeHandle
1002 Routine Description:
1004 This function searches if RootBridgeHandle has already existed
1005 in current device pool.
1007 If so, it means the given root bridge has been already enumerated.
1011 RootBridgeHandle - An efi handle.
1019 PCI_IO_DEVICE
*Bridge
;
1021 Bridge
= GetRootBridgeByHandle (RootBridgeHandle
);
1023 if (Bridge
!= NULL
) {
1032 IN PCI_IO_DEVICE
*Bridge
,
1033 IN PCI_IO_DEVICE
*PciIoDevice
1037 Routine Description:
1041 Bridge - A pointer to the PCI_IO_DEVICE.
1042 PciIoDevice - A pointer to the PCI_IO_DEVICE.
1051 PCI_IO_DEVICE
*Temp
;
1052 LIST_ENTRY
*CurrentLink
;
1054 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1056 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
1058 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1060 if (Temp
== PciIoDevice
) {
1064 if (!IsListEmpty (&Temp
->ChildList
)) {
1065 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
1070 CurrentLink
= CurrentLink
->ForwardLink
;
1077 ActiveVGADeviceOnTheSameSegment (
1078 IN PCI_IO_DEVICE
*VgaDevice
1082 Routine Description:
1086 VgaDevice - A pointer to the PCI_IO_DEVICE.
1094 LIST_ENTRY
*CurrentLink
;
1095 PCI_IO_DEVICE
*Temp
;
1097 CurrentLink
= gPciDevicePool
.ForwardLink
;
1099 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
1101 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1103 if (Temp
->PciRootBridgeIo
->SegmentNumber
== VgaDevice
->PciRootBridgeIo
->SegmentNumber
) {
1105 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1112 CurrentLink
= CurrentLink
->ForwardLink
;
1119 ActiveVGADeviceOnTheRootBridge (
1120 IN PCI_IO_DEVICE
*RootBridge
1124 Routine Description:
1128 RootBridge - A pointer to the PCI_IO_DEVICE.
1136 LIST_ENTRY
*CurrentLink
;
1137 PCI_IO_DEVICE
*Temp
;
1139 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1141 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
1143 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1145 if (IS_PCI_VGA(&Temp
->Pci
) &&
1147 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1148 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1149 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
))) {
1153 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
1155 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1162 CurrentLink
= CurrentLink
->ForwardLink
;
1170 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1171 IN EFI_DEVICE_PATH_PROTOCOL
*HpcDevicePath
,
1172 OUT UINT64
*PciAddress
1176 Routine Description:
1180 PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1181 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
1182 PciAddress - A pointer to the pci address.
1189 // TODO: EFI_NOT_FOUND - add return value to function comment
1190 // TODO: EFI_NOT_FOUND - add return value to function comment
1191 // TODO: EFI_SUCCESS - add return value to function comment
1192 // TODO: EFI_NOT_FOUND - add return value to function comment
1194 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1195 EFI_DEV_PATH_PTR Node
;
1196 LIST_ENTRY
*CurrentLink
;
1197 PCI_IO_DEVICE
*RootBridge
;
1200 CurrentDevicePath
= HpcDevicePath
;
1203 // Get the remaining device path for this PCI device, if it is a PCI device
1205 while (!EfiIsDevicePathEnd (CurrentDevicePath
)) {
1207 Node
.DevPath
= CurrentDevicePath
;
1210 // Check if it is PCI device Path?
1212 if ((Node
.DevPath
->Type
!= HARDWARE_DEVICE_PATH
) ||
1213 ((Node
.DevPath
->SubType
!= HW_PCI_DP
) &&
1214 (DevicePathNodeLength (Node
.DevPath
) != sizeof (PCI_DEVICE_PATH
)))) {
1215 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1223 // Check if it is not PCI device path
1225 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
1226 return EFI_NOT_FOUND
;
1229 CurrentLink
= gPciDevicePool
.ForwardLink
;
1231 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
1233 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1235 // Locate the right root bridge to start
1237 if (RootBridge
->PciRootBridgeIo
== PciRootBridgeIo
) {
1238 Status
= GetHpcPciAddressFromRootBridge (
1243 if (EFI_ERROR (Status
)) {
1244 return EFI_NOT_FOUND
;
1251 CurrentLink
= CurrentLink
->ForwardLink
;
1254 return EFI_NOT_FOUND
;
1258 GetHpcPciAddressFromRootBridge (
1259 IN PCI_IO_DEVICE
*RootBridge
,
1260 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
1261 OUT UINT64
*PciAddress
1265 Routine Description:
1269 PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1270 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
1271 PciAddress - A pointer to the pci address.
1278 // TODO: RootBridge - add argument and description to function comment
1279 // TODO: RemainingDevicePath - add argument and description to function comment
1280 // TODO: EFI_SUCCESS - add return value to function comment
1281 // TODO: EFI_NOT_FOUND - add return value to function comment
1282 // TODO: EFI_SUCCESS - add return value to function comment
1284 EFI_DEV_PATH_PTR Node
;
1285 PCI_IO_DEVICE
*Temp
;
1286 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1287 LIST_ENTRY
*CurrentLink
;
1292 CurrentDevicePath
= RemainingDevicePath
;
1293 Node
.DevPath
= CurrentDevicePath
;
1296 while (!EfiIsDevicePathEnd (CurrentDevicePath
)) {
1298 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1299 Node
.DevPath
= CurrentDevicePath
;
1301 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
1302 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1304 if (Node
.Pci
->Device
== Temp
->DeviceNumber
&&
1305 Node
.Pci
->Function
== Temp
->FunctionNumber
) {
1310 CurrentLink
= CurrentLink
->ForwardLink
;
1314 // Check if we find the bridge
1316 if (CurrentLink
== &RootBridge
->ChildList
) {
1323 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1328 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1330 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
1331 *PciAddress
= EFI_PCI_ADDRESS (RootBridge
->BusNumber
, Node
.Pci
->Device
, Node
.Pci
->Function
, 0);
1335 return EFI_NOT_FOUND
;
1338 *PciAddress
= EFI_PCI_ADDRESS (Temp
->BusNumber
, Temp
->DeviceNumber
, Temp
->FunctionNumber
, 0);