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