Subject: Addition of two bus_*() functions
To: None <tech-kern@NetBSD.ORG>
From: Charles M. Hannum <mycroft@mit.edu>
List: tech-kern
Date: 05/17/1996 21:06:36
I will be adding two new bus_*() functions, as follows:

int bus_io_subregion __P((bus_chipset_tag_t bc, bus_io_handle_t ioh,
	bus_io_size_t offset, bus_io_size_t size, bus_io_handle_t *nioh));
int bus_mem_subregion __P((bus_chipset_tag_t bc, bus_mem_handle_t memh,
	bus_mem_size_t offset, bus_mem_size_t size, bus_mem_handle_t *nmemh));

These functions take the existing handle `ioh' (`memh') and create a
new handle `nioh' (`nmemh') which can be passed to any of the
bus_{io,mem}_{read,write}_*() functions.  Using the new handle is
equivalent to using the old handle and adding the specified offset to
the offset argument of the bus_{io,mem}_{read,write}_*() calls.

When the old handle is unmapped, in addition to that I/O (memory)
handle becoming invalid, all I/O (memory) handles of all subregions of
the old handle also become invalid.  Thus there is no explicit
mechanism for unmapping a subregion.

For example, assuming that all of the calls succeed, this sequence:

bus_io_map(bc, PORT, SIZE, &ioh);
bus_io_subregion(bc, ioh, FOO, SIZE - FOO, &nioh);
DATA1 = bus_io_read_1(bc, nioh, OFFSET1);
bus_io_write_1(bc, nioh, OFFSET2, DATA2);
bus_io_unmap(bc, ioh, SIZE);

is equivalent to:

bus_io_map(bc, PORT, SIZE, &ioh);
DATA1 = bus_io_read_1(bc, ioh, FOO + OFFSET1);
bus_io_write_1(bc, ioh, FOO + OFFSET2, DATA2);
bus_io_unmap(bc, ioh, SIZE);

Like the bus_{io,mem}_map() functions, the bus_{io,mem}_subregion()
functions return zero on success and non-zero on failure.


Implementation notes:

It is expected that most implementations will handle these functions
by simply adding an offset to some part of the bus_{io,mem}_handle_t.
The `size' argument and the return value are mainly intended for the
use of additional error checking code.

If it is excessively difficult to `simply add an offset' to an I/O or
memory address on some architecture, the implementor may choose to
fall back to inserting an offset into each handle, which will be
initialized to 0 by bus_{io,mem}_map() and will be adjusted as
appropriate by bus_{io,mem}_subregion().  The author is not aware of
any specific cases where this should be necessary.