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