2 The platform device manager reference implementation
4 Copyright (c) 2004 - 2009, 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)
73 This function is invoked if user selected a interactive opcode from Device Manager's
74 Formset. The decision by user is saved to gCallbackKey for later processing. If
75 user set VBIOS, the new value is saved to EFI variable.
77 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
78 @param Action Specifies the type of action taken by the browser.
79 @param QuestionId A unique value which is sent to the original exporting driver
80 so that it can identify the type of data to expect.
81 @param Type The type of value for the question.
82 @param Value A pointer to the data being sent to the original exporting driver.
83 @param ActionRequest On return, points to the action requested by the callback function.
85 @retval EFI_SUCCESS The callback successfully handled the action.
86 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
91 DeviceManagerCallback (
92 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
93 IN EFI_BROWSER_ACTION Action
,
94 IN EFI_QUESTION_ID QuestionId
,
96 IN EFI_IFR_TYPE_VALUE
*Value
,
97 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
100 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
101 return EFI_INVALID_PARAMETER
;
104 gCallbackKey
= QuestionId
;
107 // Request to exit SendForm(), so as to switch to selected form
109 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
116 This function registers HII packages to HII database.
118 @retval EFI_SUCCESS HII packages for the Device Manager were registered successfully.
119 @retval EFI_OUT_OF_RESOURCES HII packages for the Device Manager failed to be registered.
123 InitializeDeviceManager (
130 // Install Device Path Protocol and Config Access protocol to driver handle
132 Status
= gBS
->InstallMultipleProtocolInterfaces (
133 &gDeviceManagerPrivate
.DriverHandle
,
134 &gEfiDevicePathProtocolGuid
,
135 &mDeviceManagerHiiVendorDevicePath
,
136 &gEfiHiiConfigAccessProtocolGuid
,
137 &gDeviceManagerPrivate
.ConfigAccess
,
140 ASSERT_EFI_ERROR (Status
);
142 Status
= gBS
->InstallMultipleProtocolInterfaces (
143 &gDeviceManagerPrivate
.DriverHealthHandle
,
144 &gEfiHiiConfigAccessProtocolGuid
,
145 &gDeviceManagerPrivate
.DriverHealthConfigAccess
,
148 ASSERT_EFI_ERROR (Status
);
151 // Publish our HII data
153 gDeviceManagerPrivate
.HiiHandle
= HiiAddPackages (
155 gDeviceManagerPrivate
.DriverHandle
,
160 if (gDeviceManagerPrivate
.HiiHandle
== NULL
) {
161 return EFI_OUT_OF_RESOURCES
;
163 Status
= EFI_SUCCESS
;
167 // Publish Driver Health HII data
169 gDeviceManagerPrivate
.DriverHealthHiiHandle
= HiiAddPackages (
171 gDeviceManagerPrivate
.DriverHealthHandle
,
176 if (gDeviceManagerPrivate
.DriverHealthHiiHandle
== NULL
) {
177 Status
= EFI_OUT_OF_RESOURCES
;
179 Status
= EFI_SUCCESS
;
186 Extract the displayed formset for given HII handle and class guid.
188 @param Handle The HII handle.
189 @param SetupClassGuid The class guid specifies which form set will be displayed.
190 @param FormSetTitle Formset title string.
191 @param FormSetHelp Formset help string.
193 @retval TRUE The formset for given HII handle will be displayed.
194 @return FALSE The formset for given HII handle will not be displayed.
198 ExtractDisplayedHiiFormFromHiiHandle (
199 IN EFI_HII_HANDLE Handle
,
200 IN EFI_GUID
*SetupClassGuid
,
201 OUT EFI_STRING_ID
*FormSetTitle
,
202 OUT EFI_STRING_ID
*FormSetHelp
207 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
212 UINT32 PackageListLength
;
213 EFI_HII_PACKAGE_HEADER PackageHeader
;
217 ASSERT (Handle
!= NULL
);
218 ASSERT (SetupClassGuid
!= NULL
);
219 ASSERT (FormSetTitle
!= NULL
);
220 ASSERT (FormSetHelp
!= NULL
);
228 // Get HII PackageList
231 HiiPackageList
= NULL
;
232 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
234 // Handle is a invalid handle. Check if Handle is corrupted.
236 ASSERT (Status
!= EFI_NOT_FOUND
);
238 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
240 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
242 HiiPackageList
= AllocatePool (BufferSize
);
243 ASSERT (HiiPackageList
!= NULL
);
245 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
246 if (EFI_ERROR (Status
)) {
251 // Get Form package from this HII package List
253 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
255 PackageListLength
= ReadUnaligned32 (&HiiPackageList
->PackageLength
);
257 while (Offset
< PackageListLength
) {
258 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
259 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
261 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
263 // Search FormSet Opcode in this Form Package
265 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
266 while (Offset2
< PackageHeader
.Length
) {
267 OpCodeData
= Package
+ Offset2
;
269 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
271 // Find FormSet OpCode
273 ClassGuidNum
= ((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
;
274 ClassGuid
= (EFI_GUID
*) (VOID
*)(OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
275 while (ClassGuidNum
-- > 0) {
276 if (CompareGuid (SetupClassGuid
, ClassGuid
)) {
277 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
278 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
279 FreePool (HiiPackageList
);
288 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
293 // Go to next package
295 Offset
+= PackageHeader
.Length
;
298 FreePool (HiiPackageList
);
304 Call the browser and display the device manager to allow user
305 to configure the platform.
307 This function create the dynamic content for device manager. It includes
308 section header for all class of devices, one-of opcode to set VBIOS.
310 @retval EFI_SUCCESS Operation is successful.
311 @return Other values if failed to clean up the dynamic content from HII
324 EFI_STRING_ID TokenHelp
;
325 EFI_HII_HANDLE
*HiiHandles
;
326 EFI_HII_HANDLE HiiHandle
;
327 EFI_STRING_ID FormSetTitle
;
328 EFI_STRING_ID FormSetHelp
;
329 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
330 VOID
*StartOpCodeHandle
;
331 VOID
*EndOpCodeHandle
;
332 EFI_IFR_GUID_LABEL
*StartLabel
;
333 EFI_IFR_GUID_LABEL
*EndLabel
;
335 EFI_HANDLE
*DriverHealthHandles
;
338 Status
= EFI_SUCCESS
;
341 DriverHealthHandles
= NULL
;
344 // Connect all prior to entering the platform setup menu.
346 if (!gConnectAllHappened
) {
347 BdsLibConnectAllDriversToAllControllers ();
348 gConnectAllHappened
= TRUE
;
351 // Create Subtitle OpCodes
354 // Allocate space for creation of UpdateData Buffer
356 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
357 ASSERT (StartOpCodeHandle
!= NULL
);
359 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
360 ASSERT (EndOpCodeHandle
!= NULL
);
363 // Create Hii Extend Label OpCode as the start opcode
365 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
366 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
367 StartLabel
->Number
= LABEL_DEVICES_LIST
;
370 // Create Hii Extend Label OpCode as the end opcode
372 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
373 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
374 EndLabel
->Number
= LABEL_END
;
376 HiiCreateSubTitleOpCode (StartOpCodeHandle
, STRING_TOKEN (STR_DEVICES_LIST
), 0, 0, 1);
379 // Get all the Hii handles
381 HiiHandles
= HiiGetHiiHandles (NULL
);
382 ASSERT (HiiHandles
!= NULL
);
384 HiiHandle
= gDeviceManagerPrivate
.HiiHandle
;
387 // Search for formset of each class type
389 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
390 if (!ExtractDisplayedHiiFormFromHiiHandle (HiiHandles
[Index
], &gEfiHiiPlatformSetupFormsetGuid
, &FormSetTitle
, &FormSetHelp
)) {
394 String
= HiiGetString (HiiHandles
[Index
], FormSetTitle
, NULL
);
395 if (String
== NULL
) {
396 String
= HiiGetString (HiiHandle
, STR_MISSING_STRING
, NULL
);
397 ASSERT (String
!= NULL
);
399 Token
= HiiSetString (HiiHandle
, 0, String
, NULL
);
402 String
= HiiGetString (HiiHandles
[Index
], FormSetHelp
, NULL
);
403 if (String
== NULL
) {
404 String
= HiiGetString (HiiHandle
, STR_MISSING_STRING
, NULL
);
405 ASSERT (String
!= NULL
);
407 TokenHelp
= HiiSetString (HiiHandle
, 0, String
, NULL
);
410 HiiCreateActionOpCode (
412 (EFI_QUESTION_ID
) (Index
+ DEVICE_KEY_OFFSET
),
415 EFI_IFR_FLAG_CALLBACK
,
421 // Add End Opcode for Subtitle
423 HiiCreateEndOpCode (StartOpCodeHandle
);
425 Status
= gBS
->LocateHandleBuffer (
427 &gEfiDriverHealthProtocolGuid
,
433 // If there are no drivers installed driver health protocol
435 if (NumHandles
== 0) {
436 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DM_DRIVER_HEALTH_TITLE
), GetStringById (STRING_TOKEN (STR_EMPTY_STRING
)), NULL
);
437 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
), GetStringById (STRING_TOKEN (STR_EMPTY_STRING
)), NULL
);
440 // Check All Driver health status
442 if (!PlaformHealthStatusCheck ()) {
444 // At least one driver in the platform are not in healthy status
446 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
), GetStringById (STRING_TOKEN (STR_DRIVER_NOT_HEALTH
)), NULL
);
449 // For the string of STR_DRIVER_HEALTH_ALL_HEALTHY previously has been updated and we need to update it while re-entry.
451 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
), GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
)), NULL
);
458 DEVICE_MANAGER_FORM_ID
,
463 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
464 Status
= gFormBrowser2
->SendForm (
473 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
474 EnableResetRequired ();
478 // We will have returned from processing a callback - user either hit ESC to exit, or selected
479 // a target to display
481 if ((gCallbackKey
!= 0) && (gCallbackKey
!= DEVICE_MANAGER_KEY_DRIVER_HEALTH
)) {
482 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
483 Status
= gFormBrowser2
->SendForm (
485 &HiiHandles
[gCallbackKey
- DEVICE_KEY_OFFSET
],
493 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
494 EnableResetRequired ();
498 // Force return to Device Manager
500 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
504 // Driver Health item chose.
506 if (gCallbackKey
== DEVICE_MANAGER_KEY_DRIVER_HEALTH
) {
511 // Cleanup dynamic created strings in HII database by reinstall the packagelist
513 HiiRemovePackages (HiiHandle
);
515 gDeviceManagerPrivate
.HiiHandle
= HiiAddPackages (
517 gDeviceManagerPrivate
.DriverHandle
,
522 if (gDeviceManagerPrivate
.HiiHandle
== NULL
) {
523 Status
= EFI_OUT_OF_RESOURCES
;
525 Status
= EFI_SUCCESS
;
528 HiiFreeOpCodeHandle (StartOpCodeHandle
);
529 HiiFreeOpCodeHandle (EndOpCodeHandle
);
530 FreePool (HiiHandles
);
536 This function is invoked if user selected a interactive opcode from Driver Health's
537 Formset. The decision by user is saved to gCallbackKey for later processing.
539 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
540 @param Action Specifies the type of action taken by the browser.
541 @param QuestionId A unique value which is sent to the original exporting driver
542 so that it can identify the type of data to expect.
543 @param Type The type of value for the question.
544 @param Value A pointer to the data being sent to the original exporting driver.
545 @param ActionRequest On return, points to the action requested by the callback function.
547 @retval EFI_SUCCESS The callback successfully handled the action.
548 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
553 DriverHealthCallback (
554 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
555 IN EFI_BROWSER_ACTION Action
,
556 IN EFI_QUESTION_ID QuestionId
,
558 IN EFI_IFR_TYPE_VALUE
*Value
,
559 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
562 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
563 return EFI_INVALID_PARAMETER
;
566 gCallbackKey
= QuestionId
;
569 // Request to exit SendForm(), so as to switch to selected form
571 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
577 Collect and display the platform's driver health relative information, allow user to do interactive
578 operation while the platform is unhealthy.
580 This function display a form which divided into two parts. The one list all modules which has installed
581 driver health protocol. The list usually contain driver name, controller name, and it's health info.
582 While the driver name can't be retrieved, will use device path as backup. The other part of the form provide
583 a choice to the user to repair all platform.
592 EFI_HII_HANDLE HiiHandle
;
593 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
594 EFI_IFR_GUID_LABEL
*StartLabel
;
595 EFI_IFR_GUID_LABEL
*StartLabelRepair
;
596 EFI_IFR_GUID_LABEL
*EndLabel
;
597 EFI_IFR_GUID_LABEL
*EndLabelRepair
;
598 VOID
*StartOpCodeHandle
;
599 VOID
*EndOpCodeHandle
;
600 VOID
*StartOpCodeHandleRepair
;
601 VOID
*EndOpCodeHandleRepair
;
604 EFI_STRING_ID TokenHelp
;
606 EFI_STRING TmpString
;
607 EFI_STRING DriverName
;
608 EFI_STRING ControllerName
;
609 LIST_ENTRY DriverHealthList
;
610 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
612 EFI_DEVICE_PATH_PROTOCOL
*DriverDevicePath
;
615 HiiHandle
= gDeviceManagerPrivate
.DriverHealthHiiHandle
;
618 DriverHealthInfo
= NULL
;
619 DriverDevicePath
= NULL
;
620 InitializeListHead (&DriverHealthList
);
623 // Allocate space for creation of UpdateData Buffer
625 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
626 ASSERT (StartOpCodeHandle
!= NULL
);
628 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
629 ASSERT (EndOpCodeHandle
!= NULL
);
631 StartOpCodeHandleRepair
= HiiAllocateOpCodeHandle ();
632 ASSERT (StartOpCodeHandleRepair
!= NULL
);
634 EndOpCodeHandleRepair
= HiiAllocateOpCodeHandle ();
635 ASSERT (EndOpCodeHandleRepair
!= NULL
);
638 // Create Hii Extend Label OpCode as the start opcode
640 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
641 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
642 StartLabel
->Number
= LABEL_DRIVER_HEALTH
;
645 // Create Hii Extend Label OpCode as the start opcode
647 StartLabelRepair
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandleRepair
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
648 StartLabelRepair
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
649 StartLabelRepair
->Number
= LABEL_DRIVER_HEALTH_REAPIR_ALL
;
652 // Create Hii Extend Label OpCode as the end opcode
654 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
655 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
656 EndLabel
->Number
= LABEL_DRIVER_HEALTH_END
;
659 // Create Hii Extend Label OpCode as the end opcode
661 EndLabelRepair
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandleRepair
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
662 EndLabelRepair
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
663 EndLabelRepair
->Number
= LABEL_DRIVER_HEALTH_REAPIR_ALL_END
;
665 HiiCreateSubTitleOpCode (StartOpCodeHandle
, STRING_TOKEN (STR_DH_STATUS_LIST
), 0, 0, 1);
667 Status
= GetAllControllersHealthStatus (&DriverHealthList
);
668 ASSERT (Status
!= EFI_OUT_OF_RESOURCES
);
670 Link
= GetFirstNode (&DriverHealthList
);
672 while (!IsNull (&DriverHealthList
, Link
)) {
673 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
676 // Assume no line strings is longer than 512 bytes.
678 String
= (EFI_STRING
) AllocateZeroPool (0x200);
679 ASSERT (String
!= NULL
);
681 Status
= DriverHealthGetDriverName (DriverHealthInfo
->DriverHandle
, &DriverName
);
682 if (EFI_ERROR (Status
)) {
684 // Can not get the Driver name, so use the Device path
686 DriverDevicePath
= DevicePathFromHandle (DriverHealthInfo
->DriverHandle
);
687 DriverName
= DevicePathToStr (DriverDevicePath
);
690 // Add the Driver name & Controller name into FormSetTitle string
692 StrnCat (String
, DriverName
, StrLen (DriverName
));
695 Status
= DriverHealthGetControllerName (
696 DriverHealthInfo
->DriverHandle
,
697 DriverHealthInfo
->ControllerHandle
,
698 DriverHealthInfo
->ChildHandle
,
702 if (!EFI_ERROR (Status
)) {
704 // Can not get the Controller name, just let it empty.
706 StrnCat (String
, L
" ", StrLen (L
" "));
707 StrnCat (String
, ControllerName
, StrLen (ControllerName
));
711 // Add the message of the Module itself provided after the string item.
713 if ((DriverHealthInfo
->MessageList
!= NULL
) && (DriverHealthInfo
->MessageList
->StringId
!= 0)) {
714 StrnCat (String
, L
" ", StrLen (L
" "));
715 TmpString
= HiiGetString (
716 DriverHealthInfo
->MessageList
->HiiHandle
,
717 DriverHealthInfo
->MessageList
->StringId
,
721 // Assert if can not retrieve the message string
723 ASSERT (TmpString
!= NULL
);
724 StrnCat (String
, TmpString
, StrLen (TmpString
));
725 FreePool (TmpString
);
728 // Update the string will be displayed base on the driver's health status
730 switch(DriverHealthInfo
->HealthStatus
) {
731 case EfiDriverHealthStatusRepairRequired
:
732 Length
= StrLen (GetStringById (STRING_TOKEN (STR_REPAIR_REQUIRED
)));
733 StrnCat (String
, GetStringById (STRING_TOKEN (STR_REPAIR_REQUIRED
)), Length
);
735 case EfiDriverHealthStatusConfigurationRequired
:
736 Length
= StrLen (GetStringById (STRING_TOKEN (STR_CONFIGURATION_REQUIRED
)));
737 StrnCat (String
, GetStringById (STRING_TOKEN (STR_CONFIGURATION_REQUIRED
)), Length
);
739 case EfiDriverHealthStatusFailed
:
740 Length
= StrLen (GetStringById (STRING_TOKEN (STR_OPERATION_FAILED
)));
741 StrnCat (String
, GetStringById (STRING_TOKEN (STR_OPERATION_FAILED
)), Length
);
743 case EfiDriverHealthStatusReconnectRequired
:
744 Length
= StrLen (GetStringById (STRING_TOKEN (STR_RECONNECT_REQUIRED
)));
745 StrnCat (String
, GetStringById (STRING_TOKEN (STR_RECONNECT_REQUIRED
)), Length
);
747 case EfiDriverHealthStatusRebootRequired
:
748 Length
= StrLen (GetStringById (STRING_TOKEN (STR_REBOOT_REQUIRED
)));
749 StrnCat (String
, GetStringById (STRING_TOKEN (STR_REBOOT_REQUIRED
)), Length
);
752 Length
= StrLen (GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_HEALTHY
)));
753 StrnCat (String
, GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_HEALTHY
)), Length
);
758 Token
= HiiSetString (HiiHandle
, 0, String
, NULL
);
761 TokenHelp
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_SINGLE_HELP
)), NULL
);
763 HiiCreateActionOpCode (
765 (EFI_QUESTION_ID
) (Index
+ DRIVER_HEALTH_KEY_OFFSET
),
768 EFI_IFR_FLAG_CALLBACK
,
772 Link
= GetNextNode (&DriverHealthList
, Link
);
776 // Add End Opcode for Subtitle
778 HiiCreateEndOpCode (StartOpCodeHandle
);
780 HiiCreateSubTitleOpCode (StartOpCodeHandleRepair
, STRING_TOKEN (STR_DRIVER_HEALTH_REPAIR_ALL
), 0, 0, 1);
781 TokenHelp
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_ALL_HELP
)), NULL
);
783 if (PlaformHealthStatusCheck ()) {
785 // No action need to do for the platform
787 Token
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
)), NULL
);
788 HiiCreateActionOpCode (
789 StartOpCodeHandleRepair
,
793 EFI_IFR_FLAG_READ_ONLY
,
798 // Create ActionOpCode only while the platform need to do health related operation.
800 Token
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_ALL_TITLE
)), NULL
);
801 HiiCreateActionOpCode (
802 StartOpCodeHandleRepair
,
803 (EFI_QUESTION_ID
) DRIVER_HEALTH_REPAIR_ALL_KEY
,
806 EFI_IFR_FLAG_CALLBACK
,
811 HiiCreateEndOpCode (StartOpCodeHandleRepair
);
813 Status
= HiiUpdateForm (
816 DRIVER_HEALTH_FORM_ID
,
820 ASSERT (Status
!= EFI_NOT_FOUND
);
821 ASSERT (Status
!= EFI_BUFFER_TOO_SMALL
);
823 Status
= HiiUpdateForm (
826 DRIVER_HEALTH_FORM_ID
,
827 StartOpCodeHandleRepair
,
828 EndOpCodeHandleRepair
830 ASSERT (Status
!= EFI_NOT_FOUND
);
831 ASSERT (Status
!= EFI_BUFFER_TOO_SMALL
);
833 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
834 Status
= gFormBrowser2
->SendForm (
839 DRIVER_HEALTH_FORM_ID
,
843 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
844 EnableResetRequired ();
848 // We will have returned from processing a callback - user either hit ESC to exit, or selected
849 // a target to display.
850 // Process the diver health status states here.
852 if (gCallbackKey
>= DRIVER_HEALTH_KEY_OFFSET
&& gCallbackKey
!= DRIVER_HEALTH_REPAIR_ALL_KEY
&& gCallbackKey
!= FRONT_PAGE_KEY_DEVICE_MANAGER
) {
853 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
855 Link
= GetFirstNode (&DriverHealthList
);
858 while (!IsNull (&DriverHealthList
, Link
)) {
860 // Got the item relative node in the List
862 if (Index
== (gCallbackKey
- DRIVER_HEALTH_KEY_OFFSET
)) {
863 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
865 // Process the driver's healthy status for the specify module
867 ProcessSingleControllerHealth (
868 DriverHealthInfo
->DriverHealth
,
869 DriverHealthInfo
->ControllerHandle
,
870 DriverHealthInfo
->ChildHandle
,
871 DriverHealthInfo
->HealthStatus
,
872 &(DriverHealthInfo
->MessageList
),
873 DriverHealthInfo
->HiiHandle
878 Link
= GetNextNode (&DriverHealthList
, Link
);
881 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
882 EnableResetRequired ();
886 // Force return to the form of Driver Health in Device Manager
888 gCallbackKey
= DRIVER_HEALTH_RETURN_KEY
;
892 // Repair the whole platform
894 if (gCallbackKey
== DRIVER_HEALTH_REPAIR_ALL_KEY
) {
895 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
897 PlatformRepairAll (&DriverHealthList
);
899 gCallbackKey
= DRIVER_HEALTH_RETURN_KEY
;
903 // Cleanup dynamic created strings in HII database by reinstall the packagelist
906 HiiRemovePackages (HiiHandle
);
908 gDeviceManagerPrivate
.DriverHealthHiiHandle
= HiiAddPackages (
910 gDeviceManagerPrivate
.DriverHealthHandle
,
915 if (gDeviceManagerPrivate
.DriverHealthHiiHandle
== NULL
) {
916 Status
= EFI_OUT_OF_RESOURCES
;
918 Status
= EFI_SUCCESS
;
921 // Free driver health info list
923 while (!IsListEmpty (&DriverHealthList
)) {
925 Link
= GetFirstNode(&DriverHealthList
);
926 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
927 RemoveEntryList (Link
);
929 if (DriverHealthInfo
->MessageList
!= NULL
) {
930 FreePool(DriverHealthInfo
->MessageList
);
931 FreePool (DriverHealthInfo
);
935 HiiFreeOpCodeHandle (StartOpCodeHandle
);
936 HiiFreeOpCodeHandle (EndOpCodeHandle
);
937 HiiFreeOpCodeHandle (StartOpCodeHandleRepair
);
938 HiiFreeOpCodeHandle (EndOpCodeHandleRepair
);
940 if (gCallbackKey
== DRIVER_HEALTH_RETURN_KEY
) {
941 gCallbackKey
= DEVICE_MANAGER_KEY_DRIVER_HEALTH
;
944 if (gCallbackKey
== DEVICE_MANAGER_KEY_DRIVER_HEALTH
) {
951 Check the Driver Health status of a single controller and try to process it if not healthy.
953 This function called by CheckAllControllersHealthStatus () function in order to process a specify
954 contoller's health state.
956 @param DriverHealth A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
957 @param ControllerHandle The class guid specifies which form set will be displayed.
958 @param ChildHandle The handle of the child controller to retrieve the health
959 status on. This is an optional parameter that may be NULL.
960 @param HealthStatus The health status of the controller.
961 @param MessageList An array of warning or error messages associated
962 with the controller specified by ControllerHandle and
963 ChildHandle. This is an optional parameter that may be NULL.
964 @param FormHiiHandle The HII handle for an HII form associated with the
965 controller specified by ControllerHandle and ChildHandle.
967 @retval EFI_INVALID_PARAMETER HealthStatus or DriverHealth is NULL.
968 @retval HealthStatus The Health status of specify controller.
969 @retval EFI_OUT_OF_RESOURCES The list of Driver Health Protocol handles can not be retrieved.
970 @retval EFI_NOT_FOUND No controller in the platform install Driver Health Protocol.
971 @retval EFI_SUCCESS The Health related operation has been taken successfully.
976 GetSingleControllerHealthStatus (
977 IN OUT LIST_ENTRY
*DriverHealthList
,
978 IN EFI_HANDLE DriverHandle
,
979 IN EFI_HANDLE ControllerHandle
, OPTIONAL
980 IN EFI_HANDLE ChildHandle
, OPTIONAL
981 IN EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
,
982 IN EFI_DRIVER_HEALTH_STATUS
*HealthStatus
986 EFI_DRIVER_HEALTH_HII_MESSAGE
*MessageList
;
987 EFI_HII_HANDLE FormHiiHandle
;
988 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
990 if (HealthStatus
== NULL
) {
992 // If HealthStatus is NULL, then return EFI_INVALID_PARAMETER
994 return EFI_INVALID_PARAMETER
;
998 // Assume the HealthStatus is healthy
1000 *HealthStatus
= EfiDriverHealthStatusHealthy
;
1002 if (DriverHealth
== NULL
) {
1004 // If DriverHealth is NULL, then return EFI_INVALID_PARAMETER
1006 return EFI_INVALID_PARAMETER
;
1009 if (ControllerHandle
== NULL
) {
1011 // If ControllerHandle is NULL, the return the cumulative health status of the driver
1013 Status
= DriverHealth
->GetHealthStatus (DriverHealth
, NULL
, NULL
, HealthStatus
, NULL
, NULL
);
1014 if (*HealthStatus
== EfiDriverHealthStatusHealthy
) {
1016 // Add the driver health related information into the list
1018 DriverHealthInfo
= AllocateZeroPool (sizeof (DRIVER_HEALTH_INFO
));
1019 if (DriverHealthInfo
== NULL
) {
1020 return EFI_OUT_OF_RESOURCES
;
1023 DriverHealthInfo
->Signature
= DEVICE_MANAGER_DRIVER_HEALTH_INFO_SIGNATURE
;
1024 DriverHealthInfo
->DriverHandle
= DriverHandle
;
1025 DriverHealthInfo
->ControllerHandle
= NULL
;
1026 DriverHealthInfo
->ChildHandle
= NULL
;
1027 DriverHealthInfo
->HiiHandle
= NULL
;
1028 DriverHealthInfo
->DriverHealth
= DriverHealth
;
1029 DriverHealthInfo
->MessageList
= NULL
;
1030 DriverHealthInfo
->HealthStatus
= *HealthStatus
;
1032 InsertTailList (DriverHealthList
, &DriverHealthInfo
->Link
);
1038 FormHiiHandle
= NULL
;
1041 // Collect the health status with the optional HII message list
1043 Status
= DriverHealth
->GetHealthStatus (DriverHealth
, ControllerHandle
, ChildHandle
, HealthStatus
, &MessageList
, &FormHiiHandle
);
1045 if (EFI_ERROR (Status
)) {
1047 // If the health status could not be retrieved, then return immediately
1053 // Add the driver health related information into the list
1055 DriverHealthInfo
= AllocateZeroPool (sizeof (DRIVER_HEALTH_INFO
));
1056 if (DriverHealthInfo
== NULL
) {
1057 return EFI_OUT_OF_RESOURCES
;
1060 DriverHealthInfo
->Signature
= DEVICE_MANAGER_DRIVER_HEALTH_INFO_SIGNATURE
;
1061 DriverHealthInfo
->DriverHandle
= DriverHandle
;
1062 DriverHealthInfo
->ControllerHandle
= ControllerHandle
;
1063 DriverHealthInfo
->ChildHandle
= ChildHandle
;
1064 DriverHealthInfo
->HiiHandle
= FormHiiHandle
;
1065 DriverHealthInfo
->DriverHealth
= DriverHealth
;
1066 DriverHealthInfo
->MessageList
= MessageList
;
1067 DriverHealthInfo
->HealthStatus
= *HealthStatus
;
1069 InsertTailList (DriverHealthList
, &DriverHealthInfo
->Link
);
1075 Collects all the EFI Driver Health Protocols currently present in the EFI Handle Database,
1076 and queries each EFI Driver Health Protocol to determine if one or more of the controllers
1077 managed by each EFI Driver Health Protocol instance are not healthy.
1079 @param DriverHealthList A Pointer to the list contain all of the platform driver health
1082 @retval EFI_NOT_FOUND No controller in the platform install Driver Health Protocol.
1083 @retval EFI_SUCCESS All the controllers in the platform are healthy.
1084 @retval EFI_OUT_OF_RESOURCES The list of Driver Health Protocol handles can not be retrieved.
1088 GetAllControllersHealthStatus (
1089 IN OUT LIST_ENTRY
*DriverHealthList
1094 EFI_HANDLE
*DriverHealthHandles
;
1095 EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
;
1096 EFI_DRIVER_HEALTH_STATUS HealthStatus
;
1097 UINTN DriverHealthIndex
;
1098 EFI_HANDLE
*Handles
;
1100 UINTN ControllerIndex
;
1104 // Initialize local variables
1107 DriverHealthHandles
= NULL
;
1111 HealthStatus
= EfiDriverHealthStatusHealthy
;
1113 Status
= gBS
->LocateHandleBuffer (
1115 &gEfiDriverHealthProtocolGuid
,
1118 &DriverHealthHandles
1121 if (Status
== EFI_NOT_FOUND
|| NumHandles
== 0) {
1123 // If there are no Driver Health Protocols handles, then return EFI_NOT_FOUND
1125 return EFI_NOT_FOUND
;
1128 if (EFI_ERROR (Status
) || DriverHealthHandles
== NULL
) {
1130 // If the list of Driver Health Protocol handles can not be retrieved, then
1131 // return EFI_OUT_OF_RESOURCES
1133 return EFI_OUT_OF_RESOURCES
;
1137 // Check the health status of all controllers in the platform
1138 // Start by looping through all the Driver Health Protocol handles in the handle database
1140 for (DriverHealthIndex
= 0; DriverHealthIndex
< NumHandles
; DriverHealthIndex
++) {
1142 // Skip NULL Driver Health Protocol handles
1144 if (DriverHealthHandles
[DriverHealthIndex
] == NULL
) {
1149 // Retrieve the Driver Health Protocol from DriverHandle
1151 Status
= gBS
->HandleProtocol (
1152 DriverHealthHandles
[DriverHealthIndex
],
1153 &gEfiDriverHealthProtocolGuid
,
1154 (VOID
**)&DriverHealth
1156 if (EFI_ERROR (Status
)) {
1158 // If the Driver Health Protocol can not be retrieved, then skip to the next
1159 // Driver Health Protocol handle
1165 // Check the health of all the controllers managed by a Driver Health Protocol handle
1167 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], NULL
, NULL
, DriverHealth
, &HealthStatus
);
1170 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1171 // and skip to the next Driver Health Protocol handle
1173 if (EFI_ERROR (Status
)) {
1178 // If all the controllers managed by this Driver Health Protocol are healthy, then skip to the next
1179 // Driver Health Protocol handle
1181 if (HealthStatus
== EfiDriverHealthStatusHealthy
) {
1186 // See if the list of all handles in the handle database has been retrieved
1189 if (Handles
== NULL
) {
1191 // Retrieve the list of all handles from the handle database
1193 Status
= gBS
->LocateHandleBuffer (
1200 if (EFI_ERROR (Status
) || Handles
== NULL
) {
1202 // If all the handles in the handle database can not be retrieved, then
1203 // return EFI_OUT_OF_RESOURCES
1205 Status
= EFI_OUT_OF_RESOURCES
;
1210 // Loop through all the controller handles in the handle database
1212 for (ControllerIndex
= 0; ControllerIndex
< HandleCount
; ControllerIndex
++) {
1214 // Skip NULL controller handles
1216 if (Handles
[ControllerIndex
] == NULL
) {
1220 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], Handles
[ControllerIndex
], NULL
, DriverHealth
, &HealthStatus
);
1221 if (EFI_ERROR (Status
)) {
1223 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1225 HealthStatus
= EfiDriverHealthStatusHealthy
;
1229 // If CheckHealthSingleController() returned an error on a terminal state, then do not check the health of child controllers
1231 if (EFI_ERROR (Status
)) {
1236 // Loop through all the child handles in the handle database
1238 for (ChildIndex
= 0; ChildIndex
< HandleCount
; ChildIndex
++) {
1240 // Skip NULL child handles
1242 if (Handles
[ChildIndex
] == NULL
) {
1246 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], Handles
[ControllerIndex
], Handles
[ChildIndex
], DriverHealth
, &HealthStatus
);
1247 if (EFI_ERROR (Status
)) {
1249 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1251 HealthStatus
= EfiDriverHealthStatusHealthy
;
1255 // If CheckHealthSingleController() returned an error on a terminal state, then skip to the next child
1257 if (EFI_ERROR (Status
)) {
1264 Status
= EFI_SUCCESS
;
1267 if (Handles
!= NULL
) {
1268 gBS
->FreePool (Handles
);
1270 if (DriverHealthHandles
!= NULL
) {
1271 gBS
->FreePool (DriverHealthHandles
);
1279 Check the healthy status of the platform, this function will return immediately while found one driver
1280 in the platform are not healthy.
1282 @retval FALSE at least one driver in the platform are not healthy.
1283 @retval TRUE No controller install Driver Health Protocol,
1284 or all controllers in the platform are in healthy status.
1287 PlaformHealthStatusCheck (
1291 EFI_DRIVER_HEALTH_STATUS HealthStatus
;
1295 EFI_HANDLE
*DriverHealthHandles
;
1296 EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
;
1300 // Initialize local variables
1302 DriverHealthHandles
= NULL
;
1303 DriverHealth
= NULL
;
1305 HealthStatus
= EfiDriverHealthStatusHealthy
;
1307 Status
= gBS
->LocateHandleBuffer (
1309 &gEfiDriverHealthProtocolGuid
,
1312 &DriverHealthHandles
1315 // There are no handles match the search for Driver Health Protocol has been installed.
1317 if (Status
== EFI_NOT_FOUND
) {
1321 // Assume all modules are healthy.
1326 // Found one or more Handles.
1328 if (!EFI_ERROR (Status
)) {
1329 for (Index
= 0; Index
< NoHandles
; Index
++) {
1330 Status
= gBS
->HandleProtocol (
1331 DriverHealthHandles
[Index
],
1332 &gEfiDriverHealthProtocolGuid
,
1333 (VOID
**) &DriverHealth
1335 if (!EFI_ERROR (Status
)) {
1336 Status
= DriverHealth
->GetHealthStatus (
1346 // Get the healthy status of the module
1348 if (!EFI_ERROR (Status
)) {
1349 if (HealthStatus
!= EfiDriverHealthStatusHealthy
) {
1351 // Return immediately one driver's status not in healthy.
1362 Processes a single controller using the EFI Driver Health Protocol associated with
1363 that controller. This algorithm continues to query the GetHealthStatus() service until
1364 one of the legal terminal states of the EFI Driver Health Protocol is reached. This may
1365 require the processing of HII Messages, HII Form, and invocation of repair operations.
1367 @param DriverHealth A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
1368 @param ControllerHandle The class guid specifies which form set will be displayed.
1369 @param ChildHandle The handle of the child controller to retrieve the health
1370 status on. This is an optional parameter that may be NULL.
1371 @param HealthStatus The health status of the controller.
1372 @param MessageList An array of warning or error messages associated
1373 with the controller specified by ControllerHandle and
1374 ChildHandle. This is an optional parameter that may be NULL.
1375 @param FormHiiHandle The HII handle for an HII form associated with the
1376 controller specified by ControllerHandle and ChildHandle.
1379 ProcessSingleControllerHealth (
1380 IN EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
,
1381 IN EFI_HANDLE ControllerHandle
, OPTIONAL
1382 IN EFI_HANDLE ChildHandle
, OPTIONAL
1383 IN EFI_DRIVER_HEALTH_STATUS HealthStatus
,
1384 IN EFI_DRIVER_HEALTH_HII_MESSAGE
**MessageList
, OPTIONAL
1385 IN EFI_HII_HANDLE FormHiiHandle
1389 EFI_DRIVER_HEALTH_STATUS LocalHealthStatus
;
1391 LocalHealthStatus
= HealthStatus
;
1393 // If the module need to be repaired or reconfiguration, will process it until
1394 // reach a terminal status. The status from EfiDriverHealthStatusRepairRequired after repair
1395 // will be in (Health, Failed, Configuration Required).
1397 while( LocalHealthStatus
== EfiDriverHealthStatusConfigurationRequired
||
1398 LocalHealthStatus
== EfiDriverHealthStatusRepairRequired
) {
1400 if (LocalHealthStatus
== EfiDriverHealthStatusRepairRequired
) {
1401 Status
= DriverHealth
->Repair (
1405 (EFI_DRIVER_HEALTH_REPAIR_PROGRESS_NOTIFY
) RepairNotify
1409 // Via a form of the driver need to do configuration provided to process of status in
1410 // EfiDriverHealthStatusConfigurationRequired. The status after configuration should be in
1411 // (Healthy, Reboot Required, Failed, Reconnect Required, Repair Required).
1413 if (LocalHealthStatus
== EfiDriverHealthStatusConfigurationRequired
) {
1414 Status
= gFormBrowser2
->SendForm (
1418 &gEfiHiiDriverHealthFormsetGuid
,
1423 ASSERT( !EFI_ERROR (Status
));
1426 Status
= DriverHealth
->GetHealthStatus (
1434 ASSERT_EFI_ERROR (Status
);
1436 if (*MessageList
!= NULL
) {
1437 ProcessMessages (*MessageList
);
1442 // Health status in {Healthy, Failed} may also have Messages need to process
1444 if (LocalHealthStatus
== EfiDriverHealthStatusHealthy
|| LocalHealthStatus
== EfiDriverHealthStatusFailed
) {
1445 if (*MessageList
!= NULL
) {
1446 ProcessMessages (*MessageList
);
1450 // Check for RebootRequired or ReconnectRequired
1452 if (LocalHealthStatus
== EfiDriverHealthStatusRebootRequired
) {
1453 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1457 // Do reconnect if need.
1459 if (LocalHealthStatus
== EfiDriverHealthStatusReconnectRequired
) {
1460 Status
= gBS
->DisconnectController (ControllerHandle
, NULL
, NULL
);
1461 if (EFI_ERROR (Status
)) {
1463 // Disconnect failed. Need to promote reconnect to a reboot.
1465 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1467 gBS
->ConnectController (ControllerHandle
, NULL
, NULL
, TRUE
);
1473 Platform specific notification function for controller repair operations.
1475 If the driver for a controller support the Driver Health Protocol and the
1476 current state of the controller is EfiDriverHealthStatusRepairRequired then
1477 when the Repair() service of the Driver Health Protocol is called, this
1478 platform specific notification function can display the progress of the repair
1479 operation. Some platforms may choose to not display anything, other may choose
1480 to show the percentage complete on text consoles, and other may choose to render
1481 a progress bar on text and graphical consoles.
1483 This function displays the percentage of the repair operation that has been
1484 completed on text consoles. The percentage is Value / Limit * 100%.
1486 @param Value Value in the range 0..Limit the the repair has completed..
1487 @param Limit The maximum value of Value
1499 Print(L
"Repair Progress Undefined\n\r");
1501 Percent
= Value
* 100 / Limit
;
1502 Print(L
"Repair Progress = %3d%%\n\r", Percent
);
1507 Processes a set of messages returned by the GetHealthStatus ()
1508 service of the EFI Driver Health Protocol
1510 @param MessageList The MessageList point to messages need to processed.
1515 IN EFI_DRIVER_HEALTH_HII_MESSAGE
*MessageList
1519 EFI_STRING MessageString
;
1521 for (MessageIndex
= 0;
1522 MessageList
[MessageIndex
].HiiHandle
!= NULL
;
1525 MessageString
= HiiGetString (
1526 MessageList
[MessageIndex
].HiiHandle
,
1527 MessageList
[MessageIndex
].StringId
,
1530 if (MessageString
!= NULL
) {
1532 // User can customize the output. Just simply print out the MessageString like below.
1533 // Also can use the HiiHandle to display message on the front page.
1535 // Print(L"%s\n",MessageString);
1536 // gBS->Stall (100000);
1543 Repair the whole platform.
1545 This function is the main entry for user choose "Repair All" in the front page.
1546 It will try to do recovery job till all the driver health protocol installed modules
1547 reach a terminal state.
1549 @param DriverHealthList A Pointer to the list contain all of the platform driver health
1555 IN LIST_ENTRY
*DriverHealthList
1558 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
1561 ASSERT (DriverHealthList
!= NULL
);
1563 Link
= GetFirstNode (DriverHealthList
);
1565 while (!IsNull (DriverHealthList
, Link
)) {
1566 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
1568 // Do driver health status operation by each link node
1570 ASSERT (DriverHealthInfo
!= NULL
);
1572 ProcessSingleControllerHealth (
1573 DriverHealthInfo
->DriverHealth
,
1574 DriverHealthInfo
->ControllerHandle
,
1575 DriverHealthInfo
->ChildHandle
,
1576 DriverHealthInfo
->HealthStatus
,
1577 &(DriverHealthInfo
->MessageList
),
1578 DriverHealthInfo
->HiiHandle
1581 Link
= GetNextNode (DriverHealthList
, Link
);
1587 Select the best matching language according to front page policy for best user experience.
1589 This function supports both ISO 639-2 and RFC 4646 language codes, but language
1590 code types may not be mixed in a single call to this function.
1592 @param SupportedLanguages A pointer to a Null-terminated ASCII string that
1593 contains a set of language codes in the format
1594 specified by Iso639Language.
1595 @param Iso639Language If TRUE, then all language codes are assumed to be
1596 in ISO 639-2 format. If FALSE, then all language
1597 codes are assumed to be in RFC 4646 language format.
1599 @retval NULL The best matching language could not be found in SupportedLanguages.
1600 @retval NULL There are not enough resources available to return the best matching
1602 @retval Other A pointer to a Null-terminated ASCII string that is the best matching
1603 language in SupportedLanguages.
1606 DriverHealthSelectBestLanguage (
1607 IN CHAR8
*SupportedLanguages
,
1608 IN BOOLEAN Iso639Language
1611 CHAR8
*LanguageVariable
;
1612 CHAR8
*BestLanguage
;
1614 LanguageVariable
= GetEfiGlobalVariable (Iso639Language
? L
"Lang" : L
"PlatformLang");
1616 BestLanguage
= GetBestLanguage(
1619 (LanguageVariable
!= NULL
) ? LanguageVariable
: "",
1620 Iso639Language
? "eng" : "en-US",
1623 if (LanguageVariable
!= NULL
) {
1624 FreePool (LanguageVariable
);
1627 return BestLanguage
;
1634 This is an internal worker function to get the Component Name (2) protocol interface
1635 and the language it supports.
1637 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
1638 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1639 @param ComponentName A pointer to the Component Name (2) protocol interface.
1640 @param SupportedLanguage The best suitable language that matches the SupportedLangues interface for the
1641 located Component Name (2) instance.
1643 @param EFI_SUCCESS The Component Name (2) protocol instance is successfully located and we find
1644 the best matching language it support.
1645 @param EFI_UNSUPPORTED The input Language is not supported by the Component Name (2) protocol.
1646 @param Other Some error occurs when locating Component Name (2) protocol instance or finding
1647 the supported language.
1651 GetComponentNameWorker (
1652 IN EFI_GUID
*ProtocolGuid
,
1653 IN EFI_HANDLE DriverBindingHandle
,
1654 OUT EFI_COMPONENT_NAME_PROTOCOL
**ComponentName
,
1655 OUT CHAR8
**SupportedLanguage
1661 // Locate Component Name (2) protocol on the driver binging handle.
1663 Status
= gBS
->OpenProtocol (
1664 DriverBindingHandle
,
1666 (VOID
**) ComponentName
,
1669 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1671 if (EFI_ERROR (Status
)) {
1676 // Apply shell policy to select the best language.
1678 *SupportedLanguage
= DriverHealthSelectBestLanguage (
1679 (*ComponentName
)->SupportedLanguages
,
1680 (BOOLEAN
) (ProtocolGuid
== &gEfiComponentNameProtocolGuid
)
1682 if (*SupportedLanguage
== NULL
) {
1683 Status
= EFI_UNSUPPORTED
;
1691 This is an internal worker function to get driver name from Component Name (2) protocol interface.
1694 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
1695 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1696 @param DriverName A pointer to the Unicode string to return. This Unicode string is the name
1697 of the driver specified by This.
1699 @retval EFI_SUCCESS The driver name is successfully retrieved from Component Name (2) protocol
1701 @retval Other The driver name cannot be retrieved from Component Name (2) protocol
1706 GetDriverNameWorker (
1707 IN EFI_GUID
*ProtocolGuid
,
1708 IN EFI_HANDLE DriverBindingHandle
,
1709 OUT CHAR16
**DriverName
1713 CHAR8
*BestLanguage
;
1714 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
1717 // Retrieve Component Name (2) protocol instance on the driver binding handle and
1718 // find the best language this instance supports.
1720 Status
= GetComponentNameWorker (
1722 DriverBindingHandle
,
1726 if (EFI_ERROR (Status
)) {
1731 // Get the driver name from Component Name (2) protocol instance on the driver binging handle.
1733 Status
= ComponentName
->GetDriverName (
1738 FreePool (BestLanguage
);
1745 This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface
1746 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name.
1747 If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward
1748 compatibility support.
1750 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1751 @param DriverName A pointer to the Unicode string to return. This Unicode string is the name
1752 of the driver specified by This.
1754 @retval EFI_SUCCESS The driver name is successfully retrieved from Component Name (2) protocol
1756 @retval Other The driver name cannot be retrieved from Component Name (2) protocol
1761 DriverHealthGetDriverName (
1762 IN EFI_HANDLE DriverBindingHandle
,
1763 OUT CHAR16
**DriverName
1769 // Get driver name from UEFI 2.0 Component Name 2 protocol interface.
1771 Status
= GetDriverNameWorker (&gEfiComponentName2ProtocolGuid
, DriverBindingHandle
, DriverName
);
1772 if (EFI_ERROR (Status
)) {
1774 // If it fails to get the driver name from Component Name protocol interface, we should fall back on
1775 // EFI 1.1 Component Name protocol interface.
1777 Status
= GetDriverNameWorker (&gEfiComponentNameProtocolGuid
, DriverBindingHandle
, DriverName
);
1786 This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
1787 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
1788 If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
1789 compatibility support.
1791 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
1792 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1793 @param ControllerHandle The handle of a controller that the driver specified by This is managing.
1794 This handle specifies the controller whose name is to be returned.
1795 @param ChildHandle The handle of the child controller to retrieve the name of. This is an
1796 optional parameter that may be NULL. It will be NULL for device drivers.
1797 It will also be NULL for bus drivers that attempt to retrieve the name
1798 of the bus controller. It will not be NULL for a bus driver that attempts
1799 to retrieve the name of a child controller.
1800 @param ControllerName A pointer to the Unicode string to return. This Unicode string
1801 is the name of the controller specified by ControllerHandle and ChildHandle.
1803 @retval EFI_SUCCESS The controller name is successfully retrieved from Component Name (2) protocol
1805 @retval Other The controller name cannot be retrieved from Component Name (2) protocol.
1809 GetControllerNameWorker (
1810 IN EFI_GUID
*ProtocolGuid
,
1811 IN EFI_HANDLE DriverBindingHandle
,
1812 IN EFI_HANDLE ControllerHandle
,
1813 IN EFI_HANDLE ChildHandle
,
1814 OUT CHAR16
**ControllerName
1818 CHAR8
*BestLanguage
;
1819 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
1822 // Retrieve Component Name (2) protocol instance on the driver binding handle and
1823 // find the best language this instance supports.
1825 Status
= GetComponentNameWorker (
1827 DriverBindingHandle
,
1831 if (EFI_ERROR (Status
)) {
1836 // Get the controller name from Component Name (2) protocol instance on the driver binging handle.
1838 Status
= ComponentName
->GetControllerName (
1845 FreePool (BestLanguage
);
1852 This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
1853 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
1854 If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
1855 compatibility support.
1857 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1858 @param ControllerHandle The handle of a controller that the driver specified by This is managing.
1859 This handle specifies the controller whose name is to be returned.
1860 @param ChildHandle The handle of the child controller to retrieve the name of. This is an
1861 optional parameter that may be NULL. It will be NULL for device drivers.
1862 It will also be NULL for bus drivers that attempt to retrieve the name
1863 of the bus controller. It will not be NULL for a bus driver that attempts
1864 to retrieve the name of a child controller.
1865 @param Language An ASCII string that represents the language command line option.
1866 @param ControllerName A pointer to the Unicode string to return. This Unicode string
1867 is the name of the controller specified by ControllerHandle and ChildHandle.
1869 @retval EFI_SUCCESS The controller name is successfully retrieved from Component Name (2) protocol
1871 @retval Other The controller name cannot be retrieved from Component Name (2) protocol.
1875 DriverHealthGetControllerName (
1876 IN EFI_HANDLE DriverBindingHandle
,
1877 IN EFI_HANDLE ControllerHandle
,
1878 IN EFI_HANDLE ChildHandle
,
1879 OUT CHAR16
**ControllerName
1885 // Get controller name from UEFI 2.0 Component Name 2 protocol interface.
1887 Status
= GetControllerNameWorker (
1888 &gEfiComponentName2ProtocolGuid
,
1889 DriverBindingHandle
,
1894 if (EFI_ERROR (Status
)) {
1896 // If it fails to get the controller name from Component Name protocol interface, we should fall back on
1897 // EFI 1.1 Component Name protocol interface.
1899 Status
= GetControllerNameWorker (
1900 &gEfiComponentNameProtocolGuid
,
1901 DriverBindingHandle
,