On Fri, 12 May 2017 09:33:04 +0200
Michele Curti <[email protected]> wrote:
> On Fri, May 12, 2017 at 07:27:45AM +0200, Michele Curti wrote:
>> 
>> The efi_device_path_cmp() compares only a path node.
>> I tried the following diff just to see if I undestood something, 
>> hd0 is now set corrctly to the 29GB disk.
>> 
>> 
>> Index: efiboot/efiboot.c
>> ===================================================================
>> RCS file: /cvs/src/sys/arch/amd64/stand/efiboot/efiboot.c,v
>> retrieving revision 1.17
>> diff -u -p -r1.17 efiboot.c
>> --- efiboot/efiboot.c        3 Mar 2017 08:56:18 -0000       1.17
>> +++ efiboot/efiboot.c        12 May 2017 05:23:21 -0000
>> @@ -233,10 +233,21 @@ efi_device_path_cmp(EFI_DEVICE_PATH *dpa
>>      }
>>  
>>      if (dpt_a && dpt_b) {
>> -            cmp = DevicePathNodeLength(dpt_a) - DevicePathNodeLength(dpt_b);
>> -            if (cmp)
>> -                    return (cmp);
>> -            return (memcmp(dpt_a, dpt_b, DevicePathNodeLength(dpt_a)));
>> +            for (;!IsDevicePathEnd(dpt_a);) {
>> +                    cmp = DevicePathNodeLength(dpt_a) - 
>> DevicePathNodeLength(dpt_b);
>> +                    if (cmp)
>> +                            return (cmp);
>> +                    cmp = memcmp(dpt_a, dpt_b, DevicePathNodeLength(dpt_a));
>> +                    if (cmp)
>> +                            return (cmp);
>> +                    dpt_a = NextDevicePathNode(dpt_a);
>> +                    dpt_b = NextDevicePathNode(dpt_b);
>> +                    cmp = IsDevicePathEnd(dpt_a) - IsDevicePathEnd(dpt_b);
>> +                    if (cmp)
>> +                            return (cmp);
>> +            }
>> +
>> +            return 0;
>>      }
>>  
>>      return ((uintptr_t)dpt_a - (uintptr_t)dpt_b);
> 
> And something like this?

Yes.  What we need to do is comparing the device path node before
MEDIA_DEVICE_PATH type.  So I rewrote it like

  media_idx = device_path_index(rootdp, MEDIA_DEVICE_PATH);
  for (...)
    if (device_path_ncmp(rootdp, dp, media_idx) == 0)
       bootdev = 1;

ok? comment?

diff --git a/sys/arch/amd64/stand/efiboot/efiboot.c 
b/sys/arch/amd64/stand/efiboot/efiboot.c
index efa371f2ecd..b78ca2b350e 100644
--- a/sys/arch/amd64/stand/efiboot/efiboot.c
+++ b/sys/arch/amd64/stand/efiboot/efiboot.c
@@ -52,7 +52,9 @@ static EFI_GUID                blkio_guid = BLOCK_IO_PROTOCOL;
 static EFI_GUID                 devp_guid = DEVICE_PATH_PROTOCOL;
 u_long                  efi_loadaddr;
 
-static int      efi_device_path_cmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int);
+static int      efi_device_path_index(EFI_DEVICE_PATH *dp, int);
+static int      efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *,
+                   int);
 static void     efi_heap_init(void);
 static void     efi_memprobe_internal(void);
 static void     efi_video_init(void);
@@ -159,7 +161,7 @@ struct disklist_lh efi_disklist;
 void
 efi_diskprobe(void)
 {
-       int                      i, bootdev;
+       int                      i, media_idx, bootdev;
        UINTN                    sz;
        EFI_STATUS               status;
        EFI_HANDLE              *handles = NULL;
@@ -180,6 +182,8 @@ efi_diskprobe(void)
        if (handles == NULL || EFI_ERROR(status))
                panic("BS->LocateHandle() returns %d", status);
 
+       media_idx = efi_device_path_index(efi_bootdp, MEDIA_DEVICE_PATH);
+
        for (i = 0; i < sz / sizeof(EFI_HANDLE); i++) {
                bootdev = 0;
                status = EFI_CALL(BS->HandleProtocol, handles[i], &blkio_guid,
@@ -199,9 +203,7 @@ efi_diskprobe(void)
                    (void **)&dp);
                if (EFI_ERROR(status))
                        goto next;
-               if (!efi_device_path_cmp(efi_bootdp, dp, HARDWARE_DEVICE_PATH)&&
-                   !efi_device_path_cmp(efi_bootdp, dp, ACPI_DEVICE_PATH) &&
-                   !efi_device_path_cmp(efi_bootdp, dp, MESSAGING_DEVICE_PATH))
+               if (efi_device_path_ncmp(efi_bootdp, dp, media_idx) == 0)
                        bootdev = 1;
 next:
                if (bootdev)
@@ -214,32 +216,39 @@ next:
 }
 
 static int
-efi_device_path_cmp(EFI_DEVICE_PATH *dpa, EFI_DEVICE_PATH *dpb, int dptype)
+efi_device_path_index(EFI_DEVICE_PATH *dp, int dptype)
 {
-       int              cmp;
-       EFI_DEVICE_PATH *dp, *dpt_a = NULL, *dpt_b = NULL;
+       int     idx = 0;
 
-       for (dp = dpa; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
-               if (DevicePathType(dp) == dptype) {
-                       dpt_a = dp;
+       for (idx = 0; !IsDevicePathEnd(dp); idx++) {
+               if (DevicePathType(dp) == dptype)
                        break;
-               }
-       }
-       for (dp = dpb; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
-               if (DevicePathType(dp) == dptype) {
-                       dpt_b = dp;
-                       break;
-               }
+               dp = NextDevicePathNode(dp);
        }
 
-       if (dpt_a && dpt_b) {
-               cmp = DevicePathNodeLength(dpt_a) - DevicePathNodeLength(dpt_b);
+       return (idx);
+}
+
+static int
+efi_device_path_ncmp(EFI_DEVICE_PATH *dpa, EFI_DEVICE_PATH *dpb, int idx)
+{
+       int      i, cmp;
+
+       for (i = 0; i < idx &&
+           !IsDevicePathEnd(dpa) && !IsDevicePathEnd(dpb); i++) {
+               cmp = DevicePathNodeLength(dpa) - DevicePathNodeLength(dpb);
                if (cmp)
                        return (cmp);
-               return (memcmp(dpt_a, dpt_b, DevicePathNodeLength(dpt_a)));
+               cmp = memcmp(dpa, dpb, DevicePathNodeLength(dpa));
+               if (cmp)
+                       return (cmp);
+               dpa = NextDevicePathNode(dpa);
+               dpb = NextDevicePathNode(dpb);
        }
+       if (i < idx)
+               return (-1);
 
-       return ((uintptr_t)dpt_a - (uintptr_t)dpt_b);
+       return (0);
 }
 
 /***********************************************************************

Reply via email to