]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiShellDriver1CommandsLib/DrvDiag.c
ShellPkg: Add '-nc' flag support in 'disconnect' command
[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 - 2016, 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 if (DriverHandleList == NULL) {
98 return EFI_OUT_OF_RESOURCES;
99 }
100 DriverHandleList[0] = DriverHandle;
101 DriverHandleListCount = 1;
102 } else {
103 DriverHandleList = GetHandleListByProtocolList(DiagGuidList);
104 if (DriverHandleList == NULL) {
105 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"drvdiag", L"gEfiDriverDiagnosticsProtocolGuid", &gEfiDriverDiagnosticsProtocolGuid);
106 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROTOCOL_NF), gShellDriver1HiiHandle, L"drvdiag", L"gEfiDriverDiagnostics2ProtocolGuid", &gEfiDriverDiagnostics2ProtocolGuid);
107 return (EFI_NOT_FOUND);
108 }
109 for (Walker = DriverHandleList ; Walker != NULL && *Walker != NULL ; DriverHandleListCount++, Walker++);
110 }
111
112 if (ControllerHandle != NULL) {
113 ControllerHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));
114 if (ControllerHandleList == NULL) {
115 SHELL_FREE_NON_NULL (DriverHandleList);
116 return EFI_OUT_OF_RESOURCES;
117 }
118 ControllerHandleList[0] = ControllerHandle;
119 ControllerHandleListCount = 1;
120 } else {
121 ControllerHandleList = NULL;
122 }
123
124 if (ChildHandle != NULL) {
125 ChildHandleList = AllocateZeroPool(2*sizeof(EFI_HANDLE));
126 if (ChildHandleList == NULL) {
127 SHELL_FREE_NON_NULL (ControllerHandleList);
128 SHELL_FREE_NON_NULL (DriverHandleList);
129 return EFI_OUT_OF_RESOURCES;
130 }
131 ChildHandleList[0] = ChildHandle;
132 ChildHandleListCount = 1;
133 } else if (AllChilds) {
134 ChildHandleList = NULL;
135 //
136 // This gets handled in the loop below.
137 //
138 } else {
139 ChildHandleList = NULL;
140 }
141
142 if (Mode == TestModeList) {
143 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_HEADER), gShellDriver1HiiHandle);
144 }
145 for (DriverHandleListLoop = 0
146 ; DriverHandleListLoop < DriverHandleListCount
147 ; DriverHandleListLoop++
148 ){
149 if (Mode == TestModeList) {
150 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_DRIVER_HEADER), gShellDriver1HiiHandle, ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]));
151 }
152 if (ControllerHandle == NULL) {
153 PARSE_HANDLE_DATABASE_DEVICES(DriverHandleList[DriverHandleListLoop], &ControllerHandleListCount, &ControllerHandleList);
154 }
155 if (ControllerHandleListCount == 0) {
156 if (Mode == TestModeList) {
157 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_DRVDIAG_DRIVER_NO_HANDLES), gShellDriver1HiiHandle);
158 }
159 } else {
160 if (Mode == TestModeList) {
161 ShellPrintEx(-1, -1, L"\r\n");
162 }
163 for (ControllerHandleListLoop = 0
164 ; ControllerHandleListLoop < ControllerHandleListCount
165 ; ControllerHandleListLoop++
166 ){
167 if (AllChilds) {
168 ASSERT(ChildHandleList == NULL);
169 PARSE_HANDLE_DATABASE_MANAGED_CHILDREN(
170 DriverHandleList[DriverHandleListLoop],
171 ControllerHandleList[ControllerHandleListLoop],
172 &ChildHandleListCount,
173 &ChildHandleList);
174 }
175 for (ChildHandleListLoop = 0
176 ; (ChildHandleListLoop < ChildHandleListCount || ChildHandleList == NULL)
177 ; ChildHandleListLoop++
178 ){
179 Found = FALSE;
180 if (Mode != TestModeList) {
181 if (Lang == NULL || Lang[2] == '-') {
182 //
183 // Get the protocol pointer and call the function
184 //
185 Status = gBS->OpenProtocol(
186 DriverHandleList[DriverHandleListLoop],
187 &gEfiDriverDiagnostics2ProtocolGuid,
188 (VOID**)&DriverDiagnostics2,
189 gImageHandle,
190 NULL,
191 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
192 if (!EFI_ERROR(Status) && (DriverDiagnostics2 != NULL)) {
193 Language = GetBestLanguageForDriver(DriverDiagnostics2->SupportedLanguages, Lang, FALSE);
194 Found = TRUE;
195 Status = DriverDiagnostics2->RunDiagnostics(
196 DriverDiagnostics2,
197 ControllerHandleList[ControllerHandleListLoop],
198 ChildHandleList == NULL?NULL:ChildHandleList[ChildHandleListLoop],
199 (EFI_DRIVER_DIAGNOSTIC_TYPE)Mode,
200 Language,
201 &ErrorType,
202 &OutBufferSize,
203 &OutBuffer);
204 FreePool(Language);
205 }
206 }
207 if (!Found && (Lang == NULL||(Lang!=NULL&&(Lang[2]!='-')))){
208 Status = gBS->OpenProtocol(
209 DriverHandleList[DriverHandleListLoop],
210 &gEfiDriverDiagnosticsProtocolGuid,
211 (VOID**)&DriverDiagnostics,
212 gImageHandle,
213 NULL,
214 EFI_OPEN_PROTOCOL_GET_PROTOCOL);
215 if (!EFI_ERROR(Status)) {
216 Language = GetBestLanguageForDriver(DriverDiagnostics->SupportedLanguages, Lang, FALSE);
217 Status = DriverDiagnostics->RunDiagnostics(
218 DriverDiagnostics,
219 ControllerHandleList[ControllerHandleListLoop],
220 ChildHandleList == NULL?NULL:ChildHandleList[ChildHandleListLoop],
221 (EFI_DRIVER_DIAGNOSTIC_TYPE)Mode,
222 Language,
223 &ErrorType,
224 &OutBufferSize,
225 &OutBuffer);
226 FreePool(Language);
227 }
228 }
229 if (EFI_ERROR(Status)) {
230 Status2 = Status;
231 }
232 HandleIndex1 = ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]);
233 HandleIndex2 = ConvertHandleToHandleIndex(ControllerHandleList[ControllerHandleListLoop]);
234 ShellPrintHiiEx(
235 -1,
236 -1,
237 NULL,
238 STRING_TOKEN (STR_3P_RESULT),
239 gShellDriver1HiiHandle,
240 L"DrvDiag",
241 HandleIndex1,
242 HandleIndex2,
243 ChildHandleList == NULL?0:ConvertHandleToHandleIndex(ChildHandleList[ChildHandleListLoop]),
244 Status);
245 if (OutBuffer!=NULL) {
246 FreePool(OutBuffer);
247 OutBuffer = NULL;
248 }
249 if (ErrorType!=NULL) {
250 FreePool(ErrorType);
251 ErrorType = NULL;
252 }
253 } else {
254 HandleIndex1 = ConvertHandleToHandleIndex(DriverHandleList[DriverHandleListLoop]);
255 HandleIndex2 = ConvertHandleToHandleIndex(ControllerHandleList[ControllerHandleListLoop]);
256 //
257 // Print out the information that this set can be tested
258 //
259 ShellPrintHiiEx(
260 -1,
261 -1,
262 NULL,
263 STRING_TOKEN (STR_DRV_DIAG_ITEM_LINE),
264 gShellDriver1HiiHandle,
265 HandleIndex1,
266 HandleIndex2,
267 ChildHandleList == NULL?0:ConvertHandleToHandleIndex(ChildHandleList[ChildHandleListLoop])
268 );
269 }
270
271 //
272 // If we are doing a single pass with NULL child jump out after a single loop
273 //
274 if (ChildHandleList == NULL) {
275 break;
276 }
277 }
278 if (AllChilds) {
279 SHELL_FREE_NON_NULL(ChildHandleList);
280 ChildHandleList = NULL;
281 ChildHandleListCount = 0;
282 }
283 }
284 if (ControllerHandle == NULL) {
285 SHELL_FREE_NON_NULL(ControllerHandleList);
286 ControllerHandleList = NULL;
287 ControllerHandleListCount = 0;
288 }
289 }
290 }
291
292 if (DriverHandleList != NULL) {
293 FreePool(DriverHandleList);
294 }
295 if (ControllerHandleList != NULL) {
296 FreePool(ControllerHandleList);
297 }
298 if (ChildHandleList != NULL) {
299 FreePool(ChildHandleList);
300 }
301 return (Status2);
302 }
303
304
305 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
306 {L"-c", TypeFlag},
307 {L"-s", TypeFlag},
308 {L"-e", TypeFlag},
309 {L"-m", TypeFlag},
310 {L"-l", TypeValue},
311 {NULL, TypeMax}
312 };
313
314 /**
315 Function for 'drvdiag' command.
316
317 @param[in] ImageHandle Handle to the Image (NULL if Internal).
318 @param[in] SystemTable Pointer to the System Table (NULL if Internal).
319 **/
320 SHELL_STATUS
321 EFIAPI
322 ShellCommandRunDrvDiag (
323 IN EFI_HANDLE ImageHandle,
324 IN EFI_SYSTEM_TABLE *SystemTable
325 )
326 {
327 EFI_STATUS Status;
328 LIST_ENTRY *Package;
329 CHAR16 *ProblemParam;
330 SHELL_STATUS ShellStatus;
331 DRV_DIAG_TEST_MODE Mode;
332 CHAR8 *Language;
333 CONST CHAR16 *DriverHandleStr;
334 CONST CHAR16 *ControllerHandleStr;
335 CONST CHAR16 *ChildHandleStr;
336 CONST CHAR16 *Lang;
337 EFI_HANDLE Handle1;
338 EFI_HANDLE Handle2;
339 EFI_HANDLE Handle3;
340 UINT64 Intermediate;
341
342 ShellStatus = SHELL_SUCCESS;
343 Mode = TestModeMax;
344 Language = NULL;
345
346 //
347 // initialize the shell lib (we must be in non-auto-init...)
348 //
349 Status = ShellInitialize();
350 ASSERT_EFI_ERROR(Status);
351
352 Status = CommandInit();
353 ASSERT_EFI_ERROR(Status);
354
355 //
356 // parse the command line
357 //
358 Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
359 if (EFI_ERROR(Status)) {
360 if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
361 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drvdiag", ProblemParam);
362 FreePool(ProblemParam);
363 ShellStatus = SHELL_INVALID_PARAMETER;
364 } else {
365 ASSERT(FALSE);
366 }
367 } else {
368 //
369 // if more than 3 'value' parameters (plus the name one) or we have any 2 mode flags
370 //
371 if ((ShellCommandLineGetCount(Package) > 4)
372 ||(ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-e"))
373 ||(ShellCommandLineGetFlag(Package, L"-s") && ShellCommandLineGetFlag(Package, L"-m"))
374 ||(ShellCommandLineGetFlag(Package, L"-e") && ShellCommandLineGetFlag(Package, L"-m"))
375 ){
376 //
377 // error for too many parameters
378 //
379 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drvdiag");
380 ShellStatus = SHELL_INVALID_PARAMETER;
381 } else if ((ShellCommandLineGetFlag(Package, L"-s"))
382 || (ShellCommandLineGetFlag(Package, L"-e"))
383 || (ShellCommandLineGetFlag(Package, L"-m"))
384 ){
385 //
386 // Run the appropriate test
387 //
388 if (ShellCommandLineGetFlag(Package, L"-s")) {
389 Mode = TestModeStandard;
390 } else if (ShellCommandLineGetFlag(Package, L"-e")) {
391 Mode = TestModeExtended;
392 } else if (ShellCommandLineGetFlag(Package, L"-m")) {
393 Mode = TestModeManufacturing;
394 } else {
395 ASSERT(FALSE);
396 }
397 } else {
398 //
399 // Do a listing of what's available to test
400 //
401 Mode = TestModeList;
402 }
403
404 Lang = ShellCommandLineGetValue(Package, L"-l");
405 if (ShellCommandLineGetFlag(Package, L"-l") && Lang == NULL) {
406 ASSERT(Language == NULL);
407 ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drvdiag", L"-l");
408 ShellCommandLineFreeVarList (Package);
409 return (SHELL_INVALID_PARAMETER);
410 } else if (Lang != NULL) {
411 Language = AllocateZeroPool(StrSize(Lang));
412 AsciiSPrint(Language, StrSize(Lang), "%S", Lang);
413 }
414
415 DriverHandleStr = ShellCommandLineGetRawValue(Package, 1);
416 ControllerHandleStr = ShellCommandLineGetRawValue(Package, 2);
417 ChildHandleStr = ShellCommandLineGetRawValue(Package, 3);
418
419 if (DriverHandleStr == NULL) {
420 Handle1 = NULL;
421 } else {
422 ShellConvertStringToUint64(DriverHandleStr, &Intermediate, TRUE, FALSE);
423 Handle1 = ConvertHandleIndexToHandle((UINTN)Intermediate);
424 }
425 if (ControllerHandleStr == NULL) {
426 Handle2 = NULL;
427 } else {
428 ShellConvertStringToUint64(ControllerHandleStr, &Intermediate, TRUE, FALSE);
429 Handle2 = ConvertHandleIndexToHandle((UINTN)Intermediate);
430 }
431 if (ChildHandleStr == NULL) {
432 Handle3 = NULL;
433 } else {
434 ShellConvertStringToUint64(ChildHandleStr, &Intermediate, TRUE, FALSE);
435 Handle3 = ConvertHandleIndexToHandle((UINTN)Intermediate);
436 }
437
438 Status = DoDiagnostics (
439 Mode,
440 Language,
441 ShellCommandLineGetFlag(Package, L"-c"),
442 Handle1,
443 Handle2,
444 Handle3
445 );
446
447 SHELL_FREE_NON_NULL(Language);
448 ShellCommandLineFreeVarList (Package);
449
450 }
451 if (ShellStatus == SHELL_SUCCESS) {
452 if (Status == EFI_SECURITY_VIOLATION) {
453 ShellStatus = SHELL_SECURITY_VIOLATION;
454 } else if (Status == EFI_INVALID_PARAMETER) {
455 ShellStatus = SHELL_INVALID_PARAMETER;
456 } else if (Status == EFI_NOT_FOUND) {
457 ShellStatus = SHELL_NOT_FOUND;
458 } else if (EFI_ERROR(Status)) {
459 ShellStatus = SHELL_NOT_FOUND;
460 }
461 }
462
463 return (ShellStatus);
464 }