Subject: re: Using same com.c driver for two devices that access serial port differently?
To: Ignatios Souvatzis <is@netbsd.org>
From: matthew green <mrg@eterna.com.au>
List: tech-kern
Date: 06/26/2003 15:12:48
On Wed, Jun 25, 2003 at 11:22:27PM +0000, Ian Zagorskih wrote:
> ---cut ---
> #define bus_space_read_1(t, h, o) \
> ((t) == I386_BUS_SPACE_IO ? (inb((h) + (o))) : \
> ((t) == MY_BUS_SPACE) ? (my_bus_read_1((t), (h), (o))) : \
> ((t) == YOUR_BUS_SPACE) ? (your_bus_read_1((t), (h), (o))) : \
> ((t) == HIS_BUS_SPACE) ? (his_bus_read_1((t), (h), (o))) : \
> (*(volatile u_int8_t *)((h) + (o))))
> ---cut ---
>
> but this dosn't seems to be good nor elegant for me. Or i missed something ?
Use an array of function pointers for the access types, maybe, pointed to
by the bus space tag. I don't know how bad this would be for i386
performance; I had to do it this way for Amiga.
The other solution - would be to rewrite com.c to take an array of offsets;
this way only com.c would be penalized.
i think this comes down to a discussion that occured a year or so
ago[1] - for a similar issue. to solve it properly, bus_space macros
need to be overridable on a per-bus driver basis, and as per-bus
drivers can be MI it really involves changing the definition of
<machine/bus.h>... i recently had to solve a similar (it was
endianness rather than sparse addressing) on the sparc port and
my solution was to change the bus_space macro's into inline functions
that basically look like this:
static __inline__ u_int8_t
bus_space_read_1(t, h, o)
bus_space_tag_t t;
bus_space_handle_t h;
bus_size_t o;
{
return t->sparc_read_1 ?
(*t->sparc_read_1)(t, h, o) :
bus_space_read_1_real(t, h, o);
}
where bus_space_read_1_real is defined as the previous version
(which is a simple direct accessor.) this basically just turns
a direct access into a test and access in the normal case and
a function call in the special case. expecting this to have a
slight but noticable effect i benchmarked this and i found that
the variance in my testing usually outweighed any negative
impact so far that often the "new should be slower" kernel was
faster more than not. testing run on a sparc classic.
perhaps this is the way we should go for a truly "generic" bus
space that deal with these cases... i'm not sure. i don't know
how expensive the memory accesses (probably two of them) and
the test are...
.mrg.
[1] - this was about creating a <sys/bus.h> ? i forget...