https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Hao Wu <hao.a.wu@intel.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
		
			
				
	
	
		
			189 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @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;
 | 
						|
}
 | 
						|
 |