xref: /freebsd/sys/amd64/include/bus.h (revision 33b77e2decd50e53798014b70bf7ca3bdc4c0c7e)
1 /*	$NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the NetBSD
22  *	Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 /*
41  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
42  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
43  *
44  * Redistribution and use in source and binary forms, with or without
45  * modification, are permitted provided that the following conditions
46  * are met:
47  * 1. Redistributions of source code must retain the above copyright
48  *    notice, this list of conditions and the following disclaimer.
49  * 2. Redistributions in binary form must reproduce the above copyright
50  *    notice, this list of conditions and the following disclaimer in the
51  *    documentation and/or other materials provided with the distribution.
52  * 3. All advertising materials mentioning features or use of this software
53  *    must display the following acknowledgement:
54  *      This product includes software developed by Christopher G. Demetriou
55  *	for the NetBSD Project.
56  * 4. The name of the author may not be used to endorse or promote products
57  *    derived from this software without specific prior written permission
58  *
59  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
60  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
61  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
62  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
63  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
64  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
65  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
66  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
67  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
68  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
69  */
70 /* $Id$ */
71 
72 #ifndef _I386_BUS_H_
73 #define _I386_BUS_H_
74 
75 #include <machine/cpufunc.h>
76 
77 /*
78  * Values for the i386 bus space tag, not to be used directly by MI code.
79  */
80 #define	I386_BUS_SPACE_IO	0	/* space is i/o space */
81 #define I386_BUS_SPACE_MEM	1	/* space is mem space */
82 
83 /*
84  * Bus address and size types
85  */
86 typedef u_long bus_addr_t;
87 typedef u_long bus_size_t;
88 
89 #define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
90 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
91 #define BUS_SPACE_MAXSIZE	(64 * 1024) /* Maximum supported size */
92 #define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
93 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
94 #define BUS_SPACE_MAXADDR	0xFFFFFFFF
95 
96 /*
97  * Access methods for bus resources and address space.
98  */
99 typedef	int bus_space_tag_t;
100 typedef	u_long bus_space_handle_t;
101 
102 /*
103  * Map a region of device bus space into CPU virtual address space.
104  */
105 
106 #define	BUS_SPACE_MAP_CACHEABLE		0x01
107 #define	BUS_SPACE_MAP_LINEAR		0x02
108 
109 int	bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
110 		      int flags, bus_space_handle_t *bshp);
111 
112 /*
113  * Unmap a region of device bus space.
114  */
115 
116 void	bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
117 			bus_size_t size);
118 
119 /*
120  * Get a new handle for a subregion of an already-mapped area of bus space.
121  */
122 
123 int	bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
124 			    bus_size_t offset, bus_size_t size,
125 			    bus_space_handle_t *nbshp);
126 
127 /*
128  * Allocate a region of memory that is accessible to devices in bus space.
129  */
130 
131 int	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
132 			bus_addr_t rend, bus_size_t size, bus_size_t align,
133 			bus_size_t boundary, int flags, bus_addr_t *addrp,
134 			bus_space_handle_t *bshp);
135 
136 /*
137  * Free a region of bus space accessible memory.
138  */
139 
140 void	bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
141 		       bus_size_t size);
142 
143 #if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_)
144 
145 /*
146  * Read a 1, 2, 4, or 8 byte quantity from bus space
147  * described by tag/handle/offset.
148  */
149 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
150 					  bus_space_handle_t handle,
151 					  bus_size_t offset);
152 
153 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
154 					   bus_space_handle_t handle,
155 					   bus_size_t offset);
156 
157 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
158 					   bus_space_handle_t handle,
159 					   bus_size_t offset);
160 
161 static __inline u_int8_t
162 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
163 		 bus_size_t offset)
164 {
165 #if defined (_I386_BUS_PIO_H_)
166 #if defined (_I386_BUS_MEMIO_H_)
167 	if (tag == I386_BUS_SPACE_IO)
168 #endif
169 		return (inb(handle + offset));
170 #endif
171 #if defined (_I386_BUS_MEMIO_H_)
172 	return (*(volatile u_int8_t *)(handle + offset));
173 #endif
174 }
175 
176 static __inline u_int16_t
177 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
178 		 bus_size_t offset)
179 {
180 #if defined(_I386_BUS_PIO_H_)
181 #if defined(_I386_BUS_MEMIO_H_)
182 	if (tag == I386_BUS_SPACE_IO)
183 #endif
184 		return (inw(handle + offset));
185 #endif
186 #if defined(_I386_BUS_MEMIO_H_)
187 	return (*(volatile u_int16_t *)(handle + offset));
188 #endif
189 }
190 
191 static __inline u_int32_t
192 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
193 		 bus_size_t offset)
194 {
195 #if defined(_I386_BUS_PIO_H_)
196 #if defined(_I386_BUS_MEMIO_H_)
197 	if (tag == I386_BUS_SPACE_IO)
198 #endif
199 		return (inl(handle + offset));
200 #endif
201 #if defined(_I386_BUS_MEMIO_H_)
202 	return (*(volatile u_int32_t *)(handle + offset));
203 #endif
204 }
205 
206 #if 0	/* Cause a link error for bus_space_read_8 */
207 #define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
208 #endif
209 
210 /*
211  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
212  * described by tag/handle/offset and copy into buffer provided.
213  */
214 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
215 					    bus_space_handle_t bsh,
216 					    bus_size_t offset, u_int8_t *addr,
217 					    size_t count);
218 
219 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
220 					    bus_space_handle_t bsh,
221 					    bus_size_t offset, u_int16_t *addr,
222 					    size_t count);
223 
224 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
225 					    bus_space_handle_t bsh,
226 					    bus_size_t offset, u_int32_t *addr,
227 					    size_t count);
228 
229 static __inline void
230 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
231 		       bus_size_t offset, u_int8_t *addr, size_t count)
232 {
233 #if defined(_I386_BUS_PIO_H_)
234 #if defined(_I386_BUS_MEMIO_H_)
235 	if (tag == I386_BUS_SPACE_IO)
236 #endif
237 		insb(bsh + offset, addr, count);
238 #endif
239 #if defined(_I386_BUS_MEMIO_H_)
240 #if defined(_I386_BUS_PIO_H_)
241 	else
242 #endif
243 	{
244 		int __x __asm__("%eax");
245 		__asm __volatile("
246 			cld					;
247 		1:	movb (%1),%%al				;
248 			stosb					;
249 			loop 1b"				:
250 		    "=&a" (__x)					:
251 		    "r" (bsh + offset), "D" (addr), "c" (count)	:
252 		    "%edi", "%ecx", "memory");
253 	}
254 #endif
255 }
256 
257 static __inline void
258 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
259 		       bus_size_t offset, u_int16_t *addr, size_t count)
260 {
261 #if defined(_I386_BUS_PIO_H_)
262 #if defined(_I386_BUS_MEMIO_H_)
263 	if (tag == I386_BUS_SPACE_IO)
264 #endif
265 		insw(bsh + offset, addr, count);
266 #endif
267 #if defined(_I386_BUS_MEMIO_H_)
268 #if defined(_I386_BUS_PIO_H_)
269 	else
270 #endif
271 	{
272 		int __x __asm__("%eax");
273 		__asm __volatile("
274 			cld					;
275 		1:	movw (%1),%%ax				;
276 			stosw					;
277 			loop 1b"				:
278 		    "=&a" (__x)					:
279 		    "r" (bsh + offset), "D" (addr), "c" (count)	:
280 		    "%edi", "%ecx", "memory");
281 	}
282 #endif
283 }
284 
285 static __inline void
286 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
287 		       bus_size_t offset, u_int32_t *addr, size_t count)
288 {
289 #if defined(_I386_BUS_PIO_H_)
290 #if defined(_I386_BUS_MEMIO_H_)
291 	if (tag == I386_BUS_SPACE_IO)
292 #endif
293 		insl(bsh + offset, addr, count);
294 #endif
295 #if defined(_I386_BUS_MEMIO_H_)
296 #if defined(_I386_BUS_PIO_H_)
297 	else
298 #endif
299 	{
300 		int __x __asm__("%eax");
301 		__asm __volatile("
302 			cld					;
303 		1:	movl (%1),%%eax				;
304 			stosl					;
305 			loop 1b"				:
306 		    "=&a" (__x)					:
307 		    "r" (bsh + offset), "D" (addr), "c" (count)	:
308 		    "%edi", "%ecx", "memory");
309 	}
310 #endif
311 }
312 
313 #if 0	/* Cause a link error for bus_space_read_multi_8 */
314 #define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
315 #endif
316 
317 /*
318  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
319  * described by tag/handle and starting at `offset' and copy into
320  * buffer provided.
321  */
322 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
323 					     bus_space_handle_t bsh,
324 					     bus_size_t offset, u_int8_t *addr,
325 					     size_t count);
326 
327 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
328 					     bus_space_handle_t bsh,
329 					     bus_size_t offset, u_int16_t *addr,
330 					     size_t count);
331 
332 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
333 					     bus_space_handle_t bsh,
334 					     bus_size_t offset, u_int32_t *addr,
335 					     size_t count);
336 
337 
338 static __inline void
339 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
340 			bus_size_t offset, u_int8_t *addr, size_t count)
341 {
342 #if defined(_I386_BUS_PIO_H_)
343 #if defined(_I386_BUS_MEMIO_H_)
344 	if (tag == I386_BUS_SPACE_IO)
345 #endif
346 	{
347 		int __x __asm__("%eax");
348 		__asm __volatile("
349 			cld					;
350 		1:	inb %w1,%%al				;
351 			stosb					;
352 			incl %1					;
353 			loop 1b"				:
354 		    "=&a" (__x)					:
355 		    "d" (bsh + offset), "D" (addr), "c" (count)	:
356 		    "%edx", "%edi", "%ecx", "memory");
357 	}
358 #endif
359 #if defined(_I386_BUS_MEMIO_H_)
360 #if defined(_I386_BUS_PIO_H_)
361 	else
362 #endif
363 	{
364 		__asm __volatile("
365 			cld					;
366 			repne					;
367 			movsb"					:
368 								:
369 		    "S" (bsh + offset), "D" (addr), "c" (count)	:
370 		    "%esi", "%edi", "%ecx", "memory");
371 	}
372 #endif
373 }
374 
375 static __inline void
376 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
377 			bus_size_t offset, u_int16_t *addr, size_t count)
378 {
379 #if defined(_I386_BUS_PIO_H_)
380 #if defined(_I386_BUS_MEMIO_H_)
381 	if (tag == I386_BUS_SPACE_IO)
382 #endif
383 	{
384 		int __x __asm__("%eax");
385 		__asm __volatile("
386 			cld					;
387 		1:	inw %w1,%%ax				;
388 			stosw					;
389 			addl $2,%1				;
390 			loop 1b"				:
391 		    "=&a" (__x)					:
392 		    "d" (bsh + offset), "D" (addr), "c" (count)	:
393 		    "%edx", "%edi", "%ecx", "memory");
394 	}
395 #endif
396 #if defined(_I386_BUS_MEMIO_H_)
397 #if defined(_I386_BUS_PIO_H_)
398 	else
399 #endif
400 	{
401 		__asm __volatile("
402 			cld					;
403 			repne					;
404 			movsw"					:
405 								:
406 		    "S" (bsh + offset), "D" (addr), "c" (count)	:
407 		    "%esi", "%edi", "%ecx", "memory");
408 	}
409 #endif
410 }
411 
412 static __inline void
413 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
414 			bus_size_t offset, u_int32_t *addr, size_t count)
415 {
416 #if defined(_I386_BUS_PIO_H_)
417 #if defined(_I386_BUS_MEMIO_H_)
418 	if (tag == I386_BUS_SPACE_IO)
419 #endif
420 	{
421 		int __x __asm__("%eax");
422 		__asm __volatile("
423 			cld					;
424 		1:	inl %w1,%%eax				;
425 			stosl					;
426 			addl $4,%1				;
427 			loop 1b"				:
428 		    "=&a" (__x)					:
429 		    "d" (bsh + offset), "D" (addr), "c" (count)	:
430 		    "%edx", "%edi", "%ecx", "memory");
431 	}
432 #endif
433 #if defined(_I386_BUS_MEMIO_H_)
434 #if defined(_I386_BUS_PIO_H_)
435 	else
436 #endif
437 	{
438 		__asm __volatile("
439 			cld					;
440 			repne					;
441 			movsl"					:
442 								:
443 		    "S" (bsh + offset), "D" (addr), "c" (count)	:
444 		    "%esi", "%edi", "%ecx", "memory");
445 	}
446 #endif
447 }
448 
449 #if 0	/* Cause a link error for bus_space_read_region_8 */
450 #define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
451 #endif
452 
453 /*
454  * Write the 1, 2, 4, or 8 byte value `value' to bus space
455  * described by tag/handle/offset.
456  */
457 
458 static __inline void bus_space_write_1(bus_space_tag_t tag,
459 				       bus_space_handle_t bsh,
460 				       bus_size_t offset, u_int8_t value);
461 
462 static __inline void bus_space_write_2(bus_space_tag_t tag,
463 				       bus_space_handle_t bsh,
464 				       bus_size_t offset, u_int16_t value);
465 
466 static __inline void bus_space_write_4(bus_space_tag_t tag,
467 				       bus_space_handle_t bsh,
468 				       bus_size_t offset, u_int32_t value);
469 
470 static __inline void
471 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
472 		       bus_size_t offset, u_int8_t value)
473 {
474 #if defined(_I386_BUS_PIO_H_)
475 #if defined(_I386_BUS_MEMIO_H_)
476 	if (tag == I386_BUS_SPACE_IO)
477 #endif
478 		outb(bsh + offset, value);
479 #endif
480 #if defined(_I386_BUS_MEMIO_H_)
481 #if defined(_I386_BUS_PIO_H_)
482 	else
483 #endif
484 		*(volatile u_int8_t *)(bsh + offset) = value;
485 #endif
486 }
487 
488 static __inline void
489 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
490 		       bus_size_t offset, u_int16_t value)
491 {
492 #if defined(_I386_BUS_PIO_H_)
493 #if defined(_I386_BUS_MEMIO_H_)
494 	if (tag == I386_BUS_SPACE_IO)
495 #endif
496 		outw(bsh + offset, value);
497 #endif
498 #if defined(_I386_BUS_MEMIO_H_)
499 #if defined(_I386_BUS_PIO_H_)
500 	else
501 #endif
502 		*(volatile u_int16_t *)(bsh + offset) = value;
503 #endif
504 }
505 
506 static __inline void
507 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
508 		       bus_size_t offset, u_int32_t value)
509 {
510 #if defined(_I386_BUS_PIO_H_)
511 #if defined(_I386_BUS_MEMIO_H_)
512 	if (tag == I386_BUS_SPACE_IO)
513 #endif
514 		outl(bsh + offset, value);
515 #endif
516 #if defined(_I386_BUS_MEMIO_H_)
517 #if defined(_I386_BUS_PIO_H_)
518 	else
519 #endif
520 		*(volatile u_int32_t *)(bsh + offset) = value;
521 #endif
522 }
523 
524 #if 0	/* Cause a link error for bus_space_write_8 */
525 #define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
526 #endif
527 
528 /*
529  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
530  * provided to bus space described by tag/handle/offset.
531  */
532 
533 static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
534 					     bus_space_handle_t bsh,
535 					     bus_size_t offset,
536 					     const u_int8_t *addr,
537 					     size_t count);
538 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
539 					     bus_space_handle_t bsh,
540 					     bus_size_t offset,
541 					     const u_int16_t *addr,
542 					     size_t count);
543 
544 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
545 					     bus_space_handle_t bsh,
546 					     bus_size_t offset,
547 					     const u_int32_t *addr,
548 					     size_t count);
549 
550 static __inline void
551 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
552 			bus_size_t offset, const u_int8_t *addr, size_t count)
553 {
554 #if defined(_I386_BUS_PIO_H_)
555 #if defined(_I386_BUS_MEMIO_H_)
556 	if (tag == I386_BUS_SPACE_IO)
557 #endif
558 		outsb(bsh + offset, addr, count);
559 #endif
560 #if defined(_I386_BUS_MEMIO_H_)
561 #if defined(_I386_BUS_PIO_H_)
562 	else
563 #endif
564 	{
565 		int __x __asm__("%eax");
566 		__asm __volatile("
567 			cld					;
568 		1:	lodsb					;
569 			movb %%al,(%1)				;
570 			loop 1b"				:
571 		    "=&a" (__x)					:
572 		    "r" (bsh + offset), "S" (addr), "c" (count)	:
573 		    "%esi", "%ecx");
574 	}
575 #endif
576 }
577 
578 static __inline void
579 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
580 			bus_size_t offset, const u_int16_t *addr, size_t count)
581 {
582 #if defined(_I386_BUS_PIO_H_)
583 #if defined(_I386_BUS_MEMIO_H_)
584 	if (tag == I386_BUS_SPACE_IO)
585 #endif
586 		outsw(bsh + offset, addr, count);
587 #endif
588 #if defined(_I386_BUS_MEMIO_H_)
589 #if defined(_I386_BUS_PIO_H_)
590 	else
591 #endif
592 	{
593 		int __x __asm__("%eax");
594 		__asm __volatile("
595 			cld					;
596 		1:	lodsw					;
597 			movw %%ax,(%1)				;
598 			loop 1b"				:
599 		    "=&a" (__x)					:
600 		    "r" (bsh + offset), "S" (addr), "c" (count)	:
601 		    "%esi", "%ecx");
602 	}
603 #endif
604 }
605 
606 static __inline void
607 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
608 			bus_size_t offset, const u_int32_t *addr, size_t count)
609 {
610 #if defined(_I386_BUS_PIO_H_)
611 #if defined(_I386_BUS_MEMIO_H_)
612 	if (tag == I386_BUS_SPACE_IO)
613 #endif
614 		outsl(bsh + offset, addr, count);
615 #endif
616 #if defined(_I386_BUS_MEMIO_H_)
617 #if defined(_I386_BUS_PIO_H_)
618 	else
619 #endif
620 	{
621 		int __x __asm__("%eax");
622 		__asm __volatile("
623 			cld					;
624 		1:	lodsl					;
625 			movl %%eax,(%1)				;
626 			loop 1b"				:
627 		    "=&a" (__x)					:
628 		    "r" (bsh + offset), "S" (addr), "c" (count)	:
629 		    "%esi", "%ecx");
630 	}
631 #endif
632 }
633 
634 #if 0	/* Cause a link error for bus_space_write_multi_8 */
635 #define	bus_space_write_multi_8(t, h, o, a, c)				\
636 			!!! bus_space_write_multi_8 unimplemented !!!
637 #endif
638 
639 /*
640  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
641  * to bus space described by tag/handle starting at `offset'.
642  */
643 
644 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
645 					      bus_space_handle_t bsh,
646 					      bus_size_t offset,
647 					      const u_int8_t *addr,
648 					      size_t count);
649 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
650 					      bus_space_handle_t bsh,
651 					      bus_size_t offset,
652 					      const u_int16_t *addr,
653 					      size_t count);
654 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
655 					      bus_space_handle_t bsh,
656 					      bus_size_t offset,
657 					      const u_int32_t *addr,
658 					      size_t count);
659 
660 static __inline void
661 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
662 			 bus_size_t offset, const u_int8_t *addr, size_t count)
663 {
664 #if defined(_I386_BUS_PIO_H_)
665 #if defined(_I386_BUS_MEMIO_H_)
666 	if (tag == I386_BUS_SPACE_IO)
667 #endif
668 	{
669 		int __x __asm__("%eax");
670 		__asm __volatile("
671 			cld					;
672 		1:	lodsb					;
673 			outb %%al,%w1				;
674 			incl %1					;
675 			loop 1b"				:
676 		    "=&a" (__x)					:
677 		    "d" (bsh + offset), "S" (addr), "c" (count)	:
678 		    "%edx", "%esi", "%ecx", "memory");
679 	}
680 #endif
681 #if defined(_I386_BUS_MEMIO_H_)
682 #if defined(_I386_BUS_PIO_H_)
683 	else
684 #endif
685 	{
686 		__asm __volatile("
687 			cld					;
688 			repne					;
689 			movsb"					:
690 								:
691 		    "D" (bsh + offset), "S" (addr), "c" (count)	:
692 		    "%edi", "%esi", "%ecx", "memory");
693 	}
694 #endif
695 }
696 
697 static __inline void
698 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
699 			 bus_size_t offset, const u_int16_t *addr, size_t count)
700 {
701 #if defined(_I386_BUS_PIO_H_)
702 #if defined(_I386_BUS_MEMIO_H_)
703 	if (tag == I386_BUS_SPACE_IO)
704 #endif
705 	{
706 		int __x __asm__("%eax");
707 		__asm __volatile("
708 			cld					;
709 		1:	lodsw					;
710 			outw %%ax,%w1				;
711 			addl $2,%1				;
712 			loop 1b"				:
713 		    "=&a" (__x)					:
714 		    "d" (bsh + offset), "S" (addr), "c" (count)	:
715 		    "%edx", "%esi", "%ecx", "memory");
716 	}
717 #endif
718 #if defined(_I386_BUS_MEMIO_H_)
719 #if defined(_I386_BUS_PIO_H_)
720 	else
721 #endif
722 	{
723 		__asm __volatile("
724 			cld					;
725 			repne					;
726 			movsw"					:
727 								:
728 		    "D" (bsh + offset), "S" (addr), "c" (count)	:
729 		    "%edi", "%esi", "%ecx", "memory");
730 	}
731 #endif
732 }
733 
734 static __inline void
735 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
736 			 bus_size_t offset, const u_int32_t *addr, size_t count)
737 {
738 #if defined(_I386_BUS_PIO_H_)
739 #if defined(_I386_BUS_MEMIO_H_)
740 	if (tag == I386_BUS_SPACE_IO)
741 #endif
742 	{
743 		int __x __asm__("%eax");
744 		__asm __volatile("
745 			cld					;
746 		1:	lodsl					;
747 			outl %%eax,%w1				;
748 			addl $4,%1				;
749 			loop 1b"				:
750 		    "=&a" (__x)					:
751 		    "d" (bsh + offset), "S" (addr), "c" (count)	:
752 		    "%edx", "%esi", "%ecx", "memory");
753 	}
754 #endif
755 #if defined(_I386_BUS_MEMIO_H_)
756 #if defined(_I386_BUS_PIO_H_)
757 	else
758 #endif
759 	{
760 		__asm __volatile("
761 			cld					;
762 			repne					;
763 			movsl"					:
764 								:
765 		    "D" (bsh + offset), "S" (addr), "c" (count)	:
766 		    "%edi", "%esi", "%ecx", "memory");
767 	}
768 #endif
769 }
770 
771 #if 0	/* Cause a link error for bus_space_write_region_8 */
772 #define	bus_space_write_region_8					\
773 			!!! bus_space_write_region_8 unimplemented !!!
774 #endif
775 
776 /*
777  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
778  * by tag/handle/offset `count' times.
779  */
780 
781 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
782 					   bus_space_handle_t bsh,
783 					   bus_size_t offset,
784 					   u_int8_t value, size_t count);
785 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
786 					   bus_space_handle_t bsh,
787 					   bus_size_t offset,
788 					   u_int16_t value, size_t count);
789 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
790 					   bus_space_handle_t bsh,
791 					   bus_size_t offset,
792 					   u_int32_t value, size_t count);
793 
794 static __inline void
795 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
796 		      bus_size_t offset, u_int8_t value, size_t count)
797 {
798 	bus_addr_t addr = bsh + offset;
799 
800 #if defined(_I386_BUS_PIO_H_)
801 #if defined(_I386_BUS_MEMIO_H_)
802 	if (tag == I386_BUS_SPACE_IO)
803 #endif
804 		while (count--)
805 			outb(addr, value);
806 #endif
807 #if defined(_I386_BUS_MEMIO_H_)
808 #if defined(_I386_BUS_PIO_H_)
809 	else
810 #endif
811 		while (count--)
812 			*(volatile u_int8_t *)(addr) = value;
813 #endif
814 }
815 
816 static __inline void
817 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
818 		     bus_size_t offset, u_int16_t value, size_t count)
819 {
820 	bus_addr_t addr = bsh + offset;
821 
822 #if defined(_I386_BUS_PIO_H_)
823 #if defined(_I386_BUS_MEMIO_H_)
824 	if (tag == I386_BUS_SPACE_IO)
825 #endif
826 		while (count--)
827 			outw(addr, value);
828 #endif
829 #if defined(_I386_BUS_MEMIO_H_)
830 #if defined(_I386_BUS_PIO_H_)
831 	else
832 #endif
833 		while (count--)
834 			*(volatile u_int16_t *)(addr) = value;
835 #endif
836 }
837 
838 static __inline void
839 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
840 		      bus_size_t offset, u_int32_t value, size_t count)
841 {
842 	bus_addr_t addr = bsh + offset;
843 
844 #if defined(_I386_BUS_PIO_H_)
845 #if defined(_I386_BUS_MEMIO_H_)
846 	if (tag == I386_BUS_SPACE_IO)
847 #endif
848 		while (count--)
849 			outl(addr, value);
850 #endif
851 #if defined(_I386_BUS_MEMIO_H_)
852 #if defined(_I386_BUS_PIO_H_)
853 	else
854 #endif
855 		while (count--)
856 			*(volatile u_int32_t *)(addr) = value;
857 #endif
858 }
859 
860 #if 0	/* Cause a link error for bus_space_set_multi_8 */
861 #define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
862 #endif
863 
864 /*
865  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
866  * by tag/handle starting at `offset'.
867  */
868 
869 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
870 					    bus_space_handle_t bsh,
871 					    bus_size_t offset, u_int8_t value,
872 					    size_t count);
873 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
874 					    bus_space_handle_t bsh,
875 					    bus_size_t offset, u_int16_t value,
876 					    size_t count);
877 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
878 					    bus_space_handle_t bsh,
879 					    bus_size_t offset, u_int32_t value,
880 					    size_t count);
881 
882 static __inline void
883 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
884 		       bus_size_t offset, u_int8_t value, size_t count)
885 {
886 	bus_addr_t addr = bsh + offset;
887 
888 #if defined(_I386_BUS_PIO_H_)
889 #if defined(_I386_BUS_MEMIO_H_)
890 	if (tag == I386_BUS_SPACE_IO)
891 #endif
892 		for (; count != 0; count--, addr++)
893 			outb(addr, value);
894 #endif
895 #if defined(_I386_BUS_MEMIO_H_)
896 #if defined(_I386_BUS_PIO_H_)
897 	else
898 #endif
899 		for (; count != 0; count--, addr++)
900 			*(volatile u_int8_t *)(addr) = value;
901 #endif
902 }
903 
904 static __inline void
905 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
906 		       bus_size_t offset, u_int16_t value, size_t count)
907 {
908 	bus_addr_t addr = bsh + offset;
909 
910 #if defined(_I386_BUS_PIO_H_)
911 #if defined(_I386_BUS_MEMIO_H_)
912 	if (tag == I386_BUS_SPACE_IO)
913 #endif
914 		for (; count != 0; count--, addr += 2)
915 			outw(addr, value);
916 #endif
917 #if defined(_I386_BUS_MEMIO_H_)
918 #if defined(_I386_BUS_PIO_H_)
919 	else
920 #endif
921 		for (; count != 0; count--, addr += 2)
922 			*(volatile u_int16_t *)(addr) = value;
923 #endif
924 }
925 
926 static __inline void
927 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
928 		       bus_size_t offset, u_int32_t value, size_t count)
929 {
930 	bus_addr_t addr = bsh + offset;
931 
932 #if defined(_I386_BUS_PIO_H_)
933 #if defined(_I386_BUS_MEMIO_H_)
934 	if (tag == I386_BUS_SPACE_IO)
935 #endif
936 		for (; count != 0; count--, addr += 4)
937 			outl(addr, value);
938 #endif
939 #if defined(_I386_BUS_MEMIO_H_)
940 #if defined(_I386_BUS_PIO_H_)
941 	else
942 #endif
943 		for (; count != 0; count--, addr += 4)
944 			*(volatile u_int32_t *)(addr) = value;
945 #endif
946 }
947 
948 #if 0	/* Cause a link error for bus_space_set_region_8 */
949 #define	bus_space_set_region_8	!!! bus_space_set_region_8 unimplemented !!!
950 #endif
951 
952 /*
953  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
954  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
955  */
956 
957 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
958 					     bus_space_handle_t bsh1,
959 					     bus_size_t off1,
960 					     bus_space_handle_t bsh2,
961 					     bus_size_t off2, size_t count);
962 
963 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
964 					     bus_space_handle_t bsh1,
965 					     bus_size_t off1,
966 					     bus_space_handle_t bsh2,
967 					     bus_size_t off2, size_t count);
968 
969 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
970 					     bus_space_handle_t bsh1,
971 					     bus_size_t off1,
972 					     bus_space_handle_t bsh2,
973 					     bus_size_t off2, size_t count);
974 
975 static __inline void
976 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
977 			bus_size_t off1, bus_space_handle_t bsh2,
978 			bus_size_t off2, size_t count)
979 {
980 	bus_addr_t addr1 = bsh1 + off1;
981 	bus_addr_t addr2 = bsh2 + off2;
982 
983 #if defined(_I386_BUS_PIO_H_)
984 #if defined(_I386_BUS_MEMIO_H_)
985 	if (tag == I386_BUS_SPACE_IO)
986 #endif
987 	{
988 		if (addr1 >= addr2) {
989 			/* src after dest: copy forward */
990 			for (; count != 0; count--, addr1++, addr2++)
991 				outb(addr2, inb(addr1));
992 		} else {
993 			/* dest after src: copy backwards */
994 			for (addr1 += (count - 1), addr2 += (count - 1);
995 			    count != 0; count--, addr1--, addr2--)
996 				outb(addr2, inb(addr1));
997 		}
998 	}
999 #endif
1000 #if defined(_I386_BUS_MEMIO_H_)
1001 #if defined(_I386_BUS_PIO_H_)
1002 	else
1003 #endif
1004 	{
1005 		if (addr1 >= addr2) {
1006 			/* src after dest: copy forward */
1007 			for (; count != 0; count--, addr1++, addr2++)
1008 				*(volatile u_int8_t *)(addr2) =
1009 				    *(volatile u_int8_t *)(addr1);
1010 		} else {
1011 			/* dest after src: copy backwards */
1012 			for (addr1 += (count - 1), addr2 += (count - 1);
1013 			    count != 0; count--, addr1--, addr2--)
1014 				*(volatile u_int8_t *)(addr2) =
1015 				    *(volatile u_int8_t *)(addr1);
1016 		}
1017 	}
1018 #endif
1019 }
1020 
1021 static __inline void
1022 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
1023 			bus_size_t off1, bus_space_handle_t bsh2,
1024 			bus_size_t off2, size_t count)
1025 {
1026 	bus_addr_t addr1 = bsh1 + off1;
1027 	bus_addr_t addr2 = bsh2 + off2;
1028 
1029 #if defined(_I386_BUS_PIO_H_)
1030 #if defined(_I386_BUS_MEMIO_H_)
1031 	if (tag == I386_BUS_SPACE_IO)
1032 #endif
1033 	{
1034 		if (addr1 >= addr2) {
1035 			/* src after dest: copy forward */
1036 			for (; count != 0; count--, addr1 += 2, addr2 += 2)
1037 				outw(addr2, inw(addr1));
1038 		} else {
1039 			/* dest after src: copy backwards */
1040 			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1041 			    count != 0; count--, addr1 -= 2, addr2 -= 2)
1042 				outw(addr2, inw(addr1));
1043 		}
1044 	}
1045 #endif
1046 #if defined(_I386_BUS_MEMIO_H_)
1047 #if defined(_I386_BUS_PIO_H_)
1048 	else
1049 #endif
1050 	{
1051 		if (addr1 >= addr2) {
1052 			/* src after dest: copy forward */
1053 			for (; count != 0; count--, addr1 += 2, addr2 += 2)
1054 				*(volatile u_int16_t *)(addr2) =
1055 				    *(volatile u_int16_t *)(addr1);
1056 		} else {
1057 			/* dest after src: copy backwards */
1058 			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1059 			    count != 0; count--, addr1 -= 2, addr2 -= 2)
1060 				*(volatile u_int16_t *)(addr2) =
1061 				    *(volatile u_int16_t *)(addr1);
1062 		}
1063 	}
1064 #endif
1065 }
1066 
1067 static __inline void
1068 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
1069 			bus_size_t off1, bus_space_handle_t bsh2,
1070 			bus_size_t off2, size_t count)
1071 {
1072 	bus_addr_t addr1 = bsh1 + off1;
1073 	bus_addr_t addr2 = bsh2 + off2;
1074 
1075 #if defined(_I386_BUS_PIO_H_)
1076 #if defined(_I386_BUS_MEMIO_H_)
1077 	if (tag == I386_BUS_SPACE_IO)
1078 #endif
1079 	{
1080 		if (addr1 >= addr2) {
1081 			/* src after dest: copy forward */
1082 			for (; count != 0; count--, addr1 += 4, addr2 += 4)
1083 				outl(addr2, inl(addr1));
1084 		} else {
1085 			/* dest after src: copy backwards */
1086 			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1087 			    count != 0; count--, addr1 -= 4, addr2 -= 4)
1088 				outl(addr2, inl(addr1));
1089 		}
1090 	}
1091 #endif
1092 #if defined(_I386_BUS_MEMIO_H_)
1093 #if defined(_I386_BUS_PIO_H_)
1094 	else
1095 #endif
1096 	{
1097 		if (addr1 >= addr2) {
1098 			/* src after dest: copy forward */
1099 			for (; count != 0; count--, addr1 += 4, addr2 += 4)
1100 				*(volatile u_int32_t *)(addr2) =
1101 				    *(volatile u_int32_t *)(addr1);
1102 		} else {
1103 			/* dest after src: copy backwards */
1104 			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1105 			    count != 0; count--, addr1 -= 4, addr2 -= 4)
1106 				*(volatile u_int32_t *)(addr2) =
1107 				    *(volatile u_int32_t *)(addr1);
1108 		}
1109 	}
1110 #endif
1111 }
1112 
1113 #endif /* defined(_I386_BUS_PIO_H_) || defined(_I386_MEM_IO_H_) */
1114 
1115 #if 0	/* Cause a link error for bus_space_copy_8 */
1116 #define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
1117 #endif
1118 
1119 /*
1120  * Bus read/write barrier methods.
1121  *
1122  *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
1123  *			       bus_size_t offset, bus_size_t len, int flags);
1124  *
1125  * Note: the i386 does not currently require barriers, but we must
1126  * provide the flags to MI code.
1127  */
1128 #define	bus_space_barrier(t, h, o, l, f)	\
1129 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
1130 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
1131 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
1132 
1133 /*
1134  * Flags used in various bus DMA methods.
1135  */
1136 #define	BUS_DMA_WAITOK		0x00	/* safe to sleep (pseudo-flag) */
1137 #define	BUS_DMA_NOWAIT		0x01	/* not safe to sleep */
1138 #define	BUS_DMA_ALLOCNOW	0x02	/* perform resource allocation now */
1139 #define	BUS_DMAMEM_NOSYNC	0x04	/* map memory to not require sync */
1140 #define	BUS_DMA_BUS1		0x10	/* placeholders for bus functions... */
1141 #define	BUS_DMA_BUS2		0x20
1142 #define	BUS_DMA_BUS3		0x40
1143 #define	BUS_DMA_BUS4		0x80
1144 
1145 /* Forwards needed by prototypes below. */
1146 struct mbuf;
1147 struct uio;
1148 
1149 /*
1150  *	bus_dmasync_op_t
1151  *
1152  *	Operations performed by bus_dmamap_sync().
1153  */
1154 typedef enum {
1155 	BUS_DMASYNC_PREREAD,
1156 	BUS_DMASYNC_POSTREAD,
1157 	BUS_DMASYNC_PREWRITE,
1158 	BUS_DMASYNC_POSTWRITE,
1159 } bus_dmasync_op_t;
1160 
1161 /*
1162  *	bus_dma_tag_t
1163  *
1164  *	A machine-dependent opaque type describing the characteristics
1165  *	of how to perform DMA mappings.  This structure encapsultes
1166  *	information concerning address and alignment restrictions, number
1167  *	of S/G	segments, amount of data per S/G segment, etc.
1168  */
1169 typedef struct bus_dma_tag	*bus_dma_tag_t;
1170 
1171 /*
1172  *	bus_dmamap_t
1173  *
1174  *	DMA mapping instance information.
1175  */
1176 typedef struct bus_dmamap	*bus_dmamap_t;
1177 
1178 /*
1179  *	bus_dma_segment_t
1180  *
1181  *	Describes a single contiguous DMA transaction.  Values
1182  *	are suitable for programming into DMA registers.
1183  */
1184 typedef struct bus_dma_segment {
1185 	bus_addr_t	ds_addr;	/* DMA address */
1186 	bus_size_t	ds_len;		/* length of transfer */
1187 } bus_dma_segment_t;
1188 
1189 /*
1190  * A function that returns 1 if the address cannot be accessed by
1191  * a device and 0 if it can be.
1192  */
1193 typedef int bus_dma_filter_t(void *, bus_addr_t);
1194 
1195 /*
1196  * Allocate a device specific dma_tag encapsulating the constraints of
1197  * the parent tag in addition to other restrictions specified:
1198  *
1199  *	boundary:	Boundary that segments cannot cross.
1200  *	lowaddr:	Low restricted address that cannot appear in a mapping.
1201  *	highaddr:	High restricted address that cannot appear in a mapping.
1202  *	filtfunc:	An optional function to further test if an address
1203  *			within the range of lowaddr and highaddr cannot appear
1204  *			in a mapping.
1205  *	filtfuncarg:	An argument that will be passed to filtfunc in addition
1206  *			to the address to test.
1207  *	flags:		Bus DMA flags.
1208  *	dmat:		A pointer to set to a valid dma tag should the return
1209  *			value of this function indicate success.
1210  */
1211 int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t boundary,
1212 		       bus_addr_t lowaddr, bus_addr_t highaddr,
1213 		       bus_dma_filter_t *filtfunc, void *filtfuncarg,
1214 		       bus_size_t maxsize, int nsegments, bus_size_t maxsegsz,
1215 		       int flags, bus_dma_tag_t *dmat);
1216 
1217 int bus_dma_tag_destroy(bus_dma_tag_t dmat);
1218 
1219 /*
1220  * Allocate a handle for mapping from kva/uva/physical
1221  * address space into bus device space.
1222  *
1223  *	maxsize:	Maximum mapping size supported by this handle.
1224  *	nsegments:	Number of discontinuities allowed in the map.
1225  *	maxsegsz:	Maximum size of a segment in the map.
1226  */
1227 int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp);
1228 
1229 /*
1230  * Destroy  a handle for mapping from kva/uva/physical
1231  * address space into bus device space.
1232  */
1233 int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map);
1234 
1235 /*
1236  * A function that processes a successfully loaded dma map or an error
1237  * from a delayed load map.
1238  */
1239 typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
1240 
1241 /*
1242  * Map the buffer buf into bus space using the dmamap map.
1243  */
1244 int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
1245 		    bus_size_t buflen, bus_dmamap_callback_t *callback,
1246 		    void *callback_arg, int flags);
1247 
1248 /*
1249  * Perform a syncronization operation on the given map.
1250  */
1251 void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t);
1252 #define bus_dmamap_sync(dmat, dmamap, op) 		\
1253 	if ((dmamap) != NULL)				\
1254 		_bus_dmamap_sync(dmat, dmamap, op)
1255 
1256 /*
1257  * Release the mapping held by map.
1258  */
1259 void _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map);
1260 #define bus_dmamap_unload(dmat, dmamap) 		\
1261 	if ((dmamap) != NULL)				\
1262 		_bus_dmamap_unload(dmat, dmamap)
1263 
1264 #endif /* _I386_BUS_H_ */
1265