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