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