mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-11 14:28:08 +01:00
569 lines
22 KiB
C
569 lines
22 KiB
C
|
/** @file
|
||
|
The UEFI driver model driver which is responsible for locating the
|
||
|
Redfish service through Redfish host interface and executing EDKII
|
||
|
Redfish feature drivers.
|
||
|
|
||
|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
||
|
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
||
|
|
||
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||
|
|
||
|
**/
|
||
|
|
||
|
#include "RedfishConfigHandlerDriver.h"
|
||
|
|
||
|
EFI_EVENT gEfiRedfishDiscoverProtocolEvent = NULL;
|
||
|
|
||
|
//
|
||
|
// Variables for using RFI Redfish Discover Protocol
|
||
|
//
|
||
|
VOID *gEfiRedfishDiscoverRegistration;
|
||
|
EFI_HANDLE gEfiRedfishDiscoverControllerHandle = NULL;
|
||
|
EFI_REDFISH_DISCOVER_PROTOCOL *gEfiRedfishDiscoverProtocol = NULL;
|
||
|
BOOLEAN gRedfishDiscoverActivated = FALSE;
|
||
|
BOOLEAN gRedfishServiceDiscovered = FALSE;
|
||
|
|
||
|
///
|
||
|
/// Driver Binding Protocol instance
|
||
|
///
|
||
|
EFI_DRIVER_BINDING_PROTOCOL gRedfishConfigDriverBinding = {
|
||
|
RedfishConfigDriverBindingSupported,
|
||
|
RedfishConfigDriverBindingStart,
|
||
|
RedfishConfigDriverBindingStop,
|
||
|
REDFISH_CONFIG_VERSION,
|
||
|
NULL,
|
||
|
NULL
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
Stop acquiring Redfish service.
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
RedfishConfigStopRedfishDiscovery (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
if (gRedfishDiscoverActivated) {
|
||
|
//
|
||
|
// No more EFI Discover Protocol.
|
||
|
//
|
||
|
if (gEfiRedfishDiscoverProtocolEvent != NULL) {
|
||
|
gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);
|
||
|
}
|
||
|
|
||
|
gEfiRedfishDiscoverControllerHandle = NULL;
|
||
|
gEfiRedfishDiscoverProtocol = NULL;
|
||
|
gRedfishDiscoverActivated = FALSE;
|
||
|
gRedfishServiceDiscovered = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Callback function executed when a Redfish Config Handler Protocol is installed.
|
||
|
|
||
|
@param[in] Event Event whose notification function is being invoked.
|
||
|
@param[in] Context Pointer to the REDFISH_CONFIG_DRIVER_DATA buffer.
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
EFIAPI
|
||
|
RedfishConfigHandlerInstalledCallback (
|
||
|
IN EFI_EVENT Event,
|
||
|
IN VOID *Context
|
||
|
)
|
||
|
{
|
||
|
if (!gRedfishDiscoverActivated) {
|
||
|
//
|
||
|
// No Redfish service is discovered yet.
|
||
|
//
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
RedfishConfigHandlerInitialization ();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Tests to see if this driver supports a given controller. If a child device is provided,
|
||
|
it further tests to see if this driver supports creating a handle for the specified child device.
|
||
|
|
||
|
This function checks to see if the driver specified by This supports the device specified by
|
||
|
ControllerHandle. Drivers will typically use the device path attached to
|
||
|
ControllerHandle and/or the services from the bus I/O abstraction attached to
|
||
|
ControllerHandle to determine if the driver supports ControllerHandle. This function
|
||
|
may be called many times during platform initialization. In order to reduce boot times, the tests
|
||
|
performed by this function must be very small, and take as little time as possible to execute. This
|
||
|
function must not change the state of any hardware devices, and this function must be aware that the
|
||
|
device specified by ControllerHandle may already be managed by the same driver or a
|
||
|
different driver. This function must match its calls to AllocatePages() with FreePages(),
|
||
|
AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
|
||
|
Because ControllerHandle may have been previously started by the same driver, if a protocol is
|
||
|
already in the opened state, then it must not be closed with CloseProtocol(). This is required
|
||
|
to guarantee the state of ControllerHandle is not modified by this function.
|
||
|
|
||
|
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||
|
@param[in] ControllerHandle The handle of the controller to test. This handle
|
||
|
must support a protocol interface that supplies
|
||
|
an I/O abstraction to the driver.
|
||
|
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||
|
parameter is ignored by device drivers, and is optional for bus
|
||
|
drivers. For bus drivers, if this parameter is not NULL, then
|
||
|
the bus driver must determine if the bus controller specified
|
||
|
by ControllerHandle and the child controller specified
|
||
|
by RemainingDevicePath are both supported by this
|
||
|
bus driver.
|
||
|
|
||
|
@retval EFI_SUCCESS The device specified by ControllerHandle and
|
||
|
RemainingDevicePath is supported by the driver specified by This.
|
||
|
@retval EFI_UNSUPPORTED The device specified by ControllerHandle and
|
||
|
RemainingDevicePath is not supported by the driver specified by This.
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
RedfishConfigDriverBindingSupported (
|
||
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||
|
IN EFI_HANDLE ControllerHandle,
|
||
|
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
EFI_REST_EX_PROTOCOL *RestEx;
|
||
|
EFI_STATUS Status;
|
||
|
EFI_HANDLE ChildHandle;
|
||
|
|
||
|
ChildHandle = NULL;
|
||
|
|
||
|
//
|
||
|
// Check if REST EX is ready. This just makes sure
|
||
|
// the network stack is brought up.
|
||
|
//
|
||
|
Status = NetLibCreateServiceChild (
|
||
|
ControllerHandle,
|
||
|
This->ImageHandle,
|
||
|
&gEfiRestExServiceBindingProtocolGuid,
|
||
|
&ChildHandle
|
||
|
);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
return EFI_UNSUPPORTED;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Test if REST EX protocol is ready.
|
||
|
//
|
||
|
Status = gBS->OpenProtocol (
|
||
|
ChildHandle,
|
||
|
&gEfiRestExProtocolGuid,
|
||
|
(VOID **)&RestEx,
|
||
|
This->DriverBindingHandle,
|
||
|
ControllerHandle,
|
||
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||
|
);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
Status = EFI_UNSUPPORTED;
|
||
|
}
|
||
|
|
||
|
NetLibDestroyServiceChild (
|
||
|
ControllerHandle,
|
||
|
This->ImageHandle,
|
||
|
&gEfiRestExServiceBindingProtocolGuid,
|
||
|
ChildHandle
|
||
|
);
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Starts a device controller or a bus controller.
|
||
|
|
||
|
The Start() function is designed to be invoked from the EFI boot service ConnectController().
|
||
|
As a result, much of the error checking on the parameters to Start() has been moved into this
|
||
|
common boot service. It is legal to call Start() from other locations,
|
||
|
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||
|
1. ControllerHandle must be a valid EFI_HANDLE.
|
||
|
2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
|
||
|
EFI_DEVICE_PATH_PROTOCOL.
|
||
|
3. Prior to calling Start(), the Supported() function for the driver specified by This must
|
||
|
have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
|
||
|
|
||
|
@param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
|
||
|
@param[in] ControllerHandle The handle of the controller to start. This handle
|
||
|
must support a protocol interface that supplies
|
||
|
an I/O abstraction to the driver.
|
||
|
@param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
|
||
|
parameter is ignored by device drivers, and is optional for bus
|
||
|
drivers. For a bus driver, if this parameter is NULL, then handles
|
||
|
for all the children of Controller are created by this driver.
|
||
|
If this parameter is not NULL and the first Device Path Node is
|
||
|
not the End of Device Path Node, then only the handle for the
|
||
|
child device specified by the first Device Path Node of
|
||
|
RemainingDevicePath is created by this driver.
|
||
|
If the first Device Path Node of RemainingDevicePath is
|
||
|
the End of Device Path Node, no child handle is created by this
|
||
|
driver.
|
||
|
|
||
|
@retval EFI_SUCCESS The driver is started.
|
||
|
@retval EFI_ALREADY_STARTED The driver was already started.
|
||
|
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
RedfishConfigDriverBindingStart (
|
||
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||
|
IN EFI_HANDLE ControllerHandle,
|
||
|
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
VOID *ConfigHandlerRegistration;
|
||
|
|
||
|
if (gRedfishConfigData.Event != NULL) {
|
||
|
return EFI_ALREADY_STARTED;
|
||
|
}
|
||
|
|
||
|
gRedfishConfigData.Event = EfiCreateProtocolNotifyEvent (
|
||
|
&gEdkIIRedfishConfigHandlerProtocolGuid,
|
||
|
TPL_CALLBACK,
|
||
|
RedfishConfigHandlerInstalledCallback,
|
||
|
(VOID *)&gRedfishConfigData,
|
||
|
&ConfigHandlerRegistration
|
||
|
);
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Stops a device controller or a bus controller.
|
||
|
|
||
|
The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
|
||
|
As a result, much of the error checking on the parameters to Stop() has been moved
|
||
|
into this common boot service. It is legal to call Stop() from other locations,
|
||
|
but the following calling restrictions must be followed, or the system behavior will not be deterministic.
|
||
|
1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
|
||
|
same driver's Start() function.
|
||
|
2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
|
||
|
EFI_HANDLE. In addition, all of these handles must have been created in this driver's
|
||
|
Start() function, and the Start() function must have called OpenProtocol() on
|
||
|
ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_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
|
||
|
RedfishConfigDriverBindingStop (
|
||
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
||
|
IN EFI_HANDLE ControllerHandle,
|
||
|
IN UINTN NumberOfChildren,
|
||
|
IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
|
||
|
if (ControllerHandle == gEfiRedfishDiscoverControllerHandle) {
|
||
|
RedfishConfigStopRedfishDiscovery ();
|
||
|
}
|
||
|
|
||
|
gBS->CloseProtocol (
|
||
|
ControllerHandle,
|
||
|
&gEfiRedfishDiscoverProtocolGuid,
|
||
|
gRedfishConfigData.Image,
|
||
|
gRedfishConfigData.Image
|
||
|
);
|
||
|
|
||
|
Status = RedfishConfigCommonStop ();
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
return EFI_DEVICE_ERROR;
|
||
|
}
|
||
|
|
||
|
if (gRedfishConfigData.Event != NULL) {
|
||
|
gBS->CloseEvent (gRedfishConfigData.Event);
|
||
|
gRedfishConfigData.Event = NULL;
|
||
|
}
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Callback function when Redfish service is discovered.
|
||
|
|
||
|
@param[in] Event Event whose notification function is being invoked.
|
||
|
@param[out] Context Pointer to the Context buffer
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
EFIAPI
|
||
|
RedfishServiceDiscoveredCallback (
|
||
|
IN EFI_EVENT Event,
|
||
|
OUT VOID *Context
|
||
|
)
|
||
|
{
|
||
|
EFI_REDFISH_DISCOVERED_TOKEN *RedfishDiscoveredToken;
|
||
|
EFI_REDFISH_DISCOVERED_INSTANCE *RedfishInstance;
|
||
|
|
||
|
RedfishDiscoveredToken = (EFI_REDFISH_DISCOVERED_TOKEN *)Context;
|
||
|
gBS->CloseEvent (RedfishDiscoveredToken->Event);
|
||
|
|
||
|
//
|
||
|
// Only support one Redfish service on platform.
|
||
|
//
|
||
|
if (!gRedfishServiceDiscovered) {
|
||
|
RedfishInstance = RedfishDiscoveredToken->DiscoverList.RedfishInstances;
|
||
|
//
|
||
|
// Only pick up the first found Redfish service.
|
||
|
//
|
||
|
if (RedfishInstance->Status == EFI_SUCCESS) {
|
||
|
gRedfishConfigData.RedfishServiceInfo.RedfishServiceRestExHandle = RedfishInstance->Information.RedfishRestExHandle;
|
||
|
gRedfishConfigData.RedfishServiceInfo.RedfishServiceVersion = RedfishInstance->Information.RedfishVersion;
|
||
|
gRedfishConfigData.RedfishServiceInfo.RedfishServiceLocation = RedfishInstance->Information.Location;
|
||
|
gRedfishConfigData.RedfishServiceInfo.RedfishServiceUuid = RedfishInstance->Information.Uuid;
|
||
|
gRedfishConfigData.RedfishServiceInfo.RedfishServiceOs = RedfishInstance->Information.Os;
|
||
|
gRedfishConfigData.RedfishServiceInfo.RedfishServiceOsVersion = RedfishInstance->Information.OsVersion;
|
||
|
gRedfishConfigData.RedfishServiceInfo.RedfishServiceProduct = RedfishInstance->Information.Product;
|
||
|
gRedfishConfigData.RedfishServiceInfo.RedfishServiceProductVer = RedfishInstance->Information.ProductVer;
|
||
|
gRedfishConfigData.RedfishServiceInfo.RedfishServiceUseHttps = RedfishInstance->Information.UseHttps;
|
||
|
gRedfishServiceDiscovered = TRUE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Invoke RedfishConfigHandlerInstalledCallback to execute
|
||
|
// the initialization of Redfish Configure Handler instance.
|
||
|
//
|
||
|
RedfishConfigHandlerInstalledCallback (gRedfishConfigData.Event, &gRedfishConfigData);
|
||
|
}
|
||
|
|
||
|
FreePool (RedfishDiscoveredToken);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Callback function executed when the EFI_REDFISH_DISCOVER_PROTOCOL
|
||
|
protocol interface is installed.
|
||
|
|
||
|
@param[in] Event Event whose notification function is being invoked.
|
||
|
@param[out] Context Pointer to the Context buffer
|
||
|
|
||
|
**/
|
||
|
VOID
|
||
|
EFIAPI
|
||
|
RedfishDiscoverProtocolInstalled (
|
||
|
IN EFI_EVENT Event,
|
||
|
OUT VOID *Context
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
UINTN BufferSize;
|
||
|
EFI_HANDLE HandleBuffer;
|
||
|
UINTN NetworkInterfaceIndex;
|
||
|
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface;
|
||
|
EFI_REDFISH_DISCOVERED_TOKEN *ThisRedfishDiscoveredToken;
|
||
|
UINTN NumberOfNetworkInterfaces;
|
||
|
|
||
|
DEBUG ((DEBUG_MANAGEABILITY, "%a: New network interface is installed on system by EFI Redfish discover driver.\n", __func__));
|
||
|
|
||
|
BufferSize = sizeof (EFI_HANDLE);
|
||
|
Status = gBS->LocateHandle (
|
||
|
ByRegisterNotify,
|
||
|
NULL,
|
||
|
gEfiRedfishDiscoverRegistration,
|
||
|
&BufferSize,
|
||
|
&HandleBuffer
|
||
|
);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
DEBUG ((DEBUG_ERROR, "%a: Can't locate handle with EFI_REDFISH_DISCOVER_PROTOCOL installed.\n", __func__));
|
||
|
}
|
||
|
|
||
|
gRedfishDiscoverActivated = TRUE;
|
||
|
if (gEfiRedfishDiscoverProtocol == NULL) {
|
||
|
gEfiRedfishDiscoverControllerHandle = HandleBuffer;
|
||
|
//
|
||
|
// First time to open EFI_REDFISH_DISCOVER_PROTOCOL.
|
||
|
//
|
||
|
Status = gBS->OpenProtocol (
|
||
|
gEfiRedfishDiscoverControllerHandle,
|
||
|
&gEfiRedfishDiscoverProtocolGuid,
|
||
|
(VOID **)&gEfiRedfishDiscoverProtocol,
|
||
|
gRedfishConfigData.Image,
|
||
|
gRedfishConfigData.Image,
|
||
|
EFI_OPEN_PROTOCOL_BY_DRIVER
|
||
|
);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
gEfiRedfishDiscoverProtocol = NULL;
|
||
|
gRedfishDiscoverActivated = FALSE;
|
||
|
DEBUG ((DEBUG_ERROR, "%a: Can't locate EFI_REDFISH_DISCOVER_PROTOCOL.\n", __func__));
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Status = gEfiRedfishDiscoverProtocol->GetNetworkInterfaceList (
|
||
|
gEfiRedfishDiscoverProtocol,
|
||
|
gRedfishConfigData.Image,
|
||
|
&NumberOfNetworkInterfaces,
|
||
|
&ThisNetworkInterface
|
||
|
);
|
||
|
if (EFI_ERROR (Status) || (NumberOfNetworkInterfaces == 0)) {
|
||
|
DEBUG ((DEBUG_ERROR, "%a: No network interfaces found on the handle.\n", __func__));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Loop to discover Redfish service on each network interface.
|
||
|
//
|
||
|
for (NetworkInterfaceIndex = 0; NetworkInterfaceIndex < NumberOfNetworkInterfaces; NetworkInterfaceIndex++) {
|
||
|
ThisRedfishDiscoveredToken = (EFI_REDFISH_DISCOVERED_TOKEN *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVERED_TOKEN));
|
||
|
if (ThisRedfishDiscoveredToken == NULL) {
|
||
|
DEBUG ((DEBUG_ERROR, "%a: Not enough memory for EFI_REDFISH_DISCOVERED_TOKEN.\n", __func__));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ThisRedfishDiscoveredToken->Signature = REDFISH_DISCOVER_TOKEN_SIGNATURE;
|
||
|
|
||
|
//
|
||
|
// Initial this Redfish Discovered Token
|
||
|
//
|
||
|
Status = gBS->CreateEvent (
|
||
|
EVT_NOTIFY_SIGNAL,
|
||
|
TPL_CALLBACK,
|
||
|
RedfishServiceDiscoveredCallback,
|
||
|
(VOID *)ThisRedfishDiscoveredToken,
|
||
|
&ThisRedfishDiscoveredToken->Event
|
||
|
);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
FreePool (ThisRedfishDiscoveredToken);
|
||
|
DEBUG ((DEBUG_ERROR, "%a: Failed to create event for Redfish discovered token.\n", __func__));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Acquire for Redfish service which is reported by
|
||
|
// Redfish Host Interface.
|
||
|
//
|
||
|
Status = gEfiRedfishDiscoverProtocol->AcquireRedfishService (
|
||
|
gEfiRedfishDiscoverProtocol,
|
||
|
gRedfishConfigData.Image,
|
||
|
ThisNetworkInterface,
|
||
|
EFI_REDFISH_DISCOVER_HOST_INTERFACE,
|
||
|
ThisRedfishDiscoveredToken
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Free Redfish Discovered Token if Discover Instance was not created and
|
||
|
// Redfish Service Discovered Callback event was not triggered.
|
||
|
//
|
||
|
if ((ThisRedfishDiscoveredToken->DiscoverList.NumberOfServiceFound == 0) ||
|
||
|
EFI_ERROR (ThisRedfishDiscoveredToken->DiscoverList.RedfishInstances->Status))
|
||
|
{
|
||
|
gBS->CloseEvent (ThisRedfishDiscoveredToken->Event);
|
||
|
DEBUG ((DEBUG_ERROR, "%a: Free Redfish discovered token - %x.\n", __func__, ThisRedfishDiscoveredToken));
|
||
|
FreePool (ThisRedfishDiscoveredToken);
|
||
|
}
|
||
|
|
||
|
ThisNetworkInterface++;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
Unloads an image.
|
||
|
|
||
|
@param[in] ImageHandle Handle that identifies the image to be unloaded.
|
||
|
|
||
|
@retval EFI_SUCCESS The image has been unloaded.
|
||
|
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
RedfishConfigHandlerDriverUnload (
|
||
|
IN EFI_HANDLE ImageHandle
|
||
|
)
|
||
|
{
|
||
|
RedfishConfigDriverCommonUnload (ImageHandle);
|
||
|
|
||
|
RedfishConfigStopRedfishDiscovery ();
|
||
|
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
This is the declaration of an EFI image entry point. This entry point is
|
||
|
the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
|
||
|
both device drivers and bus drivers.
|
||
|
|
||
|
@param[in] ImageHandle The firmware allocated handle for the UEFI image.
|
||
|
@param[in] SystemTable A pointer to the EFI System Table.
|
||
|
|
||
|
@retval EFI_SUCCESS The operation completed successfully.
|
||
|
@retval Others An unexpected error occurred.
|
||
|
**/
|
||
|
EFI_STATUS
|
||
|
EFIAPI
|
||
|
RedfishConfigHandlerDriverEntryPoint (
|
||
|
IN EFI_HANDLE ImageHandle,
|
||
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||
|
)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
|
||
|
ZeroMem ((VOID *)&gRedfishConfigData, sizeof (REDFISH_CONFIG_DRIVER_DATA));
|
||
|
gRedfishConfigData.Image = ImageHandle;
|
||
|
//
|
||
|
// Register event for EFI_REDFISH_DISCOVER_PROTOCOL protocol install
|
||
|
// notification.
|
||
|
//
|
||
|
Status = gBS->CreateEventEx (
|
||
|
EVT_NOTIFY_SIGNAL,
|
||
|
TPL_CALLBACK,
|
||
|
RedfishDiscoverProtocolInstalled,
|
||
|
NULL,
|
||
|
&gEfiRedfishDiscoverProtocolGuid,
|
||
|
&gEfiRedfishDiscoverProtocolEvent
|
||
|
);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
DEBUG ((DEBUG_ERROR, "%a: Fail to create event for the installation of EFI_REDFISH_DISCOVER_PROTOCOL.", __func__));
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
Status = gBS->RegisterProtocolNotify (
|
||
|
&gEfiRedfishDiscoverProtocolGuid,
|
||
|
gEfiRedfishDiscoverProtocolEvent,
|
||
|
&gEfiRedfishDiscoverRegistration
|
||
|
);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the installation of EFI_REDFISH_DISCOVER_PROTOCOL.", __func__));
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
Status = RedfishConfigCommonInit (ImageHandle, SystemTable);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);
|
||
|
gEfiRedfishDiscoverProtocolEvent = NULL;
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Install UEFI Driver Model protocol(s).
|
||
|
//
|
||
|
Status = EfiLibInstallDriverBinding (
|
||
|
ImageHandle,
|
||
|
SystemTable,
|
||
|
&gRedfishConfigDriverBinding,
|
||
|
ImageHandle
|
||
|
);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
gBS->CloseEvent (gEndOfDxeEvent);
|
||
|
gEndOfDxeEvent = NULL;
|
||
|
gBS->CloseEvent (gExitBootServiceEvent);
|
||
|
gExitBootServiceEvent = NULL;
|
||
|
gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);
|
||
|
gEfiRedfishDiscoverProtocolEvent = NULL;
|
||
|
DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI Binding Protocol of EFI Redfish Config driver.", __func__));
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
return Status;
|
||
|
}
|