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