14.2.2 Bus Drivers and Hybrid Drivers
Bus drivers and hybrid drivers implementing the Driver Health Protocol must
verify that ControllerHandle and ChildHandle represent a device that is
currently under the driver's management. The Driver Health Protocol also
supports returning the combined health status for all controllers a UEFI Driver
manages. This request is made by passing in a ControllerHandle value of
NULL
.
The example below shows the steps required to check these parameters and also
retrieve the private context data structure. If these checks pass, the health
status is returned. In this specific example, the driver opens the PCI I/O
Protocol in its Driver Binding Start() function. This is why
gEfiPciIoProtocolGuid
is used in the call to the EDK II Library UefiLib
function EfiTestManagedDevice()
that checks to see if the UEFI
Drivers providing this GetHealthStatus()
service is currently managing
ControllerHandle. If the private context structure is required, the UEFI Boot
Service OpenProtocol()
is typically used to open one of the UEFI Driver
produced protocols on ControllerHandle and then uses a CR()
based macro to
retrieve a pointer to the private context structure. If diagnostics are being
run on ChildHandle, a produced protocol on ChildHandle can be opened.
Note: If ChildHandle is NULL, a request is being made to run diagnostics on the bus controller. If ChildHandle is not NULL,then a request is being made to run diagnostics on a UEFI Driver managed child controller.
Example 154-GetHealthStatus() for a Bus Driver or Hybrid Driver
#include <Uefi.h>
#include <Protocol/DriverHealth.h>
#include <Protocol/PciIo.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiLib.h>
EFI_STATUS
EFIAPI
AbcGetHealthStatus (
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
)
{
EFI_STATUS Status;
//
// Check input parameters
//
if (HealthStatus == NULL) {
return EFI_INVALID_PARAMETER;
}
if (ControllerHandle == NULL) {
//
// If all controllers managed by this UEFI Driver are healthly,
// then assign HealthStatus to EfiDriverHealthStatusHealthy.
// Otherwise, assign HealthStatus to EfiDriverHealthStatusFailed.
//
return EFI_SUCCESS;
}
//
// Make sure this driver is currently managing ControllerHandle
//
Status = EfiTestManagedDevice (
ControllerHandle,
gAbcDriverBinding.DriverBindingHandle,
&gEfiPciIoProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// If ChildHandle is not NULL, then make sure this driver produced ChildHandle
//
if (ChildHandle != NULL) {
Status = EfiTestChildHandle (
ControllerHandle,
ChildHandle,
&gEfiPciIoProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
}
if (ChildHandle == NULL) {
//
// Retrieve health status for ControllerHandle
//
} else {
//
// Retrieve health status for ChildHandle
//
}
return EFI_SUCCESS;
}
Bus drivers and hybrid drivers are recommended
to provide health status for
both the bus controller and the child controllers these types of drivers
produce. Implementing diagnostics for only the bus controller or only the child
controllers is strongly discouraged.