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