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