On Fri, May 12, 2017 at 11:05:13AM +0900, YASUOKA Masahiko wrote:
> On Thu, 11 May 2017 23:45:17 +0200
> Michele Curti <[email protected]> wrote:
>
> All disks are identical in HARDWARE_DEVICE_PATH and ACPI_DEVICE_PATH
> and they all don't have MESSAGING_DEVICE_PATH. So the boot loader
> mistakenly treats all of them as the bootdisk..
>
> I'd like to know whether there is a way to distigish those disks. Can
> you try the diff following?
>
> diff --git a/sys/arch/amd64/stand/efiboot/efiboot.c
> b/sys/arch/amd64/stand/efiboot/efiboot.c
> index efa371f2ecd..891b6c75cc9 100644
> --- a/sys/arch/amd64/stand/efiboot/efiboot.c
> +++ b/sys/arch/amd64/stand/efiboot/efiboot.c
> @@ -208,6 +208,14 @@ next:
> TAILQ_INSERT_HEAD(&efi_disklist, di, list);
> else
> TAILQ_INSERT_TAIL(&efi_disklist, di, list);
> +
> + printf("%d\n", i);
> + for (; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
> + int ii;
> + for (ii = 0; ii < DevicePathNodeLength(dp); ii++)
> + printf("%x ", *((u_char *)dp + ii));
> + printf("\n");
> + }
> }
>
> free(handles, sz);
>
0
2 1 c 0 d0 41 3 a 0 0 0 0
1 1 6 0 0 17
1 5 8 0 0 0 0 0
1
2 1 c 0 d0 41 3 a 0 0 0 0
1 1 6 0 0 17
1 5 8 0 1 0 0 0
2
2 1 c 0 d0 41 3 a 0 0 0 0
1 1 6 0 0 17
1 5 8 0 2 0 0 0
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);