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