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.
18 This file provides routine to support Pci device node manipulation
25 #include "PciDeviceSupport.h"
28 // This device structure is serviced as a header.
29 // Its Next field points to the first root bridge device node
31 LIST_ENTRY gPciDevicePool
;
34 InitializePciDevicePool (
41 Initialize the gPciDevicePool
50 // TODO: EFI_SUCCESS - add return value to function comment
52 InitializeListHead (&gPciDevicePool
);
59 PCI_IO_DEVICE
*RootBridge
65 Insert a root bridge into PCI device pool
69 RootBridge - A pointer to the PCI_IO_DEVICE.
76 // TODO: EFI_SUCCESS - add return value to function comment
79 InsertTailList (&gPciDevicePool
, &(RootBridge
->Link
));
86 PCI_IO_DEVICE
*Bridge
,
87 PCI_IO_DEVICE
*PciDeviceNode
93 This function is used to insert a PCI device node under
97 Bridge - A pointer to the PCI_IO_DEVICE.
98 PciDeviceNode - A pointer to the PCI_IO_DEVICE.
105 // TODO: EFI_SUCCESS - add return value to function comment
108 InsertTailList (&Bridge
->ChildList
, &(PciDeviceNode
->Link
));
109 PciDeviceNode
->Parent
= Bridge
;
116 IN PCI_IO_DEVICE
*RootBridge
125 RootBridge - A pointer to the PCI_IO_DEVICE.
132 // TODO: EFI_SUCCESS - add return value to function comment
134 DestroyPciDeviceTree (RootBridge
);
136 FreePciDevice (RootBridge
);
143 IN PCI_IO_DEVICE
*PciIoDevice
149 Destroy a pci device node.
150 Also all direct or indirect allocated resource for this node will be freed.
154 PciIoDevice - A pointer to the PCI_IO_DEVICE.
161 // TODO: EFI_SUCCESS - add return value to function comment
165 // Assume all children have been removed underneath this device
167 if (PciIoDevice
->ResourcePaddingDescriptors
!= NULL
) {
168 gBS
->FreePool (PciIoDevice
->ResourcePaddingDescriptors
);
171 if (PciIoDevice
->DevicePath
!= NULL
) {
172 gBS
->FreePool (PciIoDevice
->DevicePath
);
175 gBS
->FreePool (PciIoDevice
);
181 DestroyPciDeviceTree (
182 IN PCI_IO_DEVICE
*Bridge
188 Destroy all the pci device node under the bridge.
189 Bridge itself is not included.
193 Bridge - A pointer to the PCI_IO_DEVICE.
200 // TODO: EFI_SUCCESS - add return value to function comment
202 LIST_ENTRY
*CurrentLink
;
205 while (!IsListEmpty (&Bridge
->ChildList
)) {
207 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
210 // Remove this node from the linked list
212 RemoveEntryList (CurrentLink
);
214 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
216 if (!IsListEmpty (&Temp
->ChildList
)) {
217 DestroyPciDeviceTree (Temp
);
220 FreePciDevice (Temp
);
227 DestroyRootBridgeByHandle (
228 EFI_HANDLE Controller
234 Destroy all device nodes under the root bridge
235 specified by Controller.
236 The root bridge itself is also included.
240 Controller - An efi handle.
247 // TODO: EFI_SUCCESS - add return value to function comment
248 // TODO: EFI_NOT_FOUND - add return value to function comment
251 LIST_ENTRY
*CurrentLink
;
254 CurrentLink
= gPciDevicePool
.ForwardLink
;
256 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
257 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
259 if (Temp
->Handle
== Controller
) {
261 RemoveEntryList (CurrentLink
);
263 DestroyPciDeviceTree (Temp
);
265 FreePciDevice (Temp
);
270 CurrentLink
= CurrentLink
->ForwardLink
;
273 return EFI_NOT_FOUND
;
278 IN EFI_HANDLE Controller
,
279 IN PCI_IO_DEVICE
*PciIoDevice
,
280 OUT EFI_HANDLE
*Handle OPTIONAL
286 This function registers the PCI IO device. It creates a handle for this PCI IO device
287 (if the handle does not exist), attaches appropriate protocols onto the handle, does
288 necessary initialization, and sets up parent/child relationship with its bus controller.
292 Controller - An EFI handle for the PCI bus controller.
293 PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
294 Handle - A pointer to hold the EFI handle for the PCI IO device.
298 EFI_SUCCESS - The PCI device is successfully registered.
299 Others - An error occurred when registering the PCI device.
304 VOID
*PlatformOpRomBuffer
;
305 UINTN PlatformOpRomSize
;
306 UINT8 PciExpressCapRegOffset
;
307 EFI_PCI_IO_PROTOCOL
*PciIo
;
311 // Install the pciio protocol, device path protocol
313 Status
= gBS
->InstallMultipleProtocolInterfaces (
314 &PciIoDevice
->Handle
,
315 &gEfiDevicePathProtocolGuid
,
316 PciIoDevice
->DevicePath
,
317 &gEfiPciIoProtocolGuid
,
321 if (EFI_ERROR (Status
)) {
326 // Detect if PCI Express Device
328 PciExpressCapRegOffset
= 0;
329 Status
= LocateCapabilityRegBlock (
331 EFI_PCI_CAPABILITY_ID_PCIEXP
,
332 &PciExpressCapRegOffset
,
335 if (!EFI_ERROR (Status
)) {
336 PciIoDevice
->IsPciExp
= TRUE
;
340 // Force Interrupt line to "Unknown" or "No Connection"
342 PciIo
= &(PciIoDevice
->PciIo
);
343 Data8
= PCI_INT_LINE_UNKNOWN
;
345 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &Data8
);
348 // Process Platform OpRom
350 if (gPciPlatformProtocol
!= NULL
&& !PciIoDevice
->AllOpRomProcessed
) {
351 PciIoDevice
->AllOpRomProcessed
= TRUE
;
353 Status
= gPciPlatformProtocol
->GetPciRom (
354 gPciPlatformProtocol
,
356 &PlatformOpRomBuffer
,
360 if (!EFI_ERROR (Status
)) {
363 // Have Platform OpRom
365 PciIoDevice
->RomSize
= PlatformOpRomSize
;
366 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
367 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
372 ProcessOpRomImage (PciIoDevice
);
376 if (PciIoDevice
->BusOverride
) {
378 // Install BusSpecificDriverOverride Protocol
380 Status
= gBS
->InstallMultipleProtocolInterfaces (
381 &PciIoDevice
->Handle
,
382 &gEfiBusSpecificDriverOverrideProtocolGuid
,
383 &PciIoDevice
->PciDriverOverride
,
386 if (EFI_ERROR (Status
)) {
387 gBS
->UninstallMultipleProtocolInterfaces (
388 &PciIoDevice
->Handle
,
389 &gEfiDevicePathProtocolGuid
,
390 PciIoDevice
->DevicePath
,
391 &gEfiPciIoProtocolGuid
,
400 Status
= gBS
->OpenProtocol (
402 &gEfiPciRootBridgeIoProtocolGuid
,
403 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
404 gPciBusDriverBinding
.DriverBindingHandle
,
406 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
408 if (EFI_ERROR (Status
)) {
413 // Install Pccard Hotplug GUID for Pccard device so that
414 // to notify CardBus driver to stop the device when de-register happens
416 InstallPciHotplugGuid (PciIoDevice
);
418 if (Handle
!= NULL
) {
419 *Handle
= PciIoDevice
->Handle
;
423 // Indicate the pci device is registered
425 PciIoDevice
->Registered
= TRUE
;
431 RemoveAllPciDeviceOnBridge (
432 EFI_HANDLE RootBridgeHandle
,
433 PCI_IO_DEVICE
*Bridge
439 This function is used to remove the whole PCI devices from the bridge.
443 RootBridgeHandle - An efi handle.
444 Bridge - A pointer to the PCI_IO_DEVICE.
451 // TODO: EFI_SUCCESS - add return value to function comment
454 LIST_ENTRY
*CurrentLink
;
457 while (!IsListEmpty (&Bridge
->ChildList
)) {
459 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
460 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
463 // Check if the current node has been deregistered before
464 // If it is not, then deregister it
466 if (Temp
->Registered
) {
467 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
471 // Remove this node from the linked list
473 RemoveEntryList (CurrentLink
);
475 if (!IsListEmpty (&Temp
->ChildList
)) {
476 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
479 FreePciDevice (Temp
);
486 DeRegisterPciDevice (
487 IN EFI_HANDLE Controller
,
494 This function is used to de-register the PCI device from the EFI,
495 That includes un-installing PciIo protocol from the specified PCI
500 Controller - An efi handle.
501 Handle - An efi handle.
508 // TODO: EFI_SUCCESS - add return value to function comment
509 // TODO: EFI_SUCCESS - add return value to function comment
510 // TODO: EFI_SUCCESS - add return value to function comment
512 EFI_PCI_IO_PROTOCOL
*PciIo
;
514 PCI_IO_DEVICE
*PciIoDevice
;
516 LIST_ENTRY
*CurrentLink
;
517 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
519 Status
= gBS
->OpenProtocol (
521 &gEfiPciIoProtocolGuid
,
523 gPciBusDriverBinding
.DriverBindingHandle
,
525 EFI_OPEN_PROTOCOL_GET_PROTOCOL
527 if (!EFI_ERROR (Status
)) {
528 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
531 // If it is already de-registered
533 if (!PciIoDevice
->Registered
) {
538 // If it is PPB, first de-register its children
541 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
543 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
545 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
546 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
547 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
549 if (EFI_ERROR (Status
)) {
553 CurrentLink
= CurrentLink
->ForwardLink
;
557 // Uninstall Pccard Hotplug GUID for Pccard device
559 UninstallPciHotplugGuid (PciIoDevice
);
562 // Close the child handle
564 Status
= gBS
->CloseProtocol (
566 &gEfiPciRootBridgeIoProtocolGuid
,
567 gPciBusDriverBinding
.DriverBindingHandle
,
572 // Un-install the device path protocol and pci io protocol
574 if (PciIoDevice
->BusOverride
) {
575 Status
= gBS
->UninstallMultipleProtocolInterfaces (
577 &gEfiDevicePathProtocolGuid
,
578 PciIoDevice
->DevicePath
,
579 &gEfiPciIoProtocolGuid
,
581 &gEfiBusSpecificDriverOverrideProtocolGuid
,
582 &PciIoDevice
->PciDriverOverride
,
586 Status
= gBS
->UninstallMultipleProtocolInterfaces (
588 &gEfiDevicePathProtocolGuid
,
589 PciIoDevice
->DevicePath
,
590 &gEfiPciIoProtocolGuid
,
596 if (EFI_ERROR (Status
)) {
599 &gEfiPciRootBridgeIoProtocolGuid
,
600 (VOID
**) &PciRootBridgeIo
,
601 gPciBusDriverBinding
.DriverBindingHandle
,
603 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
609 // The Device Driver should disable this device after disconnect
610 // so the Pci Bus driver will not touch this device any more.
611 // Restore the register field to the original value
613 PciIoDevice
->Registered
= FALSE
;
614 PciIoDevice
->Handle
= NULL
;
618 // Handle may be closed before
627 StartPciDevicesOnBridge (
628 IN EFI_HANDLE Controller
,
629 IN PCI_IO_DEVICE
*RootBridge
,
630 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
631 IN OUT UINT8
*NumberOfChildren
,
632 IN OUT EFI_HANDLE
*ChildHandleBuffer
638 Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge
642 Controller - An efi handle.
643 RootBridge - A pointer to the PCI_IO_DEVICE.
644 RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
645 NumberOfChildren - Children number.
646 ChildHandleBuffer - A pointer to the child handle buffer.
653 // TODO: EFI_NOT_READY - add return value to function comment
654 // TODO: EFI_SUCCESS - add return value to function comment
655 // TODO: EFI_UNSUPPORTED - add return value to function comment
656 // TODO: EFI_NOT_FOUND - add return value to function comment
659 PCI_IO_DEVICE
*PciIoDevice
;
660 EFI_DEV_PATH_PTR Node
;
661 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
663 LIST_ENTRY
*CurrentLink
;
666 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
668 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
670 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
671 if (RemainingDevicePath
!= NULL
) {
673 Node
.DevPath
= RemainingDevicePath
;
675 if (Node
.Pci
->Device
!= Temp
->DeviceNumber
||
676 Node
.Pci
->Function
!= Temp
->FunctionNumber
) {
677 CurrentLink
= CurrentLink
->ForwardLink
;
682 // Check if the device has been assigned with required resource
684 if (!Temp
->Allocated
) {
685 return EFI_NOT_READY
;
689 // Check if the current node has been registered before
690 // If it is not, register it
692 if (!Temp
->Registered
) {
695 Status
= RegisterPciDevice (
703 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& Temp
->Registered
) {
704 ChildHandleBuffer
[*NumberOfChildren
] = Temp
->Handle
;
705 (*NumberOfChildren
)++;
709 // Get the next device path
711 CurrentDevicePath
= EfiNextDevicePathNode (RemainingDevicePath
);
712 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
719 if (!IsListEmpty (&Temp
->ChildList
)) {
720 Status
= StartPciDevicesOnBridge (
728 Temp
->PciIo
.Attributes (
730 EfiPciIoAttributeOperationSupported
,
734 Supports
&= EFI_PCI_DEVICE_ENABLE
;
735 Temp
->PciIo
.Attributes (
737 EfiPciIoAttributeOperationEnable
,
746 // Currently, the PCI bus driver only support PCI-PCI bridge
748 return EFI_UNSUPPORTED
;
754 // If remaining device path is NULL,
755 // try to enable all the pci devices under this bridge
758 if (!Temp
->Registered
&& Temp
->Allocated
) {
762 Status
= RegisterPciDevice (
770 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& Temp
->Registered
) {
771 ChildHandleBuffer
[*NumberOfChildren
] = Temp
->Handle
;
772 (*NumberOfChildren
)++;
775 if (!IsListEmpty (&Temp
->ChildList
)) {
776 Status
= StartPciDevicesOnBridge (
784 Temp
->PciIo
.Attributes (
786 EfiPciIoAttributeOperationSupported
,
790 Supports
&= EFI_PCI_DEVICE_ENABLE
;
791 Temp
->PciIo
.Attributes (
793 EfiPciIoAttributeOperationEnable
,
800 CurrentLink
= CurrentLink
->ForwardLink
;
805 return EFI_NOT_FOUND
;
810 IN EFI_HANDLE Controller
,
811 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
817 Start to manage the PCI device according to RemainingDevicePath
818 If RemainingDevicePath == NULL, the PCI bus driver will start
819 to manage all the PCI devices it found previously
822 Controller - An efi handle.
823 RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
830 // TODO: EFI_UNSUPPORTED - add return value to function comment
831 // TODO: EFI_SUCCESS - add return value to function comment
833 EFI_DEV_PATH_PTR Node
;
834 PCI_IO_DEVICE
*RootBridge
;
835 LIST_ENTRY
*CurrentLink
;
837 if (RemainingDevicePath
!= NULL
) {
840 // Check if the RemainingDevicePath is valid
842 Node
.DevPath
= RemainingDevicePath
;
843 if ((Node
.DevPath
->Type
!= HARDWARE_DEVICE_PATH
) ||
844 ((Node
.DevPath
->SubType
!= HW_PCI_DP
) &&
845 (DevicePathNodeLength (Node
.DevPath
) != sizeof (PCI_DEVICE_PATH
)))
847 return EFI_UNSUPPORTED
;
851 CurrentLink
= gPciDevicePool
.ForwardLink
;
853 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
855 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
857 // Locate the right root bridge to start
859 if (RootBridge
->Handle
== Controller
) {
860 StartPciDevicesOnBridge (
869 CurrentLink
= CurrentLink
->ForwardLink
;
877 IN EFI_HANDLE RootBridgeHandle
885 RootBridgeHandle - An efi handle.
896 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
897 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
900 Status
= gBS
->AllocatePool (
902 sizeof (PCI_IO_DEVICE
),
906 if (EFI_ERROR (Status
)) {
910 ZeroMem (Dev
, sizeof (PCI_IO_DEVICE
));
911 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
912 Dev
->Handle
= RootBridgeHandle
;
913 InitializeListHead (&Dev
->ChildList
);
915 Status
= gBS
->OpenProtocol (
917 &gEfiDevicePathProtocolGuid
,
918 (VOID
**) &ParentDevicePath
,
919 gPciBusDriverBinding
.DriverBindingHandle
,
921 EFI_OPEN_PROTOCOL_GET_PROTOCOL
924 if (EFI_ERROR (Status
)) {
930 // Record the root bridge parent device path
932 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
935 // Get the pci root bridge io protocol
937 Status
= gBS
->OpenProtocol (
939 &gEfiPciRootBridgeIoProtocolGuid
,
940 (VOID
**) &PciRootBridgeIo
,
941 gPciBusDriverBinding
.DriverBindingHandle
,
943 EFI_OPEN_PROTOCOL_GET_PROTOCOL
946 if (EFI_ERROR (Status
)) {
951 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
954 // Initialize the PCI I/O instance structure
956 Status
= InitializePciIoInstance (Dev
);
957 Status
= InitializePciDriverOverrideInstance (Dev
);
960 // Initialize reserved resource list and
961 // option rom driver list
963 InitializeListHead (&Dev
->ReservedResourceList
);
964 InitializeListHead (&Dev
->OptionRomDriverList
);
970 GetRootBridgeByHandle (
971 EFI_HANDLE RootBridgeHandle
980 RootBridgeHandle - An efi handle.
988 PCI_IO_DEVICE
*RootBridgeDev
;
989 LIST_ENTRY
*CurrentLink
;
991 CurrentLink
= gPciDevicePool
.ForwardLink
;
993 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
995 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
996 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
997 return RootBridgeDev
;
1000 CurrentLink
= CurrentLink
->ForwardLink
;
1008 IN EFI_HANDLE RootBridgeHandle
1012 Routine Description:
1014 This function searches if RootBridgeHandle has already existed
1015 in current device pool.
1017 If so, it means the given root bridge has been already enumerated.
1021 RootBridgeHandle - An efi handle.
1029 PCI_IO_DEVICE
*Bridge
;
1031 Bridge
= GetRootBridgeByHandle (RootBridgeHandle
);
1033 if (Bridge
!= NULL
) {
1042 IN PCI_IO_DEVICE
*Bridge
,
1043 IN PCI_IO_DEVICE
*PciIoDevice
1047 Routine Description:
1051 Bridge - A pointer to the PCI_IO_DEVICE.
1052 PciIoDevice - A pointer to the PCI_IO_DEVICE.
1061 PCI_IO_DEVICE
*Temp
;
1062 LIST_ENTRY
*CurrentLink
;
1064 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1066 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
1068 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1070 if (Temp
== PciIoDevice
) {
1074 if (!IsListEmpty (&Temp
->ChildList
)) {
1075 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
1080 CurrentLink
= CurrentLink
->ForwardLink
;
1087 ActiveVGADeviceOnTheSameSegment (
1088 IN PCI_IO_DEVICE
*VgaDevice
1092 Routine Description:
1096 VgaDevice - A pointer to the PCI_IO_DEVICE.
1104 LIST_ENTRY
*CurrentLink
;
1105 PCI_IO_DEVICE
*Temp
;
1107 CurrentLink
= gPciDevicePool
.ForwardLink
;
1109 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
1111 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1113 if (Temp
->PciRootBridgeIo
->SegmentNumber
== VgaDevice
->PciRootBridgeIo
->SegmentNumber
) {
1115 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1122 CurrentLink
= CurrentLink
->ForwardLink
;
1129 ActiveVGADeviceOnTheRootBridge (
1130 IN PCI_IO_DEVICE
*RootBridge
1134 Routine Description:
1138 RootBridge - A pointer to the PCI_IO_DEVICE.
1146 LIST_ENTRY
*CurrentLink
;
1147 PCI_IO_DEVICE
*Temp
;
1149 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1151 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
1153 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1155 if (IS_PCI_VGA(&Temp
->Pci
) &&
1157 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1158 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1159 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
))) {
1163 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
1165 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1172 CurrentLink
= CurrentLink
->ForwardLink
;
1180 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1181 IN EFI_DEVICE_PATH_PROTOCOL
*HpcDevicePath
,
1182 OUT UINT64
*PciAddress
1186 Routine Description:
1190 PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1191 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
1192 PciAddress - A pointer to the pci address.
1199 // TODO: EFI_NOT_FOUND - add return value to function comment
1200 // TODO: EFI_NOT_FOUND - add return value to function comment
1201 // TODO: EFI_SUCCESS - add return value to function comment
1202 // TODO: EFI_NOT_FOUND - add return value to function comment
1204 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1205 EFI_DEV_PATH_PTR Node
;
1206 LIST_ENTRY
*CurrentLink
;
1207 PCI_IO_DEVICE
*RootBridge
;
1210 CurrentDevicePath
= HpcDevicePath
;
1213 // Get the remaining device path for this PCI device, if it is a PCI device
1215 while (!EfiIsDevicePathEnd (CurrentDevicePath
)) {
1217 Node
.DevPath
= CurrentDevicePath
;
1220 // Check if it is PCI device Path?
1222 if ((Node
.DevPath
->Type
!= HARDWARE_DEVICE_PATH
) ||
1223 ((Node
.DevPath
->SubType
!= HW_PCI_DP
) &&
1224 (DevicePathNodeLength (Node
.DevPath
) != sizeof (PCI_DEVICE_PATH
)))) {
1225 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1233 // Check if it is not PCI device path
1235 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
1236 return EFI_NOT_FOUND
;
1239 CurrentLink
= gPciDevicePool
.ForwardLink
;
1241 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
1243 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1245 // Locate the right root bridge to start
1247 if (RootBridge
->PciRootBridgeIo
== PciRootBridgeIo
) {
1248 Status
= GetHpcPciAddressFromRootBridge (
1253 if (EFI_ERROR (Status
)) {
1254 return EFI_NOT_FOUND
;
1261 CurrentLink
= CurrentLink
->ForwardLink
;
1264 return EFI_NOT_FOUND
;
1268 GetHpcPciAddressFromRootBridge (
1269 IN PCI_IO_DEVICE
*RootBridge
,
1270 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
1271 OUT UINT64
*PciAddress
1275 Routine Description:
1279 PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1280 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
1281 PciAddress - A pointer to the pci address.
1288 // TODO: RootBridge - add argument and description to function comment
1289 // TODO: RemainingDevicePath - add argument and description to function comment
1290 // TODO: EFI_SUCCESS - add return value to function comment
1291 // TODO: EFI_NOT_FOUND - add return value to function comment
1292 // TODO: EFI_SUCCESS - add return value to function comment
1294 EFI_DEV_PATH_PTR Node
;
1295 PCI_IO_DEVICE
*Temp
;
1296 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1297 LIST_ENTRY
*CurrentLink
;
1302 CurrentDevicePath
= RemainingDevicePath
;
1303 Node
.DevPath
= CurrentDevicePath
;
1306 while (!EfiIsDevicePathEnd (CurrentDevicePath
)) {
1308 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1309 Node
.DevPath
= CurrentDevicePath
;
1311 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
1312 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1314 if (Node
.Pci
->Device
== Temp
->DeviceNumber
&&
1315 Node
.Pci
->Function
== Temp
->FunctionNumber
) {
1320 CurrentLink
= CurrentLink
->ForwardLink
;
1324 // Check if we find the bridge
1326 if (CurrentLink
== &RootBridge
->ChildList
) {
1333 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1338 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1340 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
1341 *PciAddress
= EFI_PCI_ADDRESS (RootBridge
->BusNumber
, Node
.Pci
->Device
, Node
.Pci
->Function
, 0);
1345 return EFI_NOT_FOUND
;
1348 *PciAddress
= EFI_PCI_ADDRESS (Temp
->BusNumber
, Temp
->DeviceNumber
, Temp
->FunctionNumber
, 0);