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