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