]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellDriver1CommandsLib/DrvDiag.c
ShellPkg: Fixes and updates for the 'devices' command
[mirror_edk2.git] / ShellPkg / Library / UefiShellDriver1CommandsLib / DrvDiag.c
CommitLineData
4ba49616 1/** @file\r
2 Main file for DrvDiag shell Driver1 function.\r
3\r
a71003f2 4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
4ba49616 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "UefiShellDriver1CommandsLib.h"\r
16\r
17STATIC CONST EFI_GUID *DiagGuidList[] = {&gEfiDriverDiagnosticsProtocolGuid, &gEfiDriverDiagnostics2ProtocolGuid, NULL};\r
18//\r
19// We need 1 more item on the list...\r
20//\r
21typedef enum {\r
361a8267 22 TestModeStandard = EfiDriverDiagnosticTypeStandard,\r
23 TestModeExtended = EfiDriverDiagnosticTypeExtended,\r
24 TestModeManufacturing = EfiDriverDiagnosticTypeManufacturing,\r
25 TestModeList,\r
26 TestModeMax\r
4ba49616 27} DRV_DIAG_TEST_MODE;\r
28\r
361a8267 29/**\r
30 Do the diagnostics call for some set of handles.\r
31\r
32 @param[in] Mode The type of diagnostic test to run.\r
33 @param[in] Lang The language code to use.\r
34 @param[in] AllChilds Should the test be on all children.\r
35 @param[in] DriverHandle The driver handle to test with.\r
36 @param[in] ControllerHandle The specific controller handle to test.\r
37 @param[in] ChildHandle The specific child handle to test.\r
38\r
39 @retval EFI_SUCCESS The operation was successful.\r
40 @retval EFI_INVALID_PARAMETER A parameter had an invalid value.\r
41 @retval EFI_NOT_FOUND No diagnostic handle could be found.\r
42**/\r
4ba49616 43EFI_STATUS\r
44EFIAPI\r
45DoDiagnostics (\r
46 IN CONST DRV_DIAG_TEST_MODE Mode,\r
47 IN CONST CHAR8 *Lang,\r
48 IN CONST BOOLEAN AllChilds,\r
49 IN CONST EFI_HANDLE DriverHandle,\r
50 IN CONST EFI_HANDLE ControllerHandle,\r
51 IN CONST EFI_HANDLE ChildHandle\r
52 )\r
53{\r
54 EFI_DRIVER_DIAGNOSTICS_PROTOCOL *DriverDiagnostics;\r
55 EFI_DRIVER_DIAGNOSTICS2_PROTOCOL *DriverDiagnostics2;\r
56 EFI_HANDLE *DriverHandleList;\r
57 EFI_HANDLE *ControllerHandleList;\r
58 EFI_HANDLE *ChildHandleList;\r
59 EFI_HANDLE *Walker;\r
60 UINTN DriverHandleListCount;\r
61 UINTN ControllerHandleListCount;\r
62 UINTN ChildHandleListCount;\r
63 UINTN DriverHandleListLoop;\r
64 UINTN ControllerHandleListLoop;\r
65 UINTN ChildHandleListLoop;\r
66 EFI_STATUS Status;\r
67 EFI_STATUS Status2;\r
68 EFI_GUID *ErrorType;\r
69 UINTN OutBufferSize;\r
70 CHAR16 *OutBuffer;\r
71 UINTN HandleIndex1;\r
72 UINTN HandleIndex2;\r
361a8267 73 CHAR8 *Language;\r
361a8267 74 BOOLEAN Found;\r
4ba49616 75\r
361a8267 76 if ((ChildHandle != NULL && AllChilds) || (Mode >= TestModeMax)){\r
4ba49616 77 return (EFI_INVALID_PARAMETER);\r
78 }\r
79\r
80 DriverDiagnostics = NULL;\r
81 DriverDiagnostics2 = NULL;\r
82 Status = EFI_SUCCESS;\r
83 Status2 = EFI_SUCCESS;\r
84 DriverHandleList = NULL;\r
85 ControllerHandleList = NULL;\r
86 ChildHandleList = NULL;\r
361a8267 87 Language = NULL;\r
4ba49616 88 OutBuffer = NULL;\r
89 ErrorType = NULL;\r
90 DriverHandleListCount = 0;\r
91 ControllerHandleListCount = 0;\r
92 ChildHandleListCount = 0;\r
93\r
94 if (DriverHandle != NULL) {\r
95 DriverHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));\r
96 ASSERT(DriverHandleList!=NULL);\r
97 DriverHandleList[0] = DriverHandle;\r
98 DriverHandleListCount = 1;\r
99 } else {\r
100 DriverHandleList = GetHandleListByProtocolList(DiagGuidList);\r
101 if (DriverHandleList == NULL) {\r
361a8267 102 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"gEfiDriverDiagnosticsProtocolGuid", &gEfiDriverDiagnosticsProtocolGuid);\r
103 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"gEfiDriverDiagnostics2ProtocolGuid", &gEfiDriverDiagnostics2ProtocolGuid);\r
4ba49616 104 return (EFI_NOT_FOUND);\r
105 } \r
106 for (Walker = DriverHandleList ; Walker != NULL && *Walker != NULL ; DriverHandleListCount++, Walker++);\r
107 }\r
108\r
109 if (ControllerHandle != NULL) {\r
110 ControllerHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));\r
111 ASSERT(ControllerHandleList!=NULL);\r
112 ControllerHandleList[0] = ControllerHandle;\r
113 ControllerHandleListCount = 1;\r
114 } else {\r
115 ControllerHandleList = NULL;\r
116 }\r
117\r
118 if (ChildHandle != NULL) {\r
119 ChildHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));\r
120 ASSERT(ChildHandleList!=NULL);\r
121 ChildHandleList[0] = ChildHandle;\r
122 ChildHandleListCount = 1;\r
123 } else if (AllChilds) {\r
124 ChildHandleList = NULL;\r
125 //\r
126 // This gets handled in the loop below.\r
127 //\r
128 } else {\r
129 ChildHandleList = NULL;\r
130 }\r
131\r
361a8267 132 if (Mode == TestModeList) {\r
133 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_HEADER), gShellDriver1HiiHandle);\r
134 }\r
4ba49616 135 for (DriverHandleListLoop = 0\r
136 ; DriverHandleListLoop < DriverHandleListCount\r
137 ; DriverHandleListLoop++\r
138 ){\r
361a8267 139 if (Mode == TestModeList) {\r
140 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_DRIVER_HEADER), gShellDriver1HiiHandle, ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]));\r
141 }\r
4ba49616 142 if (ControllerHandle == NULL) {\r
143 PARSE_HANDLE_DATABASE_DEVICES(DriverHandleList[DriverHandleListLoop], &ControllerHandleListCount, &ControllerHandleList);\r
361a8267 144 } \r
145 if (ControllerHandleListCount == 0) {\r
146 if (Mode == TestModeList) {\r
147 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_DRIVER_NO_HANDLES), gShellDriver1HiiHandle);\r
148 }\r
149 } else {\r
150 if (Mode == TestModeList) {\r
151 ShellPrintEx(-1, -1, L"\r\n");\r
4ba49616 152 }\r
361a8267 153 for (ControllerHandleListLoop = 0\r
154 ; ControllerHandleListLoop < ControllerHandleListCount\r
155 ; ControllerHandleListLoop++\r
4ba49616 156 ){\r
361a8267 157 if (AllChilds) {\r
158 ASSERT(ChildHandleList == NULL);\r
159 PARSE_HANDLE_DATABASE_MANAGED_CHILDREN(\r
160 DriverHandleList[DriverHandleListLoop], \r
161 ControllerHandleList[ControllerHandleListLoop],\r
162 &ChildHandleListCount,\r
163 &ChildHandleList);\r
164 }\r
165 for (ChildHandleListLoop = 0\r
166 ; (ChildHandleListLoop < ChildHandleListCount || ChildHandleList == NULL)\r
167 ; ChildHandleListLoop++\r
168 ){\r
169 Found = FALSE;\r
170 if (Mode != TestModeList) {\r
171 if (Lang == NULL || Lang[2] == '-') {\r
172 //\r
173 // Get the protocol pointer and call the function\r
174 //\r
175 Status = gBS->OpenProtocol(\r
176 DriverHandleList[DriverHandleListLoop],\r
177 &gEfiDriverDiagnostics2ProtocolGuid,\r
178 (VOID**)&DriverDiagnostics2,\r
179 gImageHandle,\r
180 NULL,\r
181 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
a71003f2
ED
182 if (!EFI_ERROR(Status) && (DriverDiagnostics2 != NULL)) {\r
183 Language = GetBestLanguageForDriver(DriverDiagnostics2->SupportedLanguages, Lang, FALSE);\r
361a8267 184 Found = TRUE;\r
185 Status = DriverDiagnostics2->RunDiagnostics(\r
186 DriverDiagnostics2,\r
187 ControllerHandleList[ControllerHandleListLoop],\r
188 ChildHandleList == NULL?NULL:ChildHandleList[ChildHandleListLoop],\r
189 (EFI_DRIVER_DIAGNOSTIC_TYPE)Mode,\r
190 Language,\r
191 &ErrorType,\r
192 &OutBufferSize,\r
193 &OutBuffer);\r
194 FreePool(Language);\r
195 }\r
196 } \r
a1d4bfcc 197 if (!Found && (Lang == NULL||(Lang!=NULL&&(Lang[2]!='-')))){\r
361a8267 198 Status = gBS->OpenProtocol(\r
199 DriverHandleList[DriverHandleListLoop],\r
200 &gEfiDriverDiagnosticsProtocolGuid,\r
201 (VOID**)&DriverDiagnostics,\r
202 gImageHandle,\r
203 NULL,\r
204 EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
205 if (!EFI_ERROR(Status)) {\r
a71003f2 206 Language = GetBestLanguageForDriver(DriverDiagnostics->SupportedLanguages, Lang, FALSE);\r
361a8267 207 Status = DriverDiagnostics->RunDiagnostics(\r
208 DriverDiagnostics,\r
209 ControllerHandleList[ControllerHandleListLoop],\r
210 ChildHandleList == NULL?NULL:ChildHandleList[ChildHandleListLoop],\r
211 (EFI_DRIVER_DIAGNOSTIC_TYPE)Mode,\r
212 Language,\r
213 &ErrorType,\r
214 &OutBufferSize,\r
215 &OutBuffer);\r
216 FreePool(Language);\r
217 }\r
218 }\r
219 if (EFI_ERROR(Status)) {\r
220 Status2 = Status;\r
221 }\r
222 HandleIndex1 = ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]);\r
223 HandleIndex2 = ConvertHandleToHandleIndex(ControllerHandleList[ControllerHandleListLoop]);\r
224 ShellPrintHiiEx(\r
225 -1,\r
226 -1,\r
4ba49616 227 NULL,\r
361a8267 228 STRING_TOKEN (STR_3P_RESULT),\r
229 gShellDriver1HiiHandle,\r
230 L"DrvDiag",\r
231 HandleIndex1,\r
232 HandleIndex2,\r
233 ChildHandleList == NULL?0:ConvertHandleToHandleIndex(ChildHandleList[ChildHandleListLoop]),\r
234 Status);\r
235 if (OutBuffer!=NULL) {\r
236 FreePool(OutBuffer);\r
237 OutBuffer = NULL;\r
238 }\r
239 if (ErrorType!=NULL) {\r
240 FreePool(ErrorType);\r
241 ErrorType = NULL;\r
4ba49616 242 }\r
243 } else {\r
361a8267 244 HandleIndex1 = ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]);\r
245 HandleIndex2 = ConvertHandleToHandleIndex(ControllerHandleList[ControllerHandleListLoop]);\r
246 //\r
247 // Print out the information that this set can be tested\r
248 //\r
249 ShellPrintHiiEx(\r
250 -1,\r
251 -1,\r
4ba49616 252 NULL,\r
361a8267 253 STRING_TOKEN (STR_DRV_DIAG_ITEM_LINE),\r
254 gShellDriver1HiiHandle,\r
255 HandleIndex1,\r
256 HandleIndex2,\r
257 ChildHandleList == NULL?0:ConvertHandleToHandleIndex(ChildHandleList[ChildHandleListLoop])\r
258 );\r
4ba49616 259 }\r
361a8267 260\r
4ba49616 261 //\r
361a8267 262 // If we are doing a single pass with NULL child jump out after a single loop\r
4ba49616 263 //\r
361a8267 264 if (ChildHandleList == NULL) {\r
265 break;\r
266 }\r
4ba49616 267 }\r
361a8267 268 if (AllChilds) {\r
269 SHELL_FREE_NON_NULL(ChildHandleList);\r
270 ChildHandleList = NULL;\r
271 ChildHandleListCount = 0;\r
4ba49616 272 }\r
273 }\r
361a8267 274 if (ControllerHandle == NULL) {\r
275 SHELL_FREE_NON_NULL(ControllerHandleList);\r
276 ControllerHandleList = NULL;\r
277 ControllerHandleListCount = 0;\r
278 }\r
4ba49616 279 }\r
4ba49616 280 }\r
281\r
282 if (DriverHandleList != NULL) {\r
283 FreePool(DriverHandleList);\r
284 }\r
285 if (ControllerHandleList != NULL) {\r
286 FreePool(ControllerHandleList);\r
287 }\r
288 if (ChildHandleList != NULL) {\r
289 FreePool(ChildHandleList);\r
290 }\r
291 return (Status2);\r
292}\r
293\r
294\r
295STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
296 {L"-c", TypeFlag},\r
297 {L"-s", TypeFlag},\r
298 {L"-e", TypeFlag},\r
299 {L"-m", TypeFlag},\r
300 {L"-l", TypeValue},\r
301 {NULL, TypeMax}\r
302 };\r
303\r
361a8267 304/**\r
305 Function for 'drvdiag' command.\r
306\r
307 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
308 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
309**/\r
4ba49616 310SHELL_STATUS\r
311EFIAPI\r
312ShellCommandRunDrvDiag (\r
313 IN EFI_HANDLE ImageHandle,\r
314 IN EFI_SYSTEM_TABLE *SystemTable\r
315 )\r
316{\r
317 EFI_STATUS Status;\r
318 LIST_ENTRY *Package;\r
319 CHAR16 *ProblemParam;\r
320 SHELL_STATUS ShellStatus;\r
321 DRV_DIAG_TEST_MODE Mode;\r
322 CHAR8 *Language;\r
323 CONST CHAR16 *DriverHandleStr;\r
324 CONST CHAR16 *ControllerHandleStr;\r
325 CONST CHAR16 *ChildHandleStr;\r
326 CONST CHAR16 *Lang;\r
327 EFI_HANDLE Handle1;\r
328 EFI_HANDLE Handle2;\r
329 EFI_HANDLE Handle3;\r
361a8267 330 UINT64 Intermediate;\r
4ba49616 331\r
332 ShellStatus = SHELL_SUCCESS;\r
361a8267 333 Mode = TestModeMax;\r
4ba49616 334 Language = NULL;\r
335\r
336 //\r
337 // initialize the shell lib (we must be in non-auto-init...)\r
338 //\r
339 Status = ShellInitialize();\r
340 ASSERT_EFI_ERROR(Status);\r
341\r
342 Status = CommandInit();\r
343 ASSERT_EFI_ERROR(Status);\r
344\r
345 //\r
346 // parse the command line\r
347 //\r
348 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);\r
349 if (EFI_ERROR(Status)) {\r
350 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {\r
351 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, ProblemParam);\r
352 FreePool(ProblemParam);\r
353 ShellStatus = SHELL_INVALID_PARAMETER;\r
354 } else {\r
355 ASSERT(FALSE);\r
356 }\r
357 } else {\r
358 //\r
359 // if more than 3 'value' parameters (plus the name one) or we have any 2 mode flags\r
360 //\r
361 if ((ShellCommandLineGetCount(Package) > 4)\r
362 ||(ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-e"))\r
363 ||(ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-m"))\r
364 ||(ShellCommandLineGetFlag(Package, L"-e") && ShellCommandLineGetFlag(Package, L"-m"))\r
365 ){\r
366 //\r
367 // error for too many parameters\r
368 //\r
369 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle);\r
370 ShellStatus = SHELL_INVALID_PARAMETER;\r
371 } else if ((ShellCommandLineGetFlag(Package, L"-s"))\r
372 || (ShellCommandLineGetFlag(Package, L"-e"))\r
373 || (ShellCommandLineGetFlag(Package, L"-m"))\r
374 ){\r
375 //\r
376 // Run the apropriate test\r
377 //\r
378 if (ShellCommandLineGetFlag(Package, L"-s")) {\r
361a8267 379 Mode = TestModeStandard;\r
4ba49616 380 } else if (ShellCommandLineGetFlag(Package, L"-e")) {\r
361a8267 381 Mode = TestModeExtended;\r
4ba49616 382 } else if (ShellCommandLineGetFlag(Package, L"-m")) {\r
361a8267 383 Mode = TestModeManufacturing;\r
4ba49616 384 } else {\r
385 ASSERT(FALSE);\r
386 }\r
387 } else {\r
388 //\r
389 // Do a listing of what's available to test\r
390 //\r
361a8267 391 Mode = TestModeList;\r
4ba49616 392 }\r
393\r
394 Lang = ShellCommandLineGetValue(Package, L"-l");\r
361a8267 395 if (ShellCommandLineGetFlag(Package, L"-l") && Lang == NULL) {\r
4ba49616 396 ASSERT(Language == NULL);\r
397 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"-l");\r
398 ShellCommandLineFreeVarList (Package);\r
399 return (SHELL_INVALID_PARAMETER);\r
361a8267 400 } else if (Lang != NULL) {\r
401 Language = AllocateZeroPool(StrSize(Lang));\r
402 AsciiSPrint(Language, StrSize(Lang), "%S", Lang);\r
4ba49616 403 }\r
404\r
405 DriverHandleStr = ShellCommandLineGetRawValue(Package, 1);\r
406 ControllerHandleStr = ShellCommandLineGetRawValue(Package, 2);\r
407 ChildHandleStr = ShellCommandLineGetRawValue(Package, 3);\r
408\r
409 if (DriverHandleStr == NULL) {\r
410 Handle1 = NULL;\r
411 } else {\r
361a8267 412 ShellConvertStringToUint64(DriverHandleStr, &Intermediate, TRUE, FALSE);\r
413 Handle1 = ConvertHandleIndexToHandle((UINTN)Intermediate);\r
4ba49616 414 }\r
415 if (ControllerHandleStr == NULL) {\r
416 Handle2 = NULL;\r
417 } else {\r
361a8267 418 ShellConvertStringToUint64(ControllerHandleStr, &Intermediate, TRUE, FALSE);\r
419 Handle2 = ConvertHandleIndexToHandle((UINTN)Intermediate);\r
4ba49616 420 }\r
421 if (ChildHandleStr == NULL) {\r
422 Handle3 = NULL;\r
423 } else {\r
361a8267 424 ShellConvertStringToUint64(ChildHandleStr, &Intermediate, TRUE, FALSE);\r
425 Handle3 = ConvertHandleIndexToHandle((UINTN)Intermediate);\r
4ba49616 426 }\r
427\r
428 Status = DoDiagnostics (\r
429 Mode,\r
430 Language,\r
431 ShellCommandLineGetFlag(Package, L"-c"),\r
432 Handle1, \r
433 Handle2, \r
434 Handle3\r
435 );\r
436\r
437 SHELL_FREE_NON_NULL(Language);\r
438 ShellCommandLineFreeVarList (Package);\r
439\r
440 }\r
441 if (ShellStatus == SHELL_SUCCESS) {\r
442 if (Status == EFI_SECURITY_VIOLATION) {\r
443 ShellStatus = SHELL_SECURITY_VIOLATION;\r
444 } else if (Status == EFI_INVALID_PARAMETER) {\r
445 ShellStatus = SHELL_INVALID_PARAMETER;\r
446 } else if (Status == EFI_NOT_FOUND) {\r
447 ShellStatus = SHELL_NOT_FOUND;\r
448 } else if (EFI_ERROR(Status)) {\r
449 ShellStatus = SHELL_NOT_FOUND;\r
450 }\r
451 }\r
452\r
453 return (ShellStatus);\r
454}\r