14.3.1 Device Drivers

Device drivers implementing Repair() must verify that ChildHandle is NULL and that ControllerHandle represents a device the device driver is currently managing. The following example shows the steps required to check these parameters.

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 the GetHealthStatus() service is currently managing ControllerHandle. If the private context structure is required, typically, the UEFI Boot Service OpenProtocol()opens 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. This example also calls ProgressNotification from 10% to 100% at 10% increments.

Example 155-Repair() Function for a Device Driver

#include <Uefi.h>
#include <Protocol/DriverHealth.h>
EFI_STATUS EFIAPI
AbcRepair (
IN EFI_DRIVER_HEALTH_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle, OPTIONAL
IN EFI_DRIVER_HEALTH_REPAIR_PROGRESS_NOTIFY ProgressNotification OPTIONAL
)
{
EFI_STATUS Status;
UINTN Index;
//
// ChildHandle must be NULL for a Device Driver
//
if (ChildHandle != NULL) {
return EFI_UNSUPPORTED;
}
//
// Make sure this driver is currently managing ControllerHandle
//
Status = EfiTestManagedDevice (
ControllerHandle,
gAbcDriverBinding.DriverBindingHandle,
&gEfiPciIoProtocolGuid
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Repair ControllerHandle
//
for (Index = 0;
Index < 10; Index++) {
//
// Perform 10% of the work required to repair ControllerHandle
//
if (ProgressNotification != NULL) {
ProgressNotification (Index, 10);
}
}
return EFI_SUCCESS;
}