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