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