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