mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-31 03:03:46 +01:00 
			
		
		
		
	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>
		
			
				
	
	
		
			284 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			284 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| 
 | |
|   Copyright (C) 2016, Linaro Ltd. All rights reserved.<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "NonDiscoverablePciDeviceIo.h"
 | |
| 
 | |
| #include <Protocol/DriverBinding.h>
 | |
| 
 | |
| #define MAX_NON_DISCOVERABLE_PCI_DEVICE_ID   (32 * 256)
 | |
| 
 | |
| STATIC UINTN               mUniqueIdCounter = 0;
 | |
| EFI_CPU_ARCH_PROTOCOL      *mCpu;
 | |
| 
 | |
| //
 | |
| // We only support the following device types
 | |
| //
 | |
| STATIC
 | |
| CONST EFI_GUID * CONST
 | |
| SupportedNonDiscoverableDevices[] = {
 | |
|   &gEdkiiNonDiscoverableAhciDeviceGuid,
 | |
|   &gEdkiiNonDiscoverableEhciDeviceGuid,
 | |
|   &gEdkiiNonDiscoverableNvmeDeviceGuid,
 | |
|   &gEdkiiNonDiscoverableOhciDeviceGuid,
 | |
|   &gEdkiiNonDiscoverableSdhciDeviceGuid,
 | |
|   &gEdkiiNonDiscoverableUfsDeviceGuid,
 | |
|   &gEdkiiNonDiscoverableUhciDeviceGuid,
 | |
|   &gEdkiiNonDiscoverableXhciDeviceGuid,
 | |
| };
 | |
| 
 | |
| //
 | |
| // Probe, start and stop functions of this driver, called by the DXE core for
 | |
| // specific devices.
 | |
| //
 | |
| // The following specifications document these interfaces:
 | |
| // - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol
 | |
| // - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol
 | |
| //
 | |
| // The implementation follows:
 | |
| // - Driver Writer's Guide for UEFI 2.3.1 v1.01
 | |
| //   - 5.1.3.4 OpenProtocol() and CloseProtocol()
 | |
| // - UEFI Spec 2.3.1 + Errata C
 | |
| //   -  6.3 Protocol Handler Services
 | |
| //
 | |
| 
 | |
| /**
 | |
|   Supported function of Driver Binding protocol for this driver.
 | |
|   Test to see if this driver supports ControllerHandle.
 | |
| 
 | |
|   @param This                   Protocol instance pointer.
 | |
|   @param DeviceHandle           Handle of device to test.
 | |
|   @param RemainingDevicePath    A pointer to the device path.
 | |
|                                 it should be ignored by device driver.
 | |
| 
 | |
|   @retval EFI_SUCCESS           This driver supports this device.
 | |
|   @retval other                 This driver does not support this device.
 | |
| 
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| NonDiscoverablePciDeviceSupported (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL *This,
 | |
|   IN EFI_HANDLE                  DeviceHandle,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
 | |
|   )
 | |
| {
 | |
|   NON_DISCOVERABLE_DEVICE             *Device;
 | |
|   EFI_STATUS                          Status;
 | |
|   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR   *Desc;
 | |
|   INTN                                Idx;
 | |
| 
 | |
|   Status = gBS->OpenProtocol (DeviceHandle,
 | |
|                   &gEdkiiNonDiscoverableDeviceProtocolGuid, (VOID **)&Device,
 | |
|                   This->DriverBindingHandle, DeviceHandle,
 | |
|                   EFI_OPEN_PROTOCOL_BY_DRIVER);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = EFI_UNSUPPORTED;
 | |
|   for (Idx = 0; Idx < ARRAY_SIZE (SupportedNonDiscoverableDevices); Idx++) {
 | |
|     if (CompareGuid (Device->Type, SupportedNonDiscoverableDevices [Idx])) {
 | |
|       Status = EFI_SUCCESS;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto CloseProtocol;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // We only support MMIO devices, so iterate over the resources to ensure
 | |
|   // that they only describe things that we can handle
 | |
|   //
 | |
|   for (Desc = Device->Resources; Desc->Desc != ACPI_END_TAG_DESCRIPTOR;
 | |
|        Desc = (VOID *)((UINT8 *)Desc + Desc->Len + 3)) {
 | |
|     if (Desc->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR ||
 | |
|         Desc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) {
 | |
|       Status = EFI_UNSUPPORTED;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| CloseProtocol:
 | |
|   gBS->CloseProtocol (DeviceHandle, &gEdkiiNonDiscoverableDeviceProtocolGuid,
 | |
|          This->DriverBindingHandle, DeviceHandle);
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This routine is called right after the .Supported() called and
 | |
|   Start this driver on ControllerHandle.
 | |
| 
 | |
|   @param This                   Protocol instance pointer.
 | |
|   @param DeviceHandle           Handle of device to bind driver to.
 | |
|   @param RemainingDevicePath    A pointer to the device path.
 | |
|                                 it should be ignored by device driver.
 | |
| 
 | |
|   @retval EFI_SUCCESS           This driver is added to this device.
 | |
|   @retval other                 Some error occurs when binding this driver to this device.
 | |
| 
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| NonDiscoverablePciDeviceStart (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL *This,
 | |
|   IN EFI_HANDLE                  DeviceHandle,
 | |
|   IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
 | |
|   )
 | |
| {
 | |
|   NON_DISCOVERABLE_PCI_DEVICE   *Dev;
 | |
|   EFI_STATUS                    Status;
 | |
| 
 | |
|   ASSERT (mUniqueIdCounter < MAX_NON_DISCOVERABLE_PCI_DEVICE_ID);
 | |
|   if (mUniqueIdCounter >= MAX_NON_DISCOVERABLE_PCI_DEVICE_ID) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   Dev = AllocateZeroPool (sizeof *Dev);
 | |
|   if (Dev == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   Status = gBS->OpenProtocol (DeviceHandle,
 | |
|                   &gEdkiiNonDiscoverableDeviceProtocolGuid,
 | |
|                   (VOID **)&Dev->Device, This->DriverBindingHandle,
 | |
|                   DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto FreeDev;
 | |
|   }
 | |
| 
 | |
|   InitializePciIoProtocol (Dev);
 | |
| 
 | |
|   //
 | |
|   // Setup complete, attempt to export the driver instance's
 | |
|   // EFI_PCI_IO_PROTOCOL interface.
 | |
|   //
 | |
|   Dev->Signature = NON_DISCOVERABLE_PCI_DEVICE_SIG;
 | |
|   Status = gBS->InstallProtocolInterface (&DeviceHandle, &gEfiPciIoProtocolGuid,
 | |
|                   EFI_NATIVE_INTERFACE, &Dev->PciIo);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     goto CloseProtocol;
 | |
|   }
 | |
| 
 | |
|   Dev->UniqueId = mUniqueIdCounter++;
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| 
 | |
| CloseProtocol:
 | |
|   gBS->CloseProtocol (DeviceHandle, &gEdkiiNonDiscoverableDeviceProtocolGuid,
 | |
|          This->DriverBindingHandle, DeviceHandle);
 | |
| 
 | |
| FreeDev:
 | |
|   FreePool (Dev);
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Stop this driver on ControllerHandle.
 | |
| 
 | |
|   @param This               Protocol instance pointer.
 | |
|   @param DeviceHandle       Handle of device to stop driver on.
 | |
|   @param NumberOfChildren   Not used.
 | |
|   @param ChildHandleBuffer  Not used.
 | |
| 
 | |
|   @retval EFI_SUCCESS   This driver is removed from this device.
 | |
|   @retval other         Some error occurs when removing this driver from this device.
 | |
| 
 | |
| **/
 | |
