468 lines
17 KiB
C
468 lines
17 KiB
C
/** @file
|
|
Driver health sample driver which implement the driver health protocol instance.
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2017, Insyde Software Corp. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
|
|
*/
|
|
#include "DriverHealthSampleDxe.h"
|
|
|
|
EFI_HII_HANDLE mDriverHealthSampleHiiHandle = NULL;
|
|
EFI_GUID mDriverHealthSampleBindingGuid = {0xd2781bab, 0x4f1d, 0x415a, {0x96, 0x31, 0x6a, 0x6f, 0xeb, 0xbc, 0x32, 0xad}};
|
|
DRIVER_HEALTH_SAMPLE_DEVICE_PATH mDriverHealthSampleHiiDevicePath = {{{HARDWARE_DEVICE_PATH,
|
|
HW_VENDOR_DP,
|
|
{(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
|
|
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)}},
|
|
EFI_CALLER_ID_GUID},
|
|
{END_DEVICE_PATH_TYPE,
|
|
END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
|
{(UINT8) (END_DEVICE_PATH_LENGTH),
|
|
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)}}
|
|
};
|
|
EFI_HII_CONFIG_ACCESS_PROTOCOL mDriverHealthSampleConfigAccess = {DriverHealthSampleFakeExtractConfig,
|
|
DriverHealthSampleFakeRouteConfig,
|
|
DriverHealthSampleCallback
|
|
};
|
|
EFI_DRIVER_HEALTH_PROTOCOL mDriverHealthSampleDriverHealth = {DriverHealthSampleGetHealthStatus,
|
|
DriverHealthSampleRepair
|
|
};
|
|
EFI_COMPONENT_NAME_PROTOCOL mDriverHealthSampleComponentName = {DriverHealthSampleGetDriverName,
|
|
DriverHealthSampleGetControllerName,
|
|
"eng"
|
|
};
|
|
EFI_COMPONENT_NAME2_PROTOCOL mDriverHealthSampleComponentName2 = {(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) DriverHealthSampleGetDriverName,
|
|
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) DriverHealthSampleGetControllerName,
|
|
"en"
|
|
};
|
|
EFI_UNICODE_STRING_TABLE mDriverHealthSampleNameTable[] = {{"eng;en",
|
|
L"DriverHealthSample Driver"
|
|
},
|
|
{NULL,
|
|
NULL
|
|
}};
|
|
EFI_DRIVER_BINDING_PROTOCOL mDriverHealthSampleDriverBinding = {DriverHealthSampleDriverSupported,
|
|
DriverHealthSampleDriverStart,
|
|
DriverHealthSampleDriverStop,
|
|
0xa,
|
|
NULL,
|
|
NULL
|
|
};
|
|
DRIVER_HEALTH_SAMPLE_DEVICE_INFO mDriverHealthSampleDevList[] = {
|
|
{NULL, L"Device 01 (healthy)" , EfiDriverHealthStatusHealthy , FALSE},
|
|
{NULL, L"Device 02 (healthy)" , EfiDriverHealthStatusHealthy , FALSE},
|
|
{NULL, L"Device 03 (RepairRequired)" , EfiDriverHealthStatusRepairRequired , FALSE},
|
|
{NULL, L"Device 04 (RepairRequired)" , EfiDriverHealthStatusRepairRequired , FALSE},
|
|
{NULL, L"Device 05 (ConfigRequired)" , EfiDriverHealthStatusConfigurationRequired, FALSE},
|
|
{NULL, L"Device 06 (ConfigRequired)" , EfiDriverHealthStatusConfigurationRequired, FALSE},
|
|
{NULL, L"Device 07 (Failed)" , EfiDriverHealthStatusFailed , FALSE},
|
|
{NULL, L"Device 08 (Failed)" , EfiDriverHealthStatusFailed , FALSE},
|
|
{NULL, L"Device 09 (ReconnectRequired)", EfiDriverHealthStatusReconnectRequired , FALSE},
|
|
{NULL, L"Device 10 (ReconnectRequired)", EfiDriverHealthStatusReconnectRequired , FALSE},
|
|
{NULL, L"Device 11 (RebootRequired)" , EfiDriverHealthStatusRebootRequired , FALSE},
|
|
{NULL, L"Device 12 (RebootRequired)" , EfiDriverHealthStatusRebootRequired , FALSE},
|
|
};
|
|
UINTN mDriverHealthSampleDevCount = sizeof(mDriverHealthSampleDevList) / sizeof(DRIVER_HEALTH_SAMPLE_DEVICE_INFO);
|
|
|
|
|
|
STATIC
|
|
DRIVER_HEALTH_SAMPLE_DEVICE_INFO *
|
|
GetDeviceInfo (
|
|
IN EFI_HANDLE Controller
|
|
)
|
|
{
|
|
UINTN Index;
|
|
|
|
for (Index = 0; Index < mDriverHealthSampleDevCount; Index++) {
|
|
if (mDriverHealthSampleDevList[Index].Controller == Controller) {
|
|
return &mDriverHealthSampleDevList[Index];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// EFI_HII_CONFIG_ACCESS_PROTOCOL instance
|
|
//
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleFakeExtractConfig (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN CONST EFI_STRING Request,
|
|
OUT EFI_STRING *Progress,
|
|
OUT EFI_STRING *Results
|
|
)
|
|
{
|
|
if (Progress == NULL || Results == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
*Progress = Request;
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleFakeRouteConfig (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN CONST EFI_STRING Configuration,
|
|
OUT EFI_STRING *Progress
|
|
)
|
|
{
|
|
if (Configuration == NULL || Progress == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleCallback (
|
|
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
|
|
IN EFI_BROWSER_ACTION Action,
|
|
IN EFI_QUESTION_ID QuestionId,
|
|
IN UINT8 Type,
|
|
IN EFI_IFR_TYPE_VALUE *Value,
|
|
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
|
|
)
|
|
{
|
|
if ((Value == NULL) || (ActionRequest == NULL)) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (Action != EFI_BROWSER_ACTION_CHANGED) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// EFI_DRIVER_BINDING_PROTOCOL instance
|
|
//
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleDriverSupported (
|
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
IN EFI_HANDLE Controller,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
VOID *Instance;
|
|
|
|
Status = gBS->HandleProtocol (
|
|
Controller,
|
|
&mDriverHealthSampleBindingGuid,
|
|
(VOID **) &Instance
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
Status = gBS->OpenProtocol (
|
|
Controller,
|
|
&mDriverHealthSampleBindingGuid,
|
|
(VOID **) &Instance,
|
|
This->DriverBindingHandle,
|
|
Controller,
|
|
EFI_OPEN_PROTOCOL_BY_DRIVER
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return gBS->CloseProtocol (
|
|
Controller,
|
|
&mDriverHealthSampleBindingGuid,
|
|
This->DriverBindingHandle,
|
|
Controller
|
|
);
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleDriverStart (
|
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
IN EFI_HANDLE Controller,
|
|
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
|
|
)
|
|
{
|
|
VOID *Instance;
|
|
|
|
return gBS->OpenProtocol (
|
|
Controller,
|
|
&mDriverHealthSampleBindingGuid,
|
|
(VOID **) &Instance,
|
|
This->DriverBindingHandle,
|
|
Controller,
|
|
EFI_OPEN_PROTOCOL_BY_DRIVER
|
|
);
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleDriverStop (
|
|
IN EFI_DRIVER_BINDING_PROTOCOL *This,
|
|
IN EFI_HANDLE Controller,
|
|
IN UINTN NumberOfChildren,
|
|
IN EFI_HANDLE *ChildHandleBuffer
|
|
)
|
|
{
|
|
DRIVER_HEALTH_SAMPLE_DEVICE_INFO *DeviceInfo;
|
|
|
|
DeviceInfo = GetDeviceInfo (Controller);
|
|
if (DeviceInfo == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
DeviceInfo->Reconnected = TRUE;
|
|
|
|
gBS->CloseProtocol (
|
|
Controller,
|
|
&mDriverHealthSampleBindingGuid,
|
|
This->DriverBindingHandle,
|
|
Controller
|
|
);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// EFI_COMPONENT_NAME_PROTOCOL instance
|
|
//
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleGetDriverName (
|
|
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
|
IN CHAR8 *Language,
|
|
OUT CHAR16 **DriverName
|
|
)
|
|
{
|
|
return LookupUnicodeString2 (
|
|
Language,
|
|
This->SupportedLanguages,
|
|
mDriverHealthSampleNameTable,
|
|
DriverName,
|
|
(BOOLEAN)(This == &mDriverHealthSampleComponentName)
|
|
);
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleGetControllerName (
|
|
IN EFI_COMPONENT_NAME_PROTOCOL *This,
|
|
IN EFI_HANDLE ControllerHandle,
|
|
IN EFI_HANDLE ChildHandle OPTIONAL,
|
|
IN CHAR8 *Language,
|
|
OUT CHAR16 **ControllerName
|
|
)
|
|
{
|
|
DRIVER_HEALTH_SAMPLE_DEVICE_INFO *DeviceInfo;
|
|
|
|
if (ControllerHandle == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
if (ChildHandle != NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
DeviceInfo = GetDeviceInfo (ControllerHandle);
|
|
if (DeviceInfo == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
*ControllerName = AllocateCopyPool (StrSize (DeviceInfo->DeviceName), DeviceInfo->DeviceName);
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// EFI_DRIVER_HEALTH_PROTOCOL instance
|
|
//
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleGetHealthStatus (
|
|
IN EFI_DRIVER_HEALTH_PROTOCOL *This,
|
|
IN EFI_HANDLE ControllerHandle OPTIONAL,
|
|
IN EFI_HANDLE ChildHandle OPTIONAL,
|
|
OUT EFI_DRIVER_HEALTH_STATUS *HealthStatus,
|
|
OUT EFI_DRIVER_HEALTH_HII_MESSAGE **MessageList OPTIONAL,
|
|
OUT EFI_HII_HANDLE *FormHiiHandle OPTIONAL
|
|
)
|
|
{
|
|
UINTN Index;
|
|
DRIVER_HEALTH_SAMPLE_DEVICE_INFO *DeviceInfo;
|
|
EFI_DRIVER_HEALTH_HII_MESSAGE *MsgList;
|
|
|
|
if (HealthStatus == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (ControllerHandle == NULL) {
|
|
for (Index = 0; Index < mDriverHealthSampleDevCount; Index++) {
|
|
if (mDriverHealthSampleDevList[Index].HealthStatus != EfiDriverHealthStatusHealthy) {
|
|
*HealthStatus = EfiDriverHealthStatusFailed;
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
|
|
*HealthStatus = EfiDriverHealthStatusHealthy;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
if (ChildHandle != NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
DeviceInfo = GetDeviceInfo (ControllerHandle);
|
|
if (DeviceInfo == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
*HealthStatus = DeviceInfo->HealthStatus;
|
|
if (MessageList != NULL) {
|
|
MsgList = NULL;
|
|
if (DeviceInfo->HealthStatus == EfiDriverHealthStatusReconnectRequired) {
|
|
MsgList = AllocateZeroPool (sizeof (EFI_DRIVER_HEALTH_HII_MESSAGE) * 2);
|
|
if (MsgList != NULL) {
|
|
MsgList->HiiHandle = mDriverHealthSampleHiiHandle;
|
|
MsgList->StringId = DeviceInfo->Reconnected ? STRING_TOKEN (STR_DRIVER_HEALTH_SAMPLE_RECONNECTED) :
|
|
STRING_TOKEN (STR_DRIVER_HEALTH_SAMPLE_NOT_RECONNECTED);
|
|
}
|
|
}
|
|
*MessageList = MsgList;
|
|
}
|
|
if (FormHiiHandle != NULL) {
|
|
*FormHiiHandle = (DeviceInfo->HealthStatus == EfiDriverHealthStatusConfigurationRequired) ? mDriverHealthSampleHiiHandle : NULL;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleRepair (
|
|
IN EFI_DRIVER_HEALTH_PROTOCOL *This,
|
|
IN EFI_HANDLE ControllerHandle,
|
|
IN EFI_HANDLE ChildHandle OPTIONAL,
|
|
IN EFI_DRIVER_HEALTH_REPAIR_NOTIFY RepairNotify OPTIONAL
|
|
)
|
|
{
|
|
DRIVER_HEALTH_SAMPLE_DEVICE_INFO *DeviceInfo;
|
|
|
|
if (ControllerHandle == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (ChildHandle != NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
DeviceInfo = GetDeviceInfo (ControllerHandle);
|
|
if (DeviceInfo == NULL) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
if (DeviceInfo->HealthStatus != EfiDriverHealthStatusRepairRequired) {
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
DeviceInfo->HealthStatus = EfiDriverHealthStatusHealthy;
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Install necessary protocol instances.
|
|
|
|
@param[in] ImageHandle The image handle.
|
|
@param[in] SystemTable The system table.
|
|
|
|
@retval EFI_SUCEESS Success to install necessary protocol instances
|
|
@retval Other Failed to install protocol
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverHealthSampleDxeEntry (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN Index;
|
|
EFI_HANDLE Handle;
|
|
|
|
//
|
|
// Install HII related protocol and data
|
|
//
|
|
Handle = NULL;
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&Handle,
|
|
&gEfiDevicePathProtocolGuid,
|
|
&mDriverHealthSampleHiiDevicePath,
|
|
&gEfiHiiConfigAccessProtocolGuid,
|
|
&mDriverHealthSampleConfigAccess,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
mDriverHealthSampleHiiHandle = HiiAddPackages (
|
|
&gEfiCallerIdGuid,
|
|
Handle,
|
|
DriverHealthSampleVfrBin,
|
|
STRING_ARRAY_NAME,
|
|
NULL
|
|
);
|
|
if (mDriverHealthSampleHiiHandle == NULL) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Install driver binding, component name(2) and driver health protocols
|
|
//
|
|
Status = EfiLibInstallDriverBindingComponentName2 (
|
|
ImageHandle,
|
|
SystemTable,
|
|
&mDriverHealthSampleDriverBinding,
|
|
ImageHandle,
|
|
&mDriverHealthSampleComponentName,
|
|
&mDriverHealthSampleComponentName2
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&ImageHandle,
|
|
&gEfiDriverHealthProtocolGuid,
|
|
&mDriverHealthSampleDriverHealth,
|
|
NULL
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Produce fake devices which are controled by this driver
|
|
//
|
|
for (Index = 0; Index < mDriverHealthSampleDevCount; Index++) {
|
|
gBS->InstallProtocolInterface (
|
|
&mDriverHealthSampleDevList[Index].Controller,
|
|
&mDriverHealthSampleBindingGuid,
|
|
EFI_NATIVE_INTERFACE,
|
|
&mDriverHealthSampleDevList[Index]
|
|
);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|