/** @file
  Work with PCI capabilities in PCI config space.

  Provides functions to parse capabilities lists, and to locate, describe, read
  and write capabilities. PCI config space access is abstracted away.

  Copyright (C) 2018, Red Hat, Inc.

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <IndustryStandard/PciExpress21.h>

#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>

#include "BasePciCapLib.h"

/**
  Compare a standalone PCI_CAP_KEY against a PCI_CAP containing an embedded
  PCI_CAP_KEY.

  @param[in] PciCapKey  Pointer to the bare PCI_CAP_KEY.

  @param[in] PciCap     Pointer to the PCI_CAP with the embedded PCI_CAP_KEY.

  @retval <0  If PciCapKey compares less than PciCap->Key.

  @retval  0  If PciCapKey compares equal to PciCap->Key.

  @retval >0  If PciCapKey compares greater than PciCap->Key.
**/
STATIC
INTN
EFIAPI
ComparePciCapKey (
  IN CONST VOID  *PciCapKey,
  IN CONST VOID  *PciCap
  )
{
  CONST PCI_CAP_KEY  *Key1;
  CONST PCI_CAP_KEY  *Key2;

  Key1 = PciCapKey;
  Key2 = &((CONST PCI_CAP *)PciCap)->Key;

  if (Key1->Domain < Key2->Domain) {
    return -1;
  }

  if (Key1->Domain > Key2->Domain) {
    return 1;
  }

  if (Key1->CapId < Key2->CapId) {
    return -1;
  }

  if (Key1->CapId > Key2->CapId) {
    return 1;
  }

  if (Key1->Instance < Key2->Instance) {
    return -1;
  }

  if (Key1->Instance > Key2->Instance) {
    return 1;
  }

  return 0;
}

/**
  Compare two PCI_CAP objects based on PCI_CAP.Key.

  @param[in] PciCap1  Pointer to the first PCI_CAP.

  @param[in] PciCap2  Pointer to the second PCI_CAP.

  @retval <0  If PciCap1 compares less than PciCap2.

  @retval  0  If PciCap1 compares equal to PciCap2.

  @retval >0  If PciCap1 compares greater than PciCap2.
**/
STATIC
INTN
EFIAPI
ComparePciCap (
  IN CONST VOID  *PciCap1,
  IN CONST VOID  *PciCap2
  )
{
  CONST PCI_CAP_KEY  *PciCap1Key;

  PciCap1Key = &((CONST PCI_CAP *)PciCap1)->Key;
  return ComparePciCapKey (PciCap1Key, PciCap2);
}

/**
  Compare the standalone UINT16 config space offset of a capability header
  against a PCI_CAP containing an embedded Offset.

  @param[in] CapHdrOffset  Pointer to the bare UINT16 config space offset.

  @param[in] PciCap        Pointer to the PCI_CAP with the embedded Offset.

  @retval <0  If CapHdrOffset compares less than PciCap->Offset.

  @retval  0  If CapHdrOffset compares equal to PciCap->Offset.

  @retval >0  If CapHdrOffset compares greater than PciCap->Offset.
**/
STATIC
INTN
EFIAPI
ComparePciCapOffsetKey (
  IN CONST VOID  *CapHdrOffset,
  IN CONST VOID  *PciCap
  )
{
  UINT16  Offset1;
  UINT16  Offset2;

  Offset1 = *(CONST UINT16 *)CapHdrOffset;
  Offset2 = ((CONST PCI_CAP *)PciCap)->Offset;
  //
  // Note: both Offset1 and Offset2 are promoted to INT32 below, and the
  // subtraction takes place between INT32 values.
  //
  return Offset1 - Offset2;
}

/**
  Compare two PCI_CAP objects based on PCI_CAP.Offset.

  @param[in] PciCap1  Pointer to the first PCI_CAP.

  @param[in] PciCap2  Pointer to the second PCI_CAP.

  @retval <0  If PciCap1 compares less than PciCap2.

  @retval  0  If PciCap1 compares equal to PciCap2.

  @retval >0  If PciCap1 compares greater than PciCap2.
**/
STATIC
INTN
EFIAPI
ComparePciCapOffset (
  IN CONST VOID  *PciCap1,
  IN CONST VOID  *PciCap2
  )
{
  UINT16  Offset1;
  UINT16  Offset2;

  Offset1 = ((CONST PCI_CAP *)PciCap1)->Offset;
  Offset2 = ((CONST PCI_CAP *)PciCap2)->Offset;
  //
  // Note: both Offset1 and Offset2 are promoted to INT32 below, and the
  // subtraction takes place between INT32 values.
  //
  return Offset1 - Offset2;
}

