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