| STATIC
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| NonDiscoverablePciDeviceStop (
 | |
|   IN EFI_DRIVER_BINDING_PROTOCOL *This,
 | |
|   IN EFI_HANDLE                  DeviceHandle,
 | |
|   IN UINTN                       NumberOfChildren,
 | |
|   IN EFI_HANDLE                  *ChildHandleBuffer
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                      Status;
 | |
|   EFI_PCI_IO_PROTOCOL             *PciIo;
 | |
|   NON_DISCOVERABLE_PCI_DEVICE     *Dev;
 | |
| 
 | |
|   Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
 | |
|                   (VOID **)&PciIo, This->DriverBindingHandle, DeviceHandle,
 | |
|                   EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Dev = NON_DISCOVERABLE_PCI_DEVICE_FROM_PCI_IO (PciIo);
 | |
| 
 | |
|   //
 | |
|   // Handle Stop() requests for in-use driver instances gracefully.
 | |
|   //
 | |
|   Status = gBS->UninstallProtocolInterface (DeviceHandle,
 | |
|                   &gEfiPciIoProtocolGuid, &Dev->PciIo);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   gBS->CloseProtocol (DeviceHandle, &gEdkiiNonDiscoverableDeviceProtocolGuid,
 | |
|          This->DriverBindingHandle, DeviceHandle);
 | |
| 
 | |
|   FreePool (Dev);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| //
 | |
| // The static object that groups the Supported() (ie. probe), Start() and
 | |
| // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
 | |
| // C, 10.1 EFI Driver Binding Protocol.
 | |
| //
 | |
| STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
 | |
|   &NonDiscoverablePciDeviceSupported,
 | |
|   &NonDiscoverablePciDeviceStart,
 | |
|   &NonDiscoverablePciDeviceStop,
 | |
|   0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
 | |
|   NULL,
 | |
|   NULL
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Entry point of this driver.
 | |
| 
 | |
|   @param  ImageHandle     Image handle this driver.
 | |
|   @param  SystemTable     Pointer to the System Table.
 | |
| 
 | |
|   @retval EFI_SUCCESS     The entry point is executed successfully.
 | |
|   @retval other           Some error occurred when executing this entry point.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| NonDiscoverablePciDeviceDxeEntryPoint (
 | |
|   IN EFI_HANDLE       ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS      Status;
 | |
| 
 | |
|   Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu);
 | |
|   ASSERT_EFI_ERROR(Status);
 | |
| 
 | |
|   return EfiLibInstallDriverBindingComponentName2 (
 | |
|            ImageHandle,
 | |
|            SystemTable,
 | |
|            &gDriverBinding,
 | |
|            ImageHandle,
 | |
|            &gComponentName,
 | |
|            &gComponentName2
 | |
|            );
 | |
| }
 |