Import Usb/UsbBusDxe and Usb/UsbMassStorageDxe into MdeModulePkg.
[mirror_edk2.git] / EdkNt32Pkg / Library / EdkGenericBdsLib / DevicePath.c
1 /*++
2
3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 DevicePath.c
15
16 Abstract:
17
18 BDS internal function define the default device path string, it can be
19 replaced by platform device path.
20
21 --*/
22
23 EFI_GUID mEfiWinNtThunkProtocolGuid = EFI_WIN_NT_THUNK_PROTOCOL_GUID;
24 EFI_GUID mEfiWinNtUgaGuid = EFI_WIN_NT_UGA_GUID;
25 EFI_GUID mEfiWinNtGopGuid = EFI_WIN_NT_GOP_GUID;
26 EFI_GUID mEfiWinNtSerialPortGuid = EFI_WIN_NT_SERIAL_PORT_GUID;
27 EFI_GUID mEfiMsgPcAnsiGuid = DEVICE_PATH_MESSAGING_PC_ANSI;
28 EFI_GUID mEfiMsgVt100Guid = DEVICE_PATH_MESSAGING_VT_100;
29 EFI_GUID mEfiMsgVt100PlusGuid = DEVICE_PATH_MESSAGING_VT_100_PLUS;
30 EFI_GUID mEfiMsgVt100Utf8Guid = DEVICE_PATH_MESSAGING_VT_UTF8;
31
32 VOID *
33 ReallocatePool (
34 IN VOID *OldPool,
35 IN UINTN OldSize,
36 IN UINTN NewSize
37 )
38 /*++
39
40 Routine Description:
41
42 Adjusts the size of a previously allocated buffer.
43
44 Arguments:
45
46 OldPool - A pointer to the buffer whose size is being adjusted.
47
48 OldSize - The size of the current buffer.
49
50 NewSize - The size of the new buffer.
51
52 Returns:
53
54 EFI_SUCEESS - The requested number of bytes were allocated.
55
56 EFI_OUT_OF_RESOURCES - The pool requested could not be allocated.
57
58 EFI_INVALID_PARAMETER - The buffer was invalid.
59
60 --*/
61 {
62 VOID *NewPool;
63
64 NewPool = NULL;
65 if (NewSize) {
66 NewPool = AllocateZeroPool (NewSize);
67 }
68
69 if (OldPool) {
70 if (NewPool) {
71 CopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
72 }
73
74 FreePool (OldPool);
75 }
76
77 return NewPool;
78 }
79
80 CHAR16 *
81 CatPrint (
82 IN OUT POOL_PRINT *Str,
83 IN CHAR16 *fmt,
84 ...
85 )
86 /*++
87
88 Routine Description:
89
90 Concatenates a formatted unicode string to allocated pool.
91 The caller must free the resulting buffer.
92
93 Arguments:
94
95 Str - Tracks the allocated pool, size in use, and
96 amount of pool allocated.
97
98 fmt - The format string
99
100 Returns:
101
102 Allocated buffer with the formatted string printed in it.
103 The caller must free the allocated buffer. The buffer
104 allocation is not packed.
105
106 --*/
107 {
108 UINT16 *AppendStr;
109 VA_LIST args;
110 UINTN strsize;
111
112 AppendStr = AllocateZeroPool (0x1000);
113 if (AppendStr == NULL) {
114 return Str->str;
115 }
116
117 VA_START (args, fmt);
118 UnicodeVSPrint (AppendStr, 0x1000, fmt, args);
119 VA_END (args);
120 if (NULL == Str->str) {
121 strsize = StrSize (AppendStr);
122 Str->str = AllocateZeroPool (strsize);
123 ASSERT (Str->str != NULL);
124 } else {
125 strsize = StrSize (AppendStr) + StrSize (Str->str) - sizeof (UINT16);
126 Str->str = ReallocatePool (
127 Str->str,
128 StrSize (Str->str),
129 strsize
130 );
131 ASSERT (Str->str != NULL);
132 }
133
134 Str->maxlen = MAX_CHAR * sizeof (UINT16);
135 if (strsize < Str->maxlen) {
136 StrCat (Str->str, AppendStr);
137 Str->len = strsize - sizeof (UINT16);
138 }
139
140 FreePool (AppendStr);
141 return Str->str;
142 }
143
144 EFI_DEVICE_PATH_PROTOCOL *
145 BdsLibUnpackDevicePath (
146 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
147 )
148 /*++
149
150 Routine Description:
151
152 Function unpacks a device path data structure so that all the nodes
153 of a device path are naturally aligned.
154
155 Arguments:
156
157 DevPath - A pointer to a device path data structure
158
159 Returns:
160
161 If the memory for the device path is successfully allocated, then a
162 pointer to the new device path is returned. Otherwise, NULL is returned.
163
164 --*/
165 {
166 EFI_DEVICE_PATH_PROTOCOL *Src;
167 EFI_DEVICE_PATH_PROTOCOL *Dest;
168 EFI_DEVICE_PATH_PROTOCOL *NewPath;
169 UINTN Size;
170
171 //
172 // Walk device path and round sizes to valid boundries
173 //
174 Src = DevPath;
175 Size = 0;
176 for (;;) {
177 Size += DevicePathNodeLength (Src);
178 Size += ALIGN_SIZE (Size);
179
180 if (IsDevicePathEnd (Src)) {
181 break;
182 }
183
184 Src = NextDevicePathNode (Src);
185 }
186 //
187 // Allocate space for the unpacked path
188 //
189 NewPath = AllocateZeroPool (Size);
190 if (NewPath) {
191
192 ASSERT (((UINTN) NewPath) % MIN_ALIGNMENT_SIZE == 0);
193
194 //
195 // Copy each node
196 //
197 Src = DevPath;
198 Dest = NewPath;
199 for (;;) {
200 Size = DevicePathNodeLength (Src);
201 CopyMem (Dest, Src, Size);
202 Size += ALIGN_SIZE (Size);
203 SetDevicePathNodeLength (Dest, Size);
204 Dest->Type |= EFI_DP_TYPE_UNPACKED;
205 Dest = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) Dest) + Size);
206
207 if (IsDevicePathEnd (Src)) {
208 break;
209 }
210
211 Src = NextDevicePathNode (Src);
212 }
213 }
214
215 return NewPath;
216 }
217
218 VOID
219 DevPathPci (
220 IN OUT POOL_PRINT *Str,
221 IN VOID *DevPath
222 )
223 {
224 PCI_DEVICE_PATH *Pci;
225
226 Pci = DevPath;
227 CatPrint (Str, L"Pci(%x|%x)", Pci->Device, Pci->Function);
228 }
229
230 VOID
231 DevPathPccard (
232 IN OUT POOL_PRINT *Str,
233 IN VOID *DevPath
234 )
235 {
236 PCCARD_DEVICE_PATH *Pccard;
237
238 Pccard = DevPath;
239 CatPrint (Str, L"Pcmcia(Function%x)", Pccard->FunctionNumber);
240 }
241
242 VOID
243 DevPathMemMap (
244 IN OUT POOL_PRINT *Str,
245 IN VOID *DevPath
246 )
247 {
248 MEMMAP_DEVICE_PATH *MemMap;
249
250 MemMap = DevPath;
251 CatPrint (
252 Str,
253 L"MemMap(%d:%.lx-%.lx)",
254 MemMap->MemoryType,
255 MemMap->StartingAddress,
256 MemMap->EndingAddress
257 );
258 }
259
260 VOID
261 DevPathController (
262 IN OUT POOL_PRINT *Str,
263 IN VOID *DevPath
264 )
265 {
266 CONTROLLER_DEVICE_PATH *Controller;
267
268 Controller = DevPath;
269 CatPrint (Str, L"Ctrl(%d)", Controller->ControllerNumber);
270 }
271
272 VOID
273 DevPathVendor (
274 IN OUT POOL_PRINT *Str,
275 IN VOID *DevPath
276 )
277 /*++
278
279 Routine Description:
280
281 Convert Vendor device path to device name
282
283 Arguments:
284
285 Str - The buffer store device name
286 DevPath - Pointer to vendor device path
287
288 Returns:
289
290 When it return, the device name have been stored in *Str.
291
292 --*/
293 {
294 VENDOR_DEVICE_PATH *Vendor;
295 CHAR16 *Type;
296 INT32 *Temp;
297
298 Vendor = DevPath;
299 Temp = (INT32 *) (&Vendor->Guid);
300
301 switch (DevicePathType (&Vendor->Header)) {
302 case HARDWARE_DEVICE_PATH:
303 //
304 // If the device is a winntbus device, we will give it a readable device name.
305 //
306 if (CompareGuid (&Vendor->Guid, &mEfiWinNtThunkProtocolGuid)) {
307 CatPrint (Str, L"%s", L"WinNtBus");
308 return ;
309 } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtUgaGuid)) {
310 CatPrint (Str, L"%s", L"UGA");
311 return ;
312 } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtGopGuid)) {
313 CatPrint (Str, L"%s", L"GOP");
314 return ;
315 } else if (CompareGuid (&Vendor->Guid, &mEfiWinNtSerialPortGuid)) {
316 CatPrint (Str, L"%s", L"Serial");
317 return ;
318 } else {
319 Type = L"Hw";
320 break;
321 }
322
323 case MESSAGING_DEVICE_PATH:
324 //
325 // If the device is a winntbus device, we will give it a readable device name.
326 //
327 if (CompareGuid (&Vendor->Guid, &mEfiMsgPcAnsiGuid)) {
328 CatPrint (Str, L"%s", L"PC-ANSI");
329 return ;
330 } else if (CompareGuid (&Vendor->Guid, &mEfiMsgVt100Guid)) {
331 CatPrint (Str, L"%s", L"VT100");
332 return ;
333 } else if (CompareGuid (&Vendor->Guid, &mEfiMsgVt100PlusGuid)) {
334 CatPrint (Str, L"%s", L"VT100+");
335 return ;
336 } else if (CompareGuid (&Vendor->Guid, &mEfiMsgVt100Utf8Guid)) {
337 CatPrint (Str, L"%s", L"VT100-UTF8");
338 return ;
339 } else {
340 Type = L"Msg";
341 break;
342 }
343
344 case MEDIA_DEVICE_PATH:
345 Type = L"Media";
346 break;
347
348 default:
349 Type = L"?";
350 break;
351 }
352
353 CatPrint (Str, L"Ven%s(%g)", Type, &Vendor->Guid);
354 }
355
356 VOID
357 DevPathAcpi (
358 IN OUT POOL_PRINT *Str,
359 IN VOID *DevPath
360 )
361 {
362 ACPI_HID_DEVICE_PATH *Acpi;
363
364 Acpi = DevPath;
365 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
366 CatPrint (Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
367 } else {
368 CatPrint (Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);
369 }
370 }
371
372 VOID
373 DevPathExtendedAcpi (
374 IN OUT POOL_PRINT *Str,
375 IN VOID *DevPath
376 )
377 {
378 ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi;
379 //
380 // Index for HID, UID and CID strings, 0 for non-exist
381 //
382 UINT16 HIDSTRIdx;
383 UINT16 UIDSTRIdx;
384 UINT16 CIDSTRIdx;
385 UINT16 Index;
386 UINT16 Length;
387 UINT16 Anchor;
388 CHAR8 *AsChar8Array;
389
390 ASSERT (Str != NULL);
391 ASSERT (DevPath != NULL);
392
393 HIDSTRIdx = 0;
394 UIDSTRIdx = 0;
395 CIDSTRIdx = 0;
396 ExtendedAcpi = DevPath;
397 Length = DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) ExtendedAcpi);
398
399 ASSERT (Length >= 19);
400 AsChar8Array = (CHAR8 *) ExtendedAcpi;
401
402 //
403 // find HIDSTR
404 //
405 Anchor = 16;
406 for (Index = Anchor; Index < Length && AsChar8Array[Index]; Index++) {
407 ;
408 }
409 if (Index > Anchor) {
410 HIDSTRIdx = Anchor;
411 }
412 //
413 // find UIDSTR
414 //
415 Anchor = Index + 1;
416 for (Index = Anchor; Index < Length && AsChar8Array[Index]; Index++) {
417 ;
418 }
419 if (Index > Anchor) {
420 UIDSTRIdx = Anchor;
421 }
422 //
423 // find CIDSTR
424 //
425 Anchor = Index + 1;
426 for (Index = Anchor; Index < Length && AsChar8Array[Index]; Index++) {
427 ;
428 }
429 if (Index > Anchor) {
430 CIDSTRIdx = Anchor;
431 }
432
433 if (HIDSTRIdx == 0 && CIDSTRIdx == 0 && ExtendedAcpi->UID == 0) {
434 CatPrint (Str, L"AcpiExp(");
435 if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
436 CatPrint (Str, L"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi->HID));
437 } else {
438 CatPrint (Str, L"%08x,", ExtendedAcpi->HID);
439 }
440 if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
441 CatPrint (Str, L"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi->CID));
442 } else {
443 CatPrint (Str, L"%08x,", ExtendedAcpi->CID);
444 }
445 if (UIDSTRIdx != 0) {
446 CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);
447 } else {
448 CatPrint (Str, L"\"\")");
449 }
450 } else {
451 CatPrint (Str, L"AcpiEx(");
452 if ((ExtendedAcpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
453 CatPrint (Str, L"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi->HID));
454 } else {
455 CatPrint (Str, L"%08x,", ExtendedAcpi->HID);
456 }
457 if ((ExtendedAcpi->CID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
458 CatPrint (Str, L"PNP%04x,", EISA_ID_TO_NUM (ExtendedAcpi->CID));
459 } else {
460 CatPrint (Str, L"%08x,", ExtendedAcpi->CID);
461 }
462 CatPrint (Str, L"%x,", ExtendedAcpi->UID);
463
464 if (HIDSTRIdx != 0) {
465 CatPrint (Str, L"%a,", AsChar8Array + HIDSTRIdx);
466 } else {
467 CatPrint (Str, L"\"\",");
468 }
469 if (CIDSTRIdx != 0) {
470 CatPrint (Str, L"%a,", AsChar8Array + CIDSTRIdx);
471 } else {
472 CatPrint (Str, L"\"\",");
473 }
474 if (UIDSTRIdx != 0) {
475 CatPrint (Str, L"%a)", AsChar8Array + UIDSTRIdx);
476 } else {
477 CatPrint (Str, L"\"\")");
478 }
479 }
480
481 }
482
483 VOID
484 DevPathAdrAcpi (
485 IN OUT POOL_PRINT *Str,
486 IN VOID *DevPath
487 )
488 {
489 ACPI_ADR_DEVICE_PATH *AcpiAdr;
490 UINT16 Index;
491 UINT16 Length;
492 UINT16 AdditionalAdrCount;
493
494 AcpiAdr = DevPath;
495 Length = DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
496 AdditionalAdrCount = (Length - 8) / 4;
497
498 CatPrint (Str, L"AcpiAdr(%x", AcpiAdr->ADR);
499 for (Index = 0; Index < AdditionalAdrCount; Index++) {
500 CatPrint (Str, L",%x", *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));
501 }
502 CatPrint (Str, L")");
503 }
504
505 VOID
506 DevPathAtapi (
507 IN OUT POOL_PRINT *Str,
508 IN VOID *DevPath
509 )
510 {
511 ATAPI_DEVICE_PATH *Atapi;
512
513 Atapi = DevPath;
514 CatPrint (
515 Str,
516 L"Ata(%s,%s)",
517 Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
518 Atapi->SlaveMaster ? L"Slave" : L"Master"
519 );
520 }
521
522 VOID
523 DevPathScsi (
524 IN OUT POOL_PRINT *Str,
525 IN VOID *DevPath
526 )
527 {
528 SCSI_DEVICE_PATH *Scsi;
529
530 Scsi = DevPath;
531 CatPrint (Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun);
532 }
533
534 VOID
535 DevPathFibre (
536 IN OUT POOL_PRINT *Str,
537 IN VOID *DevPath
538 )
539 {
540 FIBRECHANNEL_DEVICE_PATH *Fibre;
541
542 Fibre = DevPath;
543 CatPrint (Str, L"Fibre(Wwn%lx,Lun%x)", Fibre->WWN, Fibre->Lun);
544 }
545
546 VOID
547 DevPath1394 (
548 IN OUT POOL_PRINT *Str,
549 IN VOID *DevPath
550 )
551 {
552 F1394_DEVICE_PATH *F1394;
553
554 F1394 = DevPath;
555 CatPrint (Str, L"1394(%g)", &F1394->Guid);
556 }
557
558 VOID
559 DevPathUsb (
560 IN OUT POOL_PRINT *Str,
561 IN VOID *DevPath
562 )
563 {
564 USB_DEVICE_PATH *Usb;
565
566 Usb = DevPath;
567 CatPrint (Str, L"Usb(%x, %x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
568 }
569
570 VOID
571 DevPathUsbClass (
572 IN OUT POOL_PRINT *Str,
573 IN VOID *DevPath
574 )
575 {
576 USB_CLASS_DEVICE_PATH *UsbClass;
577
578 UsbClass = DevPath;
579 CatPrint (
580 Str,
581 L"Usb Class(%x, %x, %x, %x, %x)",
582 UsbClass->VendorId,
583 UsbClass->ProductId,
584 UsbClass->DeviceClass,
585 UsbClass->DeviceSubClass,
586 UsbClass->DeviceProtocol
587 );
588 }
589
590 VOID
591 DevPathI2O (
592 IN OUT POOL_PRINT *Str,
593 IN VOID *DevPath
594 )
595 {
596 I2O_DEVICE_PATH *I2O;
597
598 I2O = DevPath;
599 CatPrint (Str, L"I2O(%x)", I2O->Tid);
600 }
601
602 VOID
603 DevPathMacAddr (
604 IN OUT POOL_PRINT *Str,
605 IN VOID *DevPath
606 )
607 {
608 MAC_ADDR_DEVICE_PATH *MAC;
609 UINTN HwAddressSize;
610 UINTN Index;
611
612 MAC = DevPath;
613
614 HwAddressSize = sizeof (EFI_MAC_ADDRESS);
615 if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
616 HwAddressSize = 6;
617 }
618
619 CatPrint (Str, L"Mac(");
620
621 for (Index = 0; Index < HwAddressSize; Index++) {
622 CatPrint (Str, L"%02x", MAC->MacAddress.Addr[Index]);
623 }
624
625 CatPrint (Str, L")");
626 }
627
628 VOID
629 DevPathIPv4 (
630 IN OUT POOL_PRINT *Str,
631 IN VOID *DevPath
632 )
633 {
634 IPv4_DEVICE_PATH *IP;
635
636 IP = DevPath;
637 CatPrint (
638 Str,
639 L"IPv4(%d.%d.%d.%d:%d)",
640 IP->RemoteIpAddress.Addr[0],
641 IP->RemoteIpAddress.Addr[1],
642 IP->RemoteIpAddress.Addr[2],
643 IP->RemoteIpAddress.Addr[3],
644 IP->RemotePort
645 );
646 }
647
648 VOID
649 DevPathIPv6 (
650 IN OUT POOL_PRINT *Str,
651 IN VOID *DevPath
652 )
653 {
654 IPv6_DEVICE_PATH *IP;
655
656 IP = DevPath;
657 CatPrint (Str, L"IP-v6(not-done)");
658 }
659
660 VOID
661 DevPathInfiniBand (
662 IN OUT POOL_PRINT *Str,
663 IN VOID *DevPath
664 )
665 {
666 INFINIBAND_DEVICE_PATH *InfiniBand;
667
668 InfiniBand = DevPath;
669 CatPrint (Str, L"InfiniBand(not-done)");
670 }
671
672 VOID
673 DevPathUart (
674 IN OUT POOL_PRINT *Str,
675 IN VOID *DevPath
676 )
677 {
678 UART_DEVICE_PATH *Uart;
679 CHAR8 Parity;
680
681 Uart = DevPath;
682 switch (Uart->Parity) {
683 case 0:
684 Parity = 'D';
685 break;
686
687 case 1:
688 Parity = 'N';
689 break;
690
691 case 2:
692 Parity = 'E';
693 break;
694
695 case 3:
696 Parity = 'O';
697 break;
698
699 case 4:
700 Parity = 'M';
701 break;
702
703 case 5:
704 Parity = 'S';
705 break;
706
707 default:
708 Parity = 'x';
709 break;
710 }
711
712 if (Uart->BaudRate == 0) {
713 CatPrint (Str, L"Uart(DEFAULT %c", Parity);
714 } else {
715 CatPrint (Str, L"Uart(%d %c", Uart->BaudRate, Parity);
716 }
717
718 if (Uart->DataBits == 0) {
719 CatPrint (Str, L"D");
720 } else {
721 CatPrint (Str, L"%d", Uart->DataBits);
722 }
723
724 switch (Uart->StopBits) {
725 case 0:
726 CatPrint (Str, L"D)");
727 break;
728
729 case 1:
730 CatPrint (Str, L"1)");
731 break;
732
733 case 2:
734 CatPrint (Str, L"1.5)");
735 break;
736
737 case 3:
738 CatPrint (Str, L"2)");
739 break;
740
741 default:
742 CatPrint (Str, L"x)");
743 break;
744 }
745 }
746
747 VOID
748 DevPathHardDrive (
749 IN OUT POOL_PRINT *Str,
750 IN VOID *DevPath
751 )
752 {
753 HARDDRIVE_DEVICE_PATH *Hd;
754
755 Hd = DevPath;
756 switch (Hd->SignatureType) {
757 case SIGNATURE_TYPE_MBR:
758 CatPrint (
759 Str,
760 L"HD(Part%d,Sig%08x)",
761 Hd->PartitionNumber,
762 *((UINT32 *) (&(Hd->Signature[0])))
763 );
764 break;
765
766 case SIGNATURE_TYPE_GUID:
767 CatPrint (
768 Str,
769 L"HD(Part%d,Sig%g)",
770 Hd->PartitionNumber,
771 (EFI_GUID *) &(Hd->Signature[0])
772 );
773 break;
774
775 default:
776 CatPrint (
777 Str,
778 L"HD(Part%d,MBRType=%02x,SigType=%02x)",
779 Hd->PartitionNumber,
780 Hd->MBRType,
781 Hd->SignatureType
782 );
783 break;
784 }
785 }
786
787 VOID
788 DevPathCDROM (
789 IN OUT POOL_PRINT *Str,
790 IN VOID *DevPath
791 )
792 {
793 CDROM_DEVICE_PATH *Cd;
794
795 Cd = DevPath;
796 CatPrint (Str, L"CDROM(Entry%x)", Cd->BootEntry);
797 }
798
799 VOID
800 DevPathFilePath (
801 IN OUT POOL_PRINT *Str,
802 IN VOID *DevPath
803 )
804 {
805 FILEPATH_DEVICE_PATH *Fp;
806
807 Fp = DevPath;
808 CatPrint (Str, L"%s", Fp->PathName);
809 }
810
811 VOID
812 DevPathMediaProtocol (
813 IN OUT POOL_PRINT *Str,
814 IN VOID *DevPath
815 )
816 {
817 MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
818
819 MediaProt = DevPath;
820 CatPrint (Str, L"%g", &MediaProt->Protocol);
821 }
822
823 VOID
824 DevPathFvFilePath (
825 IN OUT POOL_PRINT *Str,
826 IN VOID *DevPath
827 )
828 {
829 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
830
831 FvFilePath = DevPath;
832 CatPrint (Str, L"%g", &FvFilePath->NameGuid);
833 }
834
835 VOID
836 DevPathBssBss (
837 IN OUT POOL_PRINT *Str,
838 IN VOID *DevPath
839 )
840 {
841 BBS_BBS_DEVICE_PATH *Bbs;
842 CHAR16 *Type;
843
844 Bbs = DevPath;
845 switch (Bbs->DeviceType) {
846 case BBS_TYPE_FLOPPY:
847 Type = L"Floppy";
848 break;
849
850 case BBS_TYPE_HARDDRIVE:
851 Type = L"Harddrive";
852 break;
853
854 case BBS_TYPE_CDROM:
855 Type = L"CDROM";
856 break;
857
858 case BBS_TYPE_PCMCIA:
859 Type = L"PCMCIA";
860 break;
861
862 case BBS_TYPE_USB:
863 Type = L"Usb";
864 break;
865
866 case BBS_TYPE_EMBEDDED_NETWORK:
867 Type = L"Net";
868 break;
869
870 default:
871 Type = L"?";
872 break;
873 }
874 //
875 // Since current Print function hasn't implemented %a (for ansi string)
876 // we will only print Unicode strings.
877 //
878 CatPrint (Str, L"Legacy-%s", Type);
879 }
880
881 VOID
882 DevPathEndInstance (
883 IN OUT POOL_PRINT *Str,
884 IN VOID *DevPath
885 )
886 {
887 CatPrint (Str, L",");
888 }
889
890 VOID
891 DevPathNodeUnknown (
892 IN OUT POOL_PRINT *Str,
893 IN VOID *DevPath
894 )
895 {
896 CatPrint (Str, L"?");
897 }
898
899 DEVICE_PATH_STRING_TABLE DevPathTable[] = {
900 HARDWARE_DEVICE_PATH,
901 HW_PCI_DP,
902 DevPathPci,
903 HARDWARE_DEVICE_PATH,
904 HW_PCCARD_DP,
905 DevPathPccard,
906 HARDWARE_DEVICE_PATH,
907 HW_MEMMAP_DP,
908 DevPathMemMap,
909 HARDWARE_DEVICE_PATH,
910 HW_VENDOR_DP,
911 DevPathVendor,
912 HARDWARE_DEVICE_PATH,
913 HW_CONTROLLER_DP,
914 DevPathController,
915 ACPI_DEVICE_PATH,
916 ACPI_DP,
917 DevPathAcpi,
918 ACPI_DEVICE_PATH,
919 ACPI_EXTENDED_DP,
920 DevPathExtendedAcpi,
921 ACPI_DEVICE_PATH,
922 ACPI_ADR_DP,
923 DevPathAdrAcpi,
924 MESSAGING_DEVICE_PATH,
925 MSG_ATAPI_DP,
926 DevPathAtapi,
927 MESSAGING_DEVICE_PATH,
928 MSG_SCSI_DP,
929 DevPathScsi,
930 MESSAGING_DEVICE_PATH,
931 MSG_FIBRECHANNEL_DP,
932 DevPathFibre,
933 MESSAGING_DEVICE_PATH,
934 MSG_1394_DP,
935 DevPath1394,
936 MESSAGING_DEVICE_PATH,
937 MSG_USB_DP,
938 DevPathUsb,
939 MESSAGING_DEVICE_PATH,
940 MSG_USB_CLASS_DP,
941 DevPathUsbClass,
942 MESSAGING_DEVICE_PATH,
943 MSG_I2O_DP,
944 DevPathI2O,
945 MESSAGING_DEVICE_PATH,
946 MSG_MAC_ADDR_DP,
947 DevPathMacAddr,
948 MESSAGING_DEVICE_PATH,
949 MSG_IPv4_DP,
950 DevPathIPv4,
951 MESSAGING_DEVICE_PATH,
952 MSG_IPv6_DP,
953 DevPathIPv6,
954 MESSAGING_DEVICE_PATH,
955 MSG_INFINIBAND_DP,
956 DevPathInfiniBand,
957 MESSAGING_DEVICE_PATH,
958 MSG_UART_DP,
959 DevPathUart,
960 MESSAGING_DEVICE_PATH,
961 MSG_VENDOR_DP,
962 DevPathVendor,
963 MEDIA_DEVICE_PATH,
964 MEDIA_HARDDRIVE_DP,
965 DevPathHardDrive,
966 MEDIA_DEVICE_PATH,
967 MEDIA_CDROM_DP,
968 DevPathCDROM,
969 MEDIA_DEVICE_PATH,
970 MEDIA_VENDOR_DP,
971 DevPathVendor,
972 MEDIA_DEVICE_PATH,
973 MEDIA_FILEPATH_DP,
974 DevPathFilePath,
975 MEDIA_DEVICE_PATH,
976 MEDIA_PROTOCOL_DP,
977 DevPathMediaProtocol,
978 BBS_DEVICE_PATH,
979 BBS_BBS_DP,
980 DevPathBssBss,
981 END_DEVICE_PATH_TYPE,
982 END_INSTANCE_DEVICE_PATH_SUBTYPE,
983 DevPathEndInstance,
984 0,
985 0,
986 NULL
987 };
988
989 CHAR16 *
990 DevicePathToStr (
991 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
992 )
993 /*++
994
995 Turns the Device Path into a printable string. Allcoates
996 the string from pool. The caller must SafeFreePool the returned
997 string.
998
999 --*/
1000 {
1001 POOL_PRINT Str;
1002 EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
1003 VOID (*DumpNode) (POOL_PRINT *, VOID *);
1004
1005 UINTN Index;
1006 UINTN NewSize;
1007
1008 ZeroMem (&Str, sizeof (Str));
1009
1010 if (DevPath == NULL) {
1011 goto Done;
1012 }
1013 //
1014 // Unpacked the device path
1015 //
1016 DevPath = BdsLibUnpackDevicePath (DevPath);
1017 ASSERT (DevPath);
1018
1019 //
1020 // Process each device path node
1021 //
1022 DevPathNode = DevPath;
1023 while (!IsDevicePathEnd (DevPathNode)) {
1024 //
1025 // Find the handler to dump this device path node
1026 //
1027 DumpNode = NULL;
1028 for (Index = 0; DevPathTable[Index].Function; Index += 1) {
1029
1030 if (DevicePathType (DevPathNode) == DevPathTable[Index].Type &&
1031 DevicePathSubType (DevPathNode) == DevPathTable[Index].SubType
1032 ) {
1033 DumpNode = DevPathTable[Index].Function;
1034 break;
1035 }
1036 }
1037 //
1038 // If not found, use a generic function
1039 //
1040 if (!DumpNode) {
1041 DumpNode = DevPathNodeUnknown;
1042 }
1043 //
1044 // Put a path seperator in if needed
1045 //
1046 if (Str.len && DumpNode != DevPathEndInstance) {
1047 CatPrint (&Str, L"/");
1048 }
1049 //
1050 // Print this node of the device path
1051 //
1052 DumpNode (&Str, DevPathNode);
1053
1054 //
1055 // Next device path node
1056 //
1057 DevPathNode = NextDevicePathNode (DevPathNode);
1058 }
1059 //
1060 // Shrink pool used for string allocation
1061 //
1062 FreePool (DevPath);
1063
1064 Done:
1065 NewSize = (Str.len + 1) * sizeof (CHAR16);
1066 Str.str = ReallocatePool (Str.str, NewSize, NewSize);
1067 ASSERT (Str.str != NULL);
1068 Str.str[Str.len] = 0;
1069 return Str.str;
1070 }
1071
1072 EFI_DEVICE_PATH_PROTOCOL *
1073 LibDuplicateDevicePathInstance (
1074 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
1075 )
1076 /*++
1077
1078 Routine Description:
1079
1080 Function creates a device path data structure that identically matches the
1081 device path passed in.
1082
1083 Arguments:
1084
1085 DevPath - A pointer to a device path data structure.
1086
1087 Returns:
1088
1089 The new copy of DevPath is created to identically match the input.
1090 Otherwise, NULL is returned.
1091
1092 --*/
1093 {
1094 EFI_DEVICE_PATH_PROTOCOL *NewDevPath;
1095 EFI_DEVICE_PATH_PROTOCOL *DevicePathInst;
1096 EFI_DEVICE_PATH_PROTOCOL *Temp;
1097 UINTN Size;
1098
1099 //
1100 // get the size of an instance from the input
1101 //
1102 Temp = DevPath;
1103 DevicePathInst = GetNextDevicePathInstance (&Temp, &Size);
1104
1105 //
1106 // Make a copy
1107 //
1108 NewDevPath = NULL;
1109 if (Size) {
1110 NewDevPath = AllocateZeroPool (Size);
1111 ASSERT (NewDevPath != NULL);
1112 }
1113
1114 if (NewDevPath) {
1115 CopyMem (NewDevPath, DevicePathInst, Size);
1116 }
1117
1118 return NewDevPath;
1119 }