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
38 // Which Mac Address string is select
39 // it will decide what menu need to show in the NETWORK_DEVICE_FORM_ID form.
41 EFI_STRING mSelectedMacAddrString
;
44 // Which form Id need to be show.
46 EFI_FORM_ID mNextShowFormId
= DEVICE_MANAGER_FORM_ID
;
49 // The Mac Address show in the NETWORK_DEVICE_LIST_FORM_ID
51 MAC_ADDRESS_NODE_LIST mMacDeviceList
;
53 DEVICE_MANAGER_MENU_ITEM mDeviceManagerMenuItemTable
[] = {
54 { STRING_TOKEN (STR_DISK_DEVICE
), EFI_DISK_DEVICE_CLASS
},
55 { STRING_TOKEN (STR_VIDEO_DEVICE
), EFI_VIDEO_DEVICE_CLASS
},
56 { STRING_TOKEN (STR_NETWORK_DEVICE
), EFI_NETWORK_DEVICE_CLASS
},
57 { STRING_TOKEN (STR_INPUT_DEVICE
), EFI_INPUT_DEVICE_CLASS
},
58 { STRING_TOKEN (STR_ON_BOARD_DEVICE
), EFI_ON_BOARD_DEVICE_CLASS
},
59 { STRING_TOKEN (STR_OTHER_DEVICE
), EFI_OTHER_DEVICE_CLASS
}
62 HII_VENDOR_DEVICE_PATH mDeviceManagerHiiVendorDevicePath
= {
68 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
69 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
72 DEVICE_MANAGER_FORMSET_GUID
76 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
78 (UINT8
) (END_DEVICE_PATH_LENGTH
),
79 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
84 HII_VENDOR_DEVICE_PATH mDriverHealthHiiVendorDevicePath
= {
90 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
91 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
94 DRIVER_HEALTH_FORMSET_GUID
98 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
100 (UINT8
) (END_DEVICE_PATH_LENGTH
),
101 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
107 This function is invoked if user selected a interactive opcode from Device Manager's
108 Formset. The decision by user is saved to gCallbackKey for later processing. If
109 user set VBIOS, the new value is saved to EFI variable.
111 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
112 @param Action Specifies the type of action taken by the browser.
113 @param QuestionId A unique value which is sent to the original exporting driver
114 so that it can identify the type of data to expect.
115 @param Type The type of value for the question.
116 @param Value A pointer to the data being sent to the original exporting driver.
117 @param ActionRequest On return, points to the action requested by the callback function.
119 @retval EFI_SUCCESS The callback successfully handled the action.
120 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
125 DeviceManagerCallback (
126 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
127 IN EFI_BROWSER_ACTION Action
,
128 IN EFI_QUESTION_ID QuestionId
,
130 IN EFI_IFR_TYPE_VALUE
*Value
,
131 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
136 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
137 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
138 return EFI_INVALID_PARAMETER
;
141 gCallbackKey
= QuestionId
;
142 if ((QuestionId
< MAX_KEY_SECTION_LEN
+ NETWORK_DEVICE_LIST_KEY_OFFSET
) && (QuestionId
>= NETWORK_DEVICE_LIST_KEY_OFFSET
)) {
144 // If user select the mac address, need to record mac address string to support next form show.
146 for (CurIndex
= 0; CurIndex
< mMacDeviceList
.CurListLen
; CurIndex
++) {
147 if (mMacDeviceList
.NodeList
[CurIndex
].QuestionId
== QuestionId
) {
148 mSelectedMacAddrString
= HiiGetString (gDeviceManagerPrivate
.HiiHandle
, mMacDeviceList
.NodeList
[CurIndex
].PromptId
, NULL
);
154 // Request to exit SendForm(), so as to switch to selected form
156 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
162 // All other action return unsupported.
164 return EFI_UNSUPPORTED
;
169 This function registers HII packages to HII database.
171 @retval EFI_SUCCESS HII packages for the Device Manager were registered successfully.
172 @retval EFI_OUT_OF_RESOURCES HII packages for the Device Manager failed to be registered.
176 InitializeDeviceManager (
183 // Install Device Path Protocol and Config Access protocol to driver handle
185 Status
= gBS
->InstallMultipleProtocolInterfaces (
186 &gDeviceManagerPrivate
.DriverHandle
,
187 &gEfiDevicePathProtocolGuid
,
188 &mDeviceManagerHiiVendorDevicePath
,
189 &gEfiHiiConfigAccessProtocolGuid
,
190 &gDeviceManagerPrivate
.ConfigAccess
,
193 ASSERT_EFI_ERROR (Status
);
195 Status
= gBS
->InstallMultipleProtocolInterfaces (
196 &gDeviceManagerPrivate
.DriverHealthHandle
,
197 &gEfiDevicePathProtocolGuid
,
198 &mDriverHealthHiiVendorDevicePath
,
199 &gEfiHiiConfigAccessProtocolGuid
,
200 &gDeviceManagerPrivate
.DriverHealthConfigAccess
,
203 ASSERT_EFI_ERROR (Status
);
205 mMacDeviceList
.CurListLen
= 0;
206 mMacDeviceList
.MaxListLen
= 0;
212 Extract the displayed formset for given HII handle and class guid.
214 @param Handle The HII handle.
215 @param SetupClassGuid The class guid specifies which form set will be displayed.
216 @param FormSetTitle Formset title string.
217 @param FormSetHelp Formset help string.
219 @retval TRUE The formset for given HII handle will be displayed.
220 @return FALSE The formset for given HII handle will not be displayed.
224 ExtractDisplayedHiiFormFromHiiHandle (
225 IN EFI_HII_HANDLE Handle
,
226 IN EFI_GUID
*SetupClassGuid
,
227 OUT EFI_STRING_ID
*FormSetTitle
,
228 OUT EFI_STRING_ID
*FormSetHelp
233 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
238 UINT32 PackageListLength
;
239 EFI_HII_PACKAGE_HEADER PackageHeader
;
243 ASSERT (Handle
!= NULL
);
244 ASSERT (SetupClassGuid
!= NULL
);
245 ASSERT (FormSetTitle
!= NULL
);
246 ASSERT (FormSetHelp
!= NULL
);
254 // Get HII PackageList
257 HiiPackageList
= NULL
;
258 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
260 // Handle is a invalid handle. Check if Handle is corrupted.
262 ASSERT (Status
!= EFI_NOT_FOUND
);
264 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
266 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
268 HiiPackageList
= AllocatePool (BufferSize
);
269 ASSERT (HiiPackageList
!= NULL
);
271 Status
= gHiiDatabase
->ExportPackageLists (gHiiDatabase
, Handle
, &BufferSize
, HiiPackageList
);
272 if (EFI_ERROR (Status
)) {
277 // Get Form package from this HII package List
279 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
281 PackageListLength
= ReadUnaligned32 (&HiiPackageList
->PackageLength
);
283 while (Offset
< PackageListLength
) {
284 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
285 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
287 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
289 // Search FormSet Opcode in this Form Package
291 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
292 while (Offset2
< PackageHeader
.Length
) {
293 OpCodeData
= Package
+ Offset2
;
295 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
296 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
> OFFSET_OF (EFI_IFR_FORM_SET
, Flags
)) {
298 // Find FormSet OpCode
300 ClassGuidNum
= (UINT8
) (((EFI_IFR_FORM_SET
*) OpCodeData
)->Flags
& 0x3);
301 ClassGuid
= (EFI_GUID
*) (VOID
*)(OpCodeData
+ sizeof (EFI_IFR_FORM_SET
));
302 while (ClassGuidNum
-- > 0) {
303 if (CompareGuid (SetupClassGuid
, ClassGuid
)) {
304 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
305 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
306 FreePool (HiiPackageList
);
312 CopyMem (FormSetTitle
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->FormSetTitle
, sizeof (EFI_STRING_ID
));
313 CopyMem (FormSetHelp
, &((EFI_IFR_FORM_SET
*) OpCodeData
)->Help
, sizeof (EFI_STRING_ID
));
314 FreePool (HiiPackageList
);
322 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
327 // Go to next package
329 Offset
+= PackageHeader
.Length
;
332 FreePool (HiiPackageList
);
338 Get the mac address string from the device path.
339 if the device path has the vlan, get the vanid also.
341 @param MacAddressNode Device path begin with mac address
342 @param PBuffer Output string buffer contain mac address.
347 IN MAC_ADDR_DEVICE_PATH
*MacAddressNode
,
354 EFI_DEVICE_PATH_PROTOCOL
*Node
;
361 ASSERT(MacAddressNode
!= NULL
);
363 HwAddressSize
= sizeof (EFI_MAC_ADDRESS
);
364 if (MacAddressNode
->IfType
== 0x01 || MacAddressNode
->IfType
== 0x00) {
369 // The output format is MAC:XX:XX:XX:...\XXXX
370 // The size is the Number size + ":" size + Vlan size(\XXXX) + End
372 BufferLen
= (4 + 2 * HwAddressSize
+ (HwAddressSize
- 1) + 5 + 1) * sizeof (CHAR16
);
373 String
= AllocateZeroPool (BufferLen
);
374 if (String
== NULL
) {
379 StrCpy(String
, L
"MAC:");
383 // Convert the MAC address into a unicode string.
385 HwAddress
= &MacAddressNode
->MacAddress
.Addr
[0];
386 for (Index
= 0; Index
< HwAddressSize
; Index
++) {
387 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, *(HwAddress
++), 2);
388 if (Index
< HwAddressSize
- 1) {
394 // If VLAN is configured, it will need extra 5 characters like "\0005".
395 // Plus one unicode character for the null-terminator.
397 Node
= (EFI_DEVICE_PATH_PROTOCOL
*)MacAddressNode
;
398 while (!IsDevicePathEnd (Node
)) {
399 if (Node
->Type
== MESSAGING_DEVICE_PATH
&& Node
->SubType
== MSG_VLAN_DP
) {
400 VlanId
= ((VLAN_DEVICE_PATH
*) Node
)->VlanId
;
402 Node
= NextDevicePathNode (Node
);
407 String
+= UnicodeValueToString (String
, PREFIX_ZERO
| RADIX_HEX
, VlanId
, 4);
411 // Null terminate the Unicode string
419 Save question id and prompt id to the mac device list.
420 If the same mac address has saved yet, no need to add more.
422 @param MacAddrString Mac address string.
424 @retval EFI_SUCCESS Add the item is successful.
425 @return Other values if failed to Add the item.
428 AddIdToMacDeviceList (
429 IN EFI_STRING MacAddrString
432 MENU_INFO_ITEM
*TempDeviceList
;
434 EFI_STRING StoredString
;
435 EFI_STRING_ID PromptId
;
436 EFI_HII_HANDLE HiiHandle
;
438 HiiHandle
= gDeviceManagerPrivate
.HiiHandle
;
439 TempDeviceList
= NULL
;
441 for (Index
= 0; Index
< mMacDeviceList
.CurListLen
; Index
++) {
442 StoredString
= HiiGetString (HiiHandle
, mMacDeviceList
.NodeList
[Index
].PromptId
, NULL
);
443 if (StoredString
== NULL
) {
448 // Already has save the same mac address to the list.
450 if (StrCmp (MacAddrString
, StoredString
) == 0) {
455 PromptId
= HiiSetString(HiiHandle
, 0, MacAddrString
, NULL
);
457 // If not in the list, save it.
459 if (mMacDeviceList
.MaxListLen
> mMacDeviceList
.CurListLen
+ 1) {
460 mMacDeviceList
.NodeList
[mMacDeviceList
.CurListLen
].PromptId
= PromptId
;
461 mMacDeviceList
.NodeList
[mMacDeviceList
.CurListLen
].QuestionId
= (EFI_QUESTION_ID
) (mMacDeviceList
.CurListLen
+ NETWORK_DEVICE_LIST_KEY_OFFSET
);
463 mMacDeviceList
.MaxListLen
+= MAX_MAC_ADDRESS_NODE_LIST_LEN
;
464 if (mMacDeviceList
.CurListLen
!= 0) {
465 TempDeviceList
= (MENU_INFO_ITEM
*)AllocateCopyPool (sizeof (MENU_INFO_ITEM
) * mMacDeviceList
.MaxListLen
, (VOID
*)mMacDeviceList
.NodeList
);
467 TempDeviceList
= (MENU_INFO_ITEM
*)AllocatePool (sizeof (MENU_INFO_ITEM
) * mMacDeviceList
.MaxListLen
);
470 if (TempDeviceList
== NULL
) {
473 TempDeviceList
[mMacDeviceList
.CurListLen
].PromptId
= PromptId
;
474 TempDeviceList
[mMacDeviceList
.CurListLen
].QuestionId
= (EFI_QUESTION_ID
) (mMacDeviceList
.CurListLen
+ NETWORK_DEVICE_LIST_KEY_OFFSET
);
476 if (mMacDeviceList
.CurListLen
> 0) {
477 FreePool(mMacDeviceList
.NodeList
);
480 mMacDeviceList
.NodeList
= TempDeviceList
;
482 mMacDeviceList
.CurListLen
++;
488 Check the devcie path, try to find whether it has mac address path.
490 In this function, first need to check whether this path has mac address path.
491 second, when the mac address device path has find, also need to deicide whether
492 need to add this mac address relate info to the menu.
494 @param *Node Input device which need to be check.
495 @param *NeedAddItem Whether need to add the menu in the network device list.
497 @retval TRUE Has mac address device path.
498 @retval FALSE NOT Has mac address device path.
502 IsMacAddressDevicePath (
504 OUT BOOLEAN
*NeedAddItem
507 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
511 ASSERT (Node
!= NULL
);
512 *NeedAddItem
= FALSE
;
516 DevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) Node
;
519 // find the partition device path node
521 while (!IsDevicePathEnd (DevicePath
)) {
522 if ((DevicePathType (DevicePath
) == MESSAGING_DEVICE_PATH
) &&
523 (DevicePathSubType (DevicePath
) == MSG_MAC_ADDR_DP
)) {
526 if (DEVICE_MANAGER_FORM_ID
== mNextShowFormId
) {
531 if (!GetMacAddressString((MAC_ADDR_DEVICE_PATH
*)DevicePath
, &Buffer
)) {
535 if (NETWORK_DEVICE_FORM_ID
== mNextShowFormId
) {
536 if (StrCmp (Buffer
, mSelectedMacAddrString
) == 0) {
542 if (NETWORK_DEVICE_LIST_FORM_ID
== mNextShowFormId
) {
544 // Same handle may has two network child handle, so the questionid
545 // has the offset of SAME_HANDLE_KEY_OFFSET.
547 if (AddIdToMacDeviceList (Buffer
)) {
553 DevicePath
= NextDevicePathNode (DevicePath
);
556 if (Buffer
!= NULL
) {
564 Check to see if the device path is for the network device.
566 @param Handle The HII handle which include the mac address device path.
567 @param ItemCount The new add Mac address item count.
569 @retval TRUE Need to add new item in the menu.
570 @return FALSE Do not need to add the menu about the network.
574 IsNeedAddNetworkMenu (
575 IN EFI_HII_HANDLE Handle
,
582 EFI_HANDLE DriverHandle
;
583 EFI_HANDLE ControllerHandle
;
584 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
585 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
586 EFI_DEVICE_PATH_PROTOCOL
*ChildDevicePath
;
587 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
591 OpenInfoBuffer
= NULL
;
592 if ((Handle
== NULL
) || (ItemCount
== NULL
)) {
597 Status
= gHiiDatabase
->GetPackageListHandle (gHiiDatabase
, Handle
, &DriverHandle
);
598 if (EFI_ERROR (Status
)) {
602 // Get the device path by the got Driver handle .
604 Status
= gBS
->HandleProtocol (DriverHandle
, &gEfiDevicePathProtocolGuid
, (VOID
**) &DevicePath
);
605 if (EFI_ERROR (Status
)) {
608 TmpDevicePath
= DevicePath
;
611 // Check whether this device path include mac address device path.
612 // If this path has mac address path, get the value whether need
613 // add this info to the menu and return.
614 // Else check more about the child handle devcie path.
616 if (IsMacAddressDevicePath(TmpDevicePath
, &IsNeedAdd
)) {
617 if ((NETWORK_DEVICE_LIST_FORM_ID
== mNextShowFormId
) && IsNeedAdd
) {
624 // Search whether this path is the controller path, not he child handle path.
625 // And the child handle has the network devcie connected.
627 TmpDevicePath
= DevicePath
;
628 Status
= gBS
->LocateDevicePath(&gEfiDevicePathProtocolGuid
, &TmpDevicePath
, &ControllerHandle
);
629 if (EFI_ERROR (Status
)) {
633 if (!IsDevicePathEnd (TmpDevicePath
)) {
638 // Retrieve the list of agents that are consuming the specific protocol
639 // on ControllerHandle.
640 // The buffer point by OpenInfoBuffer need be free at this function.
642 Status
= gBS
->OpenProtocolInformation (
644 &gEfiPciIoProtocolGuid
,
648 if (EFI_ERROR (Status
)) {
653 // Inspect if ChildHandle is one of the agents.
655 Status
= EFI_UNSUPPORTED
;
656 for (Index
= 0; Index
< EntryCount
; Index
++) {
658 // Query all the children created by the controller handle's driver
660 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
661 Status
= gBS
->OpenProtocol (
662 OpenInfoBuffer
[Index
].ControllerHandle
,
663 &gEfiDevicePathProtocolGuid
,
664 (VOID
**) &ChildDevicePath
,
667 EFI_OPEN_PROTOCOL_GET_PROTOCOL
669 if (EFI_ERROR (Status
)) {
674 // Check whether this device path include mac address device path.
676 if (!IsMacAddressDevicePath(ChildDevicePath
, &IsNeedAdd
)) {
678 // If this path not has mac address path, check the other.
683 // If need to update the NETWORK_DEVICE_LIST_FORM, try to get more.
685 if ((NETWORK_DEVICE_LIST_FORM_ID
== mNextShowFormId
)) {
692 // If need to update other form, return whether need to add to the menu.
701 if (OpenInfoBuffer
!= NULL
) {
702 FreePool (OpenInfoBuffer
);
708 Call the browser and display the device manager to allow user
709 to configure the platform.
711 This function create the dynamic content for device manager. It includes
712 section header for all class of devices, one-of opcode to set VBIOS.
714 @retval EFI_SUCCESS Operation is successful.
715 @return Other values if failed to clean up the dynamic content from HII
728 EFI_STRING_ID TokenHelp
;
729 EFI_HII_HANDLE
*HiiHandles
;
730 EFI_HII_HANDLE HiiHandle
;
731 EFI_STRING_ID FormSetTitle
;
732 EFI_STRING_ID FormSetHelp
;
733 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
734 VOID
*StartOpCodeHandle
;
735 VOID
*EndOpCodeHandle
;
736 EFI_IFR_GUID_LABEL
*StartLabel
;
737 EFI_IFR_GUID_LABEL
*EndLabel
;
739 EFI_HANDLE
*DriverHealthHandles
;
740 BOOLEAN AddNetworkMenu
;
743 EFI_STRING NewStringTitle
;
746 Status
= EFI_SUCCESS
;
749 DriverHealthHandles
= NULL
;
750 AddNetworkMenu
= FALSE
;
754 // Connect all prior to entering the platform setup menu.
756 if (!gConnectAllHappened
) {
757 BdsLibConnectAllDriversToAllControllers ();
758 gConnectAllHappened
= TRUE
;
761 HiiHandle
= gDeviceManagerPrivate
.HiiHandle
;
762 if (HiiHandle
== NULL
) {
764 // Publish our HII data.
766 HiiHandle
= HiiAddPackages (
767 &gDeviceManagerFormSetGuid
,
768 gDeviceManagerPrivate
.DriverHandle
,
773 if (HiiHandle
== NULL
) {
774 return EFI_OUT_OF_RESOURCES
;
777 gDeviceManagerPrivate
.HiiHandle
= HiiHandle
;
781 // If need show the Network device list form, clear the old save list first.
783 if ((mNextShowFormId
== NETWORK_DEVICE_LIST_FORM_ID
) && (mMacDeviceList
.CurListLen
> 0)) {
784 mMacDeviceList
.CurListLen
= 0;
788 // Update the network device form titile.
790 if (mNextShowFormId
== NETWORK_DEVICE_FORM_ID
) {
791 String
= HiiGetString (HiiHandle
, STRING_TOKEN (STR_FORM_NETWORK_DEVICE_TITLE
), NULL
);
792 NewStringLen
= StrLen(mSelectedMacAddrString
) * 2;
793 NewStringLen
+= (StrLen(String
) + 2) * 2;
794 NewStringTitle
= AllocatePool (NewStringLen
);
795 UnicodeSPrint (NewStringTitle
, NewStringLen
, L
"%s %s", String
, mSelectedMacAddrString
);
796 HiiSetString (HiiHandle
, STRING_TOKEN (STR_FORM_NETWORK_DEVICE_TITLE
), NewStringTitle
, NULL
);
798 FreePool (NewStringTitle
);
802 // Allocate space for creation of UpdateData Buffer
804 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
805 ASSERT (StartOpCodeHandle
!= NULL
);
807 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
808 ASSERT (EndOpCodeHandle
!= NULL
);
811 // Create Hii Extend Label OpCode as the start opcode
813 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
814 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
816 // According to the next show Form id(mNextShowFormId) to decide which form need to update.
818 StartLabel
->Number
= (UINT16
) (LABEL_FORM_ID_OFFSET
+ mNextShowFormId
);
821 // Create Hii Extend Label OpCode as the end opcode
823 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
824 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
825 EndLabel
->Number
= LABEL_END
;
828 // Get all the Hii handles
830 HiiHandles
= HiiGetHiiHandles (NULL
);
831 ASSERT (HiiHandles
!= NULL
);
834 // Search for formset of each class type
836 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
838 // The QuestionId in the form which will call the driver form has this asssumption.
839 // QuestionId = Handle Index + NETWORK_DEVICE_LIST_KEY_OFFSET;
840 // Different QuestionId at least has the section of NETWORK_DEVICE_LIST_KEY_OFFSET.
842 ASSERT(Index
< MAX_KEY_SECTION_LEN
);
844 if (!ExtractDisplayedHiiFormFromHiiHandle (HiiHandles
[Index
], &gEfiHiiPlatformSetupFormsetGuid
, &FormSetTitle
, &FormSetHelp
)) {
848 String
= HiiGetString (HiiHandles
[Index
], FormSetTitle
, NULL
);
849 if (String
== NULL
) {
850 String
= HiiGetString (HiiHandle
, STR_MISSING_STRING
, NULL
);
851 ASSERT (String
!= NULL
);
853 Token
= HiiSetString (HiiHandle
, 0, String
, NULL
);
856 String
= HiiGetString (HiiHandles
[Index
], FormSetHelp
, NULL
);
857 if (String
== NULL
) {
858 String
= HiiGetString (HiiHandle
, STR_MISSING_STRING
, NULL
);
859 ASSERT (String
!= NULL
);
861 TokenHelp
= HiiSetString (HiiHandle
, 0, String
, NULL
);
865 // Network device process
867 if (IsNeedAddNetworkMenu (HiiHandles
[Index
], &AddItemCount
)) {
868 if (mNextShowFormId
== DEVICE_MANAGER_FORM_ID
) {
870 // Only show one menu item "Network Config" in the device manger form.
872 if (!AddNetworkMenu
) {
873 AddNetworkMenu
= TRUE
;
874 HiiCreateGotoOpCode (
876 DEVICE_MANAGER_FORM_ID
,
877 STRING_TOKEN (STR_FORM_NETWORK_DEVICE_LIST_TITLE
),
878 STRING_TOKEN (STR_FORM_NETWORK_DEVICE_LIST_HELP
),
879 EFI_IFR_FLAG_CALLBACK
,
880 (EFI_QUESTION_ID
) QUESTION_NETWORK_DEVICE_ID
883 } else if (mNextShowFormId
== NETWORK_DEVICE_LIST_FORM_ID
) {
885 // In network device list form, same mac address device only show one menu.
887 while (AddItemCount
> 0) {
888 HiiCreateGotoOpCode (
890 NETWORK_DEVICE_LIST_FORM_ID
,
891 mMacDeviceList
.NodeList
[mMacDeviceList
.CurListLen
- AddItemCount
].PromptId
,
892 STRING_TOKEN (STR_NETWORK_DEVICE_HELP
),
893 EFI_IFR_FLAG_CALLBACK
,
894 mMacDeviceList
.NodeList
[mMacDeviceList
.CurListLen
- AddItemCount
].QuestionId
898 } else if (mNextShowFormId
== NETWORK_DEVICE_FORM_ID
) {
900 // In network device form, only the selected mac address device need to be show.
902 HiiCreateGotoOpCode (
904 NETWORK_DEVICE_FORM_ID
,
907 EFI_IFR_FLAG_CALLBACK
,
908 (EFI_QUESTION_ID
) (Index
+ DEVICE_KEY_OFFSET
)
914 // Not network device process, only need to show at device manger form.
916 if (mNextShowFormId
== DEVICE_MANAGER_FORM_ID
) {
917 HiiCreateGotoOpCode (
919 DEVICE_MANAGER_FORM_ID
,
922 EFI_IFR_FLAG_CALLBACK
,
923 (EFI_QUESTION_ID
) (Index
+ DEVICE_KEY_OFFSET
)
929 Status
= gBS
->LocateHandleBuffer (
931 &gEfiDriverHealthProtocolGuid
,
938 // If there are no drivers installed driver health protocol, do not create driver health entry in UI
940 if (NumHandles
!= 0) {
942 // If driver health protocol is installed, create Driver Health subtitle and entry
944 HiiCreateSubTitleOpCode (StartOpCodeHandle
, STRING_TOKEN (STR_DM_DRIVER_HEALTH_TITLE
), 0, 0, 0);
945 HiiCreateGotoOpCode (
947 DRIVER_HEALTH_FORM_ID
,
948 STRING_TOKEN(STR_DRIVER_HEALTH_ALL_HEALTHY
), // Prompt text
949 STRING_TOKEN(STR_DRIVER_HEALTH_STATUS_HELP
), // Help text
950 EFI_IFR_FLAG_CALLBACK
,
951 DEVICE_MANAGER_KEY_DRIVER_HEALTH
// Question ID
955 // Check All Driver health status
957 if (!PlaformHealthStatusCheck ()) {
959 // At least one driver in the platform are not in healthy status
961 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
), GetStringById (STRING_TOKEN (STR_DRIVER_NOT_HEALTH
)), NULL
);
964 // For the string of STR_DRIVER_HEALTH_ALL_HEALTHY previously has been updated and we need to update it while re-entry.
966 HiiSetString (HiiHandle
, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
), GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
)), NULL
);
972 &gDeviceManagerFormSetGuid
,
978 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
979 Status
= gFormBrowser2
->SendForm (
983 &gDeviceManagerFormSetGuid
,
988 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
989 EnableResetRequired ();
993 // We will have returned from processing a callback, selected
994 // a target to display
996 if ((gCallbackKey
>= DEVICE_KEY_OFFSET
)) {
997 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
998 Status
= gFormBrowser2
->SendForm (
1000 &HiiHandles
[gCallbackKey
- DEVICE_KEY_OFFSET
],
1008 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1009 EnableResetRequired ();
1013 // Force return to Device Manager
1015 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1020 // Driver Health item chose.
1022 if (gCallbackKey
== DEVICE_MANAGER_KEY_DRIVER_HEALTH
) {
1023 CallDriverHealth ();
1025 // Force return to Device Manager
1027 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1032 // Enter from device manager and into the network device list.
1034 if (gCallbackKey
== QUESTION_NETWORK_DEVICE_ID
) {
1035 mNextShowFormId
= NETWORK_DEVICE_LIST_FORM_ID
;
1036 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1041 // In this case, go from the network device list to the specify device.
1043 if ((gCallbackKey
< MAX_KEY_SECTION_LEN
+ NETWORK_DEVICE_LIST_KEY_OFFSET
) && (gCallbackKey
>= NETWORK_DEVICE_LIST_KEY_OFFSET
)) {
1044 mNextShowFormId
= NETWORK_DEVICE_FORM_ID
;
1045 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1050 // Select the ESC, the gCallbackKey == 0.
1052 if(mNextShowFormId
- 1 < DEVICE_MANAGER_FORM_ID
) {
1053 mNextShowFormId
= DEVICE_MANAGER_FORM_ID
;
1055 mNextShowFormId
= (UINT16
) (mNextShowFormId
- 1);
1056 gCallbackKey
= FRONT_PAGE_KEY_DEVICE_MANAGER
;
1061 // Remove our packagelist from HII database.
1063 HiiRemovePackages (HiiHandle
);
1064 gDeviceManagerPrivate
.HiiHandle
= NULL
;
1066 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1067 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1068 FreePool (HiiHandles
);
1074 This function is invoked if user selected a interactive opcode from Driver Health's
1075 Formset. The decision by user is saved to gCallbackKey for later processing.
1077 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1078 @param Action Specifies the type of action taken by the browser.
1079 @param QuestionId A unique value which is sent to the original exporting driver
1080 so that it can identify the type of data to expect.
1081 @param Type The type of value for the question.
1082 @param Value A pointer to the data being sent to the original exporting driver.
1083 @param ActionRequest On return, points to the action requested by the callback function.
1085 @retval EFI_SUCCESS The callback successfully handled the action.
1086 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
1091 DriverHealthCallback (
1092 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
1093 IN EFI_BROWSER_ACTION Action
,
1094 IN EFI_QUESTION_ID QuestionId
,
1096 IN EFI_IFR_TYPE_VALUE
*Value
,
1097 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
1100 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1101 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
1102 return EFI_INVALID_PARAMETER
;
1105 gCallbackKey
= QuestionId
;
1108 // Request to exit SendForm(), so as to switch to selected form
1110 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
1116 // All other action return unsupported.
1118 return EFI_UNSUPPORTED
;
1122 Collect and display the platform's driver health relative information, allow user to do interactive
1123 operation while the platform is unhealthy.
1125 This function display a form which divided into two parts. The one list all modules which has installed
1126 driver health protocol. The list usually contain driver name, controller name, and it's health info.
1127 While the driver name can't be retrieved, will use device path as backup. The other part of the form provide
1128 a choice to the user to repair all platform.
1137 EFI_HII_HANDLE HiiHandle
;
1138 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
1139 EFI_IFR_GUID_LABEL
*StartLabel
;
1140 EFI_IFR_GUID_LABEL
*StartLabelRepair
;
1141 EFI_IFR_GUID_LABEL
*EndLabel
;
1142 EFI_IFR_GUID_LABEL
*EndLabelRepair
;
1143 VOID
*StartOpCodeHandle
;
1144 VOID
*EndOpCodeHandle
;
1145 VOID
*StartOpCodeHandleRepair
;
1146 VOID
*EndOpCodeHandleRepair
;
1148 EFI_STRING_ID Token
;
1149 EFI_STRING_ID TokenHelp
;
1151 EFI_STRING TmpString
;
1152 EFI_STRING DriverName
;
1153 EFI_STRING ControllerName
;
1154 LIST_ENTRY DriverHealthList
;
1155 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
1157 EFI_DEVICE_PATH_PROTOCOL
*DriverDevicePath
;
1158 BOOLEAN RebootRequired
;
1161 DriverHealthInfo
= NULL
;
1162 DriverDevicePath
= NULL
;
1163 InitializeListHead (&DriverHealthList
);
1165 HiiHandle
= gDeviceManagerPrivate
.DriverHealthHiiHandle
;
1166 if (HiiHandle
== NULL
) {
1168 // Publish Driver Health HII data.
1170 HiiHandle
= HiiAddPackages (
1171 &gDeviceManagerFormSetGuid
,
1172 gDeviceManagerPrivate
.DriverHealthHandle
,
1177 if (HiiHandle
== NULL
) {
1181 gDeviceManagerPrivate
.DriverHealthHiiHandle
= HiiHandle
;
1185 // Allocate space for creation of UpdateData Buffer
1187 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
1188 ASSERT (StartOpCodeHandle
!= NULL
);
1190 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
1191 ASSERT (EndOpCodeHandle
!= NULL
);
1193 StartOpCodeHandleRepair
= HiiAllocateOpCodeHandle ();
1194 ASSERT (StartOpCodeHandleRepair
!= NULL
);
1196 EndOpCodeHandleRepair
= HiiAllocateOpCodeHandle ();
1197 ASSERT (EndOpCodeHandleRepair
!= NULL
);
1200 // Create Hii Extend Label OpCode as the start opcode
1202 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1203 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1204 StartLabel
->Number
= LABEL_DRIVER_HEALTH
;
1207 // Create Hii Extend Label OpCode as the start opcode
1209 StartLabelRepair
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandleRepair
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1210 StartLabelRepair
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1211 StartLabelRepair
->Number
= LABEL_DRIVER_HEALTH_REAPIR_ALL
;
1214 // Create Hii Extend Label OpCode as the end opcode
1216 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1217 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1218 EndLabel
->Number
= LABEL_DRIVER_HEALTH_END
;
1221 // Create Hii Extend Label OpCode as the end opcode
1223 EndLabelRepair
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandleRepair
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
1224 EndLabelRepair
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
1225 EndLabelRepair
->Number
= LABEL_DRIVER_HEALTH_REAPIR_ALL_END
;
1227 HiiCreateSubTitleOpCode (StartOpCodeHandle
, STRING_TOKEN (STR_DH_STATUS_LIST
), 0, 0, 1);
1229 Status
= GetAllControllersHealthStatus (&DriverHealthList
);
1230 ASSERT (Status
!= EFI_OUT_OF_RESOURCES
);
1232 Link
= GetFirstNode (&DriverHealthList
);
1234 while (!IsNull (&DriverHealthList
, Link
)) {
1235 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
1238 // Assume no line strings is longer than 512 bytes.
1240 String
= (EFI_STRING
) AllocateZeroPool (0x200);
1241 ASSERT (String
!= NULL
);
1243 Status
= DriverHealthGetDriverName (DriverHealthInfo
->DriverHandle
, &DriverName
);
1244 if (EFI_ERROR (Status
)) {
1246 // Can not get the Driver name, so use the Device path
1248 DriverDevicePath
= DevicePathFromHandle (DriverHealthInfo
->DriverHandle
);
1249 DriverName
= DevicePathToStr (DriverDevicePath
);
1252 // Add the Driver name & Controller name into FormSetTitle string
1254 StrnCat (String
, DriverName
, StrLen (DriverName
));
1257 Status
= DriverHealthGetControllerName (
1258 DriverHealthInfo
->DriverHandle
,
1259 DriverHealthInfo
->ControllerHandle
,
1260 DriverHealthInfo
->ChildHandle
,
1264 if (!EFI_ERROR (Status
)) {
1266 // Can not get the Controller name, just let it empty.
1268 StrnCat (String
, L
" ", StrLen (L
" "));
1269 StrnCat (String
, ControllerName
, StrLen (ControllerName
));
1273 // Add the message of the Module itself provided after the string item.
1275 if ((DriverHealthInfo
->MessageList
!= NULL
) && (DriverHealthInfo
->MessageList
->StringId
!= 0)) {
1276 StrnCat (String
, L
" ", StrLen (L
" "));
1277 TmpString
= HiiGetString (
1278 DriverHealthInfo
->MessageList
->HiiHandle
,
1279 DriverHealthInfo
->MessageList
->StringId
,
1284 // Update the string will be displayed base on the driver's health status
1286 switch(DriverHealthInfo
->HealthStatus
) {
1287 case EfiDriverHealthStatusRepairRequired
:
1288 TmpString
= GetStringById (STRING_TOKEN (STR_REPAIR_REQUIRED
));
1290 case EfiDriverHealthStatusConfigurationRequired
:
1291 TmpString
= GetStringById (STRING_TOKEN (STR_CONFIGURATION_REQUIRED
));
1293 case EfiDriverHealthStatusFailed
:
1294 TmpString
= GetStringById (STRING_TOKEN (STR_OPERATION_FAILED
));
1296 case EfiDriverHealthStatusReconnectRequired
:
1297 TmpString
= GetStringById (STRING_TOKEN (STR_RECONNECT_REQUIRED
));
1299 case EfiDriverHealthStatusRebootRequired
:
1300 TmpString
= GetStringById (STRING_TOKEN (STR_REBOOT_REQUIRED
));
1303 TmpString
= GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_HEALTHY
));
1308 ASSERT (TmpString
!= NULL
);
1309 StrCat (String
, TmpString
);
1310 FreePool (TmpString
);
1312 Token
= HiiSetString (HiiHandle
, 0, String
, NULL
);
1315 TokenHelp
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_SINGLE_HELP
)), NULL
);
1317 HiiCreateActionOpCode (
1319 (EFI_QUESTION_ID
) (Index
+ DRIVER_HEALTH_KEY_OFFSET
),
1322 EFI_IFR_FLAG_CALLBACK
,
1326 Link
= GetNextNode (&DriverHealthList
, Link
);
1330 // Add End Opcode for Subtitle
1332 HiiCreateEndOpCode (StartOpCodeHandle
);
1334 HiiCreateSubTitleOpCode (StartOpCodeHandleRepair
, STRING_TOKEN (STR_DRIVER_HEALTH_REPAIR_ALL
), 0, 0, 1);
1335 TokenHelp
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_ALL_HELP
)), NULL
);
1337 if (PlaformHealthStatusCheck ()) {
1339 // No action need to do for the platform
1341 Token
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY
)), NULL
);
1342 HiiCreateActionOpCode (
1343 StartOpCodeHandleRepair
,
1347 EFI_IFR_FLAG_READ_ONLY
,
1352 // Create ActionOpCode only while the platform need to do health related operation.
1354 Token
= HiiSetString (HiiHandle
, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_ALL_TITLE
)), NULL
);
1355 HiiCreateActionOpCode (
1356 StartOpCodeHandleRepair
,
1357 (EFI_QUESTION_ID
) DRIVER_HEALTH_REPAIR_ALL_KEY
,
1360 EFI_IFR_FLAG_CALLBACK
,
1365 HiiCreateEndOpCode (StartOpCodeHandleRepair
);
1367 Status
= HiiUpdateForm (
1369 &gDriverHealthFormSetGuid
,
1370 DRIVER_HEALTH_FORM_ID
,
1374 ASSERT (Status
!= EFI_NOT_FOUND
);
1375 ASSERT (Status
!= EFI_BUFFER_TOO_SMALL
);
1377 Status
= HiiUpdateForm (
1379 &gDriverHealthFormSetGuid
,
1380 DRIVER_HEALTH_FORM_ID
,
1381 StartOpCodeHandleRepair
,
1382 EndOpCodeHandleRepair
1384 ASSERT (Status
!= EFI_NOT_FOUND
);
1385 ASSERT (Status
!= EFI_BUFFER_TOO_SMALL
);
1387 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1388 Status
= gFormBrowser2
->SendForm (
1392 &gDriverHealthFormSetGuid
,
1393 DRIVER_HEALTH_FORM_ID
,
1397 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1398 EnableResetRequired ();
1402 // We will have returned from processing a callback - user either hit ESC to exit, or selected
1403 // a target to display.
1404 // Process the diver health status states here.
1406 if (gCallbackKey
>= DRIVER_HEALTH_KEY_OFFSET
&& gCallbackKey
!= DRIVER_HEALTH_REPAIR_ALL_KEY
) {
1407 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1409 Link
= GetFirstNode (&DriverHealthList
);
1412 while (!IsNull (&DriverHealthList
, Link
)) {
1414 // Got the item relative node in the List
1416 if (Index
== (gCallbackKey
- DRIVER_HEALTH_KEY_OFFSET
)) {
1417 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
1419 // Process the driver's healthy status for the specify module
1421 RebootRequired
= FALSE
;
1422 ProcessSingleControllerHealth (
1423 DriverHealthInfo
->DriverHealth
,
1424 DriverHealthInfo
->ControllerHandle
,
1425 DriverHealthInfo
->ChildHandle
,
1426 DriverHealthInfo
->HealthStatus
,
1427 &(DriverHealthInfo
->MessageList
),
1428 DriverHealthInfo
->HiiHandle
,
1431 if (RebootRequired
) {
1432 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
1437 Link
= GetNextNode (&DriverHealthList
, Link
);
1440 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
1441 EnableResetRequired ();
1445 // Force return to the form of Driver Health in Device Manager
1447 gCallbackKey
= DRIVER_HEALTH_RETURN_KEY
;
1451 // Repair the whole platform
1453 if (gCallbackKey
== DRIVER_HEALTH_REPAIR_ALL_KEY
) {
1454 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1456 PlatformRepairAll (&DriverHealthList
);
1458 gCallbackKey
= DRIVER_HEALTH_RETURN_KEY
;
1462 // Remove driver health packagelist from HII database.
1464 HiiRemovePackages (HiiHandle
);
1465 gDeviceManagerPrivate
.DriverHealthHiiHandle
= NULL
;
1468 // Free driver health info list
1470 while (!IsListEmpty (&DriverHealthList
)) {
1472 Link
= GetFirstNode(&DriverHealthList
);
1473 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
1474 RemoveEntryList (Link
);
1476 if (DriverHealthInfo
->MessageList
!= NULL
) {
1477 FreePool(DriverHealthInfo
->MessageList
);
1478 FreePool (DriverHealthInfo
);
1482 HiiFreeOpCodeHandle (StartOpCodeHandle
);
1483 HiiFreeOpCodeHandle (EndOpCodeHandle
);
1484 HiiFreeOpCodeHandle (StartOpCodeHandleRepair
);
1485 HiiFreeOpCodeHandle (EndOpCodeHandleRepair
);
1487 if (gCallbackKey
== DRIVER_HEALTH_RETURN_KEY
) {
1489 // Force return to Driver Health Form
1491 gCallbackKey
= DEVICE_MANAGER_KEY_DRIVER_HEALTH
;
1492 CallDriverHealth ();
1498 Check the Driver Health status of a single controller and try to process it if not healthy.
1500 This function called by CheckAllControllersHealthStatus () function in order to process a specify
1501 contoller's health state.
1503 @param DriverHealthList A Pointer to the list contain all of the platform driver health information.
1504 @param DriverHandle The handle of driver.
1505 @param ControllerHandle The class guid specifies which form set will be displayed.
1506 @param ChildHandle The handle of the child controller to retrieve the health
1507 status on. This is an optional parameter that may be NULL.
1508 @param DriverHealth A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
1509 @param HealthStatus The health status of the controller.
1511 @retval EFI_INVALID_PARAMETER HealthStatus or DriverHealth is NULL.
1512 @retval HealthStatus The Health status of specify controller.
1513 @retval EFI_OUT_OF_RESOURCES The list of Driver Health Protocol handles can not be retrieved.
1514 @retval EFI_NOT_FOUND No controller in the platform install Driver Health Protocol.
1515 @retval EFI_SUCCESS The Health related operation has been taken successfully.
1520 GetSingleControllerHealthStatus (
1521 IN OUT LIST_ENTRY
*DriverHealthList
,
1522 IN EFI_HANDLE DriverHandle
,
1523 IN EFI_HANDLE ControllerHandle
, OPTIONAL
1524 IN EFI_HANDLE ChildHandle
, OPTIONAL
1525 IN EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
,
1526 IN EFI_DRIVER_HEALTH_STATUS
*HealthStatus
1530 EFI_DRIVER_HEALTH_HII_MESSAGE
*MessageList
;
1531 EFI_HII_HANDLE FormHiiHandle
;
1532 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
1534 if (HealthStatus
== NULL
) {
1536 // If HealthStatus is NULL, then return EFI_INVALID_PARAMETER
1538 return EFI_INVALID_PARAMETER
;
1542 // Assume the HealthStatus is healthy
1544 *HealthStatus
= EfiDriverHealthStatusHealthy
;
1546 if (DriverHealth
== NULL
) {
1548 // If DriverHealth is NULL, then return EFI_INVALID_PARAMETER
1550 return EFI_INVALID_PARAMETER
;
1553 if (ControllerHandle
== NULL
) {
1555 // If ControllerHandle is NULL, the return the cumulative health status of the driver
1557 Status
= DriverHealth
->GetHealthStatus (DriverHealth
, NULL
, NULL
, HealthStatus
, NULL
, NULL
);
1558 if (*HealthStatus
== EfiDriverHealthStatusHealthy
) {
1560 // Add the driver health related information into the list
1562 DriverHealthInfo
= AllocateZeroPool (sizeof (DRIVER_HEALTH_INFO
));
1563 if (DriverHealthInfo
== NULL
) {
1564 return EFI_OUT_OF_RESOURCES
;
1567 DriverHealthInfo
->Signature
= DEVICE_MANAGER_DRIVER_HEALTH_INFO_SIGNATURE
;
1568 DriverHealthInfo
->DriverHandle
= DriverHandle
;
1569 DriverHealthInfo
->ControllerHandle
= NULL
;
1570 DriverHealthInfo
->ChildHandle
= NULL
;
1571 DriverHealthInfo
->HiiHandle
= NULL
;
1572 DriverHealthInfo
->DriverHealth
= DriverHealth
;
1573 DriverHealthInfo
->MessageList
= NULL
;
1574 DriverHealthInfo
->HealthStatus
= *HealthStatus
;
1576 InsertTailList (DriverHealthList
, &DriverHealthInfo
->Link
);
1582 FormHiiHandle
= NULL
;
1585 // Collect the health status with the optional HII message list
1587 Status
= DriverHealth
->GetHealthStatus (DriverHealth
, ControllerHandle
, ChildHandle
, HealthStatus
, &MessageList
, &FormHiiHandle
);
1589 if (EFI_ERROR (Status
)) {
1591 // If the health status could not be retrieved, then return immediately
1597 // Add the driver health related information into the list
1599 DriverHealthInfo
= AllocateZeroPool (sizeof (DRIVER_HEALTH_INFO
));
1600 if (DriverHealthInfo
== NULL
) {
1601 return EFI_OUT_OF_RESOURCES
;
1604 DriverHealthInfo
->Signature
= DEVICE_MANAGER_DRIVER_HEALTH_INFO_SIGNATURE
;
1605 DriverHealthInfo
->DriverHandle
= DriverHandle
;
1606 DriverHealthInfo
->ControllerHandle
= ControllerHandle
;
1607 DriverHealthInfo
->ChildHandle
= ChildHandle
;
1608 DriverHealthInfo
->HiiHandle
= FormHiiHandle
;
1609 DriverHealthInfo
->DriverHealth
= DriverHealth
;
1610 DriverHealthInfo
->MessageList
= MessageList
;
1611 DriverHealthInfo
->HealthStatus
= *HealthStatus
;
1613 InsertTailList (DriverHealthList
, &DriverHealthInfo
->Link
);
1619 Collects all the EFI Driver Health Protocols currently present in the EFI Handle Database,
1620 and queries each EFI Driver Health Protocol to determine if one or more of the controllers
1621 managed by each EFI Driver Health Protocol instance are not healthy.
1623 @param DriverHealthList A Pointer to the list contain all of the platform driver health
1626 @retval EFI_NOT_FOUND No controller in the platform install Driver Health Protocol.
1627 @retval EFI_SUCCESS All the controllers in the platform are healthy.
1628 @retval EFI_OUT_OF_RESOURCES The list of Driver Health Protocol handles can not be retrieved.
1632 GetAllControllersHealthStatus (
1633 IN OUT LIST_ENTRY
*DriverHealthList
1638 EFI_HANDLE
*DriverHealthHandles
;
1639 EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
;
1640 EFI_DRIVER_HEALTH_STATUS HealthStatus
;
1641 UINTN DriverHealthIndex
;
1642 EFI_HANDLE
*Handles
;
1644 UINTN ControllerIndex
;
1648 // Initialize local variables
1651 DriverHealthHandles
= NULL
;
1655 HealthStatus
= EfiDriverHealthStatusHealthy
;
1657 Status
= gBS
->LocateHandleBuffer (
1659 &gEfiDriverHealthProtocolGuid
,
1662 &DriverHealthHandles
1665 if (Status
== EFI_NOT_FOUND
|| NumHandles
== 0) {
1667 // If there are no Driver Health Protocols handles, then return EFI_NOT_FOUND
1669 return EFI_NOT_FOUND
;
1672 if (EFI_ERROR (Status
) || DriverHealthHandles
== NULL
) {
1674 // If the list of Driver Health Protocol handles can not be retrieved, then
1675 // return EFI_OUT_OF_RESOURCES
1677 return EFI_OUT_OF_RESOURCES
;
1681 // Check the health status of all controllers in the platform
1682 // Start by looping through all the Driver Health Protocol handles in the handle database
1684 for (DriverHealthIndex
= 0; DriverHealthIndex
< NumHandles
; DriverHealthIndex
++) {
1686 // Skip NULL Driver Health Protocol handles
1688 if (DriverHealthHandles
[DriverHealthIndex
] == NULL
) {
1693 // Retrieve the Driver Health Protocol from DriverHandle
1695 Status
= gBS
->HandleProtocol (
1696 DriverHealthHandles
[DriverHealthIndex
],
1697 &gEfiDriverHealthProtocolGuid
,
1698 (VOID
**)&DriverHealth
1700 if (EFI_ERROR (Status
)) {
1702 // If the Driver Health Protocol can not be retrieved, then skip to the next
1703 // Driver Health Protocol handle
1709 // Check the health of all the controllers managed by a Driver Health Protocol handle
1711 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], NULL
, NULL
, DriverHealth
, &HealthStatus
);
1714 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1715 // and skip to the next Driver Health Protocol handle
1717 if (EFI_ERROR (Status
)) {
1722 // If all the controllers managed by this Driver Health Protocol are healthy, then skip to the next
1723 // Driver Health Protocol handle
1725 if (HealthStatus
== EfiDriverHealthStatusHealthy
) {
1730 // See if the list of all handles in the handle database has been retrieved
1733 if (Handles
== NULL
) {
1735 // Retrieve the list of all handles from the handle database
1737 Status
= gBS
->LocateHandleBuffer (
1744 if (EFI_ERROR (Status
) || Handles
== NULL
) {
1746 // If all the handles in the handle database can not be retrieved, then
1747 // return EFI_OUT_OF_RESOURCES
1749 Status
= EFI_OUT_OF_RESOURCES
;
1754 // Loop through all the controller handles in the handle database
1756 for (ControllerIndex
= 0; ControllerIndex
< HandleCount
; ControllerIndex
++) {
1758 // Skip NULL controller handles
1760 if (Handles
[ControllerIndex
] == NULL
) {
1764 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], Handles
[ControllerIndex
], NULL
, DriverHealth
, &HealthStatus
);
1765 if (EFI_ERROR (Status
)) {
1767 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1769 HealthStatus
= EfiDriverHealthStatusHealthy
;
1773 // If CheckHealthSingleController() returned an error on a terminal state, then do not check the health of child controllers
1775 if (EFI_ERROR (Status
)) {
1780 // Loop through all the child handles in the handle database
1782 for (ChildIndex
= 0; ChildIndex
< HandleCount
; ChildIndex
++) {
1784 // Skip NULL child handles
1786 if (Handles
[ChildIndex
] == NULL
) {
1790 Status
= GetSingleControllerHealthStatus (DriverHealthList
, DriverHealthHandles
[DriverHealthIndex
], Handles
[ControllerIndex
], Handles
[ChildIndex
], DriverHealth
, &HealthStatus
);
1791 if (EFI_ERROR (Status
)) {
1793 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1795 HealthStatus
= EfiDriverHealthStatusHealthy
;
1799 // If CheckHealthSingleController() returned an error on a terminal state, then skip to the next child
1801 if (EFI_ERROR (Status
)) {
1808 Status
= EFI_SUCCESS
;
1811 if (Handles
!= NULL
) {
1812 gBS
->FreePool (Handles
);
1814 if (DriverHealthHandles
!= NULL
) {
1815 gBS
->FreePool (DriverHealthHandles
);
1823 Check the healthy status of the platform, this function will return immediately while found one driver
1824 in the platform are not healthy.
1826 @retval FALSE at least one driver in the platform are not healthy.
1827 @retval TRUE No controller install Driver Health Protocol,
1828 or all controllers in the platform are in healthy status.
1831 PlaformHealthStatusCheck (
1835 EFI_DRIVER_HEALTH_STATUS HealthStatus
;
1839 EFI_HANDLE
*DriverHealthHandles
;
1840 EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
;
1844 // Initialize local variables
1846 DriverHealthHandles
= NULL
;
1847 DriverHealth
= NULL
;
1849 HealthStatus
= EfiDriverHealthStatusHealthy
;
1851 Status
= gBS
->LocateHandleBuffer (
1853 &gEfiDriverHealthProtocolGuid
,
1856 &DriverHealthHandles
1859 // There are no handles match the search for Driver Health Protocol has been installed.
1861 if (Status
== EFI_NOT_FOUND
) {
1865 // Assume all modules are healthy.
1870 // Found one or more Handles.
1872 if (!EFI_ERROR (Status
)) {
1873 for (Index
= 0; Index
< NoHandles
; Index
++) {
1874 Status
= gBS
->HandleProtocol (
1875 DriverHealthHandles
[Index
],
1876 &gEfiDriverHealthProtocolGuid
,
1877 (VOID
**) &DriverHealth
1879 if (!EFI_ERROR (Status
)) {
1880 Status
= DriverHealth
->GetHealthStatus (
1890 // Get the healthy status of the module
1892 if (!EFI_ERROR (Status
)) {
1893 if (HealthStatus
!= EfiDriverHealthStatusHealthy
) {
1895 // Return immediately one driver's status not in healthy.
1906 Processes a single controller using the EFI Driver Health Protocol associated with
1907 that controller. This algorithm continues to query the GetHealthStatus() service until
1908 one of the legal terminal states of the EFI Driver Health Protocol is reached. This may
1909 require the processing of HII Messages, HII Form, and invocation of repair operations.
1911 @param DriverHealth A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
1912 @param ControllerHandle The class guid specifies which form set will be displayed.
1913 @param ChildHandle The handle of the child controller to retrieve the health
1914 status on. This is an optional parameter that may be NULL.
1915 @param HealthStatus The health status of the controller.
1916 @param MessageList An array of warning or error messages associated
1917 with the controller specified by ControllerHandle and
1918 ChildHandle. This is an optional parameter that may be NULL.
1919 @param FormHiiHandle The HII handle for an HII form associated with the
1920 controller specified by ControllerHandle and ChildHandle.
1921 @param RebootRequired Indicate whether a reboot is required to repair the controller.
1924 ProcessSingleControllerHealth (
1925 IN EFI_DRIVER_HEALTH_PROTOCOL
*DriverHealth
,
1926 IN EFI_HANDLE ControllerHandle
, OPTIONAL
1927 IN EFI_HANDLE ChildHandle
, OPTIONAL
1928 IN EFI_DRIVER_HEALTH_STATUS HealthStatus
,
1929 IN EFI_DRIVER_HEALTH_HII_MESSAGE
**MessageList
, OPTIONAL
1930 IN EFI_HII_HANDLE FormHiiHandle
,
1931 IN OUT BOOLEAN
*RebootRequired
1935 EFI_DRIVER_HEALTH_STATUS LocalHealthStatus
;
1937 LocalHealthStatus
= HealthStatus
;
1939 // If the module need to be repaired or reconfiguration, will process it until
1940 // reach a terminal status. The status from EfiDriverHealthStatusRepairRequired after repair
1941 // will be in (Health, Failed, Configuration Required).
1943 while(LocalHealthStatus
== EfiDriverHealthStatusConfigurationRequired
||
1944 LocalHealthStatus
== EfiDriverHealthStatusRepairRequired
) {
1946 if (LocalHealthStatus
== EfiDriverHealthStatusRepairRequired
) {
1947 Status
= DriverHealth
->Repair (
1951 (EFI_DRIVER_HEALTH_REPAIR_PROGRESS_NOTIFY
) RepairNotify
1955 // Via a form of the driver need to do configuration provided to process of status in
1956 // EfiDriverHealthStatusConfigurationRequired. The status after configuration should be in
1957 // (Healthy, Reboot Required, Failed, Reconnect Required, Repair Required).
1959 if (LocalHealthStatus
== EfiDriverHealthStatusConfigurationRequired
) {
1960 if (FormHiiHandle
!= NULL
) {
1961 Status
= gFormBrowser2
->SendForm (
1965 &gEfiHiiDriverHealthFormsetGuid
,
1970 ASSERT( !EFI_ERROR (Status
));
1973 // Exit the loop in case no FormHiiHandle is supplied to prevent dead-loop
1979 Status
= DriverHealth
->GetHealthStatus (
1987 ASSERT_EFI_ERROR (Status
);
1989 if (*MessageList
!= NULL
) {
1990 ProcessMessages (*MessageList
);
1995 // Health status in {Healthy, Failed} may also have Messages need to process
1997 if (LocalHealthStatus
== EfiDriverHealthStatusHealthy
|| LocalHealthStatus
== EfiDriverHealthStatusFailed
) {
1998 if (*MessageList
!= NULL
) {
1999 ProcessMessages (*MessageList
);
2003 // Check for RebootRequired or ReconnectRequired
2005 if (LocalHealthStatus
== EfiDriverHealthStatusRebootRequired
) {
2006 *RebootRequired
= TRUE
;
2010 // Do reconnect if need.
2012 if (LocalHealthStatus
== EfiDriverHealthStatusReconnectRequired
) {
2013 Status
= gBS
->DisconnectController (ControllerHandle
, NULL
, NULL
);
2014 if (EFI_ERROR (Status
)) {
2016 // Disconnect failed. Need to promote reconnect to a reboot.
2018 *RebootRequired
= TRUE
;
2020 gBS
->ConnectController (ControllerHandle
, NULL
, NULL
, TRUE
);
2027 Platform specific notification function for controller repair operations.
2029 If the driver for a controller support the Driver Health Protocol and the
2030 current state of the controller is EfiDriverHealthStatusRepairRequired then
2031 when the Repair() service of the Driver Health Protocol is called, this
2032 platform specific notification function can display the progress of the repair
2033 operation. Some platforms may choose to not display anything, other may choose
2034 to show the percentage complete on text consoles, and other may choose to render
2035 a progress bar on text and graphical consoles.
2037 This function displays the percentage of the repair operation that has been
2038 completed on text consoles. The percentage is Value / Limit * 100%.
2040 @param Value Value in the range 0..Limit the the repair has completed..
2041 @param Limit The maximum value of Value
2053 Print(L
"Repair Progress Undefined\n\r");
2055 Percent
= Value
* 100 / Limit
;
2056 Print(L
"Repair Progress = %3d%%\n\r", Percent
);
2061 Processes a set of messages returned by the GetHealthStatus ()
2062 service of the EFI Driver Health Protocol
2064 @param MessageList The MessageList point to messages need to processed.
2069 IN EFI_DRIVER_HEALTH_HII_MESSAGE
*MessageList
2073 EFI_STRING MessageString
;
2075 for (MessageIndex
= 0;
2076 MessageList
[MessageIndex
].HiiHandle
!= NULL
;
2079 MessageString
= HiiGetString (
2080 MessageList
[MessageIndex
].HiiHandle
,
2081 MessageList
[MessageIndex
].StringId
,
2084 if (MessageString
!= NULL
) {
2086 // User can customize the output. Just simply print out the MessageString like below.
2087 // Also can use the HiiHandle to display message on the front page.
2089 // Print(L"%s\n",MessageString);
2090 // gBS->Stall (100000);
2097 Repair the whole platform.
2099 This function is the main entry for user choose "Repair All" in the front page.
2100 It will try to do recovery job till all the driver health protocol installed modules
2101 reach a terminal state.
2103 @param DriverHealthList A Pointer to the list contain all of the platform driver health
2109 IN LIST_ENTRY
*DriverHealthList
2112 DRIVER_HEALTH_INFO
*DriverHealthInfo
;
2114 BOOLEAN RebootRequired
;
2116 ASSERT (DriverHealthList
!= NULL
);
2118 RebootRequired
= FALSE
;
2120 for ( Link
= GetFirstNode (DriverHealthList
)
2121 ; !IsNull (DriverHealthList
, Link
)
2122 ; Link
= GetNextNode (DriverHealthList
, Link
)
2124 DriverHealthInfo
= DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link
);
2126 // Do driver health status operation by each link node
2128 ASSERT (DriverHealthInfo
!= NULL
);
2130 ProcessSingleControllerHealth (
2131 DriverHealthInfo
->DriverHealth
,
2132 DriverHealthInfo
->ControllerHandle
,
2133 DriverHealthInfo
->ChildHandle
,
2134 DriverHealthInfo
->HealthStatus
,
2135 &(DriverHealthInfo
->MessageList
),
2136 DriverHealthInfo
->HiiHandle
,
2141 if (RebootRequired
) {
2142 gRT
->ResetSystem (EfiResetWarm
, EFI_SUCCESS
, 0, NULL
);
2148 Select the best matching language according to front page policy for best user experience.
2150 This function supports both ISO 639-2 and RFC 4646 language codes, but language
2151 code types may not be mixed in a single call to this function.
2153 @param SupportedLanguages A pointer to a Null-terminated ASCII string that
2154 contains a set of language codes in the format
2155 specified by Iso639Language.
2156 @param Iso639Language If TRUE, then all language codes are assumed to be
2157 in ISO 639-2 format. If FALSE, then all language
2158 codes are assumed to be in RFC 4646 language format.
2160 @retval NULL The best matching language could not be found in SupportedLanguages.
2161 @retval NULL There are not enough resources available to return the best matching
2163 @retval Other A pointer to a Null-terminated ASCII string that is the best matching
2164 language in SupportedLanguages.
2167 DriverHealthSelectBestLanguage (
2168 IN CHAR8
*SupportedLanguages
,
2169 IN BOOLEAN Iso639Language
2172 CHAR8
*LanguageVariable
;
2173 CHAR8
*BestLanguage
;
2175 LanguageVariable
= GetEfiGlobalVariable (Iso639Language
? L
"Lang" : L
"PlatformLang");
2177 BestLanguage
= GetBestLanguage(
2180 (LanguageVariable
!= NULL
) ? LanguageVariable
: "",
2181 Iso639Language
? "eng" : "en-US",
2184 if (LanguageVariable
!= NULL
) {
2185 FreePool (LanguageVariable
);
2188 return BestLanguage
;
2195 This is an internal worker function to get the Component Name (2) protocol interface
2196 and the language it supports.
2198 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
2199 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
2200 @param ComponentName A pointer to the Component Name (2) protocol interface.
2201 @param SupportedLanguage The best suitable language that matches the SupportedLangues interface for the
2202 located Component Name (2) instance.
2204 @retval EFI_SUCCESS The Component Name (2) protocol instance is successfully located and we find
2205 the best matching language it support.
2206 @retval EFI_UNSUPPORTED The input Language is not supported by the Component Name (2) protocol.
2207 @retval Other Some error occurs when locating Component Name (2) protocol instance or finding
2208 the supported language.
2212 GetComponentNameWorker (
2213 IN EFI_GUID
*ProtocolGuid
,
2214 IN EFI_HANDLE DriverBindingHandle
,
2215 OUT EFI_COMPONENT_NAME_PROTOCOL
**ComponentName
,
2216 OUT CHAR8
**SupportedLanguage
2222 // Locate Component Name (2) protocol on the driver binging handle.
2224 Status
= gBS
->OpenProtocol (
2225 DriverBindingHandle
,
2227 (VOID
**) ComponentName
,
2230 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2232 if (EFI_ERROR (Status
)) {
2237 // Apply shell policy to select the best language.
2239 *SupportedLanguage
= DriverHealthSelectBestLanguage (
2240 (*ComponentName
)->SupportedLanguages
,
2241 (BOOLEAN
) (ProtocolGuid
== &gEfiComponentNameProtocolGuid
)
2243 if (*SupportedLanguage
== NULL
) {
2244 Status
= EFI_UNSUPPORTED
;
2252 This is an internal worker function to get driver name from Component Name (2) protocol interface.
2255 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
2256 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
2257 @param DriverName A pointer to the Unicode string to return. This Unicode string is the name
2258 of the driver specified by This.
2260 @retval EFI_SUCCESS The driver name is successfully retrieved from Component Name (2) protocol
2262 @retval Other The driver name cannot be retrieved from Component Name (2) protocol
2267 GetDriverNameWorker (
2268 IN EFI_GUID
*ProtocolGuid
,
2269 IN EFI_HANDLE DriverBindingHandle
,
2270 OUT CHAR16
**DriverName
2274 CHAR8
*BestLanguage
;
2275 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
2278 // Retrieve Component Name (2) protocol instance on the driver binding handle and
2279 // find the best language this instance supports.
2281 Status
= GetComponentNameWorker (
2283 DriverBindingHandle
,
2287 if (EFI_ERROR (Status
)) {
2292 // Get the driver name from Component Name (2) protocol instance on the driver binging handle.
2294 Status
= ComponentName
->GetDriverName (
2299 FreePool (BestLanguage
);
2306 This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface
2307 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name.
2308 If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward
2309 compatibility support.
2311 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
2312 @param DriverName A pointer to the Unicode string to return. This Unicode string is the name
2313 of the driver specified by This.
2315 @retval EFI_SUCCESS The driver name is successfully retrieved from Component Name (2) protocol
2317 @retval Other The driver name cannot be retrieved from Component Name (2) protocol
2322 DriverHealthGetDriverName (
2323 IN EFI_HANDLE DriverBindingHandle
,
2324 OUT CHAR16
**DriverName
2330 // Get driver name from UEFI 2.0 Component Name 2 protocol interface.
2332 Status
= GetDriverNameWorker (&gEfiComponentName2ProtocolGuid
, DriverBindingHandle
, DriverName
);
2333 if (EFI_ERROR (Status
)) {
2335 // If it fails to get the driver name from Component Name protocol interface, we should fall back on
2336 // EFI 1.1 Component Name protocol interface.
2338 Status
= GetDriverNameWorker (&gEfiComponentNameProtocolGuid
, DriverBindingHandle
, DriverName
);
2347 This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
2348 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
2349 If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
2350 compatibility support.
2352 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
2353 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
2354 @param ControllerHandle The handle of a controller that the driver specified by This is managing.
2355 This handle specifies the controller whose name is to be returned.
2356 @param ChildHandle The handle of the child controller to retrieve the name of. This is an
2357 optional parameter that may be NULL. It will be NULL for device drivers.
2358 It will also be NULL for bus drivers that attempt to retrieve the name
2359 of the bus controller. It will not be NULL for a bus driver that attempts
2360 to retrieve the name of a child controller.
2361 @param ControllerName A pointer to the Unicode string to return. This Unicode string
2362 is the name of the controller specified by ControllerHandle and ChildHandle.
2364 @retval EFI_SUCCESS The controller name is successfully retrieved from Component Name (2) protocol
2366 @retval Other The controller name cannot be retrieved from Component Name (2) protocol.
2370 GetControllerNameWorker (
2371 IN EFI_GUID
*ProtocolGuid
,
2372 IN EFI_HANDLE DriverBindingHandle
,
2373 IN EFI_HANDLE ControllerHandle
,
2374 IN EFI_HANDLE ChildHandle
,
2375 OUT CHAR16
**ControllerName
2379 CHAR8
*BestLanguage
;
2380 EFI_COMPONENT_NAME_PROTOCOL
*ComponentName
;
2383 // Retrieve Component Name (2) protocol instance on the driver binding handle and
2384 // find the best language this instance supports.
2386 Status
= GetComponentNameWorker (
2388 DriverBindingHandle
,
2392 if (EFI_ERROR (Status
)) {
2397 // Get the controller name from Component Name (2) protocol instance on the driver binging handle.
2399 Status
= ComponentName
->GetControllerName (
2406 FreePool (BestLanguage
);
2413 This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
2414 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
2415 If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
2416 compatibility support.
2418 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
2419 @param ControllerHandle The handle of a controller that the driver specified by This is managing.
2420 This handle specifies the controller whose name is to be returned.
2421 @param ChildHandle The handle of the child controller to retrieve the name of. This is an
2422 optional parameter that may be NULL. It will be NULL for device drivers.
2423 It will also be NULL for bus drivers that attempt to retrieve the name
2424 of the bus controller. It will not be NULL for a bus driver that attempts
2425 to retrieve the name of a child controller.
2426 @param ControllerName A pointer to the Unicode string to return. This Unicode string
2427 is the name of the controller specified by ControllerHandle and ChildHandle.
2429 @retval EFI_SUCCESS The controller name is successfully retrieved from Component Name (2) protocol
2431 @retval Other The controller name cannot be retrieved from Component Name (2) protocol.
2435 DriverHealthGetControllerName (
2436 IN EFI_HANDLE DriverBindingHandle
,
2437 IN EFI_HANDLE ControllerHandle
,
2438 IN EFI_HANDLE ChildHandle
,
2439 OUT CHAR16
**ControllerName
2445 // Get controller name from UEFI 2.0 Component Name 2 protocol interface.
2447 Status
= GetControllerNameWorker (
2448 &gEfiComponentName2ProtocolGuid
,
2449 DriverBindingHandle
,
2454 if (EFI_ERROR (Status
)) {
2456 // If it fails to get the controller name from Component Name protocol interface, we should fall back on
2457 // EFI 1.1 Component Name protocol interface.
2459 Status
= GetControllerNameWorker (
2460 &gEfiComponentNameProtocolGuid
,
2461 DriverBindingHandle
,