1 /* $NetBSD: dpath.c,v 1.1.1.1 2014/04/01 16:16:06 jakllsch Exp $ */ 2 3 /*++ 4 5 Copyright (c) 1998 Intel Corporation 6 7 Module Name: 8 9 dpath.c 10 11 Abstract: 12 MBR & Device Path functions 13 14 15 16 Revision History 17 18 --*/ 19 20 #include "lib.h" 21 22 #define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0) 23 24 25 26 EFI_DEVICE_PATH * 27 DevicePathFromHandle ( 28 IN EFI_HANDLE Handle 29 ) 30 { 31 EFI_STATUS Status; 32 EFI_DEVICE_PATH *DevicePath; 33 34 Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &DevicePathProtocol, (VOID*)&DevicePath); 35 if (EFI_ERROR(Status)) { 36 DevicePath = NULL; 37 } 38 39 return DevicePath; 40 } 41 42 43 EFI_DEVICE_PATH * 44 DevicePathInstance ( 45 IN OUT EFI_DEVICE_PATH **DevicePath, 46 OUT UINTN *Size 47 ) 48 { 49 EFI_DEVICE_PATH *Start, *Next, *DevPath; 50 UINTN Count; 51 52 DevPath = *DevicePath; 53 Start = DevPath; 54 55 if (!DevPath) { 56 return NULL; 57 } 58 59 // 60 // Check for end of device path type 61 // 62 63 for (Count = 0; ; Count++) { 64 Next = NextDevicePathNode(DevPath); 65 66 if (IsDevicePathEndType(DevPath)) { 67 break; 68 } 69 70 if (Count > 01000) { 71 // 72 // BugBug: Debug code to catch bogus device paths 73 // 74 DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) )); 75 DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start); 76 break; 77 } 78 79 DevPath = Next; 80 } 81 82 ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE || 83 DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE); 84 85 // 86 // Set next position 87 // 88 89 if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) { 90 Next = NULL; 91 } 92 93 *DevicePath = Next; 94 95 // 96 // Return size and start of device path instance 97 // 98 99 *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start); 100 return Start; 101 } 102 103 UINTN 104 DevicePathInstanceCount ( 105 IN EFI_DEVICE_PATH *DevicePath 106 ) 107 { 108 UINTN Count, Size; 109 110 Count = 0; 111 while (DevicePathInstance(&DevicePath, &Size)) { 112 Count += 1; 113 } 114 115 return Count; 116 } 117 118 119 EFI_DEVICE_PATH * 120 AppendDevicePath ( 121 IN EFI_DEVICE_PATH *Src1, 122 IN EFI_DEVICE_PATH *Src2 123 ) 124 // Src1 may have multiple "instances" and each instance is appended 125 // Src2 is appended to each instance is Src1. (E.g., it's possible 126 // to append a new instance to the complete device path by passing 127 // it in Src2) 128 { 129 UINTN Src1Size, Src1Inst, Src2Size, Size; 130 EFI_DEVICE_PATH *Dst, *Inst; 131 UINT8 *DstPos; 132 133 // 134 // If there's only 1 path, just duplicate it 135 // 136 137 if (!Src1) { 138 ASSERT (!IsDevicePathUnpacked (Src2)); 139 return DuplicateDevicePath (Src2); 140 } 141 142 if (!Src2) { 143 ASSERT (!IsDevicePathUnpacked (Src1)); 144 return DuplicateDevicePath (Src1); 145 } 146 147 // 148 // Verify we're not working with unpacked paths 149 // 150 151 // ASSERT (!IsDevicePathUnpacked (Src1)); 152 // ASSERT (!IsDevicePathUnpacked (Src2)); 153 154 // 155 // Append Src2 to every instance in Src1 156 // 157 158 Src1Size = DevicePathSize(Src1); 159 Src1Inst = DevicePathInstanceCount(Src1); 160 Src2Size = DevicePathSize(Src2); 161 Size = Src1Size * Src1Inst + Src2Size; 162 163 Dst = AllocatePool (Size); 164 if (Dst) { 165 DstPos = (UINT8 *) Dst; 166 167 // 168 // Copy all device path instances 169 // 170 171 while ((Inst = DevicePathInstance (&Src1, &Size))) { 172 173 CopyMem(DstPos, Inst, Size); 174 DstPos += Size; 175 176 CopyMem(DstPos, Src2, Src2Size); 177 DstPos += Src2Size; 178 179 CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH)); 180 DstPos += sizeof(EFI_DEVICE_PATH); 181 } 182 183 // Change last end marker 184 DstPos -= sizeof(EFI_DEVICE_PATH); 185 CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH)); 186 } 187 188 return Dst; 189 } 190 191 192 EFI_DEVICE_PATH * 193 AppendDevicePathNode ( 194 IN EFI_DEVICE_PATH *Src1, 195 IN EFI_DEVICE_PATH *Src2 196 ) 197 // Src1 may have multiple "instances" and each instance is appended 198 // Src2 is a signal device path node (without a terminator) that is 199 // appended to each instance is Src1. 200 { 201 EFI_DEVICE_PATH *Temp, *Eop; 202 UINTN Length; 203 204 // 205 // Build a Src2 that has a terminator on it 206 // 207 208 Length = DevicePathNodeLength(Src2); 209 Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH)); 210 if (!Temp) { 211 return NULL; 212 } 213 214 CopyMem (Temp, Src2, Length); 215 Eop = NextDevicePathNode(Temp); 216 SetDevicePathEndNode(Eop); 217 218 // 219 // Append device paths 220 // 221 222 Src1 = AppendDevicePath (Src1, Temp); 223 FreePool (Temp); 224 return Src1; 225 } 226 227 228 EFI_DEVICE_PATH * 229 FileDevicePath ( 230 IN EFI_HANDLE Device OPTIONAL, 231 IN CHAR16 *FileName 232 ) 233 /*++ 234 235 N.B. Results are allocated from pool. The caller must FreePool 236 the resulting device path structure 237 238 --*/ 239 { 240 UINTN Size; 241 FILEPATH_DEVICE_PATH *FilePath; 242 EFI_DEVICE_PATH *Eop, *DevicePath; 243 244 Size = StrSize(FileName); 245 FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH)); 246 DevicePath = NULL; 247 248 if (FilePath) { 249 250 // 251 // Build a file path 252 // 253 254 FilePath->Header.Type = MEDIA_DEVICE_PATH; 255 FilePath->Header.SubType = MEDIA_FILEPATH_DP; 256 SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); 257 CopyMem (FilePath->PathName, FileName, Size); 258 Eop = NextDevicePathNode(&FilePath->Header); 259 SetDevicePathEndNode(Eop); 260 261 // 262 // Append file path to device's device path 263 // 264 265 DevicePath = (EFI_DEVICE_PATH *) FilePath; 266 if (Device) { 267 DevicePath = AppendDevicePath ( 268 DevicePathFromHandle(Device), 269 DevicePath 270 ); 271 272 FreePool(FilePath); 273 } 274 } 275 276 return DevicePath; 277 } 278 279 280 281 UINTN 282 DevicePathSize ( 283 IN EFI_DEVICE_PATH *DevPath 284 ) 285 { 286 EFI_DEVICE_PATH *Start; 287 288 // 289 // Search for the end of the device path structure 290 // 291 292 Start = DevPath; 293 while (!IsDevicePathEnd(DevPath)) { 294 DevPath = NextDevicePathNode(DevPath); 295 } 296 297 // 298 // Compute the size 299 // 300 301 return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH); 302 } 303 304 EFI_DEVICE_PATH * 305 DuplicateDevicePath ( 306 IN EFI_DEVICE_PATH *DevPath 307 ) 308 { 309 EFI_DEVICE_PATH *NewDevPath; 310 UINTN Size; 311 312 313 // 314 // Compute the size 315 // 316 317 Size = DevicePathSize (DevPath); 318 319 // 320 // Make a copy 321 // 322 323 NewDevPath = AllocatePool (Size); 324 if (NewDevPath) { 325 CopyMem (NewDevPath, DevPath, Size); 326 } 327 328 return NewDevPath; 329 } 330 331 EFI_DEVICE_PATH * 332 UnpackDevicePath ( 333 IN EFI_DEVICE_PATH *DevPath 334 ) 335 { 336 EFI_DEVICE_PATH *Src, *Dest, *NewPath; 337 UINTN Size; 338 339 // 340 // Walk device path and round sizes to valid boundries 341 // 342 343 Src = DevPath; 344 Size = 0; 345 for (; ;) { 346 Size += DevicePathNodeLength(Src); 347 Size += ALIGN_SIZE(Size); 348 349 if (IsDevicePathEnd(Src)) { 350 break; 351 } 352 353 Src = NextDevicePathNode(Src); 354 } 355 356 357 // 358 // Allocate space for the unpacked path 359 // 360 361 NewPath = AllocateZeroPool (Size); 362 if (NewPath) { 363 364 ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0); 365 366 // 367 // Copy each node 368 // 369 370 Src = DevPath; 371 Dest = NewPath; 372 for (; ;) { 373 Size = DevicePathNodeLength(Src); 374 CopyMem (Dest, Src, Size); 375 Size += ALIGN_SIZE(Size); 376 SetDevicePathNodeLength (Dest, Size); 377 Dest->Type |= EFI_DP_TYPE_UNPACKED; 378 Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size); 379 380 if (IsDevicePathEnd(Src)) { 381 break; 382 } 383 384 Src = NextDevicePathNode(Src); 385 } 386 } 387 388 return NewPath; 389 } 390 391 392 EFI_DEVICE_PATH* 393 AppendDevicePathInstance ( 394 IN EFI_DEVICE_PATH *Src, 395 IN EFI_DEVICE_PATH *Instance 396 ) 397 { 398 UINT8 *Ptr; 399 EFI_DEVICE_PATH *DevPath; 400 UINTN SrcSize; 401 UINTN InstanceSize; 402 403 if (Src == NULL) { 404 return DuplicateDevicePath (Instance); 405 } 406 SrcSize = DevicePathSize(Src); 407 InstanceSize = DevicePathSize(Instance); 408 Ptr = AllocatePool (SrcSize + InstanceSize); 409 DevPath = (EFI_DEVICE_PATH *)Ptr; 410 ASSERT(DevPath); 411 412 CopyMem (Ptr, Src, SrcSize); 413 // FreePool (Src); 414 415 while (!IsDevicePathEnd(DevPath)) { 416 DevPath = NextDevicePathNode(DevPath); 417 } 418 // 419 // Convert the End to an End Instance, since we are 420 // appending another instacne after this one its a good 421 // idea. 422 // 423 DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; 424 425 DevPath = NextDevicePathNode(DevPath); 426 CopyMem (DevPath, Instance, InstanceSize); 427 return (EFI_DEVICE_PATH *)Ptr; 428 } 429 430 EFI_STATUS 431 LibDevicePathToInterface ( 432 IN EFI_GUID *Protocol, 433 IN EFI_DEVICE_PATH *FilePath, 434 OUT VOID **Interface 435 ) 436 { 437 EFI_STATUS Status; 438 EFI_HANDLE Device; 439 440 Status = uefi_call_wrapper(BS->LocateDevicePath, 3, Protocol, &FilePath, &Device); 441 442 if (!EFI_ERROR(Status)) { 443 444 // If we didn't get a direct match return not found 445 Status = EFI_NOT_FOUND; 446 447 if (IsDevicePathEnd(FilePath)) { 448 449 // 450 // It was a direct match, lookup the protocol interface 451 // 452 453 Status =uefi_call_wrapper(BS->HandleProtocol, 3, Device, Protocol, Interface); 454 } 455 } 456 457 // 458 // If there was an error, do not return an interface 459 // 460 461 if (EFI_ERROR(Status)) { 462 *Interface = NULL; 463 } 464 465 return Status; 466 } 467 468 VOID 469 _DevPathPci ( 470 IN OUT POOL_PRINT *Str, 471 IN VOID *DevPath 472 ) 473 { 474 PCI_DEVICE_PATH *Pci; 475 476 Pci = DevPath; 477 CatPrint(Str, L"Pci(%x|%x)", Pci->Device, Pci->Function); 478 } 479 480 VOID 481 _DevPathPccard ( 482 IN OUT POOL_PRINT *Str, 483 IN VOID *DevPath 484 ) 485 { 486 PCCARD_DEVICE_PATH *Pccard; 487 488 Pccard = DevPath; 489 CatPrint(Str, L"Pccard(Socket%x)", Pccard->SocketNumber); 490 } 491 492 VOID 493 _DevPathMemMap ( 494 IN OUT POOL_PRINT *Str, 495 IN VOID *DevPath 496 ) 497 { 498 MEMMAP_DEVICE_PATH *MemMap; 499 500 MemMap = DevPath; 501 CatPrint(Str, L"MemMap(%d:%x-%x)", 502 MemMap->MemoryType, 503 MemMap->StartingAddress, 504 MemMap->EndingAddress 505 ); 506 } 507 508 VOID 509 _DevPathController ( 510 IN OUT POOL_PRINT *Str, 511 IN VOID *DevPath 512 ) 513 { 514 CONTROLLER_DEVICE_PATH *Controller; 515 516 Controller = DevPath; 517 CatPrint(Str, L"Ctrl(%d)", 518 Controller->Controller 519 ); 520 } 521 522 VOID 523 _DevPathVendor ( 524 IN OUT POOL_PRINT *Str, 525 IN VOID *DevPath 526 ) 527 { 528 VENDOR_DEVICE_PATH *Vendor; 529 CHAR16 *Type; 530 UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevPath; 531 532 Vendor = DevPath; 533 switch (DevicePathType(&Vendor->Header)) { 534 case HARDWARE_DEVICE_PATH: Type = L"Hw"; break; 535 case MESSAGING_DEVICE_PATH: Type = L"Msg"; break; 536 case MEDIA_DEVICE_PATH: Type = L"Media"; break; 537 default: Type = L"?"; break; 538 } 539 540 CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid); 541 if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) { 542 // 543 // GUID used by EFI to enumerate an EDD 1.1 device 544 // 545 UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor; 546 CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter); 547 } else { 548 CatPrint(Str, L")"); 549 } 550 } 551 552 553 VOID 554 _DevPathAcpi ( 555 IN OUT POOL_PRINT *Str, 556 IN VOID *DevPath 557 ) 558 { 559 ACPI_HID_DEVICE_PATH *Acpi; 560 561 Acpi = DevPath; 562 if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) { 563 CatPrint(Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID); 564 } else { 565 CatPrint(Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID); 566 } 567 } 568 569 570 VOID 571 _DevPathAtapi ( 572 IN OUT POOL_PRINT *Str, 573 IN VOID *DevPath 574 ) 575 { 576 ATAPI_DEVICE_PATH *Atapi; 577 578 Atapi = DevPath; 579 CatPrint(Str, L"Ata(%s,%s)", 580 Atapi->PrimarySecondary ? L"Secondary" : L"Primary", 581 Atapi->SlaveMaster ? L"Slave" : L"Master" 582 ); 583 } 584 585 VOID 586 _DevPathScsi ( 587 IN OUT POOL_PRINT *Str, 588 IN VOID *DevPath 589 ) 590 { 591 SCSI_DEVICE_PATH *Scsi; 592 593 Scsi = DevPath; 594 CatPrint(Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun); 595 } 596 597 598 VOID 599 _DevPathFibre ( 600 IN OUT POOL_PRINT *Str, 601 IN VOID *DevPath 602 ) 603 { 604 FIBRECHANNEL_DEVICE_PATH *Fibre; 605 606 Fibre = DevPath; 607 CatPrint(Str, L"Fibre(%lx)", Fibre->WWN); 608 } 609 610 VOID 611 _DevPath1394 ( 612 IN OUT POOL_PRINT *Str, 613 IN VOID *DevPath 614 ) 615 { 616 F1394_DEVICE_PATH *F1394; 617 618 F1394 = DevPath; 619 CatPrint(Str, L"1394(%g)", &F1394->Guid); 620 } 621 622 623 624 VOID 625 _DevPathUsb ( 626 IN OUT POOL_PRINT *Str, 627 IN VOID *DevPath 628 ) 629 { 630 USB_DEVICE_PATH *Usb; 631 632 Usb = DevPath; 633 CatPrint(Str, L"Usb(%x)", Usb->Port); 634 } 635 636 637 VOID 638 _DevPathI2O ( 639 IN OUT POOL_PRINT *Str, 640 IN VOID *DevPath 641 ) 642 { 643 I2O_DEVICE_PATH *I2O; 644 645 I2O = DevPath; 646 CatPrint(Str, L"I2O(%x)", I2O->Tid); 647 } 648 649 VOID 650 _DevPathMacAddr ( 651 IN OUT POOL_PRINT *Str, 652 IN VOID *DevPath 653 ) 654 { 655 MAC_ADDR_DEVICE_PATH *MAC; 656 UINTN HwAddressSize; 657 UINTN Index; 658 659 MAC = DevPath; 660 661 HwAddressSize = sizeof(EFI_MAC_ADDRESS); 662 if (MAC->IfType == 0x01 || MAC->IfType == 0x00) { 663 HwAddressSize = 6; 664 } 665 666 CatPrint(Str, L"Mac("); 667 668 for(Index = 0; Index < HwAddressSize; Index++) { 669 CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]); 670 } 671 CatPrint(Str, L")"); 672 } 673 674 VOID 675 _DevPathIPv4 ( 676 IN OUT POOL_PRINT *Str, 677 IN VOID *DevPath 678 ) 679 { 680 IPv4_DEVICE_PATH *IP; 681 682 IP = DevPath; 683 CatPrint(Str, L"IPv4(not-done)"); 684 } 685 686 VOID 687 _DevPathIPv6 ( 688 IN OUT POOL_PRINT *Str, 689 IN VOID *DevPath 690 ) 691 { 692 IPv6_DEVICE_PATH *IP; 693 694 IP = DevPath; 695 CatPrint(Str, L"IP-v6(not-done)"); 696 } 697 698 VOID 699 _DevPathInfiniBand ( 700 IN OUT POOL_PRINT *Str, 701 IN VOID *DevPath 702 ) 703 { 704 INFINIBAND_DEVICE_PATH *InfiniBand; 705 706 InfiniBand = DevPath; 707 CatPrint(Str, L"InfiniBand(not-done)"); 708 } 709 710 VOID 711 _DevPathUart ( 712 IN OUT POOL_PRINT *Str, 713 IN VOID *DevPath 714 ) 715 { 716 UART_DEVICE_PATH *Uart; 717 CHAR8 Parity; 718 719 Uart = DevPath; 720 switch (Uart->Parity) { 721 case 0 : Parity = 'D'; break; 722 case 1 : Parity = 'N'; break; 723 case 2 : Parity = 'E'; break; 724 case 3 : Parity = 'O'; break; 725 case 4 : Parity = 'M'; break; 726 case 5 : Parity = 'S'; break; 727 default : Parity = 'x'; break; 728 } 729 730 if (Uart->BaudRate == 0) { 731 CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity); 732 } else { 733 CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity); 734 } 735 736 if (Uart->DataBits == 0) { 737 CatPrint(Str, L"D"); 738 } else { 739 CatPrint(Str, L"%d",Uart->DataBits); 740 } 741 742 switch (Uart->StopBits) { 743 case 0 : CatPrint(Str, L"D)"); break; 744 case 1 : CatPrint(Str, L"1)"); break; 745 case 2 : CatPrint(Str, L"1.5)"); break; 746 case 3 : CatPrint(Str, L"2)"); break; 747 default : CatPrint(Str, L"x)"); break; 748 } 749 } 750 751 752 VOID 753 _DevPathHardDrive ( 754 IN OUT POOL_PRINT *Str, 755 IN VOID *DevPath 756 ) 757 { 758 HARDDRIVE_DEVICE_PATH *Hd; 759 760 Hd = DevPath; 761 switch (Hd->SignatureType) { 762 case SIGNATURE_TYPE_MBR: 763 CatPrint(Str, L"HD(Part%d,Sig%08X)", 764 Hd->PartitionNumber, 765 *((UINT32 *)(&(Hd->Signature[0]))) 766 ); 767 break; 768 case SIGNATURE_TYPE_GUID: 769 CatPrint(Str, L"HD(Part%d,Sig%g)", 770 Hd->PartitionNumber, 771 (EFI_GUID *) &(Hd->Signature[0]) 772 ); 773 break; 774 default: 775 CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)", 776 Hd->PartitionNumber, 777 Hd->MBRType, 778 Hd->SignatureType 779 ); 780 break; 781 } 782 } 783 784 VOID 785 _DevPathCDROM ( 786 IN OUT POOL_PRINT *Str, 787 IN VOID *DevPath 788 ) 789 { 790 CDROM_DEVICE_PATH *Cd; 791 792 Cd = DevPath; 793 CatPrint(Str, L"CDROM(Entry%x)", Cd->BootEntry); 794 } 795 796 VOID 797 _DevPathFilePath ( 798 IN OUT POOL_PRINT *Str, 799 IN VOID *DevPath 800 ) 801 { 802 FILEPATH_DEVICE_PATH *Fp; 803 804 Fp = DevPath; 805 CatPrint(Str, L"%s", Fp->PathName); 806 } 807 808 VOID 809 _DevPathMediaProtocol ( 810 IN OUT POOL_PRINT *Str, 811 IN VOID *DevPath 812 ) 813 { 814 MEDIA_PROTOCOL_DEVICE_PATH *MediaProt; 815 816 MediaProt = DevPath; 817 CatPrint(Str, L"%g", &MediaProt->Protocol); 818 } 819 820 VOID 821 _DevPathBssBss ( 822 IN OUT POOL_PRINT *Str, 823 IN VOID *DevPath 824 ) 825 { 826 BBS_BBS_DEVICE_PATH *Bss; 827 CHAR16 *Type; 828 829 Bss = DevPath; 830 switch (Bss->DeviceType) { 831 case BBS_TYPE_FLOPPY: Type = L"Floppy"; break; 832 case BBS_TYPE_HARDDRIVE: Type = L"Harddrive"; break; 833 case BBS_TYPE_CDROM: Type = L"CDROM"; break; 834 case BBS_TYPE_PCMCIA: Type = L"PCMCIA"; break; 835 case BBS_TYPE_USB: Type = L"Usb"; break; 836 case BBS_TYPE_EMBEDDED_NETWORK: Type = L"Net"; break; 837 default: Type = L"?"; break; 838 } 839 840 CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String); 841 } 842 843 844 VOID 845 _DevPathEndInstance ( 846 IN OUT POOL_PRINT *Str, 847 IN VOID *DevPath 848 ) 849 { 850 CatPrint(Str, L","); 851 } 852 853 VOID 854 _DevPathNodeUnknown ( 855 IN OUT POOL_PRINT *Str, 856 IN VOID *DevPath 857 ) 858 { 859 CatPrint(Str, L"?"); 860 } 861 862 863 struct { 864 UINT8 Type; 865 UINT8 SubType; 866 VOID (*Function)(POOL_PRINT *, VOID *); 867 } DevPathTable[] = { 868 { HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci}, 869 { HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard}, 870 { HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap}, 871 { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, _DevPathVendor}, 872 { HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, _DevPathController}, 873 { ACPI_DEVICE_PATH, ACPI_DP, _DevPathAcpi}, 874 { MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, _DevPathAtapi}, 875 { MESSAGING_DEVICE_PATH, MSG_SCSI_DP, _DevPathScsi}, 876 { MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, _DevPathFibre}, 877 { MESSAGING_DEVICE_PATH, MSG_1394_DP, _DevPath1394}, 878 { MESSAGING_DEVICE_PATH, MSG_USB_DP, _DevPathUsb}, 879 { MESSAGING_DEVICE_PATH, MSG_I2O_DP, _DevPathI2O}, 880 { MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, _DevPathMacAddr}, 881 { MESSAGING_DEVICE_PATH, MSG_IPv4_DP, _DevPathIPv4}, 882 { MESSAGING_DEVICE_PATH, MSG_IPv6_DP, _DevPathIPv6}, 883 { MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, _DevPathInfiniBand}, 884 { MESSAGING_DEVICE_PATH, MSG_UART_DP, _DevPathUart}, 885 { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, _DevPathVendor}, 886 { MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, _DevPathHardDrive}, 887 { MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, _DevPathCDROM}, 888 { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, _DevPathVendor}, 889 { MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, _DevPathFilePath}, 890 { MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, _DevPathMediaProtocol}, 891 { BBS_DEVICE_PATH, BBS_BBS_DP, _DevPathBssBss}, 892 { END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance}, 893 { 0, 0, NULL} 894 }; 895 896 897 CHAR16 * 898 DevicePathToStr ( 899 EFI_DEVICE_PATH *DevPath 900 ) 901 /*++ 902 903 Turns the Device Path into a printable string. Allcoates 904 the string from pool. The caller must FreePool the returned 905 string. 906 907 --*/ 908 { 909 POOL_PRINT Str; 910 EFI_DEVICE_PATH *DevPathNode; 911 VOID (*DumpNode)(POOL_PRINT *, VOID *); 912 UINTN Index, NewSize; 913 914 ZeroMem(&Str, sizeof(Str)); 915 916 // 917 // Unpacked the device path 918 // 919 920 DevPath = UnpackDevicePath(DevPath); 921 ASSERT (DevPath); 922 923 924 // 925 // Process each device path node 926 // 927 928 DevPathNode = DevPath; 929 while (!IsDevicePathEnd(DevPathNode)) { 930 // 931 // Find the handler to dump this device path node 932 // 933 934 DumpNode = NULL; 935 for (Index = 0; DevPathTable[Index].Function; Index += 1) { 936 937 if (DevicePathType(DevPathNode) == DevPathTable[Index].Type && 938 DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) { 939 DumpNode = DevPathTable[Index].Function; 940 break; 941 } 942 } 943 944 // 945 // If not found, use a generic function 946 // 947 948 if (!DumpNode) { 949 DumpNode = _DevPathNodeUnknown; 950 } 951 952 // 953 // Put a path seperator in if needed 954 // 955 956 if (Str.len && DumpNode != _DevPathEndInstance) { 957 CatPrint (&Str, L"/"); 958 } 959 960 // 961 // Print this node of the device path 962 // 963 964 DumpNode (&Str, DevPathNode); 965 966 // 967 // Next device path node 968 // 969 970 DevPathNode = NextDevicePathNode(DevPathNode); 971 } 972 973 // 974 // Shrink pool used for string allocation 975 // 976 977 FreePool (DevPath); 978 NewSize = (Str.len + 1) * sizeof(CHAR16); 979 Str.str = ReallocatePool (Str.str, NewSize, NewSize); 980 Str.str[Str.len] = 0; 981 return Str.str; 982 } 983 984 BOOLEAN 985 LibMatchDevicePaths ( 986 IN EFI_DEVICE_PATH *Multi, 987 IN EFI_DEVICE_PATH *Single 988 ) 989 { 990 EFI_DEVICE_PATH *DevicePath, *DevicePathInst; 991 UINTN Size; 992 993 if (!Multi || !Single) { 994 return FALSE; 995 } 996 997 DevicePath = Multi; 998 while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) { 999 if (CompareMem (Single, DevicePathInst, Size) == 0) { 1000 return TRUE; 1001 } 1002 } 1003 return FALSE; 1004 } 1005 1006 EFI_DEVICE_PATH * 1007 LibDuplicateDevicePathInstance ( 1008 IN EFI_DEVICE_PATH *DevPath 1009 ) 1010 { 1011 EFI_DEVICE_PATH *NewDevPath,*DevicePathInst,*Temp; 1012 UINTN Size; 1013 1014 // 1015 // get the size of an instance from the input 1016 // 1017 1018 Temp = DevPath; 1019 DevicePathInst = DevicePathInstance (&Temp, &Size); 1020 1021 // 1022 // Make a copy and set proper end type 1023 // 1024 NewDevPath = NULL; 1025 if (Size) { 1026 NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH)); 1027 } 1028 1029 if (NewDevPath) { 1030 CopyMem (NewDevPath, DevicePathInst, Size); 1031 Temp = NextDevicePathNode(NewDevPath); 1032 SetDevicePathEndNode(Temp); 1033 } 1034 1035 return NewDevPath; 1036 } 1037 1038