2 Main file for DrvDiag shell Driver1 function.
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
10 #include "UefiShellDriver1CommandsLib.h"
12 STATIC CONST EFI_GUID
*DiagGuidList
[] = { &gEfiDriverDiagnosticsProtocolGuid
, &gEfiDriverDiagnostics2ProtocolGuid
, NULL
};
14 // We need 1 more item on the list...
17 TestModeStandard
= EfiDriverDiagnosticTypeStandard
,
18 TestModeExtended
= EfiDriverDiagnosticTypeExtended
,
19 TestModeManufacturing
= EfiDriverDiagnosticTypeManufacturing
,
25 Do the diagnostics call for some set of handles.
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.
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.
40 IN CONST DRV_DIAG_TEST_MODE Mode
,
42 IN CONST BOOLEAN AllChilds
,
43 IN CONST EFI_HANDLE DriverHandle
,
44 IN CONST EFI_HANDLE ControllerHandle
,
45 IN CONST EFI_HANDLE ChildHandle
48 EFI_DRIVER_DIAGNOSTICS_PROTOCOL
*DriverDiagnostics
;
49 EFI_DRIVER_DIAGNOSTICS2_PROTOCOL
*DriverDiagnostics2
;
50 EFI_HANDLE
*DriverHandleList
;
51 EFI_HANDLE
*ControllerHandleList
;
52 EFI_HANDLE
*ChildHandleList
;
54 UINTN DriverHandleListCount
;
55 UINTN ControllerHandleListCount
;
56 UINTN ChildHandleListCount
;
57 UINTN DriverHandleListLoop
;
58 UINTN ControllerHandleListLoop
;
59 UINTN ChildHandleListLoop
;
70 if (((ChildHandle
!= NULL
) && AllChilds
) || (Mode
>= TestModeMax
)) {
71 return (EFI_INVALID_PARAMETER
);
74 DriverDiagnostics
= NULL
;
75 DriverDiagnostics2
= NULL
;
77 Status2
= EFI_SUCCESS
;
78 DriverHandleList
= NULL
;
79 ControllerHandleList
= NULL
;
80 ChildHandleList
= NULL
;
84 DriverHandleListCount
= 0;
85 ControllerHandleListCount
= 0;
86 ChildHandleListCount
= 0;
88 if (DriverHandle
!= NULL
) {
89 DriverHandleList
= AllocateZeroPool (2*sizeof (EFI_HANDLE
));
90 if (DriverHandleList
== NULL
) {
91 return EFI_OUT_OF_RESOURCES
;
94 DriverHandleList
[0] = DriverHandle
;
95 DriverHandleListCount
= 1;
97 DriverHandleList
= GetHandleListByProtocolList (DiagGuidList
);
98 if (DriverHandleList
== NULL
) {
99 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROTOCOL_NF
), gShellDriver1HiiHandle
, L
"drvdiag", L
"gEfiDriverDiagnosticsProtocolGuid", &gEfiDriverDiagnosticsProtocolGuid
);
100 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROTOCOL_NF
), gShellDriver1HiiHandle
, L
"drvdiag", L
"gEfiDriverDiagnostics2ProtocolGuid", &gEfiDriverDiagnostics2ProtocolGuid
);
101 return (EFI_NOT_FOUND
);
104 for (Walker
= DriverHandleList
; Walker
!= NULL
&& *Walker
!= NULL
; DriverHandleListCount
++, Walker
++) {
108 if (ControllerHandle
!= NULL
) {
109 ControllerHandleList
= AllocateZeroPool (2*sizeof (EFI_HANDLE
));
110 if (ControllerHandleList
== NULL
) {
111 SHELL_FREE_NON_NULL (DriverHandleList
);
112 return EFI_OUT_OF_RESOURCES
;
115 ControllerHandleList
[0] = ControllerHandle
;
116 ControllerHandleListCount
= 1;
118 ControllerHandleList
= NULL
;
121 if (ChildHandle
!= NULL
) {
122 ChildHandleList
= AllocateZeroPool (2*sizeof (EFI_HANDLE
));
123 if (ChildHandleList
== NULL
) {
124 SHELL_FREE_NON_NULL (ControllerHandleList
);
125 SHELL_FREE_NON_NULL (DriverHandleList
);
126 return EFI_OUT_OF_RESOURCES
;
129 ChildHandleList
[0] = ChildHandle
;
130 ChildHandleListCount
= 1;
131 } else if (AllChilds
) {
132 ChildHandleList
= NULL
;
134 // This gets handled in the loop below.
137 ChildHandleList
= NULL
;
140 if (Mode
== TestModeList
) {
141 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DRVDIAG_HEADER
), gShellDriver1HiiHandle
);
144 for (DriverHandleListLoop
= 0
145 ; DriverHandleListLoop
< DriverHandleListCount
146 ; DriverHandleListLoop
++
149 if (Mode
== TestModeList
) {
150 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DRVDIAG_DRIVER_HEADER
), gShellDriver1HiiHandle
, ConvertHandleToHandleIndex (DriverHandleList
[DriverHandleListLoop
]));
153 if (ControllerHandle
== NULL
) {
154 PARSE_HANDLE_DATABASE_DEVICES (DriverHandleList
[DriverHandleListLoop
], &ControllerHandleListCount
, &ControllerHandleList
);
157 if (ControllerHandleListCount
== 0) {
158 if (Mode
== TestModeList
) {
159 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DRVDIAG_DRIVER_NO_HANDLES
), gShellDriver1HiiHandle
);
162 if (Mode
== TestModeList
) {
163 ShellPrintEx (-1, -1, L
"\r\n");
166 for (ControllerHandleListLoop
= 0
167 ; ControllerHandleListLoop
< ControllerHandleListCount
168 ; ControllerHandleListLoop
++
172 ASSERT (ChildHandleList
== NULL
);
173 PARSE_HANDLE_DATABASE_MANAGED_CHILDREN (
174 DriverHandleList
[DriverHandleListLoop
],
175 ControllerHandleList
[ControllerHandleListLoop
],
176 &ChildHandleListCount
,
181 for (ChildHandleListLoop
= 0
182 ; (ChildHandleListLoop
< ChildHandleListCount
|| ChildHandleList
== NULL
)
183 ; ChildHandleListLoop
++
187 if (Mode
!= TestModeList
) {
188 if ((Lang
== NULL
) || (Lang
[2] == '-')) {
190 // Get the protocol pointer and call the function
192 Status
= gBS
->OpenProtocol (
193 DriverHandleList
[DriverHandleListLoop
],
194 &gEfiDriverDiagnostics2ProtocolGuid
,
195 (VOID
**)&DriverDiagnostics2
,
198 EFI_OPEN_PROTOCOL_GET_PROTOCOL
200 if (!EFI_ERROR (Status
) && (DriverDiagnostics2
!= NULL
)) {
201 Language
= GetBestLanguageForDriver (DriverDiagnostics2
->SupportedLanguages
, Lang
, FALSE
);
203 Status
= DriverDiagnostics2
->RunDiagnostics (
205 ControllerHandleList
[ControllerHandleListLoop
],
206 ChildHandleList
== NULL
? NULL
: ChildHandleList
[ChildHandleListLoop
],
207 (EFI_DRIVER_DIAGNOSTIC_TYPE
)Mode
,
217 if (!Found
&& ((Lang
== NULL
) || ((Lang
!= NULL
) && (Lang
[2] != '-')))) {
218 Status
= gBS
->OpenProtocol (
219 DriverHandleList
[DriverHandleListLoop
],
220 &gEfiDriverDiagnosticsProtocolGuid
,
221 (VOID
**)&DriverDiagnostics
,
224 EFI_OPEN_PROTOCOL_GET_PROTOCOL
226 if (!EFI_ERROR (Status
)) {
227 Language
= GetBestLanguageForDriver (DriverDiagnostics
->SupportedLanguages
, Lang
, FALSE
);
228 Status
= DriverDiagnostics
->RunDiagnostics (
230 ControllerHandleList
[ControllerHandleListLoop
],
231 ChildHandleList
== NULL
? NULL
: ChildHandleList
[ChildHandleListLoop
],
232 (EFI_DRIVER_DIAGNOSTIC_TYPE
)Mode
,
242 if (EFI_ERROR (Status
)) {
246 HandleIndex1
= ConvertHandleToHandleIndex (DriverHandleList
[DriverHandleListLoop
]);
247 HandleIndex2
= ConvertHandleToHandleIndex (ControllerHandleList
[ControllerHandleListLoop
]);
252 STRING_TOKEN (STR_3P_RESULT
),
253 gShellDriver1HiiHandle
,
257 ChildHandleList
== NULL
? 0 : ConvertHandleToHandleIndex (ChildHandleList
[ChildHandleListLoop
]),
260 if (OutBuffer
!= NULL
) {
261 FreePool (OutBuffer
);
265 if (ErrorType
!= NULL
) {
266 FreePool (ErrorType
);
270 HandleIndex1
= ConvertHandleToHandleIndex (DriverHandleList
[DriverHandleListLoop
]);
271 HandleIndex2
= ConvertHandleToHandleIndex (ControllerHandleList
[ControllerHandleListLoop
]);
273 // Print out the information that this set can be tested
279 STRING_TOKEN (STR_DRV_DIAG_ITEM_LINE
),
280 gShellDriver1HiiHandle
,
283 ChildHandleList
== NULL
? 0 : ConvertHandleToHandleIndex (ChildHandleList
[ChildHandleListLoop
])
288 // If we are doing a single pass with NULL child jump out after a single loop
290 if (ChildHandleList
== NULL
) {
296 SHELL_FREE_NON_NULL (ChildHandleList
);
297 ChildHandleList
= NULL
;
298 ChildHandleListCount
= 0;
302 if (ControllerHandle
== NULL
) {
303 SHELL_FREE_NON_NULL (ControllerHandleList
);
304 ControllerHandleList
= NULL
;
305 ControllerHandleListCount
= 0;
310 if (DriverHandleList
!= NULL
) {
311 FreePool (DriverHandleList
);
314 if (ControllerHandleList
!= NULL
) {
315 FreePool (ControllerHandleList
);
318 if (ChildHandleList
!= NULL
) {
319 FreePool (ChildHandleList
);
325 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
330 { L
"-l", TypeValue
},
335 Function for 'drvdiag' command.
337 @param[in] ImageHandle Handle to the Image (NULL if Internal).
338 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
342 ShellCommandRunDrvDiag (
343 IN EFI_HANDLE ImageHandle
,
344 IN EFI_SYSTEM_TABLE
*SystemTable
349 CHAR16
*ProblemParam
;
350 SHELL_STATUS ShellStatus
;
351 DRV_DIAG_TEST_MODE Mode
;
353 CONST CHAR16
*DriverHandleStr
;
354 CONST CHAR16
*ControllerHandleStr
;
355 CONST CHAR16
*ChildHandleStr
;
362 ShellStatus
= SHELL_SUCCESS
;
367 // initialize the shell lib (we must be in non-auto-init...)
369 Status
= ShellInitialize ();
370 ASSERT_EFI_ERROR (Status
);
372 Status
= CommandInit ();
373 ASSERT_EFI_ERROR (Status
);
376 // parse the command line
378 Status
= ShellCommandLineParse (ParamList
, &Package
, &ProblemParam
, TRUE
);
379 if (EFI_ERROR (Status
)) {
380 if ((Status
== EFI_VOLUME_CORRUPTED
) && (ProblemParam
!= NULL
)) {
381 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_PROBLEM
), gShellDriver1HiiHandle
, L
"drvdiag", ProblemParam
);
382 FreePool (ProblemParam
);
383 ShellStatus
= SHELL_INVALID_PARAMETER
;
389 // if more than 3 'value' parameters (plus the name one) or we have any 2 mode flags
391 if ( (ShellCommandLineGetCount (Package
) > 4)
392 || (ShellCommandLineGetFlag (Package
, L
"-s") && ShellCommandLineGetFlag (Package
, L
"-e"))
393 || (ShellCommandLineGetFlag (Package
, L
"-s") && ShellCommandLineGetFlag (Package
, L
"-m"))
394 || (ShellCommandLineGetFlag (Package
, L
"-e") && ShellCommandLineGetFlag (Package
, L
"-m"))
398 // error for too many parameters
400 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_TOO_MANY
), gShellDriver1HiiHandle
, L
"drvdiag");
401 ShellStatus
= SHELL_INVALID_PARAMETER
;
402 } else if ( (ShellCommandLineGetFlag (Package
, L
"-s"))
403 || (ShellCommandLineGetFlag (Package
, L
"-e"))
404 || (ShellCommandLineGetFlag (Package
, L
"-m"))
408 // Run the appropriate test
410 if (ShellCommandLineGetFlag (Package
, L
"-s")) {
411 Mode
= TestModeStandard
;
412 } else if (ShellCommandLineGetFlag (Package
, L
"-e")) {
413 Mode
= TestModeExtended
;
414 } else if (ShellCommandLineGetFlag (Package
, L
"-m")) {
415 Mode
= TestModeManufacturing
;
421 // Do a listing of what's available to test
426 Lang
= ShellCommandLineGetValue (Package
, L
"-l");
427 if (ShellCommandLineGetFlag (Package
, L
"-l") && (Lang
== NULL
)) {
428 ASSERT (Language
== NULL
);
429 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_GEN_NO_VALUE
), gShellDriver1HiiHandle
, L
"drvdiag", L
"-l");
430 ShellCommandLineFreeVarList (Package
);
431 return (SHELL_INVALID_PARAMETER
);
432 } else if (Lang
!= NULL
) {
433 Language
= AllocateZeroPool (StrSize (Lang
));
434 AsciiSPrint (Language
, StrSize (Lang
), "%S", Lang
);
437 DriverHandleStr
= ShellCommandLineGetRawValue (Package
, 1);
438 ControllerHandleStr
= ShellCommandLineGetRawValue (Package
, 2);
439 ChildHandleStr
= ShellCommandLineGetRawValue (Package
, 3);
441 if (DriverHandleStr
== NULL
) {
444 ShellConvertStringToUint64 (DriverHandleStr
, &Intermediate
, TRUE
, FALSE
);
445 Handle1
= ConvertHandleIndexToHandle ((UINTN
)Intermediate
);
448 if (ControllerHandleStr
== NULL
) {
451 ShellConvertStringToUint64 (ControllerHandleStr
, &Intermediate
, TRUE
, FALSE
);
452 Handle2
= ConvertHandleIndexToHandle ((UINTN
)Intermediate
);
455 if (ChildHandleStr
== NULL
) {
458 ShellConvertStringToUint64 (ChildHandleStr
, &Intermediate
, TRUE
, FALSE
);
459 Handle3
= ConvertHandleIndexToHandle ((UINTN
)Intermediate
);
462 Status
= DoDiagnostics (
465 ShellCommandLineGetFlag (Package
, L
"-c"),
471 SHELL_FREE_NON_NULL (Language
);
472 ShellCommandLineFreeVarList (Package
);
475 if (ShellStatus
== SHELL_SUCCESS
) {
476 if (Status
== EFI_SECURITY_VIOLATION
) {
477 ShellStatus
= SHELL_SECURITY_VIOLATION
;
478 } else if (Status
== EFI_INVALID_PARAMETER
) {
479 ShellStatus
= SHELL_INVALID_PARAMETER
;
480 } else if (Status
== EFI_NOT_FOUND
) {
481 ShellStatus
= SHELL_NOT_FOUND
;
482 } else if (EFI_ERROR (Status
)) {
483 ShellStatus
= SHELL_NOT_FOUND
;
487 return (ShellStatus
);