/**
  Insert a new instance of the PCI capability given by (Domain, CapId) in
  CapList.

  @param[in,out] CapList        The PCI_CAP_LIST into which the new PCI_CAP
                                should be inserted. CapList will own the new
                                PCI_CAP structure.

  @param[in,out] CapHdrOffsets  Link the new PCI_CAP structure into the
                                (non-owning) CapHdrOffsets collection as well.
                                CapHdrOffsets orders the PCI_CAP structures
                                based on the PCI_CAP.Offset member, and enables
                                the calculation of PCI_CAP.MaxSizeHint.

  @param[in] Domain             Whether the capability is normal or extended.

  @param[in] CapId              Capability ID (specific to Domain).

  @param[in] Offset             Config space offset at which the standard
                                header of the capability starts. The caller is
                                responsible for ensuring that Offset be DWORD
                                aligned. The caller is also responsible for
                                ensuring that Offset be within the config space
                                identified by Domain.

  @param[in] Version            The version number of the capability. The
                                caller is responsible for passing 0 as Version
                                if Domain is PciCapNormal.

  @retval RETURN_SUCCESS           Insertion successful.

  @retval RETURN_OUT_OF_RESOURCES  Memory allocation failed.

  @retval RETURN_DEVICE_ERROR      A PCI_CAP with Offset is already linked by
                                   CapHdrOffsets. This indicates a loop in the
                                   capabilities list being parsed.
**/
STATIC
RETURN_STATUS
InsertPciCap (
  IN OUT PCI_CAP_LIST        *CapList,
  IN OUT ORDERED_COLLECTION  *CapHdrOffsets,
  IN     PCI_CAP_DOMAIN      Domain,
  IN     UINT16              CapId,
  IN     UINT16              Offset,
  IN     UINT8               Version
  )
{
  PCI_CAP                   *PciCap;
  RETURN_STATUS             Status;
  ORDERED_COLLECTION_ENTRY  *PciCapEntry;
  PCI_CAP                   *InstanceZero;

  ASSERT ((Offset & 0x3) == 0);
  ASSERT (
    Offset < (Domain == PciCapNormal ?
              PCI_MAX_CONFIG_OFFSET : PCI_EXP_MAX_CONFIG_OFFSET)
    );
  ASSERT (Domain == PciCapExtended || Version == 0);

  //
  // Set InstanceZero to suppress incorrect compiler/analyzer warnings.
  //
  InstanceZero = NULL;

  //
  // Allocate PciCap, and populate it assuming it is the first occurrence of
  // (Domain, CapId). Note that PciCap->MaxSizeHint is not assigned the final
  // value just yet.
  //
  PciCap = AllocatePool (sizeof *PciCap);
  if (PciCap == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  PciCap->Key.Domain                     = Domain;
  PciCap->Key.CapId                      = CapId;
  PciCap->Key.Instance                   = 0;
  PciCap->NumInstancesUnion.NumInstances = 1;
  PciCap->Offset                         = Offset;
  PciCap->MaxSizeHint                    = 0;
  PciCap->Version                        = Version;

  //
  // Add PciCap to CapList.
  //
  Status = OrderedCollectionInsert (
             CapList->Capabilities,
             &PciCapEntry,
             PciCap
             );
  if (RETURN_ERROR (Status)) {
    if (Status == RETURN_OUT_OF_RESOURCES) {
      goto FreePciCap;
    }

    ASSERT (Status == RETURN_ALREADY_STARTED);
    //
    // PciCap is not the first instance of (Domain, CapId). Add it as a new
    // instance, taking the current instance count from Instance#0. Note that
    // we don't bump the instance count maintained in Instance#0 just yet, to
    // keep rollback on errors simple.
    //
    InstanceZero                           = OrderedCollectionUserStruct (PciCapEntry);
    PciCap->Key.Instance                   = InstanceZero->NumInstancesUnion.NumInstances;
    PciCap->NumInstancesUnion.InstanceZero = InstanceZero;

    ASSERT (PciCap->Key.Instance > 0);
    Status = OrderedCollectionInsert (
               CapList->Capabilities,
               &PciCapEntry,
               PciCap
               );
    if (Status == RETURN_OUT_OF_RESOURCES) {
      goto FreePciCap;
    }
  }

  //
  // At this point, PciCap has been inserted in CapList->Capabilities, either
  // with Instance==0 or with Instance>0. PciCapEntry is the iterator that
  // links PciCap.
  //
  ASSERT_RETURN_ERROR (Status);

  //
  // Link PciCap into CapHdrOffsets too, to order it globally based on config
  // space offset. Note that partial overlaps between capability headers is not
  // possible: Offset is DWORD aligned, normal capability headers are 16-bit
  // wide, and extended capability headers are 32-bit wide. Therefore any two
  // capability headers either are distinct or start at the same offset
  // (implying a loop in the respective capabilities list).
  //
  Status = OrderedCollectionInsert (CapHdrOffsets, NULL, PciCap);
  if (RETURN_ERROR (Status)) {
    if (Status == RETURN_ALREADY_STARTED) {
      //
      // Loop found; map return status accordingly.
      //
      Status = RETURN_DEVICE_ERROR;
    }

    goto DeletePciCapFromCapList;
  }

  //
  // Now we can bump the instance count maintained in Instance#0, if PciCap is
  // not the first instance of (Domain, CapId).
  //
  if (PciCap->Key.Instance > 0) {
    //
    // Suppress invalid "nullptr dereference" compiler/analyzer warnings: the
    // only way for "PciCap->Key.Instance" to be positive here is for it to
    // have been assigned *from* dereferencing "InstanceZero" above.
    //
    ASSERT (InstanceZero != NULL);

    InstanceZero->NumInstancesUnion.NumInstances++;
  }

  return RETURN_SUCCESS;

DeletePciCapFromCapList:
  OrderedCollectionDelete (CapList->Capabilities, PciCapEntry, NULL);

FreePciCap:
  FreePool (PciCap);

  return Status;
}

/**
  Calculate the MaxSizeHint member for a PCI_CAP object.

  CalculatePciCapMaxSizeHint() may only be called once all capability instances
  have been successfully processed by InsertPciCap().

  @param[in,out] PciCap  The PCI_CAP object for which to calculate the
                         MaxSizeHint member. The caller is responsible for
                         passing a PCI_CAP object that has been created by a
                         successful invocation of InsertPciCap().

  @param[in] NextPciCap  If NextPciCap is NULL, then the caller is responsible
                         for PciCap to represent the capability instance with
                         the highest header offset in all config space. If
                         NextPciCap is not NULL, then the caller is responsible
                         for (a) having created NextPciCap with a successful
                         invocation of InsertPciCap(), and (b) NextPciCap being
                         the direct successor of PciCap in config space offset
                         order, as ordered by ComparePciCapOffset().
**/
STATIC
VOID
CalculatePciCapMaxSizeHint (
  IN OUT PCI_CAP  *PciCap,
  IN     PCI_CAP  *NextPciCap OPTIONAL
  )
{
  UINT16  ConfigSpaceSize;

  ConfigSpaceSize = (PciCap->Key.Domain == PciCapNormal ?
                     PCI_MAX_CONFIG_OFFSET : PCI_EXP_MAX_CONFIG_OFFSET);
  //
  // The following is guaranteed by the interface contract on
  // CalculatePciCapMaxSizeHint().
  //
  ASSERT (NextPciCap == NULL || PciCap->Offset < NextPciCap->Offset);
  //
  // The following is guaranteed by the interface contract on InsertPciCap().
  //
  ASSERT (PciCap->Offset < ConfigSpaceSize);
  //
  // Thus we can safely subtract PciCap->Offset from either of
  // - ConfigSpaceSize
  // - and NextPciCap->Offset (if NextPciCap is not NULL).
  //
  // PciCap extends from PciCap->Offset to NextPciCap->Offset (if any), except
  // it cannot cross config space boundary.
  //
  if ((NextPciCap == NULL) || (NextPciCap->Offset >= ConfigSpaceSize)) {
    PciCap->MaxSizeHint = ConfigSpaceSize - PciCap->Offset;
    return;
  }

  PciCap->MaxSizeHint = NextPciCap->Offset - PciCap->Offset;
}

/**
  Debug dump a PCI_CAP_LIST object at the DEBUG_VERBOSE level.

  @param[in] CapList  The PCI_CAP_LIST object to dump.
**/
STATIC
VOID
EFIAPI
DebugDumpPciCapList (
  IN PCI_CAP_LIST  *CapList
  )
{
  DEBUG_CODE_BEGIN ();
  ORDERED_COLLECTION_ENTRY  *PciCapEntry;

  for (PciCapEntry = OrderedCollectionMin (CapList->Capabilities);
       PciCapEntry != NULL;
       PciCapEntry = OrderedCollectionNext (PciCapEntry))
  {
    PCI_CAP        *PciCap;
    RETURN_STATUS  Status;
    PCI_CAP_INFO   Info;

    PciCap = OrderedCollectionUserStruct (PciCapEntry);
    Status = PciCapGetInfo (PciCap, &Info);
    //
    // PciCapGetInfo() cannot fail in this library instance.
    //
    ASSERT_RETURN_ERROR (Status);

    DEBUG ((
      DEBUG_VERBOSE,
      "%a:%a: %a 0x%04x %03u/%03u v0x%x @0x%03x+0x%03x\n",
      gEfiCallerBaseName,
      __func__,
      (Info.Domain == PciCapNormal ? "Norm" : "Extd"),
      Info.CapId,
      Info.Instance,
      Info.NumInstances,
      Info.Version,
      Info.Offset,
      Info.MaxSizeHint
      ));
  }

  DEBUG_CODE_END ();
}

/**
  Empty a collection of PCI_CAP structures, optionally releasing the referenced
  PCI_CAP structures themselves. Release the collection at last.

  @param[in,out] PciCapCollection  The collection to empty and release.

  @param[in] FreePciCap            TRUE if the PCI_CAP structures linked by
                                   PciCapCollection should be released. When
                                   FALSE, the caller is responsible for
                                   retaining at least one reference to each
                                   PCI_CAP structure originally linked by
                                   PciCapCollection.
**/
STATIC
VOID
EmptyAndUninitPciCapCollection (
  IN OUT ORDERED_COLLECTION  *PciCapCollection,
  IN     BOOLEAN             FreePciCap
  )
{
  ORDERED_COLLECTION_ENTRY  *PciCapEntry;
  ORDERED_COLLECTION_ENTRY  *NextEntry;

  for (PciCapEntry = OrderedCollectionMin (PciCapCollection);
       PciCapEntry != NULL;
       PciCapEntry = NextEntry)
  {
    PCI_CAP  *PciCap;

    NextEntry = OrderedCollectionNext (PciCapEntry);
    OrderedCollectionDelete (PciCapCollection, PciCapEntry, (VOID **)&PciCap);
    if (FreePciCap) {
      FreePool (PciCap);
    }
  }

  OrderedCollectionUninit (PciCapCollection);
}

/**
  Parse the capabilities lists (both normal and extended, as applicable) of a
  PCI device.

  If the PCI device has no capabilities, that per se will not fail
  PciCapListInit(); an empty capabilities list will be represented.

  If the PCI device is found to be PCI Express, then an attempt will be made to
  parse the extended capabilities list as well. If the first extended config
  space access -- via PciDevice->ReadConfig() with SourceOffset=0x100 and
  Size=4 -- fails, that per se will not fail PciCapListInit(); the device will
  be assumed to have no extended capabilities.

  @param[in] PciDevice  Implementation-specific unique representation of the
                        PCI device in the PCI hierarchy.

  @param[out] CapList   Opaque data structure that holds an in-memory
                        representation of the parsed capabilities lists of
                        PciDevice.

  @retval RETURN_SUCCESS           The capabilities lists have been parsed from
                                   config space.

  @retval RETURN_OUT_OF_RESOURCES  Memory allocation failed.

  @retval RETURN_DEVICE_ERROR      A loop or some other kind of invalid pointer
                                   was detected in the capabilities lists of
                                   PciDevice.

  @return                          Error codes propagated from
                                   PciDevice->ReadConfig().
**/
RETURN_STATUS
EFIAPI
PciCapListInit (
  IN  PCI_CAP_DEV   *PciDevice,
  OUT PCI_CAP_LIST  **CapList
  )
{
  PCI_CAP_LIST              *OutCapList;
  RETURN_STATUS             Status;
  ORDERED_COLLECTION        *CapHdrOffsets;
  UINT16                    PciStatusReg;
  BOOLEAN                   DeviceIsExpress;
  ORDERED_COLLECTION_ENTRY  *OffsetEntry;

  //
  // Allocate the output structure.
  //
  OutCapList = AllocatePool (sizeof *OutCapList);
  if (OutCapList == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // The OutCapList->Capabilities collection owns the PCI_CAP structures and
  // orders them based on PCI_CAP.Key.
  //
  OutCapList->Capabilities = OrderedCollectionInit (
                               ComparePciCap,
                               ComparePciCapKey
                               );
  if (OutCapList->Capabilities == NULL) {
    Status = RETURN_OUT_OF_RESOURCES;
    goto FreeOutCapList;
  }

  //
  // The (temporary) CapHdrOffsets collection only references PCI_CAP
  // structures, and orders them based on PCI_CAP.Offset.
  //
  CapHdrOffsets = OrderedCollectionInit (
                    ComparePciCapOffset,
                    ComparePciCapOffsetKey
                    );
  if (CapHdrOffsets == NULL) {
    Status = RETURN_OUT_OF_RESOURCES;
    goto FreeCapabilities;
  }

  //
  // Whether the device is PCI Express depends on the normal capability with
  // identifier EFI_PCI_CAPABILITY_ID_PCIEXP.
  //
  DeviceIsExpress = FALSE;

  //
  // Check whether a normal capabilities list is present. If there's none,
  // that's not an error; we'll just return OutCapList->Capabilities empty.
  //
  Status = PciDevice->ReadConfig (
                        PciDevice,
                        PCI_PRIMARY_STATUS_OFFSET,
                        &PciStatusReg,
                        sizeof PciStatusReg
                        );
  if (RETURN_ERROR (Status)) {
    goto FreeCapHdrOffsets;
  }

  if ((PciStatusReg & EFI_PCI_STATUS_CAPABILITY) != 0) {
    UINT8  NormalCapHdrOffset;

    //
    // Fetch the start offset of the normal capabilities list.
    //
    Status = PciDevice->ReadConfig (
                          PciDevice,
                          PCI_CAPBILITY_POINTER_OFFSET,
                          &NormalCapHdrOffset,
                          sizeof NormalCapHdrOffset
                          );
    if (RETURN_ERROR (Status)) {
      goto FreeCapHdrOffsets;
    }

    //
    // Traverse the normal capabilities list.
    //
    NormalCapHdrOffset &= 0xFC;
    while (NormalCapHdrOffset > 0) {
      EFI_PCI_CAPABILITY_HDR  NormalCapHdr;

      Status = PciDevice->ReadConfig (
                            PciDevice,
                            NormalCapHdrOffset,
                            &NormalCapHdr,
                            sizeof NormalCapHdr
                            );
      if (RETURN_ERROR (Status)) {
        goto FreeCapHdrOffsets;
      }

      Status = InsertPciCap (
                 OutCapList,
                 CapHdrOffsets,
                 PciCapNormal,
                 NormalCapHdr.CapabilityID,
                 NormalCapHdrOffset,
                 0
                 );
      if (RETURN_ERROR (Status)) {
        goto FreeCapHdrOffsets;
      }

      if (NormalCapHdr.CapabilityID == EFI_PCI_CAPABILITY_ID_PCIEXP) {
        DeviceIsExpress = TRUE;
      }

      NormalCapHdrOffset = NormalCapHdr.NextItemPtr & 0xFC;
    }
  }

  //
  // If the device has been found PCI Express, attempt to traverse the extended
  // capabilities list. It starts right after the normal config space.
  //
  if (DeviceIsExpress) {
    UINT16  ExtendedCapHdrOffset;

    ExtendedCapHdrOffset = PCI_MAX_CONFIG_OFFSET;
    while (ExtendedCapHdrOffset > 0) {
      PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER  ExtendedCapHdr;

      Status = PciDevice->ReadConfig (
                            PciDevice,
                            ExtendedCapHdrOffset,
                            &ExtendedCapHdr,
                            sizeof ExtendedCapHdr
                            );
      //
      // If the first extended config space access fails, assume the device has
      // no extended capabilities. If the first extended config space access
      // succeeds but we read an "all bits zero" extended capability header,
      // that means (by spec) the device has no extended capabilities.
      //
      if ((ExtendedCapHdrOffset == PCI_MAX_CONFIG_OFFSET) &&
          (RETURN_ERROR (Status) ||
           IsZeroBuffer (&ExtendedCapHdr, sizeof ExtendedCapHdr)))
      {
        break;
      }

      if (RETURN_ERROR (Status)) {
        goto FreeCapHdrOffsets;
      }

      Status = InsertPciCap (
                 OutCapList,
                 CapHdrOffsets,
                 PciCapExtended,
                 (UINT16)ExtendedCapHdr.CapabilityId,
                 ExtendedCapHdrOffset,
                 (UINT8)ExtendedCapHdr.CapabilityVersion
                 );
      if (RETURN_ERROR (Status)) {
        goto FreeCapHdrOffsets;
      }

      ExtendedCapHdrOffset = ExtendedCapHdr.NextCapabilityOffset & 0xFFC;
      if ((ExtendedCapHdrOffset > 0) &&
          (ExtendedCapHdrOffset < PCI_MAX_CONFIG_OFFSET))
      {
        //
        // Invalid capability pointer.
        //
        Status = RETURN_DEVICE_ERROR;
        goto FreeCapHdrOffsets;
      }
    }
  }

  //
  // Both capabilities lists have been parsed; compute the PCI_CAP.MaxSizeHint
  // members if at least one capability has been found. In parallel, evacuate
  // the CapHdrOffsets collection.
  //
  // At first, set OffsetEntry to the iterator of the PCI_CAP object with the
  // lowest Offset (if such exists).
  //
  OffsetEntry = OrderedCollectionMin (CapHdrOffsets);
  if (OffsetEntry != NULL) {
    ORDERED_COLLECTION_ENTRY  *NextOffsetEntry;
    PCI_CAP                   *PciCap;

    //
    // Initialize NextOffsetEntry to the iterator of the PCI_CAP object with
    // the second lowest Offset (if such exists).
    //
    NextOffsetEntry = OrderedCollectionNext (OffsetEntry);
    //
    // Calculate MaxSizeHint for all PCI_CAP objects except the one with the
    // highest Offset.
    //
    while (NextOffsetEntry != NULL) {
      PCI_CAP  *NextPciCap;

      OrderedCollectionDelete (CapHdrOffsets, OffsetEntry, (VOID **)&PciCap);
      NextPciCap = OrderedCollectionUserStruct (NextOffsetEntry);
      CalculatePciCapMaxSizeHint (PciCap, NextPciCap);

      OffsetEntry     = NextOffsetEntry;
      NextOffsetEntry = OrderedCollectionNext (OffsetEntry);
    }

    //
    // Calculate MaxSizeHint for the PCI_CAP object with the highest Offset.
    //
    OrderedCollectionDelete (CapHdrOffsets, OffsetEntry, (VOID **)&PciCap);
    CalculatePciCapMaxSizeHint (PciCap, NULL);
  }

  ASSERT (OrderedCollectionIsEmpty (CapHdrOffsets));
  OrderedCollectionUninit (CapHdrOffsets);

  DebugDumpPciCapList (OutCapList);
  *CapList = OutCapList;
  return RETURN_SUCCESS;

FreeCapHdrOffsets:
  EmptyAndUninitPciCapCollection (CapHdrOffsets, FALSE);

FreeCapabilities:
  EmptyAndUninitPciCapCollection (OutCapList->Capabilities, TRUE);

FreeOutCapList:
  FreePool (OutCapList);

  ASSERT (RETURN_ERROR (Status));
  DEBUG ((
    DEBUG_ERROR,
    "%a:%a: %r\n",
    gEfiCallerBaseName,
    __func__,
    Status
    ));
  return Status;
}

/**
  Free the resources used by CapList.

  @param[in] CapList  The PCI_CAP_LIST object to free, originally produced by
                      PciCapListInit().
**/
VOID
EFIAPI
PciCapListUninit (
  IN PCI_CAP_LIST  *CapList
  )
{
  EmptyAndUninitPciCapCollection (CapList->Capabilities, TRUE);
  FreePool (CapList);
}

/**
  Locate a capability instance in the parsed capabilities lists.

  @param[in] CapList   The PCI_CAP_LIST object produced by PciCapListInit().

  @param[in] Domain    Distinguishes whether CapId is 8-bit wide and
                       interpreted in normal config space, or 16-bit wide and
                       interpreted in extended config space. Capability ID
                       definitions are relative to domain.

  @param[in] CapId     Capability identifier to look up.

  @param[in] Instance  Domain and CapId may identify a multi-instance
                       capability. When Instance is zero, the first instance of
                       the capability is located (in list traversal order --
                       which may not mean increasing config space offset
                       order). Higher Instance values locate subsequent
                       instances of the same capability (in list traversal
                       order).

  @param[out] Cap      The capability instance that matches the search
                       criteria. Cap is owned by CapList and becomes invalid
                       when CapList is freed with PciCapListUninit().
                       PciCapListFindCap() may be called with Cap set to NULL,
                       in order to test the existence of a specific capability
                       instance.

  @retval RETURN_SUCCESS    The capability instance identified by (Domain,
                            CapId, Instance) has been found.

  @retval RETURN_NOT_FOUND  The requested (Domain, CapId, Instance) capability
                            instance does not exist.
**/
RETURN_STATUS
EFIAPI
PciCapListFindCap (
  IN  PCI_CAP_LIST    *CapList,
  IN  PCI_CAP_DOMAIN  Domain,
  IN  UINT16          CapId,
  IN  UINT16          Instance,
  OUT PCI_CAP         **Cap    OPTIONAL
  )
{
  PCI_CAP_KEY               Key;
  ORDERED_COLLECTION_ENTRY  *PciCapEntry;

  Key.Domain   = Domain;
  Key.CapId    = CapId;
  Key.Instance = Instance;

  PciCapEntry = OrderedCollectionFind (CapList->Capabilities, &Key);
  if (PciCapEntry == NULL) {
    return RETURN_NOT_FOUND;
  }

  if (Cap != NULL) {
    *Cap = OrderedCollectionUserStruct (PciCapEntry);
  }

  return RETURN_SUCCESS;
}

/**
  Locate the first instance of the capability given by (Domain, CapId) such
  that the instance's Version is greater than or equal to MinVersion.

  This is a convenience function that may save client code calls to
  PciCapListFindCap() and PciCapGetInfo().

  @param[in] CapList     The PCI_CAP_LIST object produced by PciCapListInit().

  @param[in] Domain      Distinguishes whether CapId is 8-bit wide and
                         interpreted in normal config space, or 16-bit wide and
                         interpreted in extended config space. Capability ID
                         definitions are relative to domain.

  @param[in] CapId       Capability identifier to look up.

  @param[in] MinVersion  The minimum version that the capability instance is
                         required to have. Note that all capability instances
                         in Domain=PciCapNormal have Version=0.

  @param[out] Cap        The first capability instance that matches the search
                         criteria. Cap is owned by CapList and becomes invalid
                         when CapList is freed with PciCapListUninit().
                         PciCapListFindCapVersion() may be called with Cap set
                         to NULL, in order just to test whether the search
                         criteria are satisfiable.

  @retval RETURN_SUCCESS    The first capability instance matching (Domain,
                            CapId, MinVersion) has been located.

  @retval RETURN_NOT_FOUND  No capability instance matches (Domain, CapId,
                            MinVersion).
**/
RETURN_STATUS
EFIAPI
PciCapListFindCapVersion (
  IN  PCI_CAP_LIST    *CapList,
  IN  PCI_CAP_DOMAIN  Domain,
  IN  UINT16          CapId,
  IN  UINT8           MinVersion,
  OUT PCI_CAP         **Cap      OPTIONAL
  )
{
  PCI_CAP_KEY               Key;
  ORDERED_COLLECTION_ENTRY  *PciCapEntry;

  //
  // Start the version checks at Instance#0 of (Domain, CapId).
  //
  Key.Domain   = Domain;
  Key.CapId    = CapId;
  Key.Instance = 0;

  for (PciCapEntry = OrderedCollectionFind (CapList->Capabilities, &Key);
       PciCapEntry != NULL;
       PciCapEntry = OrderedCollectionNext (PciCapEntry))
  {
    PCI_CAP  *PciCap;

    PciCap = OrderedCollectionUserStruct (PciCapEntry);
    //
    // PCI_CAP.Key ordering keeps instances of the same (Domain, CapId)
    // adjacent to each other, so stop searching if either Domain or CapId
    // changes.
    //
    if ((PciCap->Key.Domain != Domain) || (PciCap->Key.CapId != CapId)) {
      break;
    }

    if (PciCap->Version >= MinVersion) {
      //
      // Match found.
      //
      if (Cap != NULL) {
        *Cap = PciCap;
      }

      return RETURN_SUCCESS;
    }
  }

  return RETURN_NOT_FOUND;
}

/**
  Get information about a PCI Capability instance.

  @param[in] Cap    The capability instance to get info about, located with
                    PciCapListFindCap*().

  @param[out] Info  A PCI_CAP_INFO structure that describes the properties of
                    Cap.

  @retval RETURN_SUCCESS  Fields of Info have been set.

  @return                 Unspecified error codes, if filling in Info failed
                          for some reason.
**/
RETURN_STATUS
EFIAPI
PciCapGetInfo (
  IN  PCI_CAP       *Cap,
  OUT PCI_CAP_INFO  *Info
  )
{
  PCI_CAP  *InstanceZero;

  ASSERT (Info != NULL);

  InstanceZero = (Cap->Key.Instance == 0 ? Cap :
                  Cap->NumInstancesUnion.InstanceZero);

  Info->Domain       = Cap->Key.Domain;
  Info->CapId        = Cap->Key.CapId;
  Info->NumInstances = InstanceZero->NumInstancesUnion.NumInstances;
  Info->Instance     = Cap->Key.Instance;
  Info->Offset       = Cap->Offset;
  Info->MaxSizeHint  = Cap->MaxSizeHint;
  Info->Version      = Cap->Version;

  return RETURN_SUCCESS;
}

/**
  Read a slice of a capability instance.

  The function performs as few config space accesses as possible (without
  attempting 64-bit wide accesses). PciCapRead() performs bounds checking on
  SourceOffsetInCap and Size, and only invokes PciDevice->ReadConfig() if the
  requested transfer falls within Cap.

  @param[in] PciDevice           Implementation-specific unique representation
                                 of the PCI device in the PCI hierarchy.

  @param[in] Cap                 The capability instance to read, located with
                                 PciCapListFindCap*().

  @param[in] SourceOffsetInCap   Source offset relative to the capability
                                 header to start reading from. A zero value
                                 refers to the first byte of the capability
                                 header.

  @param[out] DestinationBuffer  Buffer to store the read data to.

  @param[in] Size                The number of bytes to transfer.

  @retval RETURN_SUCCESS          Size bytes have been transferred from Cap to
                                  DestinationBuffer.

  @retval RETURN_BAD_BUFFER_SIZE  Reading Size bytes starting from
                                  SourceOffsetInCap would not (entirely) be
                                  contained within Cap, as suggested by
                                  PCI_CAP_INFO.MaxSizeHint. No bytes have been
                                  read.

  @return                         Error codes propagated from
                                  PciDevice->ReadConfig(). Fewer than Size
                                  bytes may have been read.
**/
RETURN_STATUS
EFIAPI
PciCapRead (
  IN  PCI_CAP_DEV  *PciDevice,
  IN  PCI_CAP      *Cap,
  IN  UINT16       SourceOffsetInCap,
  OUT VOID         *DestinationBuffer,
  IN  UINT16       Size
  )
{
  //
  // Note: all UINT16 values are promoted to INT32 below, and addition and
  // comparison take place between INT32 values.
  //
  if (SourceOffsetInCap + Size > Cap->MaxSizeHint) {
    return RETURN_BAD_BUFFER_SIZE;
  }

  return PciDevice->ReadConfig (
                      PciDevice,
                      Cap->Offset + SourceOffsetInCap,
                      DestinationBuffer,
                      Size
                      );
}

/**
  Write a slice of a capability instance.

  The function performs as few config space accesses as possible (without
  attempting 64-bit wide accesses). PciCapWrite() performs bounds checking on
  DestinationOffsetInCap and Size, and only invokes PciDevice->WriteConfig() if
  the requested transfer falls within Cap.

  @param[in] PciDevice               Implementation-specific unique
                                     representation of the PCI device in the
                                     PCI hierarchy.

  @param[in] Cap                     The capability instance to write, located
                                     with PciCapListFindCap*().

  @param[in] DestinationOffsetInCap  Destination offset relative to the
                                     capability header to start writing at. A
                                     zero value refers to the first byte of the
                                     capability header.

  @param[in] SourceBuffer            Buffer to read the data to be stored from.

  @param[in] Size                    The number of bytes to transfer.

  @retval RETURN_SUCCESS          Size bytes have been transferred from
                                  SourceBuffer to Cap.

  @retval RETURN_BAD_BUFFER_SIZE  Writing Size bytes starting at
                                  DestinationOffsetInCap would not (entirely)
                                  be contained within Cap, as suggested by
                                  PCI_CAP_INFO.MaxSizeHint. No bytes have been
                                  written.

  @return                         Error codes propagated from
                                  PciDevice->WriteConfig(). Fewer than Size
                                  bytes may have been written.
**/
RETURN_STATUS
EFIAPI
PciCapWrite (
  IN PCI_CAP_DEV  *PciDevice,
  IN PCI_CAP      *Cap,
  IN UINT16       DestinationOffsetInCap,
  IN VOID         *SourceBuffer,
  IN UINT16       Size
  )
{
  //
  // Note: all UINT16 values are promoted to INT32 below, and addition and
  // comparison take place between INT32 values.
  //
  if (DestinationOffsetInCap + Size > Cap->MaxSizeHint) {
    return RETURN_BAD_BUFFER_SIZE;
  }

  return PciDevice->WriteConfig (
                      PciDevice,
                      Cap->Offset + DestinationOffsetInCap,
                      SourceBuffer,
                      Size
                      );
}
