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;
}