/** @file Device driver for the Atmel ATSHA204A random number generator. Copyright (c) 2018, Linaro Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include "AtSha204aDriver.h" /** Tests to see if this driver supports a given controller. @param This[in] A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. @param ControllerHandle[in] The handle of the controller to test. @param RemainingDevicePath[in] The remaining device path. (Ignored - this is not a bus driver.) @retval EFI_SUCCESS The driver supports this controller. @retval EFI_ALREADY_STARTED The device specified by ControllerHandle is already being managed by the driver specified by This. @retval EFI_UNSUPPORTED The device specified by ControllerHandle is not supported by the driver specified by This. **/ EFI_STATUS EFIAPI I2cHwrngDriverBindingSupported ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_I2C_IO_PROTOCOL *I2cIo; EFI_STATUS Status; // // Connect to the I2C stack // Status = gBS->OpenProtocol (ControllerHandle, &gEfiI2cIoProtocolGuid, (VOID **) &I2cIo, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); if (EFI_ERROR (Status)) { return Status; } if (CompareGuid (I2cIo->DeviceGuid, &gAtSha204aI2cDeviceGuid)) { DEBUG ((DEBUG_INIT | DEBUG_INFO, "Detected AtSha204a RNG device\n")); Status = EFI_SUCCESS; } else { Status = EFI_UNSUPPORTED; } // // Clean up. // gBS->CloseProtocol (ControllerHandle, &gEfiI2cIoProtocolGuid, This->DriverBindingHandle, ControllerHandle); return Status; } /** Starts a device controller or a bus controller. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. @param[in] ControllerHandle The handle of the device to start. This handle must support a protocol interface that supplies an I/O abstraction to the driver. @param[in] RemainingDevicePath The remaining portion of the device path. (Ignored - this is not a bus driver.) @retval EFI_SUCCESS The device was started. @retval EFI_DEVICE_ERROR The device could not be started due to a device error. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. **/ EFI_STATUS EFIAPI I2cHwrngDriverBindingStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL ) { return AtSha204aInit (This->DriverBindingHandle, ControllerHandle); } /** Stops a device controller or a bus controller. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. @param[in] ControllerHandle A handle to the device being stopped. The handle must support a bus specific I/O protocol for the driver to use to stop the device. @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL if NumberOfChildren is 0. @retval EFI_SUCCESS The device was stopped. @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. **/ EFI_STATUS EFIAPI I2cHwrngDriverBindingStop ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ) { return AtSha204aRelease (This->DriverBindingHandle, ControllerHandle); } STATIC EFI_DRIVER_BINDING_PROTOCOL gI2cHwrngDriverBinding = { I2cHwrngDriverBindingSupported, I2cHwrngDriverBindingStart, I2cHwrngDriverBindingStop, 0xa, NULL, NULL }; /** The entry point of AtSha204a UEFI Driver. @param ImageHandle The image handle of the UEFI Driver. @param SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The Driver or UEFI Driver exited normally. @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than SystemTable->Hdr.Revision. **/ EFI_STATUS EFIAPI EntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; // // Add the driver to the list of drivers // Status = EfiLibInstallDriverBindingComponentName2 ( ImageHandle, SystemTable, &gI2cHwrngDriverBinding, ImageHandle, NULL, &gAtSha204aDriverComponentName2); ASSERT_EFI_ERROR (Status); DEBUG ((DEBUG_INIT | DEBUG_INFO, "*** Installed AtSha204a driver! ***\n")); return EFI_SUCCESS; } /** Unload function for the AtSha204a Driver. @param ImageHandle[in] The allocated handle for the EFI image @retval EFI_SUCCESS The driver was unloaded successfully @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. **/ EFI_STATUS EFIAPI UnloadImage ( IN EFI_HANDLE ImageHandle ) { EFI_STATUS Status; EFI_HANDLE *HandleBuffer; UINTN HandleCount; UINTN Index; // // Retrieve all I2C I/O handles in the handle database // Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiI2cIoProtocolGuid, NULL, &HandleCount, &HandleBuffer); if (EFI_ERROR (Status)) { return Status; } // // Disconnect the driver from the handles in the handle database // for (Index = 0; Index < HandleCount; Index++) { Status = gBS->DisconnectController (HandleBuffer[Index], gImageHandle, NULL); } // // Free the handle array // gBS->FreePool (HandleBuffer); // // Uninstall protocols installed by the driver in its entrypoint // Status = gBS->UninstallMultipleProtocolInterfaces (ImageHandle, &gEfiDriverBindingProtocolGuid, &gI2cHwrngDriverBinding, NULL ); return EFI_SUCCESS; }