2 The platform device manager reference implementation
4 Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
5 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 #define MAX_MAC_ADDRESS_NODE_LIST_LEN 10
37 EFI_GUID mDeviceManagerGuid
= DEVICE_MANAGER_FORMSET_GUID
;
38 EFI_GUID mDriverHealthGuid
= DRIVER_HEALTH_FORMSET_GUID
;
41 // Which Mac Address string is select
42 // it will decide what menu need to show in the NETWORK_DEVICE_FORM_ID form.
44 EFI_STRING mSelectedMacAddrString
;
47 // Which form Id need to be show.
49 EFI_FORM_ID mNextShowFormId
= DEVICE_MANAGER_FORM_ID
;
52 // The Mac Address show in the NETWORK_DEVICE_LIST_FORM_ID
54 MAC_ADDRESS_NODE_LIST mMacDeviceList
;
56 DEVICE_MANAGER_MENU_ITEM mDeviceManagerMenuItemTable
[] = {
57 { STRING_TOKEN (STR_DISK_DEVICE
), EFI_DISK_DEVICE_CLASS
},
58 { STRING_TOKEN (STR_VIDEO_DEVICE
), EFI_VIDEO_DEVICE_CLASS
},
59 { STRING_TOKEN (STR_NETWORK_DEVICE
), EFI_NETWORK_DEVICE_CLASS
},
60 { STRING_TOKEN (STR_INPUT_DEVICE
), EFI_INPUT_DEVICE_CLASS
},
61 { STRING_TOKEN (STR_ON_BOARD_DEVICE
), EFI_ON_BOARD_DEVICE_CLASS
},
62 { STRING_TOKEN (STR_OTHER_DEVICE
), EFI_OTHER_DEVICE_CLASS
}
65 HII_VENDOR_DEVICE_PATH mDeviceManagerHiiVendorDevicePath
= {
71 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
72 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
76 // {102579A0-3686-466e-ACD8-80C087044F4A}
78 { 0x102579a0, 0x3686, 0x466e, { 0xac, 0xd8, 0x80, 0xc0, 0x87, 0x4, 0x4f, 0x4a } }
82 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
84 (UINT8
) (END_DEVICE_PATH_LENGTH
),
85 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
90 HII_VENDOR_DEVICE_PATH mDriverHealthHiiVendorDevicePath
= {
96 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
97 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
101 // {D8F76651-1675-4986-BED4-3824B2F1F4C8}
103 { 0xd8f76651, 0x1675, 0x4986, { 0xbe, 0xd4, 0x38, 0x24, 0xb2, 0xf1, 0xf4, 0xc8 } }
106 END_DEVICE_PATH_TYPE
,
107 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
109 (UINT8
) (END_DEVICE_PATH_LENGTH
),
110 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
116 This function is invoked if user selected a interactive opcode from Device Manager's
117 Formset. The decision by user is saved to gCallbackKey for later processing. If
118 user set VBIOS, the new value is saved to EFI variable.
120 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
121 @param Action Specifies the type of action taken by the browser.
122 @param QuestionId A unique value which is sent to the original exporting driver
123 so that it can identify the type of data to expect.
124 @param Type The type of value for the question.
125 @param Value A pointer to the data being sent to the original exporting driver.
126 @param ActionRequest On return, points to the action requested by the callback function.
128 @retval EFI_SUCCESS The callback successfully handled the action.
129 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
134 DeviceManagerCallback (
135 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
136 IN EFI_BROWSER_ACTION Action
,
137 IN EFI_QUESTION_ID QuestionId
,
139 IN EFI_IFR_TYPE_VALUE
*Value
,
140 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
145 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
146 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
147 return EFI_INVALID_PARAMETER
;
150 gCallbackKey
= QuestionId
;
151 if ((QuestionId
< MAX_KEY_SECTION_LEN
+ NETWORK_DEVICE_LIST_KEY_OFFSET
) && (QuestionId
>= NETWORK_DEVICE_LIST_KEY_OFFSET
)) {
153 // If user select the mac address, need to record mac address string to support next form show.
155 for (CurIndex
= 0; CurIndex
< mMacDeviceList
.CurListLen
; CurIndex
++) {
156 if (mMacDeviceList
.NodeList
[CurIndex
].QuestionId
== QuestionId
) {
157 mSelectedMacAddrString
= HiiGetString (gDeviceManagerPrivate
.HiiHandle
, mMacDeviceList
.NodeList
[CurIndex
].PromptId
, NULL
);
163 // Request to exit SendForm(), so as to switch to selected form
165 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
171 // All other action return unsupported.
173 return EFI_UNSUPPORTED
;
178 This function registers HII packages to HII database.
180 @retval EFI_SUCCESS HII packages for the Device Manager were registered successfully.
181 @retval EFI_OUT_OF_RESOURCES HII packages for the Device Manager failed to be registered.
185 InitializeDeviceManager (
192 // Install Device Path Protocol and Config Access protocol to driver handle
194 Status
= gBS
->InstallMultipleProtocolInterfaces (
195 &gDeviceManagerPrivate
.DriverHandle
,
196 &gEfiDevicePathProtocolGuid
,
197 &mDeviceManagerHiiVendorDevicePath
,
198 &gEfiHiiConfigAccessProtocolGuid
,
199 &gDeviceManagerPrivate
.ConfigAccess
,
202 ASSERT_EFI_ERROR (Status
);
204 Status
= gBS
->InstallMultipleProtocolInterfaces (
205 &gDeviceManagerPrivate
.DriverHealthHandle
,
206 &gEfiDevicePathProtocolGuid
,
207 &mDriverHealthHiiVendorDevicePath
,
208 &gEfiHiiConfigAccessProtocolGuid
,
209 &gDeviceManagerPrivate
.DriverHealthConfigAccess
,
212 ASSERT_EFI_ERROR (Status
);
214 mMacDeviceList
.CurListLen
= 0;
215 mMacDeviceList
.MaxListLen
= 0;
221 Extract the displayed formset for given HII handle and class guid.
223 @param Handle The HII handle.
224 @param SetupClassGuid The class guid specifies which form set will be displayed.
225 @param FormSetTitle Formset title string.
226 @param FormSetHelp Formset help string.
228 @retval TRUE The formset for given HII handle will be displayed.
229 @return FALSE The formset for given HII handle will not be displayed.
233 ExtractDisplayedHiiFormFromHiiHandle (
234 IN EFI_HII_HANDLE Handle
,
235 IN EFI_GUID
*SetupClassGuid
,
236 OUT EFI_STRING_ID
*FormSetTitle
,
237 OUT EFI_STRING_ID
*FormSetHelp
242 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
247 UINT32 PackageListLength
;
248 EFI_HII_PACKAGE_HEADER PackageHeader
;
252 ASSERT (Handle
!= NULL
);
253 ASSERT (SetupClassGuid
!= NULL
);
254 ASSERT (FormSetTitle
!= NULL
);
255 ASSERT (FormSetHelp
!= NULL
);
263 // Get HII PackageList
266 HiiPackageList
= NULL
;
267 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
269 // Handle is a invalid handle. Check if Handle is corrupted.
271 ASSERT (Status
!= EFI_NOT_FOUND
);
273 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
275 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
277 HiiPackageList
= AllocatePool (BufferSize
);
278 ASSERT (HiiPackageList
!= NULL
);
280 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
281 if (EFI_ERROR (Status
)) {
286 // Get Form package from this HII package List
288 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
290 PackageListLength
= ReadUnaligned32 (&HiiPackageList
->PackageLength
);
292 while (Offset
< PackageListLength
) {
293 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
294 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
296 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
298 // Search FormSet Opcode in this Form Package
300 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
301 while (Offset2
< PackageHeader
.Length
) {
302 OpCodeData
= Package
+ Offset2
;
304 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
305 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
307 // Find FormSet OpCode
309 ClassGuidNum
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
310 ClassGuid
= (EFI_GUID
*) (VOID
*)(OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
311 while (ClassGuidNum
-- > 0) {
312 if (CompareGuid (SetupClassGuid
, ClassGuid
)) {
313 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
314 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
315 FreePool (HiiPackageList
);
321 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
322 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
323 FreePool (HiiPackageList
);
331 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
336 // Go to next package
338 Offset
+= PackageHeader
.Length
;
341 FreePool (HiiPackageList
);
347 Get the mac address string from the device path.
348 if the device path has the vlan, get the vanid also.
350 @param MacAddressNode Device path begin with mac address
351 @param PBuffer Output string buffer contain mac address.
356 IN MAC_ADDR_DEVICE_PATH
*MacAddressNode
,
363 EFI_DEVICE_PATH_PROTOCOL
*Node
;
370 ASSERT(MacAddressNode
!= NULL
);
372 HwAddressSize
= sizeof (EFI_MAC_ADDRESS
);
373 if (MacAddressNode
->IfType
== 0x01 || MacAddressNode
->IfType
== 0x00) {
378 // The output format is MAC:XX:XX:XX:...\XXXX
379 // The size is the Number size + ":" size + Vlan size(\XXXX) + End
381 BufferLen
= (4 + 2 * HwAddressSize
+ (HwAddressSize
- 1) + 5 + 1) * sizeof (CHAR16
);
382 String
= AllocateZeroPool (BufferLen
);
383 if (String
== NULL
) {
388 StrCpy(String
, L
"MAC:");
392 // Convert the MAC address into a unicode string.
394 HwAddress
= &MacAddressNode
->MacAddress
.Addr
[0];
395 for (Index
= 0; Index
< HwAddressSize
; Index
++) {
396 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *(HwAddress
++), 2);
397 if (Index
< HwAddressSize
- 1) {
403 // If VLAN is configured, it will need extra 5 characters like "\0005".
404 // Plus one unicode character for the null-terminator.
406 Node
= (EFI_DEVICE_PATH_PROTOCOL
*)MacAddressNode
;
407 while (!IsDevicePathEnd (Node
)) {
408 if (Node
->Type
== MESSAGING_DEVICE_PATH
&& Node
->SubType
== MSG_VLAN_DP
) {
409 VlanId
= ((VLAN_DEVICE_PATH
*) Node
)->VlanId
;
411 Node
= NextDevicePathNode (Node
);
416 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, VlanId
, 4);
420 // Null terminate the Unicode string
428 Save question id and prompt id to the mac device list.
429 If the same mac address has saved yet, no need to add more.
431 @param MacAddrString Mac address string.
433 @retval EFI_SUCCESS Add the item is successful.
434 @return Other values if failed to Add the item.
437 AddIdToMacDeviceList (
438 IN EFI_STRING MacAddrString
441 MENU_INFO_ITEM
*TempDeviceList
;
443 EFI_STRING StoredString
;
444 EFI_STRING_ID PromptId
;
445 EFI_HII_HANDLE HiiHandle
;
447 HiiHandle
= gDeviceManagerPrivate
.HiiHandle
;
448 TempDeviceList
= NULL
;
450 for (Index
= 0; Index
< mMacDeviceList
.CurListLen
; Index
++) {
451 StoredString
= HiiGetString (HiiHandle
, mMacDeviceList
.NodeList
[Index
].PromptId
, NULL
);
452 if (StoredString
== NULL
) {
457 // Already has save the same mac address to the list.
459 if (StrCmp (MacAddrString
, StoredString
) == 0) {
464 PromptId
= HiiSetString(HiiHandle
, 0, MacAddrString
, NULL
);
466 // If not in the list, save it.
468 if (mMacDeviceList
.MaxListLen
> mMacDeviceList
.CurListLen
+ 1) {
469 mMacDeviceList
.NodeList
[mMacDeviceList
.CurListLen
].PromptId
= PromptId
;
470 mMacDeviceList
.NodeList
[mMacDeviceList
.CurListLen
].QuestionId
= (EFI_QUESTION_ID
) (mMacDeviceList
.CurListLen
+ NETWORK_DEVICE_LIST_KEY_OFFSET
);
472 mMacDeviceList
.MaxListLen
+= MAX_MAC_ADDRESS_NODE_LIST_LEN
;
473 if (mMacDeviceList
.CurListLen
!= 0) {
474 TempDeviceList
= (MENU_INFO_ITEM
*)AllocateCopyPool (sizeof (MENU_INFO_ITEM
) * mMacDeviceList
.MaxListLen
, (VOID
*)mMacDeviceList
.NodeList
);
476 TempDeviceList
= (MENU_INFO_ITEM
*)AllocatePool (sizeof (MENU_INFO_ITEM
) * mMacDeviceList
.MaxListLen
);
479 if (TempDeviceList
== NULL
) {
482 TempDeviceList
[mMacDeviceList
.CurListLen
].PromptId
= PromptId
;
483 TempDeviceList
[mMacDeviceList
.CurListLen
].QuestionId
= (EFI_QUESTION_ID
) (mMacDeviceList
.CurListLen
+ NETWORK_DEVICE_LIST_KEY_OFFSET
);
485 if (mMacDeviceList
.CurListLen
> 0) {
486 FreePool(mMacDeviceList
.NodeList
);
489 mMacDeviceList
.NodeList
= TempDeviceList
;
491 mMacDeviceList
.CurListLen
++;
497 Check the devcie path, try to find whether it has mac address path.
499 In this function, first need to check whether this path has mac address path.
500 second, when the mac address device path has find, also need to deicide whether
501 need to add this mac address relate info to the menu.
503 @param *Node Input device which need to be check.
504 @param *NeedAddItem Whether need to add the menu in the network device list.
506 @retval TRUE Has mac address device path.
507 @retval FALSE NOT Has mac address device path.
511 IsMacAddressDevicePath (
513 OUT BOOLEAN
*NeedAddItem
516 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
520 ASSERT (Node
!= NULL
);
521 *NeedAddItem
= FALSE
;
525 DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) Node
;
528 // find the partition device path node
530 while (!IsDevicePathEnd (DevicePath
)) {
531 if ((DevicePathType (DevicePath
) == MESSAGING_DEVICE_PATH
) &&
532 (DevicePathSubType (DevicePath
) == MSG_MAC_ADDR_DP
)) {
535 if (DEVICE_MANAGER_FORM_ID
== mNextShowFormId
) {
540 if (!GetMacAddressString((MAC_ADDR_DEVICE_PATH
*)DevicePath
, &Buffer
)) {
544 if (NETWORK_DEVICE_FORM_ID
== mNextShowFormId
) {
545 if (StrCmp (Buffer
, mSelectedMacAddrString
) == 0) {
551 if (NETWORK_DEVICE_LIST_FORM_ID
== mNextShowFormId
) {
553 // Same handle may has two network child handle, so the questionid
554 // has the offset of SAME_HANDLE_KEY_OFFSET.
556 if (AddIdToMacDeviceList (Buffer
)) {
562 DevicePath
= NextDevicePathNode (DevicePath
);
565 if (Buffer
!= NULL
) {
573 Check to see if the device path is for the network device.
575 @param Handle The HII handle which include the mac address device path.
576 @param ItemCount The new add Mac address item count.
578 @retval TRUE Need to add new item in the menu.
579 @return FALSE Do not need to add the menu about the network.
583 IsNeedAddNetworkMenu (
584 IN EFI_HII_HANDLE Handle
,
591 EFI_HII_HANDLE HiiDeviceManagerHandle
;
592 EFI_HANDLE DriverHandle
;
593 EFI_HANDLE ControllerHandle
;
594 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
595 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
596 EFI_DEVICE_PATH_PROTOCOL
*ChildDevicePath
;
597 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
600 HiiDeviceManagerHandle
= gDeviceManagerPrivate
.HiiHandle
;
602 OpenInfoBuffer
= NULL
;
603 if ((Handle
== NULL
) || (ItemCount
== NULL
)) {
608 Status
= gHiiDatabase
->GetPackageListHandle (gHiiDatabase
, Handle
, &DriverHandle
);
609 if (EFI_ERROR (Status
)) {
613 // Get the device path by the got Driver handle .
615 Status
= gBS
->HandleProtocol (DriverHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**) &DevicePath
);
616 if (EFI_ERROR (Status
)) {
619 TmpDevicePath
= DevicePath
;
622 // Check whether this device path include mac address device path.
623 // If this path has mac address path, get the value whether need
624 // add this info to the menu and return.
625 // Else check more about the child handle devcie path.
627 if (IsMacAddressDevicePath(TmpDevicePath
, &IsNeedAdd
)) {
628 if ((NETWORK_DEVICE_LIST_FORM_ID
== mNextShowFormId
) && IsNeedAdd
) {
635 // Search whether this path is the controller path, not he child handle path.
636 // And the child handle has the network devcie connected.
638 TmpDevicePath
= DevicePath
;
639 Status
= gBS
->LocateDevicePath(&gEfiDevicePathProtocolGuid
, &TmpDevicePath
, &ControllerHandle
);
640 if (EFI_ERROR (Status
)) {
644 if (!IsDevicePathEnd (TmpDevicePath
)) {
649 // Retrieve the list of agents that are consuming the specific protocol
650 // on ControllerHandle.
651 // The buffer point by OpenInfoBuffer need be free at this function.
653 Status
= gBS
->OpenProtocolInformation (
655 &gEfiPciIoProtocolGuid
,
659 if (EFI_ERROR (Status
)) {
664 // Inspect if ChildHandle is one of the agents.
666 Status
= EFI_UNSUPPORTED
;
667 for (Index
= 0; Index
< EntryCount
; Index
++) {
669 // Query all the children created by the controller handle's driver
671 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
672 Status
= gBS
->OpenProtocol (
673 OpenInfoBuffer
[Index
].ControllerHandle
,
674 &gEfiDevicePathProtocolGuid
,
675 (VOID
**) &ChildDevicePath
,
678 EFI_OPEN_PROTOCOL_GET_PROTOCOL
680 if (EFI_ERROR (Status
)) {
685 // Check whether this device path include mac address device path.
687 if (!IsMacAddressDevicePath(ChildDevicePath
, &IsNeedAdd
)) {
689 // If this path not has mac address path, check the other.
694 // If need to update the NETWORK_DEVICE_LIST_FORM, try to get more.
696 if ((NETWORK_DEVICE_LIST_FORM_ID
== mNextShowFormId
)) {
703 // If need to update other form, return whether need to add to the menu.
712 if (OpenInfoBuffer
!= NULL
) {
713 FreePool (OpenInfoBuffer
);
719 Call the browser and display the device manager to allow user
720 to configure the platform.
722 This function create the dynamic content for device manager. It includes
723 section header for all class of devices, one-of opcode to set VBIOS.
725 @retval EFI_SUCCESS Operation is successful.
726 @return Other values if failed to clean up the dynamic content from HII
739 EFI_STRING_ID TokenHelp
;
740 EFI_HII_HANDLE
*HiiHandles
;
741 EFI_HII_HANDLE HiiHandle
;
742 EFI_STRING_ID FormSetTitle
;
743 EFI_STRING_ID FormSetHelp
;
744 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
745 VOID
*StartOpCodeHandle
;
746 VOID
*EndOpCodeHandle
;
747 EFI_IFR_GUID_LABEL
*StartLabel
;
748 EFI_IFR_GUID_LABEL
*EndLabel
;
750 EFI_HANDLE
*DriverHealthHandles
;
751 BOOLEAN AddNetworkMenu
;
754 EFI_STRING NewStringTitle
;
757 Status
= EFI_SUCCESS
;
760 DriverHealthHandles
= NULL
;
761 AddNetworkMenu
= FALSE
;
765 // Connect all prior to entering the platform setup menu.
767 if (!gConnectAllHappened
) {
768 BdsLibConnectAllDriversToAllControllers ();
769 gConnectAllHappened
= TRUE
;
772 HiiHandle
= gDeviceManagerPrivate
.HiiHandle
;
773 if (HiiHandle
== NULL
) {
775 // Publish our HII data.
777 HiiHandle
= HiiAddPackages (
779 gDeviceManagerPrivate
.DriverHandle
,
784 if (HiiHandle
== NULL
) {
785 return EFI_OUT_OF_RESOURCES
;
788 gDeviceManagerPrivate
.HiiHandle
= HiiHandle
;
792 // If need show the Network device list form, clear the old save list first.
794 if ((mNextShowFormId
== NETWORK_DEVICE_LIST_FORM_ID
) && (mMacDeviceList
.CurListLen
> 0)) {
795 mMacDeviceList
.CurListLen
= 0;
799 // Update the network device form titile.
801 if (mNextShowFormId
== NETWORK_DEVICE_FORM_ID
) {
802 String
= HiiGetString (HiiHandle
, STRING_TOKEN (STR_FORM_NETWORK_DEVICE_TITLE
), NULL
);
803 NewStringLen
= StrLen(mSelectedMacAddrString
) * 2;
804 NewStringLen
+= (StrLen(String
) + 2) * 2;
805 NewStringTitle
= AllocatePool (NewStringLen
);
806 UnicodeSPrint (NewStringTitle
, NewStringLen
, L
"%s %s", String
, mSelectedMacAddrString
);
807 HiiSetString (HiiHandle
, STRING_TOKEN (STR_FORM_NETWORK_DEVICE_TITLE
), NewStringTitle
, NULL
);
809 FreePool (NewStringTitle
);
813 // Allocate space for creation of UpdateData Buffer
815 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
816 ASSERT (StartOpCodeHandle
!= NULL
);
818 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
819 ASSERT (EndOpCodeHandle
!= NULL
);
822 // Create Hii Extend Label OpCode as the start opcode
824 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
825 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
827 // According to the next show Form id(mNextShowFormId) to decide which form need to update.
829 StartLabel
->Number
= (UINT16
) (LABEL_FORM_ID_OFFSET
+ mNextShowFormId
);
832 // Create Hii Extend Label OpCode as the end opcode
834 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
835 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
836 EndLabel
->Number
= LABEL_END
;
839 // Get all the Hii handles
841 HiiHandles
= HiiGetHiiHandles (NULL
);
842 ASSERT (HiiHandles
!= NULL
);
845 // Search for formset of each class type
847 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
849 // The QuestionId in the form which will call the driver form has this asssumption.
850 // QuestionId = Handle Index + NETWORK_DEVICE_LIST_KEY_OFFSET;
851 // Different QuestionId at least has the section of NETWORK_DEVICE_LIST_KEY_OFFSET.
853 ASSERT(Index
< MAX_KEY_SECTION_LEN
);
855 if (!ExtractDisplayedHiiFormFromHiiHandle (HiiHandles
[Index
], &gEfiHiiPlatformSetupFormsetGuid
, &FormSetTitle
, &FormSetHelp
)) {
859 String
= HiiGetString (HiiHandles
[Index
], FormSetTitle
, NULL
);
860 if (String
== NULL
) {
861 String
= HiiGetString (HiiHandle
, STR_MISSING_STRING
, NULL
);
862 ASSERT (String
!= NULL
);
864 Token
= HiiSetString (HiiHandle
, 0, String
, NULL
);
867 String
= HiiGetString (HiiHandles
[Index
], FormSetHelp
, NULL
);
868 if (String
== NULL
) {
869 String
= HiiGetString (HiiHandle
, STR_MISSING_STRING
, NULL
);
870 ASSERT (String
!= NULL
);
872 TokenHelp
= HiiSetString (HiiHandle
, 0, String
, NULL
);
876 // Network device process
878 if (IsNeedAddNetworkMenu (HiiHandles
[Index
], &AddItemCount
)) {
879 if (mNextShowFormId
== DEVICE_MANAGER_FORM_ID
) {
881 // Only show one menu item "Network Config" in the device manger form.
883 if (!AddNetworkMenu
) {
884 AddNetworkMenu
= TRUE
;
885 HiiCreateGotoOpCode (
887 DEVICE_MANAGER_FORM_ID
,
888 STRING_TOKEN (STR_FORM_NETWORK_DEVICE_LIST_TITLE
),
889 STRING_TOKEN (STR_FORM_NETWORK_DEVICE_LIST_HELP
),
890 EFI_IFR_FLAG_CALLBACK
,
891 (EFI_QUESTION_ID
) QUESTION_NETWORK_DEVICE_ID
894 } else if (mNextShowFormId
== NETWORK_DEVICE_LIST_FORM_ID
) {
896 // In network device list form, same mac address device only show one menu.
898 while (AddItemCount
> 0) {
899 HiiCreateGotoOpCode (
901 NETWORK_DEVICE_LIST_FORM_ID
,
902 mMacDeviceList
.NodeList
[mMacDeviceList
.CurListLen
- AddItemCount
].PromptId
,
903 STRING_TOKEN (STR_NETWORK_DEVICE_HELP
),
904 EFI_IFR_FLAG_CALLBACK
,
905 mMacDeviceList
.NodeList
[mMacDeviceList
.CurListLen
- AddItemCount
].QuestionId
909 } else if (mNextShowFormId
== NETWORK_DEVICE_FORM_ID
) {
911 // In network device form, only the selected mac address device need to be show.
913 HiiCreateGotoOpCode (
915 NETWORK_DEVICE_FORM_ID
,
918 EFI_IFR_FLAG_CALLBACK
,
919 (EFI_QUESTION_ID
) (Index
+ DEVICE_KEY_OFFSET
)
925 // Not network device process, only need to show at device manger form.
927 if (mNextShowFormId
== DEVICE_MANAGER_FORM_ID
) {
928 HiiCreateGotoOpCode (
930 DEVICE_MANAGER_FORM_ID
,
933 EFI_IFR_FLAG_CALLBACK
,
934 (EFI_QUESTION_ID
) (Index
+ DEVICE_KEY_OFFSET
)
940 Status
= gBS
->LocateHandleBuffer (
942 &gEfiDriverHealthProtocolGuid
,
949 // If there are no drivers installed driver health protocol, do not create driver health entry in UI
951 if (NumHandles
!= 0) {
953 // If driver health protocol is installed, create Driver Health subtitle and entry
955 HiiCreateSubTitleOpCode (StartOpCodeHandle
, STRING_TOKEN (STR_DM_DRIVER_HEALTH_TITLE
), 0, 0, 0);
956 HiiCreateGotoOpCode (
958 DRIVER_HEALTH_FORM_ID
,
959 STRING_TOKEN(STR_DRIVER_HEALTH_ALL_HEALTHY
), // Prompt text
960 STRING_TOKEN(STR_DRIVER_HEALTH_STATUS_HELP
), // Help text
961 EFI_IFR_FLAG_CALLBACK
,
962 DEVICE_MANAGER_KEY_DRIVER_HEALTH
// Question ID
966 // Check All Driver health status
968 if (!PlaformHealthStatusCheck ()) {
970 // At least one driver in the platform are not in healthy status
972 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
), GetStringById (STRING_TOKEN (STR_DRIVER_NOT_HEALTH
)), NULL
);
975 // For the string of STR_DRIVER_HEALTH_ALL_HEALTHY previously has been updated and we need to update it while re-entry.
977 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
), GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
)), NULL
);
989 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
990 Status
= gFormBrowser2
->SendForm (
999 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1000 EnableResetRequired ();
1004 // We will have returned from processing a callback, selected
1005 // a target to display
1007 if ((gCallbackKey
>= DEVICE_KEY_OFFSET
)) {
1008 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1009 Status
= gFormBrowser2
->SendForm (
1011 &HiiHandles
[gCallbackKey
- DEVICE_KEY_OFFSET
],
1019 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1020 EnableResetRequired ();
1024 // Force return to Device Manager
1026 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1031 // Driver Health item chose.
1033 if (gCallbackKey
== DEVICE_MANAGER_KEY_DRIVER_HEALTH
) {
1034 CallDriverHealth ();
1036 // Force return to Device Manager
1038 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1043 // Enter from device manager and into the network device list.
1045 if (gCallbackKey
== QUESTION_NETWORK_DEVICE_ID
) {
1046 mNextShowFormId
= NETWORK_DEVICE_LIST_FORM_ID
;
1047 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1052 // In this case, go from the network device list to the specify device.
1054 if ((gCallbackKey
< MAX_KEY_SECTION_LEN
+ NETWORK_DEVICE_LIST_KEY_OFFSET
) && (gCallbackKey
>= NETWORK_DEVICE_LIST_KEY_OFFSET
)) {
1055 mNextShowFormId
= NETWORK_DEVICE_FORM_ID
;
1056 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1061 // Select the ESC, the gCallbackKey == 0.
1063 if(mNextShowFormId
- 1 < DEVICE_MANAGER_FORM_ID
) {
1064 mNextShowFormId
= DEVICE_MANAGER_FORM_ID
;
1066 mNextShowFormId
= (UINT16
) (mNextShowFormId
- 1);
1067 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1072 // Remove our packagelist from HII database.
1074 HiiRemovePackages (HiiHandle
);
1075 gDeviceManagerPrivate
.HiiHandle
= NULL
;
1077 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1078 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1079 FreePool (HiiHandles
);
1085 This function is invoked if user selected a interactive opcode from Driver Health's
1086 Formset. The decision by user is saved to gCallbackKey for later processing.
1088 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1089 @param Action Specifies the type of action taken by the browser.
1090 @param QuestionId A unique value which is sent to the original exporting driver
1091 so that it can identify the type of data to expect.
1092 @param Type The type of value for the question.
1093 @param Value A pointer to the data being sent to the original exporting driver.
1094 @param ActionRequest On return, points to the action requested by the callback function.
1096 @retval EFI_SUCCESS The callback successfully handled the action.
1097 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
1102 DriverHealthCallback (
1103 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1104 IN EFI_BROWSER_ACTION Action
,
1105 IN EFI_QUESTION_ID QuestionId
,
1107 IN EFI_IFR_TYPE_VALUE
*Value
,
1108 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1111 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1112 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1113 return EFI_INVALID_PARAMETER
;
1116 gCallbackKey
= QuestionId
;
1119 // Request to exit SendForm(), so as to switch to selected form
1121 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1127 // All other action return unsupported.
1129 return EFI_UNSUPPORTED
;
1133 Collect and display the platform's driver health relative information, allow user to do interactive
1134 operation while the platform is unhealthy.
1136 This function display a form which divided into two parts. The one list all modules which has installed
1137 driver health protocol. The list usually contain driver name, controller name, and it's health info.
1138 While the driver name can't be retrieved, will use device path as backup. The other part of the form provide
1139 a choice to the user to repair all platform.
1148 EFI_HII_HANDLE HiiHandle
;
1149 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
1150 EFI_IFR_GUID_LABEL
*StartLabel
;
1151 EFI_IFR_GUID_LABEL
*StartLabelRepair
;
1152 EFI_IFR_GUID_LABEL
*EndLabel
;
1153 EFI_IFR_GUID_LABEL
*EndLabelRepair
;
1154 VOID
*StartOpCodeHandle
;
1155 VOID
*EndOpCodeHandle
;
1156 VOID
*StartOpCodeHandleRepair
;
1157 VOID
*EndOpCodeHandleRepair
;
1159 EFI_STRING_ID Token
;
1160 EFI_STRING_ID TokenHelp
;
1162 EFI_STRING TmpString
;
1163 EFI_STRING DriverName
;
1164 EFI_STRING ControllerName
;
1165 LIST_ENTRY DriverHealthList
;
1166 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
1168 EFI_DEVICE_PATH_PROTOCOL
*DriverDevicePath
;
1170 BOOLEAN RebootRequired
;
1174 DriverHealthInfo
= NULL
;
1175 DriverDevicePath
= NULL
;
1176 InitializeListHead (&DriverHealthList
);
1178 HiiHandle
= gDeviceManagerPrivate
.DriverHealthHiiHandle
;
1179 if (HiiHandle
== NULL
) {
1181 // Publish Driver Health HII data.
1183 HiiHandle
= HiiAddPackages (
1184 &mDeviceManagerGuid
,
1185 gDeviceManagerPrivate
.DriverHealthHandle
,
1190 if (HiiHandle
== NULL
) {
1194 gDeviceManagerPrivate
.DriverHealthHiiHandle
= HiiHandle
;
1198 // Allocate space for creation of UpdateData Buffer
1200 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1201 ASSERT (StartOpCodeHandle
!= NULL
);
1203 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1204 ASSERT (EndOpCodeHandle
!= NULL
);
1206 StartOpCodeHandleRepair
= HiiAllocateOpCodeHandle ();
1207 ASSERT (StartOpCodeHandleRepair
!= NULL
);
1209 EndOpCodeHandleRepair
= HiiAllocateOpCodeHandle ();
1210 ASSERT (EndOpCodeHandleRepair
!= NULL
);
1213 // Create Hii Extend Label OpCode as the start opcode
1215 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1216 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1217 StartLabel
->Number
= LABEL_DRIVER_HEALTH
;
1220 // Create Hii Extend Label OpCode as the start opcode
1222 StartLabelRepair
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandleRepair
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1223 StartLabelRepair
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1224 StartLabelRepair
->Number
= LABEL_DRIVER_HEALTH_REAPIR_ALL
;
1227 // Create Hii Extend Label OpCode as the end opcode
1229 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1230 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1231 EndLabel
->Number
= LABEL_DRIVER_HEALTH_END
;
1234 // Create Hii Extend Label OpCode as the end opcode
1236 EndLabelRepair
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandleRepair
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1237 EndLabelRepair
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1238 EndLabelRepair
->Number
= LABEL_DRIVER_HEALTH_REAPIR_ALL_END
;
1240 HiiCreateSubTitleOpCode (StartOpCodeHandle
, STRING_TOKEN (STR_DH_STATUS_LIST
), 0, 0, 1);
1242 Status
= GetAllControllersHealthStatus (&DriverHealthList
);
1243 ASSERT (Status
!= EFI_OUT_OF_RESOURCES
);
1245 Link
= GetFirstNode (&DriverHealthList
);
1247 while (!IsNull (&DriverHealthList
, Link
)) {
1248 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
1251 // Assume no line strings is longer than 512 bytes.
1253 String
= (EFI_STRING
) AllocateZeroPool (0x200);
1254 ASSERT (String
!= NULL
);
1256 Status
= DriverHealthGetDriverName (DriverHealthInfo
->DriverHandle
, &DriverName
);
1257 if (EFI_ERROR (Status
)) {
1259 // Can not get the Driver name, so use the Device path
1261 DriverDevicePath
= DevicePathFromHandle (DriverHealthInfo
->DriverHandle
);
1262 DriverName
= DevicePathToStr (DriverDevicePath
);
1265 // Add the Driver name & Controller name into FormSetTitle string
1267 StrnCat (String
, DriverName
, StrLen (DriverName
));
1270 Status
= DriverHealthGetControllerName (
1271 DriverHealthInfo
->DriverHandle
,
1272 DriverHealthInfo
->ControllerHandle
,
1273 DriverHealthInfo
->ChildHandle
,
1277 if (!EFI_ERROR (Status
)) {
1279 // Can not get the Controller name, just let it empty.
1281 StrnCat (String
, L
" ", StrLen (L
" "));
1282 StrnCat (String
, ControllerName
, StrLen (ControllerName
));
1286 // Add the message of the Module itself provided after the string item.
1288 if ((DriverHealthInfo
->MessageList
!= NULL
) && (DriverHealthInfo
->MessageList
->StringId
!= 0)) {
1289 StrnCat (String
, L
" ", StrLen (L
" "));
1290 TmpString
= HiiGetString (
1291 DriverHealthInfo
->MessageList
->HiiHandle
,
1292 DriverHealthInfo
->MessageList
->StringId
,
1297 // Update the string will be displayed base on the driver's health status
1299 switch(DriverHealthInfo
->HealthStatus
) {
1300 case EfiDriverHealthStatusRepairRequired
:
1301 TmpString
= GetStringById (STRING_TOKEN (STR_REPAIR_REQUIRED
));
1303 case EfiDriverHealthStatusConfigurationRequired
:
1304 TmpString
= GetStringById (STRING_TOKEN (STR_CONFIGURATION_REQUIRED
));
1306 case EfiDriverHealthStatusFailed
:
1307 TmpString
= GetStringById (STRING_TOKEN (STR_OPERATION_FAILED
));
1309 case EfiDriverHealthStatusReconnectRequired
:
1310 TmpString
= GetStringById (STRING_TOKEN (STR_RECONNECT_REQUIRED
));
1312 case EfiDriverHealthStatusRebootRequired
:
1313 TmpString
= GetStringById (STRING_TOKEN (STR_REBOOT_REQUIRED
));
1316 TmpString
= GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_HEALTHY
));
1321 ASSERT (TmpString
!= NULL
);
1322 StrCat (String
, TmpString
);
1323 FreePool (TmpString
);
1325 Token
= HiiSetString (HiiHandle
, 0, String
, NULL
);
1328 TokenHelp
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_SINGLE_HELP
)), NULL
);
1330 HiiCreateActionOpCode (
1332 (EFI_QUESTION_ID
) (Index
+ DRIVER_HEALTH_KEY_OFFSET
),
1335 EFI_IFR_FLAG_CALLBACK
,
1339 Link
= GetNextNode (&DriverHealthList
, Link
);
1343 // Add End Opcode for Subtitle
1345 HiiCreateEndOpCode (StartOpCodeHandle
);
1347 HiiCreateSubTitleOpCode (StartOpCodeHandleRepair
, STRING_TOKEN (STR_DRIVER_HEALTH_REPAIR_ALL
), 0, 0, 1);
1348 TokenHelp
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_ALL_HELP
)), NULL
);
1350 if (PlaformHealthStatusCheck ()) {
1352 // No action need to do for the platform
1354 Token
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
)), NULL
);
1355 HiiCreateActionOpCode (
1356 StartOpCodeHandleRepair
,
1360 EFI_IFR_FLAG_READ_ONLY
,
1365 // Create ActionOpCode only while the platform need to do health related operation.
1367 Token
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_ALL_TITLE
)), NULL
);
1368 HiiCreateActionOpCode (
1369 StartOpCodeHandleRepair
,
1370 (EFI_QUESTION_ID
) DRIVER_HEALTH_REPAIR_ALL_KEY
,
1373 EFI_IFR_FLAG_CALLBACK
,
1378 HiiCreateEndOpCode (StartOpCodeHandleRepair
);
1380 Status
= HiiUpdateForm (
1383 DRIVER_HEALTH_FORM_ID
,
1387 ASSERT (Status
!= EFI_NOT_FOUND
);
1388 ASSERT (Status
!= EFI_BUFFER_TOO_SMALL
);
1390 Status
= HiiUpdateForm (
1393 DRIVER_HEALTH_FORM_ID
,
1394 StartOpCodeHandleRepair
,
1395 EndOpCodeHandleRepair
1397 ASSERT (Status
!= EFI_NOT_FOUND
);
1398 ASSERT (Status
!= EFI_BUFFER_TOO_SMALL
);
1400 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1401 Status
= gFormBrowser2
->SendForm (
1406 DRIVER_HEALTH_FORM_ID
,
1410 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1411 EnableResetRequired ();
1415 // We will have returned from processing a callback - user either hit ESC to exit, or selected
1416 // a target to display.
1417 // Process the diver health status states here.
1419 if (gCallbackKey
>= DRIVER_HEALTH_KEY_OFFSET
&& gCallbackKey
!= DRIVER_HEALTH_REPAIR_ALL_KEY
) {
1420 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1422 Link
= GetFirstNode (&DriverHealthList
);
1425 while (!IsNull (&DriverHealthList
, Link
)) {
1427 // Got the item relative node in the List
1429 if (Index
== (gCallbackKey
- DRIVER_HEALTH_KEY_OFFSET
)) {
1430 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
1432 // Process the driver's healthy status for the specify module
1434 RebootRequired
= FALSE
;
1435 ProcessSingleControllerHealth (
1436 DriverHealthInfo
->DriverHealth
,
1437 DriverHealthInfo
->ControllerHandle
,
1438 DriverHealthInfo
->ChildHandle
,
1439 DriverHealthInfo
->HealthStatus
,
1440 &(DriverHealthInfo
->MessageList
),
1441 DriverHealthInfo
->HiiHandle
,
1444 if (RebootRequired
) {
1445 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1450 Link
= GetNextNode (&DriverHealthList
, Link
);
1453 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1454 EnableResetRequired ();
1458 // Force return to the form of Driver Health in Device Manager
1460 gCallbackKey
= DRIVER_HEALTH_RETURN_KEY
;
1464 // Repair the whole platform
1466 if (gCallbackKey
== DRIVER_HEALTH_REPAIR_ALL_KEY
) {
1467 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1469 PlatformRepairAll (&DriverHealthList
);
1471 gCallbackKey
= DRIVER_HEALTH_RETURN_KEY
;
1475 // Remove driver health packagelist from HII database.
1477 HiiRemovePackages (HiiHandle
);
1478 gDeviceManagerPrivate
.DriverHealthHiiHandle
= NULL
;
1481 // Free driver health info list
1483 while (!IsListEmpty (&DriverHealthList
)) {
1485 Link
= GetFirstNode(&DriverHealthList
);
1486 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
1487 RemoveEntryList (Link
);
1489 if (DriverHealthInfo
->MessageList
!= NULL
) {
1490 FreePool(DriverHealthInfo
->MessageList
);
1491 FreePool (DriverHealthInfo
);
1495 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1496 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1497 HiiFreeOpCodeHandle (StartOpCodeHandleRepair
);
1498 HiiFreeOpCodeHandle (EndOpCodeHandleRepair
);
1500 if (gCallbackKey
== DRIVER_HEALTH_RETURN_KEY
) {
1502 // Force return to Driver Health Form
1504 gCallbackKey
= DEVICE_MANAGER_KEY_DRIVER_HEALTH
;
1505 CallDriverHealth ();
1511 Check the Driver Health status of a single controller and try to process it if not healthy.
1513 This function called by CheckAllControllersHealthStatus () function in order to process a specify
1514 contoller's health state.
1516 @param DriverHealthList A Pointer to the list contain all of the platform driver health information.
1517 @param DriverHandle The handle of driver.
1518 @param ControllerHandle The class guid specifies which form set will be displayed.
1519 @param ChildHandle The handle of the child controller to retrieve the health
1520 status on. This is an optional parameter that may be NULL.
1521 @param DriverHealth A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
1522 @param HealthStatus The health status of the controller.
1524 @retval EFI_INVALID_PARAMETER HealthStatus or DriverHealth is NULL.
1525 @retval HealthStatus The Health status of specify controller.
1526 @retval EFI_OUT_OF_RESOURCES The list of Driver Health Protocol handles can not be retrieved.
1527 @retval EFI_NOT_FOUND No controller in the platform install Driver Health Protocol.
1528 @retval EFI_SUCCESS The Health related operation has been taken successfully.
1533 GetSingleControllerHealthStatus (
1534 IN OUT LIST_ENTRY
*DriverHealthList
,
1535 IN EFI_HANDLE DriverHandle
,
1536 IN EFI_HANDLE ControllerHandle
, OPTIONAL
1537 IN EFI_HANDLE ChildHandle
, OPTIONAL
1538 IN EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
,
1539 IN EFI_DRIVER_HEALTH_STATUS
*HealthStatus
1543 EFI_DRIVER_HEALTH_HII_MESSAGE
*MessageList
;
1544 EFI_HII_HANDLE FormHiiHandle
;
1545 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
1547 if (HealthStatus
== NULL
) {
1549 // If HealthStatus is NULL, then return EFI_INVALID_PARAMETER
1551 return EFI_INVALID_PARAMETER
;
1555 // Assume the HealthStatus is healthy
1557 *HealthStatus
= EfiDriverHealthStatusHealthy
;
1559 if (DriverHealth
== NULL
) {
1561 // If DriverHealth is NULL, then return EFI_INVALID_PARAMETER
1563 return EFI_INVALID_PARAMETER
;
1566 if (ControllerHandle
== NULL
) {
1568 // If ControllerHandle is NULL, the return the cumulative health status of the driver
1570 Status
= DriverHealth
->GetHealthStatus (DriverHealth
, NULL
, NULL
, HealthStatus
, NULL
, NULL
);
1571 if (*HealthStatus
== EfiDriverHealthStatusHealthy
) {
1573 // Add the driver health related information into the list
1575 DriverHealthInfo
= AllocateZeroPool (sizeof (DRIVER_HEALTH_INFO
));
1576 if (DriverHealthInfo
== NULL
) {
1577 return EFI_OUT_OF_RESOURCES
;
1580 DriverHealthInfo
->Signature
= DEVICE_MANAGER_DRIVER_HEALTH_INFO_SIGNATURE
;
1581 DriverHealthInfo
->DriverHandle
= DriverHandle
;
1582 DriverHealthInfo
->ControllerHandle
= NULL
;
1583 DriverHealthInfo
->ChildHandle
= NULL
;
1584 DriverHealthInfo
->HiiHandle
= NULL
;
1585 DriverHealthInfo
->DriverHealth
= DriverHealth
;
1586 DriverHealthInfo
->MessageList
= NULL
;
1587 DriverHealthInfo
->HealthStatus
= *HealthStatus
;
1589 InsertTailList (DriverHealthList
, &DriverHealthInfo
->Link
);
1595 FormHiiHandle
= NULL
;
1598 // Collect the health status with the optional HII message list
1600 Status
= DriverHealth
->GetHealthStatus (DriverHealth
, ControllerHandle
, ChildHandle
, HealthStatus
, &MessageList
, &FormHiiHandle
);
1602 if (EFI_ERROR (Status
)) {
1604 // If the health status could not be retrieved, then return immediately
1610 // Add the driver health related information into the list
1612 DriverHealthInfo
= AllocateZeroPool (sizeof (DRIVER_HEALTH_INFO
));
1613 if (DriverHealthInfo
== NULL
) {
1614 return EFI_OUT_OF_RESOURCES
;
1617 DriverHealthInfo
->Signature
= DEVICE_MANAGER_DRIVER_HEALTH_INFO_SIGNATURE
;
1618 DriverHealthInfo
->DriverHandle
= DriverHandle
;
1619 DriverHealthInfo
->ControllerHandle
= ControllerHandle
;
1620 DriverHealthInfo
->ChildHandle
= ChildHandle
;
1621 DriverHealthInfo
->HiiHandle
= FormHiiHandle
;
1622 DriverHealthInfo
->DriverHealth
= DriverHealth
;
1623 DriverHealthInfo
->MessageList
= MessageList
;
1624 DriverHealthInfo
->HealthStatus
= *HealthStatus
;
1626 InsertTailList (DriverHealthList
, &DriverHealthInfo
->Link
);
1632 Collects all the EFI Driver Health Protocols currently present in the EFI Handle Database,
1633 and queries each EFI Driver Health Protocol to determine if one or more of the controllers
1634 managed by each EFI Driver Health Protocol instance are not healthy.
1636 @param DriverHealthList A Pointer to the list contain all of the platform driver health
1639 @retval EFI_NOT_FOUND No controller in the platform install Driver Health Protocol.
1640 @retval EFI_SUCCESS All the controllers in the platform are healthy.
1641 @retval EFI_OUT_OF_RESOURCES The list of Driver Health Protocol handles can not be retrieved.
1645 GetAllControllersHealthStatus (
1646 IN OUT LIST_ENTRY
*DriverHealthList
1651 EFI_HANDLE
*DriverHealthHandles
;
1652 EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
;
1653 EFI_DRIVER_HEALTH_STATUS HealthStatus
;
1654 UINTN DriverHealthIndex
;
1655 EFI_HANDLE
*Handles
;
1657 UINTN ControllerIndex
;
1661 // Initialize local variables
1664 DriverHealthHandles
= NULL
;
1668 HealthStatus
= EfiDriverHealthStatusHealthy
;
1670 Status
= gBS
->LocateHandleBuffer (
1672 &gEfiDriverHealthProtocolGuid
,
1675 &DriverHealthHandles
1678 if (Status
== EFI_NOT_FOUND
|| NumHandles
== 0) {
1680 // If there are no Driver Health Protocols handles, then return EFI_NOT_FOUND
1682 return EFI_NOT_FOUND
;
1685 if (EFI_ERROR (Status
) || DriverHealthHandles
== NULL
) {
1687 // If the list of Driver Health Protocol handles can not be retrieved, then
1688 // return EFI_OUT_OF_RESOURCES
1690 return EFI_OUT_OF_RESOURCES
;
1694 // Check the health status of all controllers in the platform
1695 // Start by looping through all the Driver Health Protocol handles in the handle database
1697 for (DriverHealthIndex
= 0; DriverHealthIndex
< NumHandles
; DriverHealthIndex
++) {
1699 // Skip NULL Driver Health Protocol handles
1701 if (DriverHealthHandles
[DriverHealthIndex
] == NULL
) {
1706 // Retrieve the Driver Health Protocol from DriverHandle
1708 Status
= gBS
->HandleProtocol (
1709 DriverHealthHandles
[DriverHealthIndex
],
1710 &gEfiDriverHealthProtocolGuid
,
1711 (VOID
**)&DriverHealth
1713 if (EFI_ERROR (Status
)) {
1715 // If the Driver Health Protocol can not be retrieved, then skip to the next
1716 // Driver Health Protocol handle
1722 // Check the health of all the controllers managed by a Driver Health Protocol handle
1724 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], NULL
, NULL
, DriverHealth
, &HealthStatus
);
1727 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1728 // and skip to the next Driver Health Protocol handle
1730 if (EFI_ERROR (Status
)) {
1735 // If all the controllers managed by this Driver Health Protocol are healthy, then skip to the next
1736 // Driver Health Protocol handle
1738 if (HealthStatus
== EfiDriverHealthStatusHealthy
) {
1743 // See if the list of all handles in the handle database has been retrieved
1746 if (Handles
== NULL
) {
1748 // Retrieve the list of all handles from the handle database
1750 Status
= gBS
->LocateHandleBuffer (
1757 if (EFI_ERROR (Status
) || Handles
== NULL
) {
1759 // If all the handles in the handle database can not be retrieved, then
1760 // return EFI_OUT_OF_RESOURCES
1762 Status
= EFI_OUT_OF_RESOURCES
;
1767 // Loop through all the controller handles in the handle database
1769 for (ControllerIndex
= 0; ControllerIndex
< HandleCount
; ControllerIndex
++) {
1771 // Skip NULL controller handles
1773 if (Handles
[ControllerIndex
] == NULL
) {
1777 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], Handles
[ControllerIndex
], NULL
, DriverHealth
, &HealthStatus
);
1778 if (EFI_ERROR (Status
)) {
1780 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1782 HealthStatus
= EfiDriverHealthStatusHealthy
;
1786 // If CheckHealthSingleController() returned an error on a terminal state, then do not check the health of child controllers
1788 if (EFI_ERROR (Status
)) {
1793 // Loop through all the child handles in the handle database
1795 for (ChildIndex
= 0; ChildIndex
< HandleCount
; ChildIndex
++) {
1797 // Skip NULL child handles
1799 if (Handles
[ChildIndex
] == NULL
) {
1803 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], Handles
[ControllerIndex
], Handles
[ChildIndex
], DriverHealth
, &HealthStatus
);
1804 if (EFI_ERROR (Status
)) {
1806 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1808 HealthStatus
= EfiDriverHealthStatusHealthy
;
1812 // If CheckHealthSingleController() returned an error on a terminal state, then skip to the next child
1814 if (EFI_ERROR (Status
)) {
1821 Status
= EFI_SUCCESS
;
1824 if (Handles
!= NULL
) {
1825 gBS
->FreePool (Handles
);
1827 if (DriverHealthHandles
!= NULL
) {
1828 gBS
->FreePool (DriverHealthHandles
);
1836 Check the healthy status of the platform, this function will return immediately while found one driver
1837 in the platform are not healthy.
1839 @retval FALSE at least one driver in the platform are not healthy.
1840 @retval TRUE No controller install Driver Health Protocol,
1841 or all controllers in the platform are in healthy status.
1844 PlaformHealthStatusCheck (
1848 EFI_DRIVER_HEALTH_STATUS HealthStatus
;
1852 EFI_HANDLE
*DriverHealthHandles
;
1853 EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
;
1857 // Initialize local variables
1859 DriverHealthHandles
= NULL
;
1860 DriverHealth
= NULL
;
1862 HealthStatus
= EfiDriverHealthStatusHealthy
;
1864 Status
= gBS
->LocateHandleBuffer (
1866 &gEfiDriverHealthProtocolGuid
,
1869 &DriverHealthHandles
1872 // There are no handles match the search for Driver Health Protocol has been installed.
1874 if (Status
== EFI_NOT_FOUND
) {
1878 // Assume all modules are healthy.
1883 // Found one or more Handles.
1885 if (!EFI_ERROR (Status
)) {
1886 for (Index
= 0; Index
< NoHandles
; Index
++) {
1887 Status
= gBS
->HandleProtocol (
1888 DriverHealthHandles
[Index
],
1889 &gEfiDriverHealthProtocolGuid
,
1890 (VOID
**) &DriverHealth
1892 if (!EFI_ERROR (Status
)) {
1893 Status
= DriverHealth
->GetHealthStatus (
1903 // Get the healthy status of the module
1905 if (!EFI_ERROR (Status
)) {
1906 if (HealthStatus
!= EfiDriverHealthStatusHealthy
) {
1908 // Return immediately one driver's status not in healthy.
1919 Processes a single controller using the EFI Driver Health Protocol associated with
1920 that controller. This algorithm continues to query the GetHealthStatus() service until
1921 one of the legal terminal states of the EFI Driver Health Protocol is reached. This may
1922 require the processing of HII Messages, HII Form, and invocation of repair operations.
1924 @param DriverHealth A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
1925 @param ControllerHandle The class guid specifies which form set will be displayed.
1926 @param ChildHandle The handle of the child controller to retrieve the health
1927 status on. This is an optional parameter that may be NULL.
1928 @param HealthStatus The health status of the controller.
1929 @param MessageList An array of warning or error messages associated
1930 with the controller specified by ControllerHandle and
1931 ChildHandle. This is an optional parameter that may be NULL.
1932 @param FormHiiHandle The HII handle for an HII form associated with the
1933 controller specified by ControllerHandle and ChildHandle.
1934 @param RebootRequired Indicate whether a reboot is required to repair the controller.
1937 ProcessSingleControllerHealth (
1938 IN EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
,
1939 IN EFI_HANDLE ControllerHandle
, OPTIONAL
1940 IN EFI_HANDLE ChildHandle
, OPTIONAL
1941 IN EFI_DRIVER_HEALTH_STATUS HealthStatus
,
1942 IN EFI_DRIVER_HEALTH_HII_MESSAGE
**MessageList
, OPTIONAL
1943 IN EFI_HII_HANDLE FormHiiHandle
,
1944 IN OUT BOOLEAN
*RebootRequired
1948 EFI_DRIVER_HEALTH_STATUS LocalHealthStatus
;
1950 LocalHealthStatus
= HealthStatus
;
1952 // If the module need to be repaired or reconfiguration, will process it until
1953 // reach a terminal status. The status from EfiDriverHealthStatusRepairRequired after repair
1954 // will be in (Health, Failed, Configuration Required).
1956 while(LocalHealthStatus
== EfiDriverHealthStatusConfigurationRequired
||
1957 LocalHealthStatus
== EfiDriverHealthStatusRepairRequired
) {
1959 if (LocalHealthStatus
== EfiDriverHealthStatusRepairRequired
) {
1960 Status
= DriverHealth
->Repair (
1964 (EFI_DRIVER_HEALTH_REPAIR_PROGRESS_NOTIFY
) RepairNotify
1968 // Via a form of the driver need to do configuration provided to process of status in
1969 // EfiDriverHealthStatusConfigurationRequired. The status after configuration should be in
1970 // (Healthy, Reboot Required, Failed, Reconnect Required, Repair Required).
1972 if (LocalHealthStatus
== EfiDriverHealthStatusConfigurationRequired
) {
1973 if (FormHiiHandle
!= NULL
) {
1974 Status
= gFormBrowser2
->SendForm (
1978 &gEfiHiiDriverHealthFormsetGuid
,
1983 ASSERT( !EFI_ERROR (Status
));
1986 // Exit the loop in case no FormHiiHandle is supplied to prevent dead-loop
1992 Status
= DriverHealth
->GetHealthStatus (
2000 ASSERT_EFI_ERROR (Status
);
2002 if (*MessageList
!= NULL
) {
2003 ProcessMessages (*MessageList
);
2008 // Health status in {Healthy, Failed} may also have Messages need to process
2010 if (LocalHealthStatus
== EfiDriverHealthStatusHealthy
|| LocalHealthStatus
== EfiDriverHealthStatusFailed
) {
2011 if (*MessageList
!= NULL
) {
2012 ProcessMessages (*MessageList
);
2016 // Check for RebootRequired or ReconnectRequired
2018 if (LocalHealthStatus
== EfiDriverHealthStatusRebootRequired
) {
2019 *RebootRequired
= TRUE
;
2023 // Do reconnect if need.
2025 if (LocalHealthStatus
== EfiDriverHealthStatusReconnectRequired
) {
2026 Status
= gBS
->DisconnectController (ControllerHandle
, NULL
, NULL
);
2027 if (EFI_ERROR (Status
)) {
2029 // Disconnect failed. Need to promote reconnect to a reboot.
2031 *RebootRequired
= TRUE
;
2033 gBS
->ConnectController (ControllerHandle
, NULL
, NULL
, TRUE
);
2040 Platform specific notification function for controller repair operations.
2042 If the driver for a controller support the Driver Health Protocol and the
2043 current state of the controller is EfiDriverHealthStatusRepairRequired then
2044 when the Repair() service of the Driver Health Protocol is called, this
2045 platform specific notification function can display the progress of the repair
2046 operation. Some platforms may choose to not display anything, other may choose
2047 to show the percentage complete on text consoles, and other may choose to render
2048 a progress bar on text and graphical consoles.
2050 This function displays the percentage of the repair operation that has been
2051 completed on text consoles. The percentage is Value / Limit * 100%.
2053 @param Value Value in the range 0..Limit the the repair has completed..
2054 @param Limit The maximum value of Value
2066 Print(L
"Repair Progress Undefined\n\r");
2068 Percent
= Value
* 100 / Limit
;
2069 Print(L
"Repair Progress = %3d%%\n\r", Percent
);
2074 Processes a set of messages returned by the GetHealthStatus ()
2075 service of the EFI Driver Health Protocol
2077 @param MessageList The MessageList point to messages need to processed.
2082 IN EFI_DRIVER_HEALTH_HII_MESSAGE
*MessageList
2086 EFI_STRING MessageString
;
2088 for (MessageIndex
= 0;
2089 MessageList
[MessageIndex
].HiiHandle
!= NULL
;
2092 MessageString
= HiiGetString (
2093 MessageList
[MessageIndex
].HiiHandle
,
2094 MessageList
[MessageIndex
].StringId
,
2097 if (MessageString
!= NULL
) {
2099 // User can customize the output. Just simply print out the MessageString like below.
2100 // Also can use the HiiHandle to display message on the front page.
2102 // Print(L"%s\n",MessageString);
2103 // gBS->Stall (100000);
2110 Repair the whole platform.
2112 This function is the main entry for user choose "Repair All" in the front page.
2113 It will try to do recovery job till all the driver health protocol installed modules
2114 reach a terminal state.
2116 @param DriverHealthList A Pointer to the list contain all of the platform driver health
2122 IN LIST_ENTRY
*DriverHealthList
2125 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
2127 BOOLEAN RebootRequired
;
2129 ASSERT (DriverHealthList
!= NULL
);
2131 RebootRequired
= FALSE
;
2133 for ( Link
= GetFirstNode (DriverHealthList
)
2134 ; !IsNull (DriverHealthList
, Link
)
2135 ; Link
= GetNextNode (DriverHealthList
, Link
)
2137 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
2139 // Do driver health status operation by each link node
2141 ASSERT (DriverHealthInfo
!= NULL
);
2143 ProcessSingleControllerHealth (
2144 DriverHealthInfo
->DriverHealth
,
2145 DriverHealthInfo
->ControllerHandle
,
2146 DriverHealthInfo
->ChildHandle
,
2147 DriverHealthInfo
->HealthStatus
,
2148 &(DriverHealthInfo
->MessageList
),
2149 DriverHealthInfo
->HiiHandle
,
2154 if (RebootRequired
) {
2155 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
2161 Select the best matching language according to front page policy for best user experience.
2163 This function supports both ISO 639-2 and RFC 4646 language codes, but language
2164 code types may not be mixed in a single call to this function.
2166 @param SupportedLanguages A pointer to a Null-terminated ASCII string that
2167 contains a set of language codes in the format
2168 specified by Iso639Language.
2169 @param Iso639Language If TRUE, then all language codes are assumed to be
2170 in ISO 639-2 format. If FALSE, then all language
2171 codes are assumed to be in RFC 4646 language format.
2173 @retval NULL The best matching language could not be found in SupportedLanguages.
2174 @retval NULL There are not enough resources available to return the best matching
2176 @retval Other A pointer to a Null-terminated ASCII string that is the best matching
2177 language in SupportedLanguages.
2180 DriverHealthSelectBestLanguage (
2181 IN CHAR8
*SupportedLanguages
,
2182 IN BOOLEAN Iso639Language
2185 CHAR8
*LanguageVariable
;
2186 CHAR8
*BestLanguage
;
2188 LanguageVariable
= GetEfiGlobalVariable (Iso639Language
? L
"Lang" : L
"PlatformLang");
2190 BestLanguage
= GetBestLanguage(
2193 (LanguageVariable
!= NULL
) ? LanguageVariable
: "",
2194 Iso639Language
? "eng" : "en-US",
2197 if (LanguageVariable
!= NULL
) {
2198 FreePool (LanguageVariable
);
2201 return BestLanguage
;
2208 This is an internal worker function to get the Component Name (2) protocol interface
2209 and the language it supports.
2211 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
2212 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
2213 @param ComponentName A pointer to the Component Name (2) protocol interface.
2214 @param SupportedLanguage The best suitable language that matches the SupportedLangues interface for the
2215 located Component Name (2) instance.
2217 @retval EFI_SUCCESS The Component Name (2) protocol instance is successfully located and we find
2218 the best matching language it support.
2219 @retval EFI_UNSUPPORTED The input Language is not supported by the Component Name (2) protocol.
2220 @retval Other Some error occurs when locating Component Name (2) protocol instance or finding
2221 the supported language.
2225 GetComponentNameWorker (
2226 IN EFI_GUID
*ProtocolGuid
,
2227 IN EFI_HANDLE DriverBindingHandle
,
2228 OUT EFI_COMPONENT_NAME_PROTOCOL
**ComponentName
,
2229 OUT CHAR8
**SupportedLanguage
2235 // Locate Component Name (2) protocol on the driver binging handle.
2237 Status
= gBS
->OpenProtocol (
2238 DriverBindingHandle
,
2240 (VOID
**) ComponentName
,
2243 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2245 if (EFI_ERROR (Status
)) {
2250 // Apply shell policy to select the best language.
2252 *SupportedLanguage
= DriverHealthSelectBestLanguage (
2253 (*ComponentName
)->SupportedLanguages
,
2254 (BOOLEAN
) (ProtocolGuid
== &gEfiComponentNameProtocolGuid
)
2256 if (*SupportedLanguage
== NULL
) {
2257 Status
= EFI_UNSUPPORTED
;
2265 This is an internal worker function to get driver name from Component Name (2) protocol interface.
2268 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
2269 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
2270 @param DriverName A pointer to the Unicode string to return. This Unicode string is the name
2271 of the driver specified by This.
2273 @retval EFI_SUCCESS The driver name is successfully retrieved from Component Name (2) protocol
2275 @retval Other The driver name cannot be retrieved from Component Name (2) protocol
2280 GetDriverNameWorker (
2281 IN EFI_GUID
*ProtocolGuid
,
2282 IN EFI_HANDLE DriverBindingHandle
,
2283 OUT CHAR16
**DriverName
2287 CHAR8
*BestLanguage
;
2288 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
2291 // Retrieve Component Name (2) protocol instance on the driver binding handle and
2292 // find the best language this instance supports.
2294 Status
= GetComponentNameWorker (
2296 DriverBindingHandle
,
2300 if (EFI_ERROR (Status
)) {
2305 // Get the driver name from Component Name (2) protocol instance on the driver binging handle.
2307 Status
= ComponentName
->GetDriverName (
2312 FreePool (BestLanguage
);
2319 This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface
2320 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name.
2321 If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward
2322 compatibility support.
2324 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
2325 @param DriverName A pointer to the Unicode string to return. This Unicode string is the name
2326 of the driver specified by This.
2328 @retval EFI_SUCCESS The driver name is successfully retrieved from Component Name (2) protocol
2330 @retval Other The driver name cannot be retrieved from Component Name (2) protocol
2335 DriverHealthGetDriverName (
2336 IN EFI_HANDLE DriverBindingHandle
,
2337 OUT CHAR16
**DriverName
2343 // Get driver name from UEFI 2.0 Component Name 2 protocol interface.
2345 Status
= GetDriverNameWorker (&gEfiComponentName2ProtocolGuid
, DriverBindingHandle
, DriverName
);
2346 if (EFI_ERROR (Status
)) {
2348 // If it fails to get the driver name from Component Name protocol interface, we should fall back on
2349 // EFI 1.1 Component Name protocol interface.
2351 Status
= GetDriverNameWorker (&gEfiComponentNameProtocolGuid
, DriverBindingHandle
, DriverName
);
2360 This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
2361 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
2362 If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
2363 compatibility support.
2365 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
2366 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
2367 @param ControllerHandle The handle of a controller that the driver specified by This is managing.
2368 This handle specifies the controller whose name is to be returned.
2369 @param ChildHandle The handle of the child controller to retrieve the name of. This is an
2370 optional parameter that may be NULL. It will be NULL for device drivers.
2371 It will also be NULL for bus drivers that attempt to retrieve the name
2372 of the bus controller. It will not be NULL for a bus driver that attempts
2373 to retrieve the name of a child controller.
2374 @param ControllerName A pointer to the Unicode string to return. This Unicode string
2375 is the name of the controller specified by ControllerHandle and ChildHandle.
2377 @retval EFI_SUCCESS The controller name is successfully retrieved from Component Name (2) protocol
2379 @retval Other The controller name cannot be retrieved from Component Name (2) protocol.
2383 GetControllerNameWorker (
2384 IN EFI_GUID
*ProtocolGuid
,
2385 IN EFI_HANDLE DriverBindingHandle
,
2386 IN EFI_HANDLE ControllerHandle
,
2387 IN EFI_HANDLE ChildHandle
,
2388 OUT CHAR16
**ControllerName
2392 CHAR8
*BestLanguage
;
2393 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
2396 // Retrieve Component Name (2) protocol instance on the driver binding handle and
2397 // find the best language this instance supports.
2399 Status
= GetComponentNameWorker (
2401 DriverBindingHandle
,
2405 if (EFI_ERROR (Status
)) {
2410 // Get the controller name from Component Name (2) protocol instance on the driver binging handle.
2412 Status
= ComponentName
->GetControllerName (
2419 FreePool (BestLanguage
);
2426 This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
2427 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
2428 If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
2429 compatibility support.
2431 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
2432 @param ControllerHandle The handle of a controller that the driver specified by This is managing.
2433 This handle specifies the controller whose name is to be returned.
2434 @param ChildHandle The handle of the child controller to retrieve the name of. This is an
2435 optional parameter that may be NULL. It will be NULL for device drivers.
2436 It will also be NULL for bus drivers that attempt to retrieve the name
2437 of the bus controller. It will not be NULL for a bus driver that attempts
2438 to retrieve the name of a child controller.
2439 @param ControllerName A pointer to the Unicode string to return. This Unicode string
2440 is the name of the controller specified by ControllerHandle and ChildHandle.
2442 @retval EFI_SUCCESS The controller name is successfully retrieved from Component Name (2) protocol
2444 @retval Other The controller name cannot be retrieved from Component Name (2) protocol.
2448 DriverHealthGetControllerName (
2449 IN EFI_HANDLE DriverBindingHandle
,
2450 IN EFI_HANDLE ControllerHandle
,
2451 IN EFI_HANDLE ChildHandle
,
2452 OUT CHAR16
**ControllerName
2458 // Get controller name from UEFI 2.0 Component Name 2 protocol interface.
2460 Status
= GetControllerNameWorker (
2461 &gEfiComponentName2ProtocolGuid
,
2462 DriverBindingHandle
,
2467 if (EFI_ERROR (Status
)) {
2469 // If it fails to get the controller name from Component Name protocol interface, we should fall back on
2470 // EFI 1.1 Component Name protocol interface.
2472 Status
= GetControllerNameWorker (
2473 &gEfiComponentNameProtocolGuid
,
2474 DriverBindingHandle
,