]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/UefiBootManagerLib/BmDriverHealth.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmDriverHealth.c
CommitLineData
067ed98a
RN
1/** @file\r
2 Library functions which relates with driver health.\r
3\r
d1102dba 4Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
b34e4461
GL
5(C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
6(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
067ed98a
RN
7This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include "InternalBm.h"\r
18\r
19GLOBAL_REMOVE_IF_UNREFERENCED\r
20 CHAR16 *mBmHealthStatusText[] = {\r
21 L"Healthy",\r
22 L"Repair Required",\r
23 L"Configuration Required",\r
24 L"Failed",\r
25 L"Reconnect Required",\r
26 L"Reboot Required"\r
27 };\r
28\r
29/**\r
30 Return the controller name.\r
31\r
32 @param DriverHealthHandle The handle on which the Driver Health protocol instance is retrieved.\r
33 @param ControllerHandle The handle of a controller that the driver specified by DriverBindingHandle is managing.\r
34 This handle specifies the controller whose name is to be returned.\r
35 @param ChildHandle The handle of the child controller to retrieve the name of. This is an\r
36 optional parameter that may be NULL. It will be NULL for device drivers.\r
37 It will also be NULL for bus drivers that attempt to retrieve the name\r
38 of the bus controller. It will not be NULL for a bus driver that attempts\r
39 to retrieve the name of a child controller.\r
40\r
41 @return A pointer to the Unicode string to return. This Unicode string is the name of the controller\r
42 specified by ControllerHandle and ChildHandle.\r
43**/\r
44CHAR16 *\r
45BmGetControllerName (\r
46 IN EFI_HANDLE DriverHealthHandle,\r
47 IN EFI_HANDLE ControllerHandle,\r
48 IN EFI_HANDLE ChildHandle\r
49 )\r
50{\r
51 EFI_STATUS Status;\r
52 CHAR16 *ControllerName;\r
53 CHAR8 *LanguageVariable;\r
54 CHAR8 *BestLanguage;\r
55 BOOLEAN Iso639Language;\r
56 EFI_COMPONENT_NAME_PROTOCOL *ComponentName;\r
57\r
58 ControllerName = NULL;\r
59\r
60 //\r
61 // Locate Component Name (2) protocol on the driver binging handle.\r
62 //\r
63 Iso639Language = FALSE;\r
64 Status = gBS->HandleProtocol (\r
65 DriverHealthHandle,\r
66 &gEfiComponentName2ProtocolGuid,\r
67 (VOID **) &ComponentName\r
68 );\r
69 if (EFI_ERROR (Status)) {\r
70 Status = gBS->HandleProtocol (\r
71 DriverHealthHandle,\r
72 &gEfiComponentNameProtocolGuid,\r
73 (VOID **) &ComponentName\r
74 );\r
75 if (!EFI_ERROR (Status)) {\r
76 Iso639Language = TRUE;\r
77 }\r
78 }\r
79\r
80 if (!EFI_ERROR (Status)) {\r
cf34f86b 81 GetEfiGlobalVariable2 (Iso639Language ? L"Lang" : L"PlatformLang", (VOID**)&LanguageVariable, NULL);\r
067ed98a
RN
82 BestLanguage = GetBestLanguage(\r
83 ComponentName->SupportedLanguages,\r
84 Iso639Language,\r
85 (LanguageVariable != NULL) ? LanguageVariable : "",\r
86 Iso639Language ? "eng" : "en-US",\r
87 NULL\r
88 );\r
89 if (LanguageVariable != NULL) {\r
90 FreePool (LanguageVariable);\r
91 }\r
92\r
93 Status = ComponentName->GetControllerName (\r
94 ComponentName,\r
d1102dba 95 ControllerHandle,\r
067ed98a
RN
96 ChildHandle,\r
97 BestLanguage,\r
98 &ControllerName\r
99 );\r
100 }\r
101\r
102 if (!EFI_ERROR (Status)) {\r
103 return AllocateCopyPool (StrSize (ControllerName), ControllerName);\r
104 } else {\r
105 return ConvertDevicePathToText (\r
106 DevicePathFromHandle (ChildHandle != NULL ? ChildHandle : ControllerHandle),\r
107 FALSE,\r
108 FALSE\r
109 );\r
110 }\r
111}\r
112\r
113/**\r
114 Display a set of messages returned by the GetHealthStatus () service of the EFI Driver Health Protocol\r
115\r
116 @param DriverHealthInfo Pointer to the Driver Health information entry.\r
117**/\r
118VOID\r
119BmDisplayMessages (\r
120 IN EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO *DriverHealthInfo\r
121 )\r
122{\r
123 UINTN Index;\r
124 EFI_STRING String;\r
125 CHAR16 *ControllerName;\r
126\r
127 if (DriverHealthInfo->MessageList == NULL ||\r
128 DriverHealthInfo->MessageList[0].HiiHandle == NULL) {\r
129 return;\r
130 }\r
131\r
132 ControllerName = BmGetControllerName (\r
133 DriverHealthInfo->DriverHealthHandle,\r
d1102dba 134 DriverHealthInfo->ControllerHandle,\r
067ed98a
RN
135 DriverHealthInfo->ChildHandle\r
136 );\r
137\r
138 DEBUG ((EFI_D_INFO, "Controller: %s\n", ControllerName));\r
139 Print (L"Controller: %s\n", ControllerName);\r
140 for (Index = 0; DriverHealthInfo->MessageList[Index].HiiHandle != NULL; Index++) {\r
141 String = HiiGetString (\r
142 DriverHealthInfo->MessageList[Index].HiiHandle,\r
143 DriverHealthInfo->MessageList[Index].StringId,\r
144 NULL\r
145 );\r
146 if (String != NULL) {\r
147 Print (L" %s\n", String);\r
148 DEBUG ((EFI_D_INFO, " %s\n", String));\r
149 FreePool (String);\r
150 }\r
151 }\r
152\r
153 if (ControllerName != NULL) {\r
154 FreePool (ControllerName);\r
155 }\r
156}\r
157\r
158/**\r
159 The repair notify function.\r
160 @param Value A value between 0 and Limit that identifies the current progress\r
161 of the repair operation.\r
162 @param Limit The maximum value of Value for the current repair operation.\r
163 If Limit is 0, then the completion progress is indeterminate.\r
164 For example, a driver that wants to specify progress in percent\r
165 would use a Limit value of 100.\r
166\r
167 @retval EFI_SUCCESS Successfully return from the notify function.\r
168**/\r
169EFI_STATUS\r
170EFIAPI\r
171BmRepairNotify (\r
172 IN UINTN Value,\r
173 IN UINTN Limit\r
174 )\r
175{\r
176 DEBUG ((EFI_D_INFO, "[BDS]RepairNotify: %d/%d\n", Value, Limit));\r
177 Print (L"[BDS]RepairNotify: %d/%d\n", Value, Limit);\r
178\r
179 return EFI_SUCCESS;\r
180}\r
181\r
182/**\r
183 Collect the Driver Health status of a single controller.\r
d1102dba 184\r
067ed98a
RN
185 @param DriverHealthInfo A pointer to the array containing all of the platform driver health information.\r
186 @param Count Return the updated array count.\r
187 @param DriverHealthHandle The handle on which the Driver Health protocol instance is retrieved.\r
188 @param ControllerHandle The handle of the controller..\r
189 @param ChildHandle The handle of the child controller to retrieve the health\r
190 status on. This is an optional parameter that may be NULL.\r
191\r
192 @retval Status The status returned from GetHealthStatus.\r
193 @retval EFI_ABORTED The health status is healthy so no further query is needed.\r
194\r
195**/\r
196EFI_STATUS\r
197BmGetSingleControllerHealthStatus (\r
198 IN OUT EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO **DriverHealthInfo,\r
199 IN OUT UINTN *Count,\r
200 IN EFI_HANDLE DriverHealthHandle,\r
201 IN EFI_HANDLE ControllerHandle, OPTIONAL\r
202 IN EFI_HANDLE ChildHandle OPTIONAL\r
203 )\r
204{\r
205 EFI_STATUS Status;\r
206 EFI_DRIVER_HEALTH_PROTOCOL *DriverHealth;\r
207 EFI_DRIVER_HEALTH_HII_MESSAGE *MessageList;\r
208 EFI_HII_HANDLE FormHiiHandle;\r
209 EFI_DRIVER_HEALTH_STATUS HealthStatus;\r
210\r
211 ASSERT (DriverHealthHandle != NULL);\r
212 //\r
213 // Retrieve the Driver Health Protocol from DriverHandle\r
214 //\r
215 Status = gBS->HandleProtocol (\r
216 DriverHealthHandle,\r
217 &gEfiDriverHealthProtocolGuid,\r
218 (VOID **) &DriverHealth\r
219 );\r
220 ASSERT_EFI_ERROR (Status);\r
d1102dba 221\r
067ed98a
RN
222\r
223 if (ControllerHandle == NULL) {\r
224 //\r
225 // If ControllerHandle is NULL, the return the cumulative health status of the driver\r
226 //\r
227 Status = DriverHealth->GetHealthStatus (DriverHealth, NULL, NULL, &HealthStatus, NULL, NULL);\r
228 if (!EFI_ERROR (Status) && HealthStatus == EfiDriverHealthStatusHealthy) {\r
229 *DriverHealthInfo = ReallocatePool (\r
230 (*Count) * sizeof (EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO),\r
231 (*Count + 1) * sizeof (EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO),\r
232 *DriverHealthInfo\r
233 );\r
234 ASSERT (*DriverHealthInfo != NULL);\r
235\r
236 (*DriverHealthInfo)[*Count].DriverHealthHandle = DriverHealthHandle;\r
237 (*DriverHealthInfo)[*Count].DriverHealth = DriverHealth;\r
238 (*DriverHealthInfo)[*Count].HealthStatus = HealthStatus;\r
239\r
240 *Count = *Count + 1;\r
241\r
242 Status = EFI_ABORTED;\r
243 }\r
244 return Status;\r
245 }\r
246\r
247 MessageList = NULL;\r
248 FormHiiHandle = NULL;\r
249\r
250 //\r
251 // Collect the health status with the optional HII message list\r
252 //\r
253 Status = DriverHealth->GetHealthStatus (DriverHealth, ControllerHandle, ChildHandle, &HealthStatus, &MessageList, &FormHiiHandle);\r
254 if (!EFI_ERROR (Status)) {\r
255 *DriverHealthInfo = ReallocatePool (\r
256 (*Count) * sizeof (EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO),\r
257 (*Count + 1) * sizeof (EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO),\r
258 *DriverHealthInfo\r
259 );\r
260 ASSERT (*DriverHealthInfo != NULL);\r
261 (*DriverHealthInfo)[*Count].DriverHealth = DriverHealth;\r
262 (*DriverHealthInfo)[*Count].DriverHealthHandle = DriverHealthHandle;\r
263 (*DriverHealthInfo)[*Count].ControllerHandle = ControllerHandle;\r
264 (*DriverHealthInfo)[*Count].ChildHandle = ChildHandle;\r
265 (*DriverHealthInfo)[*Count].HiiHandle = FormHiiHandle;\r
266 (*DriverHealthInfo)[*Count].MessageList = MessageList;\r
267 (*DriverHealthInfo)[*Count].HealthStatus = HealthStatus;\r
268\r
269 *Count = *Count + 1;\r
270 }\r
271\r
272 return Status;\r
273}\r
274\r
275/**\r
276 Return all the Driver Health information.\r
277\r
278 When the cumulative health status of all the controllers managed by the\r
279 driver who produces the EFI_DRIVER_HEALTH_PROTOCOL is healthy, only one\r
280 EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO entry is created for such\r
281 EFI_DRIVER_HEALTH_PROTOCOL instance.\r
282 Otherwise, every controller creates one EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO\r
283 entry. Additionally every child controller creates one\r
284 EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO entry if the driver is a bus driver.\r
285\r
286 @param Count Return the count of the Driver Health information.\r
287\r
288 @retval NULL No Driver Health information is returned.\r
289 @retval !NULL Pointer to the Driver Health information array.\r
290**/\r
291EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO *\r
292EFIAPI\r
293EfiBootManagerGetDriverHealthInfo (\r
294 UINTN *Count\r
295 )\r
296{\r
297 EFI_STATUS Status;\r
298 UINTN NumHandles;\r
299 EFI_HANDLE *DriverHealthHandles;\r
067ed98a
RN
300 UINTN DriverHealthIndex;\r
301 EFI_HANDLE *Handles;\r
302 UINTN HandleCount;\r
303 UINTN ControllerIndex;\r
304 UINTN ChildIndex;\r
305 EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO *DriverHealthInfo;\r
306\r
307 //\r
308 // Initialize local variables\r
309 //\r
310 *Count = 0;\r
311 DriverHealthInfo = NULL;\r
312 Handles = NULL;\r
313 DriverHealthHandles = NULL;\r
314 NumHandles = 0;\r
315 HandleCount = 0;\r
316\r
067ed98a
RN
317 Status = gBS->LocateHandleBuffer (\r
318 ByProtocol,\r
319 &gEfiDriverHealthProtocolGuid,\r
320 NULL,\r
321 &NumHandles,\r
322 &DriverHealthHandles\r
323 );\r
324\r
325 if (Status == EFI_NOT_FOUND || NumHandles == 0) {\r
326 //\r
327 // If there are no Driver Health Protocols handles, then return EFI_NOT_FOUND\r
328 //\r
329 return NULL;\r
330 }\r
331\r
332 ASSERT_EFI_ERROR (Status);\r
333 ASSERT (DriverHealthHandles != NULL);\r
334\r
335 //\r
336 // Check the health status of all controllers in the platform\r
337 // Start by looping through all the Driver Health Protocol handles in the handle database\r
338 //\r
339 for (DriverHealthIndex = 0; DriverHealthIndex < NumHandles; DriverHealthIndex++) {\r
340 //\r
341 // Get the cumulative health status of the driver\r
342 //\r
343 Status = BmGetSingleControllerHealthStatus (&DriverHealthInfo, Count, DriverHealthHandles[DriverHealthIndex], NULL, NULL);\r
344 if (EFI_ERROR (Status)) {\r
345 continue;\r
346 }\r
347\r
348 //\r
349 // See if the list of all handles in the handle database has been retrieved\r
350 //\r
351 //\r
352 if (Handles == NULL) {\r
353 //\r
354 // Retrieve the list of all handles from the handle database\r
355 //\r
356 Status = gBS->LocateHandleBuffer (\r
357 AllHandles,\r
358 NULL,\r
359 NULL,\r
360 &HandleCount,\r
361 &Handles\r
362 );\r
363 ASSERT_EFI_ERROR (Status);\r
364 }\r
365 //\r
366 // Loop through all the controller handles in the handle database\r
367 //\r
368 for (ControllerIndex = 0; ControllerIndex < HandleCount; ControllerIndex++) {\r
369 Status = BmGetSingleControllerHealthStatus (&DriverHealthInfo, Count, DriverHealthHandles[DriverHealthIndex], Handles[ControllerIndex], NULL);\r
370 if (EFI_ERROR (Status)) {\r
371 continue;\r
372 }\r
373\r
374 //\r
375 // Loop through all the child handles in the handle database\r
376 //\r
377 for (ChildIndex = 0; ChildIndex < HandleCount; ChildIndex++) {\r
378 Status = BmGetSingleControllerHealthStatus (&DriverHealthInfo, Count, DriverHealthHandles[DriverHealthIndex], Handles[ControllerIndex], Handles[ChildIndex]);\r
379 if (EFI_ERROR (Status)) {\r
380 continue;\r
381 }\r
382 }\r
383 }\r
384 }\r
385\r
386 Status = EFI_SUCCESS;\r
387\r
388 if (Handles != NULL) {\r
389 FreePool (Handles);\r
390 }\r
391 if (DriverHealthHandles != NULL) {\r
392 FreePool (DriverHealthHandles);\r
393 }\r
394\r
395 return DriverHealthInfo;\r
396}\r
397\r
398/**\r
399 Free the Driver Health information array.\r
400\r
401 @param DriverHealthInfo Pointer to array of the Driver Health information.\r
402 @param Count Count of the array.\r
403\r
404 @retval EFI_SUCCESS The array is freed.\r
405 @retval EFI_INVALID_PARAMETER The array is NULL.\r
406**/\r
407EFI_STATUS\r
408EFIAPI\r
409EfiBootManagerFreeDriverHealthInfo (\r
410 EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO *DriverHealthInfo,\r
411 UINTN Count\r
412 )\r
413{\r
414 UINTN Index;\r
415\r
416 for (Index = 0; Index < Count; Index++) {\r
417 if (DriverHealthInfo[Index].MessageList != NULL) {\r
418 FreePool (DriverHealthInfo[Index].MessageList);\r
419 }\r
420 }\r
421 return gBS->FreePool (DriverHealthInfo);\r
422}\r
423\r
424/**\r
425 Repair all the controllers according to the Driver Health status queried.\r
72208a9a
HG
426\r
427 @param ReconnectRepairCount To record the number of recursive call of\r
428 this function itself.\r
067ed98a
RN
429**/\r
430VOID\r
431BmRepairAllControllers (\r
72208a9a 432 UINTN ReconnectRepairCount\r
067ed98a
RN
433 )\r
434{\r
435 EFI_STATUS Status;\r
436 EFI_BOOT_MANAGER_DRIVER_HEALTH_INFO *DriverHealthInfo;\r
437 EFI_DRIVER_HEALTH_STATUS HealthStatus;\r
438 UINTN Count;\r
439 UINTN Index;\r
440 BOOLEAN RepairRequired;\r
441 BOOLEAN ConfigurationRequired;\r
442 BOOLEAN ReconnectRequired;\r
443 BOOLEAN RebootRequired;\r
444 EFI_HII_HANDLE *HiiHandles;\r
445 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
b34e4461
GL
446 UINT32 MaxRepairCount;\r
447 UINT32 RepairCount;\r
067ed98a
RN
448\r
449 //\r
450 // Configure PcdDriverHealthConfigureForm to ZeroGuid to disable driver health check.\r
451 //\r
39cde03c 452 if (IsZeroGuid (PcdGetPtr (PcdDriverHealthConfigureForm))) {\r
067ed98a
RN
453 return;\r
454 }\r
455\r
456 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
457 ASSERT_EFI_ERROR (Status);\r
458\r
b34e4461
GL
459 MaxRepairCount = PcdGet32 (PcdMaxRepairCount);\r
460 RepairCount = 0;\r
461\r
067ed98a
RN
462 do {\r
463 RepairRequired = FALSE;\r
464 ConfigurationRequired = FALSE;\r
465\r
466 //\r
467 // Deal with Repair Required\r
468 //\r
469 DriverHealthInfo = EfiBootManagerGetDriverHealthInfo (&Count);\r
470 for (Index = 0; Index < Count; Index++) {\r
471 if (DriverHealthInfo[Index].HealthStatus == EfiDriverHealthStatusConfigurationRequired) {\r
472 ConfigurationRequired = TRUE;\r
473 }\r
d1102dba 474\r
067ed98a
RN
475 if (DriverHealthInfo[Index].HealthStatus == EfiDriverHealthStatusRepairRequired) {\r
476 RepairRequired = TRUE;\r
477\r
478 BmDisplayMessages (&DriverHealthInfo[Index]);\r
479\r
480 Status = DriverHealthInfo[Index].DriverHealth->Repair (\r
481 DriverHealthInfo[Index].DriverHealth,\r
482 DriverHealthInfo[Index].ControllerHandle,\r
483 DriverHealthInfo[Index].ChildHandle,\r
484 BmRepairNotify\r
485 );\r
486 if (!EFI_ERROR (Status) && !ConfigurationRequired) {\r
487 Status = DriverHealthInfo[Index].DriverHealth->GetHealthStatus (\r
488 DriverHealthInfo[Index].DriverHealth,\r
489 DriverHealthInfo[Index].ControllerHandle,\r
490 DriverHealthInfo[Index].ChildHandle,\r
491 &HealthStatus,\r
492 NULL,\r
493 NULL\r
494 );\r
495 if (!EFI_ERROR (Status) && (HealthStatus == EfiDriverHealthStatusConfigurationRequired)) {\r
496 ConfigurationRequired = TRUE;\r
497 }\r
498 }\r
499 }\r
500 }\r
501\r
502 if (ConfigurationRequired) {\r
503 HiiHandles = HiiGetHiiHandles (NULL);\r
504 if (HiiHandles != NULL) {\r
505 for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
506 Status = FormBrowser2->SendForm (\r
507 FormBrowser2,\r
508 &HiiHandles[Index],\r
509 1,\r
510 PcdGetPtr (PcdDriverHealthConfigureForm),\r
511 0,\r
512 NULL,\r
513 NULL\r
514 );\r
515 if (!EFI_ERROR (Status)) {\r
516 break;\r
517 }\r
518 }\r
519 FreePool (HiiHandles);\r
520 }\r
521 }\r
d1102dba 522\r
067ed98a 523 EfiBootManagerFreeDriverHealthInfo (DriverHealthInfo, Count);\r
b34e4461
GL
524 RepairCount++;\r
525 } while ((RepairRequired || ConfigurationRequired) && ((MaxRepairCount == 0) || (RepairCount < MaxRepairCount)));\r
067ed98a
RN
526\r
527 RebootRequired = FALSE;\r
528 ReconnectRequired = FALSE;\r
529 DriverHealthInfo = EfiBootManagerGetDriverHealthInfo (&Count);\r
530 for (Index = 0; Index < Count; Index++) {\r
531\r
532 BmDisplayMessages (&DriverHealthInfo[Index]);\r
533\r
534 if (DriverHealthInfo[Index].HealthStatus == EfiDriverHealthStatusReconnectRequired) {\r
535 Status = gBS->DisconnectController (DriverHealthInfo[Index].ControllerHandle, NULL, NULL);\r
536 if (EFI_ERROR (Status)) {\r
537 //\r
538 // Disconnect failed. Need to promote reconnect to a reboot.\r
539 //\r
540 RebootRequired = TRUE;\r
541 } else {\r
542 gBS->ConnectController (DriverHealthInfo[Index].ControllerHandle, NULL, NULL, TRUE);\r
543 ReconnectRequired = TRUE;\r
544 }\r
545 }\r
546\r
547 if (DriverHealthInfo[Index].HealthStatus == EfiDriverHealthStatusRebootRequired) {\r
548 RebootRequired = TRUE;\r
549 }\r
550 }\r
551 EfiBootManagerFreeDriverHealthInfo (DriverHealthInfo, Count);\r
552\r
553\r
067ed98a
RN
554 DEBUG_CODE (\r
555 CHAR16 *ControllerName;\r
556\r
557 DriverHealthInfo = EfiBootManagerGetDriverHealthInfo (&Count);\r
558 for (Index = 0; Index < Count; Index++) {\r
559 ControllerName = BmGetControllerName (\r
560 DriverHealthInfo[Index].DriverHealthHandle,\r
561 DriverHealthInfo[Index].ControllerHandle,\r
562 DriverHealthInfo[Index].ChildHandle\r
563 );\r
564 DEBUG ((\r
565 EFI_D_INFO,\r
566 "%02d: %s - %s\n",\r
567 Index,\r
568 ControllerName,\r
569 mBmHealthStatusText[DriverHealthInfo[Index].HealthStatus]\r
570 ));\r
571 if (ControllerName != NULL) {\r
572 FreePool (ControllerName);\r
573 }\r
574 }\r
575 EfiBootManagerFreeDriverHealthInfo (DriverHealthInfo, Count);\r
576 );\r
577\r
72208a9a
HG
578 if (ReconnectRequired) {\r
579 if (ReconnectRepairCount < MAX_RECONNECT_REPAIR) {\r
580 BmRepairAllControllers (ReconnectRepairCount + 1);\r
581 } else {\r
582 DEBUG ((DEBUG_ERROR, "[%a:%d] Repair failed after %d retries.\n",\r
583 __FUNCTION__, __LINE__, ReconnectRepairCount));\r
584 }\r
585 }\r
586\r
067ed98a
RN
587 if (RebootRequired) {\r
588 DEBUG ((EFI_D_INFO, "[BDS] One of the Driver Health instances requires rebooting.\n"));\r
589 gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);\r
590 }\r
591}\r