]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/DeviceMngr/DeviceManager.c
Driver health management implementation in BDS based on UEFI Specification 2.3.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / DeviceMngr / DeviceManager.c
1 /** @file
2 The platform device manager reference implementation
3
4 Copyright (c) 2004 - 2009, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
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.
12
13 **/
14
15 #include "DeviceManager.h"
16
17 DEVICE_MANAGER_CALLBACK_DATA gDeviceManagerPrivate = {
18 DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE,
19 NULL,
20 NULL,
21 NULL,
22 NULL,
23 {
24 FakeExtractConfig,
25 FakeRouteConfig,
26 DeviceManagerCallback
27 },
28 {
29 FakeExtractConfig,
30 FakeRouteConfig,
31 DriverHealthCallback
32 }
33 };
34
35 EFI_GUID mDeviceManagerGuid = DEVICE_MANAGER_FORMSET_GUID;
36 EFI_GUID mDriverHealthGuid = DRIVER_HEALTH_FORMSET_GUID;
37
38 DEVICE_MANAGER_MENU_ITEM mDeviceManagerMenuItemTable[] = {
39 { STRING_TOKEN (STR_DISK_DEVICE), EFI_DISK_DEVICE_CLASS },
40 { STRING_TOKEN (STR_VIDEO_DEVICE), EFI_VIDEO_DEVICE_CLASS },
41 { STRING_TOKEN (STR_NETWORK_DEVICE), EFI_NETWORK_DEVICE_CLASS },
42 { STRING_TOKEN (STR_INPUT_DEVICE), EFI_INPUT_DEVICE_CLASS },
43 { STRING_TOKEN (STR_ON_BOARD_DEVICE), EFI_ON_BOARD_DEVICE_CLASS },
44 { STRING_TOKEN (STR_OTHER_DEVICE), EFI_OTHER_DEVICE_CLASS }
45 };
46
47 HII_VENDOR_DEVICE_PATH mDeviceManagerHiiVendorDevicePath = {
48 {
49 {
50 HARDWARE_DEVICE_PATH,
51 HW_VENDOR_DP,
52 {
53 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
54 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
55 }
56 },
57 //
58 // {102579A0-3686-466e-ACD8-80C087044F4A}
59 //
60 { 0x102579a0, 0x3686, 0x466e, { 0xac, 0xd8, 0x80, 0xc0, 0x87, 0x4, 0x4f, 0x4a } }
61 },
62 {
63 END_DEVICE_PATH_TYPE,
64 END_ENTIRE_DEVICE_PATH_SUBTYPE,
65 {
66 (UINT8) (END_DEVICE_PATH_LENGTH),
67 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
68 }
69 }
70 };
71
72 /**
73 This function is invoked if user selected a interactive opcode from Device Manager's
74 Formset. The decision by user is saved to gCallbackKey for later processing. If
75 user set VBIOS, the new value is saved to EFI variable.
76
77 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
78 @param Action Specifies the type of action taken by the browser.
79 @param QuestionId A unique value which is sent to the original exporting driver
80 so that it can identify the type of data to expect.
81 @param Type The type of value for the question.
82 @param Value A pointer to the data being sent to the original exporting driver.
83 @param ActionRequest On return, points to the action requested by the callback function.
84
85 @retval EFI_SUCCESS The callback successfully handled the action.
86 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
87
88 **/
89 EFI_STATUS
90 EFIAPI
91 DeviceManagerCallback (
92 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
93 IN EFI_BROWSER_ACTION Action,
94 IN EFI_QUESTION_ID QuestionId,
95 IN UINT8 Type,
96 IN EFI_IFR_TYPE_VALUE *Value,
97 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
98 )
99 {
100 if ((Value == NULL) || (ActionRequest == NULL)) {
101 return EFI_INVALID_PARAMETER;
102 }
103
104 gCallbackKey = QuestionId;
105
106 //
107 // Request to exit SendForm(), so as to switch to selected form
108 //
109 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
110
111 return EFI_SUCCESS;
112 }
113
114 /**
115
116 This function registers HII packages to HII database.
117
118 @retval EFI_SUCCESS HII packages for the Device Manager were registered successfully.
119 @retval EFI_OUT_OF_RESOURCES HII packages for the Device Manager failed to be registered.
120
121 **/
122 EFI_STATUS
123 InitializeDeviceManager (
124 VOID
125 )
126 {
127 EFI_STATUS Status;
128
129 //
130 // Install Device Path Protocol and Config Access protocol to driver handle
131 //
132 Status = gBS->InstallMultipleProtocolInterfaces (
133 &gDeviceManagerPrivate.DriverHandle,
134 &gEfiDevicePathProtocolGuid,
135 &mDeviceManagerHiiVendorDevicePath,
136 &gEfiHiiConfigAccessProtocolGuid,
137 &gDeviceManagerPrivate.ConfigAccess,
138 NULL
139 );
140 ASSERT_EFI_ERROR (Status);
141
142 Status = gBS->InstallMultipleProtocolInterfaces (
143 &gDeviceManagerPrivate.DriverHealthHandle,
144 &gEfiHiiConfigAccessProtocolGuid,
145 &gDeviceManagerPrivate.DriverHealthConfigAccess,
146 NULL
147 );
148 ASSERT_EFI_ERROR (Status);
149
150 //
151 // Publish our HII data
152 //
153 gDeviceManagerPrivate.HiiHandle = HiiAddPackages (
154 &mDeviceManagerGuid,
155 gDeviceManagerPrivate.DriverHandle,
156 DeviceManagerVfrBin,
157 BdsDxeStrings,
158 NULL
159 );
160 if (gDeviceManagerPrivate.HiiHandle == NULL) {
161 return EFI_OUT_OF_RESOURCES;
162 } else {
163 Status = EFI_SUCCESS;
164 }
165
166 //
167 // Publish Driver Health HII data
168 //
169 gDeviceManagerPrivate.DriverHealthHiiHandle = HiiAddPackages (
170 &mDeviceManagerGuid,
171 gDeviceManagerPrivate.DriverHealthHandle,
172 DriverHealthVfrBin,
173 BdsDxeStrings,
174 NULL
175 );
176 if (gDeviceManagerPrivate.DriverHealthHiiHandle == NULL) {
177 Status = EFI_OUT_OF_RESOURCES;
178 } else {
179 Status = EFI_SUCCESS;
180 }
181
182 return Status;
183 }
184
185 /**
186 Extract the displayed formset for given HII handle and class guid.
187
188 @param Handle The HII handle.
189 @param SetupClassGuid The class guid specifies which form set will be displayed.
190 @param FormSetTitle Formset title string.
191 @param FormSetHelp Formset help string.
192
193 @retval TRUE The formset for given HII handle will be displayed.
194 @return FALSE The formset for given HII handle will not be displayed.
195
196 **/
197 BOOLEAN
198 ExtractDisplayedHiiFormFromHiiHandle (
199 IN EFI_HII_HANDLE Handle,
200 IN EFI_GUID *SetupClassGuid,
201 OUT EFI_STRING_ID *FormSetTitle,
202 OUT EFI_STRING_ID *FormSetHelp
203 )
204 {
205 EFI_STATUS Status;
206 UINTN BufferSize;
207 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
208 UINT8 *Package;
209 UINT8 *OpCodeData;
210 UINT32 Offset;
211 UINT32 Offset2;
212 UINT32 PackageListLength;
213 EFI_HII_PACKAGE_HEADER PackageHeader;
214 EFI_GUID *ClassGuid;
215 UINT8 ClassGuidNum;
216
217 ASSERT (Handle != NULL);
218 ASSERT (SetupClassGuid != NULL);
219 ASSERT (FormSetTitle != NULL);
220 ASSERT (FormSetHelp != NULL);
221
222 *FormSetTitle = 0;
223 *FormSetHelp = 0;
224 ClassGuidNum = 0;
225 ClassGuid = NULL;
226
227 //
228 // Get HII PackageList
229 //
230 BufferSize = 0;
231 HiiPackageList = NULL;
232 Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList);
233 //
234 // Handle is a invalid handle. Check if Handle is corrupted.
235 //
236 ASSERT (Status != EFI_NOT_FOUND);
237 //
238 // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
239 //
240 ASSERT (Status == EFI_BUFFER_TOO_SMALL);
241
242 HiiPackageList = AllocatePool (BufferSize);
243 ASSERT (HiiPackageList != NULL);
244
245 Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, &BufferSize, HiiPackageList);
246 if (EFI_ERROR (Status)) {
247 return FALSE;
248 }
249
250 //
251 // Get Form package from this HII package List
252 //
253 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
254 Offset2 = 0;
255 PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength);
256
257 while (Offset < PackageListLength) {
258 Package = ((UINT8 *) HiiPackageList) + Offset;
259 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
260
261 if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
262 //
263 // Search FormSet Opcode in this Form Package
264 //
265 Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
266 while (Offset2 < PackageHeader.Length) {
267 OpCodeData = Package + Offset2;
268
269 if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
270 //
271 // Find FormSet OpCode
272 //
273 ClassGuidNum = ((EFI_IFR_FORM_SET *) OpCodeData)->Flags;
274 ClassGuid = (EFI_GUID *) (VOID *)(OpCodeData + sizeof (EFI_IFR_FORM_SET));
275 while (ClassGuidNum-- > 0) {
276 if (CompareGuid (SetupClassGuid, ClassGuid)) {
277 CopyMem (FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));
278 CopyMem (FormSetHelp, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));
279 FreePool (HiiPackageList);
280 return TRUE;
281 }
282 }
283 }
284
285 //
286 // Go to next opcode
287 //
288 Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
289 }
290 }
291
292 //
293 // Go to next package
294 //
295 Offset += PackageHeader.Length;
296 }
297
298 FreePool (HiiPackageList);
299
300 return FALSE;
301 }
302
303 /**
304 Call the browser and display the device manager to allow user
305 to configure the platform.
306
307 This function create the dynamic content for device manager. It includes
308 section header for all class of devices, one-of opcode to set VBIOS.
309
310 @retval EFI_SUCCESS Operation is successful.
311 @return Other values if failed to clean up the dynamic content from HII
312 database.
313
314 **/
315 EFI_STATUS
316 CallDeviceManager (
317 VOID
318 )
319 {
320 EFI_STATUS Status;
321 UINTN Index;
322 EFI_STRING String;
323 EFI_STRING_ID Token;
324 EFI_STRING_ID TokenHelp;
325 EFI_HII_HANDLE *HiiHandles;
326 EFI_HII_HANDLE HiiHandle;
327 EFI_STRING_ID FormSetTitle;
328 EFI_STRING_ID FormSetHelp;
329 EFI_BROWSER_ACTION_REQUEST ActionRequest;
330 VOID *StartOpCodeHandle;
331 VOID *EndOpCodeHandle;
332 EFI_IFR_GUID_LABEL *StartLabel;
333 EFI_IFR_GUID_LABEL *EndLabel;
334 UINTN NumHandles;
335 EFI_HANDLE *DriverHealthHandles;
336
337 HiiHandles = NULL;
338 Status = EFI_SUCCESS;
339 gCallbackKey = 0;
340 NumHandles = 0;
341 DriverHealthHandles = NULL;
342
343 //
344 // Connect all prior to entering the platform setup menu.
345 //
346 if (!gConnectAllHappened) {
347 BdsLibConnectAllDriversToAllControllers ();
348 gConnectAllHappened = TRUE;
349 }
350 //
351 // Create Subtitle OpCodes
352 //
353 //
354 // Allocate space for creation of UpdateData Buffer
355 //
356 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
357 ASSERT (StartOpCodeHandle != NULL);
358
359 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
360 ASSERT (EndOpCodeHandle != NULL);
361
362 //
363 // Create Hii Extend Label OpCode as the start opcode
364 //
365 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
366 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
367 StartLabel->Number = LABEL_DEVICES_LIST;
368
369 //
370 // Create Hii Extend Label OpCode as the end opcode
371 //
372 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
373 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
374 EndLabel->Number = LABEL_END;
375
376 HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_DEVICES_LIST), 0, 0, 1);
377
378 //
379 // Get all the Hii handles
380 //
381 HiiHandles = HiiGetHiiHandles (NULL);
382 ASSERT (HiiHandles != NULL);
383
384 HiiHandle = gDeviceManagerPrivate.HiiHandle;
385
386 //
387 // Search for formset of each class type
388 //
389 for (Index = 0; HiiHandles[Index] != NULL; Index++) {
390 if (!ExtractDisplayedHiiFormFromHiiHandle (HiiHandles[Index], &gEfiHiiPlatformSetupFormsetGuid, &FormSetTitle, &FormSetHelp)) {
391 continue;
392 }
393
394 String = HiiGetString (HiiHandles[Index], FormSetTitle, NULL);
395 if (String == NULL) {
396 String = HiiGetString (HiiHandle, STR_MISSING_STRING, NULL);
397 ASSERT (String != NULL);
398 }
399 Token = HiiSetString (HiiHandle, 0, String, NULL);
400 FreePool (String);
401
402 String = HiiGetString (HiiHandles[Index], FormSetHelp, NULL);
403 if (String == NULL) {
404 String = HiiGetString (HiiHandle, STR_MISSING_STRING, NULL);
405 ASSERT (String != NULL);
406 }
407 TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);
408 FreePool (String);
409
410 HiiCreateActionOpCode (
411 StartOpCodeHandle,
412 (EFI_QUESTION_ID) (Index + DEVICE_KEY_OFFSET),
413 Token,
414 TokenHelp,
415 EFI_IFR_FLAG_CALLBACK,
416 0
417 );
418 }
419
420 //
421 // Add End Opcode for Subtitle
422 //
423 HiiCreateEndOpCode (StartOpCodeHandle);
424
425 Status = gBS->LocateHandleBuffer (
426 ByProtocol,
427 &gEfiDriverHealthProtocolGuid,
428 NULL,
429 &NumHandles,
430 &DriverHealthHandles
431 );
432 //
433 // If there are no drivers installed driver health protocol
434 //
435 if (NumHandles == 0) {
436 HiiSetString (HiiHandle, STRING_TOKEN (STR_DM_DRIVER_HEALTH_TITLE), GetStringById (STRING_TOKEN (STR_EMPTY_STRING)), NULL);
437 HiiSetString (HiiHandle, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY), GetStringById (STRING_TOKEN (STR_EMPTY_STRING)), NULL);
438 } else {
439 //
440 // Check All Driver health status
441 //
442 if (!PlaformHealthStatusCheck ()) {
443 //
444 // At least one driver in the platform are not in healthy status
445 //
446 HiiSetString (HiiHandle, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY), GetStringById (STRING_TOKEN (STR_DRIVER_NOT_HEALTH)), NULL);
447 } else {
448 //
449 // For the string of STR_DRIVER_HEALTH_ALL_HEALTHY previously has been updated and we need to update it while re-entry.
450 //
451 HiiSetString (HiiHandle, STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY), GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY)), NULL);
452 }
453 }
454
455 HiiUpdateForm (
456 HiiHandle,
457 &mDeviceManagerGuid,
458 DEVICE_MANAGER_FORM_ID,
459 StartOpCodeHandle,
460 EndOpCodeHandle
461 );
462
463 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
464 Status = gFormBrowser2->SendForm (
465 gFormBrowser2,
466 &HiiHandle,
467 1,
468 &mDeviceManagerGuid,
469 0,
470 NULL,
471 &ActionRequest
472 );
473 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
474 EnableResetRequired ();
475 }
476
477 //
478 // We will have returned from processing a callback - user either hit ESC to exit, or selected
479 // a target to display
480 //
481 if ((gCallbackKey != 0) && (gCallbackKey != DEVICE_MANAGER_KEY_DRIVER_HEALTH)) {
482 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
483 Status = gFormBrowser2->SendForm (
484 gFormBrowser2,
485 &HiiHandles[gCallbackKey - DEVICE_KEY_OFFSET],
486 1,
487 NULL,
488 0,
489 NULL,
490 &ActionRequest
491 );
492
493 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
494 EnableResetRequired ();
495 }
496
497 //
498 // Force return to Device Manager
499 //
500 gCallbackKey = FRONT_PAGE_KEY_DEVICE_MANAGER;
501 }
502
503 //
504 // Driver Health item chose.
505 //
506 if (gCallbackKey == DEVICE_MANAGER_KEY_DRIVER_HEALTH) {
507 CallDriverHealth ();
508 }
509
510 //
511 // Cleanup dynamic created strings in HII database by reinstall the packagelist
512 //
513 HiiRemovePackages (HiiHandle);
514
515 gDeviceManagerPrivate.HiiHandle = HiiAddPackages (
516 &mDeviceManagerGuid,
517 gDeviceManagerPrivate.DriverHandle,
518 DeviceManagerVfrBin,
519 BdsDxeStrings,
520 NULL
521 );
522 if (gDeviceManagerPrivate.HiiHandle == NULL) {
523 Status = EFI_OUT_OF_RESOURCES;
524 } else {
525 Status = EFI_SUCCESS;
526 }
527
528 HiiFreeOpCodeHandle (StartOpCodeHandle);
529 HiiFreeOpCodeHandle (EndOpCodeHandle);
530 FreePool (HiiHandles);
531
532 return Status;
533 }
534
535 /**
536 This function is invoked if user selected a interactive opcode from Driver Health's
537 Formset. The decision by user is saved to gCallbackKey for later processing.
538
539 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
540 @param Action Specifies the type of action taken by the browser.
541 @param QuestionId A unique value which is sent to the original exporting driver
542 so that it can identify the type of data to expect.
543 @param Type The type of value for the question.
544 @param Value A pointer to the data being sent to the original exporting driver.
545 @param ActionRequest On return, points to the action requested by the callback function.
546
547 @retval EFI_SUCCESS The callback successfully handled the action.
548 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
549
550 **/
551 EFI_STATUS
552 EFIAPI
553 DriverHealthCallback (
554 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
555 IN EFI_BROWSER_ACTION Action,
556 IN EFI_QUESTION_ID QuestionId,
557 IN UINT8 Type,
558 IN EFI_IFR_TYPE_VALUE *Value,
559 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
560 )
561 {
562 if ((Value == NULL) || (ActionRequest == NULL)) {
563 return EFI_INVALID_PARAMETER;
564 }
565
566 gCallbackKey = QuestionId;
567
568 //
569 // Request to exit SendForm(), so as to switch to selected form
570 //
571 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
572
573 return EFI_SUCCESS;
574 }
575
576 /**
577 Collect and display the platform's driver health relative information, allow user to do interactive
578 operation while the platform is unhealthy.
579
580 This function display a form which divided into two parts. The one list all modules which has installed
581 driver health protocol. The list usually contain driver name, controller name, and it's health info.
582 While the driver name can't be retrieved, will use device path as backup. The other part of the form provide
583 a choice to the user to repair all platform.
584
585 **/
586 VOID
587 CallDriverHealth (
588 VOID
589 )
590 {
591 EFI_STATUS Status;
592 EFI_HII_HANDLE HiiHandle;
593 EFI_BROWSER_ACTION_REQUEST ActionRequest;
594 EFI_IFR_GUID_LABEL *StartLabel;
595 EFI_IFR_GUID_LABEL *StartLabelRepair;
596 EFI_IFR_GUID_LABEL *EndLabel;
597 EFI_IFR_GUID_LABEL *EndLabelRepair;
598 VOID *StartOpCodeHandle;
599 VOID *EndOpCodeHandle;
600 VOID *StartOpCodeHandleRepair;
601 VOID *EndOpCodeHandleRepair;
602 UINTN Index;
603 EFI_STRING_ID Token;
604 EFI_STRING_ID TokenHelp;
605 EFI_STRING String;
606 EFI_STRING TmpString;
607 EFI_STRING DriverName;
608 EFI_STRING ControllerName;
609 LIST_ENTRY DriverHealthList;
610 DRIVER_HEALTH_INFO *DriverHealthInfo;
611 LIST_ENTRY *Link;
612 EFI_DEVICE_PATH_PROTOCOL *DriverDevicePath;
613 UINTN Length;
614
615 HiiHandle = gDeviceManagerPrivate.DriverHealthHiiHandle;
616 Index = 0;
617 Length = 0;
618 DriverHealthInfo = NULL;
619 DriverDevicePath = NULL;
620 InitializeListHead (&DriverHealthList);
621
622 //
623 // Allocate space for creation of UpdateData Buffer
624 //
625 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
626 ASSERT (StartOpCodeHandle != NULL);
627
628 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
629 ASSERT (EndOpCodeHandle != NULL);
630
631 StartOpCodeHandleRepair = HiiAllocateOpCodeHandle ();
632 ASSERT (StartOpCodeHandleRepair != NULL);
633
634 EndOpCodeHandleRepair = HiiAllocateOpCodeHandle ();
635 ASSERT (EndOpCodeHandleRepair != NULL);
636
637 //
638 // Create Hii Extend Label OpCode as the start opcode
639 //
640 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
641 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
642 StartLabel->Number = LABEL_DRIVER_HEALTH;
643
644 //
645 // Create Hii Extend Label OpCode as the start opcode
646 //
647 StartLabelRepair = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandleRepair, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
648 StartLabelRepair->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
649 StartLabelRepair->Number = LABEL_DRIVER_HEALTH_REAPIR_ALL;
650
651 //
652 // Create Hii Extend Label OpCode as the end opcode
653 //
654 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
655 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
656 EndLabel->Number = LABEL_DRIVER_HEALTH_END;
657
658 //
659 // Create Hii Extend Label OpCode as the end opcode
660 //
661 EndLabelRepair = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandleRepair, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
662 EndLabelRepair->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
663 EndLabelRepair->Number = LABEL_DRIVER_HEALTH_REAPIR_ALL_END;
664
665 HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_DH_STATUS_LIST), 0, 0, 1);
666
667 Status = GetAllControllersHealthStatus (&DriverHealthList);
668 ASSERT (Status != EFI_OUT_OF_RESOURCES);
669
670 Link = GetFirstNode (&DriverHealthList);
671
672 while (!IsNull (&DriverHealthList, Link)) {
673 DriverHealthInfo = DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link);
674
675 //
676 // Assume no line strings is longer than 512 bytes.
677 //
678 String = (EFI_STRING) AllocateZeroPool (0x200);
679 ASSERT (String != NULL);
680
681 Status = DriverHealthGetDriverName (DriverHealthInfo->DriverHandle, &DriverName);
682 if (EFI_ERROR (Status)) {
683 //
684 // Can not get the Driver name, so use the Device path
685 //
686 DriverDevicePath = DevicePathFromHandle (DriverHealthInfo->DriverHandle);
687 DriverName = DevicePathToStr (DriverDevicePath);
688 }
689 //
690 // Add the Driver name & Controller name into FormSetTitle string
691 //
692 StrnCat (String, DriverName, StrLen (DriverName));
693
694
695 Status = DriverHealthGetControllerName (
696 DriverHealthInfo->DriverHandle,
697 DriverHealthInfo->ControllerHandle,
698 DriverHealthInfo->ChildHandle,
699 &ControllerName
700 );
701
702 if (!EFI_ERROR (Status)) {
703 //
704 // Can not get the Controller name, just let it empty.
705 //
706 StrnCat (String, L" ", StrLen (L" "));
707 StrnCat (String, ControllerName, StrLen (ControllerName));
708 }
709
710 //
711 // Add the message of the Module itself provided after the string item.
712 //
713 if ((DriverHealthInfo->MessageList != NULL) && (DriverHealthInfo->MessageList->StringId != 0)) {
714 StrnCat (String, L" ", StrLen (L" "));
715 TmpString = HiiGetString (
716 DriverHealthInfo->MessageList->HiiHandle,
717 DriverHealthInfo->MessageList->StringId,
718 NULL
719 );
720 //
721 // Assert if can not retrieve the message string
722 //
723 ASSERT (TmpString != NULL);
724 StrnCat (String, TmpString, StrLen (TmpString));
725 FreePool (TmpString);
726 } else {
727 //
728 // Update the string will be displayed base on the driver's health status
729 //
730 switch(DriverHealthInfo->HealthStatus) {
731 case EfiDriverHealthStatusRepairRequired:
732 Length = StrLen (GetStringById (STRING_TOKEN (STR_REPAIR_REQUIRED)));
733 StrnCat (String, GetStringById (STRING_TOKEN (STR_REPAIR_REQUIRED)), Length);
734 break;
735 case EfiDriverHealthStatusConfigurationRequired:
736 Length = StrLen (GetStringById (STRING_TOKEN (STR_CONFIGURATION_REQUIRED)));
737 StrnCat (String, GetStringById (STRING_TOKEN (STR_CONFIGURATION_REQUIRED)), Length);
738 break;
739 case EfiDriverHealthStatusFailed:
740 Length = StrLen (GetStringById (STRING_TOKEN (STR_OPERATION_FAILED)));
741 StrnCat (String, GetStringById (STRING_TOKEN (STR_OPERATION_FAILED)), Length);
742 break;
743 case EfiDriverHealthStatusReconnectRequired:
744 Length = StrLen (GetStringById (STRING_TOKEN (STR_RECONNECT_REQUIRED)));
745 StrnCat (String, GetStringById (STRING_TOKEN (STR_RECONNECT_REQUIRED)), Length);
746 break;
747 case EfiDriverHealthStatusRebootRequired:
748 Length = StrLen (GetStringById (STRING_TOKEN (STR_REBOOT_REQUIRED)));
749 StrnCat (String, GetStringById (STRING_TOKEN (STR_REBOOT_REQUIRED)), Length);
750 break;
751 default:
752 Length = StrLen (GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_HEALTHY)));
753 StrnCat (String, GetStringById (STRING_TOKEN (STR_DRIVER_HEALTH_HEALTHY)), Length);
754 break;
755 }
756 }
757
758 Token = HiiSetString (HiiHandle, 0, String, NULL);
759 FreePool (String);
760
761 TokenHelp = HiiSetString (HiiHandle, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_SINGLE_HELP)), NULL);
762
763 HiiCreateActionOpCode (
764 StartOpCodeHandle,
765 (EFI_QUESTION_ID) (Index + DRIVER_HEALTH_KEY_OFFSET),
766 Token,
767 TokenHelp,
768 EFI_IFR_FLAG_CALLBACK,
769 0
770 );
771 Index++;
772 Link = GetNextNode (&DriverHealthList, Link);
773 }
774
775 //
776 // Add End Opcode for Subtitle
777 //
778 HiiCreateEndOpCode (StartOpCodeHandle);
779
780 HiiCreateSubTitleOpCode (StartOpCodeHandleRepair, STRING_TOKEN (STR_DRIVER_HEALTH_REPAIR_ALL), 0, 0, 1);
781 TokenHelp = HiiSetString (HiiHandle, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_ALL_HELP)), NULL);
782
783 if (PlaformHealthStatusCheck ()) {
784 //
785 // No action need to do for the platform
786 //
787 Token = HiiSetString (HiiHandle, 0, GetStringById( STRING_TOKEN (STR_DRIVER_HEALTH_ALL_HEALTHY)), NULL);
788 HiiCreateActionOpCode (
789 StartOpCodeHandleRepair,
790 0,
791 Token,
792 TokenHelp,
793 EFI_IFR_FLAG_READ_ONLY,
794 0
795 );
796 } else {
797 //
798 // Create ActionOpCode only while the platform need to do health related operation.
799 //
800 Token = HiiSetString (HiiHandle, 0, GetStringById( STRING_TOKEN (STR_DH_REPAIR_ALL_TITLE)), NULL);
801 HiiCreateActionOpCode (
802 StartOpCodeHandleRepair,
803 (EFI_QUESTION_ID) DRIVER_HEALTH_REPAIR_ALL_KEY,
804 Token,
805 TokenHelp,
806 EFI_IFR_FLAG_CALLBACK,
807 0
808 );
809 }
810
811 HiiCreateEndOpCode (StartOpCodeHandleRepair);
812
813 Status = HiiUpdateForm (
814 HiiHandle,
815 &mDriverHealthGuid,
816 DRIVER_HEALTH_FORM_ID,
817 StartOpCodeHandle,
818 EndOpCodeHandle
819 );
820 ASSERT (Status != EFI_NOT_FOUND);
821 ASSERT (Status != EFI_BUFFER_TOO_SMALL);
822
823 Status = HiiUpdateForm (
824 HiiHandle,
825 &mDriverHealthGuid,
826 DRIVER_HEALTH_FORM_ID,
827 StartOpCodeHandleRepair,
828 EndOpCodeHandleRepair
829 );
830 ASSERT (Status != EFI_NOT_FOUND);
831 ASSERT (Status != EFI_BUFFER_TOO_SMALL);
832
833 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
834 Status = gFormBrowser2->SendForm (
835 gFormBrowser2,
836 &HiiHandle,
837 1,
838 &mDriverHealthGuid,
839 DRIVER_HEALTH_FORM_ID,
840 NULL,
841 &ActionRequest
842 );
843 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
844 EnableResetRequired ();
845 }
846
847 //
848 // We will have returned from processing a callback - user either hit ESC to exit, or selected
849 // a target to display.
850 // Process the diver health status states here.
851 //
852 if (gCallbackKey >= DRIVER_HEALTH_KEY_OFFSET && gCallbackKey != DRIVER_HEALTH_REPAIR_ALL_KEY && gCallbackKey != FRONT_PAGE_KEY_DEVICE_MANAGER) {
853 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
854
855 Link = GetFirstNode (&DriverHealthList);
856 Index = 0;
857
858 while (!IsNull (&DriverHealthList, Link)) {
859 //
860 // Got the item relative node in the List
861 //
862 if (Index == (gCallbackKey - DRIVER_HEALTH_KEY_OFFSET)) {
863 DriverHealthInfo = DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link);
864 //
865 // Process the driver's healthy status for the specify module
866 //
867 ProcessSingleControllerHealth (
868 DriverHealthInfo->DriverHealth,
869 DriverHealthInfo->ControllerHandle,
870 DriverHealthInfo->ChildHandle,
871 DriverHealthInfo->HealthStatus,
872 &(DriverHealthInfo->MessageList),
873 DriverHealthInfo->HiiHandle
874 );
875 break;
876 }
877 Index++;
878 Link = GetNextNode (&DriverHealthList, Link);
879 }
880
881 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
882 EnableResetRequired ();
883 }
884
885 //
886 // Force return to the form of Driver Health in Device Manager
887 //
888 gCallbackKey = DRIVER_HEALTH_RETURN_KEY;
889 }
890
891 //
892 // Repair the whole platform
893 //
894 if (gCallbackKey == DRIVER_HEALTH_REPAIR_ALL_KEY) {
895 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
896
897 PlatformRepairAll (&DriverHealthList);
898
899 gCallbackKey = DRIVER_HEALTH_RETURN_KEY;
900 }
901
902 //
903 // Cleanup dynamic created strings in HII database by reinstall the packagelist
904 //
905
906 HiiRemovePackages (HiiHandle);
907
908 gDeviceManagerPrivate.DriverHealthHiiHandle = HiiAddPackages (
909 &mDriverHealthGuid,
910 gDeviceManagerPrivate.DriverHealthHandle,
911 DriverHealthVfrBin,
912 BdsDxeStrings,
913 NULL
914 );
915 if (gDeviceManagerPrivate.DriverHealthHiiHandle == NULL) {
916 Status = EFI_OUT_OF_RESOURCES;
917 } else {
918 Status = EFI_SUCCESS;
919 }
920 //
921 // Free driver health info list
922 //
923 while (!IsListEmpty (&DriverHealthList)) {
924
925 Link = GetFirstNode(&DriverHealthList);
926 DriverHealthInfo = DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link);
927 RemoveEntryList (Link);
928
929 if (DriverHealthInfo->MessageList != NULL) {
930 FreePool(DriverHealthInfo->MessageList);
931 FreePool (DriverHealthInfo);
932 }
933 }
934
935 HiiFreeOpCodeHandle (StartOpCodeHandle);
936 HiiFreeOpCodeHandle (EndOpCodeHandle);
937 HiiFreeOpCodeHandle (StartOpCodeHandleRepair);
938 HiiFreeOpCodeHandle (EndOpCodeHandleRepair);
939
940 if (gCallbackKey == DRIVER_HEALTH_RETURN_KEY) {
941 gCallbackKey = DEVICE_MANAGER_KEY_DRIVER_HEALTH;
942 CallDriverHealth ();
943 }
944 if (gCallbackKey == DEVICE_MANAGER_KEY_DRIVER_HEALTH) {
945 CallDeviceManager();
946 }
947 }
948
949
950 /*
951 Check the Driver Health status of a single controller and try to process it if not healthy.
952
953 This function called by CheckAllControllersHealthStatus () function in order to process a specify
954 contoller's health state.
955
956 @param DriverHealth A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
957 @param ControllerHandle The class guid specifies which form set will be displayed.
958 @param ChildHandle The handle of the child controller to retrieve the health
959 status on. This is an optional parameter that may be NULL.
960 @param HealthStatus The health status of the controller.
961 @param MessageList An array of warning or error messages associated
962 with the controller specified by ControllerHandle and
963 ChildHandle. This is an optional parameter that may be NULL.
964 @param FormHiiHandle The HII handle for an HII form associated with the
965 controller specified by ControllerHandle and ChildHandle.
966
967 @retval EFI_INVALID_PARAMETER HealthStatus or DriverHealth is NULL.
968 @retval HealthStatus The Health status of specify controller.
969 @retval EFI_OUT_OF_RESOURCES The list of Driver Health Protocol handles can not be retrieved.
970 @retval EFI_NOT_FOUND No controller in the platform install Driver Health Protocol.
971 @retval EFI_SUCCESS The Health related operation has been taken successfully.
972
973 */
974 EFI_STATUS
975 EFIAPI
976 GetSingleControllerHealthStatus (
977 IN OUT LIST_ENTRY *DriverHealthList,
978 IN EFI_HANDLE DriverHandle,
979 IN EFI_HANDLE ControllerHandle, OPTIONAL
980 IN EFI_HANDLE ChildHandle, OPTIONAL
981 IN EFI_DRIVER_HEALTH_PROTOCOL *DriverHealth,
982 IN EFI_DRIVER_HEALTH_STATUS *HealthStatus
983 )
984 {
985 EFI_STATUS Status;
986 EFI_DRIVER_HEALTH_HII_MESSAGE *MessageList;
987 EFI_HII_HANDLE FormHiiHandle;
988 DRIVER_HEALTH_INFO *DriverHealthInfo;
989
990 if (HealthStatus == NULL) {
991 //
992 // If HealthStatus is NULL, then return EFI_INVALID_PARAMETER
993 //
994 return EFI_INVALID_PARAMETER;
995 }
996
997 //
998 // Assume the HealthStatus is healthy
999 //
1000 *HealthStatus = EfiDriverHealthStatusHealthy;
1001
1002 if (DriverHealth == NULL) {
1003 //
1004 // If DriverHealth is NULL, then return EFI_INVALID_PARAMETER
1005 //
1006 return EFI_INVALID_PARAMETER;
1007 }
1008
1009 if (ControllerHandle == NULL) {
1010 //
1011 // If ControllerHandle is NULL, the return the cumulative health status of the driver
1012 //
1013 Status = DriverHealth->GetHealthStatus (DriverHealth, NULL, NULL, HealthStatus, NULL, NULL);
1014 if (*HealthStatus == EfiDriverHealthStatusHealthy) {
1015 //
1016 // Add the driver health related information into the list
1017 //
1018 DriverHealthInfo = AllocateZeroPool (sizeof (DRIVER_HEALTH_INFO));
1019 if (DriverHealthInfo == NULL) {
1020 return EFI_OUT_OF_RESOURCES;
1021 }
1022
1023 DriverHealthInfo->Signature = DEVICE_MANAGER_DRIVER_HEALTH_INFO_SIGNATURE;
1024 DriverHealthInfo->DriverHandle = DriverHandle;
1025 DriverHealthInfo->ControllerHandle = NULL;
1026 DriverHealthInfo->ChildHandle = NULL;
1027 DriverHealthInfo->HiiHandle = NULL;
1028 DriverHealthInfo->DriverHealth = DriverHealth;
1029 DriverHealthInfo->MessageList = NULL;
1030 DriverHealthInfo->HealthStatus = *HealthStatus;
1031
1032 InsertTailList (DriverHealthList, &DriverHealthInfo->Link);
1033 }
1034 return Status;
1035 }
1036
1037 MessageList = NULL;
1038 FormHiiHandle = NULL;
1039
1040 //
1041 // Collect the health status with the optional HII message list
1042 //
1043 Status = DriverHealth->GetHealthStatus (DriverHealth, ControllerHandle, ChildHandle, HealthStatus, &MessageList, &FormHiiHandle);
1044
1045 if (EFI_ERROR (Status)) {
1046 //
1047 // If the health status could not be retrieved, then return immediately
1048 //
1049 return Status;
1050 }
1051
1052 //
1053 // Add the driver health related information into the list
1054 //
1055 DriverHealthInfo = AllocateZeroPool (sizeof (DRIVER_HEALTH_INFO));
1056 if (DriverHealthInfo == NULL) {
1057 return EFI_OUT_OF_RESOURCES;
1058 }
1059
1060 DriverHealthInfo->Signature = DEVICE_MANAGER_DRIVER_HEALTH_INFO_SIGNATURE;
1061 DriverHealthInfo->DriverHandle = DriverHandle;
1062 DriverHealthInfo->ControllerHandle = ControllerHandle;
1063 DriverHealthInfo->ChildHandle = ChildHandle;
1064 DriverHealthInfo->HiiHandle = FormHiiHandle;
1065 DriverHealthInfo->DriverHealth = DriverHealth;
1066 DriverHealthInfo->MessageList = MessageList;
1067 DriverHealthInfo->HealthStatus = *HealthStatus;
1068
1069 InsertTailList (DriverHealthList, &DriverHealthInfo->Link);
1070
1071 return EFI_SUCCESS;
1072 }
1073
1074 /**
1075 Collects all the EFI Driver Health Protocols currently present in the EFI Handle Database,
1076 and queries each EFI Driver Health Protocol to determine if one or more of the controllers
1077 managed by each EFI Driver Health Protocol instance are not healthy.
1078
1079 @param DriverHealthList A Pointer to the list contain all of the platform driver health
1080 information.
1081
1082 @retval EFI_NOT_FOUND No controller in the platform install Driver Health Protocol.
1083 @retval EFI_SUCCESS All the controllers in the platform are healthy.
1084 @retval EFI_OUT_OF_RESOURCES The list of Driver Health Protocol handles can not be retrieved.
1085
1086 **/
1087 EFI_STATUS
1088 GetAllControllersHealthStatus (
1089 IN OUT LIST_ENTRY *DriverHealthList
1090 )
1091 {
1092 EFI_STATUS Status;
1093 UINTN NumHandles;
1094 EFI_HANDLE *DriverHealthHandles;
1095 EFI_DRIVER_HEALTH_PROTOCOL *DriverHealth;
1096 EFI_DRIVER_HEALTH_STATUS HealthStatus;
1097 UINTN DriverHealthIndex;
1098 EFI_HANDLE *Handles;
1099 UINTN HandleCount;
1100 UINTN ControllerIndex;
1101 UINTN ChildIndex;
1102
1103 //
1104 // Initialize local variables
1105 //
1106 Handles = NULL;
1107 DriverHealthHandles = NULL;
1108 NumHandles = 0;
1109 HandleCount = 0;
1110
1111 HealthStatus = EfiDriverHealthStatusHealthy;
1112
1113 Status = gBS->LocateHandleBuffer (
1114 ByProtocol,
1115 &gEfiDriverHealthProtocolGuid,
1116 NULL,
1117 &NumHandles,
1118 &DriverHealthHandles
1119 );
1120
1121 if (Status == EFI_NOT_FOUND || NumHandles == 0) {
1122 //
1123 // If there are no Driver Health Protocols handles, then return EFI_NOT_FOUND
1124 //
1125 return EFI_NOT_FOUND;
1126 }
1127
1128 if (EFI_ERROR (Status) || DriverHealthHandles == NULL) {
1129 //
1130 // If the list of Driver Health Protocol handles can not be retrieved, then
1131 // return EFI_OUT_OF_RESOURCES
1132 //
1133 return EFI_OUT_OF_RESOURCES;
1134 }
1135
1136 //
1137 // Check the health status of all controllers in the platform
1138 // Start by looping through all the Driver Health Protocol handles in the handle database
1139 //
1140 for (DriverHealthIndex = 0; DriverHealthIndex < NumHandles; DriverHealthIndex++) {
1141 //
1142 // Skip NULL Driver Health Protocol handles
1143 //
1144 if (DriverHealthHandles[DriverHealthIndex] == NULL) {
1145 continue;
1146 }
1147
1148 //
1149 // Retrieve the Driver Health Protocol from DriverHandle
1150 //
1151 Status = gBS->HandleProtocol (
1152 DriverHealthHandles[DriverHealthIndex],
1153 &gEfiDriverHealthProtocolGuid,
1154 (VOID **)&DriverHealth
1155 );
1156 if (EFI_ERROR (Status)) {
1157 //
1158 // If the Driver Health Protocol can not be retrieved, then skip to the next
1159 // Driver Health Protocol handle
1160 //
1161 continue;
1162 }
1163
1164 //
1165 // Check the health of all the controllers managed by a Driver Health Protocol handle
1166 //
1167 Status = GetSingleControllerHealthStatus (DriverHealthList, DriverHealthHandles[DriverHealthIndex], NULL, NULL, DriverHealth, &HealthStatus);
1168
1169 //
1170 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1171 // and skip to the next Driver Health Protocol handle
1172 //
1173 if (EFI_ERROR (Status)) {
1174 continue;
1175 }
1176
1177 //
1178 // If all the controllers managed by this Driver Health Protocol are healthy, then skip to the next
1179 // Driver Health Protocol handle
1180 //
1181 if (HealthStatus == EfiDriverHealthStatusHealthy) {
1182 continue;
1183 }
1184
1185 //
1186 // See if the list of all handles in the handle database has been retrieved
1187 //
1188 //
1189 if (Handles == NULL) {
1190 //
1191 // Retrieve the list of all handles from the handle database
1192 //
1193 Status = gBS->LocateHandleBuffer (
1194 AllHandles,
1195 NULL,
1196 NULL,
1197 &HandleCount,
1198 &Handles
1199 );
1200 if (EFI_ERROR (Status) || Handles == NULL) {
1201 //
1202 // If all the handles in the handle database can not be retrieved, then
1203 // return EFI_OUT_OF_RESOURCES
1204 //
1205 Status = EFI_OUT_OF_RESOURCES;
1206 goto Done;
1207 }
1208 }
1209 //
1210 // Loop through all the controller handles in the handle database
1211 //
1212 for (ControllerIndex = 0; ControllerIndex < HandleCount; ControllerIndex++) {
1213 //
1214 // Skip NULL controller handles
1215 //
1216 if (Handles[ControllerIndex] == NULL) {
1217 continue;
1218 }
1219
1220 Status = GetSingleControllerHealthStatus (DriverHealthList, DriverHealthHandles[DriverHealthIndex], Handles[ControllerIndex], NULL, DriverHealth, &HealthStatus);
1221 if (EFI_ERROR (Status)) {
1222 //
1223 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1224 //
1225 HealthStatus = EfiDriverHealthStatusHealthy;
1226 }
1227
1228 //
1229 // If CheckHealthSingleController() returned an error on a terminal state, then do not check the health of child controllers
1230 //
1231 if (EFI_ERROR (Status)) {
1232 continue;
1233 }
1234
1235 //
1236 // Loop through all the child handles in the handle database
1237 //
1238 for (ChildIndex = 0; ChildIndex < HandleCount; ChildIndex++) {
1239 //
1240 // Skip NULL child handles
1241 //
1242 if (Handles[ChildIndex] == NULL) {
1243 continue;
1244 }
1245
1246 Status = GetSingleControllerHealthStatus (DriverHealthList, DriverHealthHandles[DriverHealthIndex], Handles[ControllerIndex], Handles[ChildIndex], DriverHealth, &HealthStatus);
1247 if (EFI_ERROR (Status)) {
1248 //
1249 // If Status is an error code, then the health information could not be retrieved, so assume healthy
1250 //
1251 HealthStatus = EfiDriverHealthStatusHealthy;
1252 }
1253
1254 //
1255 // If CheckHealthSingleController() returned an error on a terminal state, then skip to the next child
1256 //
1257 if (EFI_ERROR (Status)) {
1258 continue;
1259 }
1260 }
1261 }
1262 }
1263
1264 Status = EFI_SUCCESS;
1265
1266 Done:
1267 if (Handles != NULL) {
1268 gBS->FreePool (Handles);
1269 }
1270 if (DriverHealthHandles != NULL) {
1271 gBS->FreePool (DriverHealthHandles);
1272 }
1273
1274 return Status;
1275 }
1276
1277
1278 /*
1279 Check the healthy status of the platform, this function will return immediately while found one driver
1280 in the platform are not healthy.
1281
1282 @retval FALSE at least one driver in the platform are not healthy.
1283 @retval TRUE No controller install Driver Health Protocol,
1284 or all controllers in the platform are in healthy status.
1285 */
1286 BOOLEAN
1287 PlaformHealthStatusCheck (
1288 VOID
1289 )
1290 {
1291 EFI_DRIVER_HEALTH_STATUS HealthStatus;
1292 EFI_STATUS Status;
1293 UINTN Index;
1294 UINTN NoHandles;
1295 EFI_HANDLE *DriverHealthHandles;
1296 EFI_DRIVER_HEALTH_PROTOCOL *DriverHealth;
1297 BOOLEAN AllHealthy;
1298
1299 //
1300 // Initialize local variables
1301 //
1302 DriverHealthHandles = NULL;
1303 DriverHealth = NULL;
1304
1305 HealthStatus = EfiDriverHealthStatusHealthy;
1306
1307 Status = gBS->LocateHandleBuffer (
1308 ByProtocol,
1309 &gEfiDriverHealthProtocolGuid,
1310 NULL,
1311 &NoHandles,
1312 &DriverHealthHandles
1313 );
1314 //
1315 // There are no handles match the search for Driver Health Protocol has been installed.
1316 //
1317 if (Status == EFI_NOT_FOUND) {
1318 return TRUE;
1319 }
1320 //
1321 // Assume all modules are healthy.
1322 //
1323 AllHealthy = TRUE;
1324
1325 //
1326 // Found one or more Handles.
1327 //
1328 if (!EFI_ERROR (Status)) {
1329 for (Index = 0; Index < NoHandles; Index++) {
1330 Status = gBS->HandleProtocol (
1331 DriverHealthHandles[Index],
1332 &gEfiDriverHealthProtocolGuid,
1333 (VOID **) &DriverHealth
1334 );
1335 if (!EFI_ERROR (Status)) {
1336 Status = DriverHealth->GetHealthStatus (
1337 DriverHealth,
1338 NULL,
1339 NULL,
1340 &HealthStatus,
1341 NULL,
1342 NULL
1343 );
1344 }
1345 //
1346 // Get the healthy status of the module
1347 //
1348 if (!EFI_ERROR (Status)) {
1349 if (HealthStatus != EfiDriverHealthStatusHealthy) {
1350 //
1351 // Return immediately one driver's status not in healthy.
1352 //
1353 return FALSE;
1354 }
1355 }
1356 }
1357 }
1358 return AllHealthy;
1359 }
1360
1361 /**
1362 Processes a single controller using the EFI Driver Health Protocol associated with
1363 that controller. This algorithm continues to query the GetHealthStatus() service until
1364 one of the legal terminal states of the EFI Driver Health Protocol is reached. This may
1365 require the processing of HII Messages, HII Form, and invocation of repair operations.
1366
1367 @param DriverHealth A pointer to the EFI_DRIVER_HEALTH_PROTOCOL instance.
1368 @param ControllerHandle The class guid specifies which form set will be displayed.
1369 @param ChildHandle The handle of the child controller to retrieve the health
1370 status on. This is an optional parameter that may be NULL.
1371 @param HealthStatus The health status of the controller.
1372 @param MessageList An array of warning or error messages associated
1373 with the controller specified by ControllerHandle and
1374 ChildHandle. This is an optional parameter that may be NULL.
1375 @param FormHiiHandle The HII handle for an HII form associated with the
1376 controller specified by ControllerHandle and ChildHandle.
1377 **/
1378 VOID
1379 ProcessSingleControllerHealth (
1380 IN EFI_DRIVER_HEALTH_PROTOCOL *DriverHealth,
1381 IN EFI_HANDLE ControllerHandle, OPTIONAL
1382 IN EFI_HANDLE ChildHandle, OPTIONAL
1383 IN EFI_DRIVER_HEALTH_STATUS HealthStatus,
1384 IN EFI_DRIVER_HEALTH_HII_MESSAGE **MessageList, OPTIONAL
1385 IN EFI_HII_HANDLE FormHiiHandle
1386 )
1387 {
1388 EFI_STATUS Status;
1389 EFI_DRIVER_HEALTH_STATUS LocalHealthStatus;
1390
1391 LocalHealthStatus = HealthStatus;
1392 //
1393 // If the module need to be repaired or reconfiguration, will process it until
1394 // reach a terminal status. The status from EfiDriverHealthStatusRepairRequired after repair
1395 // will be in (Health, Failed, Configuration Required).
1396 //
1397 while( LocalHealthStatus == EfiDriverHealthStatusConfigurationRequired ||
1398 LocalHealthStatus == EfiDriverHealthStatusRepairRequired) {
1399
1400 if (LocalHealthStatus == EfiDriverHealthStatusRepairRequired) {
1401 Status = DriverHealth->Repair (
1402 DriverHealth,
1403 ControllerHandle,
1404 ChildHandle,
1405 (EFI_DRIVER_HEALTH_REPAIR_PROGRESS_NOTIFY) RepairNotify
1406 );
1407 }
1408 //
1409 // Via a form of the driver need to do configuration provided to process of status in
1410 // EfiDriverHealthStatusConfigurationRequired. The status after configuration should be in
1411 // (Healthy, Reboot Required, Failed, Reconnect Required, Repair Required).
1412 //
1413 if (LocalHealthStatus == EfiDriverHealthStatusConfigurationRequired) {
1414 Status = gFormBrowser2->SendForm (
1415 gFormBrowser2,
1416 &FormHiiHandle,
1417 1,
1418 &gEfiHiiDriverHealthFormsetGuid,
1419 0,
1420 NULL,
1421 NULL
1422 );
1423 ASSERT( !EFI_ERROR (Status));
1424 }
1425
1426 Status = DriverHealth->GetHealthStatus (
1427 DriverHealth,
1428 ControllerHandle,
1429 ChildHandle,
1430 &LocalHealthStatus,
1431 NULL,
1432 &FormHiiHandle
1433 );
1434 ASSERT_EFI_ERROR (Status);
1435
1436 if (*MessageList != NULL) {
1437 ProcessMessages (*MessageList);
1438 }
1439 }
1440
1441 //
1442 // Health status in {Healthy, Failed} may also have Messages need to process
1443 //
1444 if (LocalHealthStatus == EfiDriverHealthStatusHealthy || LocalHealthStatus == EfiDriverHealthStatusFailed) {
1445 if (*MessageList != NULL) {
1446 ProcessMessages (*MessageList);
1447 }
1448 }
1449 //
1450 // Check for RebootRequired or ReconnectRequired
1451 //
1452 if (LocalHealthStatus == EfiDriverHealthStatusRebootRequired) {
1453 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
1454 }
1455
1456 //
1457 // Do reconnect if need.
1458 //
1459 if (LocalHealthStatus == EfiDriverHealthStatusReconnectRequired) {
1460 Status = gBS->DisconnectController (ControllerHandle, NULL, NULL);
1461 if (EFI_ERROR (Status)) {
1462 //
1463 // Disconnect failed. Need to promote reconnect to a reboot.
1464 //
1465 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
1466 }
1467 gBS->ConnectController (ControllerHandle, NULL, NULL, TRUE);
1468 }
1469 }
1470
1471
1472 /**
1473 Platform specific notification function for controller repair operations.
1474
1475 If the driver for a controller support the Driver Health Protocol and the
1476 current state of the controller is EfiDriverHealthStatusRepairRequired then
1477 when the Repair() service of the Driver Health Protocol is called, this
1478 platform specific notification function can display the progress of the repair
1479 operation. Some platforms may choose to not display anything, other may choose
1480 to show the percentage complete on text consoles, and other may choose to render
1481 a progress bar on text and graphical consoles.
1482
1483 This function displays the percentage of the repair operation that has been
1484 completed on text consoles. The percentage is Value / Limit * 100%.
1485
1486 @param Value Value in the range 0..Limit the the repair has completed..
1487 @param Limit The maximum value of Value
1488
1489 **/
1490 VOID
1491 RepairNotify (
1492 IN UINTN Value,
1493 IN UINTN Limit
1494 )
1495 {
1496 UINTN Percent;
1497
1498 if (Limit == 0) {
1499 Print(L"Repair Progress Undefined\n\r");
1500 } else {
1501 Percent = Value * 100 / Limit;
1502 Print(L"Repair Progress = %3d%%\n\r", Percent);
1503 }
1504 }
1505
1506 /**
1507 Processes a set of messages returned by the GetHealthStatus ()
1508 service of the EFI Driver Health Protocol
1509
1510 @param MessageList The MessageList point to messages need to processed.
1511
1512 **/
1513 VOID
1514 ProcessMessages (
1515 IN EFI_DRIVER_HEALTH_HII_MESSAGE *MessageList
1516 )
1517 {
1518 UINTN MessageIndex;
1519 EFI_STRING MessageString;
1520
1521 for (MessageIndex = 0;
1522 MessageList[MessageIndex].HiiHandle != NULL;
1523 MessageIndex++) {
1524
1525 MessageString = HiiGetString (
1526 MessageList[MessageIndex].HiiHandle,
1527 MessageList[MessageIndex].StringId,
1528 NULL
1529 );
1530 if (MessageString != NULL) {
1531 //
1532 // User can customize the output. Just simply print out the MessageString like below.
1533 // Also can use the HiiHandle to display message on the front page.
1534 //
1535 // Print(L"%s\n",MessageString);
1536 // gBS->Stall (100000);
1537 }
1538 }
1539
1540 }
1541
1542 /*
1543 Repair the whole platform.
1544
1545 This function is the main entry for user choose "Repair All" in the front page.
1546 It will try to do recovery job till all the driver health protocol installed modules
1547 reach a terminal state.
1548
1549 @param DriverHealthList A Pointer to the list contain all of the platform driver health
1550 information.
1551
1552 */
1553 VOID
1554 PlatformRepairAll (
1555 IN LIST_ENTRY *DriverHealthList
1556 )
1557 {
1558 DRIVER_HEALTH_INFO *DriverHealthInfo;
1559 LIST_ENTRY *Link;
1560
1561 ASSERT (DriverHealthList != NULL);
1562
1563 Link = GetFirstNode (DriverHealthList);
1564
1565 while (!IsNull (DriverHealthList, Link)) {
1566 DriverHealthInfo = DEVICE_MANAGER_HEALTH_INFO_FROM_LINK (Link);
1567 //
1568 // Do driver health status operation by each link node
1569 //
1570 ASSERT (DriverHealthInfo != NULL);
1571
1572 ProcessSingleControllerHealth (
1573 DriverHealthInfo->DriverHealth,
1574 DriverHealthInfo->ControllerHandle,
1575 DriverHealthInfo->ChildHandle,
1576 DriverHealthInfo->HealthStatus,
1577 &(DriverHealthInfo->MessageList),
1578 DriverHealthInfo->HiiHandle
1579 );
1580
1581 Link = GetNextNode (DriverHealthList, Link);
1582 }
1583 }
1584
1585 /**
1586
1587 Select the best matching language according to front page policy for best user experience.
1588
1589 This function supports both ISO 639-2 and RFC 4646 language codes, but language
1590 code types may not be mixed in a single call to this function.
1591
1592 @param SupportedLanguages A pointer to a Null-terminated ASCII string that
1593 contains a set of language codes in the format
1594 specified by Iso639Language.
1595 @param Iso639Language If TRUE, then all language codes are assumed to be
1596 in ISO 639-2 format. If FALSE, then all language
1597 codes are assumed to be in RFC 4646 language format.
1598
1599 @retval NULL The best matching language could not be found in SupportedLanguages.
1600 @retval NULL There are not enough resources available to return the best matching
1601 language.
1602 @retval Other A pointer to a Null-terminated ASCII string that is the best matching
1603 language in SupportedLanguages.
1604 **/
1605 CHAR8 *
1606 DriverHealthSelectBestLanguage (
1607 IN CHAR8 *SupportedLanguages,
1608 IN BOOLEAN Iso639Language
1609 )
1610 {
1611 CHAR8 *LanguageVariable;
1612 CHAR8 *BestLanguage;
1613
1614 LanguageVariable = GetEfiGlobalVariable (Iso639Language ? L"Lang" : L"PlatformLang");
1615
1616 BestLanguage = GetBestLanguage(
1617 SupportedLanguages,
1618 Iso639Language,
1619 (LanguageVariable != NULL) ? LanguageVariable : "",
1620 Iso639Language ? "eng" : "en-US",
1621 NULL
1622 );
1623 if (LanguageVariable != NULL) {
1624 FreePool (LanguageVariable);
1625 }
1626
1627 return BestLanguage;
1628 }
1629
1630
1631
1632 /**
1633
1634 This is an internal worker function to get the Component Name (2) protocol interface
1635 and the language it supports.
1636
1637 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
1638 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1639 @param ComponentName A pointer to the Component Name (2) protocol interface.
1640 @param SupportedLanguage The best suitable language that matches the SupportedLangues interface for the
1641 located Component Name (2) instance.
1642
1643 @param EFI_SUCCESS The Component Name (2) protocol instance is successfully located and we find
1644 the best matching language it support.
1645 @param EFI_UNSUPPORTED The input Language is not supported by the Component Name (2) protocol.
1646 @param Other Some error occurs when locating Component Name (2) protocol instance or finding
1647 the supported language.
1648
1649 **/
1650 EFI_STATUS
1651 GetComponentNameWorker (
1652 IN EFI_GUID *ProtocolGuid,
1653 IN EFI_HANDLE DriverBindingHandle,
1654 OUT EFI_COMPONENT_NAME_PROTOCOL **ComponentName,
1655 OUT CHAR8 **SupportedLanguage
1656 )
1657 {
1658 EFI_STATUS Status;
1659
1660 //
1661 // Locate Component Name (2) protocol on the driver binging handle.
1662 //
1663 Status = gBS->OpenProtocol (
1664 DriverBindingHandle,
1665 ProtocolGuid,
1666 (VOID **) ComponentName,
1667 NULL,
1668 NULL,
1669 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1670 );
1671 if (EFI_ERROR (Status)) {
1672 return Status;
1673 }
1674
1675 //
1676 // Apply shell policy to select the best language.
1677 //
1678 *SupportedLanguage = DriverHealthSelectBestLanguage (
1679 (*ComponentName)->SupportedLanguages,
1680 (BOOLEAN) (ProtocolGuid == &gEfiComponentNameProtocolGuid)
1681 );
1682 if (*SupportedLanguage == NULL) {
1683 Status = EFI_UNSUPPORTED;
1684 }
1685
1686 return Status;
1687 }
1688
1689 /**
1690
1691 This is an internal worker function to get driver name from Component Name (2) protocol interface.
1692
1693
1694 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
1695 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1696 @param DriverName A pointer to the Unicode string to return. This Unicode string is the name
1697 of the driver specified by This.
1698
1699 @retval EFI_SUCCESS The driver name is successfully retrieved from Component Name (2) protocol
1700 interface.
1701 @retval Other The driver name cannot be retrieved from Component Name (2) protocol
1702 interface.
1703
1704 **/
1705 EFI_STATUS
1706 GetDriverNameWorker (
1707 IN EFI_GUID *ProtocolGuid,
1708 IN EFI_HANDLE DriverBindingHandle,
1709 OUT CHAR16 **DriverName
1710 )
1711 {
1712 EFI_STATUS Status;
1713 CHAR8 *BestLanguage;
1714 EFI_COMPONENT_NAME_PROTOCOL *ComponentName;
1715
1716 //
1717 // Retrieve Component Name (2) protocol instance on the driver binding handle and
1718 // find the best language this instance supports.
1719 //
1720 Status = GetComponentNameWorker (
1721 ProtocolGuid,
1722 DriverBindingHandle,
1723 &ComponentName,
1724 &BestLanguage
1725 );
1726 if (EFI_ERROR (Status)) {
1727 return Status;
1728 }
1729
1730 //
1731 // Get the driver name from Component Name (2) protocol instance on the driver binging handle.
1732 //
1733 Status = ComponentName->GetDriverName (
1734 ComponentName,
1735 BestLanguage,
1736 DriverName
1737 );
1738 FreePool (BestLanguage);
1739
1740 return Status;
1741 }
1742
1743 /**
1744
1745 This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface
1746 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name.
1747 If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward
1748 compatibility support.
1749
1750 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1751 @param DriverName A pointer to the Unicode string to return. This Unicode string is the name
1752 of the driver specified by This.
1753
1754 @retval EFI_SUCCESS The driver name is successfully retrieved from Component Name (2) protocol
1755 interface.
1756 @retval Other The driver name cannot be retrieved from Component Name (2) protocol
1757 interface.
1758
1759 **/
1760 EFI_STATUS
1761 DriverHealthGetDriverName (
1762 IN EFI_HANDLE DriverBindingHandle,
1763 OUT CHAR16 **DriverName
1764 )
1765 {
1766 EFI_STATUS Status;
1767
1768 //
1769 // Get driver name from UEFI 2.0 Component Name 2 protocol interface.
1770 //
1771 Status = GetDriverNameWorker (&gEfiComponentName2ProtocolGuid, DriverBindingHandle, DriverName);
1772 if (EFI_ERROR (Status)) {
1773 //
1774 // If it fails to get the driver name from Component Name protocol interface, we should fall back on
1775 // EFI 1.1 Component Name protocol interface.
1776 //
1777 Status = GetDriverNameWorker (&gEfiComponentNameProtocolGuid, DriverBindingHandle, DriverName);
1778 }
1779
1780 return Status;
1781 }
1782
1783
1784
1785 /**
1786 This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
1787 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
1788 If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
1789 compatibility support.
1790
1791 @param ProtocolGuid A pointer to an EFI_GUID. It points to Component Name (2) protocol GUID.
1792 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1793 @param ControllerHandle The handle of a controller that the driver specified by This is managing.
1794 This handle specifies the controller whose name is to be returned.
1795 @param ChildHandle The handle of the child controller to retrieve the name of. This is an
1796 optional parameter that may be NULL. It will be NULL for device drivers.
1797 It will also be NULL for bus drivers that attempt to retrieve the name
1798 of the bus controller. It will not be NULL for a bus driver that attempts
1799 to retrieve the name of a child controller.
1800 @param ControllerName A pointer to the Unicode string to return. This Unicode string
1801 is the name of the controller specified by ControllerHandle and ChildHandle.
1802
1803 @retval EFI_SUCCESS The controller name is successfully retrieved from Component Name (2) protocol
1804 interface.
1805 @retval Other The controller name cannot be retrieved from Component Name (2) protocol.
1806
1807 **/
1808 EFI_STATUS
1809 GetControllerNameWorker (
1810 IN EFI_GUID *ProtocolGuid,
1811 IN EFI_HANDLE DriverBindingHandle,
1812 IN EFI_HANDLE ControllerHandle,
1813 IN EFI_HANDLE ChildHandle,
1814 OUT CHAR16 **ControllerName
1815 )
1816 {
1817 EFI_STATUS Status;
1818 CHAR8 *BestLanguage;
1819 EFI_COMPONENT_NAME_PROTOCOL *ComponentName;
1820
1821 //
1822 // Retrieve Component Name (2) protocol instance on the driver binding handle and
1823 // find the best language this instance supports.
1824 //
1825 Status = GetComponentNameWorker (
1826 ProtocolGuid,
1827 DriverBindingHandle,
1828 &ComponentName,
1829 &BestLanguage
1830 );
1831 if (EFI_ERROR (Status)) {
1832 return Status;
1833 }
1834
1835 //
1836 // Get the controller name from Component Name (2) protocol instance on the driver binging handle.
1837 //
1838 Status = ComponentName->GetControllerName (
1839 ComponentName,
1840 ControllerHandle,
1841 ChildHandle,
1842 BestLanguage,
1843 ControllerName
1844 );
1845 FreePool (BestLanguage);
1846
1847 return Status;
1848 }
1849
1850 /**
1851
1852 This function gets controller name from Component Name 2 protocol interface and Component Name protocol interface
1853 in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the controller name.
1854 If the attempt fails, it then gets the controller name from EFI 1.1 Component Name protocol for backward
1855 compatibility support.
1856
1857 @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved.
1858 @param ControllerHandle The handle of a controller that the driver specified by This is managing.
1859 This handle specifies the controller whose name is to be returned.
1860 @param ChildHandle The handle of the child controller to retrieve the name of. This is an
1861 optional parameter that may be NULL. It will be NULL for device drivers.
1862 It will also be NULL for bus drivers that attempt to retrieve the name
1863 of the bus controller. It will not be NULL for a bus driver that attempts
1864 to retrieve the name of a child controller.
1865 @param Language An ASCII string that represents the language command line option.
1866 @param ControllerName A pointer to the Unicode string to return. This Unicode string
1867 is the name of the controller specified by ControllerHandle and ChildHandle.
1868
1869 @retval EFI_SUCCESS The controller name is successfully retrieved from Component Name (2) protocol
1870 interface.
1871 @retval Other The controller name cannot be retrieved from Component Name (2) protocol.
1872
1873 **/
1874 EFI_STATUS
1875 DriverHealthGetControllerName (
1876 IN EFI_HANDLE DriverBindingHandle,
1877 IN EFI_HANDLE ControllerHandle,
1878 IN EFI_HANDLE ChildHandle,
1879 OUT CHAR16 **ControllerName
1880 )
1881 {
1882 EFI_STATUS Status;
1883
1884 //
1885 // Get controller name from UEFI 2.0 Component Name 2 protocol interface.
1886 //
1887 Status = GetControllerNameWorker (
1888 &gEfiComponentName2ProtocolGuid,
1889 DriverBindingHandle,
1890 ControllerHandle,
1891 ChildHandle,
1892 ControllerName
1893 );
1894 if (EFI_ERROR (Status)) {
1895 //
1896 // If it fails to get the controller name from Component Name protocol interface, we should fall back on
1897 // EFI 1.1 Component Name protocol interface.
1898 //
1899 Status = GetControllerNameWorker (
1900 &gEfiComponentNameProtocolGuid,
1901 DriverBindingHandle,
1902 ControllerHandle,
1903 ChildHandle,
1904 ControllerName
1905 );
1906 }
1907
1908 return Status;
1909 }