/** @file
  Functions implementation for Bus Specific Driver Override protocol.

Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PciBus.h"

/**
  Initializes a PCI Driver Override Instance.

  @param  PciIoDevice   PCI Device instance.

**/
VOID
InitializePciDriverOverrideInstance (
  IN OUT PCI_IO_DEVICE  *PciIoDevice
  )
{
  PciIoDevice->PciDriverOverride.GetDriver = GetDriver;
}

/**
  Find the image handle whose path equals to ImagePath.

  @param ImagePath   Image path.

  @return Image handle.
**/
EFI_HANDLE
LocateImageHandle (
  IN EFI_DEVICE_PATH_PROTOCOL  *ImagePath
  )
{
  EFI_STATUS                Status;
  EFI_HANDLE                *Handles;
  UINTN                     Index;
  UINTN                     HandleNum;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  UINTN                     ImagePathSize;
  EFI_HANDLE                ImageHandle;

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiLoadedImageDevicePathProtocolGuid,
                  NULL,
                  &HandleNum,
                  &Handles
                  );
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  ImageHandle   = NULL;
  ImagePathSize = GetDevicePathSize (ImagePath);

  for (Index = 0; Index < HandleNum; Index++) {
    Status = gBS->HandleProtocol (Handles[Index], &gEfiLoadedImageDevicePathProtocolGuid, (VOID **)&DevicePath);
    if (EFI_ERROR (Status)) {
      continue;
    }

    if ((ImagePathSize == GetDevicePathSize (DevicePath)) &&
        (CompareMem (ImagePath, DevicePath, ImagePathSize) == 0)
        )
    {
      ImageHandle = Handles[Index];
      break;
    }
  }

  FreePool (Handles);
  return ImageHandle;
}

/**
  Uses a bus specific algorithm to retrieve a driver image handle for a controller.

  @param  This                  A pointer to the EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL instance.
  @param  DriverImageHandle     On input, a pointer to the previous driver image handle returned
                                by GetDriver(). On output, a pointer to the next driver
                                image handle. Passing in a NULL, will return the first driver
                                image handle.

  @retval EFI_SUCCESS           A bus specific override driver is returned in DriverImageHandle.
  @retval EFI_NOT_FOUND         The end of the list of override drivers was reached.
                                A bus specific override driver is not returned in DriverImageHandle.
  @retval EFI_INVALID_PARAMETER DriverImageHandle is not a handle that was returned on a
                                previous call to GetDriver().

**/
EFI_STATUS
EFIAPI
GetDriver (
  IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL  *This,
  IN OUT EFI_HANDLE                             *DriverImageHandle
  )
{
  PCI_IO_DEVICE             *PciIoDevice;
  LIST_ENTRY                *Link;
  PCI_DRIVER_OVERRIDE_LIST  *Override;
  BOOLEAN                   ReturnNext;

  Override    = NULL;
  PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);
  ReturnNext  = (BOOLEAN)(*DriverImageHandle == NULL);
  for ( Link = GetFirstNode (&PciIoDevice->OptionRomDriverList)
        ; !IsNull (&PciIoDevice->OptionRomDriverList, Link)
        ; Link = GetNextNode (&PciIoDevice->OptionRomDriverList, Link)
        )
  {
    Override = DRIVER_OVERRIDE_FROM_LINK (Link);

    if (ReturnNext) {
      if (Override->DriverImageHandle == NULL) {
        Override->DriverImageHandle = LocateImageHandle (Override->DriverImagePath);
      }

      if (Override->DriverImageHandle == NULL) {
        //
        // The Option ROM identified by Override->DriverImagePath is not loaded.
        //
        continue;
      } else {
        *DriverImageHandle = Override->DriverImageHandle;
        return EFI_SUCCESS;
      }
    }

    if (*DriverImageHandle == Override->DriverImageHandle) {
      ReturnNext = TRUE;
    }
  }

  ASSERT (IsNull (&PciIoDevice->OptionRomDriverList, Link));
  //
  // ReturnNext indicates a handle match happens.
  // If all nodes are checked without handle match happening,
  // the DriverImageHandle should be a invalid handle.
  //
  if (ReturnNext) {
    return EFI_NOT_FOUND;
  } else {
    return EFI_INVALID_PARAMETER;
  }
}

/**
  Add an overriding driver image.

  @param PciIoDevice        Instance of PciIo device.
  @param DriverImageHandle  Image handle of newly added driver image.
  @param DriverImagePath    Device path of newly added driver image.

  @retval EFI_SUCCESS          Successfully added driver.
  @retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.
  @retval other                Some error occurred when locating gEfiLoadedImageProtocolGuid.

**/
EFI_STATUS
AddDriver (
  IN PCI_IO_DEVICE             *PciIoDevice,
  IN EFI_HANDLE                DriverImageHandle,
  IN EFI_DEVICE_PATH_PROTOCOL  *DriverImagePath
  )
{
  PCI_DRIVER_OVERRIDE_LIST  *Node;

  //
  // Caller should pass in either Image Handle or Image Path, but not both.
  //
  ASSERT ((DriverImageHandle == NULL) || (DriverImagePath == NULL));

  Node = AllocateZeroPool (sizeof (PCI_DRIVER_OVERRIDE_LIST));
  if (Node == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Node->Signature         = DRIVER_OVERRIDE_SIGNATURE;
  Node->DriverImageHandle = DriverImageHandle;
  Node->DriverImagePath   = DuplicateDevicePath (DriverImagePath);

  InsertTailList (&PciIoDevice->OptionRomDriverList, &Node->Link);

  PciIoDevice->BusOverride = TRUE;
  return EFI_SUCCESS;
}
