| /*++ |
| |
| 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; |
| } |
| |