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