Subject: Re: bus_spacing a FreeBSD driver
To: Eduardo E. Horvath <eeh@one-o.com>
From: Chris G. Demetriou <cgd@netbsd.org>
List: tech-kern
Date: 09/11/1998 17:27:49
"Eduardo E. Horvath" <eeh@one-o.com> writes:

> You should be able to get away with structures if:
> 
> You make sure you use absolute types.  Different ports have different
> sizeof(long). 
> 
> You place pad fields in every hole so you don't rely on the compiler
> padding for you.  Always do:
> [ ... ]

> You do not use bitfields (which this particular FreeBSD driver obviously
> uses).
> 
> You only use the structure to dereference device registers through a
> bus_space* accessor, never directly:
> 
> 	bus_space_read1(tag, &foo_ptr->foo_field, ...)

Uh, that's not going to work; you need a handle, then an offset from a
handle.  that handle can be gotten via offsetof or an equivalent, but
it's not quite as easy as you've incidated.

> Never split a register into different fields in a structure.  If it's a
> 16-bit register always access it through a 16-bit structure field, even if
> you only want to deal with only 8-bits of that register.  Otherwise you
> may have endianness problems.


There's one other case:

A region which has been mapped with BUS_SPACE_MAP_LINEAR.

In that case, that region should act just like normal memory.

_HOWEVER_, reliance on BUS_SPACE_MAP_LINEAR is a very bad thing to do,
because it may not be supported, or even supportable, for a given
architecture, space type, or memory region.

If you want a driver that is correctly written, you should use
BUS_SPACE_MAP_LINEAR if you insist on using structures and direct
acces.  However, that correctly-written driver still don't be very
portable.  8-)



cgd