aboutsummaryrefslogtreecommitdiff
path: root/gnu-efi/gnu-efi-3.0/lib/dpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu-efi/gnu-efi-3.0/lib/dpath.c')
-rw-r--r--gnu-efi/gnu-efi-3.0/lib/dpath.c1035
1 files changed, 1035 insertions, 0 deletions
diff --git a/gnu-efi/gnu-efi-3.0/lib/dpath.c b/gnu-efi/gnu-efi-3.0/lib/dpath.c
new file mode 100644
index 0000000..11c1b20
--- /dev/null
+++ b/gnu-efi/gnu-efi-3.0/lib/dpath.c
@@ -0,0 +1,1035 @@
+/*++
+
+Copyright (c) 1998 Intel Corporation
+
+Module Name:
+
+ dpath.c
+
+Abstract:
+ MBR & Device Path functions
+
+
+
+Revision History
+
+--*/
+
+#include "lib.h"
+
+#define ALIGN_SIZE(a) ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)
+
+
+
+EFI_DEVICE_PATH *
+DevicePathFromHandle (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH *DevicePath;
+
+ Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &DevicePathProtocol, (VOID*)&DevicePath);
+ if (EFI_ERROR(Status)) {
+ DevicePath = NULL;
+ }
+
+ return DevicePath;
+}
+
+
+EFI_DEVICE_PATH *
+DevicePathInstance (
+ IN OUT EFI_DEVICE_PATH **DevicePath,
+ OUT UINTN *Size
+ )
+{
+ EFI_DEVICE_PATH *Start, *Next, *DevPath;
+ UINTN Count;
+
+ DevPath = *DevicePath;
+ Start = DevPath;
+
+ if (!DevPath) {
+ return NULL;
+ }
+
+ //
+ // Check for end of device path type
+ //
+
+ for (Count = 0; ; Count++) {
+ Next = NextDevicePathNode(DevPath);
+
+ if (IsDevicePathEndType(DevPath)) {
+ break;
+ }
+
+ if (Count > 01000) {
+ //
+ // BugBug: Debug code to catch bogus device paths
+ //
+ DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) ));
+ DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start);
+ break;
+ }
+
+ DevPath = Next;
+ }
+
+ ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE ||
+ DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
+
+ //
+ // Set next position
+ //
+
+ if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
+ Next = NULL;
+ }
+
+ *DevicePath = Next;
+
+ //
+ // Return size and start of device path instance
+ //
+
+ *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start);
+ return Start;
+}
+
+UINTN
+DevicePathInstanceCount (
+ IN EFI_DEVICE_PATH *DevicePath
+ )
+{
+ UINTN Count, Size;
+
+ Count = 0;
+ while (DevicePathInstance(&DevicePath, &Size)) {
+ Count += 1;
+ }
+
+ return Count;
+}
+
+
+EFI_DEVICE_PATH *
+AppendDevicePath (
+ IN EFI_DEVICE_PATH *Src1,
+ IN EFI_DEVICE_PATH *Src2
+ )
+// Src1 may have multiple "instances" and each instance is appended
+// Src2 is appended to each instance is Src1. (E.g., it's possible
+// to append a new instance to the complete device path by passing
+// it in Src2)
+{
+ UINTN Src1Size, Src1Inst, Src2Size, Size;
+ EFI_DEVICE_PATH *Dst, *Inst;
+ UINT8 *DstPos;
+
+ //
+ // If there's only 1 path, just duplicate it
+ //
+
+ if (!Src1) {
+ ASSERT (!IsDevicePathUnpacked (Src2));
+ return DuplicateDevicePath (Src2);
+ }
+
+ if (!Src2) {
+ ASSERT (!IsDevicePathUnpacked (Src1));
+ return DuplicateDevicePath (Src1);
+ }
+
+ //
+ // Verify we're not working with unpacked paths
+ //
+
+// ASSERT (!IsDevicePathUnpacked (Src1));
+// ASSERT (!IsDevicePathUnpacked (Src2));
+
+ //
+ // Append Src2 to every instance in Src1
+ //
+
+ Src1Size = DevicePathSize(Src1);
+ Src1Inst = DevicePathInstanceCount(Src1);
+ Src2Size = DevicePathSize(Src2);
+ Size = Src1Size * Src1Inst + Src2Size;
+
+ Dst = AllocatePool (Size);
+ if (Dst) {
+ DstPos = (UINT8 *) Dst;
+
+ //
+ // Copy all device path instances
+ //
+
+ while ((Inst = DevicePathInstance (&Src1, &Size))) {
+
+ CopyMem(DstPos, Inst, Size);
+ DstPos += Size;
+
+ CopyMem(DstPos, Src2, Src2Size);
+ DstPos += Src2Size;
+
+ CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH));
+ DstPos += sizeof(EFI_DEVICE_PATH);
+ }
+
+ // Change last end marker
+ DstPos -= sizeof(EFI_DEVICE_PATH);
+ CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH));
+ }
+
+ return Dst;
+}
+
+
+EFI_DEVICE_PATH *
+AppendDevicePathNode (
+ IN EFI_DEVICE_PATH *Src1,
+ IN EFI_DEVICE_PATH *Src2
+ )
+// Src1 may have multiple "instances" and each instance is appended
+// Src2 is a signal device path node (without a terminator) that is
+// appended to each instance is Src1.
+{
+ EFI_DEVICE_PATH *Temp, *Eop;
+ UINTN Length;
+
+ //
+ // Build a Src2 that has a terminator on it
+ //
+
+ Length = DevicePathNodeLength(Src2);
+ Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH));
+ if (!Temp) {
+ return NULL;
+ }
+
+ CopyMem (Temp, Src2, Length);
+ Eop = NextDevicePathNode(Temp);
+ SetDevicePathEndNode(Eop);
+
+ //
+ // Append device paths
+ //
+
+ Src1 = AppendDevicePath (Src1, Temp);
+ FreePool (Temp);
+ return Src1;
+}
+
+
+EFI_DEVICE_PATH *
+FileDevicePath (
+ IN EFI_HANDLE Device OPTIONAL,
+ IN CHAR16 *FileName
+ )
+/*++
+
+ N.B. Results are allocated from pool. The caller must FreePool
+ the resulting device path structure
+
+--*/
+{
+ UINTN Size;
+ FILEPATH_DEVICE_PATH *FilePath;
+ EFI_DEVICE_PATH *Eop, *DevicePath;
+
+ Size = StrSize(FileName);
+ FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH));
+ DevicePath = NULL;
+
+ if (FilePath) {
+
+ //
+ // Build a file path
+ //
+
+ FilePath->Header.Type = MEDIA_DEVICE_PATH;
+ FilePath->Header.SubType = MEDIA_FILEPATH_DP;
+ SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
+ CopyMem (FilePath->PathName, FileName, Size);
+ Eop = NextDevicePathNode(&FilePath->Header);
+ SetDevicePathEndNode(Eop);
+
+ //
+ // Append file path to device's device path
+ //
+
+ DevicePath = (EFI_DEVICE_PATH *) FilePath;
+ if (Device) {
+ DevicePath = AppendDevicePath (
+ DevicePathFromHandle(Device),
+ DevicePath
+ );
+
+ FreePool(FilePath);
+ }
+ }
+
+ return DevicePath;
+}
+
+
+
+UINTN
+DevicePathSize (
+ IN EFI_DEVICE_PATH *DevPath
+ )
+{
+ EFI_DEVICE_PATH *Start;
+
+ //
+ // Search for the end of the device path structure
+ //
+
+ Start = DevPath;
+ while (!IsDevicePathEnd(DevPath)) {
+ DevPath = NextDevicePathNode(DevPath);
+ }
+
+ //
+ // Compute the size
+ //
+
+ return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH);
+}
+
+EFI_DEVICE_PATH *
+DuplicateDevicePath (
+ IN EFI_DEVICE_PATH *DevPath
+ )
+{
+ EFI_DEVICE_PATH *NewDevPath;
+ UINTN Size;
+
+
+ //
+ // Compute the size
+ //
+
+ Size = DevicePathSize (DevPath);
+
+ //
+ // Make a copy
+ //
+
+ NewDevPath = AllocatePool (Size);
+ if (NewDevPath) {
+ CopyMem (NewDevPath, DevPath, Size);
+ }
+
+ return NewDevPath;
+}
+
+EFI_DEVICE_PATH *
+UnpackDevicePath (
+ IN EFI_DEVICE_PATH *DevPath
+ )
+{
+ EFI_DEVICE_PATH *Src, *Dest, *NewPath;
+ UINTN Size;
+
+ //
+ // Walk device path and round sizes to valid boundries
+ //
+
+ Src = DevPath;
+ Size = 0;
+ for (; ;) {
+ Size += DevicePathNodeLength(Src);
+ Size += ALIGN_SIZE(Size);
+
+ if (IsDevicePathEnd(Src)) {
+ break;
+ }
+
+ Src = NextDevicePathNode(Src);
+ }
+
+
+ //
+ // Allocate space for the unpacked path
+ //
+
+ NewPath = AllocateZeroPool (Size);
+ if (NewPath) {
+
+ ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0);
+
+ //
+ // Copy each node
+ //
+
+ Src = DevPath;
+ Dest = NewPath;
+ for (; ;) {
+ Size = DevicePathNodeLength(Src);
+ CopyMem (Dest, Src, Size);
+ Size += ALIGN_SIZE(Size);
+ SetDevicePathNodeLength (Dest, Size);
+ Dest->Type |= EFI_DP_TYPE_UNPACKED;
+ Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size);
+
+ if (IsDevicePathEnd(Src)) {
+ break;
+ }
+
+ Src = NextDevicePathNode(Src);
+ }
+ }
+
+ return NewPath;
+}
+
+
+EFI_DEVICE_PATH*
+AppendDevicePathInstance (
+ IN EFI_DEVICE_PATH *Src,
+ IN EFI_DEVICE_PATH *Instance
+ )
+{
+ UINT8 *Ptr;
+ EFI_DEVICE_PATH *DevPath;
+ UINTN SrcSize;
+ UINTN InstanceSize;
+
+ if (Src == NULL) {
+ return DuplicateDevicePath (Instance);
+ }
+ SrcSize = DevicePathSize(Src);
+ InstanceSize = DevicePathSize(Instance);
+ Ptr = AllocatePool (SrcSize + InstanceSize);
+ DevPath = (EFI_DEVICE_PATH *)Ptr;
+ ASSERT(DevPath);
+
+ CopyMem (Ptr, Src, SrcSize);
+// FreePool (Src);
+
+ while (!IsDevicePathEnd(DevPath)) {
+ DevPath = NextDevicePathNode(DevPath);
+ }
+ //
+ // Convert the End to an End Instance, since we are
+ // appending another instacne after this one its a good
+ // idea.
+ //
+ DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+ DevPath = NextDevicePathNode(DevPath);
+ CopyMem (DevPath, Instance, InstanceSize);
+ return (EFI_DEVICE_PATH *)Ptr;
+}
+
+EFI_STATUS
+LibDevicePathToInterface (
+ IN EFI_GUID *Protocol,
+ IN EFI_DEVICE_PATH *FilePath,
+ OUT VOID **Interface
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Device;
+
+ Status = uefi_call_wrapper(BS->LocateDevicePath, 3, Protocol, &FilePath, &Device);
+
+ if (!EFI_ERROR(Status)) {
+
+ // If we didn't get a direct match return not found
+ Status = EFI_NOT_FOUND;
+
+ if (IsDevicePathEnd(FilePath)) {
+
+ //
+ // It was a direct match, lookup the protocol interface
+ //
+
+ Status =uefi_call_wrapper(BS->HandleProtocol, 3, Device, Protocol, Interface);
+ }
+ }
+
+ //
+ // If there was an error, do not return an interface
+ //
+
+ if (EFI_ERROR(Status)) {
+ *Interface = NULL;
+ }
+
+ return Status;
+}
+
+VOID
+_DevPathPci (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ PCI_DEVICE_PATH *Pci;
+
+ Pci = DevPath;
+ CatPrint(Str, L"Pci(%x|%x)", Pci->Device, Pci->Function);
+}
+
+VOID
+_DevPathPccard (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ PCCARD_DEVICE_PATH *Pccard;
+
+ Pccard = DevPath;
+ CatPrint(Str, L"Pccard(Socket%x)", Pccard->SocketNumber);
+}
+
+VOID
+_DevPathMemMap (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ MemMap = DevPath;
+ CatPrint(Str, L"MemMap(%d:%x-%x)",
+ MemMap->MemoryType,
+ MemMap->StartingAddress,
+ MemMap->EndingAddress
+ );
+}
+
+VOID
+_DevPathController (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ CONTROLLER_DEVICE_PATH *Controller;
+
+ Controller = DevPath;
+ CatPrint(Str, L"Ctrl(%d)",
+ Controller->Controller
+ );
+}
+
+VOID
+_DevPathVendor (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+ CHAR16 *Type;
+ UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownDevPath;
+
+ Vendor = DevPath;
+ switch (DevicePathType(&Vendor->Header)) {
+ case HARDWARE_DEVICE_PATH: Type = L"Hw"; break;
+ case MESSAGING_DEVICE_PATH: Type = L"Msg"; break;
+ case MEDIA_DEVICE_PATH: Type = L"Media"; break;
+ default: Type = L"?"; break;
+ }
+
+ CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid);
+ if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) {
+ //
+ // GUID used by EFI to enumerate an EDD 1.1 device
+ //
+ UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor;
+ CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter);
+ } else {
+ CatPrint(Str, L")");
+ }
+}
+
+
+VOID
+_DevPathAcpi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ Acpi = DevPath;
+ if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ CatPrint(Str, L"Acpi(PNP%04x,%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
+ } else {
+ CatPrint(Str, L"Acpi(%08x,%x)", Acpi->HID, Acpi->UID);
+ }
+}
+
+
+VOID
+_DevPathAtapi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ ATAPI_DEVICE_PATH *Atapi;
+
+ Atapi = DevPath;
+ CatPrint(Str, L"Ata(%s,%s)",
+ Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
+ Atapi->SlaveMaster ? L"Slave" : L"Master"
+ );
+}
+
+VOID
+_DevPathScsi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ SCSI_DEVICE_PATH *Scsi;
+
+ Scsi = DevPath;
+ CatPrint(Str, L"Scsi(Pun%x,Lun%x)", Scsi->Pun, Scsi->Lun);
+}
+
+
+VOID
+_DevPathFibre (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ FIBRECHANNEL_DEVICE_PATH *Fibre;
+
+ Fibre = DevPath;
+ CatPrint(Str, L"Fibre(%lx)", Fibre->WWN);
+}
+
+VOID
+_DevPath1394 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ F1394_DEVICE_PATH *F1394;
+
+ F1394 = DevPath;
+ CatPrint(Str, L"1394(%g)", &F1394->Guid);
+}
+
+
+
+VOID
+_DevPathUsb (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ USB_DEVICE_PATH *Usb;
+
+ Usb = DevPath;
+ CatPrint(Str, L"Usb(%x)", Usb->Port);
+}
+
+
+VOID
+_DevPathI2O (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ I2O_DEVICE_PATH *I2O;
+
+ I2O = DevPath;
+ CatPrint(Str, L"I2O(%x)", I2O->Tid);
+}
+
+VOID
+_DevPathMacAddr (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ MAC_ADDR_DEVICE_PATH *MAC;
+ UINTN HwAddressSize;
+ UINTN Index;
+
+ MAC = DevPath;
+
+ HwAddressSize = sizeof(EFI_MAC_ADDRESS);
+ if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
+ HwAddressSize = 6;
+ }
+
+ CatPrint(Str, L"Mac(");
+
+ for(Index = 0; Index < HwAddressSize; Index++) {
+ CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]);
+ }
+ CatPrint(Str, L")");
+}
+
+VOID
+_DevPathIPv4 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ IPv4_DEVICE_PATH *IP;
+
+ IP = DevPath;
+ CatPrint(Str, L"IPv4(not-done)");
+}
+
+VOID
+_DevPathIPv6 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ IPv6_DEVICE_PATH *IP;
+
+ IP = DevPath;
+ CatPrint(Str, L"IP-v6(not-done)");
+}
+
+VOID
+_DevPathInfiniBand (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ InfiniBand = DevPath;
+ CatPrint(Str, L"InfiniBand(not-done)");
+}
+
+VOID
+_DevPathUart (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ UART_DEVICE_PATH *Uart;
+ CHAR8 Parity;
+
+ Uart = DevPath;
+ switch (Uart->Parity) {
+ case 0 : Parity = 'D'; break;
+ case 1 : Parity = 'N'; break;
+ case 2 : Parity = 'E'; break;
+ case 3 : Parity = 'O'; break;
+ case 4 : Parity = 'M'; break;
+ case 5 : Parity = 'S'; break;
+ default : Parity = 'x'; break;
+ }
+
+ if (Uart->BaudRate == 0) {
+ CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity);
+ } else {
+ CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity);
+ }
+
+ if (Uart->DataBits == 0) {
+ CatPrint(Str, L"D");
+ } else {
+ CatPrint(Str, L"%d",Uart->DataBits);
+ }
+
+ switch (Uart->StopBits) {
+ case 0 : CatPrint(Str, L"D)"); break;
+ case 1 : CatPrint(Str, L"1)"); break;
+ case 2 : CatPrint(Str, L"1.5)"); break;
+ case 3 : CatPrint(Str, L"2)"); break;
+ default : CatPrint(Str, L"x)"); break;
+ }
+}
+
+
+VOID
+_DevPathHardDrive (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ HARDDRIVE_DEVICE_PATH *Hd;
+
+ Hd = DevPath;
+ switch (Hd->SignatureType) {
+ case SIGNATURE_TYPE_MBR:
+ CatPrint(Str, L"HD(Part%d,Sig%08X)",
+ Hd->PartitionNumber,
+ *((UINT32 *)(&(Hd->Signature[0])))
+ );
+ break;
+ case SIGNATURE_TYPE_GUID:
+ CatPrint(Str, L"HD(Part%d,Sig%g)",
+ Hd->PartitionNumber,
+ (EFI_GUID *) &(Hd->Signature[0])
+ );
+ break;
+ default:
+ CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)",
+ Hd->PartitionNumber,
+ Hd->MBRType,
+ Hd->SignatureType
+ );
+ break;
+ }
+}
+
+VOID
+_DevPathCDROM (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ CDROM_DEVICE_PATH *Cd;
+
+ Cd = DevPath;
+ CatPrint(Str, L"CDROM(Entry%x)", Cd->BootEntry);
+}
+
+VOID
+_DevPathFilePath (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ FILEPATH_DEVICE_PATH *Fp;
+
+ Fp = DevPath;
+ CatPrint(Str, L"%s", Fp->PathName);
+}
+
+VOID
+_DevPathMediaProtocol (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
+
+ MediaProt = DevPath;
+ CatPrint(Str, L"%g", &MediaProt->Protocol);
+}
+
+VOID
+_DevPathBssBss (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ BBS_BBS_DEVICE_PATH *Bss;
+ CHAR16 *Type;
+
+ Bss = DevPath;
+ switch (Bss->DeviceType) {
+ case BBS_TYPE_FLOPPY: Type = L"Floppy"; break;
+ case BBS_TYPE_HARDDRIVE: Type = L"Harddrive"; break;
+ case BBS_TYPE_CDROM: Type = L"CDROM"; break;
+ case BBS_TYPE_PCMCIA: Type = L"PCMCIA"; break;
+ case BBS_TYPE_USB: Type = L"Usb"; break;
+ case BBS_TYPE_EMBEDDED_NETWORK: Type = L"Net"; break;
+ default: Type = L"?"; break;
+ }
+
+ CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String);
+}
+
+
+VOID
+_DevPathEndInstance (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ CatPrint(Str, L",");
+}
+
+VOID
+_DevPathNodeUnknown (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath
+ )
+{
+ CatPrint(Str, L"?");
+}
+
+
+struct {
+ UINT8 Type;
+ UINT8 SubType;
+ VOID (*Function)(POOL_PRINT *, VOID *);
+} DevPathTable[] = {
+ { HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci},
+ { HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard},
+ { HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap},
+ { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, _DevPathVendor},
+ { HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, _DevPathController},
+ { ACPI_DEVICE_PATH, ACPI_DP, _DevPathAcpi},
+ { MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, _DevPathAtapi},
+ { MESSAGING_DEVICE_PATH, MSG_SCSI_DP, _DevPathScsi},
+ { MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, _DevPathFibre},
+ { MESSAGING_DEVICE_PATH, MSG_1394_DP, _DevPath1394},
+ { MESSAGING_DEVICE_PATH, MSG_USB_DP, _DevPathUsb},
+ { MESSAGING_DEVICE_PATH, MSG_I2O_DP, _DevPathI2O},
+ { MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, _DevPathMacAddr},
+ { MESSAGING_DEVICE_PATH, MSG_IPv4_DP, _DevPathIPv4},
+ { MESSAGING_DEVICE_PATH, MSG_IPv6_DP, _DevPathIPv6},
+ { MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, _DevPathInfiniBand},
+ { MESSAGING_DEVICE_PATH, MSG_UART_DP, _DevPathUart},
+ { MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, _DevPathVendor},
+ { MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, _DevPathHardDrive},
+ { MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, _DevPathCDROM},
+ { MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, _DevPathVendor},
+ { MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, _DevPathFilePath},
+ { MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, _DevPathMediaProtocol},
+ { BBS_DEVICE_PATH, BBS_BBS_DP, _DevPathBssBss},
+ { END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance},
+ { 0, 0, NULL}
+};
+
+
+CHAR16 *
+DevicePathToStr (
+ EFI_DEVICE_PATH *DevPath
+ )
+/*++
+
+ Turns the Device Path into a printable string. Allcoates
+ the string from pool. The caller must FreePool the returned
+ string.
+
+--*/
+{
+ POOL_PRINT Str;
+ EFI_DEVICE_PATH *DevPathNode;
+ VOID (*DumpNode)(POOL_PRINT *, VOID *);
+ UINTN Index, NewSize;
+
+ ZeroMem(&Str, sizeof(Str));
+
+ //
+ // Unpacked the device path
+ //
+
+ DevPath = UnpackDevicePath(DevPath);
+ ASSERT (DevPath);
+
+
+ //
+ // Process each device path node
+ //
+
+ DevPathNode = DevPath;
+ while (!IsDevicePathEnd(DevPathNode)) {
+ //
+ // Find the handler to dump this device path node
+ //
+
+ DumpNode = NULL;
+ for (Index = 0; DevPathTable[Index].Function; Index += 1) {
+
+ if (DevicePathType(DevPathNode) == DevPathTable[Index].Type &&
+ DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) {
+ DumpNode = DevPathTable[Index].Function;
+ break;
+ }
+ }
+
+ //
+ // If not found, use a generic function
+ //
+
+ if (!DumpNode) {
+ DumpNode = _DevPathNodeUnknown;
+ }
+
+ //
+ // Put a path seperator in if needed
+ //
+
+ if (Str.len && DumpNode != _DevPathEndInstance) {
+ CatPrint (&Str, L"/");
+ }
+
+ //
+ // Print this node of the device path
+ //
+
+ DumpNode (&Str, DevPathNode);
+
+ //
+ // Next device path node
+ //
+
+ DevPathNode = NextDevicePathNode(DevPathNode);
+ }
+
+ //
+ // Shrink pool used for string allocation
+ //
+
+ FreePool (DevPath);
+ NewSize = (Str.len + 1) * sizeof(CHAR16);
+ Str.str = ReallocatePool (Str.str, NewSize, NewSize);
+ Str.str[Str.len] = 0;
+ return Str.str;
+}
+
+BOOLEAN
+LibMatchDevicePaths (
+ IN EFI_DEVICE_PATH *Multi,
+ IN EFI_DEVICE_PATH *Single
+ )
+{
+ EFI_DEVICE_PATH *DevicePath, *DevicePathInst;
+ UINTN Size;
+
+ if (!Multi || !Single) {
+ return FALSE;
+ }
+
+ DevicePath = Multi;
+ while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) {
+ if (CompareMem (Single, DevicePathInst, Size) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+EFI_DEVICE_PATH *
+LibDuplicateDevicePathInstance (
+ IN EFI_DEVICE_PATH *DevPath
+ )
+{
+ EFI_DEVICE_PATH *NewDevPath,*DevicePathInst,*Temp;
+ UINTN Size = 0;
+
+ //
+ // get the size of an instance from the input
+ //
+
+ Temp = DevPath;
+ DevicePathInst = DevicePathInstance (&Temp, &Size);
+
+ //
+ // Make a copy and set proper end type
+ //
+ NewDevPath = NULL;
+ if (Size) {
+ NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH));
+ }
+
+ if (NewDevPath) {
+ CopyMem (NewDevPath, DevicePathInst, Size);
+ Temp = NextDevicePathNode(NewDevPath);
+ SetDevicePathEndNode(Temp);
+ }
+
+ return NewDevPath;
+}
+