Home | History | Annotate | Line # | Download | only in lib
dpath.c revision 1.1.1.1.16.1
      1  1.1.1.1.16.1  pgoyette /*	$NetBSD: dpath.c,v 1.1.1.1.16.1 2017/03/20 06:57:45 pgoyette 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.1.1.1.16.1  pgoyette     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.1.1.1.16.1  pgoyette     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.1.1.1.16.1  pgoyette     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