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
This commit is contained in:
parent
c0347e182c
commit
5a75fc4b11
@ -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;
|
||||
|
@ -27,18 +27,14 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct uboot_devdesc {
|
||||
struct devdesc dd; /* Must be first. */
|
||||
union {
|
||||
struct {
|
||||
int slice;
|
||||
int partition;
|
||||
off_t offset;
|
||||
} disk;
|
||||
} d_kind;
|
||||
};
|
||||
#include <disk.h>
|
||||
|
||||
#define d_disk d_kind.disk
|
||||
struct uboot_devdesc {
|
||||
union {
|
||||
struct devdesc dd;
|
||||
struct disk_devdesc d_disk;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Default network packet alignment in memory. On arm arches packets must be
|
||||
|
Loading…
Reference in New Issue
Block a user