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