/* Enable a PCI driver to access PCI config space. */
STATIC EFI_STATUS EFIAPI PciIoPciRead(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT32 Offset, IN UINTN Count, IN OUT VOID *Buffer)
/* Enable a PCI driver to access PCI config space. */
STATIC EFI_STATUS EFIAPI PciIoPciRead(IN EFI_PCI_IO_PROTOCOL *This, IN EFI_PCI_IO_PROTOCOL_WIDTH Width, IN UINT32 Offset, IN UINTN Count, IN OUT VOID *Buffer)
{
  NON_DISCOVERABLE_PCI_DEVICE  *Dev;
  VOID                         *Address;
  UINTN                        Length;
  if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) {
    return EFI_INVALID_PARAMETER;
  }
  Dev     = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (This);
  Address = (UINT8 *)&Dev->ConfigSpace + Offset;
  Length  = Count << ((UINTN)Width & 0x3);
  if (Offset >= sizeof (Dev->ConfigSpace)) {
    ZeroMem (Buffer, Length);
    return EFI_SUCCESS;
  }
  if (Offset + Length > sizeof (Dev->ConfigSpace)) {
    Length -= sizeof (Dev->ConfigSpace) - Offset;
    ZeroMem ((UINT8 *)Buffer + sizeof (Dev->ConfigSpace) - Offset, Length);
    Count -= Length >> ((UINTN)Width & 0x3);
  }
  return PciIoMemRW (Width, Count, 1, Buffer, 1, Address);
}