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