]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellCommandLib/ConsistMapping.c
ShellPkg: Refine the code to reduce time cost of 'map -r'
[mirror_edk2.git] / ShellPkg / Library / UefiShellCommandLib / ConsistMapping.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for support of shell consist mapping.\r
3\r
e75390f0 4 Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>\r
a405b86d 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12**/\r
13\r
14#include "UefiShellCommandLib.h"\r
15#include <Library/DevicePathLib.h>\r
16#include <Library/SortLib.h>\r
cc4c3312 17#include <Library/UefiLib.h>\r
0db3fade 18#include <Protocol/UsbIo.h>\r
e9fc5387
QS
19#include <Protocol/BlockIo.h>\r
20#include <Protocol/SimpleFileSystem.h>\r
21\r
22\r
a405b86d 23\r
24typedef enum {\r
25 MTDTypeUnknown,\r
26 MTDTypeFloppy,\r
27 MTDTypeHardDisk,\r
28 MTDTypeCDRom,\r
29 MTDTypeEnd\r
30} MTD_TYPE;\r
31\r
32typedef struct {\r
33 CHAR16 *Str;\r
34 UINTN Len;\r
35} POOL_PRINT;\r
36\r
37typedef struct {\r
1a63ec8f 38 UINTN Hi;\r
39 MTD_TYPE Mtd;\r
40 POOL_PRINT Csd;\r
a405b86d 41 BOOLEAN Digital;\r
42} DEVICE_CONSIST_MAPPING_INFO;\r
43\r
44typedef struct {\r
45 MTD_TYPE MTDType;\r
46 CHAR16 *Name;\r
47} MTD_NAME;\r
48\r
41089802
ED
49/**\r
50 Serial Decode function.\r
51\r
52 @param DevPath The Device path info.\r
53 @param MapInfo The map info.\r
54 @param OrigDevPath The original device path protocol.\r
55\r
56**/\r
57typedef \r
58VOID \r
59(EFIAPI *SERIAL_DECODE_FUNCTION) (\r
60 EFI_DEVICE_PATH_PROTOCOL *DevPath, \r
61 DEVICE_CONSIST_MAPPING_INFO *MapInfo,\r
62 EFI_DEVICE_PATH_PROTOCOL *OrigDevPath\r
63 );\r
0db3fade 64\r
a405b86d 65typedef struct {\r
66 UINT8 Type;\r
67 UINT8 SubType;\r
41089802 68 SERIAL_DECODE_FUNCTION SerialFun;\r
1a63ec8f 69 INTN (EFIAPI *CompareFun) (EFI_DEVICE_PATH_PROTOCOL *DevPath, EFI_DEVICE_PATH_PROTOCOL *DevPath2);\r
a405b86d 70} DEV_PATH_CONSIST_MAPPING_TABLE;\r
71\r
72\r
73/**\r
74 Concatenates a formatted unicode string to allocated pool.\r
75 The caller must free the resulting buffer.\r
76\r
77 @param Str Tracks the allocated pool, size in use, and amount of pool allocated.\r
78 @param Fmt The format string\r
79 @param ... The data will be printed.\r
80\r
81 @return Allocated buffer with the formatted string printed in it.\r
82 The caller must free the allocated buffer.\r
83 The buffer allocation is not packed.\r
84\r
85**/\r
86CHAR16 *\r
87EFIAPI\r
88CatPrint (\r
89 IN OUT POOL_PRINT *Str,\r
90 IN CHAR16 *Fmt,\r
91 ...\r
92 )\r
93{\r
94 UINT16 *AppendStr;\r
95 VA_LIST Args;\r
96 UINTN StringSize;\r
97\r
98 AppendStr = AllocateZeroPool (0x1000);\r
99 if (AppendStr == NULL) {\r
100 ASSERT(FALSE);\r
101 return Str->Str;\r
102 }\r
103\r
104 VA_START (Args, Fmt);\r
105 UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);\r
106 VA_END (Args);\r
107 if (NULL == Str->Str) {\r
108 StringSize = StrSize (AppendStr);\r
109 Str->Str = AllocateZeroPool (StringSize);\r
110 ASSERT (Str->Str != NULL);\r
111 } else {\r
112 StringSize = StrSize (AppendStr);\r
113 StringSize += (StrSize (Str->Str) - sizeof (UINT16));\r
114\r
115 Str->Str = ReallocatePool (\r
116 StrSize (Str->Str),\r
117 StringSize,\r
118 Str->Str\r
119 );\r
120 ASSERT (Str->Str != NULL);\r
121 }\r
122\r
e75390f0 123 StrCatS (Str->Str, StringSize/sizeof(CHAR16), AppendStr);\r
a405b86d 124 Str->Len = StringSize;\r
125\r
126 FreePool (AppendStr);\r
127 return Str->Str;\r
128}\r
129\r
130MTD_NAME mMTDName[] = {\r
131 {\r
132 MTDTypeUnknown,\r
133 L"F"\r
134 },\r
135 {\r
136 MTDTypeFloppy,\r
137 L"FP"\r
138 },\r
139 {\r
140 MTDTypeHardDisk,\r
141 L"HD"\r
142 },\r
143 {\r
144 MTDTypeCDRom,\r
145 L"CD"\r
146 },\r
147 {\r
148 MTDTypeEnd,\r
149 NULL\r
150 }\r
151};\r
152\r
1a63ec8f 153/**\r
154 Function to append a 64 bit number / 25 onto the string.\r
155\r
4ff7e37b
ED
156 @param[in, out] Str The string so append onto.\r
157 @param[in] Num The number to divide and append.\r
1a63ec8f 158\r
159 @retval EFI_INVALID_PARAMETER A parameter was NULL.\r
160 @retval EFI_SUCCESS The appending was successful.\r
161**/\r
162EFI_STATUS\r
163EFIAPI\r
a405b86d 164AppendCSDNum2 (\r
165 IN OUT POOL_PRINT *Str,\r
166 IN UINT64 Num\r
167 )\r
168{\r
169 UINT64 Result;\r
170 UINT32 Rem;\r
171\r
1a63ec8f 172 if (Str == NULL) {\r
173 return (EFI_INVALID_PARAMETER);\r
174 }\r
a405b86d 175\r
176 Result = DivU64x32Remainder (Num, 25, &Rem);\r
177 if (Result > 0) {\r
178 AppendCSDNum2 (Str, Result);\r
179 }\r
180\r
181 CatPrint (Str, L"%c", Rem + 'a');\r
1a63ec8f 182 return (EFI_SUCCESS);\r
a405b86d 183}\r
184\r
1a63ec8f 185/**\r
186 Function to append a 64 bit number onto the mapping info.\r
187\r
4ff7e37b
ED
188 @param[in, out] MappingItem The mapping info object to append onto.\r
189 @param[in] Num The info to append.\r
1a63ec8f 190\r
191 @retval EFI_INVALID_PARAMETER A parameter was NULL.\r
192 @retval EFI_SUCCESS The appending was successful.\r
193**/\r
194EFI_STATUS\r
195EFIAPI\r
a405b86d 196AppendCSDNum (\r
1a63ec8f 197 IN OUT DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
198 IN UINT64 Num\r
a405b86d 199 )\r
200{\r
1a63ec8f 201 if (MappingItem == NULL) {\r
202 return EFI_INVALID_PARAMETER;\r
203 }\r
a405b86d 204\r
205 if (MappingItem->Digital) {\r
1a63ec8f 206 CatPrint (&MappingItem->Csd, L"%ld", Num);\r
a405b86d 207 } else {\r
1a63ec8f 208 AppendCSDNum2 (&MappingItem->Csd, Num);\r
a405b86d 209 }\r
210\r
211 MappingItem->Digital = (BOOLEAN)!(MappingItem->Digital);\r
1a63ec8f 212\r
213 return (EFI_SUCCESS);\r
a405b86d 214}\r
215\r
1a63ec8f 216/**\r
217 Function to append string into the mapping info.\r
218\r
4ff7e37b
ED
219 @param[in, out] MappingItem The mapping info object to append onto.\r
220 @param[in] Str The info to append.\r
1a63ec8f 221\r
222 @retval EFI_INVALID_PARAMETER A parameter was NULL.\r
223 @retval EFI_SUCCESS The appending was successful.\r
224**/\r
225EFI_STATUS\r
226EFIAPI\r
a405b86d 227AppendCSDStr (\r
1a63ec8f 228 IN OUT DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
229 IN CHAR16 *Str\r
a405b86d 230 )\r
231{\r
232 CHAR16 *Index;\r
233\r
1a63ec8f 234 if (Str == NULL || MappingItem == NULL) {\r
235 return (EFI_INVALID_PARAMETER);\r
236 }\r
a405b86d 237\r
238 if (MappingItem->Digital) {\r
239 //\r
240 // To aVOID mult-meaning, the mapping is:\r
241 // 0 1 2 3 4 5 6 7 8 9 a b c d e f\r
242 // 0 16 2 3 4 5 6 7 8 9 10 11 12 13 14 15\r
243 //\r
244 for (Index = Str; *Index != 0; Index++) {\r
245 switch (*Index) {\r
246 case '0':\r
247 case '2':\r
248 case '3':\r
249 case '4':\r
250 case '5':\r
251 case '6':\r
252 case '7':\r
253 case '8':\r
254 case '9':\r
1a63ec8f 255 CatPrint (&MappingItem->Csd, L"%c", *Index);\r
a405b86d 256 break;\r
257\r
258 case '1':\r
1a63ec8f 259 CatPrint (&MappingItem->Csd, L"16");\r
a405b86d 260 break;\r
261\r
262 case 'a':\r
263 case 'b':\r
264 case 'c':\r
265 case 'd':\r
266 case 'e':\r
267 case 'f':\r
1a63ec8f 268 CatPrint (&MappingItem->Csd, L"1%c", *Index - 'a' + '0');\r
a405b86d 269 break;\r
270\r
271 case 'A':\r
272 case 'B':\r
273 case 'C':\r
274 case 'D':\r
275 case 'E':\r
276 case 'F':\r
1a63ec8f 277 CatPrint (&MappingItem->Csd, L"1%c", *Index - 'A' + '0');\r
a405b86d 278 break;\r
279 }\r
280 }\r
281 } else {\r
282 for (Index = Str; *Index != 0; Index++) {\r
283 //\r
284 // The mapping is:\r
285 // 0 1 2 3 4 5 6 7 8 9 a b c d e f\r
286 // a b c d e f g h i j k l m n o p\r
287 //\r
288 if (*Index >= '0' && *Index <= '9') {\r
1a63ec8f 289 CatPrint (&MappingItem->Csd, L"%c", *Index - '0' + 'a');\r
a405b86d 290 } else if (*Index >= 'a' && *Index <= 'f') {\r
1a63ec8f 291 CatPrint (&MappingItem->Csd, L"%c", *Index - 'a' + 'k');\r
a405b86d 292 } else if (*Index >= 'A' && *Index <= 'F') {\r
1a63ec8f 293 CatPrint (&MappingItem->Csd, L"%c", *Index - 'A' + 'k');\r
a405b86d 294 }\r
295 }\r
296 }\r
297\r
298 MappingItem->Digital = (BOOLEAN)!(MappingItem->Digital);\r
1a63ec8f 299\r
300 return (EFI_SUCCESS);\r
a405b86d 301}\r
302\r
1a63ec8f 303/**\r
304 Function to append a Guid to the mapping item.\r
305\r
4ff7e37b
ED
306 @param[in, out] MappingItem The item to append onto.\r
307 @param[in] Guid The guid to append.\r
1a63ec8f 308\r
309 @retval EFI_SUCCESS The appending operation was successful.\r
310 @retval EFI_INVALID_PARAMETER A parameter was NULL.\r
311**/\r
312EFI_STATUS\r
313EFIAPI\r
a405b86d 314AppendCSDGuid (\r
315 DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
316 EFI_GUID *Guid\r
317 )\r
318{\r
319 CHAR16 Buffer[64];\r
1a63ec8f 320\r
321 if (Guid == NULL || MappingItem == NULL) {\r
322 return (EFI_INVALID_PARAMETER);\r
323 }\r
a405b86d 324\r
325 UnicodeSPrint (\r
326 Buffer,\r
327 0,\r
328 L"%g",\r
329 Guid\r
330 );\r
1a63ec8f 331\r
a405b86d 332 AppendCSDStr (MappingItem, Buffer);\r
1a63ec8f 333\r
334 return (EFI_SUCCESS);\r
a405b86d 335}\r
336\r
1a63ec8f 337/**\r
338 Function to compare 2 APCI device paths.\r
339\r
340 @param[in] DevicePath1 The first device path to compare.\r
341 @param[in] DevicePath2 The second device path to compare.\r
342\r
343 @retval 0 The device paths represent the same device.\r
344 @return Non zero if the devices are different, zero otherwise.\r
345**/\r
a405b86d 346INTN\r
e26d7b59 347EFIAPI\r
1a63ec8f 348DevPathCompareAcpi (\r
a405b86d 349 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,\r
350 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2\r
351 )\r
352{\r
353 ACPI_HID_DEVICE_PATH *Acpi1;\r
354 ACPI_HID_DEVICE_PATH *Acpi2;\r
355\r
1a63ec8f 356 if (DevicePath1 == NULL || DevicePath2 == NULL) {\r
357 return (-2);\r
358 }\r
a405b86d 359\r
360 Acpi1 = (ACPI_HID_DEVICE_PATH *) DevicePath1;\r
361 Acpi2 = (ACPI_HID_DEVICE_PATH *) DevicePath2;\r
362 if (Acpi1->HID > Acpi2->HID || (Acpi1->HID == Acpi2->HID && Acpi1->UID > Acpi2->UID)) {\r
363 return 1;\r
364 }\r
365\r
366 if (Acpi1->HID == Acpi2->HID && Acpi1->UID == Acpi2->UID) {\r
367 return 0;\r
368 }\r
369\r
370 return -1;\r
371}\r
372\r
1a63ec8f 373/**\r
374 Function to compare 2 PCI device paths.\r
375\r
376 @param[in] DevicePath1 The first device path to compare.\r
377 @param[in] DevicePath2 The second device path to compare.\r
378\r
379 @retval 0 The device paths represent the same device.\r
380 @return Non zero if the devices are different, zero otherwise.\r
381**/\r
a405b86d 382INTN\r
e26d7b59 383EFIAPI\r
1a63ec8f 384DevPathComparePci (\r
a405b86d 385 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,\r
386 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2\r
387 )\r
388{\r
389 PCI_DEVICE_PATH *Pci1;\r
390 PCI_DEVICE_PATH *Pci2;\r
391\r
392 ASSERT(DevicePath1 != NULL);\r
393 ASSERT(DevicePath2 != NULL);\r
394\r
395 Pci1 = (PCI_DEVICE_PATH *) DevicePath1;\r
396 Pci2 = (PCI_DEVICE_PATH *) DevicePath2;\r
397 if (Pci1->Device > Pci2->Device || (Pci1->Device == Pci2->Device && Pci1->Function > Pci2->Function)) {\r
398 return 1;\r
399 }\r
400\r
401 if (Pci1->Device == Pci2->Device && Pci1->Function == Pci2->Function) {\r
402 return 0;\r
403 }\r
404\r
405 return -1;\r
406}\r
407\r
408/**\r
409 Do a comparison on 2 device paths.\r
410\r
411 @param[in] DevicePath1 The first device path.\r
412 @param[in] DevicePath2 The second device path.\r
413\r
414 @retval 0 The 2 device paths are the same.\r
415 @retval <0 DevicePath2 is greater than DevicePath1.\r
416 @retval >0 DevicePath1 is greater than DevicePath2.\r
417**/\r
418INTN\r
419EFIAPI\r
420DevPathCompareDefault (\r
421 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1,\r
422 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2\r
423 )\r
424{\r
425 UINTN DevPathSize1;\r
426 UINTN DevPathSize2;\r
427\r
428 ASSERT(DevicePath1 != NULL);\r
429 ASSERT(DevicePath2 != NULL);\r
430\r
431 DevPathSize1 = DevicePathNodeLength (DevicePath1);\r
432 DevPathSize2 = DevicePathNodeLength (DevicePath2);\r
433 if (DevPathSize1 > DevPathSize2) {\r
434 return 1;\r
435 } else if (DevPathSize1 < DevPathSize2) {\r
436 return -1;\r
437 } else {\r
438 return CompareMem (DevicePath1, DevicePath2, DevPathSize1);\r
439 }\r
440}\r
441\r
442/**\r
443 DevicePathNode must be SerialHDD Channel type and this will populate the MappingItem.\r
444\r
445 @param[in] DevicePathNode The node to get info on.\r
446 @param[in] MappingItem The info item to populate.\r
41089802 447 @param[in] DevicePath Ignored.\r
a405b86d 448**/\r
449VOID\r
450EFIAPI\r
451DevPathSerialHardDrive (\r
452 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 453 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
454 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 455 )\r
456{\r
457 HARDDRIVE_DEVICE_PATH *Hd;\r
458\r
459 ASSERT(DevicePathNode != NULL);\r
460 ASSERT(MappingItem != NULL);\r
461\r
462 Hd = (HARDDRIVE_DEVICE_PATH *) DevicePathNode;\r
1a63ec8f 463 if (MappingItem->Mtd == MTDTypeUnknown) {\r
464 MappingItem->Mtd = MTDTypeHardDisk;\r
a405b86d 465 }\r
466\r
467 AppendCSDNum (MappingItem, Hd->PartitionNumber);\r
468}\r
469\r
470/**\r
471 DevicePathNode must be SerialAtapi Channel type and this will populate the MappingItem.\r
472\r
473 @param[in] DevicePathNode The node to get info on.\r
474 @param[in] MappingItem The info item to populate.\r
41089802 475 @param[in] DevicePath Ignored.\r
a405b86d 476**/\r
477VOID\r
478EFIAPI\r
479DevPathSerialAtapi (\r
480 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 481 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
482 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 483 )\r
484{\r
485 ATAPI_DEVICE_PATH *Atapi;\r
486\r
487 ASSERT(DevicePathNode != NULL);\r
488 ASSERT(MappingItem != NULL);\r
489\r
490 Atapi = (ATAPI_DEVICE_PATH *) DevicePathNode;\r
491 AppendCSDNum (MappingItem, (Atapi->PrimarySecondary * 2 + Atapi->SlaveMaster));\r
492}\r
493\r
494/**\r
495 DevicePathNode must be SerialCDROM Channel type and this will populate the MappingItem.\r
496\r
497 @param[in] DevicePathNode The node to get info on.\r
498 @param[in] MappingItem The info item to populate.\r
41089802 499 @param[in] DevicePath Ignored.\r
a405b86d 500**/\r
501VOID\r
502EFIAPI\r
503DevPathSerialCdRom (\r
504 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 505 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
506 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 507 )\r
508{\r
509 CDROM_DEVICE_PATH *Cd;\r
510\r
511 ASSERT(DevicePathNode != NULL);\r
512 ASSERT(MappingItem != NULL);\r
513\r
514 Cd = (CDROM_DEVICE_PATH *) DevicePathNode;\r
1a63ec8f 515 MappingItem->Mtd = MTDTypeCDRom;\r
a405b86d 516 AppendCSDNum (MappingItem, Cd->BootEntry);\r
517}\r
518\r
519/**\r
520 DevicePathNode must be SerialFibre Channel type and this will populate the MappingItem.\r
521\r
522 @param[in] DevicePathNode The node to get info on.\r
523 @param[in] MappingItem The info item to populate.\r
41089802 524 @param[in] DevicePath Ignored.\r
a405b86d 525**/\r
526VOID\r
527EFIAPI\r
528DevPathSerialFibre (\r
529 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 530 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
531 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 532 )\r
533{\r
534 FIBRECHANNEL_DEVICE_PATH *Fibre;\r
535\r
536 ASSERT(DevicePathNode != NULL);\r
537 ASSERT(MappingItem != NULL);\r
538\r
539 Fibre = (FIBRECHANNEL_DEVICE_PATH *) DevicePathNode;\r
540 AppendCSDNum (MappingItem, Fibre->WWN);\r
541 AppendCSDNum (MappingItem, Fibre->Lun);\r
542}\r
543\r
544/**\r
545 DevicePathNode must be SerialUart type and this will populate the MappingItem.\r
546\r
547 @param[in] DevicePathNode The node to get info on.\r
548 @param[in] MappingItem The info item to populate.\r
41089802 549 @param[in] DevicePath Ignored.\r
a405b86d 550**/\r
551VOID\r
552EFIAPI\r
553DevPathSerialUart (\r
554 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 555 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
556 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 557 )\r
558{\r
559 UART_DEVICE_PATH *Uart;\r
560\r
561 ASSERT(DevicePathNode != NULL);\r
562 ASSERT(MappingItem != NULL);\r
563\r
564 Uart = (UART_DEVICE_PATH *) DevicePathNode;\r
565 AppendCSDNum (MappingItem, Uart->BaudRate);\r
566 AppendCSDNum (MappingItem, Uart->DataBits);\r
567 AppendCSDNum (MappingItem, Uart->Parity);\r
568 AppendCSDNum (MappingItem, Uart->StopBits);\r
569}\r
570\r
571/**\r
572 DevicePathNode must be SerialUSB type and this will populate the MappingItem.\r
573\r
574 @param[in] DevicePathNode The node to get info on.\r
575 @param[in] MappingItem The info item to populate.\r
41089802 576 @param[in] DevicePath Ignored.\r
a405b86d 577**/\r
578VOID\r
579EFIAPI\r
580DevPathSerialUsb (\r
581 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 582 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
583 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 584 )\r
585{\r
0db3fade 586 USB_DEVICE_PATH *Usb;\r
587 EFI_USB_IO_PROTOCOL *UsbIo;\r
588 EFI_HANDLE TempHandle;\r
589 EFI_STATUS Status;\r
590 USB_INTERFACE_DESCRIPTOR InterfaceDesc;\r
591\r
a405b86d 592\r
593 ASSERT(DevicePathNode != NULL);\r
594 ASSERT(MappingItem != NULL);\r
595\r
596 Usb = (USB_DEVICE_PATH *) DevicePathNode;\r
597 AppendCSDNum (MappingItem, Usb->ParentPortNumber);\r
598 AppendCSDNum (MappingItem, Usb->InterfaceNumber);\r
0db3fade 599\r
600 if (PcdGetBool(PcdUsbExtendedDecode)) {\r
601 Status = gBS->LocateDevicePath( &gEfiUsbIoProtocolGuid, &DevicePath, &TempHandle );\r
602 UsbIo = NULL;\r
603 if (!EFI_ERROR(Status)) {\r
604 Status = gBS->OpenProtocol(TempHandle, &gEfiUsbIoProtocolGuid, (VOID**)&UsbIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);\r
605 } \r
606\r
607 if (!EFI_ERROR(Status)) {\r
608 ASSERT(UsbIo != NULL);\r
609 Status = UsbIo->UsbGetInterfaceDescriptor(UsbIo, &InterfaceDesc);\r
610 if (!EFI_ERROR(Status)) {\r
611 if (InterfaceDesc.InterfaceClass == USB_MASS_STORE_CLASS && MappingItem->Mtd == MTDTypeUnknown) {\r
612 switch (InterfaceDesc.InterfaceSubClass){\r
613 case USB_MASS_STORE_SCSI:\r
614 MappingItem->Mtd = MTDTypeHardDisk;\r
615 break;\r
616 case USB_MASS_STORE_8070I:\r
617 case USB_MASS_STORE_UFI:\r
618 MappingItem->Mtd = MTDTypeFloppy;\r
619 break;\r
620 case USB_MASS_STORE_8020I:\r
621 MappingItem->Mtd = MTDTypeCDRom;\r
622 break;\r
623 }\r
624 }\r
625 }\r
626 } \r
627 }\r
a405b86d 628}\r
629\r
630/**\r
631 DevicePathNode must be SerialVendor type and this will populate the MappingItem.\r
632\r
633 @param[in] DevicePathNode The node to get info on.\r
634 @param[in] MappingItem The info item to populate.\r
41089802 635 @param[in] DevicePath Ignored.\r
1a63ec8f 636\r
a405b86d 637**/\r
638VOID\r
639EFIAPI\r
640DevPathSerialVendor (\r
641 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 642 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
643 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 644 )\r
645{\r
646 VENDOR_DEVICE_PATH *Vendor;\r
647 SAS_DEVICE_PATH *Sas;\r
cc4c3312 648 UINTN TargetNameLength;\r
649 UINTN Index;\r
650 CHAR16 *Buffer;\r
a405b86d 651\r
1a63ec8f 652 if (DevicePathNode == NULL || MappingItem == NULL) {\r
653 return;\r
654 }\r
a405b86d 655\r
656 Vendor = (VENDOR_DEVICE_PATH *) DevicePathNode;\r
657 AppendCSDGuid (MappingItem, &Vendor->Guid);\r
658\r
1a63ec8f 659 if (CompareGuid (&gEfiSasDevicePathGuid, &Vendor->Guid)) {\r
a405b86d 660 Sas = (SAS_DEVICE_PATH *) Vendor;\r
661 AppendCSDNum (MappingItem, Sas->SasAddress);\r
662 AppendCSDNum (MappingItem, Sas->Lun);\r
663 AppendCSDNum (MappingItem, Sas->DeviceTopology);\r
664 AppendCSDNum (MappingItem, Sas->RelativeTargetPort);\r
cc4c3312 665 } else {\r
666 TargetNameLength = MIN(DevicePathNodeLength (DevicePathNode) - sizeof (VENDOR_DEVICE_PATH), PcdGet32(PcdShellVendorExtendedDecode));\r
667 if (TargetNameLength != 0) {\r
668 //\r
669 // String is 2 chars per data byte, plus NULL terminator\r
670 //\r
671 Buffer = AllocateZeroPool (((TargetNameLength * 2) + 1) * sizeof(CHAR16));\r
672 ASSERT(Buffer != NULL);\r
673 if (Buffer == NULL) {\r
674 return;\r
0db3fade 675 }\r
cc4c3312 676\r
677 //\r
678 // Build the string data\r
679 //\r
680 for (Index = 0; Index < TargetNameLength; Index++) {\r
681 Buffer = CatSPrint (Buffer, L"%02x", *((UINT8*)Vendor + sizeof (VENDOR_DEVICE_PATH) + Index));\r
0db3fade 682}\r
cc4c3312 683\r
684 //\r
685 // Append the new data block\r
686 //\r
687 AppendCSDStr (MappingItem, Buffer);\r
688\r
689 FreePool(Buffer);\r
690 }\r
a405b86d 691 }\r
692}\r
693\r
694/**\r
695 DevicePathNode must be SerialLun type and this will populate the MappingItem.\r
696\r
697 @param[in] DevicePathNode The node to get info on.\r
698 @param[in] MappingItem The info item to populate.\r
41089802 699 @param[in] DevicePath Ignored.\r
a405b86d 700**/\r
701VOID\r
702EFIAPI\r
703DevPathSerialLun (\r
704 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 705 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
706 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 707 )\r
708{\r
709 DEVICE_LOGICAL_UNIT_DEVICE_PATH *Lun;\r
710\r
711 ASSERT(DevicePathNode != NULL);\r
712 ASSERT(MappingItem != NULL);\r
713\r
714 Lun = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) DevicePathNode;\r
715 AppendCSDNum (MappingItem, Lun->Lun);\r
716}\r
717\r
718/**\r
719 DevicePathNode must be SerialSata type and this will populate the MappingItem.\r
720\r
721 @param[in] DevicePathNode The node to get info on.\r
722 @param[in] MappingItem The info item to populate.\r
41089802 723 @param[in] DevicePath Ignored.\r
a405b86d 724**/\r
725VOID\r
726EFIAPI\r
727DevPathSerialSata (\r
728 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 729 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
730 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 731 )\r
732{\r
733 SATA_DEVICE_PATH *Sata;\r
734\r
735 ASSERT(DevicePathNode != NULL);\r
736 ASSERT(MappingItem != NULL);\r
737\r
738 Sata = (SATA_DEVICE_PATH *) DevicePathNode;\r
739 AppendCSDNum (MappingItem, Sata->HBAPortNumber);\r
740 AppendCSDNum (MappingItem, Sata->PortMultiplierPortNumber);\r
741 AppendCSDNum (MappingItem, Sata->Lun);\r
742}\r
743\r
744/**\r
745 DevicePathNode must be SerialSCSI type and this will populate the MappingItem.\r
746\r
747 @param[in] DevicePathNode The node to get info on.\r
748 @param[in] MappingItem The info item to populate.\r
41089802 749 @param[in] DevicePath Ignored.\r
a405b86d 750**/\r
751VOID\r
752EFIAPI\r
753DevPathSerialIScsi (\r
754 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 755 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
756 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 757 )\r
758{\r
a405b86d 759 ISCSI_DEVICE_PATH *IScsi;\r
760 UINT8 *IScsiTargetName;\r
761 CHAR16 *TargetName;\r
762 UINTN TargetNameLength;\r
763 UINTN Index;\r
764\r
765 ASSERT(DevicePathNode != NULL);\r
766 ASSERT(MappingItem != NULL);\r
767\r
9b589522
JC
768 if (PcdGetBool(PcdShellDecodeIScsiMapNames)) {\r
769 IScsi = (ISCSI_DEVICE_PATH *) DevicePathNode;\r
770 AppendCSDNum (MappingItem, IScsi->NetworkProtocol);\r
771 AppendCSDNum (MappingItem, IScsi->LoginOption);\r
772 AppendCSDNum (MappingItem, IScsi->Lun);\r
773 AppendCSDNum (MappingItem, IScsi->TargetPortalGroupTag);\r
774 TargetNameLength = DevicePathNodeLength (DevicePathNode) - sizeof (ISCSI_DEVICE_PATH);\r
775 if (TargetNameLength > 0) {\r
776 TargetName = AllocateZeroPool ((TargetNameLength + 1) * sizeof (CHAR16));\r
777 if (TargetName != NULL) {\r
778 IScsiTargetName = (UINT8 *) (IScsi + 1);\r
779 for (Index = 0; Index < TargetNameLength; Index++) {\r
780 TargetName[Index] = (CHAR16) IScsiTargetName[Index];\r
781 }\r
782 AppendCSDStr (MappingItem, TargetName);\r
783 FreePool (TargetName);\r
a405b86d 784 }\r
a405b86d 785 }\r
786 }\r
a405b86d 787}\r
788\r
789/**\r
790 DevicePathNode must be SerialI20 type and this will populate the MappingItem.\r
791\r
792 @param[in] DevicePathNode The node to get info on.\r
793 @param[in] MappingItem The info item to populate.\r
41089802 794 @param[in] DevicePath Ignored.\r
a405b86d 795**/\r
796VOID\r
797EFIAPI\r
798DevPathSerialI2O (\r
799 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 800 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
801 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 802 )\r
803{\r
1a63ec8f 804 I2O_DEVICE_PATH *DevicePath_I20;\r
a405b86d 805\r
806 ASSERT(DevicePathNode != NULL);\r
807 ASSERT(MappingItem != NULL);\r
808\r
1a63ec8f 809 DevicePath_I20 = (I2O_DEVICE_PATH *) DevicePathNode;\r
810 AppendCSDNum (MappingItem, DevicePath_I20->Tid);\r
a405b86d 811}\r
812\r
813/**\r
814 DevicePathNode must be Mac Address type and this will populate the MappingItem.\r
815\r
816 @param[in] DevicePathNode The node to get info on.\r
817 @param[in] MappingItem The info item to populate.\r
41089802 818 @param[in] DevicePath Ignored.\r
a405b86d 819**/\r
820VOID\r
821EFIAPI\r
822DevPathSerialMacAddr (\r
823 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 824 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
825 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 826 )\r
827{\r
828 MAC_ADDR_DEVICE_PATH *Mac;\r
829 UINTN HwAddressSize;\r
830 UINTN Index;\r
831 CHAR16 Buffer[64];\r
832 CHAR16 *PBuffer;\r
833\r
834 ASSERT(DevicePathNode != NULL);\r
835 ASSERT(MappingItem != NULL);\r
836\r
837 Mac = (MAC_ADDR_DEVICE_PATH *) DevicePathNode;\r
838\r
839 HwAddressSize = sizeof (EFI_MAC_ADDRESS);\r
840 if (Mac->IfType == 0x01 || Mac->IfType == 0x00) {\r
841 HwAddressSize = 6;\r
842 }\r
843\r
844 for (Index = 0, PBuffer = Buffer; Index < HwAddressSize; Index++, PBuffer += 2) {\r
845 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Mac->MacAddress.Addr[Index]);\r
846 }\r
847\r
848 AppendCSDStr (MappingItem, Buffer);\r
849}\r
850\r
851/**\r
852 DevicePathNode must be InfiniBand type and this will populate the MappingItem.\r
853\r
854 @param[in] DevicePathNode The node to get info on.\r
855 @param[in] MappingItem The info item to populate.\r
41089802 856 @param[in] DevicePath Ignored.\r
a405b86d 857**/\r
858VOID\r
859EFIAPI\r
860DevPathSerialInfiniBand (\r
861 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 862 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
863 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 864 )\r
865{\r
866 INFINIBAND_DEVICE_PATH *InfiniBand;\r
867 UINTN Index;\r
868 CHAR16 Buffer[64];\r
869 CHAR16 *PBuffer;\r
870\r
871 ASSERT(DevicePathNode != NULL);\r
872 ASSERT(MappingItem != NULL);\r
873\r
874 InfiniBand = (INFINIBAND_DEVICE_PATH *) DevicePathNode;\r
875 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {\r
876 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) InfiniBand->PortGid[Index]);\r
877 }\r
878\r
879 AppendCSDStr (MappingItem, Buffer);\r
880 AppendCSDNum (MappingItem, InfiniBand->ServiceId);\r
881 AppendCSDNum (MappingItem, InfiniBand->TargetPortId);\r
882 AppendCSDNum (MappingItem, InfiniBand->DeviceId);\r
883}\r
884\r
885/**\r
886 DevicePathNode must be IPv4 type and this will populate the MappingItem.\r
887\r
888 @param[in] DevicePathNode The node to get info on.\r
889 @param[in] MappingItem The info item to populate.\r
41089802 890 @param[in] DevicePath Ignored.\r
a405b86d 891**/\r
892VOID\r
893EFIAPI\r
894DevPathSerialIPv4 (\r
895 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 896 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
897 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 898 )\r
899{\r
900 IPv4_DEVICE_PATH *Ip;\r
901 CHAR16 Buffer[10];\r
902\r
903 ASSERT(DevicePathNode != NULL);\r
904 ASSERT(MappingItem != NULL);\r
905\r
906 Ip = (IPv4_DEVICE_PATH *) DevicePathNode;\r
907 UnicodeSPrint (\r
908 Buffer,\r
909 0,\r
910 L"%02x%02x%02x%02x",\r
911 (UINTN) Ip->LocalIpAddress.Addr[0],\r
912 (UINTN) Ip->LocalIpAddress.Addr[1],\r
913 (UINTN) Ip->LocalIpAddress.Addr[2],\r
914 (UINTN) Ip->LocalIpAddress.Addr[3]\r
915 );\r
916 AppendCSDStr (MappingItem, Buffer);\r
917 AppendCSDNum (MappingItem, Ip->LocalPort);\r
918 UnicodeSPrint (\r
919 Buffer,\r
920 0,\r
921 L"%02x%02x%02x%02x",\r
922 (UINTN) Ip->RemoteIpAddress.Addr[0],\r
923 (UINTN) Ip->RemoteIpAddress.Addr[1],\r
924 (UINTN) Ip->RemoteIpAddress.Addr[2],\r
925 (UINTN) Ip->RemoteIpAddress.Addr[3]\r
926 );\r
927 AppendCSDStr (MappingItem, Buffer);\r
928 AppendCSDNum (MappingItem, Ip->RemotePort);\r
929}\r
930\r
931/**\r
932 DevicePathNode must be IPv6 type and this will populate the MappingItem.\r
933\r
934 @param[in] DevicePathNode The node to get info on.\r
935 @param[in] MappingItem The info item to populate.\r
41089802
ED
936 @param[in] DevicePath Ignored.\r
937\r
a405b86d 938**/\r
939VOID\r
940EFIAPI\r
941DevPathSerialIPv6 (\r
942 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 943 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
944 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 945 )\r
946{\r
947 IPv6_DEVICE_PATH *Ip;\r
948 UINTN Index;\r
949 CHAR16 Buffer[64];\r
950 CHAR16 *PBuffer;\r
951\r
952 ASSERT(DevicePathNode != NULL);\r
953 ASSERT(MappingItem != NULL);\r
954\r
955 Ip = (IPv6_DEVICE_PATH *) DevicePathNode;\r
956 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {\r
957 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->LocalIpAddress.Addr[Index]);\r
958 }\r
959\r
960 AppendCSDStr (MappingItem, Buffer);\r
961 AppendCSDNum (MappingItem, Ip->LocalPort);\r
962 for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {\r
963 UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->RemoteIpAddress.Addr[Index]);\r
964 }\r
965\r
966 AppendCSDStr (MappingItem, Buffer);\r
967 AppendCSDNum (MappingItem, Ip->RemotePort);\r
968}\r
969\r
970/**\r
971 DevicePathNode must be SCSI type and this will populate the MappingItem.\r
972\r
973 @param[in] DevicePathNode The node to get info on.\r
974 @param[in] MappingItem The info item to populate.\r
41089802
ED
975 @param[in] DevicePath Ignored.\r
976\r
a405b86d 977**/\r
978VOID\r
979EFIAPI\r
980DevPathSerialScsi (\r
981 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 982 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
983 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 984 )\r
985{\r
986 SCSI_DEVICE_PATH *Scsi;\r
987\r
988 ASSERT(DevicePathNode != NULL);\r
989 ASSERT(MappingItem != NULL);\r
990\r
991 Scsi = (SCSI_DEVICE_PATH *) DevicePathNode;\r
992 AppendCSDNum (MappingItem, Scsi->Pun);\r
993 AppendCSDNum (MappingItem, Scsi->Lun);\r
994}\r
995\r
996/**\r
997 DevicePathNode must be 1394 type and this will populate the MappingItem.\r
998\r
999 @param[in] DevicePathNode The node to get info on.\r
1000 @param[in] MappingItem The info item to populate.\r
41089802 1001 @param[in] DevicePath Ignored.\r
a405b86d 1002**/\r
1003VOID\r
1004EFIAPI\r
1005DevPathSerial1394 (\r
1006 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 1007 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
1008 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 1009 )\r
1010{\r
1a63ec8f 1011 F1394_DEVICE_PATH *DevicePath_F1394;\r
a405b86d 1012 CHAR16 Buffer[20];\r
1013\r
1014 ASSERT(DevicePathNode != NULL);\r
1015 ASSERT(MappingItem != NULL);\r
1016\r
1a63ec8f 1017 DevicePath_F1394 = (F1394_DEVICE_PATH *) DevicePathNode;\r
1018 UnicodeSPrint (Buffer, 0, L"%lx", DevicePath_F1394->Guid);\r
a405b86d 1019 AppendCSDStr (MappingItem, Buffer);\r
1020}\r
1021\r
1022/**\r
1023 If the node is floppy type then populate the MappingItem.\r
1024\r
1025 @param[in] DevicePathNode The node to get info on.\r
1026 @param[in] MappingItem The info item to populate.\r
41089802 1027 @param[in] DevicePath Ignored.\r
a405b86d 1028**/\r
1029VOID\r
1030EFIAPI\r
1031DevPathSerialAcpi (\r
1032 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 1033 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
1034 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 1035 )\r
1036{\r
1037 ACPI_HID_DEVICE_PATH *Acpi;\r
1038\r
1039 ASSERT(DevicePathNode != NULL);\r
1040 ASSERT(MappingItem != NULL);\r
1041\r
1042 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;\r
1043 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {\r
1044 if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) {\r
1a63ec8f 1045 MappingItem->Mtd = MTDTypeFloppy;\r
a405b86d 1046 AppendCSDNum (MappingItem, Acpi->UID);\r
1047 }\r
1048 }\r
1049}\r
1050\r
1051/**\r
1052 Empty function used for unknown devices.\r
1053\r
1a63ec8f 1054 @param[in] DevicePathNode Ignored.\r
1055 @param[in] MappingItem Ignored.\r
41089802 1056 @param[in] DevicePath Ignored.\r
1a63ec8f 1057\r
a405b86d 1058 Does nothing.\r
1059**/\r
1060VOID\r
1061EFIAPI\r
1062DevPathSerialDefault (\r
1063 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode,\r
0db3fade 1064 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
1065 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
a405b86d 1066 )\r
1067{\r
1a63ec8f 1068 return;\r
a405b86d 1069}\r
1070\r
1071DEV_PATH_CONSIST_MAPPING_TABLE DevPathConsistMappingTable[] = {\r
ce68d3bc
SZ
1072 {\r
1073 HARDWARE_DEVICE_PATH,\r
1074 HW_PCI_DP,\r
1075 DevPathSerialDefault,\r
1076 DevPathComparePci\r
1077 },\r
1078 {\r
1079 ACPI_DEVICE_PATH,\r
1080 ACPI_DP,\r
1081 DevPathSerialAcpi,\r
1082 DevPathCompareAcpi\r
1083 },\r
1084 {\r
1085 MESSAGING_DEVICE_PATH,\r
1086 MSG_ATAPI_DP,\r
1087 DevPathSerialAtapi,\r
1088 DevPathCompareDefault\r
1089 },\r
1090 {\r
1091 MESSAGING_DEVICE_PATH,\r
1092 MSG_SCSI_DP,\r
1093 DevPathSerialScsi,\r
1094 DevPathCompareDefault\r
1095 },\r
1096 {\r
1097 MESSAGING_DEVICE_PATH,\r
1098 MSG_FIBRECHANNEL_DP,\r
1099 DevPathSerialFibre,\r
1100 DevPathCompareDefault\r
1101 },\r
1102 {\r
1103 MESSAGING_DEVICE_PATH,\r
1104 MSG_1394_DP,\r
1105 DevPathSerial1394,\r
1106 DevPathCompareDefault\r
1107 },\r
1108 {\r
1109 MESSAGING_DEVICE_PATH,\r
1110 MSG_USB_DP,\r
1111 DevPathSerialUsb,\r
1112 DevPathCompareDefault\r
1113 },\r
1114 {\r
1115 MESSAGING_DEVICE_PATH,\r
1116 MSG_I2O_DP,\r
1117 DevPathSerialI2O,\r
1118 DevPathCompareDefault\r
1119 },\r
1120 {\r
1121 MESSAGING_DEVICE_PATH,\r
1122 MSG_MAC_ADDR_DP,\r
1123 DevPathSerialMacAddr,\r
1124 DevPathCompareDefault\r
1125 },\r
1126 {\r
1127 MESSAGING_DEVICE_PATH,\r
1128 MSG_IPv4_DP,\r
1129 DevPathSerialIPv4,\r
1130 DevPathCompareDefault\r
1131 },\r
1132 {\r
1133 MESSAGING_DEVICE_PATH,\r
1134 MSG_IPv6_DP,\r
1135 DevPathSerialIPv6,\r
1136 DevPathCompareDefault\r
1137 },\r
1138 {\r
1139 MESSAGING_DEVICE_PATH,\r
1140 MSG_INFINIBAND_DP,\r
1141 DevPathSerialInfiniBand,\r
1142 DevPathCompareDefault\r
1143 },\r
1144 {\r
1145 MESSAGING_DEVICE_PATH,\r
1146 MSG_UART_DP,\r
1147 DevPathSerialUart,\r
1148 DevPathCompareDefault\r
1149 },\r
1150 {\r
1151 MESSAGING_DEVICE_PATH,\r
1152 MSG_VENDOR_DP,\r
1153 DevPathSerialVendor,\r
1154 DevPathCompareDefault\r
1155 },\r
1156 {\r
1157 MESSAGING_DEVICE_PATH,\r
1158 MSG_DEVICE_LOGICAL_UNIT_DP,\r
1159 DevPathSerialLun,\r
1160 DevPathCompareDefault\r
1161 },\r
1162 {\r
1163 MESSAGING_DEVICE_PATH,\r
1164 MSG_SATA_DP,\r
1165 DevPathSerialSata,\r
1166 DevPathCompareDefault\r
1167 },\r
1168 {\r
1169 MESSAGING_DEVICE_PATH,\r
1170 MSG_ISCSI_DP,\r
1171 DevPathSerialIScsi,\r
1172 DevPathCompareDefault\r
1173 },\r
1174 {\r
1175 MEDIA_DEVICE_PATH,\r
1176 MEDIA_HARDDRIVE_DP,\r
1177 DevPathSerialHardDrive,\r
1178 DevPathCompareDefault\r
1179 },\r
1180 {\r
1181 MEDIA_DEVICE_PATH,\r
1182 MEDIA_CDROM_DP,\r
1183 DevPathSerialCdRom,\r
1184 DevPathCompareDefault\r
1185 },\r
1186 {\r
1187 MEDIA_DEVICE_PATH,\r
1188 MEDIA_VENDOR_DP,\r
1189 DevPathSerialVendor,\r
1190 DevPathCompareDefault\r
1191 },\r
1192 {\r
1193 0,\r
1194 0,\r
1195 NULL,\r
1196 NULL\r
1197 }\r
a405b86d 1198};\r
1199\r
1200/**\r
1201 Function to determine if a device path node is Hi or not.\r
1202\r
1203 @param[in] DevicePathNode The node to check.\r
1204\r
1a63ec8f 1205 @retval TRUE The node is Hi.\r
1206 @retval FALSE The node is not Hi.\r
a405b86d 1207**/\r
1208BOOLEAN\r
1209EFIAPI\r
1210IsHIDevicePathNode (\r
1211 IN EFI_DEVICE_PATH_PROTOCOL *DevicePathNode\r
1212 )\r
1213{\r
1214 ACPI_HID_DEVICE_PATH *Acpi;\r
1215\r
1216 ASSERT(DevicePathNode != NULL);\r
1217\r
1218 if (DevicePathNode->Type == HARDWARE_DEVICE_PATH) {\r
1219 return TRUE;\r
1220 }\r
1221\r
1222 if (DevicePathNode->Type == ACPI_DEVICE_PATH) {\r
1223 Acpi = (ACPI_HID_DEVICE_PATH *) DevicePathNode;\r
1224 switch (EISA_ID_TO_NUM (Acpi->HID)) {\r
1225 case 0x0301:\r
1226 case 0x0401:\r
1227 case 0x0501:\r
1228 case 0x0604:\r
1229 return FALSE;\r
1230 }\r
1231\r
1232 return TRUE;\r
1233 }\r
1234\r
1235 return FALSE;\r
1236}\r
1237\r
1238/**\r
1a63ec8f 1239 Function to convert a standard device path structure into a Hi version.\r
a405b86d 1240\r
1241 @param[in] DevicePath The device path to convert.\r
1242\r
1a63ec8f 1243 @return the device path portion that is Hi.\r
a405b86d 1244**/\r
1245EFI_DEVICE_PATH_PROTOCOL *\r
1246EFIAPI\r
1247GetHIDevicePath (\r
1248 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
1249 )\r
1250{\r
1251 UINTN NonHIDevicePathNodeCount;\r
1252 UINTN Index;\r
1253 EFI_DEV_PATH Node;\r
1254 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;\r
1255 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;\r
1256\r
1257 ASSERT(DevicePath != NULL);\r
1258\r
1259 NonHIDevicePathNodeCount = 0;\r
1260\r
1a63ec8f 1261 HIDevicePath = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));\r
a405b86d 1262 SetDevicePathEndNode (HIDevicePath);\r
1263\r
1264 Node.DevPath.Type = END_DEVICE_PATH_TYPE;\r
1265 Node.DevPath.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;\r
1266 Node.DevPath.Length[0] = (UINT8)sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
1267 Node.DevPath.Length[1] = 0;\r
1268\r
1269 while (!IsDevicePathEnd (DevicePath)) {\r
1270 if (IsHIDevicePathNode (DevicePath)) {\r
1271 for (Index = 0; Index < NonHIDevicePathNodeCount; Index++) {\r
1272 TempDevicePath = AppendDevicePathNode (HIDevicePath, &Node.DevPath);\r
1273 FreePool (HIDevicePath);\r
1274 HIDevicePath = TempDevicePath;\r
1275 }\r
1276\r
1277 TempDevicePath = AppendDevicePathNode (HIDevicePath, DevicePath);\r
1278 FreePool (HIDevicePath);\r
1279 HIDevicePath = TempDevicePath;\r
1280 } else {\r
1281 NonHIDevicePathNodeCount++;\r
1282 }\r
1283 //\r
1284 // Next device path node\r
1285 //\r
1286 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);\r
1287 }\r
1288\r
1289 return HIDevicePath;\r
1290}\r
1291\r
1292/**\r
1293 Function to walk the device path looking for a dumpable node.\r
1294\r
1295 @param[in] MappingItem The Item to fill with data.\r
1296 @param[in] DevicePath The path of the item to get data on.\r
1297\r
1298 @return EFI_SUCCESS Always returns success.\r
1299**/\r
1300EFI_STATUS\r
1301EFIAPI\r
1302GetDeviceConsistMappingInfo (\r
1303 IN DEVICE_CONSIST_MAPPING_INFO *MappingItem,\r
1304 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
1305 )\r
1306{\r
41089802 1307 SERIAL_DECODE_FUNCTION SerialFun;\r
0db3fade 1308 UINTN Index;\r
1309 EFI_DEVICE_PATH_PROTOCOL *OriginalDevicePath;\r
a405b86d 1310\r
1311 ASSERT(DevicePath != NULL);\r
1312 ASSERT(MappingItem != NULL);\r
1313\r
1a63ec8f 1314 SetMem (&MappingItem->Csd, sizeof (POOL_PRINT), 0);\r
0db3fade 1315 OriginalDevicePath = DevicePath;\r
a405b86d 1316\r
1317 while (!IsDevicePathEnd (DevicePath)) {\r
1318 //\r
0db3fade 1319 // Find the handler to dump this device path node and\r
1320 // initialize with generic function in case nothing is found\r
a405b86d 1321 //\r
0db3fade 1322 for (SerialFun = DevPathSerialDefault, Index = 0; DevPathConsistMappingTable[Index].SerialFun != NULL; Index += 1) {\r
a405b86d 1323\r
1324 if (DevicePathType (DevicePath) == DevPathConsistMappingTable[Index].Type &&\r
1325 DevicePathSubType (DevicePath) == DevPathConsistMappingTable[Index].SubType\r
1326 ) {\r
1327 SerialFun = DevPathConsistMappingTable[Index].SerialFun;\r
1328 break;\r
1329 }\r
1330 }\r
a405b86d 1331\r
0db3fade 1332 SerialFun (DevicePath, MappingItem, OriginalDevicePath);\r
a405b86d 1333\r
1334 //\r
1335 // Next device path node\r
1336 //\r
1337 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) NextDevicePathNode (DevicePath);\r
1338 }\r
1339\r
1340 return EFI_SUCCESS;\r
1341}\r
1342\r
1343/**\r
1344 Function to initialize the table for creating consistent map names.\r
1345\r
1346 @param[out] Table The pointer to pointer to pointer to DevicePathProtocol object.\r
1347\r
1348 @retval EFI_SUCCESS The table was created successfully.\r
1349**/\r
1350EFI_STATUS\r
1351EFIAPI\r
1352ShellCommandConsistMappingInitialize (\r
1353 OUT EFI_DEVICE_PATH_PROTOCOL ***Table\r
1354 )\r
1355{\r
e9fc5387
QS
1356 EFI_HANDLE *HandleBuffer;\r
1357 UINTN HandleNum;\r
1358 UINTN HandleLoop;\r
1359 EFI_DEVICE_PATH_PROTOCOL **TempTable;\r
1360 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
1361 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;\r
1362 EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
1363 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;\r
1364 UINTN Index;\r
1365 EFI_STATUS Status;\r
a405b86d 1366\r
1367 HandleBuffer = NULL;\r
1368\r
1369 Status = gBS->LocateHandleBuffer (\r
e9fc5387
QS
1370 ByProtocol,\r
1371 &gEfiDevicePathProtocolGuid,\r
a405b86d 1372 NULL,\r
1373 &HandleNum,\r
1374 &HandleBuffer\r
1375 );\r
1376 ASSERT_EFI_ERROR(Status);\r
1377\r
1378 TempTable = AllocateZeroPool ((HandleNum + 1) * sizeof (EFI_DEVICE_PATH_PROTOCOL *));\r
1379 if (TempTable == NULL) {\r
1380 return EFI_OUT_OF_RESOURCES;\r
1381 }\r
1382\r
1383 for (HandleLoop = 0 ; HandleLoop < HandleNum ; HandleLoop++) {\r
1384 DevicePath = DevicePathFromHandle (HandleBuffer[HandleLoop]);\r
1385 if (DevicePath == NULL) {\r
1386 continue;\r
1387 }\r
1388\r
1389 HIDevicePath = GetHIDevicePath (DevicePath);\r
1390 if (HIDevicePath == NULL) {\r
1391 continue;\r
1392 }\r
1393\r
e9fc5387
QS
1394 Status = gBS->HandleProtocol( HandleBuffer[HandleLoop], \r
1395 &gEfiBlockIoProtocolGuid, \r
1396 (VOID **)&BlockIo\r
1397 );\r
1398 if (EFI_ERROR(Status)) {\r
1399 Status = gBS->HandleProtocol( HandleBuffer[HandleLoop], \r
1400 &gEfiSimpleFileSystemProtocolGuid, \r
1401 (VOID **)&SimpleFileSystem\r
1402 );\r
1403 if (EFI_ERROR(Status)) {\r
1404 continue;\r
1405 }\r
1406 }\r
1407\r
a405b86d 1408 for (Index = 0; TempTable[Index] != NULL; Index++) {\r
1409 if (DevicePathCompare (&TempTable[Index], &HIDevicePath) == 0) {\r
1410 FreePool (HIDevicePath);\r
1411 break;\r
1412 }\r
1413 }\r
1414\r
1415 if (TempTable[Index] == NULL) {\r
1416 TempTable[Index] = HIDevicePath;\r
1417 }\r
1418 }\r
1419\r
1420 for (Index = 0; TempTable[Index] != NULL; Index++);\r
1421 PerformQuickSort(TempTable, Index, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare);\r
1422 *Table = TempTable;\r
1423\r
1424 if (HandleBuffer != NULL) {\r
1425 FreePool (HandleBuffer);\r
1426 }\r
1427\r
1428 return EFI_SUCCESS;\r
1429}\r
1430\r
1431/**\r
1432 Function to uninitialize the table for creating consistent map names.\r
1433\r
1434 The parameter must have been received from ShellCommandConsistMappingInitialize.\r
1435\r
1436 @param[out] Table The pointer to pointer to DevicePathProtocol object.\r
1437\r
1438 @retval EFI_SUCCESS The table was deleted successfully.\r
1439**/\r
1440EFI_STATUS\r
1441EFIAPI\r
1442ShellCommandConsistMappingUnInitialize (\r
1443 EFI_DEVICE_PATH_PROTOCOL **Table\r
1444 )\r
1445{\r
1446 UINTN Index;\r
1447\r
1448 ASSERT(Table != NULL);\r
1449\r
1450 for (Index = 0; Table[Index] != NULL; Index++) {\r
1451 FreePool (Table[Index]);\r
1452 }\r
1453\r
1454 FreePool (Table);\r
1455 return EFI_SUCCESS;\r
1456}\r
1457\r
1458/**\r
e26d7b59 1459 Create a consistent mapped name for the device specified by DevicePath\r
a405b86d 1460 based on the Table.\r
1461\r
e26d7b59 1462 This must be called after ShellCommandConsistMappingInitialize() and\r
a405b86d 1463 before ShellCommandConsistMappingUnInitialize() is called.\r
1464\r
1a63ec8f 1465 @param[in] DevicePath The pointer to the dev path for the device.\r
a405b86d 1466 @param[in] Table The Table of mapping information.\r
1467\r
1468 @retval NULL A consistent mapped name could not be created.\r
1469 @return A pointer to a string allocated from pool with the device name.\r
1470**/\r
1471CHAR16 *\r
1472EFIAPI\r
1473ShellCommandConsistMappingGenMappingName (\r
1a63ec8f 1474 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
1475 IN EFI_DEVICE_PATH_PROTOCOL **Table\r
a405b86d 1476 )\r
1477{\r
1478 POOL_PRINT Str;\r
1479 DEVICE_CONSIST_MAPPING_INFO MappingInfo;\r
1480 EFI_DEVICE_PATH_PROTOCOL *HIDevicePath;\r
1481 UINTN Index;\r
1482 UINTN NewSize;\r
1483\r
1484 ASSERT(DevicePath != NULL);\r
1485 ASSERT(Table != NULL);\r
1486\r
1487 HIDevicePath = GetHIDevicePath (DevicePath);\r
1488 if (HIDevicePath == NULL) {\r
1489 return NULL;\r
1490 }\r
1491\r
1492 for (Index = 0; Table[Index] != NULL; Index++) {\r
1493 if (DevicePathCompare (&Table[Index], &HIDevicePath) == 0) {\r
1494 break;\r
1495 }\r
1496 }\r
1497\r
1498 FreePool (HIDevicePath);\r
1499 if (Table[Index] == NULL) {\r
1500 return NULL;\r
1501 }\r
1502\r
1a63ec8f 1503 MappingInfo.Hi = Index;\r
1504 MappingInfo.Mtd = MTDTypeUnknown;\r
a405b86d 1505 MappingInfo.Digital = FALSE;\r
1506\r
1507 GetDeviceConsistMappingInfo (&MappingInfo, DevicePath);\r
1508\r
1509 SetMem (&Str, sizeof (Str), 0);\r
1510 for (Index = 0; mMTDName[Index].MTDType != MTDTypeEnd; Index++) {\r
1a63ec8f 1511 if (MappingInfo.Mtd == mMTDName[Index].MTDType) {\r
a405b86d 1512 break;\r
1513 }\r
1514 }\r
1515\r
1516 if (mMTDName[Index].MTDType != MTDTypeEnd) {\r
1517 CatPrint (&Str, L"%s", mMTDName[Index].Name);\r
1518 }\r
1519\r
1a63ec8f 1520 CatPrint (&Str, L"%d", (UINTN) MappingInfo.Hi);\r
1521 if (MappingInfo.Csd.Str != NULL) {\r
1522 CatPrint (&Str, L"%s", MappingInfo.Csd.Str);\r
1523 FreePool (MappingInfo.Csd.Str);\r
a405b86d 1524 }\r
1525\r
1526 if (Str.Str != NULL) {\r
1527 CatPrint (&Str, L":");\r
1528 }\r
1529\r
1530 NewSize = (Str.Len + 1) * sizeof (CHAR16);\r
1531 Str.Str = ReallocatePool (Str.Len, NewSize, Str.Str);\r
e53bf79d 1532 if (Str.Str == NULL) {\r
1533 return (NULL);\r
1534 }\r
a405b86d 1535 Str.Str[Str.Len] = CHAR_NULL;\r
1536 return Str.Str;\r
1537}\r
1538\r
1539/**\r
1540 Function to search the list of mappings for the node on the list based on the key.\r
1541\r
1542 @param[in] MapKey String Key to search for on the map\r
1543\r
1544 @return the node on the list.\r
1545**/\r
1546SHELL_MAP_LIST *\r
1547EFIAPI\r
1548ShellCommandFindMapItem (\r
1549 IN CONST CHAR16 *MapKey\r
1550 )\r
1551{\r
1552 SHELL_MAP_LIST *MapListItem;\r
1553\r
1554 for ( MapListItem = (SHELL_MAP_LIST *)GetFirstNode(&gShellMapList.Link)\r
1555 ; !IsNull(&gShellMapList.Link, &MapListItem->Link)\r
1556 ; MapListItem = (SHELL_MAP_LIST *)GetNextNode(&gShellMapList.Link, &MapListItem->Link)\r
1557 ){\r
1558 if (gUnicodeCollation->StriColl(gUnicodeCollation,MapListItem->MapName,(CHAR16*)MapKey) == 0) {\r
1559 return (MapListItem);\r
1560 }\r
1561 }\r
1562 return (NULL);\r
1563}\r
1564\r
1565\r