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