On 2021-11-25 5:22 a.m., Ted Bullock wrote: > On 2021-11-25 5:05 a.m., Mark Kettenis wrote: >> From: Ted Bullock <tbull...@comlore.com> >>> On 2021-11-25 3:55 a.m., Otto Moerbeek wrote: >>>>> + parent = OF_parent(handle); >>>> >>>> I think the OF_parent call can go inside the !strcmp(buf, "block") >>>> block. >>> >>> >>> I worried that the following re-assignment of the handle would cause >>> problems, so I chose an order of operations and placed the parent call >>> before this re-assignment. The reason for my concern is based on not >>> knowing the proper distinction between OF_finddevice and OF_open in the >>> boot prom itself (they are both kind of opaque to me and just send bits >>> for interpretation into the boot prom). >>> >>> if ((handle = OF_open(fname)) == -1) { >>> DNPRINTF(BOOT_D_OFDEV, "devopen: open of %s failed\n", fname); >>> return ENXIO; >>> } >>> >>> It's possible that there is no meaningful distinction between when >>> handle is re-assigned midway through the function, in which case you are >>> correct it could absolutely be moved later in the function call. >>> Notably there is quite a bit of variable re-use and re-purposing in the >>> devopen function so I chose the place I thought would be safest. >> >> I think you have a point. Might make sense to have a separate >> variables here. Probably best to keep using handle for the OF_open() >> result, and use "node" or "dhandle" for the OF_finddevice() result. >> > > More to the point I just went to test since I was now awake and thinking > about the problem some more and moving the call to OF_parent past the > reassignment with OF_open does indeed break booting. I presume that the > handle return value is contextually entirely different between > OF_finddevice and OF_open.
I deliberately left the call to OF_parent earlier in the function. This can be moved closer to the IDE comparison logic only if the variable handle isn't re-assigned. Maybe do this in a future patch. Also I left the query to name rather than device_type because it seems more correct from my reading of the ieee1275 spec. The device tree in OF uses the name as the identifier in the tree, not the device_type. I do agree that checking if the parent exists is more correct and I have done that. This patch currently works for me. Index: arch/sparc64/stand/ofwboot/ofdev.c =================================================================== RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/ofdev.c,v retrieving revision 1.31 diff -u -p -u -p -r1.31 ofdev.c --- arch/sparc64/stand/ofwboot/ofdev.c 9 Dec 2020 18:10:19 -0000 1.31 +++ arch/sparc64/stand/ofwboot/ofdev.c 25 Nov 2021 22:04:01 -0000 @@ -520,7 +520,7 @@ devopen(struct open_file *of, const char char fname[256]; char buf[DEV_BSIZE]; struct disklabel label; - int handle, part; + int handle, part, parent; int error = 0; #ifdef SOFTRAID char volno; @@ -649,6 +649,9 @@ devopen(struct open_file *of, const char #endif if ((handle = OF_finddevice(fname)) == -1) return ENOENT; + + parent = OF_parent(handle); + DNPRINTF(BOOT_D_OFDEV, "devopen: found %s\n", fname); if (OF_getprop(handle, "name", buf, sizeof buf) < 0) return ENXIO; @@ -685,6 +688,17 @@ devopen(struct open_file *of, const char of->f_dev = devsw; of->f_devdata = &ofdev; + + /* Some PROMS have bugged writing code for ide block devices */ + if (parent && + OF_getprop(parent, "name", buf, sizeof buf) > 0 && + !strcmp(buf, "ide")) + { + DNPRINTF(BOOT_D_OFDEV, + "devopen: Disable writing for IDE block device\n"); + of->f_flags |= F_NOWRITE; + } + #ifdef SPARC_BOOT_UFS bcopy(&file_system_ufs, &file_system[nfsys++], sizeof file_system[0]); bcopy(&file_system_ufs2, &file_system[nfsys++], sizeof file_system[0]); Index: arch/sparc64/stand/ofwboot/vers.c =================================================================== RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/vers.c,v retrieving revision 1.22 diff -u -p -u -p -r1.22 vers.c --- arch/sparc64/stand/ofwboot/vers.c 9 Dec 2020 18:10:19 -0000 1.22 +++ arch/sparc64/stand/ofwboot/vers.c 25 Nov 2021 22:04:01 -0000 @@ -1 +1 @@ -const char version[] = "1.21"; +const char version[] = "1.22"; Index: lib/libsa/fchmod.c =================================================================== RCS file: /cvs/src/sys/lib/libsa/fchmod.c,v retrieving revision 1.1 diff -u -p -u -p -r1.1 fchmod.c --- lib/libsa/fchmod.c 3 Aug 2019 15:22:17 -0000 1.1 +++ lib/libsa/fchmod.c 25 Nov 2021 22:04:03 -0000 @@ -53,6 +53,11 @@ fchmod(int fd, mode_t m) errno = EOPNOTSUPP; return (-1); } + /* writing is broken or unsupported */ + if (f->f_flags & F_NOWRITE) { + errno = EOPNOTSUPP; + return (-1); + } errno = (f->f_ops->fchmod)(f, m); return (0); Index: lib/libsa/stand.h =================================================================== RCS file: /cvs/src/sys/lib/libsa/stand.h,v retrieving revision 1.71 diff -u -p -u -p -r1.71 stand.h --- lib/libsa/stand.h 24 Oct 2021 17:49:19 -0000 1.71 +++ lib/libsa/stand.h 25 Nov 2021 22:04:03 -0000 @@ -107,10 +107,11 @@ struct open_file { extern struct open_file files[]; /* f_flags values */ -#define F_READ 0x0001 /* file opened for reading */ -#define F_WRITE 0x0002 /* file opened for writing */ -#define F_RAW 0x0004 /* raw device open - no file system */ -#define F_NODEV 0x0008 /* network open - no device */ +#define F_READ 0x0001 /* file opened for reading */ +#define F_WRITE 0x0002 /* file opened for writing */ +#define F_RAW 0x0004 /* raw device open - no file system */ +#define F_NODEV 0x0008 /* network open - no device */ +#define F_NOWRITE 0x0010 /* bootblock writing broken or unsupported */ #define isupper(c) ((c) >= 'A' && (c) <= 'Z') #define islower(c) ((c) >= 'a' && (c) <= 'z') -- Ted Bullock <tbull...@comlore.com>