xref: /openbsd/sys/arch/alpha/include/bus.h (revision 404b540a)
1 /*	$OpenBSD: bus.h,v 1.27 2009/07/30 21:39:15 miod Exp $	*/
2 /*	$NetBSD: bus.h,v 1.10 1996/12/02 22:19:32 cgd Exp $	*/
3 
4 /*
5  * Copyright (c) 1996 Carnegie-Mellon University.
6  * All rights reserved.
7  *
8  * Author: Chris G. Demetriou
9  *
10  * Permission to use, copy, modify and distribute this software and
11  * its documentation is hereby granted, provided that both the copyright
12  * notice and this permission notice appear in all copies of the
13  * software, derivative works or modified versions, and any portions
14  * thereof, and that both notices appear in supporting documentation.
15  *
16  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19  *
20  * Carnegie Mellon requests users of this software to return to
21  *
22  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
23  *  School of Computer Science
24  *  Carnegie Mellon University
25  *  Pittsburgh PA 15213-3890
26  *
27  * any improvements or extensions that they make and grant Carnegie the
28  * rights to redistribute these changes.
29  */
30 
31 #ifndef _ALPHA_BUS_H_
32 #define	_ALPHA_BUS_H_
33 
34 /*
35  * Addresses (in bus space).
36  */
37 typedef u_long bus_addr_t;
38 typedef u_long bus_size_t;
39 
40 /*
41  * Access methods for bus space.
42  */
43 typedef struct alpha_bus_space *bus_space_tag_t;
44 typedef u_long bus_space_handle_t;
45 
46 struct alpha_bus_space {
47 	/* cookie */
48 	void		*abs_cookie;
49 
50 	/* mapping/unmapping */
51 	int		(*abs_map)(void *, bus_addr_t, bus_size_t,
52 			    int, bus_space_handle_t *);
53 	void		(*abs_unmap)(void *, bus_space_handle_t,
54 			    bus_size_t);
55 	int		(*abs_subregion)(void *, bus_space_handle_t,
56 			    bus_size_t, bus_size_t, bus_space_handle_t *);
57 
58 	/* allocation/deallocation */
59 	int		(*abs_alloc)(void *, bus_addr_t, bus_addr_t,
60 			    bus_size_t, bus_size_t, bus_size_t, int,
61 			    bus_addr_t *, bus_space_handle_t *);
62 	void		(*abs_free)(void *, bus_space_handle_t,
63 			    bus_size_t);
64 
65 	/* barrier */
66 	void		(*abs_barrier)(void *, bus_space_handle_t,
67 			    bus_size_t, bus_size_t, int);
68 
69 	/* read (single) */
70 	u_int8_t	(*abs_r_1)(void *, bus_space_handle_t,
71 			    bus_size_t);
72 	u_int16_t	(*abs_r_2)(void *, bus_space_handle_t,
73 			    bus_size_t);
74 	u_int32_t	(*abs_r_4)(void *, bus_space_handle_t,
75 			    bus_size_t);
76 	u_int64_t	(*abs_r_8)(void *, bus_space_handle_t,
77 			    bus_size_t);
78 
79 	/* read multiple */
80 	void		(*abs_rm_1)(void *, bus_space_handle_t,
81 			    bus_size_t, u_int8_t *, bus_size_t);
82 	void		(*abs_rm_2)(void *, bus_space_handle_t,
83 			    bus_size_t, u_int16_t *, bus_size_t);
84 	void		(*abs_rm_4)(void *, bus_space_handle_t,
85 			    bus_size_t, u_int32_t *, bus_size_t);
86 	void		(*abs_rm_8)(void *, bus_space_handle_t,
87 			    bus_size_t, u_int64_t *, bus_size_t);
88 
89 	/* read region */
90 	void		(*abs_rr_1)(void *, bus_space_handle_t,
91 			    bus_size_t, u_int8_t *, bus_size_t);
92 	void		(*abs_rr_2)(void *, bus_space_handle_t,
93 			    bus_size_t, u_int16_t *, bus_size_t);
94 	void		(*abs_rr_4)(void *, bus_space_handle_t,
95 			    bus_size_t, u_int32_t *, bus_size_t);
96 	void		(*abs_rr_8)(void *, bus_space_handle_t,
97 			    bus_size_t, u_int64_t *, bus_size_t);
98 
99 	/* write (single) */
100 	void		(*abs_w_1)(void *, bus_space_handle_t,
101 			    bus_size_t, u_int8_t);
102 	void		(*abs_w_2)(void *, bus_space_handle_t,
103 			    bus_size_t, u_int16_t);
104 	void		(*abs_w_4)(void *, bus_space_handle_t,
105 			    bus_size_t, u_int32_t);
106 	void		(*abs_w_8)(void *, bus_space_handle_t,
107 			    bus_size_t, u_int64_t);
108 
109 	/* write multiple */
110 	void		(*abs_wm_1)(void *, bus_space_handle_t,
111 			    bus_size_t, const u_int8_t *, bus_size_t);
112 	void		(*abs_wm_2)(void *, bus_space_handle_t,
113 			    bus_size_t, const u_int16_t *, bus_size_t);
114 	void		(*abs_wm_4)(void *, bus_space_handle_t,
115 			    bus_size_t, const u_int32_t *, bus_size_t);
116 	void		(*abs_wm_8)(void *, bus_space_handle_t,
117 			    bus_size_t, const u_int64_t *, bus_size_t);
118 
119 	/* write region */
120 	void		(*abs_wr_1)(void *, bus_space_handle_t,
121 			    bus_size_t, const u_int8_t *, bus_size_t);
122 	void		(*abs_wr_2)(void *, bus_space_handle_t,
123 			    bus_size_t, const u_int16_t *, bus_size_t);
124 	void		(*abs_wr_4)(void *, bus_space_handle_t,
125 			    bus_size_t, const u_int32_t *, bus_size_t);
126 	void		(*abs_wr_8)(void *, bus_space_handle_t,
127 			    bus_size_t, const u_int64_t *, bus_size_t);
128 
129 	/* set multiple */
130 	void		(*abs_sm_1)(void *, bus_space_handle_t,
131 			    bus_size_t, u_int8_t, bus_size_t);
132 	void		(*abs_sm_2)(void *, bus_space_handle_t,
133 			    bus_size_t, u_int16_t, bus_size_t);
134 	void		(*abs_sm_4)(void *, bus_space_handle_t,
135 			    bus_size_t, u_int32_t, bus_size_t);
136 	void		(*abs_sm_8)(void *, bus_space_handle_t,
137 			    bus_size_t, u_int64_t, bus_size_t);
138 
139 	/* set region */
140 	void		(*abs_sr_1)(void *, bus_space_handle_t,
141 			    bus_size_t, u_int8_t, bus_size_t);
142 	void		(*abs_sr_2)(void *, bus_space_handle_t,
143 			    bus_size_t, u_int16_t, bus_size_t);
144 	void		(*abs_sr_4)(void *, bus_space_handle_t,
145 			    bus_size_t, u_int32_t, bus_size_t);
146 	void		(*abs_sr_8)(void *, bus_space_handle_t,
147 			    bus_size_t, u_int64_t, bus_size_t);
148 
149 	/* copy */
150 	void		(*abs_c_1)(void *, bus_space_handle_t, bus_size_t,
151 			    bus_space_handle_t, bus_size_t, bus_size_t);
152 	void		(*abs_c_2)(void *, bus_space_handle_t, bus_size_t,
153 			    bus_space_handle_t, bus_size_t, bus_size_t);
154 	void		(*abs_c_4)(void *, bus_space_handle_t, bus_size_t,
155 			    bus_space_handle_t, bus_size_t, bus_size_t);
156 	void		(*abs_c_8)(void *, bus_space_handle_t, bus_size_t,
157 			    bus_space_handle_t, bus_size_t, bus_size_t);
158 
159 	/* OpenBSD extensions follows */
160 
161 	/* read multiple raw */
162 	void		(*abs_rrm_2)(void *, bus_space_handle_t,
163 			    bus_size_t, u_int8_t *, bus_size_t);
164 	void		(*abs_rrm_4)(void *, bus_space_handle_t,
165 			    bus_size_t, u_int8_t *, bus_size_t);
166 	void		(*abs_rrm_8)(void *, bus_space_handle_t,
167 			    bus_size_t, u_int8_t *, bus_size_t);
168 
169 	/* write multiple raw */
170 	void		(*abs_wrm_2)(void *, bus_space_handle_t,
171 			    bus_size_t, const u_int8_t *, bus_size_t);
172 	void		(*abs_wrm_4)(void *, bus_space_handle_t,
173 			    bus_size_t, const u_int8_t *, bus_size_t);
174 	void		(*abs_wrm_8)(void *, bus_space_handle_t,
175 			    bus_size_t, const u_int8_t *, bus_size_t);
176 };
177 
178 
179 /*
180  * Utility macros; INTERNAL USE ONLY.
181  */
182 #define	__abs_c(a,b)		__CONCAT(a,b)
183 #define	__abs_opname(op,size)	__abs_c(__abs_c(__abs_c(abs_,op),_),size)
184 
185 #define	__abs_rs(sz, t, h, o)						\
186 	(*(t)->__abs_opname(r,sz))((t)->abs_cookie, h, o)
187 #define	__abs_ws(sz, t, h, o, v)					\
188 	(*(t)->__abs_opname(w,sz))((t)->abs_cookie, h, o, v)
189 #define	__abs_nonsingle(type, sz, t, h, o, a, c)			\
190 	(*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, a, c)
191 #ifndef DEBUG
192 #define	__abs_aligned_nonsingle(type, sz, t, h, o, a, c)		\
193 	__abs_nonsingle(type, sz, (t), (h), (o), (a), (c))
194 
195 #else
196 #define	__abs_aligned_nonsingle(type, sz, t, h, o, a, c)		\
197     do {								\
198 	if (((unsigned long)a & (sz - 1)) != 0)				\
199 		panic("bus non-single %d-byte unaligned (to %p) at %s:%d", \
200 		    sz, a, __FILE__, __LINE__);				\
201 	(*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, a, c);	\
202     } while (0)
203 #endif
204 #define	__abs_set(type, sz, t, h, o, v, c)				\
205 	(*(t)->__abs_opname(type,sz))((t)->abs_cookie, h, o, v, c)
206 #define	__abs_copy(sz, t, h1, o1, h2, o2, cnt)			\
207 	(*(t)->__abs_opname(c,sz))((t)->abs_cookie, h1, o1, h2, o2, cnt)
208 
209 /*
210  * Mapping and unmapping operations.
211  */
212 #define	bus_space_map(t, a, s, c, hp)					\
213 	(*(t)->abs_map)((t)->abs_cookie, (a), (s), (c), (hp))
214 #define alpha_bus_space_map_noacct bus_space_map
215 #define	bus_space_unmap(t, h, s)					\
216 	(*(t)->abs_unmap)((t)->abs_cookie, (h), (s))
217 #define alpha_bus_space_unmap_noacct bus_space_unmap
218 #define	bus_space_subregion(t, h, o, s, hp)				\
219 	(*(t)->abs_subregion)((t)->abs_cookie, (h), (o), (s), (hp))
220 
221 #define	BUS_SPACE_MAP_CACHEABLE		0x01
222 #define	BUS_SPACE_MAP_LINEAR		0x02
223 #define	BUS_SPACE_MAP_PREFETCHABLE	0x04
224 
225 /*
226  * Allocation and deallocation operations.
227  */
228 #define	bus_space_alloc(t, rs, re, s, a, b, c, ap, hp)			\
229 	(*(t)->abs_alloc)((t)->abs_cookie, (rs), (re), (s), (a), (b),	\
230 	    (c), (ap), (hp))
231 #define	bus_space_free(t, h, s)						\
232 	(*(t)->abs_free)((t)->abs_cookie, (h), (s))
233 
234 
235 /*
236  * Bus barrier operations.
237  */
238 #define	bus_space_barrier(t, h, o, l, f)				\
239 	(*(t)->abs_barrier)((t)->abs_cookie, (h), (o), (l), (f))
240 
241 #define BUS_SPACE_BARRIER_READ	0x01
242 #define BUS_SPACE_BARRIER_WRITE	0x02
243 
244 
245 /*
246  * Bus read (single) operations.
247  */
248 #define	bus_space_read_1(t, h, o)	__abs_rs(1,(t),(h),(o))
249 #define	bus_space_read_2(t, h, o)	__abs_rs(2,(t),(h),(o))
250 #define	bus_space_read_4(t, h, o)	__abs_rs(4,(t),(h),(o))
251 #define	bus_space_read_8(t, h, o)	__abs_rs(8,(t),(h),(o))
252 
253 
254 /*
255  * Bus read multiple operations.
256  */
257 #define	bus_space_read_multi_1(t, h, o, a, c)				\
258 	__abs_nonsingle(rm,1,(t),(h),(o),(a),(c))
259 #define	bus_space_read_multi_2(t, h, o, a, c)				\
260 	__abs_aligned_nonsingle(rm,2,(t),(h),(o),(a),(c))
261 #define	bus_space_read_multi_4(t, h, o, a, c)				\
262 	__abs_aligned_nonsingle(rm,4,(t),(h),(o),(a),(c))
263 #define	bus_space_read_multi_8(t, h, o, a, c)				\
264 	__abs_aligned_nonsingle(rm,8,(t),(h),(o),(a),(c))
265 
266 
267 /*
268  *	void bus_space_read_raw_multi_N(bus_space_tag_t tag,
269  *	    bus_space_handle_t bsh, bus_size_t offset,
270  *	    u_int8_t *addr, size_t count);
271  *
272  * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
273  * described by tag/handle/offset and copy into buffer provided.  The buffer
274  * must have proper alignment for the N byte wide entities.  Furthermore
275  * possible byte-swapping should be done by these functions.
276  */
277 
278 #define	bus_space_read_raw_multi_2(t, h, o, a, c)			\
279 	__abs_nonsingle(rrm,2,(t),(h),(o),(a),(c))
280 #define	bus_space_read_raw_multi_4(t, h, o, a, c)			\
281 	__abs_nonsingle(rrm,4,(t),(h),(o),(a),(c))
282 #define	bus_space_read_raw_multi_8(t, h, o, a, c)			\
283 	__abs_nonsingle(rrm,8,(t),(h),(o),(a),(c))
284 
285 /*
286  * Bus read region operations.
287  */
288 #define	bus_space_read_region_1(t, h, o, a, c)				\
289 	__abs_nonsingle(rr,1,(t),(h),(o),(a),(c))
290 #define	bus_space_read_region_2(t, h, o, a, c)				\
291 	__abs_aligned_nonsingle(rr,2,(t),(h),(o),(a),(c))
292 #define	bus_space_read_region_4(t, h, o, a, c)				\
293 	__abs_aligned_nonsingle(rr,4,(t),(h),(o),(a),(c))
294 #define	bus_space_read_region_8(t, h, o, a, c)				\
295 	__abs_aligned_nonsingle(rr,8,(t),(h),(o),(a),(c))
296 
297 
298 /*
299  *	void bus_space_read_raw_region_N(bus_space_tag_t tag,
300  *	    bus_space_handle_t bsh, bus_size_t offset,
301  *	    u_int8_t *addr, size_t count);
302  *
303  * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
304  * described by tag/handle and starting at `offset' from the
305  * buffer provided.  The buffer must have proper alignment for the N byte
306  * wide entities.  Furthermore possible byte-swapping should be done by
307  * these functions.
308  */
309 
310 #define bus_space_read_raw_region_2(t, h, o, a, c)			\
311     bus_space_read_region_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1)
312 #define bus_space_read_raw_region_4(t, h, o, a, c)			\
313     bus_space_read_region_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2)
314 
315 /*
316  * Bus write (single) operations.
317  */
318 #define	bus_space_write_1(t, h, o, v)	__abs_ws(1,(t),(h),(o),(v))
319 #define	bus_space_write_2(t, h, o, v)	__abs_ws(2,(t),(h),(o),(v))
320 #define	bus_space_write_4(t, h, o, v)	__abs_ws(4,(t),(h),(o),(v))
321 #define	bus_space_write_8(t, h, o, v)	__abs_ws(8,(t),(h),(o),(v))
322 
323 
324 /*
325  * Bus write multiple operations.
326  */
327 #define	bus_space_write_multi_1(t, h, o, a, c)				\
328 	__abs_nonsingle(wm,1,(t),(h),(o),(a),(c))
329 #define	bus_space_write_multi_2(t, h, o, a, c)				\
330 	__abs_aligned_nonsingle(wm,2,(t),(h),(o),(a),(c))
331 #define	bus_space_write_multi_4(t, h, o, a, c)				\
332 	__abs_aligned_nonsingle(wm,4,(t),(h),(o),(a),(c))
333 #define	bus_space_write_multi_8(t, h, o, a, c)				\
334 	__abs_aligned_nonsingle(wm,8,(t),(h),(o),(a),(c))
335 
336 /*
337  *	void bus_space_write_raw_multi_N(bus_space_tag_t tag,
338  *	    bus_space_handle_t bsh, bus_size_t offset,
339  *	    u_int8_t *addr, size_t count);
340  *
341  * Write `count' bytes in 2, 4 or 8 byte wide quantities from the buffer
342  * provided to bus space described by tag/handle/offset.  The buffer
343  * must have proper alignment for the N byte wide entities.  Furthermore
344  * possible byte-swapping should be done by these functions.
345  */
346 
347 #define	bus_space_write_raw_multi_2(t, h, o, a, c)			\
348 	__abs_nonsingle(wrm,2,(t),(h),(o),(a),(c))
349 #define	bus_space_write_raw_multi_4(t, h, o, a, c)			\
350 	__abs_nonsingle(wrm,4,(t),(h),(o),(a),(c))
351 #define	bus_space_write_raw_multi_8(t, h, o, a, c)			\
352 	__abs_nonsingle(wrm,8,(t),(h),(o),(a),(c))
353 
354 /*
355  * Bus write region operations.
356  */
357 #define	bus_space_write_region_1(t, h, o, a, c)				\
358 	__abs_nonsingle(wr,1,(t),(h),(o),(a),(c))
359 #define	bus_space_write_region_2(t, h, o, a, c)				\
360 	__abs_aligned_nonsingle(wr,2,(t),(h),(o),(a),(c))
361 #define	bus_space_write_region_4(t, h, o, a, c)				\
362 	__abs_aligned_nonsingle(wr,4,(t),(h),(o),(a),(c))
363 #define	bus_space_write_region_8(t, h, o, a, c)				\
364 	__abs_aligned_nonsingle(wr,8,(t),(h),(o),(a),(c))
365 
366 
367 /*
368  *	void bus_space_write_raw_region_N(bus_space_tag_t tag,
369  *	    bus_space_handle_t bsh, bus_size_t offset,
370  *	    const u_int8_t *addr, size_t count);
371  *
372  * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space
373  * described by tag/handle and starting at `offset' from the
374  * buffer provided.  The buffer must have proper alignment for the N byte
375  * wide entities.  Furthermore possible byte-swapping should be done by
376  * these functions.
377  */
378 
379 #define bus_space_write_raw_region_2(t, h, o, a, c)			\
380     bus_space_write_region_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1)
381 #define bus_space_write_raw_region_4(t, h, o, a, c)			\
382     bus_space_write_region_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2)
383 
384 /*
385  * Set multiple operations.
386  */
387 #define	bus_space_set_multi_1(t, h, o, v, c)				\
388 	__abs_set(sm,1,(t),(h),(o),(v),(c))
389 #define	bus_space_set_multi_2(t, h, o, v, c)				\
390 	__abs_set(sm,2,(t),(h),(o),(v),(c))
391 #define	bus_space_set_multi_4(t, h, o, v, c)				\
392 	__abs_set(sm,4,(t),(h),(o),(v),(c))
393 #define	bus_space_set_multi_8(t, h, o, v, c)				\
394 	__abs_set(sm,8,(t),(h),(o),(v),(c))
395 
396 
397 /*
398  * Set region operations.
399  */
400 #define	bus_space_set_region_1(t, h, o, v, c)				\
401 	__abs_set(sr,1,(t),(h),(o),(v),(c))
402 #define	bus_space_set_region_2(t, h, o, v, c)				\
403 	__abs_set(sr,2,(t),(h),(o),(v),(c))
404 #define	bus_space_set_region_4(t, h, o, v, c)				\
405 	__abs_set(sr,4,(t),(h),(o),(v),(c))
406 #define	bus_space_set_region_8(t, h, o, v, c)				\
407 	__abs_set(sr,8,(t),(h),(o),(v),(c))
408 
409 
410 /*
411  * Copy operations.
412  */
413 #define	bus_space_copy_1(t, h1, o1, h2, o2, c)				\
414 	__abs_copy(1, t, h1, o1, h2, o2, c)
415 #define	bus_space_copy_2(t, h1, o1, h2, o2, c)				\
416 	__abs_copy(2, t, h1, o1, h2, o2, c)
417 #define	bus_space_copy_4(t, h1, o1, h2, o2, c)				\
418 	__abs_copy(4, t, h1, o1, h2, o2, c)
419 #define	bus_space_copy_8(t, h1, o1, h2, o2, c)				\
420 	__abs_copy(8, t, h1, o1, h2, o2, c)
421 
422 /*
423  * Bus DMA methods.
424  */
425 
426 /*
427  * Flags used in various bus DMA methods.
428  */
429 #define	BUS_DMA_WAITOK		0x0000	/* safe to sleep (pseudo-flag) */
430 #define	BUS_DMA_NOWAIT		0x0001	/* not safe to sleep */
431 #define	BUS_DMA_ALLOCNOW	0x0002	/* perform resource allocation now */
432 #define	BUS_DMA_COHERENT	0x0004	/* hint: map memory DMA coherent */
433 #define	BUS_DMA_BUS1		0x0010	/* placeholders for bus functions... */
434 #define	BUS_DMA_BUS2		0x0020
435 #define	BUS_DMA_BUS3		0x0040
436 #define	BUS_DMA_24BIT		0x0080	/* isadma map */
437 #define	BUS_DMA_STREAMING	0x0100	/* hint: sequential, unidirectional */
438 #define	BUS_DMA_READ		0x0200	/* mapping is device -> memory only */
439 #define	BUS_DMA_WRITE		0x0400	/* mapping is memory -> device only */
440 #define	BUS_DMA_ZERO		0x1000	/* zero memory in dmamem_alloc */
441 
442 /*
443  * Private flags stored in the DMA map.
444  */
445 #define	DMAMAP_NO_COALESCE	0x40000000	/* don't coalesce adjacent
446 						   segments */
447 
448 /* Forwards needed by prototypes below. */
449 struct mbuf;
450 struct uio;
451 struct alpha_sgmap;
452 
453 /*
454  * Operations performed by bus_dmamap_sync().
455  */
456 #define BUS_DMASYNC_PREREAD	0x01
457 #define BUS_DMASYNC_POSTREAD	0x02
458 #define BUS_DMASYNC_PREWRITE	0x04
459 #define BUS_DMASYNC_POSTWRITE	0x08
460 
461 /*
462  *	alpha_bus_t
463  *
464  *	Busses supported by NetBSD/alpha, used by internal
465  *	utility functions.  NOT TO BE USED BY MACHINE-INDEPENDENT
466  *	CODE!
467  */
468 typedef enum {
469 	ALPHA_BUS_TURBOCHANNEL,
470 	ALPHA_BUS_PCI,
471 	ALPHA_BUS_EISA,
472 	ALPHA_BUS_ISA,
473 	ALPHA_BUS_TLSB,
474 } alpha_bus_t;
475 
476 typedef struct alpha_bus_dma_tag	*bus_dma_tag_t;
477 typedef struct alpha_bus_dmamap		*bus_dmamap_t;
478 
479 /*
480  *	bus_dma_segment_t
481  *
482  *	Describes a single contiguous DMA transaction.  Values
483  *	are suitable for programming into DMA registers.
484  */
485 struct alpha_bus_dma_segment {
486 	bus_addr_t	ds_addr;	/* DMA address */
487 	bus_size_t	ds_len;		/* length of transfer */
488 };
489 typedef struct alpha_bus_dma_segment	bus_dma_segment_t;
490 
491 /*
492  *	bus_dma_tag_t
493  *
494  *	A machine-dependent opaque type describing the implementation of
495  *	DMA for a given bus.
496  */
497 struct alpha_bus_dma_tag {
498 	void	*_cookie;		/* cookie used in the guts */
499 	bus_addr_t _wbase;		/* DMA window base */
500 
501 	/*
502 	 * The following two members are used to chain DMA windows
503 	 * together.  If, during the course of a map load, the
504 	 * resulting physical memory address is too large to
505 	 * be addressed by the window, the next window will be
506 	 * attempted.  These would be chained together like so:
507 	 *
508 	 *	direct -> sgmap -> NULL
509 	 *  or
510 	 *	sgmap -> NULL
511 	 *  or
512 	 *	direct -> NULL
513 	 *
514 	 * If the window size is 0, it will not be checked (e.g.
515 	 * TurboChannel DMA).
516 	 */
517 	bus_size_t _wsize;
518 	struct alpha_bus_dma_tag *_next_window;
519 
520 	/*
521 	 * Some chipsets have a built-in boundary constraint, independent
522 	 * of what the device requests.  This allows that boundary to
523 	 * be specified.  If the device has a more restrictive constraint,
524 	 * the map will use that, otherwise this boundary will be used.
525 	 * This value is ignored if 0.
526 	 */
527 	bus_size_t _boundary;
528 
529 	/*
530 	 * A chipset may have more than one SGMAP window, so SGMAP
531 	 * windows also get a pointer to their SGMAP state.
532 	 */
533 	struct alpha_sgmap *_sgmap;
534 
535 	/*
536 	 * Internal-use only utility methods.  NOT TO BE USED BY
537 	 * MACHINE-INDEPENDENT CODE!
538 	 */
539 	bus_dma_tag_t (*_get_tag)(bus_dma_tag_t, alpha_bus_t);
540 
541 	/*
542 	 * DMA mapping methods.
543 	 */
544 	int	(*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
545 		    bus_size_t, bus_size_t, int, bus_dmamap_t *);
546 	void	(*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
547 	int	(*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
548 		    bus_size_t, struct proc *, int);
549 	int	(*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
550 		    struct mbuf *, int);
551 	int	(*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
552 		    struct uio *, int);
553 	int	(*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
554 		    bus_dma_segment_t *, int, bus_size_t, int);
555 	void	(*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
556 	void	(*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
557 		    bus_addr_t, bus_size_t, int);
558 
559 	/*
560 	 * DMA memory utility functions.
561 	 */
562 	int	(*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
563 		    bus_size_t, bus_dma_segment_t *, int, int *, int);
564 	void	(*_dmamem_free)(bus_dma_tag_t,
565 		    bus_dma_segment_t *, int);
566 	int	(*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
567 		    int, size_t, caddr_t *, int);
568 	void	(*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t);
569 	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
570 		    int, off_t, int, int);
571 };
572 
573 #define	alphabus_dma_get_tag(t, b)				\
574 	(*(t)->_get_tag)(t, b)
575 
576 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
577 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
578 #define	bus_dmamap_destroy(t, p)				\
579 	(*(t)->_dmamap_destroy)((t), (p))
580 #define	bus_dmamap_load(t, m, b, s, p, f)			\
581 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
582 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
583 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
584 #define	bus_dmamap_load_uio(t, m, u, f)				\
585 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
586 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
587 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
588 #define	bus_dmamap_unload(t, p)					\
589 	(void)(t),						\
590 	(*(p)->_dm_window->_dmamap_unload)((p)->_dm_window, (p))
591 #define	bus_dmamap_sync(t, p, a, s, op)				\
592 	(void)(t), 						\
593 	(*(p)->_dm_window->_dmamap_sync)((p)->_dm_window, (p), (a), (s), (op))
594 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
595 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
596 #define	bus_dmamem_free(t, sg, n)				\
597 	(*(t)->_dmamem_free)((t), (sg), (n))
598 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
599 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
600 #define	bus_dmamem_unmap(t, k, s)				\
601 	(*(t)->_dmamem_unmap)((t), (k), (s))
602 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
603 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
604 
605 /*
606  *	bus_dmamap_t
607  *
608  *	Describes a DMA mapping.
609  */
610 struct alpha_bus_dmamap {
611 	/*
612 	 * PRIVATE MEMBERS: not for use by machine-independent code.
613 	 */
614 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
615 	int		_dm_segcnt;	/* number of segs this map can map */
616 	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
617 	bus_size_t	_dm_boundary;	/* don't cross this */
618 	int		_dm_flags;	/* misc. flags */
619 
620 	/*
621 	 * Private cookie to be used by the DMA back-end.
622 	 */
623 	void		*_dm_cookie;
624 
625 	/*
626 	 * The DMA window that we ended up being mapped in.
627 	 */
628 	bus_dma_tag_t	_dm_window;
629 
630 	/*
631 	 * PUBLIC MEMBERS: these are used by machine-independent code.
632 	 */
633 	bus_size_t	dm_mapsize;	/* size of the mapping */
634 	int		dm_nsegs;	/* # valid segments in mapping */
635 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
636 };
637 
638 #ifdef _ALPHA_BUS_DMA_PRIVATE
639 int	_bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
640 	    bus_size_t, int, bus_dmamap_t *);
641 void	_bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
642 
643 int	_bus_dmamap_load_direct(bus_dma_tag_t, bus_dmamap_t,
644 	    void *, bus_size_t, struct proc *, int);
645 int	_bus_dmamap_load_mbuf_direct(bus_dma_tag_t,
646 	    bus_dmamap_t, struct mbuf *, int);
647 int	_bus_dmamap_load_uio_direct(bus_dma_tag_t,
648 	    bus_dmamap_t, struct uio *, int);
649 int	_bus_dmamap_load_raw_direct(bus_dma_tag_t,
650 	    bus_dmamap_t, bus_dma_segment_t *, int, bus_size_t, int);
651 
652 void	_bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
653 void	_bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
654 	    bus_size_t, int);
655 
656 int	_bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
657 	    bus_size_t alignment, bus_size_t boundary,
658 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
659 int	_bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
660 	    bus_size_t alignment, bus_size_t boundary,
661 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
662 	    paddr_t low, paddr_t high);
663 void	_bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
664 	    int nsegs);
665 int	_bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
666 	    int nsegs, size_t size, caddr_t *kvap, int flags);
667 void	_bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva,
668 	    size_t size);
669 paddr_t	_bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
670 	    int nsegs, off_t off, int prot, int flags);
671 #endif /* _ALPHA_BUS_DMA_PRIVATE */
672 
673 #endif /* _ALPHA_BUS_H_ */
674