]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/GenericBdsLib/DevicePath.c
Clean up GenericBdsLib library Instance.
[mirror_edk2.git] / MdeModulePkg / Library / GenericBdsLib / DevicePath.c
1 /** @file
2 BDS internal function define the default device path string, it can be
3 replaced by platform device path.
4
5 Copyright (c) 2004 - 2008, Intel Corporation. <BR>
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "InternalBdsLib.h"
17
18
19 EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid = DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL;
20
21 EFI_GUID mEfiDevicePathMessagingSASGuid = DEVICE_PATH_MESSAGING_SAS;
22
23
24 /**
25
26 Adjusts the size of a previously allocated buffer.
27
28
29 @param OldPool A pointer to the buffer whose size is being adjusted.
30 @param OldSize The size of the current buffer.
31 @param NewSize The size of the new buffer.
32
33 @return The new buffer allocated. If allocatio failed, NULL will be returned.
34
35 **/
36 VOID *
37 ReallocatePool (
38 IN VOID *OldPool,
39 IN UINTN OldSize,
40 IN UINTN NewSize
41 )
42 {
43 VOID *NewPool;
44
45 NewPool = NULL;
46 if (NewSize != 0) {
47 NewPool = AllocateZeroPool (NewSize);
48 }
49
50 if (OldPool != NULL) {
51 if (NewPool != NULL) {
52 CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
53 }
54
55 gBS->FreePool (OldPool);
56 }
57
58 return NewPool;
59 }
60
61
62 /**
63 Concatenates a formatted unicode string to allocated pool.
64 The caller must free the resulting buffer.
65
66 @param Str Tracks the allocated pool, size in use, and amount of pool
67 allocated.
68 @param fmt The format string
69
70 @param ... Variable argument list.
71
72 @return Allocated buffer with the formatted string printed in it.
73 The caller must free the allocated buffer. The buffer
74 allocation is not packed.
75
76 **/
77 CHAR16 *
78 EFIAPI
79 CatPrint (
80 IN OUT POOL_PRINT *Str,
81 IN CHAR16 *fmt,
82 ...
83 )
84 {
85 UINT16 *AppendStr;
86 VA_LIST Args;
87 UINTN StringSize;
88
89 AppendStr = AllocateZeroPool (0x1000);
90 if (AppendStr == NULL) {
91 return Str->str;
92 }
93
94 VA_START (Args, fmt);
95 UnicodeVSPrint (AppendStr, 0x1000, fmt, Args);
96 VA_END (Args);
97 if (NULL == Str->str) {
98 StringSize = StrSize (AppendStr);
99 Str->str = AllocateZeroPool (StringSize);
100 ASSERT (Str->str != NULL);
101 } else {
102 StringSize = StrSize (AppendStr);
103 StringSize += (StrSize (Str->str) - sizeof (UINT16));
104
105 Str->str = ReallocatePool (
106 Str->str,
107 StrSize (Str->str),
108 StringSize
109 );
110 ASSERT (Str->str != NULL);
111 }
112
113 Str->maxlen = MAX_CHAR * sizeof (UINT16);
114 if (StringSize < Str->maxlen) {
115 StrCat (Str->str, AppendStr);
116 Str->len = StringSize - sizeof (UINT16);
117 }
118
119 gBS->FreePool (AppendStr);
120 return Str->str;
121 }
122
123
124 /**
125 Function unpacks a device path data structure so that all the nodes
126 of a device path are naturally aligned.
127
128 @param DevPath A pointer to a device path data structure
129
130 @return A ponter to new device If the memory for the device path is successfully allocated, then a
131 pointer to the new device path is returned. Otherwise, NULL is returned.
132
133 **/
134 EFI_DEVICE_PATH_PROTOCOL *
135 EFIAPI
136 BdsLibUnpackDevicePath (
137 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
138 )
139 {
140 EFI_DEVICE_PATH_PROTOCOL *Src;
141 EFI_DEVICE_PATH_PROTOCOL *Dest;
142 EFI_DEVICE_PATH_PROTOCOL *NewPath;
143 UINTN Size;
144
145 //
146 // Walk device path and round sizes to valid boundries
147 //
148 Src = DevPath;
149 Size = 0;
150 for (;;) {
151 Size += DevicePathNodeLength (Src);
152 Size += ALIGN_SIZE (Size);
153
154 if (IsDevicePathEnd (Src)) {
155 break;
156 }
157
158 Src = NextDevicePathNode (Src);
159 }
160 //
161 // Allocate space for the unpacked path
162 //
163 NewPath = AllocateZeroPool (Size);
164 if (NewPath != NULL) {
165
166 ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);
167
168 //
169 // Copy each node
170 //
171 Src = DevPath;
172 Dest = NewPath;
173 for (;;) {
174 Size = DevicePathNodeLength (Src);
175 CopyMem (Dest, Src, Size);
176 Size += ALIGN_SIZE (Size);
177 SetDevicePathNodeLength (Dest, Size);
178 Dest->Type |= EFI_DP_TYPE_UNPACKED;
179 Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);
180
181 if (IsDevicePathEnd (Src)) {
182 break;
183 }
184
185 Src = NextDevicePathNode (Src);
186 }
187 }
188
189 return NewPath;
190 }
191
192 /**
193 Convert Device Path to a Unicode string for printing.
194
195 @param Str The buffer holding the output string.
196 This buffer contains the length of the
197 string and the maixmum length reserved
198 for the string buffer.
199 @param DevPath The device path.
200
201 **/
202 VOID
203 DevPathPci (
204 IN OUT POOL_PRINT *Str,
205 IN VOID *DevPath
206 )
207 {
208 PCI_DEVICE_PATH *Pci;
209
210 Pci = DevPath;
211 CatPrint (Str, L"Pci(%x|%x)", (UINTN) Pci->Device, (UINTN) Pci->Function);
212 }
213
214 /**
215 Convert Device Path to a Unicode string for printing.
216
217 @param Str The buffer holding the output string.
218 This buffer contains the length of the
219 string and the maixmum length reserved
220 for the string buffer.
221 @param DevPath The device path.
222
223 **/
224 VOID
225 DevPathPccard (
226 IN OUT POOL_PRINT *Str,
227 IN VOID *DevPath
228 )
229 {
230 PCCARD_DEVICE_PATH *Pccard;
231
232 Pccard = DevPath;
233 CatPrint (Str, L"Pcmcia(Function%x)", (UINTN) Pccard->FunctionNumber);
234 }
235
236 /**
237 Convert Device Path to a Unicode string for printing.
238
239 @param Str The buffer holding the output string.
240 This buffer contains the length of the
241 string and the maixmum length reserved
242 for the string buffer.
243 @param DevPath The device path.
244
245 **/
246 VOID
247 DevPathMemMap (
248 IN OUT POOL_PRINT *Str,
249 IN VOID *DevPath
250 )
251 {
252 MEMMAP_DEVICE_PATH *MemMap;
253
254 MemMap = DevPath;
255 CatPrint (
256 Str,
257 L"MemMap(%d:%lx-%lx)",
258 MemMap->MemoryType,
259 MemMap->StartingAddress,
260 MemMap->EndingAddress
261 );
262 }
263
264 /**
265 Convert Device Path to a Unicode string for printing.
266
267 @param Str The buffer holding the output string.
268 This buffer contains the length of the
269 string and the maixmum length reserved
270 for the string buffer.
271 @param DevPath The device path.
272
273 **/
274 VOID
275 DevPathController (
276 IN OUT POOL_PRINT *Str,
277 IN VOID *DevPath
278 )
279 {
280 CONTROLLER_DEVICE_PATH *Controller;
281
282 Controller = DevPath;
283 CatPrint (Str, L"Ctrl(%d)", (UINTN) Controller->ControllerNumber);
284 }
285
286
287 /**
288 Convert Device Path to a Unicode string for printing.
289
290 @param Str The buffer holding the output string.
291 This buffer contains the length of the
292 string and the maixmum length reserved
293 for the string buffer.
294 @param DevPath The device path.
295
296 **/
297 VOID
298 EFIAPI
299 DevPathVendor (
300 IN OUT POOL_PRINT *Str,
301 IN VOID *DevPath
302 )
303 {
304 VENDOR_DEVICE_PATH *Vendor;
305 CHAR16 *Type;
306 UINTN DataLength;
307 UINTN Index;
308 UINT32 FlowControlMap;
309
310 UINT16 Info;
311
312 Vendor = DevPath;
313
314 switch (DevicePathType (&Vendor->Header)) {
315 case HARDWARE_DEVICE_PATH:
316 Type = L"Hw";
317 // bugbug: nt 32 specific definition
318 #if 0
319 //
320 // If the device is a winntbus device, we will give it a readable device name.
321 //
322 if (CompareGuid (&Vendor->Guid, &mEfiWinNtThunkProtocolGuid)) {
323 CatPrint (Str, L"%s", L"WinNtBus");
324 return ;
325 } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtGopGuid)) {
326 CatPrint (Str, L"%s", L"GOP");
327 return ;
328 } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtSerialPortGuid)) {
329 CatPrint (Str, L"%s", L"Serial");
330 return ;
331 }
332 #endif
333 break;
334
335 case MESSAGING_DEVICE_PATH:
336 Type = L"Msg";
337 if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
338 CatPrint (Str, L"VenPcAnsi()");
339 return ;
340 } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
341 CatPrint (Str, L"VenVt100()");
342 return ;
343 } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
344 CatPrint (Str, L"VenVt100Plus()");
345 return ;
346 } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
347 CatPrint (Str, L"VenUft8()");
348 return ;
349 } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingUartFlowControlGuid)) {
350 FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
351 switch (FlowControlMap & 0x00000003) {
352 case 0:
353 CatPrint (Str, L"UartFlowCtrl(%s)", L"None");
354 break;
355
356 case 1:
357 CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");
358 break;
359
360 case 2:
361 CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");
362 break;
363
364 default:
365 break;
366 }
367
368 return ;
369
370 } else if (CompareGuid (&Vendor->Guid, &mEfiDevicePathMessagingSASGuid)) {
371 CatPrint (
372 Str,
373 L"SAS(%lx,%lx,%x,",
374 ((SAS_DEVICE_PATH *) Vendor)->SasAddress,
375 ((SAS_DEVICE_PATH *) Vendor)->Lun,
376 ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort
377 );
378 Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
379 if ((Info & 0x0f) == 0) {
380 CatPrint (Str, L"NoTopology,0,0,0,");
381 } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {
382 CatPrint (
383 Str,
384 L"%s,%s,%s,",
385 ((Info & (0x1 << 4)) != 0) ? L"SATA" : L"SAS",
386 ((Info & (0x1 << 5)) != 0) ? L"External" : L"Internal",
387 ((Info & (0x1 << 6)) != 0) ? L"Expanded" : L"Direct"
388 );
389 if ((Info & 0x0f) == 1) {
390 CatPrint (Str, L"0,");
391 } else {
392 CatPrint (Str, L"%x,", (UINTN) ((Info >> 8) & 0xff));
393 }
394 } else {
395 CatPrint (Str, L"0,0,0,0,");
396 }
397
398 CatPrint (Str, L"%x)", (UINTN) ((SAS_DEVICE_PATH *) Vendor)->Reserved);
399 return ;
400
401 } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
402 CatPrint (Str, L"DebugPort()");
403 return ;
404 }
405 break;
406
407 case MEDIA_DEVICE_PATH:
408 Type = L"Media";
409 break;
410
411 default:
412 Type = L"?";
413 break;
414 }
415
416 CatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);
417 DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
418 if (DataLength > 0) {
419 CatPrint (Str, L",");
420 for (Index = 0; Index < DataLength; Index++) {
421 CatPrint (Str, L"%02x", (UINTN) ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
422 }
423 }
424 CatPrint (Str, L")");
425 }
426
427
428 /**
429 Convert Device Path to a Unicode string for printing.
430
431 @param Str The buffer holding the output string.
432 This buffer contains the length of the
433 string and the maixmum length reserved
434 for the string buffer.
435 @param DevPath The device path.
436
437 **/
438 VOID
439 DevPathAcpi (
440 IN OUT POOL_PRINT *Str,
441 IN VOID *DevPath
442 )
443 {
444 ACPI_HID_DEVICE_PATH *Acpi;
445
446 Acpi = DevPath;
447 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
448 CatPrint (Str, L"Acpi(PNP%04x,%x)", (UINTN) EISA_ID_TO_NUM (Acpi->HID), (UINTN) Acpi->UID);
449 } else {
450 CatPrint (Str, L"Acpi(%08x,%x)", (UINTN) Acpi->HID, (UINTN) Acpi->UID);
451 }
452 }
453
454 /**
455 Convert Device Path to a Unicode string for printing.
456
457 @param Str The buffer holding the output string.
458 This buffer contains the length of the
459 string and the maixmum length reserved
460 for the string buffer.
461 @param DevPath The device path.
462
463 **/
464 VOID
465 DevPathExtendedAcpi (
466 IN OUT POOL_PRINT *Str,
467 IN VOID *DevPath
468 )
469 {
470 ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;
471 //
472 // Index for HID, UID and CID strings, 0 for non-exist
473 //
474 UINT16 HIDSTRIdx;
475 UINT16 UIDSTRIdx;
476 UINT16 CIDSTRIdx;
477 UINT16 Index;
478 UINT16 Length;
479 UINT16 Anchor;
480 CHAR8 *AsChar8Array;
481
482 ASSERT (Str != NULL);
483 ASSERT (DevPath != NULL);
484
485 HIDSTRIdx = 0;
486 UIDSTRIdx = 0;
487 CIDSTRIdx = 0;
488 ExtendedAcpi = DevPath;
489 Length = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) ExtendedAcpi);
490
491 ASSERT (Length >= 19);
492 AsChar8Array = (CHAR8 *) ExtendedAcpi;
493
494 //
495 // find HIDSTR
496 //
497 Anchor = 16;
498 for (Index = Anchor; Index < Length && AsChar8Array[Index] != '\0'; Index++) {
499 ;
500 }
501 if (Index > Anchor) {
502 HIDSTRIdx = Anchor;
503 }
504 //
505 // find UIDSTR
506 //
507 Anchor = (UINT16) (Index + 1);
508 for (Index = Anchor; Index < Length && AsChar8Array[Index] != '\0'; Index++) {
509 ;
510 }
511 if (Index > Anchor) {
512 UIDSTRIdx = Anchor;
513 }
514 //
515 // find CIDSTR
516 //
517 Anchor = (UINT16) (Index + 1);
518 for (Index = Anchor; Index < Length && AsChar8Array[Index] != '\0'; Index++) {
519 ;
520 }
521 if (Index > Anchor) {
522 CIDSTRIdx = Anchor;
523 }
524
525 if (HIDSTRIdx == 0 && CIDSTRIdx == 0 && ExtendedAcpi->UID == 0) {
526 CatPrint (Str, L"AcpiExp(");
527 if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
528 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->HID));
529 } else {
530 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->HID);
531 }
532 if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
533 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->CID));
534 } else {
535 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->CID);
536 }
537 if (UIDSTRIdx != 0) {
538 CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);
539 } else {
540 CatPrint (Str, L"\"\")");
541 }
542 } else {
543 CatPrint (Str, L"AcpiEx(");
544 if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
545 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->HID));
546 } else {
547 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->HID);
548 }
549 if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
550 CatPrint (Str, L"PNP%04x,", (UINTN) EISA_ID_TO_NUM (ExtendedAcpi->CID));
551 } else {
552 CatPrint (Str, L"%08x,", (UINTN) ExtendedAcpi->CID);
553 }
554 CatPrint (Str, L"%x,", (UINTN) ExtendedAcpi->UID);
555
556 if (HIDSTRIdx != 0) {
557 CatPrint (Str, L"%a,", AsChar8Array + HIDSTRIdx);
558 } else {
559 CatPrint (Str, L"\"\",");
560 }
561 if (CIDSTRIdx != 0) {
562 CatPrint (Str, L"%a,", AsChar8Array + CIDSTRIdx);
563 } else {
564 CatPrint (Str, L"\"\",");
565 }
566 if (UIDSTRIdx != 0) {
567 CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);
568 } else {
569 CatPrint (Str, L"\"\")");
570 }
571 }
572
573 }
574
575 /**
576 Convert Device Path to a Unicode string for printing.
577
578 @param Str The buffer holding the output string.
579 This buffer contains the length of the
580 string and the maixmum length reserved
581 for the string buffer.
582 @param DevPath The device path.
583
584 **/
585 VOID
586 DevPathAdrAcpi (
587 IN OUT POOL_PRINT *Str,
588 IN VOID *DevPath
589 )
590 {
591 ACPI_ADR_DEVICE_PATH *AcpiAdr;
592 UINT16 Index;
593 UINT16 Length;
594 UINT16 AdditionalAdrCount;
595
596 AcpiAdr = DevPath;
597 Length = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
598 AdditionalAdrCount = (UINT16) ((Length - 8) / 4);
599
600 CatPrint (Str, L"AcpiAdr(%x", (UINTN) AcpiAdr->ADR);
601 for (Index = 0; Index < AdditionalAdrCount; Index++) {
602 CatPrint (Str, L",%x", (UINTN) *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));
603 }
604 CatPrint (Str, L")");
605 }
606
607 /**
608 Convert Device Path to a Unicode string for printing.
609
610 @param Str The buffer holding the output string.
611 This buffer contains the length of the
612 string and the maixmum length reserved
613 for the string buffer.
614 @param DevPath The device path.
615
616 **/
617 VOID
618 DevPathAtapi (
619 IN OUT POOL_PRINT *Str,
620 IN VOID *DevPath
621 )
622 {
623 ATAPI_DEVICE_PATH *Atapi;
624
625 Atapi = DevPath;
626 CatPrint (
627 Str,
628 L"Ata(%s,%s)",
629 Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
630 Atapi->SlaveMaster ? L"Slave" : L"Master"
631 );
632 }
633
634 /**
635 Convert Device Path to a Unicode string for printing.
636
637 @param Str The buffer holding the output string.
638 This buffer contains the length of the
639 string and the maixmum length reserved
640 for the string buffer.
641 @param DevPath The device path.
642
643 **/
644 VOID
645 DevPathScsi (
646 IN OUT POOL_PRINT *Str,
647 IN VOID *DevPath
648 )
649 {
650 SCSI_DEVICE_PATH *Scsi;
651
652 Scsi = DevPath;
653 CatPrint (Str, L"Scsi(Pun%x,Lun%x)", (UINTN) Scsi->Pun, (UINTN) Scsi->Lun);
654 }
655
656 /**
657 Convert Device Path to a Unicode string for printing.
658
659 @param Str The buffer holding the output string.
660 This buffer contains the length of the
661 string and the maixmum length reserved
662 for the string buffer.
663 @param DevPath The device path.
664
665 **/
666 VOID
667 DevPathFibre (
668 IN OUT POOL_PRINT *Str,
669 IN VOID *DevPath
670 )
671 {
672 FIBRECHANNEL_DEVICE_PATH *Fibre;
673
674 Fibre = DevPath;
675 CatPrint (Str, L"Fibre(Wwn%lx,Lun%x)", Fibre->WWN, Fibre->Lun);
676 }
677
678 /**
679 Convert Device Path to a Unicode string for printing.
680
681 @param Str The buffer holding the output string.
682 This buffer contains the length of the
683 string and the maixmum length reserved
684 for the string buffer.
685 @param DevPath The device path.
686
687 **/
688 VOID
689 DevPath1394 (
690 IN OUT POOL_PRINT *Str,
691 IN VOID *DevPath
692 )
693 {
694 F1394_DEVICE_PATH *F1394Path;
695
696 F1394Path = DevPath;
697 CatPrint (Str, L"1394(%g)", &F1394Path->Guid);
698 }
699
700 /**
701 Convert Device Path to a Unicode string for printing.
702
703 @param Str The buffer holding the output string.
704 This buffer contains the length of the
705 string and the maixmum length reserved
706 for the string buffer.
707 @param DevPath The device path.
708
709 **/
710 VOID
711 DevPathUsb (
712 IN OUT POOL_PRINT *Str,
713 IN VOID *DevPath
714 )
715 {
716 USB_DEVICE_PATH *Usb;
717
718 Usb = DevPath;
719 CatPrint (Str, L"Usb(%x,%x)", (UINTN) Usb->ParentPortNumber, (UINTN) Usb->InterfaceNumber);
720 }
721
722 /**
723 Convert Device Path to a Unicode string for printing.
724
725 @param Str The buffer holding the output string.
726 This buffer contains the length of the
727 string and the maixmum length reserved
728 for the string buffer.
729 @param DevPath The device path.
730
731 **/
732 VOID
733 DevPathUsbWWID (
734 IN OUT POOL_PRINT *Str,
735 IN VOID *DevPath
736 )
737 {
738 USB_WWID_DEVICE_PATH *UsbWWId;
739
740 UsbWWId = DevPath;
741 CatPrint (
742 Str,
743 L"UsbWwid(%x,%x,%x,\"WWID\")",
744 (UINTN) UsbWWId->VendorId,
745 (UINTN) UsbWWId->ProductId,
746 (UINTN) UsbWWId->InterfaceNumber
747 );
748 }
749
750 /**
751 Convert Device Path to a Unicode string for printing.
752
753 @param Str The buffer holding the output string.
754 This buffer contains the length of the
755 string and the maixmum length reserved
756 for the string buffer.
757 @param DevPath The device path.
758
759 **/
760 VOID
761 DevPathLogicalUnit (
762 IN OUT POOL_PRINT *Str,
763 IN VOID *DevPath
764 )
765 {
766 DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
767
768 LogicalUnit = DevPath;
769 CatPrint (Str, L"Unit(%x)", (UINTN) LogicalUnit->Lun);
770 }
771
772 /**
773 Convert Device Path to a Unicode string for printing.
774
775 @param Str The buffer holding the output string.
776 This buffer contains the length of the
777 string and the maixmum length reserved
778 for the string buffer.
779 @param DevPath The device path.
780
781 **/
782 VOID
783 DevPathUsbClass (
784 IN OUT POOL_PRINT *Str,
785 IN VOID *DevPath
786 )
787 {
788 USB_CLASS_DEVICE_PATH *UsbClass;
789
790 UsbClass = DevPath;
791 CatPrint (
792 Str,
793 L"Usb Class(%x,%x,%x,%x,%x)",
794 (UINTN) UsbClass->VendorId,
795 (UINTN) UsbClass->ProductId,
796 (UINTN) UsbClass->DeviceClass,
797 (UINTN) UsbClass->DeviceSubClass,
798 (UINTN) UsbClass->DeviceProtocol
799 );
800 }
801
802 /**
803 Convert Device Path to a Unicode string for printing.
804
805 @param Str The buffer holding the output string.
806 This buffer contains the length of the
807 string and the maixmum length reserved
808 for the string buffer.
809 @param DevPath The device path.
810
811 **/
812 VOID
813 DevPathSata (
814 IN OUT POOL_PRINT *Str,
815 IN VOID *DevPath
816 )
817 {
818 SATA_DEVICE_PATH *Sata;
819
820 Sata = DevPath;
821 CatPrint (
822 Str,
823 L"Sata(%x,%x,%x)",
824 (UINTN) Sata->HBAPortNumber,
825 (UINTN) Sata->PortMultiplierPortNumber,
826 (UINTN) Sata->Lun
827 );
828 }
829
830 /**
831 Convert Device Path to a Unicode string for printing.
832
833 @param Str The buffer holding the output string.
834 This buffer contains the length of the
835 string and the maixmum length reserved
836 for the string buffer.
837 @param DevPath The device path.
838
839 **/
840 VOID
841 DevPathI2O (
842 IN OUT POOL_PRINT *Str,
843 IN VOID *DevPath
844 )
845 {
846 I2O_DEVICE_PATH *I2OPath;
847
848 I2OPath = DevPath;
849 CatPrint (Str, L"I2O(%x)", (UINTN) I2OPath->Tid);
850 }
851
852 /**
853 Convert Device Path to a Unicode string for printing.
854
855 @param Str The buffer holding the output string.
856 This buffer contains the length of the
857 string and the maixmum length reserved
858 for the string buffer.
859 @param DevPath The device path.
860
861 **/
862 VOID
863 DevPathMacAddr (
864 IN OUT POOL_PRINT *Str,
865 IN VOID *DevPath
866 )
867 {
868 MAC_ADDR_DEVICE_PATH *MACDevPath;
869 UINTN HwAddressSize;
870 UINTN Index;
871
872 MACDevPath = DevPath;
873
874 HwAddressSize = sizeof (EFI_MAC_ADDRESS);
875 if (MACDevPath->IfType == 0x01 || MACDevPath->IfType == 0x00) {
876 HwAddressSize = 6;
877 }
878
879 CatPrint (Str, L"Mac(");
880
881 for (Index = 0; Index < HwAddressSize; Index++) {
882 CatPrint (Str, L"%02x", (UINTN) MACDevPath->MacAddress.Addr[Index]);
883 }
884
885 CatPrint (Str, L")");
886 }
887
888 /**
889 Convert Device Path to a Unicode string for printing.
890
891 @param Str The buffer holding the output string.
892 This buffer contains the length of the
893 string and the maixmum length reserved
894 for the string buffer.
895 @param DevPath The device path.
896
897 **/
898 VOID
899 DevPathIPv4 (
900 IN OUT POOL_PRINT *Str,
901 IN VOID *DevPath
902 )
903 {
904 IPv4_DEVICE_PATH *IPDevPath;
905
906 IPDevPath = DevPath;
907 CatPrint (
908 Str,
909 L"IPv4(%d.%d.%d.%d:%d)",
910 (UINTN) IPDevPath->RemoteIpAddress.Addr[0],
911 (UINTN) IPDevPath->RemoteIpAddress.Addr[1],
912 (UINTN) IPDevPath->RemoteIpAddress.Addr[2],
913 (UINTN) IPDevPath->RemoteIpAddress.Addr[3],
914 (UINTN) IPDevPath->RemotePort
915 );
916 }
917
918 /**
919 Convert Device Path to a Unicode string for printing.
920
921 @param Str The buffer holding the output string.
922 This buffer contains the length of the
923 string and the maixmum length reserved
924 for the string buffer.
925 @param DevPath The device path.
926
927 **/
928 VOID
929 DevPathIPv6 (
930 IN OUT POOL_PRINT *Str,
931 IN VOID *DevPath
932 )
933 {
934 IPv6_DEVICE_PATH *IPv6DevPath;
935
936 IPv6DevPath = DevPath;
937 CatPrint (
938 Str,
939 L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
940 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[0],
941 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[1],
942 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[2],
943 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[3],
944 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[4],
945 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[5],
946 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[6],
947 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[7],
948 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[8],
949 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[9],
950 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[10],
951 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[11],
952 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[12],
953 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[13],
954 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[14],
955 (UINTN) IPv6DevPath->RemoteIpAddress.Addr[15]
956 );
957 }
958
959 /**
960 Convert Device Path to a Unicode string for printing.
961
962 @param Str The buffer holding the output string.
963 This buffer contains the length of the
964 string and the maixmum length reserved
965 for the string buffer.
966 @param DevPath The device path.
967
968 **/
969 VOID
970 DevPathInfiniBand (
971 IN OUT POOL_PRINT *Str,
972 IN VOID *DevPath
973 )
974 {
975 INFINIBAND_DEVICE_PATH *InfiniBand;
976
977 InfiniBand = DevPath;
978 CatPrint (
979 Str,
980 L"Infiniband(%x,%g,%lx,%lx,%lx)",
981 (UINTN) InfiniBand->ResourceFlags,
982 InfiniBand->PortGid,
983 InfiniBand->ServiceId,
984 InfiniBand->TargetPortId,
985 InfiniBand->DeviceId
986 );
987 }
988
989 /**
990 Convert Device Path to a Unicode string for printing.
991
992 @param Str The buffer holding the output string.
993 This buffer contains the length of the
994 string and the maixmum length reserved
995 for the string buffer.
996 @param DevPath The device path.
997
998 **/
999 VOID
1000 DevPathUart (
1001 IN OUT POOL_PRINT *Str,
1002 IN VOID *DevPath
1003 )
1004 {
1005 UART_DEVICE_PATH *Uart;
1006 CHAR8 Parity;
1007
1008 Uart = DevPath;
1009 switch (Uart->Parity) {
1010 case 0:
1011 Parity = 'D';
1012 break;
1013
1014 case 1:
1015 Parity = 'N';
1016 break;
1017
1018 case 2:
1019 Parity = 'E';
1020 break;
1021
1022 case 3:
1023 Parity = 'O';
1024 break;
1025
1026 case 4:
1027 Parity = 'M';
1028 break;
1029
1030 case 5:
1031 Parity = 'S';
1032 break;
1033
1034 default:
1035 Parity = 'x';
1036 break;
1037 }
1038
1039 if (Uart->BaudRate == 0) {
1040 CatPrint (Str, L"Uart(DEFAULT,%c,", Parity);
1041 } else {
1042 CatPrint (Str, L"Uart(%d,%c,", Uart->BaudRate, Parity);
1043 }
1044
1045 if (Uart->DataBits == 0) {
1046 CatPrint (Str, L"D,");
1047 } else {
1048 CatPrint (Str, L"%d,", (UINTN) Uart->DataBits);
1049 }
1050
1051 switch (Uart->StopBits) {
1052 case 0:
1053 CatPrint (Str, L"D)");
1054 break;
1055
1056 case 1:
1057 CatPrint (Str, L"1)");
1058 break;
1059
1060 case 2:
1061 CatPrint (Str, L"1.5)");
1062 break;
1063
1064 case 3:
1065 CatPrint (Str, L"2)");
1066 break;
1067
1068 default:
1069 CatPrint (Str, L"x)");
1070 break;
1071 }
1072 }
1073
1074 /**
1075 Convert Device Path to a Unicode string for printing.
1076
1077 @param Str The buffer holding the output string.
1078 This buffer contains the length of the
1079 string and the maixmum length reserved
1080 for the string buffer.
1081 @param DevPath The device path.
1082
1083 **/
1084 VOID
1085 DevPathiSCSI (
1086 IN OUT POOL_PRINT *Str,
1087 IN VOID *DevPath
1088 )
1089 {
1090 ISCSI_DEVICE_PATH_WITH_NAME *IScsi;
1091 UINT16 Options;
1092
1093 ASSERT (Str != NULL);
1094 ASSERT (DevPath != NULL);
1095
1096 IScsi = DevPath;
1097 CatPrint (
1098 Str,
1099 L"iSCSI(%s,%x,%lx,",
1100 IScsi->iSCSITargetName,
1101 IScsi->TargetPortalGroupTag,
1102 IScsi->Lun
1103 );
1104
1105 Options = IScsi->LoginOption;
1106 CatPrint (Str, L"%s,", (((Options >> 1) & 0x0001) != 0) ? L"CRC32C" : L"None");
1107 CatPrint (Str, L"%s,", (((Options >> 3) & 0x0001) != 0) ? L"CRC32C" : L"None");
1108 if (((Options >> 11) & 0x0001) != 0) {
1109 CatPrint (Str, L"%s,", L"None");
1110 } else if (((Options >> 12) & 0x0001) != 0) {
1111 CatPrint (Str, L"%s,", L"CHAP_UNI");
1112 } else {
1113 CatPrint (Str, L"%s,", L"CHAP_BI");
1114
1115 }
1116
1117 CatPrint (Str, L"%s)", (IScsi->NetworkProtocol == 0) ? L"TCP" : L"reserved");
1118 }
1119
1120 /**
1121 Convert Device Path to a Unicode string for printing.
1122
1123 @param Str The buffer holding the output string.
1124 This buffer contains the length of the
1125 string and the maixmum length reserved
1126 for the string buffer.
1127 @param DevPath The device path.
1128
1129 **/
1130 VOID
1131 DevPathHardDrive (
1132 IN OUT POOL_PRINT *Str,
1133 IN VOID *DevPath
1134 )
1135 {
1136 HARDDRIVE_DEVICE_PATH *Hd;
1137
1138 Hd = DevPath;
1139 switch (Hd->SignatureType) {
1140 case SIGNATURE_TYPE_MBR:
1141 CatPrint (
1142 Str,
1143 L"HD(Part%d,Sig%08x)",
1144 (UINTN) Hd->PartitionNumber,
1145 (UINTN) *((UINT32 *) (&(Hd->Signature[0])))
1146 );
1147 break;
1148
1149 case SIGNATURE_TYPE_GUID:
1150 CatPrint (
1151 Str,
1152 L"HD(Part%d,Sig%g)",
1153 (UINTN) Hd->PartitionNumber,
1154 (EFI_GUID *) &(Hd->Signature[0])
1155 );
1156 break;
1157
1158 default:
1159 CatPrint (
1160 Str,
1161 L"HD(Part%d,MBRType=%02x,SigType=%02x)",
1162 (UINTN) Hd->PartitionNumber,
1163 (UINTN) Hd->MBRType,
1164 (UINTN) Hd->SignatureType
1165 );
1166 break;
1167 }
1168 }
1169
1170 /**
1171 Convert Device Path to a Unicode string for printing.
1172
1173 @param Str The buffer holding the output string.
1174 This buffer contains the length of the
1175 string and the maixmum length reserved
1176 for the string buffer.
1177 @param DevPath The device path.
1178
1179 **/
1180 VOID
1181 DevPathCDROM (
1182 IN OUT POOL_PRINT *Str,
1183 IN VOID *DevPath
1184 )
1185 {
1186 CDROM_DEVICE_PATH *Cd;
1187
1188 Cd = DevPath;
1189 CatPrint (Str, L"CDROM(Entry%x)", (UINTN) Cd->BootEntry);
1190 }
1191
1192 /**
1193 Convert Device Path to a Unicode string for printing.
1194
1195 @param Str The buffer holding the output string.
1196 This buffer contains the length of the
1197 string and the maixmum length reserved
1198 for the string buffer.
1199 @param DevPath The device path.
1200
1201 **/
1202 VOID
1203 DevPathFilePath (
1204 IN OUT POOL_PRINT *Str,
1205 IN VOID *DevPath
1206 )
1207 {
1208 FILEPATH_DEVICE_PATH *Fp;
1209
1210 Fp = DevPath;
1211 CatPrint (Str, L"%s", Fp->PathName);
1212 }
1213
1214 /**
1215 Convert Device Path to a Unicode string for printing.
1216
1217 @param Str The buffer holding the output string.
1218 This buffer contains the length of the
1219 string and the maixmum length reserved
1220 for the string buffer.
1221 @param DevPath The device path.
1222
1223 **/
1224 VOID
1225 DevPathMediaProtocol (
1226 IN OUT POOL_PRINT *Str,
1227 IN VOID *DevPath
1228 )
1229 {
1230 MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
1231
1232 MediaProt = DevPath;
1233 CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);
1234 }
1235
1236 /**
1237 Convert Device Path to a Unicode string for printing.
1238
1239 @param Str The buffer holding the output string.
1240 This buffer contains the length of the
1241 string and the maixmum length reserved
1242 for the string buffer.
1243 @param DevPath The device path.
1244
1245 **/
1246 VOID
1247 DevPathFvFilePath (
1248 IN OUT POOL_PRINT *Str,
1249 IN VOID *DevPath
1250 )
1251 {
1252 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
1253
1254 FvFilePath = DevPath;
1255 CatPrint (Str, L"%g", &FvFilePath->FvFileName);
1256 }
1257
1258 /**
1259 Convert Device Path to a Unicode string for printing.
1260
1261 @param Str The buffer holding the output string.
1262 This buffer contains the length of the
1263 string and the maixmum length reserved
1264 for the string buffer.
1265 @param DevPath The device path.
1266
1267 **/
1268 VOID
1269 DevPathBssBss (
1270 IN OUT POOL_PRINT *Str,
1271 IN VOID *DevPath
1272 )
1273 {
1274 BBS_BBS_DEVICE_PATH *Bbs;
1275 CHAR16 *Type;
1276
1277 Bbs = DevPath;
1278 switch (Bbs->DeviceType) {
1279 case BBS_TYPE_FLOPPY:
1280 Type = L"Floppy";
1281 break;
1282
1283 case BBS_TYPE_HARDDRIVE:
1284 Type = L"Harddrive";
1285 break;
1286
1287 case BBS_TYPE_CDROM:
1288 Type = L"CDROM";
1289 break;
1290
1291 case BBS_TYPE_PCMCIA:
1292 Type = L"PCMCIA";
1293 break;
1294
1295 case BBS_TYPE_USB:
1296 Type = L"Usb";
1297 break;
1298
1299 case BBS_TYPE_EMBEDDED_NETWORK:
1300 Type = L"Net";
1301 break;
1302
1303 case BBS_TYPE_BEV:
1304 Type = L"BEV";
1305 break;
1306
1307 default:
1308 Type = L"?";
1309 break;
1310 }
1311 CatPrint (Str, L"Legacy-%s", Type);
1312 }
1313
1314 /**
1315 Convert Device Path to a Unicode string for printing.
1316
1317 @param Str The buffer holding the output string.
1318 This buffer contains the length of the
1319 string and the maixmum length reserved
1320 for the string buffer.
1321 @param DevPath The device path.
1322
1323 **/
1324 VOID
1325 DevPathEndInstance (
1326 IN OUT POOL_PRINT *Str,
1327 IN VOID *DevPath
1328 )
1329 {
1330 CatPrint (Str, L",");
1331 }
1332
1333 /**
1334 Convert Device Path to a Unicode string for printing.
1335
1336 @param Str The buffer holding the output string.
1337 This buffer contains the length of the
1338 string and the maixmum length reserved
1339 for the string buffer.
1340 @param DevPath The device path.
1341
1342 **/
1343 VOID
1344 DevPathNodeUnknown (
1345 IN OUT POOL_PRINT *Str,
1346 IN VOID *DevPath
1347 )
1348 {
1349 CatPrint (Str, L"?");
1350 }
1351
1352 DEVICE_PATH_STRING_TABLE DevPathTable[] = {
1353 HARDWARE_DEVICE_PATH,
1354 HW_PCI_DP,
1355 DevPathPci,
1356 HARDWARE_DEVICE_PATH,
1357 HW_PCCARD_DP,
1358 DevPathPccard,
1359 HARDWARE_DEVICE_PATH,
1360 HW_MEMMAP_DP,
1361 DevPathMemMap,
1362 HARDWARE_DEVICE_PATH,
1363 HW_VENDOR_DP,
1364 DevPathVendor,
1365 HARDWARE_DEVICE_PATH,
1366 HW_CONTROLLER_DP,
1367 DevPathController,
1368 ACPI_DEVICE_PATH,
1369 ACPI_DP,
1370 DevPathAcpi,
1371 ACPI_DEVICE_PATH,
1372 ACPI_EXTENDED_DP,
1373 DevPathExtendedAcpi,
1374 ACPI_DEVICE_PATH,
1375 ACPI_ADR_DP,
1376 DevPathAdrAcpi,
1377 MESSAGING_DEVICE_PATH,
1378 MSG_ATAPI_DP,
1379 DevPathAtapi,
1380 MESSAGING_DEVICE_PATH,
1381 MSG_SCSI_DP,
1382 DevPathScsi,
1383 MESSAGING_DEVICE_PATH,
1384 MSG_FIBRECHANNEL_DP,
1385 DevPathFibre,
1386 MESSAGING_DEVICE_PATH,
1387 MSG_1394_DP,
1388 DevPath1394,
1389 MESSAGING_DEVICE_PATH,
1390 MSG_USB_DP,
1391 DevPathUsb,
1392 MESSAGING_DEVICE_PATH,
1393 MSG_USB_WWID_DP,
1394 DevPathUsbWWID,
1395 MESSAGING_DEVICE_PATH,
1396 MSG_DEVICE_LOGICAL_UNIT_DP,
1397 DevPathLogicalUnit,
1398 MESSAGING_DEVICE_PATH,
1399 MSG_USB_CLASS_DP,
1400 DevPathUsbClass,
1401 MESSAGING_DEVICE_PATH,
1402 MSG_SATA_DP,
1403 DevPathSata,
1404 MESSAGING_DEVICE_PATH,
1405 MSG_I2O_DP,
1406 DevPathI2O,
1407 MESSAGING_DEVICE_PATH,
1408 MSG_MAC_ADDR_DP,
1409 DevPathMacAddr,
1410 MESSAGING_DEVICE_PATH,
1411 MSG_IPv4_DP,
1412 DevPathIPv4,
1413 MESSAGING_DEVICE_PATH,
1414 MSG_IPv6_DP,
1415 DevPathIPv6,
1416 MESSAGING_DEVICE_PATH,
1417 MSG_INFINIBAND_DP,
1418 DevPathInfiniBand,
1419 MESSAGING_DEVICE_PATH,
1420 MSG_UART_DP,
1421 DevPathUart,
1422 MESSAGING_DEVICE_PATH,
1423 MSG_VENDOR_DP,
1424 DevPathVendor,
1425 MESSAGING_DEVICE_PATH,
1426 MSG_ISCSI_DP,
1427 DevPathiSCSI,
1428 MEDIA_DEVICE_PATH,
1429 MEDIA_HARDDRIVE_DP,
1430 DevPathHardDrive,
1431 MEDIA_DEVICE_PATH,
1432 MEDIA_CDROM_DP,
1433 DevPathCDROM,
1434 MEDIA_DEVICE_PATH,
1435 MEDIA_VENDOR_DP,
1436 DevPathVendor,
1437 MEDIA_DEVICE_PATH,
1438 MEDIA_FILEPATH_DP,
1439 DevPathFilePath,
1440 MEDIA_DEVICE_PATH,
1441 MEDIA_PROTOCOL_DP,
1442 DevPathMediaProtocol,
1443 MEDIA_DEVICE_PATH,
1444 MEDIA_PIWG_FW_FILE_DP,
1445 DevPathFvFilePath,
1446 BBS_DEVICE_PATH,
1447 BBS_BBS_DP,
1448 DevPathBssBss,
1449 END_DEVICE_PATH_TYPE,
1450 END_INSTANCE_DEVICE_PATH_SUBTYPE,
1451 DevPathEndInstance,
1452 0,
1453 0,
1454 NULL
1455 };
1456
1457
1458 /**
1459 This function converts an input device structure to a Unicode string.
1460
1461 @param DevPath A pointer to the device path structure.
1462
1463 @return A new allocated Unicode string that represents the device path.
1464
1465 **/
1466 CHAR16 *
1467 EFIAPI
1468 DevicePathToStr (
1469 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
1470 )
1471 {
1472 POOL_PRINT Str;
1473 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
1474 VOID (*DumpNode) (POOL_PRINT *, VOID *);
1475
1476 UINTN Index;
1477 UINTN NewSize;
1478
1479 EFI_STATUS Status;
1480 CHAR16 *ToText;
1481 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
1482
1483 ZeroMem (&Str, sizeof (Str));
1484
1485 if (DevPath == NULL) {
1486 goto Done;
1487 }
1488
1489 Status = gBS->LocateProtocol (
1490 &gEfiDevicePathToTextProtocolGuid,
1491 NULL,
1492 (VOID **) &DevPathToText
1493 );
1494 if (!EFI_ERROR (Status)) {
1495 ToText = DevPathToText->ConvertDevicePathToText (
1496 DevPath,
1497 FALSE,
1498 TRUE
1499 );
1500 ASSERT (ToText != NULL);
1501 return ToText;
1502 }
1503
1504 //
1505 // Unpacked the device path
1506 //
1507 DevPath = BdsLibUnpackDevicePath (DevPath);
1508 ASSERT (DevPath);
1509
1510 //
1511 // Process each device path node
1512 //
1513 DevPathNode = DevPath;
1514 while (!IsDevicePathEnd (DevPathNode)) {
1515 //
1516 // Find the handler to dump this device path node
1517 //
1518 DumpNode = NULL;
1519 for (Index = 0; DevPathTable[Index].Function; Index += 1) {
1520
1521 if (DevicePathType (DevPathNode) == DevPathTable[Index].Type &&
1522 DevicePathSubType (DevPathNode) == DevPathTable[Index].SubType
1523 ) {
1524 DumpNode = DevPathTable[Index].Function;
1525 break;
1526 }
1527 }
1528 //
1529 // If not found, use a generic function
1530 //
1531 if (!DumpNode) {
1532 DumpNode = DevPathNodeUnknown;
1533 }
1534 //
1535 // Put a path seperator in if needed
1536 //
1537 if (Str.len && DumpNode != DevPathEndInstance) {
1538 CatPrint (&Str, L"/");
1539 }
1540 //
1541 // Print this node of the device path
1542 //
1543 DumpNode (&Str, DevPathNode);
1544
1545 //
1546 // Next device path node
1547 //
1548 DevPathNode = NextDevicePathNode (DevPathNode);
1549 }
1550 //
1551 // Shrink pool used for string allocation
1552 //
1553 gBS->FreePool (DevPath);
1554
1555 Done:
1556 NewSize = (Str.len + 1) * sizeof (CHAR16);
1557 Str.str = ReallocatePool (Str.str, NewSize, NewSize);
1558 ASSERT (Str.str != NULL);
1559 Str.str[Str.len] = 0;
1560 return Str.str;
1561 }
1562
1563
1564 /**
1565 Function creates a device path data structure that identically matches the
1566 device path passed in.
1567
1568 @param DevPath A pointer to a device path data structure.
1569
1570 @return The new copy of DevPath is created to identically match the input.
1571 @return Otherwise, NULL is returned.
1572
1573 **/
1574 EFI_DEVICE_PATH_PROTOCOL *
1575 LibDuplicateDevicePathInstance (
1576 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
1577 )
1578 {
1579 EFI_DEVICE_PATH_PROTOCOL *NewDevPath;
1580 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
1581 EFI_DEVICE_PATH_PROTOCOL *Temp;
1582 UINTN Size;
1583
1584 //
1585 // get the size of an instance from the input
1586 //
1587 Temp = DevPath;
1588 DevicePathInst = GetNextDevicePathInstance (&Temp, &Size);
1589
1590 //
1591 // Make a copy
1592 //
1593 NewDevPath = NULL;
1594 if (Size != 0) {
1595 NewDevPath = AllocateZeroPool (Size);
1596 ASSERT (NewDevPath != NULL);
1597 }
1598
1599 if (NewDevPath != NULL) {
1600 CopyMem (NewDevPath, DevicePathInst, Size);
1601 }
1602
1603 return NewDevPath;
1604 }