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