Skip site navigation (1)Skip section navigation (2)
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>