/** @file
|
Device driver for the Atmel ATSHA204A random number generator.
|
|
Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
#include <Library/UefiDriverEntryPoint.h>
|
|
#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;
|
}
|