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