bus.h revision 116541
180708Sjake/*-
286228Stmm * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
380708Sjake * All rights reserved.
480708Sjake *
586228Stmm * This code is derived from software contributed to The NetBSD Foundation
686228Stmm * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
786228Stmm * NASA Ames Research Center.
886228Stmm *
980708Sjake * Redistribution and use in source and binary forms, with or without
1080708Sjake * modification, are permitted provided that the following conditions
1180708Sjake * are met:
1280708Sjake * 1. Redistributions of source code must retain the above copyright
1380708Sjake *    notice, this list of conditions and the following disclaimer.
1480708Sjake * 2. Redistributions in binary form must reproduce the above copyright
1580708Sjake *    notice, this list of conditions and the following disclaimer in the
1680708Sjake *    documentation and/or other materials provided with the distribution.
1786228Stmm * 3. All advertising materials mentioning features or use of this software
1886228Stmm *    must display the following acknowledgement:
1986228Stmm *	This product includes software developed by the NetBSD
2086228Stmm *	Foundation, Inc. and its contributors.
2186228Stmm * 4. Neither the name of The NetBSD Foundation nor the names of its
2286228Stmm *    contributors may be used to endorse or promote products derived
2386228Stmm *    from this software without specific prior written permission.
2480708Sjake *
2586228Stmm * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2686228Stmm * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2786228Stmm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2886228Stmm * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2986228Stmm * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3086228Stmm * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3186228Stmm * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3286228Stmm * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3386228Stmm * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3486228Stmm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3586228Stmm * POSSIBILITY OF SUCH DAMAGE.
3686228Stmm */
3786228Stmm/*
3886228Stmm * Copyright (c) 1997-1999 Eduardo E. Horvath. All rights reserved.
3986228Stmm * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
4086228Stmm * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
4180708Sjake *
4286228Stmm * Redistribution and use in source and binary forms, with or without
4386228Stmm * modification, are permitted provided that the following conditions
4486228Stmm * are met:
4586228Stmm * 1. Redistributions of source code must retain the above copyright
4686228Stmm *    notice, this list of conditions and the following disclaimer.
4786228Stmm * 2. Redistributions in binary form must reproduce the above copyright
4886228Stmm *    notice, this list of conditions and the following disclaimer in the
4986228Stmm *    documentation and/or other materials provided with the distribution.
5086228Stmm * 3. All advertising materials mentioning features or use of this software
5186228Stmm *    must display the following acknowledgement:
5286228Stmm *      This product includes software developed by Christopher G. Demetriou
5386228Stmm *	for the NetBSD Project.
5486228Stmm * 4. The name of the author may not be used to endorse or promote products
5586228Stmm *    derived from this software without specific prior written permission
5686228Stmm *
5786228Stmm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
5886228Stmm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5986228Stmm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
6086228Stmm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
6186228Stmm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
6286228Stmm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
6386228Stmm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
6486228Stmm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6586228Stmm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
6686228Stmm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6786228Stmm *
6886228Stmm * 	from: NetBSD: bus.h,v 1.28 2001/07/19 15:32:19 thorpej Exp
6986228Stmm *	and
7086228Stmm *	from: FreeBSD: src/sys/alpha/include/bus.h,v 1.9 2001/01/09
7186228Stmm *
7280708Sjake * $FreeBSD: head/sys/sparc64/include/bus.h 116541 2003-06-18 16:41:36Z tmm $
7380708Sjake */
7480708Sjake
7580708Sjake#ifndef	_MACHINE_BUS_H_
7680708Sjake#define	_MACHINE_BUS_H_
7780708Sjake
7890615Stmm#ifdef BUS_SPACE_DEBUG
7990615Stmm#include <sys/ktr.h>
8090615Stmm#endif
8190615Stmm
8286228Stmm#include <machine/cpufunc.h>
8390615Stmm#include <machine/upa.h>
8480708Sjake
8586228Stmm/*
8686228Stmm * UPA and SBUS spaces are non-cached and big endian
8786228Stmm * (except for RAM and PROM)
8886228Stmm *
8986228Stmm * PCI spaces are non-cached and little endian
9086228Stmm */
9186228Stmm#define	UPA_BUS_SPACE		0
9286228Stmm#define	SBUS_BUS_SPACE		1
9386228Stmm#define	PCI_CONFIG_BUS_SPACE	2
9486228Stmm#define	PCI_IO_BUS_SPACE	3
9586228Stmm#define	PCI_MEMORY_BUS_SPACE	4
9686228Stmm#define	LAST_BUS_SPACE		5
9786228Stmm
9886228Stmmextern int bus_type_asi[];
9986228Stmmextern int bus_stream_asi[];
10086228Stmm
10186228Stmm#define __BUS_SPACE_HAS_STREAM_METHODS	1
10286228Stmm
10386228Stmm/*
10486228Stmm * Bus address and size types
10586228Stmm */
10686228Stmmtypedef	u_long		bus_space_handle_t;
10786228Stmmtypedef int		bus_type_t;
10886228Stmmtypedef u_long		bus_addr_t;
10986228Stmmtypedef u_long		bus_size_t;
11086228Stmm
11186228Stmm#define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
11286228Stmm#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
113111524Smux#define BUS_SPACE_MAXSIZE	0xFFFFFFFFFFFFFFFF
11486228Stmm#define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
11586228Stmm#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
11686228Stmm#define BUS_SPACE_MAXADDR	0xFFFFFFFF
11786228Stmm
11886228Stmm#define BUS_SPACE_UNRESTRICTED	(~0UL)
11986228Stmm
12086228Stmm/*
12186228Stmm * Access methods for bus resources and address space.
12286228Stmm */
12386228Stmmtypedef struct bus_space_tag	*bus_space_tag_t;
12486228Stmm
12586228Stmmstruct bus_space_tag {
126108815Stmm	void		*bst_cookie;
127108815Stmm	bus_space_tag_t	bst_parent;
128108815Stmm	int		bst_type;
12986228Stmm
130108815Stmm	void		(*bst_bus_barrier)(bus_space_tag_t, bus_space_handle_t,
13193052Stmm	    bus_size_t, bus_size_t, int);
13286228Stmm};
13386228Stmm
13486228Stmm/*
13586228Stmm * Bus space function prototypes.
13686228Stmm */
13793052Stmmstatic void bus_space_barrier(bus_space_tag_t, bus_space_handle_t, bus_size_t,
13893052Stmm    bus_size_t, int);
139108917Sjakestatic int bus_space_subregion(bus_space_tag_t, bus_space_handle_t,
140108917Sjake    bus_size_t, bus_size_t, bus_space_handle_t *);
141111347Sobrien/*
142111347Sobrien * Unmap a region of device bus space.
143111347Sobrien */
144111347Sobrienstatic __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
145111347Sobrien				     bus_size_t size);
14686228Stmm
147111347Sobrienstatic __inline void
148111347Sobrienbus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
149111347Sobrien		bus_size_t size __unused)
150111347Sobrien{
151111347Sobrien}
152111347Sobrien
15386228Stmm/* This macro finds the first "upstream" implementation of method `f' */
15493052Stmm#define _BS_CALL(t,f)							\
15593052Stmm	while (t->f == NULL)						\
156108815Stmm		t = t->bst_parent;						\
15786228Stmm	return (*(t)->f)
15886228Stmm
15993052Stmmstatic __inline void
16093052Stmmbus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
16193052Stmm    bus_size_t s, int f)
16286228Stmm{
163108815Stmm	_BS_CALL(t, bst_bus_barrier)(t, h, o, s, f);
16486228Stmm}
16586228Stmm
166108917Sjakestatic __inline int
167108917Sjakebus_space_subregion(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
168108917Sjake    bus_size_t s, bus_space_handle_t *hp)
169108917Sjake{
170108917Sjake	*hp = h + o;
171108917Sjake	return (0);
172108917Sjake}
173108917Sjake
17486228Stmm/* flags for bus space map functions */
17586228Stmm#define BUS_SPACE_MAP_CACHEABLE		0x0001
17686228Stmm#define BUS_SPACE_MAP_LINEAR		0x0002
17786228Stmm#define BUS_SPACE_MAP_READONLY		0x0004
17886228Stmm#define BUS_SPACE_MAP_PREFETCHABLE	0x0008
17986228Stmm/* placeholders for bus functions... */
18086228Stmm#define BUS_SPACE_MAP_BUS1		0x0100
18186228Stmm#define BUS_SPACE_MAP_BUS2		0x0200
18286228Stmm#define BUS_SPACE_MAP_BUS3		0x0400
18386228Stmm#define BUS_SPACE_MAP_BUS4		0x0800
18486228Stmm
18586228Stmm/* flags for bus_space_barrier() */
18686228Stmm#define	BUS_SPACE_BARRIER_READ		0x01	/* force read barrier */
18786228Stmm#define	BUS_SPACE_BARRIER_WRITE		0x02	/* force write barrier */
18886228Stmm
18990615Stmm#ifdef BUS_SPACE_DEBUG
19090615Stmm#define	KTR_BUS				KTR_CT2
19190615Stmm#define	BUS_HANDLE_MIN			UPA_MEMSTART
19290615Stmm#define	__BUS_DEBUG_ACCESS(h, o, desc, sz) do {				\
19390615Stmm	CTR4(KTR_BUS, "bus space: %s %d: handle %#lx, offset %#lx",	\
19490615Stmm	    (desc), (sz), (h), (o));					\
19590615Stmm	if ((h) + (o) < BUS_HANDLE_MIN)					\
19690615Stmm		panic("bus space access at %#lx out of range",		\
19790615Stmm		    (h) + (o));						\
19890615Stmm} while (0)
19990615Stmm#else
20090615Stmm#define	__BUS_DEBUG_ACCESS(h, o, desc, sz)
20190615Stmm#endif
20290615Stmm
203104304Sjakestatic __inline uint8_t
204104304Sjakebus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
205104304Sjake{
20686228Stmm
207104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read", 1);
208108815Stmm	return (lduba_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
209104304Sjake}
21086228Stmm
211104304Sjakestatic __inline uint16_t
212104304Sjakebus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
213104304Sjake{
21486228Stmm
215104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read", 2);
216108815Stmm	return (lduha_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
217104304Sjake}
21886228Stmm
219104304Sjakestatic __inline uint32_t
220104304Sjakebus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
221104304Sjake{
22286228Stmm
223104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read", 4);
224108815Stmm	return (lduwa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
225104304Sjake}
22686228Stmm
227104304Sjakestatic __inline uint64_t
228104304Sjakebus_space_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
229104304Sjake{
23086228Stmm
231104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read", 8);
232108815Stmm	return (ldxa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type]));
233104304Sjake}
23486228Stmm
235104304Sjakestatic __inline void
236104304Sjakebus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
237104304Sjake    uint8_t *a, size_t c)
238104304Sjake{
23986228Stmm
240104304Sjake	while (c-- > 0)
241104304Sjake		*a++ = bus_space_read_1(t, h, o);
242104304Sjake}
24386228Stmm
244104304Sjakestatic __inline void
245104304Sjakebus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
246104304Sjake    uint16_t *a, size_t c)
247104304Sjake{
24886228Stmm
249104304Sjake	while (c-- > 0)
250104304Sjake		*a++ = bus_space_read_2(t, h, o);
251104304Sjake}
25286228Stmm
253104304Sjakestatic __inline void
254104304Sjakebus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
255104304Sjake    uint32_t *a, size_t c)
256104304Sjake{
25786228Stmm
258104304Sjake	while (c-- > 0)
259104304Sjake		*a++ = bus_space_read_4(t, h, o);
260104304Sjake}
26186228Stmm
262104304Sjakestatic __inline void
263104304Sjakebus_space_read_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
264104304Sjake    uint64_t *a, size_t c)
265104304Sjake{
26686228Stmm
267104304Sjake	while (c-- > 0)
268104304Sjake		*a++ = bus_space_read_8(t, h, o);
269104304Sjake}
27086228Stmm
271104304Sjakestatic __inline void
272104304Sjakebus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
273104304Sjake    uint8_t v)
274104304Sjake{
27586228Stmm
276104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write", 1);
277108815Stmm	stba_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
278104304Sjake}
27986228Stmm
280104304Sjakestatic __inline void
281104304Sjakebus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
282104304Sjake    uint16_t v)
283104304Sjake{
28486228Stmm
285104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write", 2);
286108815Stmm	stha_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
287104304Sjake}
28886228Stmm
28993052Stmmstatic __inline void
290104304Sjakebus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
291104304Sjake    uint32_t v)
292104304Sjake{
293104304Sjake
294104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write", 4);
295108815Stmm	stwa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
296104304Sjake}
297104304Sjake
298104304Sjakestatic __inline void
299104304Sjakebus_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
300104304Sjake    uint64_t v)
301104304Sjake{
302104304Sjake
303104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write", 8);
304108815Stmm	stxa_nc((caddr_t)(h + o), bus_type_asi[t->bst_type], v);
305104304Sjake}
306104304Sjake
307104304Sjakestatic __inline void
308104304Sjakebus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
309104304Sjake    uint8_t *a, size_t c)
310104304Sjake{
311104304Sjake
312104304Sjake	while (c-- > 0)
313104304Sjake		bus_space_write_1(t, h, o, *a++);
314104304Sjake}
315104304Sjake
316104304Sjakestatic __inline void
317104304Sjakebus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
318104304Sjake    uint16_t *a, size_t c)
319104304Sjake{
320104304Sjake
321104304Sjake	while (c-- > 0)
322104304Sjake		bus_space_write_2(t, h, o, *a++);
323104304Sjake}
324104304Sjake
325104304Sjakestatic __inline void
326104304Sjakebus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
327104304Sjake    uint32_t *a, size_t c)
328104304Sjake{
329104304Sjake
330104304Sjake	while (c-- > 0)
331104304Sjake		bus_space_write_4(t, h, o, *a++);
332104304Sjake}
333104304Sjake
334104304Sjakestatic __inline void
335104304Sjakebus_space_write_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
336104304Sjake    uint64_t *a, size_t c)
337104304Sjake{
338104304Sjake
339104304Sjake	while (c-- > 0)
340104304Sjake		bus_space_write_8(t, h, o, *a++);
341104304Sjake}
342104304Sjake
343104304Sjakestatic __inline void
344104304Sjakebus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
345104304Sjake    uint8_t v, size_t c)
346104304Sjake{
347104304Sjake
348104304Sjake	while (c-- > 0)
349104304Sjake		bus_space_write_1(t, h, o, v);
350104304Sjake}
351104304Sjake
352104304Sjakestatic __inline void
353104304Sjakebus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
354104304Sjake    uint16_t v, size_t c)
355104304Sjake{
356104304Sjake
357104304Sjake	while (c-- > 0)
358104304Sjake		bus_space_write_2(t, h, o, v);
359104304Sjake}
360104304Sjake
361104304Sjakestatic __inline void
362104304Sjakebus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
363104304Sjake    uint32_t v, size_t c)
364104304Sjake{
365104304Sjake
366104304Sjake	while (c-- > 0)
367104304Sjake		bus_space_write_4(t, h, o, v);
368104304Sjake}
369104304Sjake
370104304Sjakestatic __inline void
371104304Sjakebus_space_set_multi_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
372104304Sjake    uint64_t v, size_t c)
373104304Sjake{
374104304Sjake
375104304Sjake	while (c-- > 0)
376104304Sjake		bus_space_write_8(t, h, o, v);
377104304Sjake}
378104304Sjake
379104304Sjakestatic __inline void
38093052Stmmbus_space_read_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
38193052Stmm    u_int8_t *a, bus_size_t c)
38286228Stmm{
38386228Stmm	for (; c; a++, c--, o++)
38486228Stmm		*a = bus_space_read_1(t, h, o);
38586228Stmm}
38686228Stmm
38793052Stmmstatic __inline void
38893052Stmmbus_space_read_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
38993052Stmm    u_int16_t *a, bus_size_t c)
39086228Stmm{
39186228Stmm	for (; c; a++, c--, o+=2)
39286228Stmm		*a = bus_space_read_2(t, h, o);
39386228Stmm}
39486228Stmm
39593052Stmmstatic __inline void
39693052Stmmbus_space_read_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
39793052Stmm    u_int32_t *a, bus_size_t c)
39886228Stmm{
39986228Stmm	for (; c; a++, c--, o+=4)
40086228Stmm		*a = bus_space_read_4(t, h, o);
40186228Stmm}
40286228Stmm
40393052Stmmstatic __inline void
40493052Stmmbus_space_read_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
40593052Stmm    u_int64_t *a, bus_size_t c)
40686228Stmm{
40786228Stmm	for (; c; a++, c--, o+=8)
40886228Stmm		*a = bus_space_read_8(t, h, o);
40986228Stmm}
41086228Stmm
41193052Stmmstatic __inline void
41293052Stmmbus_space_write_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
41393052Stmm    const u_int8_t *a, bus_size_t c)
41486228Stmm{
41586228Stmm	for (; c; a++, c--, o++)
41686228Stmm		bus_space_write_1(t, h, o, *a);
41786228Stmm}
41886228Stmm
41993052Stmmstatic __inline void
42093052Stmmbus_space_write_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
42193052Stmm    const u_int16_t *a, bus_size_t c)
42286228Stmm{
42386228Stmm	for (; c; a++, c--, o+=2)
42486228Stmm		bus_space_write_2(t, h, o, *a);
42586228Stmm}
42686228Stmm
42793052Stmmstatic __inline void
42893052Stmmbus_space_write_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
42993052Stmm    const u_int32_t *a, bus_size_t c)
43086228Stmm{
43186228Stmm	for (; c; a++, c--, o+=4)
43286228Stmm		bus_space_write_4(t, h, o, *a);
43386228Stmm}
43486228Stmm
43593052Stmmstatic __inline void
43693052Stmmbus_space_write_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
43793052Stmm    const u_int64_t *a, bus_size_t c)
43886228Stmm{
43986228Stmm	for (; c; a++, c--, o+=8)
44086228Stmm		bus_space_write_8(t, h, o, *a);
44186228Stmm}
44286228Stmm
44393052Stmmstatic __inline void
44493052Stmmbus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
44593052Stmm    const u_int8_t v, bus_size_t c)
44686228Stmm{
44786228Stmm	for (; c; c--, o++)
44886228Stmm		bus_space_write_1(t, h, o, v);
44986228Stmm}
45086228Stmm
45193052Stmmstatic __inline void
45293052Stmmbus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
45393052Stmm    const u_int16_t v, bus_size_t c)
45486228Stmm{
45586228Stmm	for (; c; c--, o+=2)
45686228Stmm		bus_space_write_2(t, h, o, v);
45786228Stmm}
45886228Stmm
45993052Stmmstatic __inline void
46093052Stmmbus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
46193052Stmm    const u_int32_t v, bus_size_t c)
46286228Stmm{
46386228Stmm	for (; c; c--, o+=4)
46486228Stmm		bus_space_write_4(t, h, o, v);
46586228Stmm}
46686228Stmm
46793052Stmmstatic __inline void
46893052Stmmbus_space_set_region_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
46993052Stmm    const u_int64_t v, bus_size_t c)
47086228Stmm{
47186228Stmm	for (; c; c--, o+=8)
47286228Stmm		bus_space_write_8(t, h, o, v);
47386228Stmm}
47486228Stmm
47593052Stmmstatic __inline void
47693052Stmmbus_space_copy_region_1(bus_space_tag_t t, bus_space_handle_t h1,
47793052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
47886228Stmm{
47986228Stmm	for (; c; c--, o1++, o2++)
48086228Stmm	    bus_space_write_1(t, h1, o1, bus_space_read_1(t, h2, o2));
48186228Stmm}
48286228Stmm
48393052Stmmstatic __inline void
48493052Stmmbus_space_copy_region_2(bus_space_tag_t t, bus_space_handle_t h1,
48593052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
48686228Stmm{
48786228Stmm	for (; c; c--, o1+=2, o2+=2)
48886228Stmm	    bus_space_write_2(t, h1, o1, bus_space_read_2(t, h2, o2));
48986228Stmm}
49086228Stmm
49193052Stmmstatic __inline void
49293052Stmmbus_space_copy_region_4(bus_space_tag_t t, bus_space_handle_t h1,
49393052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
49486228Stmm{
49586228Stmm	for (; c; c--, o1+=4, o2+=4)
49686228Stmm	    bus_space_write_4(t, h1, o1, bus_space_read_4(t, h2, o2));
49786228Stmm}
49886228Stmm
49993052Stmmstatic __inline void
50093052Stmmbus_space_copy_region_8(bus_space_tag_t t, bus_space_handle_t h1,
50193052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
50286228Stmm{
50386228Stmm	for (; c; c--, o1+=8, o2+=8)
50486228Stmm	    bus_space_write_8(t, h1, o1, bus_space_read_8(t, h2, o2));
50586228Stmm}
50686228Stmm
507104304Sjakestatic __inline uint8_t
508104304Sjakebus_space_read_stream_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
509104304Sjake{
51086228Stmm
511104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read stream", 1);
512108815Stmm	return (lduba_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
513104304Sjake}
51486228Stmm
515104304Sjakestatic __inline uint16_t
516104304Sjakebus_space_read_stream_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
517104304Sjake{
51886228Stmm
519104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read stream", 2);
520108815Stmm	return (lduha_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
521104304Sjake}
52286228Stmm
523104304Sjakestatic __inline uint32_t
524104304Sjakebus_space_read_stream_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
525104304Sjake{
52686228Stmm
527104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read stream", 4);
528108815Stmm	return (lduwa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
529104304Sjake}
53086228Stmm
531104304Sjakestatic __inline uint64_t
532104304Sjakebus_space_read_stream_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
533104304Sjake{
53486228Stmm
535104304Sjake	__BUS_DEBUG_ACCESS(h, o, "read stream", 8);
536108815Stmm	return (ldxa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type]));
537104304Sjake}
53886228Stmm
539104304Sjakestatic __inline void
540104304Sjakebus_space_read_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
541104304Sjake    bus_size_t o, uint8_t *a, size_t c)
542104304Sjake{
54386228Stmm
544104304Sjake	while (c-- > 0)
545104304Sjake		*a++ = bus_space_read_stream_1(t, h, o);
546104304Sjake}
54786228Stmm
548104304Sjakestatic __inline void
549104304Sjakebus_space_read_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
550104304Sjake    bus_size_t o, uint16_t *a, size_t c)
551104304Sjake{
55286228Stmm
553104304Sjake	while (c-- > 0)
554104304Sjake		*a++ = bus_space_read_stream_2(t, h, o);
555104304Sjake}
55686228Stmm
557104304Sjakestatic __inline void
558104304Sjakebus_space_read_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
559104304Sjake    bus_size_t o, uint32_t *a, size_t c)
560104304Sjake{
56186228Stmm
562104304Sjake	while (c-- > 0)
563104304Sjake		*a++ = bus_space_read_stream_4(t, h, o);
564104304Sjake}
56586228Stmm
566104304Sjakestatic __inline void
567104304Sjakebus_space_read_multi_stream_8(bus_space_tag_t t, bus_space_handle_t h,
568104304Sjake    bus_size_t o, uint64_t *a, size_t c)
569104304Sjake{
57086228Stmm
571104304Sjake	while (c-- > 0)
572104304Sjake		*a++ = bus_space_read_stream_8(t, h, o);
573104304Sjake}
57486228Stmm
575104304Sjakestatic __inline void
576104304Sjakebus_space_write_stream_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
577104304Sjake    uint8_t v)
578104304Sjake{
57986228Stmm
580104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write stream", 1);
581108815Stmm	stba_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
582104304Sjake}
58386228Stmm
584104304Sjakestatic __inline void
585104304Sjakebus_space_write_stream_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
586104304Sjake    uint16_t v)
587104304Sjake{
58886228Stmm
589104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write stream", 2);
590108815Stmm	stha_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
591104304Sjake}
59286228Stmm
59393052Stmmstatic __inline void
594104304Sjakebus_space_write_stream_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
595104304Sjake    uint32_t v)
596104304Sjake{
597104304Sjake
598104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write stream", 4);
599108815Stmm	stwa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
600104304Sjake}
601104304Sjake
602104304Sjakestatic __inline void
603104304Sjakebus_space_write_stream_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
604104304Sjake    uint64_t v)
605104304Sjake{
606104304Sjake
607104304Sjake	__BUS_DEBUG_ACCESS(h, o, "write stream", 8);
608108815Stmm	stxa_nc((caddr_t)(h + o), bus_stream_asi[t->bst_type], v);
609104304Sjake}
610104304Sjake
611104304Sjakestatic __inline void
612104304Sjakebus_space_write_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
613111383Sobrien    bus_size_t o, const uint8_t *a, size_t c)
614104304Sjake{
615104304Sjake
616104304Sjake	while (c-- > 0)
617104304Sjake		bus_space_write_stream_1(t, h, o, *a++);
618104304Sjake}
619104304Sjake
620104304Sjakestatic __inline void
621104304Sjakebus_space_write_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
622111353Sobrien    bus_size_t o, const uint16_t *a, size_t c)
623104304Sjake{
624104304Sjake
625104304Sjake	while (c-- > 0)
626104304Sjake		bus_space_write_stream_2(t, h, o, *a++);
627104304Sjake}
628104304Sjake
629104304Sjakestatic __inline void
630104304Sjakebus_space_write_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
631111383Sobrien    bus_size_t o, const uint32_t *a, size_t c)
632104304Sjake{
633104304Sjake
634104304Sjake	while (c-- > 0)
635104304Sjake		bus_space_write_stream_4(t, h, o, *a++);
636104304Sjake}
637104304Sjake
638104304Sjakestatic __inline void
639104304Sjakebus_space_write_multi_stream_8(bus_space_tag_t t, bus_space_handle_t h,
640111383Sobrien    bus_size_t o, const uint64_t *a, size_t c)
641104304Sjake{
642104304Sjake
643104304Sjake	while (c-- > 0)
644104304Sjake		bus_space_write_stream_8(t, h, o, *a++);
645104304Sjake}
646104304Sjake
647104304Sjakestatic __inline void
648104304Sjakebus_space_set_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
649104304Sjake    bus_size_t o, uint8_t v, size_t c)
650104304Sjake{
651104304Sjake
652104304Sjake	while (c-- > 0)
653104304Sjake		bus_space_write_stream_1(t, h, o, v);
654104304Sjake}
655104304Sjake
656104304Sjakestatic __inline void
657104304Sjakebus_space_set_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
658104304Sjake    bus_size_t o, uint16_t v, size_t c)
659104304Sjake{
660104304Sjake
661104304Sjake	while (c-- > 0)
662104304Sjake		bus_space_write_stream_2(t, h, o, v);
663104304Sjake}
664104304Sjake
665104304Sjakestatic __inline void
666104304Sjakebus_space_set_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
667104304Sjake    bus_size_t o, uint32_t v, size_t c)
668104304Sjake{
669104304Sjake
670104304Sjake	while (c-- > 0)
671104304Sjake		bus_space_write_stream_4(t, h, o, v);
672104304Sjake}
673104304Sjake
674104304Sjakestatic __inline void
675104304Sjakebus_space_set_multi_stream_8(bus_space_tag_t t, bus_space_handle_t h,
676104304Sjake    bus_size_t o, uint64_t v, size_t c)
677104304Sjake{
678104304Sjake
679104304Sjake	while (c-- > 0)
680104304Sjake		bus_space_write_stream_8(t, h, o, v);
681104304Sjake}
682104304Sjake
683104304Sjakestatic __inline void
68493052Stmmbus_space_read_region_stream_1(bus_space_tag_t t, bus_space_handle_t h,
68593052Stmm    bus_size_t o, u_int8_t *a, bus_size_t c)
68686228Stmm{
68786228Stmm	for (; c; a++, c--, o++)
68886228Stmm		*a = bus_space_read_stream_1(t, h, o);
68986228Stmm}
69086228Stmm
69193052Stmmstatic __inline void
69293052Stmmbus_space_read_region_stream_2(bus_space_tag_t t, bus_space_handle_t h,
69393052Stmm    bus_size_t o, u_int16_t *a, bus_size_t c)
69486228Stmm{
69586228Stmm	for (; c; a++, c--, o+=2)
69686228Stmm		*a = bus_space_read_stream_2(t, h, o);
69786228Stmm}
69886228Stmm
69993052Stmmstatic __inline void
70093052Stmmbus_space_read_region_stream_4(bus_space_tag_t t, bus_space_handle_t h,
70193052Stmm    bus_size_t o, u_int32_t *a, bus_size_t c)
70286228Stmm{
70386228Stmm	for (; c; a++, c--, o+=4)
70486228Stmm		*a = bus_space_read_stream_4(t, h, o);
70586228Stmm}
70686228Stmm
70793052Stmmstatic __inline void
70893052Stmmbus_space_read_region_stream_8(bus_space_tag_t t, bus_space_handle_t h,
70993052Stmm    bus_size_t o, u_int64_t *a, bus_size_t c)
71086228Stmm{
71186228Stmm	for (; c; a++, c--, o+=8)
71286228Stmm		*a = bus_space_read_stream_8(t, h, o);
71386228Stmm}
71486228Stmm
71593052Stmmstatic __inline void
71693052Stmmbus_space_write_region_stream_1(bus_space_tag_t t, bus_space_handle_t h,
71793052Stmm    bus_size_t o, const u_int8_t *a, bus_size_t c)
71886228Stmm{
71986228Stmm	for (; c; a++, c--, o++)
72086228Stmm		bus_space_write_stream_1(t, h, o, *a);
72186228Stmm}
72286228Stmm
72393052Stmmstatic __inline void
72493052Stmmbus_space_write_region_stream_2(bus_space_tag_t t, bus_space_handle_t h,
72593052Stmm    bus_size_t o, const u_int16_t *a, bus_size_t c)
72686228Stmm{
72786228Stmm	for (; c; a++, c--, o+=2)
72886228Stmm		bus_space_write_stream_2(t, h, o, *a);
72986228Stmm}
73086228Stmm
73193052Stmmstatic __inline void
73293052Stmmbus_space_write_region_stream_4(bus_space_tag_t t, bus_space_handle_t h,
73393052Stmm    bus_size_t o, const u_int32_t *a, bus_size_t c)
73486228Stmm{
73586228Stmm	for (; c; a++, c--, o+=4)
73686228Stmm		bus_space_write_stream_4(t, h, o, *a);
73786228Stmm}
73886228Stmm
73993052Stmmstatic __inline void
74093052Stmmbus_space_write_region_stream_8(bus_space_tag_t t, bus_space_handle_t h,
74193052Stmm    bus_size_t o, const u_int64_t *a, bus_size_t c)
74286228Stmm{
74386228Stmm	for (; c; a++, c--, o+=8)
74486228Stmm		bus_space_write_stream_8(t, h, o, *a);
74586228Stmm}
74686228Stmm
74793052Stmmstatic __inline void
74893052Stmmbus_space_set_region_stream_1(bus_space_tag_t t, bus_space_handle_t h,
74993052Stmm    bus_size_t o, const u_int8_t v, bus_size_t c)
75086228Stmm{
75186228Stmm	for (; c; c--, o++)
75286228Stmm		bus_space_write_stream_1(t, h, o, v);
75386228Stmm}
75486228Stmm
75593052Stmmstatic __inline void
75693052Stmmbus_space_set_region_stream_2(bus_space_tag_t t, bus_space_handle_t h,
75793052Stmm    bus_size_t o, const u_int16_t v, bus_size_t c)
75886228Stmm{
75986228Stmm	for (; c; c--, o+=2)
76086228Stmm		bus_space_write_stream_2(t, h, o, v);
76186228Stmm}
76286228Stmm
76393052Stmmstatic __inline void
76493052Stmmbus_space_set_region_stream_4(bus_space_tag_t t, bus_space_handle_t h,
76593052Stmm    bus_size_t o, const u_int32_t v, bus_size_t c)
76686228Stmm{
76786228Stmm	for (; c; c--, o+=4)
76886228Stmm		bus_space_write_stream_4(t, h, o, v);
76986228Stmm}
77086228Stmm
77193052Stmmstatic __inline void
77293052Stmmbus_space_set_region_stream_8(bus_space_tag_t t, bus_space_handle_t h,
77393052Stmm    bus_size_t o, const u_int64_t v, bus_size_t c)
77486228Stmm{
77586228Stmm	for (; c; c--, o+=8)
77686228Stmm		bus_space_write_stream_8(t, h, o, v);
77786228Stmm}
77886228Stmm
77993052Stmmstatic __inline void
78093052Stmmbus_space_copy_region_stream_1(bus_space_tag_t t, bus_space_handle_t h1,
78193052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
78286228Stmm{
78386228Stmm	for (; c; c--, o1++, o2++)
78486228Stmm	    bus_space_write_stream_1(t, h1, o1, bus_space_read_stream_1(t, h2,
78586228Stmm		o2));
78686228Stmm}
78786228Stmm
78893052Stmmstatic __inline void
78993052Stmmbus_space_copy_region_stream_2(bus_space_tag_t t, bus_space_handle_t h1,
79093052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
79186228Stmm{
79286228Stmm	for (; c; c--, o1+=2, o2+=2)
79386228Stmm	    bus_space_write_stream_2(t, h1, o1, bus_space_read_stream_2(t, h2,
79486228Stmm		o2));
79586228Stmm}
79686228Stmm
79793052Stmmstatic __inline void
79893052Stmmbus_space_copy_region_stream_4(bus_space_tag_t t, bus_space_handle_t h1,
79993052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
80086228Stmm{
80186228Stmm	for (; c; c--, o1+=4, o2+=4)
80286228Stmm	    bus_space_write_stream_4(t, h1, o1, bus_space_read_stream_4(t, h2,
80386228Stmm		o2));
80486228Stmm}
80586228Stmm
80693052Stmmstatic __inline void
80793052Stmmbus_space_copy_region_stream_8(bus_space_tag_t t, bus_space_handle_t h1,
80893052Stmm    bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)
80986228Stmm{
81086228Stmm	for (; c; c--, o1+=8, o2+=8)
81186228Stmm	    bus_space_write_stream_8(t, h1, o1, bus_space_read_8(t, h2, o2));
81286228Stmm}
81386228Stmm
81486228Stmm/* Back-compat functions for old ISA drivers */
81586228Stmmextern bus_space_tag_t isa_io_bt;
81686228Stmmextern bus_space_handle_t isa_io_hdl;
81786228Stmmextern bus_space_tag_t isa_mem_bt;
81886228Stmmextern bus_space_handle_t isa_mem_hdl;
81986228Stmm
82086228Stmm#define inb(o)		bus_space_read_1(isa_io_bt, isa_io_hdl, o)
82186228Stmm#define inw(o)		bus_space_read_2(isa_io_bt, isa_io_hdl, o)
82286228Stmm#define inl(o)		bus_space_read_4(isa_io_bt, isa_io_hdl, o)
82390615Stmm#define outb(o, v)	bus_space_write_1(isa_io_bt, isa_io_hdl, o, v)
82486228Stmm#define outw(o, v)	bus_space_write_2(isa_io_bt, isa_io_hdl, o, v)
82586228Stmm#define outl(o, v)	bus_space_write_4(isa_io_bt, isa_io_hdl, o, v)
82686228Stmm
82786228Stmm#define readb(o)	bus_space_read_1(isa_mem_bt, isa_mem_hdl, o)
82886228Stmm#define readw(o)	bus_space_read_2(isa_mem_bt, isa_mem_hdl, o)
82986228Stmm#define readl(o)	bus_space_read_4(isa_mem_bt, isa_mem_hdl, o)
83086228Stmm#define writeb(o, v)	bus_space_write_1(isa_mem_bt, isa_mem_hdl, o, v)
83186228Stmm#define writew(o, v)	bus_space_write_2(isa_mem_bt, isa_mem_hdl, o, v)
83286228Stmm#define writel(o, v)	bus_space_write_4(isa_mem_bt, isa_mem_hdl, o, v)
83386228Stmm
83486228Stmm#define insb(o, a, c) \
83586228Stmm	bus_space_read_multi_1(isa_io_bt, isa_io_hdl, o, (void*)a, c)
83686228Stmm#define insw(o, a, c) \
83786228Stmm	bus_space_read_multi_2(isa_io_bt, isa_io_hdl, o, (void*)a, c)
83886228Stmm#define insl(o, a, c) \
83986228Stmm	bus_space_read_multi_4(isa_io_bt, isa_io_hdl, o, (void*)a, c)
84086228Stmm#define outsb(o, a, c) \
84186228Stmm	bus_space_write_multi_1(isa_io_bt, isa_io_hdl, o, (void*)a, c)
84286228Stmm#define outsw(o, a, c) \
84386228Stmm	bus_space_write_multi_2(isa_io_bt, isa_io_hdl, o, (void*)a, c)
84486228Stmm#define outsl(o, a, c) \
84586228Stmm	bus_space_write_multi_4(isa_io_bt, isa_io_hdl, o, (void*)a, c)
84686228Stmm
84786228Stmm#define memcpy_fromio(d, s, c) \
84886228Stmm	bus_space_read_region_1(isa_mem_bt, isa_mem_hdl, s, d, c)
84986228Stmm#define memcpy_toio(d, s, c) \
85086228Stmm	bus_space_write_region_1(isa_mem_bt, isa_mem_hdl, d, s, c)
85186228Stmm#define memcpy_io(d, s, c) \
85286228Stmm	bus_space_copy_region_1(isa_mem_bt, isa_mem_hdl, s, isa_mem_hdl, d, c)
85386228Stmm#define memset_io(d, v, c) \
85486228Stmm	bus_space_set_region_1(isa_mem_bt, isa_mem_hdl, d, v, c)
85586228Stmm#define memsetw_io(d, v, c) \
85686228Stmm	bus_space_set_region_2(isa_mem_bt, isa_mem_hdl, d, v, c)
85786228Stmm
85886228Stmmstatic __inline void
85986228Stmmmemsetw(void *d, int val, size_t size)
86086228Stmm{
86186228Stmm    u_int16_t *sp = d;
86286228Stmm
86386228Stmm    while (size--)
86486228Stmm	*sp++ = val;
86586228Stmm}
86686228Stmm
86786228Stmm/* DMA support */
86886228Stmm
86986228Stmm/*
87086228Stmm * Flags used in various bus DMA methods.
87186228Stmm */
87286228Stmm#define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
87386228Stmm#define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
87486228Stmm#define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
875115416Shmp#define	BUS_DMA_COHERENT	0x004	/* hint: map memory in a coherent way */
87686228Stmm#define	BUS_DMA_NOWRITE		0x008
87790615Stmm#define	BUS_DMA_BUS1		0x010
87886228Stmm#define	BUS_DMA_BUS2		0x020
87986228Stmm#define	BUS_DMA_BUS3		0x040
88086228Stmm#define	BUS_DMA_BUS4		0x080
88186228Stmm/*
88286228Stmm * The following flags are from NetBSD, but are not implemented for all
88386228Stmm * architetures, and should therefore not be used in MI code.
88486228Stmm * Some have different values than under NetBSD.
88586228Stmm */
88686228Stmm#define	BUS_DMA_STREAMING	0x100	/* hint: sequential, unidirectional */
88786228Stmm#define	BUS_DMA_READ		0x200	/* mapping is device -> memory only */
88886228Stmm#define	BUS_DMA_WRITE		0x400	/* mapping is memory -> device only */
88986228Stmm
89086228Stmm#define	BUS_DMA_NOCACHE		BUS_DMA_BUS1
89186228Stmm/* Don't bother with alignment */
89286228Stmm#define	BUS_DMA_DVMA		BUS_DMA_BUS2
89386228Stmm
89486228Stmm/* Forwards needed by prototypes below. */
89586228Stmmstruct mbuf;
89686228Stmmstruct uio;
89786228Stmm
898115343Sscottltypedef int bus_dmasync_op_t;
899113347Smux#define	BUS_DMASYNC_PREREAD	1
900113347Smux#define	BUS_DMASYNC_POSTREAD	2
901113347Smux#define	BUS_DMASYNC_PREWRITE	4
902113347Smux#define	BUS_DMASYNC_POSTWRITE	8
90386228Stmm
90486228Stmm/*
90586228Stmm * A function that returns 1 if the address cannot be accessed by
90686228Stmm * a device and 0 if it can be.
90786228Stmm */
90886228Stmmtypedef int bus_dma_filter_t(void *, bus_addr_t);
90986228Stmm
91086228Stmmtypedef struct bus_dma_tag	*bus_dma_tag_t;
91186228Stmmtypedef struct bus_dmamap	*bus_dmamap_t;
91286228Stmm
91386228Stmmstruct bus_dma_segment {
91486228Stmm	bus_addr_t	ds_addr;	/* DVMA address */
91586228Stmm	bus_size_t	ds_len;		/* length of transfer */
91686228Stmm};
91786228Stmmtypedef struct bus_dma_segment	bus_dma_segment_t;
91886228Stmm
91986228Stmm/*
92086228Stmm * A function that processes a successfully loaded dma map or an error
92186228Stmm * from a delayed load map.
92286228Stmm */
92386228Stmmtypedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
92486228Stmm
92586228Stmm/*
926104486Ssam * Like bus_dmamap_callback but includes map size in bytes.  This is
927104486Ssam * defined as a separate interface to maintain compatiiblity for users
928104486Ssam * of bus_dmamap_callback_t--at some point these interfaces should be merged.
929104486Ssam */
930104486Ssamtypedef void bus_dmamap_callback2_t(void *, bus_dma_segment_t *, int, bus_size_t, int);
931104486Ssam
932104486Ssam/*
933116541Stmm * Method table for a bus_dma_tag.
934116541Stmm */
935116541Stmmstruct bus_dma_methods {
936116541Stmm	int	(*dm_dmamap_create)(bus_dma_tag_t, int, bus_dmamap_t *);
937116541Stmm	int	(*dm_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
938116541Stmm	int	(*dm_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
939116541Stmm	    bus_size_t, bus_dmamap_callback_t *, void *, int);
940116541Stmm	int	(*dm_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
941116541Stmm	    struct mbuf *, bus_dmamap_callback2_t *, void *, int);
942116541Stmm	int	(*dm_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t, struct uio *,
943116541Stmm	    bus_dmamap_callback2_t *, void *, int);
944116541Stmm	void	(*dm_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
945116541Stmm	void	(*dm_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
946116541Stmm	    bus_dmasync_op_t);
947116541Stmm	int	(*dm_dmamem_alloc)(bus_dma_tag_t, void **, int, bus_dmamap_t *);
948116541Stmm	void	(*dm_dmamem_free)(bus_dma_tag_t, void *, bus_dmamap_t);
949116541Stmm};
950116541Stmm
951116541Stmm/*
952116541Stmm * bus_dma_tag_t
95386228Stmm *
954116541Stmm * A machine-dependent opaque type describing the implementation of
955116541Stmm * DMA for a given bus.
95686228Stmm */
95786228Stmmstruct bus_dma_tag {
958108815Stmm	void		*dt_cookie;		/* cookie used in the guts */
959108815Stmm	bus_dma_tag_t	dt_parent;
960108815Stmm	bus_size_t	dt_alignment;
961108815Stmm	bus_size_t	dt_boundary;
962108815Stmm	bus_addr_t	dt_lowaddr;
963108815Stmm	bus_addr_t	dt_highaddr;
964108815Stmm	bus_dma_filter_t	*dt_filter;
965108815Stmm	void		*dt_filterarg;
966108815Stmm	bus_size_t	dt_maxsize;
967108815Stmm	int		dt_nsegments;
968108815Stmm	bus_size_t	dt_maxsegsz;
969108815Stmm	int		dt_flags;
970108815Stmm	int		dt_ref_count;
971108815Stmm	int		dt_map_count;
97286228Stmm
973116541Stmm	struct bus_dma_methods	*dt_mt;
97486228Stmm};
97586228Stmm
97686228Stmmint bus_dma_tag_create(bus_dma_tag_t, bus_size_t, bus_size_t, bus_addr_t,
97793052Stmm    bus_addr_t, bus_dma_filter_t *, void *, bus_size_t, int, bus_size_t,
97893052Stmm    int, bus_dma_tag_t *);
97986228Stmm
98086228Stmmint bus_dma_tag_destroy(bus_dma_tag_t);
98186228Stmm
98286228Stmm#define	bus_dmamap_create(t, f, p)					\
983116541Stmm	((t)->dt_mt->dm_dmamap_create((t), (f), (p)))
98486228Stmm#define	bus_dmamap_destroy(t, p)					\
985116541Stmm	((t)->dt_mt->dm_dmamap_destroy((t), (p)))
98686228Stmm#define	bus_dmamap_load(t, m, p, s, cb, cba, f)				\
987116541Stmm	((t)->dt_mt->dm_dmamap_load((t), (m), (p), (s), (cb), (cba), (f)))
988116541Stmm#define	bus_dmamap_load_mbuf(t, m, mb, cb, cba, f)			\
989116541Stmm	((t)->dt_mt->dm_dmamap_load_mbuf((t), (m), (mb), (cb), (cba), (f)))
990116541Stmm#define	bus_dmamap_load_uio(t, m, ui, cb, cba, f)			\
991116541Stmm	((t)->dt_mt->dm_dmamap_load_uio((t), (m), (ui), (cb), (cba), (f)))
99286228Stmm#define	bus_dmamap_unload(t, p)						\
993116541Stmm	((t)->dt_mt->dm_dmamap_unload((t), (p)))
99486228Stmm#define	bus_dmamap_sync(t, m, op)					\
995116541Stmm	((t)->dt_mt->dm_dmamap_sync((t), (m), (op)))
99686228Stmm#define	bus_dmamem_alloc(t, v, f, m)					\
997116541Stmm	((t)->dt_mt->dm_dmamem_alloc((t), (v), (f), (m)))
99886228Stmm#define	bus_dmamem_free(t, v, m)					\
999116541Stmm	((t)->dt_mt->dm_dmamem_free((t), (v), (m)))
100086228Stmm
100180708Sjake#endif /* !_MACHINE_BUS_H_ */
1002