Date: Thu, 1 Mar 2001 18:20:50 +1100 (EST) From: Bruce Evans <bde@zeta.org.au> To: Matthew Jacob <mjacob@feral.com> Cc: arch@FreeBSD.ORG Subject: Re: lossage of a sort with using device hints... Message-ID: <Pine.BSF.4.21.0103011719200.1753-100000@besplex.bde.org> In-Reply-To: <Pine.LNX.4.21.0102281058400.3645-100000@zeppo.feral.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 28 Feb 2001, Matthew Jacob wrote: > It's actually worse for me.... > > setting > > hint.isp.0.portwnn="0x50000000aaaa0000" > hint.isp.0.nodewnn="0x50000000aaaa0001" > > guarantees me to be broken in that this will be forced to be type 'int' or > type 'long'- and neither will correctly convert- and I can't even coerce this > directly to a string- so I have to do something like: I think it is not fundamentally broken for type 'long' on machines with >=64 bit longs, but subr_bus.c:resource_find_hard() is missing support for longs. It uses strtoul() to convert the string to a number and then blindly assigns the number to an int. It also ignores range errors reported by strtoul(), of course. There may also be sign extension problems. There are no resource types for unsigned C types, so longs are abused to hold u_longs, etc. This probably works on 2's-complement machines. There are also problems with initializing the union in `struct config_resource'. We put `longval' first because C90 only supports initializing the first member of a union and we want to initialize as many bits as possible, but longs might be too small to represent pointers or too large to represent pointers as initializers (the gnu toolchain can't handle converting 32-bit pointers to 64-bit ints). I use the following "fix": --- Index: bus_private.h =================================================================== RCS file: /home/ncvs/src/sys/sys/bus_private.h,v retrieving revision 1.17 diff -c -1 -r1.17 bus_private.h *** bus_private.h 2000/11/09 10:21:23 1.17 --- bus_private.h 2000/11/10 09:57:19 *************** *** 68,70 **** union { ! long longval; int intval; --- 68,70 ---- union { ! intptr_t longval; /* sic */ int intval; --- > hint.isp.0.portwnn="w50000000aaaa0000" > hint.isp.0.nodewnn="w50000000aaaa0001" > > in order to get the string so I can then do a kernel strtouq on the portion > past the 'w'... *phppptttttt* Try changing resource_find_hard() to produce a RES_LONG instead of a RES_INT. > > > > I'm converting a driver over to using device hints instead of > > getenv_*, and one thing has stubbed my toe. The current resource types are: > > > > > > /* > > * Resources from config(8). > > */ > > typedef enum { > > RES_INT, RES_STRING, RES_LONG > > } resource_type; > > > > But I've been happily using a getenv_quad for a 64 bit WWN override. > > > > It strikes me that RES_INT and RES_LONG are too vague (as well as useless). > > How hard would it be to change these to RES_INT32 and RES_INT64? Fairly hard, and backwards. You would have to fix the abovementioned problems in the gnu toolchain for RES_INT64 to work right on i386's. Fixed-width types are even less appropriate than int/long in most places, including here. Non-vague types would be typedefed types like vm_offset_t for memory addresses, etc. I think we don't need fully typedefed types for hints (just use uintmax_t for all numeric values), but they might be worth it for resource_foo_t_value(). BTW, resource_long_value() isn't used anywhere. This is probably an i386ism (resource_long_value() is useless when sizeof(int) == sizeof(long)). This is a bug in "machine-independent" code link /sys/isa/isahint.c (it uses resource_int_value() for memory addresses...). Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0103011719200.1753-100000>