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