2 The platform device manager reference implementation
4 Copyright (c) 2004 - 2010, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "DeviceManager.h"
17 DEVICE_MANAGER_CALLBACK_DATA gDeviceManagerPrivate
= {
18 DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE
,
35 EFI_GUID mDeviceManagerGuid
= DEVICE_MANAGER_FORMSET_GUID
;
36 EFI_GUID mDriverHealthGuid
= DRIVER_HEALTH_FORMSET_GUID
;
38 DEVICE_MANAGER_MENU_ITEM mDeviceManagerMenuItemTable
[] = {
39 { STRING_TOKEN (STR_DISK_DEVICE
), EFI_DISK_DEVICE_CLASS
},
40 { STRING_TOKEN (STR_VIDEO_DEVICE
), EFI_VIDEO_DEVICE_CLASS
},
41 { STRING_TOKEN (STR_NETWORK_DEVICE
), EFI_NETWORK_DEVICE_CLASS
},
42 { STRING_TOKEN (STR_INPUT_DEVICE
), EFI_INPUT_DEVICE_CLASS
},
43 { STRING_TOKEN (STR_ON_BOARD_DEVICE
), EFI_ON_BOARD_DEVICE_CLASS
},
44 { STRING_TOKEN (STR_OTHER_DEVICE
), EFI_OTHER_DEVICE_CLASS
}
47 HII_VENDOR_DEVICE_PATH mDeviceManagerHiiVendorDevicePath
= {
53 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
54 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
58 // {102579A0-3686-466e-ACD8-80C087044F4A}
60 { 0x102579a0, 0x3686, 0x466e, { 0xac, 0xd8, 0x80, 0xc0, 0x87, 0x4, 0x4f, 0x4a } }
64 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
66 (UINT8
) (END_DEVICE_PATH_LENGTH
),
67 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
72 HII_VENDOR_DEVICE_PATH mDriverHealthHiiVendorDevicePath
= {
78 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
79 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
83 // {D8F76651-1675-4986-BED4-3824B2F1F4C8}
85 { 0xd8f76651, 0x1675, 0x4986, { 0xbe, 0xd4, 0x38, 0x24, 0xb2, 0xf1, 0xf4, 0xc8 } }
89 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
91 (UINT8
) (END_DEVICE_PATH_LENGTH
),
92 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
98 This function is invoked if user selected a interactive opcode from Device Manager's
99 Formset. The decision by user is saved to gCallbackKey for later processing. If
100 user set VBIOS, the new value is saved to EFI variable.
102 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
103 @param Action Specifies the type of action taken by the browser.
104 @param QuestionId A unique value which is sent to the original exporting driver
105 so that it can identify the type of data to expect.
106 @param Type The type of value for the question.
107 @param Value A pointer to the data being sent to the original exporting driver.
108 @param ActionRequest On return, points to the action requested by the callback function.
110 @retval EFI_SUCCESS The callback successfully handled the action.
111 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
116 DeviceManagerCallback (
117 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
118 IN EFI_BROWSER_ACTION Action
,
119 IN EFI_QUESTION_ID QuestionId
,
121 IN EFI_IFR_TYPE_VALUE
*Value
,
122 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
125 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
126 return EFI_INVALID_PARAMETER
;
129 gCallbackKey
= QuestionId
;
132 // Request to exit SendForm(), so as to switch to selected form
134 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
141 This function registers HII packages to HII database.
143 @retval EFI_SUCCESS HII packages for the Device Manager were registered successfully.
144 @retval EFI_OUT_OF_RESOURCES HII packages for the Device Manager failed to be registered.
148 InitializeDeviceManager (
155 // Install Device Path Protocol and Config Access protocol to driver handle
157 Status
= gBS
->InstallMultipleProtocolInterfaces (
158 &gDeviceManagerPrivate
.DriverHandle
,
159 &gEfiDevicePathProtocolGuid
,
160 &mDeviceManagerHiiVendorDevicePath
,
161 &gEfiHiiConfigAccessProtocolGuid
,
162 &gDeviceManagerPrivate
.ConfigAccess
,
165 ASSERT_EFI_ERROR (Status
);
167 Status
= gBS
->InstallMultipleProtocolInterfaces (
168 &gDeviceManagerPrivate
.DriverHealthHandle
,
169 &gEfiDevicePathProtocolGuid
,
170 &mDriverHealthHiiVendorDevicePath
,
171 &gEfiHiiConfigAccessProtocolGuid
,
172 &gDeviceManagerPrivate
.DriverHealthConfigAccess
,
175 ASSERT_EFI_ERROR (Status
);
178 // Publish our HII data
180 gDeviceManagerPrivate
.HiiHandle
= HiiAddPackages (
182 gDeviceManagerPrivate
.DriverHandle
,
187 if (gDeviceManagerPrivate
.HiiHandle
== NULL
) {
188 return EFI_OUT_OF_RESOURCES
;
190 Status
= EFI_SUCCESS
;
194 // Publish Driver Health HII data
196 gDeviceManagerPrivate
.DriverHealthHiiHandle
= HiiAddPackages (
198 gDeviceManagerPrivate
.DriverHealthHandle
,
203 if (gDeviceManagerPrivate
.DriverHealthHiiHandle
== NULL
) {
204 Status
= EFI_OUT_OF_RESOURCES
;
206 Status
= EFI_SUCCESS
;
213 Extract the displayed formset for given HII handle and class guid.
215 @param Handle The HII handle.
216 @param SetupClassGuid The class guid specifies which form set will be displayed.
217 @param FormSetTitle Formset title string.
218 @param FormSetHelp Formset help string.
220 @retval TRUE The formset for given HII handle will be displayed.
221 @return FALSE The formset for given HII handle will not be displayed.
225 ExtractDisplayedHiiFormFromHiiHandle (
226 IN EFI_HII_HANDLE Handle
,
227 IN EFI_GUID
*SetupClassGuid
,
228 OUT EFI_STRING_ID
*FormSetTitle
,
229 OUT EFI_STRING_ID
*FormSetHelp
234 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
239 UINT32 PackageListLength
;
240 EFI_HII_PACKAGE_HEADER PackageHeader
;
244 ASSERT (Handle
!= NULL
);
245 ASSERT (SetupClassGuid
!= NULL
);
246 ASSERT (FormSetTitle
!= NULL
);
247 ASSERT (FormSetHelp
!= NULL
);
255 // Get HII PackageList
258 HiiPackageList
= NULL
;
259 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
261 // Handle is a invalid handle. Check if Handle is corrupted.
263 ASSERT (Status
!= EFI_NOT_FOUND
);
265 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
267 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
269 HiiPackageList
= AllocatePool (BufferSize
);
270 ASSERT (HiiPackageList
!= NULL
);
272 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
273 if (EFI_ERROR (Status
)) {
278 // Get Form package from this HII package List
280 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
282 PackageListLength
= ReadUnaligned32 (&HiiPackageList
->PackageLength
);
284 while (Offset
< PackageListLength
) {
285 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
286 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
288 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
290 // Search FormSet Opcode in this Form Package
292 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
293 while (Offset2
< PackageHeader
.Length
) {
294 OpCodeData
= Package
+ Offset2
;
296 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
297 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
299 // Find FormSet OpCode
301 ClassGuidNum
= ((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
;
302 ClassGuid
= (EFI_GUID
*) (VOID
*)(OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
303 while (ClassGuidNum
-- > 0) {
304 if (CompareGuid (SetupClassGuid
, ClassGuid
)) {
305 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
306 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
307 FreePool (HiiPackageList
);
312 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
313 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
314 FreePool (HiiPackageList
);
322 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
327 // Go to next package
329 Offset
+= PackageHeader
.Length
;
332 FreePool (HiiPackageList
);
338 Call the browser and display the device manager to allow user
339 to configure the platform.
341 This function create the dynamic content for device manager. It includes
342 section header for all class of devices, one-of opcode to set VBIOS.
344 @retval EFI_SUCCESS Operation is successful.
345 @return Other values if failed to clean up the dynamic content from HII
358 EFI_STRING_ID TokenHelp
;
359 EFI_HII_HANDLE
*HiiHandles
;
360 EFI_HII_HANDLE HiiHandle
;
361 EFI_STRING_ID FormSetTitle
;
362 EFI_STRING_ID FormSetHelp
;
363 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
364 VOID
*StartOpCodeHandle
;
365 VOID
*EndOpCodeHandle
;
366 EFI_IFR_GUID_LABEL
*StartLabel
;
367 EFI_IFR_GUID_LABEL
*EndLabel
;
369 EFI_HANDLE
*DriverHealthHandles
;
372 Status
= EFI_SUCCESS
;
375 DriverHealthHandles
= NULL
;
378 // Connect all prior to entering the platform setup menu.
380 if (!gConnectAllHappened
) {
381 BdsLibConnectAllDriversToAllControllers ();
382 gConnectAllHappened
= TRUE
;
385 // Create Subtitle OpCodes
388 // Allocate space for creation of UpdateData Buffer
390 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
391 ASSERT (StartOpCodeHandle
!= NULL
);
393 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
394 ASSERT (EndOpCodeHandle
!= NULL
);
397 // Create Hii Extend Label OpCode as the start opcode
399 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
400 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
401 StartLabel
->Number
= LABEL_DEVICES_LIST
;
404 // Create Hii Extend Label OpCode as the end opcode
406 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
407 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
408 EndLabel
->Number
= LABEL_END
;
410 HiiCreateSubTitleOpCode (StartOpCodeHandle
, STRING_TOKEN (STR_DEVICES_LIST
), 0, 0, 1);
413 // Get all the Hii handles
415 HiiHandles
= HiiGetHiiHandles (NULL
);
416 ASSERT (HiiHandles
!= NULL
);
418 HiiHandle
= gDeviceManagerPrivate
.HiiHandle
;
421 // Search for formset of each class type
423 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
424 if (!ExtractDisplayedHiiFormFromHiiHandle (HiiHandles
[Index
], &gEfiHiiPlatformSetupFormsetGuid
, &FormSetTitle
, &FormSetHelp
)) {
428 String
= HiiGetString (HiiHandles
[Index
], FormSetTitle
, NULL
);
429 if (String
== NULL
) {
430 String
= HiiGetString (HiiHandle
, STR_MISSING_STRING
, NULL
);
431 ASSERT (String
!= NULL
);
433 Token
= HiiSetString (HiiHandle
, 0, String
, NULL
);
436 String
= HiiGetString (HiiHandles
[Index
], FormSetHelp
, NULL
);
437 if (String
== NULL
) {
438 String
= HiiGetString (HiiHandle
, STR_MISSING_STRING
, NULL
);
439 ASSERT (String
!= NULL
);
441 TokenHelp
= HiiSetString (HiiHandle
, 0, String
, NULL
);
444 HiiCreateActionOpCode (
446 (EFI_QUESTION_ID
) (Index
+ DEVICE_KEY_OFFSET
),
449 EFI_IFR_FLAG_CALLBACK
,
455 // Add End Opcode for Subtitle
457 HiiCreateEndOpCode (StartOpCodeHandle
);
459 Status
= gBS
->LocateHandleBuffer (
461 &gEfiDriverHealthProtocolGuid
,
467 // If there are no drivers installed driver health protocol
469 if (NumHandles
== 0) {
470 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DM_DRIVER_HEALTH_TITLE
), GetStringById (STRING_TOKEN (STR_EMPTY_STRING
)), NULL
);
471 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
), GetStringById (STRING_TOKEN (STR_EMPTY_STRING
)), NULL
);
474 // Check All Driver health status
476 if (!PlaformHealthStatusCheck ()) {
478 // At least one driver in the platform are not in healthy status
480 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
), GetStringById (STRING_TOKEN (STR_DRIVER_NOT_HEALTH
)), NULL
);
483 // For the string of STR_DRIVER_HEALTH_ALL_HEALTHY previously has been updated and we need to update it while re-entry.
485 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
), GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
)), NULL
);
492 DEVICE_MANAGER_FORM_ID
,
497 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
498 Status
= gFormBrowser2
->SendForm (
507 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
508 EnableResetRequired ();
512 // We will have returned from processing a callback - user either hit ESC to exit, or selected
513 // a target to display
515 if ((gCallbackKey
!= 0) && (gCallbackKey
!= DEVICE_MANAGER_KEY_DRIVER_HEALTH
)) {
516 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
517 Status
= gFormBrowser2
->SendForm (
519 &HiiHandles
[gCallbackKey
- DEVICE_KEY_OFFSET
],
527 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
528 EnableResetRequired ();
532 // Force return to Device Manager
534 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
538 // Driver Health item chose.
540 if (gCallbackKey
== DEVICE_MANAGER_KEY_DRIVER_HEALTH
) {
543 // Force return to Device Manager
545 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
549 // Cleanup dynamic created strings in HII database by reinstall the packagelist
551 HiiRemovePackages (HiiHandle
);
553 gDeviceManagerPrivate
.HiiHandle
= HiiAddPackages (
555 gDeviceManagerPrivate
.DriverHandle
,
560 if (gDeviceManagerPrivate
.HiiHandle
== NULL
) {
561 Status
= EFI_OUT_OF_RESOURCES
;
563 Status
= EFI_SUCCESS
;
566 HiiFreeOpCodeHandle (StartOpCodeHandle
);
567 HiiFreeOpCodeHandle (EndOpCodeHandle
);
568 FreePool (HiiHandles
);
574 This function is invoked if user selected a interactive opcode from Driver Health's
575 Formset. The decision by user is saved to gCallbackKey for later processing.
577 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
578 @param Action Specifies the type of action taken by the browser.
579 @param QuestionId A unique value which is sent to the original exporting driver
580 so that it can identify the type of data to expect.
581 @param Type The type of value for the question.
582 @param Value A pointer to the data being sent to the original exporting driver.
583 @param ActionRequest On return, points to the action requested by the callback function.
585 @retval EFI_SUCCESS The callback successfully handled the action.
586 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
591 DriverHealthCallback (
592 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
593 IN EFI_BROWSER_ACTION Action
,
594 IN EFI_QUESTION_ID QuestionId
,
596 IN EFI_IFR_TYPE_VALUE
*Value
,
597 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
600 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
601 return EFI_INVALID_PARAMETER
;
604 gCallbackKey
= QuestionId
;
607 // Request to exit SendForm(), so as to switch to selected form
609 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
615 Collect and display the platform's driver health relative information, allow user to do interactive
616 operation while the platform is unhealthy.
618 This function display a form which divided into two parts. The one list all modules which has installed
619 driver health protocol. The list usually contain driver name, controller name, and it's health info.
620 While the driver name can't be retrieved, will use device path as backup. The other part of the form provide
621 a choice to the user to repair all platform.
630 EFI_HII_HANDLE HiiHandle
;
631 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
632 EFI_IFR_GUID_LABEL
*StartLabel
;
633 EFI_IFR_GUID_LABEL
*StartLabelRepair
;
634 EFI_IFR_GUID_LABEL
*EndLabel
;
635 EFI_IFR_GUID_LABEL
*EndLabelRepair
;
636 VOID
*StartOpCodeHandle
;
637 VOID
*EndOpCodeHandle
;
638 VOID
*StartOpCodeHandleRepair
;
639 VOID
*EndOpCodeHandleRepair
;
642 EFI_STRING_ID TokenHelp
;
644 EFI_STRING TmpString
;
645 EFI_STRING DriverName
;
646 EFI_STRING ControllerName
;
647 LIST_ENTRY DriverHealthList
;
648 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
650 EFI_DEVICE_PATH_PROTOCOL
*DriverDevicePath
;
653 HiiHandle
= gDeviceManagerPrivate
.DriverHealthHiiHandle
;
656 DriverHealthInfo
= NULL
;
657 DriverDevicePath
= NULL
;
658 InitializeListHead (&DriverHealthList
);
661 // Allocate space for creation of UpdateData Buffer
663 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
664 ASSERT (StartOpCodeHandle
!= NULL
);
666 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
667 ASSERT (EndOpCodeHandle
!= NULL
);
669 StartOpCodeHandleRepair
= HiiAllocateOpCodeHandle ();
670 ASSERT (StartOpCodeHandleRepair
!= NULL
);
672 EndOpCodeHandleRepair
= HiiAllocateOpCodeHandle ();
673 ASSERT (EndOpCodeHandleRepair
!= NULL
);
676 // Create Hii Extend Label OpCode as the start opcode
678 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
679 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
680 StartLabel
->Number
= LABEL_DRIVER_HEALTH
;
683 // Create Hii Extend Label OpCode as the start opcode
685 StartLabelRepair
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandleRepair
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
686 StartLabelRepair
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
687 StartLabelRepair
->Number
= LABEL_DRIVER_HEALTH_REAPIR_ALL
;
690 // Create Hii Extend Label OpCode as the end opcode
692 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
693 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
694 EndLabel
->Number
= LABEL_DRIVER_HEALTH_END
;
697 // Create Hii Extend Label OpCode as the end opcode
699 EndLabelRepair
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandleRepair
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
700 EndLabelRepair
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
701 EndLabelRepair
->Number
= LABEL_DRIVER_HEALTH_REAPIR_ALL_END
;
703 HiiCreateSubTitleOpCode (StartOpCodeHandle
, STRING_TOKEN (STR_DH_STATUS_LIST
), 0, 0, 1);
705 Status
= GetAllControllersHealthStatus (&DriverHealthList
);
706 ASSERT (Status
!= EFI_OUT_OF_RESOURCES
);
708 Link
= GetFirstNode (&DriverHealthList
);
710 while (!IsNull (&DriverHealthList
, Link
)) {
711 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
714 // Assume no line strings is longer than 512 bytes.
716 String
= (EFI_STRING
) AllocateZeroPool (0x200);
717 ASSERT (String
!= NULL
);
719 Status
= DriverHealthGetDriverName (DriverHealthInfo
->DriverHandle
, &DriverName
);
720 if (EFI_ERROR (Status
)) {
722 // Can not get the Driver name, so use the Device path
724 DriverDevicePath
= DevicePathFromHandle (DriverHealthInfo
->DriverHandle
);
725 DriverName
= DevicePathToStr (DriverDevicePath
);
728 // Add the Driver name & Controller name into FormSetTitle string
730 StrnCat (String
, DriverName
, StrLen (DriverName
));
733 Status
= DriverHealthGetControllerName (
734 DriverHealthInfo
->DriverHandle
,
735 DriverHealthInfo
->ControllerHandle
,
736 DriverHealthInfo
->ChildHandle
,
740 if (!EFI_ERROR (Status
)) {
742 // Can not get the Controller name, just let it empty.
744 StrnCat (String
, L
" ", StrLen (L
" "));
745 StrnCat (String
, ControllerName
, StrLen (ControllerName
));
749 // Add the message of the Module itself provided after the string item.
751 if ((DriverHealthInfo
->MessageList
!= NULL
) && (DriverHealthInfo
->MessageList
->StringId
!= 0)) {
752 StrnCat (String
, L
" ", StrLen (L
" "));
753 TmpString
= HiiGetString (
754 DriverHealthInfo
->MessageList
->HiiHandle
,
755 DriverHealthInfo
->MessageList
->StringId
,
759 // Assert if can not retrieve the message string
761 ASSERT (TmpString
!= NULL
);
762 StrnCat (String
, TmpString
, StrLen (TmpString
));
763 FreePool (TmpString
);
766 // Update the string will be displayed base on the driver's health status
768 switch(DriverHealthInfo
->HealthStatus
) {
769 case EfiDriverHealthStatusRepairRequired
:
770 Length
= StrLen (GetStringById (STRING_TOKEN (STR_REPAIR_REQUIRED
)));
771 StrnCat (String
, GetStringById (STRING_TOKEN (STR_REPAIR_REQUIRED
)), Length
);
773 case EfiDriverHealthStatusConfigurationRequired
:
774 Length
= StrLen (GetStringById (STRING_TOKEN (STR_CONFIGURATION_REQUIRED
)));
775 StrnCat (String
, GetStringById (STRING_TOKEN (STR_CONFIGURATION_REQUIRED
)), Length
);
777 case EfiDriverHealthStatusFailed
:
778 Length
= StrLen (GetStringById (STRING_TOKEN (STR_OPERATION_FAILED
)));
779 StrnCat (String
, GetStringById (STRING_TOKEN (STR_OPERATION_FAILED
)), Length
);
781 case EfiDriverHealthStatusReconnectRequired
:
782 Length
= StrLen (GetStringById (STRING_TOKEN (STR_RECONNECT_REQUIRED
)));
783 StrnCat (String
, GetStringById (STRING_TOKEN (STR_RECONNECT_REQUIRED
)), Length
);
785 case EfiDriverHealthStatusRebootRequired
:
786 Length
= StrLen (GetStringById (STRING_TOKEN (STR_REBOOT_REQUIRED
)));
787 StrnCat (String
, GetStringById (STRING_TOKEN (STR_REBOOT_REQUIRED
)), Length
);
790 Length
= StrLen (GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_HEALTHY
)));
791 StrnCat (String
, GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_HEALTHY
)), Length
);
796 Token
= HiiSetString (HiiHandle
, 0, String
, NULL
);
799 TokenHelp
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_SINGLE_HELP
)), NULL
);
801 HiiCreateActionOpCode (
803 (EFI_QUESTION_ID
) (Index
+ DRIVER_HEALTH_KEY_OFFSET
),
806 EFI_IFR_FLAG_CALLBACK
,
810 Link
= GetNextNode (&DriverHealthList
, Link
);
814 // Add End Opcode for Subtitle
816 HiiCreateEndOpCode (StartOpCodeHandle
);
818 HiiCreateSubTitleOpCode (StartOpCodeHandleRepair
, STRING_TOKEN (STR_DRIVER_HEALTH_REPAIR_ALL
), 0, 0, 1);
819 TokenHelp
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_ALL_HELP
)), NULL
);
821 if (PlaformHealthStatusCheck ()) {
823 // No action need to do for the platform
825 Token
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
)), NULL
);
826 HiiCreateActionOpCode (
827 StartOpCodeHandleRepair
,
831 EFI_IFR_FLAG_READ_ONLY
,
836 // Create ActionOpCode only while the platform need to do health related operation.
838 Token
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_ALL_TITLE
)), NULL
);
839 HiiCreateActionOpCode (
840 StartOpCodeHandleRepair
,
841 (EFI_QUESTION_ID
) DRIVER_HEALTH_REPAIR_ALL_KEY
,
844 EFI_IFR_FLAG_CALLBACK
,
849 HiiCreateEndOpCode (StartOpCodeHandleRepair
);
851 Status
= HiiUpdateForm (
854 DRIVER_HEALTH_FORM_ID
,
858 ASSERT (Status
!= EFI_NOT_FOUND
);
859 ASSERT (Status
!= EFI_BUFFER_TOO_SMALL
);
861 Status
= HiiUpdateForm (
864 DRIVER_HEALTH_FORM_ID
,
865 StartOpCodeHandleRepair
,
866 EndOpCodeHandleRepair
868 ASSERT (Status
!= EFI_NOT_FOUND
);
869 ASSERT (Status
!= EFI_BUFFER_TOO_SMALL
);
871 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
872 Status
= gFormBrowser2
->SendForm (
877 DRIVER_HEALTH_FORM_ID
,
881 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
882 EnableResetRequired ();
886 // We will have returned from processing a callback - user either hit ESC to exit, or selected
887 // a target to display.
888 // Process the diver health status states here.
890 if (gCallbackKey
>= DRIVER_HEALTH_KEY_OFFSET
&& gCallbackKey
!= DRIVER_HEALTH_REPAIR_ALL_KEY
) {
891 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
893 Link
= GetFirstNode (&DriverHealthList
);
896 while (!IsNull (&DriverHealthList
, Link
)) {
898 // Got the item relative node in the List
900 if (Index
== (gCallbackKey
- DRIVER_HEALTH_KEY_OFFSET
)) {
901 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
903 // Process the driver's healthy status for the specify module
905 ProcessSingleControllerHealth (
906 DriverHealthInfo
->DriverHealth
,
907 DriverHealthInfo
->ControllerHandle
,
908 DriverHealthInfo
->ChildHandle
,
909 DriverHealthInfo
->HealthStatus
,
910 &(DriverHealthInfo
->MessageList
),
911 DriverHealthInfo
->HiiHandle
916 Link
= GetNextNode (&DriverHealthList
, Link
);
919 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
920 EnableResetRequired ();
924 // Force return to the form of Driver Health in Device Manager
926 gCallbackKey
= DRIVER_HEALTH_RETURN_KEY
;
930 // Repair the whole platform
932 if (gCallbackKey
== DRIVER_HEALTH_REPAIR_ALL_KEY
) {
933 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
935 PlatformRepairAll (&DriverHealthList
);
937 gCallbackKey
= DRIVER_HEALTH_RETURN_KEY
;
941 // Cleanup dynamic created strings in HII database by reinstall the packagelist
944 HiiRemovePackages (HiiHandle
);
946 gDeviceManagerPrivate
.DriverHealthHiiHandle
= HiiAddPackages (
948 gDeviceManagerPrivate
.DriverHealthHandle
,
953 if (gDeviceManagerPrivate
.DriverHealthHiiHandle
== NULL
) {
954 Status
= EFI_OUT_OF_RESOURCES
;
956 Status
= EFI_SUCCESS
;
959 // Free driver health info list
961 while (!IsListEmpty (&DriverHealthList
)) {
963 Link
= GetFirstNode(&DriverHealthList
);
964 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
965 RemoveEntryList (Link
);
967 if (DriverHealthInfo
->MessageList
!= NULL
) {
968 FreePool(DriverHealthInfo
->MessageList
);
969 FreePool (DriverHealthInfo
);
973 HiiFreeOpCodeHandle (StartOpCodeHandle
);
974 HiiFreeOpCodeHandle (EndOpCodeHandle
);
975 HiiFreeOpCodeHandle (StartOpCodeHandleRepair
);
976 HiiFreeOpCodeHandle (EndOpCodeHandleRepair
);
978 if (gCallbackKey
== DRIVER_HEALTH_RETURN_KEY
) {
980 // Force return to Driver Health Form
982 gCallbackKey
= DEVICE_MANAGER_KEY_DRIVER_HEALTH
;
989 Check the Driver Health status of a single controller and try to process it if not healthy.
991 This function called by CheckAllControllersHealthStatus () function in order to process a specify
992 contoller's health state.
994 @param DriverHealthList A Pointer to the list contain all of the platform driver health information.
995 @param DriverHandle The handle of driver.
996 @param ControllerHandle The class guid specifies which form set will be displayed.
997 @param ChildHandle The handle of the child controller to retrieve the health
998 status on. This is an optional parameter that may be NULL.
999 @param DriverHealth A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
1000 @param HealthStatus The health status of the controller.
1002 @retval EFI_INVALID_PARAMETER HealthStatus or DriverHealth is NULL.
1003 @retval HealthStatus The Health status of specify controller.
1004 @retval EFI_OUT_OF_RESOURCES The list of Driver Health Protocol handles can not be retrieved.
1005 @retval EFI_NOT_FOUND No controller in the platform install Driver Health Protocol.
1006 @retval EFI_SUCCESS The Health related operation has been taken successfully.
1011 GetSingleControllerHealthStatus (
1012 IN OUT LIST_ENTRY
*DriverHealthList
,
1013 IN EFI_HANDLE DriverHandle
,
1014 IN EFI_HANDLE ControllerHandle
, OPTIONAL
1015 IN EFI_HANDLE ChildHandle
, OPTIONAL
1016 IN EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
,
1017 IN EFI_DRIVER_HEALTH_STATUS
*HealthStatus
1021 EFI_DRIVER_HEALTH_HII_MESSAGE
*MessageList
;
1022 EFI_HII_HANDLE FormHiiHandle
;
1023 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
1025 if (HealthStatus
== NULL
) {
1027 // If HealthStatus is NULL, then return EFI_INVALID_PARAMETER
1029 return EFI_INVALID_PARAMETER
;
1033 // Assume the HealthStatus is healthy
1035 *HealthStatus
= EfiDriverHealthStatusHealthy
;
1037 if (DriverHealth
== NULL
) {
1039 // If DriverHealth is NULL, then return EFI_INVALID_PARAMETER
1041 return EFI_INVALID_PARAMETER
;
1044 if (ControllerHandle
== NULL
) {
1046 // If ControllerHandle is NULL, the return the cumulative health status of the driver
1048 Status
= DriverHealth
->GetHealthStatus (DriverHealth
, NULL
, NULL
, HealthStatus
, NULL
, NULL
);
1049 if (*HealthStatus
== EfiDriverHealthStatusHealthy
) {
1051 // Add the driver health related information into the list
1053 DriverHealthInfo
= AllocateZeroPool (sizeof (DRIVER_HEALTH_INFO
));
1054 if (DriverHealthInfo
== NULL
) {
1055 return EFI_OUT_OF_RESOURCES
;
1058 DriverHealthInfo
->Signature
= DEVICE_MANAGER_DRIVER_HEALTH_INFO_SIGNATURE
;
1059 DriverHealthInfo
->DriverHandle
= DriverHandle
;
1060 DriverHealthInfo
->ControllerHandle
= NULL
;
1061 DriverHealthInfo
->ChildHandle
= NULL
;
1062 DriverHealthInfo
->HiiHandle
= NULL
;
1063 DriverHealthInfo
->DriverHealth
= DriverHealth
;
1064 DriverHealthInfo
->MessageList
= NULL
;
1065 DriverHealthInfo
->HealthStatus
= *HealthStatus
;
1067 InsertTailList (DriverHealthList
, &DriverHealthInfo
->Link
);
1073 FormHiiHandle
= NULL
;
1076 // Collect the health status with the optional HII message list
1078 Status
= DriverHealth
->GetHealthStatus (DriverHealth
, ControllerHandle
, ChildHandle
, HealthStatus
, &MessageList
, &FormHiiHandle
);
1080 if (EFI_ERROR (Status
)) {
1082 // If the health status could not be retrieved, then return immediately
1088 // Add the driver health related information into the list
1090 DriverHealthInfo
= AllocateZeroPool (sizeof (DRIVER_HEALTH_INFO
));
1091 if (DriverHealthInfo
== NULL
) {
1092 return EFI_OUT_OF_RESOURCES
;
1095 DriverHealthInfo
->Signature
= DEVICE_MANAGER_DRIVER_HEALTH_INFO_SIGNATURE
;
1096 DriverHealthInfo
->DriverHandle
= DriverHandle
;
1097 DriverHealthInfo
->ControllerHandle
= ControllerHandle
;
1098 DriverHealthInfo
->ChildHandle
= ChildHandle
;
1099 DriverHealthInfo
->HiiHandle
= FormHiiHandle
;
1100 DriverHealthInfo
->DriverHealth
= DriverHealth
;
1101 DriverHealthInfo
->MessageList
= MessageList
;
1102 DriverHealthInfo
->HealthStatus
= *HealthStatus
;
1104 InsertTailList (DriverHealthList
, &DriverHealthInfo
->Link
);
1110 Collects all the EFI Driver Health Protocols currently present in the EFI Handle Database,
1111 and queries each EFI Driver Health Protocol to determine if one or more of the controllers
1112 managed by each EFI Driver Health Protocol instance are not healthy.
1114 @param DriverHealthList A Pointer to the list contain all of the platform driver health
1117 @retval EFI_NOT_FOUND No controller in the platform install Driver Health Protocol.
1118 @retval EFI_SUCCESS All the controllers in the platform are healthy.
1119 @retval EFI_OUT_OF_RESOURCES The list of Driver Health Protocol handles can not be retrieved.
1123 GetAllControllersHealthStatus (
1124 IN OUT LIST_ENTRY
*DriverHealthList
1129 EFI_HANDLE
*DriverHealthHandles
;
1130 EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
;
1131 EFI_DRIVER_HEALTH_STATUS HealthStatus
;
1132 UINTN DriverHealthIndex
;
1133 EFI_HANDLE
*Handles
;
1135 UINTN ControllerIndex
;
1139 // Initialize local variables
1142 DriverHealthHandles
= NULL
;
1146 HealthStatus
= EfiDriverHealthStatusHealthy
;
1148 Status
= gBS
->LocateHandleBuffer (
1150 &gEfiDriverHealthProtocolGuid
,
1153 &DriverHealthHandles
1156 if (Status
== EFI_NOT_FOUND
|| NumHandles
== 0) {
1158 // If there are no Driver Health Protocols handles, then return EFI_NOT_FOUND
1160 return EFI_NOT_FOUND
;
1163 if (EFI_ERROR (Status
) || DriverHealthHandles
== NULL
) {
1165 // If the list of Driver Health Protocol handles can not be retrieved, then
1166 // return EFI_OUT_OF_RESOURCES
1168 return EFI_OUT_OF_RESOURCES
;
1172 // Check the health status of all controllers in the platform
1173 // Start by looping through all the Driver Health Protocol handles in the handle database
1175 for (DriverHealthIndex
= 0; DriverHealthIndex
< NumHandles
; DriverHealthIndex
++) {
1177 // Skip NULL Driver Health Protocol handles
1179 if (DriverHealthHandles
[DriverHealthIndex
] == NULL
) {
1184 // Retrieve the Driver Health Protocol from DriverHandle
1186 Status
= gBS
->HandleProtocol (
1187 DriverHealthHandles
[DriverHealthIndex
],
1188 &gEfiDriverHealthProtocolGuid
,
1189 (VOID
**)&DriverHealth
1191 if (EFI_ERROR (Status
)) {
1193 // If the Driver Health Protocol can not be retrieved, then skip to the next
1194 // Driver Health Protocol handle
1200 // Check the health of all the controllers managed by a Driver Health Protocol handle
1202 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], NULL
, NULL
, DriverHealth
, &HealthStatus
);
1205 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1206 // and skip to the next Driver Health Protocol handle
1208 if (EFI_ERROR (Status
)) {
1213 // If all the controllers managed by this Driver Health Protocol are healthy, then skip to the next
1214 // Driver Health Protocol handle
1216 if (HealthStatus
== EfiDriverHealthStatusHealthy
) {
1221 // See if the list of all handles in the handle database has been retrieved
1224 if (Handles
== NULL
) {
1226 // Retrieve the list of all handles from the handle database
1228 Status
= gBS
->LocateHandleBuffer (
1235 if (EFI_ERROR (Status
) || Handles
== NULL
) {
1237 // If all the handles in the handle database can not be retrieved, then
1238 // return EFI_OUT_OF_RESOURCES
1240 Status
= EFI_OUT_OF_RESOURCES
;
1245 // Loop through all the controller handles in the handle database
1247 for (ControllerIndex
= 0; ControllerIndex
< HandleCount
; ControllerIndex
++) {
1249 // Skip NULL controller handles
1251 if (Handles
[ControllerIndex
] == NULL
) {
1255 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], Handles
[ControllerIndex
], NULL
, DriverHealth
, &HealthStatus
);
1256 if (EFI_ERROR (Status
)) {
1258 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1260 HealthStatus
= EfiDriverHealthStatusHealthy
;
1264 // If CheckHealthSingleController() returned an error on a terminal state, then do not check the health of child controllers
1266 if (EFI_ERROR (Status
)) {
1271 // Loop through all the child handles in the handle database
1273 for (ChildIndex
= 0; ChildIndex
< HandleCount
; ChildIndex
++) {
1275 // Skip NULL child handles
1277 if (Handles
[ChildIndex
] == NULL
) {
1281 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], Handles
[ControllerIndex
], Handles
[ChildIndex
], DriverHealth
, &HealthStatus
);
1282 if (EFI_ERROR (Status
)) {
1284 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1286 HealthStatus
= EfiDriverHealthStatusHealthy
;
1290 // If CheckHealthSingleController() returned an error on a terminal state, then skip to the next child
1292 if (EFI_ERROR (Status
)) {
1299 Status
= EFI_SUCCESS
;
1302 if (Handles
!= NULL
) {
1303 gBS
->FreePool (Handles
);
1305 if (DriverHealthHandles
!= NULL
) {
1306 gBS
->FreePool (DriverHealthHandles
);
1314 Check the healthy status of the platform, this function will return immediately while found one driver
1315 in the platform are not healthy.
1317 @retval FALSE at least one driver in the platform are not healthy.
1318 @retval TRUE No controller install Driver Health Protocol,
1319 or all controllers in the platform are in healthy status.
1322 PlaformHealthStatusCheck (
1326 EFI_DRIVER_HEALTH_STATUS HealthStatus
;
1330 EFI_HANDLE
*DriverHealthHandles
;
1331 EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
;
1335 // Initialize local variables
1337 DriverHealthHandles
= NULL
;
1338 DriverHealth
= NULL
;
1340 HealthStatus
= EfiDriverHealthStatusHealthy
;
1342 Status
= gBS
->LocateHandleBuffer (
1344 &gEfiDriverHealthProtocolGuid
,
1347 &DriverHealthHandles
1350 // There are no handles match the search for Driver Health Protocol has been installed.
1352 if (Status
== EFI_NOT_FOUND
) {
1356 // Assume all modules are healthy.
1361 // Found one or more Handles.
1363 if (!EFI_ERROR (Status
)) {
1364 for (Index
= 0; Index
< NoHandles
; Index
++) {
1365 Status
= gBS
->HandleProtocol (
1366 DriverHealthHandles
[Index
],
1367 &gEfiDriverHealthProtocolGuid
,
1368 (VOID
**) &DriverHealth
1370 if (!EFI_ERROR (Status
)) {
1371 Status
= DriverHealth
->GetHealthStatus (
1381 // Get the healthy status of the module
1383 if (!EFI_ERROR (Status
)) {
1384 if (HealthStatus
!= EfiDriverHealthStatusHealthy
) {
1386 // Return immediately one driver's status not in healthy.
1397 Processes a single controller using the EFI Driver Health Protocol associated with
1398 that controller. This algorithm continues to query the GetHealthStatus() service until
1399 one of the legal terminal states of the EFI Driver Health Protocol is reached. This may
1400 require the processing of HII Messages, HII Form, and invocation of repair operations.
1402 @param DriverHealth A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
1403 @param ControllerHandle The class guid specifies which form set will be displayed.
1404 @param ChildHandle The handle of the child controller to retrieve the health
1405 status on. This is an optional parameter that may be NULL.
1406 @param HealthStatus The health status of the controller.
1407 @param MessageList An array of warning or error messages associated
1408 with the controller specified by ControllerHandle and
1409 ChildHandle. This is an optional parameter that may be NULL.
1410 @param FormHiiHandle The HII handle for an HII form associated with the
1411 controller specified by ControllerHandle and ChildHandle.
1414 ProcessSingleControllerHealth (
1415 IN EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
,
1416 IN EFI_HANDLE ControllerHandle
, OPTIONAL
1417 IN EFI_HANDLE ChildHandle
, OPTIONAL
1418 IN EFI_DRIVER_HEALTH_STATUS HealthStatus
,
1419 IN EFI_DRIVER_HEALTH_HII_MESSAGE
**MessageList
, OPTIONAL
1420 IN EFI_HII_HANDLE FormHiiHandle
1424 EFI_DRIVER_HEALTH_STATUS LocalHealthStatus
;
1426 LocalHealthStatus
= HealthStatus
;
1428 // If the module need to be repaired or reconfiguration, will process it until
1429 // reach a terminal status. The status from EfiDriverHealthStatusRepairRequired after repair
1430 // will be in (Health, Failed, Configuration Required).
1432 while( LocalHealthStatus
== EfiDriverHealthStatusConfigurationRequired
||
1433 LocalHealthStatus
== EfiDriverHealthStatusRepairRequired
) {
1435 if (LocalHealthStatus
== EfiDriverHealthStatusRepairRequired
) {
1436 Status
= DriverHealth
->Repair (
1440 (EFI_DRIVER_HEALTH_REPAIR_PROGRESS_NOTIFY
) RepairNotify
1444 // Via a form of the driver need to do configuration provided to process of status in
1445 // EfiDriverHealthStatusConfigurationRequired. The status after configuration should be in
1446 // (Healthy, Reboot Required, Failed, Reconnect Required, Repair Required).
1448 if (LocalHealthStatus
== EfiDriverHealthStatusConfigurationRequired
) {
1449 Status
= gFormBrowser2
->SendForm (
1453 &gEfiHiiDriverHealthFormsetGuid
,
1458 ASSERT( !EFI_ERROR (Status
));
1461 Status
= DriverHealth
->GetHealthStatus (
1469 ASSERT_EFI_ERROR (Status
);
1471 if (*MessageList
!= NULL
) {
1472 ProcessMessages (*MessageList
);
1477 // Health status in {Healthy, Failed} may also have Messages need to process
1479 if (LocalHealthStatus
== EfiDriverHealthStatusHealthy
|| LocalHealthStatus
== EfiDriverHealthStatusFailed
) {
1480 if (*MessageList
!= NULL
) {
1481 ProcessMessages (*MessageList
);
1485 // Check for RebootRequired or ReconnectRequired
1487 if (LocalHealthStatus
== EfiDriverHealthStatusRebootRequired
) {
1488 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1492 // Do reconnect if need.
1494 if (LocalHealthStatus
== EfiDriverHealthStatusReconnectRequired
) {
1495 Status
= gBS
->DisconnectController (ControllerHandle
, NULL
, NULL
);
1496 if (EFI_ERROR (Status
)) {
1498 // Disconnect failed. Need to promote reconnect to a reboot.
1500 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1502 gBS
->ConnectController (ControllerHandle
, NULL
, NULL
, TRUE
);
1508 Platform specific notification function for controller repair operations.
1510 If the driver for a controller support the Driver Health Protocol and the
1511 current state of the controller is EfiDriverHealthStatusRepairRequired then
1512 when the Repair() service of the Driver Health Protocol is called, this
1513 platform specific notification function can display the progress of the repair
1514 operation. Some platforms may choose to not display anything, other may choose
1515 to show the percentage complete on text consoles, and other may choose to render
1516 a progress bar on text and graphical consoles.
1518 This function displays the percentage of the repair operation that has been
1519 completed on text consoles. The percentage is Value / Limit * 100%.
1521 @param Value Value in the range 0..Limit the the repair has completed..
1522 @param Limit The maximum value of Value
1534 Print(L
"Repair Progress Undefined\n\r");
1536 Percent
= Value
* 100 / Limit
;
1537 Print(L
"Repair Progress = %3d%%\n\r", Percent
);
1542 Processes a set of messages returned by the GetHealthStatus ()
1543 service of the EFI Driver Health Protocol
1545 @param MessageList The MessageList point to messages need to processed.
1550 IN EFI_DRIVER_HEALTH_HII_MESSAGE
*MessageList
1554 EFI_STRING MessageString
;
1556 for (MessageIndex
= 0;
1557 MessageList
[MessageIndex
].HiiHandle
!= NULL
;
1560 MessageString
= HiiGetString (
1561 MessageList
[MessageIndex
].HiiHandle
,
1562 MessageList
[MessageIndex
].StringId
,
1565 if (MessageString
!= NULL
) {
1567 // User can customize the output. Just simply print out the MessageString like below.
1568 // Also can use the HiiHandle to display message on the front page.
1570 // Print(L"%s\n",MessageString);
1571 // gBS->Stall (100000);
1578 Repair the whole platform.
1580 This function is the main entry for user choose "Repair All" in the front page.
1581 It will try to do recovery job till all the driver health protocol installed modules
1582 reach a terminal state.
1584 @param DriverHealthList A Pointer to the list contain all of the platform driver health
1590 IN LIST_ENTRY
*DriverHealthList
1593 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
1596 ASSERT (DriverHealthList
!= NULL
);
1598 Link
= GetFirstNode (DriverHealthList
);
1600 while (!IsNull (DriverHealthList
, Link
)) {
1601 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
1603 // Do driver health status operation by each link node
1605 ASSERT (DriverHealthInfo
!= NULL
);
1607 ProcessSingleControllerHealth (
1608 DriverHealthInfo
->DriverHealth
,
1609 DriverHealthInfo
->ControllerHandle
,
1610 DriverHealthInfo
->ChildHandle
,
1611 DriverHealthInfo
->HealthStatus
,
1612 &(DriverHealthInfo
->MessageList
),
1613 DriverHealthInfo
->HiiHandle
1616 Link
= GetNextNode (DriverHealthList
, Link
);
1622 Select the best matching language according to front page policy for best user experience.
1624 This function supports both ISO 639-2 and RFC 4646 language codes, but language
1625 code types may not be mixed in a single call to this function.
1627 @param SupportedLanguages A pointer to a Null-terminated ASCII string that
1628 contains a set of language codes in the format
1629 specified by Iso639Language.
1630 @param Iso639Language If TRUE, then all language codes are assumed to be
1631 in ISO 639-2 format. If FALSE, then all language
1632 codes are assumed to be in RFC 4646 language format.
1634 @retval NULL The best matching language could not be found in SupportedLanguages.
1635 @retval NULL There are not enough resources available to return the best matching
1637 @retval Other A pointer to a Null-terminated ASCII string that is the best matching
1638 language in SupportedLanguages.
1641 DriverHealthSelectBestLanguage (
1642 IN CHAR8
*SupportedLanguages
,
1643 IN BOOLEAN Iso639Language
1646 CHAR8
*LanguageVariable
;
1647 CHAR8
*BestLanguage
;
1649 LanguageVariable
= GetEfiGlobalVariable (Iso639Language
? L
"Lang" : L
"PlatformLang");
1651 BestLanguage
= GetBestLanguage(
1654 (LanguageVariable
!= NULL
) ? LanguageVariable
: "",
1655 Iso639Language
? "eng" : "en-US",
1658 if (LanguageVariable
!= NULL
) {
1659 FreePool (LanguageVariable
);
1662 return BestLanguage
;
1669 This is an internal worker function to get the Component Name (2) protocol interface
1670 and the language it supports.
1672 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
1673 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1674 @param ComponentName A pointer to the Component Name (2) protocol interface.
1675 @param SupportedLanguage The best suitable language that matches the SupportedLangues interface for the
1676 located Component Name (2) instance.
1678 @retval EFI_SUCCESS The Component Name (2) protocol instance is successfully located and we find
1679 the best matching language it support.
1680 @retval EFI_UNSUPPORTED The input Language is not supported by the Component Name (2) protocol.
1681 @retval Other Some error occurs when locating Component Name (2) protocol instance or finding
1682 the supported language.
1686 GetComponentNameWorker (
1687 IN EFI_GUID
*ProtocolGuid
,
1688 IN EFI_HANDLE DriverBindingHandle
,
1689 OUT EFI_COMPONENT_NAME_PROTOCOL
**ComponentName
,
1690 OUT CHAR8
**SupportedLanguage
1696 // Locate Component Name (2) protocol on the driver binging handle.
1698 Status
= gBS
->OpenProtocol (
1699 DriverBindingHandle
,
1701 (VOID
**) ComponentName
,
1704 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1706 if (EFI_ERROR (Status
)) {
1711 // Apply shell policy to select the best language.
1713 *SupportedLanguage
= DriverHealthSelectBestLanguage (
1714 (*ComponentName
)->SupportedLanguages
,
1715 (BOOLEAN
) (ProtocolGuid
== &gEfiComponentNameProtocolGuid
)
1717 if (*SupportedLanguage
== NULL
) {
1718 Status
= EFI_UNSUPPORTED
;
1726 This is an internal worker function to get driver name from Component Name (2) protocol interface.
1729 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
1730 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1731 @param DriverName A pointer to the Unicode string to return. This Unicode string is the name
1732 of the driver specified by This.
1734 @retval EFI_SUCCESS The driver name is successfully retrieved from Component Name (2) protocol
1736 @retval Other The driver name cannot be retrieved from Component Name (2) protocol
1741 GetDriverNameWorker (
1742 IN EFI_GUID
*ProtocolGuid
,
1743 IN EFI_HANDLE DriverBindingHandle
,
1744 OUT CHAR16
**DriverName
1748 CHAR8
*BestLanguage
;
1749 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
1752 // Retrieve Component Name (2) protocol instance on the driver binding handle and
1753 // find the best language this instance supports.
1755 Status
= GetComponentNameWorker (
1757 DriverBindingHandle
,
1761 if (EFI_ERROR (Status
)) {
1766 // Get the driver name from Component Name (2) protocol instance on the driver binging handle.
1768 Status
= ComponentName
->GetDriverName (
1773 FreePool (BestLanguage
);
1780 This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface
1781 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name.
1782 If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward
1783 compatibility support.
1785 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1786 @param DriverName A pointer to the Unicode string to return. This Unicode string is the name
1787 of the driver specified by This.
1789 @retval EFI_SUCCESS The driver name is successfully retrieved from Component Name (2) protocol
1791 @retval Other The driver name cannot be retrieved from Component Name (2) protocol
1796 DriverHealthGetDriverName (
1797 IN EFI_HANDLE DriverBindingHandle
,
1798 OUT CHAR16
**DriverName
1804 // Get driver name from UEFI 2.0 Component Name 2 protocol interface.
1806 Status
= GetDriverNameWorker (&gEfiComponentName2ProtocolGuid
, DriverBindingHandle
, DriverName
);
1807 if (EFI_ERROR (Status
)) {
1809 // If it fails to get the driver name from Component Name protocol interface, we should fall back on
1810 // EFI 1.1 Component Name protocol interface.
1812 Status
= GetDriverNameWorker (&gEfiComponentNameProtocolGuid
, DriverBindingHandle
, DriverName
);
1821 This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
1822 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
1823 If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
1824 compatibility support.
1826 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
1827 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1828 @param ControllerHandle The handle of a controller that the driver specified by This is managing.
1829 This handle specifies the controller whose name is to be returned.
1830 @param ChildHandle The handle of the child controller to retrieve the name of. This is an
1831 optional parameter that may be NULL. It will be NULL for device drivers.
1832 It will also be NULL for bus drivers that attempt to retrieve the name
1833 of the bus controller. It will not be NULL for a bus driver that attempts
1834 to retrieve the name of a child controller.
1835 @param ControllerName A pointer to the Unicode string to return. This Unicode string
1836 is the name of the controller specified by ControllerHandle and ChildHandle.
1838 @retval EFI_SUCCESS The controller name is successfully retrieved from Component Name (2) protocol
1840 @retval Other The controller name cannot be retrieved from Component Name (2) protocol.
1844 GetControllerNameWorker (
1845 IN EFI_GUID
*ProtocolGuid
,
1846 IN EFI_HANDLE DriverBindingHandle
,
1847 IN EFI_HANDLE ControllerHandle
,
1848 IN EFI_HANDLE ChildHandle
,
1849 OUT CHAR16
**ControllerName
1853 CHAR8
*BestLanguage
;
1854 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
1857 // Retrieve Component Name (2) protocol instance on the driver binding handle and
1858 // find the best language this instance supports.
1860 Status
= GetComponentNameWorker (
1862 DriverBindingHandle
,
1866 if (EFI_ERROR (Status
)) {
1871 // Get the controller name from Component Name (2) protocol instance on the driver binging handle.
1873 Status
= ComponentName
->GetControllerName (
1880 FreePool (BestLanguage
);
1887 This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
1888 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
1889 If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
1890 compatibility support.
1892 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1893 @param ControllerHandle The handle of a controller that the driver specified by This is managing.
1894 This handle specifies the controller whose name is to be returned.
1895 @param ChildHandle The handle of the child controller to retrieve the name of. This is an
1896 optional parameter that may be NULL. It will be NULL for device drivers.
1897 It will also be NULL for bus drivers that attempt to retrieve the name
1898 of the bus controller. It will not be NULL for a bus driver that attempts
1899 to retrieve the name of a child controller.
1900 @param ControllerName A pointer to the Unicode string to return. This Unicode string
1901 is the name of the controller specified by ControllerHandle and ChildHandle.
1903 @retval EFI_SUCCESS The controller name is successfully retrieved from Component Name (2) protocol
1905 @retval Other The controller name cannot be retrieved from Component Name (2) protocol.
1909 DriverHealthGetControllerName (
1910 IN EFI_HANDLE DriverBindingHandle
,
1911 IN EFI_HANDLE ControllerHandle
,
1912 IN EFI_HANDLE ChildHandle
,
1913 OUT CHAR16
**ControllerName
1919 // Get controller name from UEFI 2.0 Component Name 2 protocol interface.
1921 Status
= GetControllerNameWorker (
1922 &gEfiComponentName2ProtocolGuid
,
1923 DriverBindingHandle
,
1928 if (EFI_ERROR (Status
)) {
1930 // If it fails to get the controller name from Component Name protocol interface, we should fall back on
1931 // EFI 1.1 Component Name protocol interface.
1933 Status
= GetControllerNameWorker (
1934 &gEfiComponentNameProtocolGuid
,
1935 DriverBindingHandle
,