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