diff options
author | Ian Lepore <ian@FreeBSD.org> | 2019-02-18 04:44:52 +0000 |
---|---|---|
committer | Ian Lepore <ian@FreeBSD.org> | 2019-02-18 04:44:52 +0000 |
commit | 5a75fc4b11cb31ff90e0f4a93292861e26320ab3 (patch) | |
tree | 02dd88752b8b6d62f3d0366605cb52d30cc43aa4 /stand/uboot | |
parent | c0347e182cc23853aaca05004d2da9b4d7e47e4a (diff) | |
download | src-test-5a75fc4b11cb31ff90e0f4a93292861e26320ab3.tar.gz src-test-5a75fc4b11cb31ff90e0f4a93292861e26320ab3.zip |
Make uboot_devdesc properly alias disk_devdesc, so that parsing the u-boot
loaderdev variable works correctly.
The uboot_devdesc struct is variously cast back and forth between
uboot_devdesc and disk_devdesc as pointers are handed off through various
opaque interfaces. uboot_devdesc attempted to mimic the layout of
disk_devdesc by having a devdesc struct, followed by a union of some
device-specific stuff that included a struct that contains the same fields
as a disk_devdesc. However, one of those fields inside the struct is 64-bit
which causes the entire union to be 64-bit aligned -- 32 bits of padding
is added between the struct devdesc and the union, so the whole mess ends
up NOT properly mimicking a disk_devdesc after all. (In disk_devdesc there
is also 32 bits of padding, but it shows up immediately before the d_offset
field, rather than before the whole collection of d_* fields.)
This fixes the problem by using an anonymous union to overlay the devdesc
field uboot network devices need with the disk_devdesc that uboot storage
devices need. This is a different solution than the one contributed with
the PR (so if anything goes wrong, the blame goes to me), but 95% of the
credit for this fix goes to Pawel Worach and Manuel Stuhn who analyzed the
problem and proposed a fix.
PR: 233097
Notes
Notes:
svn path=/head/; revision=344247
Diffstat (limited to 'stand/uboot')
-rw-r--r-- | stand/uboot/common/main.c | 12 | ||||
-rw-r--r-- | stand/uboot/lib/libuboot.h | 14 |
2 files changed, 11 insertions, 15 deletions
diff --git a/stand/uboot/common/main.c b/stand/uboot/common/main.c index 50a12cd425fb0..b1534b00d2683 100644 --- a/stand/uboot/common/main.c +++ b/stand/uboot/common/main.c @@ -310,13 +310,13 @@ print_disk_probe_info() char slice[32]; char partition[32]; - if (currdev.d_disk.slice > 0) - sprintf(slice, "%d", currdev.d_disk.slice); + if (currdev.d_disk.d_slice > 0) + sprintf(slice, "%d", currdev.d_disk.d_slice); else strcpy(slice, "<auto>"); - if (currdev.d_disk.partition >= 0) - sprintf(partition, "%d", currdev.d_disk.partition); + if (currdev.d_disk.d_partition >= 0) + sprintf(partition, "%d", currdev.d_disk.d_partition); else strcpy(partition, "<auto>"); @@ -332,8 +332,8 @@ probe_disks(int devidx, int load_type, int load_unit, int load_slice, int open_result, unit; struct open_file f; - currdev.d_disk.slice = load_slice; - currdev.d_disk.partition = load_partition; + currdev.d_disk.d_slice = load_slice; + currdev.d_disk.d_partition = load_partition; f.f_devdata = &currdev; open_result = -1; diff --git a/stand/uboot/lib/libuboot.h b/stand/uboot/lib/libuboot.h index 8b81486b1fae9..59438e711a652 100644 --- a/stand/uboot/lib/libuboot.h +++ b/stand/uboot/lib/libuboot.h @@ -27,19 +27,15 @@ * $FreeBSD$ */ +#include <disk.h> + struct uboot_devdesc { - struct devdesc dd; /* Must be first. */ union { - struct { - int slice; - int partition; - off_t offset; - } disk; - } d_kind; + struct devdesc dd; + struct disk_devdesc d_disk; + }; }; -#define d_disk d_kind.disk - /* * Default network packet alignment in memory. On arm arches packets must be * aligned to cacheline boundaries. |