bus.h revision 1.2.16.1 1 /* $NetBSD: bus.h,v 1.2.16.1 2020/04/08 14:07:41 martin Exp $ */
2
3 /*-
4 * Copyright (c) 1996, 1997, 1998, 2001 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 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Copyright (c) 1996 Charles M. Hannum. All rights reserved.
35 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by Christopher G. Demetriou
48 * for the NetBSD Project.
49 * 4. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 */
63
64 #ifndef _IA64_BUS_H_
65 #define _IA64_BUS_H_
66
67 #include <sys/systm.h>
68
69 #include <machine/cpufunc.h>
70 #include <machine/vmparam.h>
71
72 #ifdef BUS_SPACE_DEBUG
73 /*
74 * Macros for sanity-checking the aligned-ness of pointers passed to
75 * bus space ops. These are not strictly necessary on the x86, but
76 * could lead to performance improvements, and help catch problems
77 * with drivers that would creep up on other architectures.
78 */
79 #define __BUS_SPACE_ALIGNED_ADDRESS(p, t) \
80 ((((u_long)(p)) & (sizeof(t)-1)) == 0)
81
82 #define __BUS_SPACE_ADDRESS_SANITY(p, t, d) \
83 ({ \
84 if (__BUS_SPACE_ALIGNED_ADDRESS((p), t) == 0) { \
85 printf("%s 0x%lx not aligned to %d bytes %s:%d\n", \
86 d, (u_long)(p), sizeof(t), __FILE__, __LINE__); \
87 } \
88 (void) 0; \
89 })
90
91 #define BUS_SPACE_ALIGNED_POINTER(p, t) __BUS_SPACE_ALIGNED_ADDRESS(p, t)
92 #else
93 #define __BUS_SPACE_ADDRESS_SANITY(p,t,d) (void) 0
94 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
95 #endif /* BUS_SPACE_DEBUG */
96
97 /*
98 * bus_space_map flags
99 */
100
101 #define BUS_SPACE_MAP_CACHEABLE 0x01
102 #define BUS_SPACE_MAP_LINEAR 0x02
103 #define BUS_SPACE_MAP_PREFETCHABLE 0x04
104
105 /*
106 * Derived from x86 implementation, ia64 has both i/o and mem spaces
107 * These values are for bus space tag.
108 */
109 #define IA64_BUS_SPACE_IO 0 /* space is i/o space */
110 #define IA64_BUS_SPACE_MEM 1 /* space is mem space */
111
112 #define __BUS_SPACE_HAS_STREAM_METHODS 1
113
114 /*
115 * Bus address and size types
116 */
117 typedef u_long bus_addr_t;
118 typedef u_long bus_size_t;
119
120 /*
121 * Access methods for bus resources and address space.
122 */
123 typedef int bus_space_tag_t;
124 typedef u_long bus_space_handle_t;
125
126 /* map/unmap */
127
128 int ia64_bus_space_map(bus_space_tag_t, bus_addr_t,
129 bus_size_t, int, bus_space_handle_t *);
130 void ia64_bus_space_unmap(bus_space_tag_t, bus_space_handle_t,
131 bus_size_t);
132 int ia64_bus_space_subregion(bus_space_tag_t, bus_space_handle_t,
133 bus_size_t, bus_size_t, bus_space_handle_t *);
134 #define bus_space_map(t, a, s, f, hp) \
135 ia64_bus_space_map((t), (a), (s), (f), (hp))
136 #define bus_space_unmap(t, h, s) \
137 ia64_bus_space_unmap((t), (h), (s))
138 #define bus_space_subregion(t, h, o, s, nhp) \
139 ia64_bus_space_subregion((t), (h), (o), (s), (nhp))
140
141 /* vaddr */
142
143 #define bus_space_vaddr(t, h) \
144 ((t) == IA64_BUS_SPACE_MEM ? (void *)(h) : (void *)0)
145
146 /* map to user space */
147
148 paddr_t ia64_bus_space_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
149
150 #define bus_space_mmap(t, b, o, p, f) \
151 ia64_bus_space_mmap((t), (b), (o), (p), (f))
152
153 /* alloc/free */
154
155 int ia64_bus_space_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t,
156 bus_size_t, bus_size_t, bus_size_t, int, bus_addr_t *,
157 bus_space_handle_t *);
158 void ia64_bus_space_free(bus_space_tag_t, bus_space_handle_t, bus_size_t);
159
160 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp) \
161 ia64_bus_space__alloc((t), (rs), (re), (s), (a), (b), (f), (ap), (hp))
162 #define bus_space_free(t, h, s) \
163 ia64_bus_space_free((t), (h), (s))
164
165 /*
166 * uintN_t bus_space_read_N(bus_space_tag_t tag,
167 * bus_space_handle_t bsh, bus_size_t offset);
168 *
169 * Read a 1, 2, 4, or 8 byte quantity from bus space
170 * described by tag/handle/offset.
171 */
172
173 #define bus_space_read_1(t, h, o) \
174 ((t) == IA64_BUS_SPACE_IO ? (inb((h) + (o))) :\
175 (*(volatile uint8_t *)((h) + (o))))
176
177 #define bus_space_read_2(t, h, o) \
178 (__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr"), \
179 ((t) == IA64_BUS_SPACE_IO ? (inw((h) + (o))) : \
180 (*(volatile uint16_t *)((h) + (o)))))
181
182 #define bus_space_read_4(t, h, o) \
183 (__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr"), \
184 ((t) == IA64_BUS_SPACE_IO ? (inl((h) + (o))) : \
185 (*(volatile uint32_t *)((h) + (o)))))
186
187 #define bus_space_read_8(t, h, o) \
188 (__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr"), \
189 ((t) == IA64_BUS_SPACE_IO ? \
190 ({ printf("%s: can't read 8bytes from I/O space\n", __FUNCTION__); 0;}) : \
191 (*(volatile uint64_t *)((h) + (o)))))
192
193 #define bus_space_read_stream_1 bus_space_read_1
194 #define bus_space_read_stream_2 bus_space_read_2
195 #define bus_space_read_stream_4 bus_space_read_4
196 #define bus_space_read_stream_8 bus_space_read_8
197
198 /*
199 * void bus_space_read_multi_N(bus_space_tag_t tag,
200 * bus_space_handle_t bsh, bus_size_t offset,
201 * uintN_t *addr, size_t count);
202 *
203 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
204 * described by tag/handle/offset and copy into buffer provided.
205 */
206
207 #define bus_space_read_multi_1(t, h, o, ptr, cnt) \
208 do { \
209 if ((t) == IA64_BUS_SPACE_IO) { \
210 insb((h) + (o), (ptr), (cnt)); \
211 } else { \
212 int __i; \
213 volatile uint8_t *__p = (uint8_t *)((h) + (o)); \
214 uint8_t *__dst = (ptr); \
215 for (__i = 0; __i < (cnt); __i++) \
216 *__dst++ = *__p; \
217 } \
218 } while (/* CONSTCOND */ 0)
219
220 #define bus_space_read_multi_2(t, h, o, ptr, cnt) \
221 do { \
222 __BUS_SPACE_ADDRESS_SANITY((ptr), uint16_t, "buffer"); \
223 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr"); \
224 if ((t) == IA64_BUS_SPACE_IO) { \
225 insw((h) + (o), (ptr), (cnt)); \
226 } else { \
227 int __i; \
228 volatile uint16_t *__p = (uint16_t *)((h) + (o)); \
229 uint16_t *__dst = (ptr); \
230 for (__i = 0; __i < (cnt); __i++) \
231 *__dst++ = *__p; \
232 } \
233 } while (/* CONSTCOND */ 0)
234
235 #define bus_space_read_multi_4(t, h, o, ptr, cnt) \
236 do { \
237 __BUS_SPACE_ADDRESS_SANITY((ptr), uint32_t, "buffer"); \
238 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr"); \
239 if ((t) == IA64_BUS_SPACE_IO) { \
240 insl((h) + (o), (ptr), (cnt)); \
241 } else { \
242 int __i; \
243 volatile uint32_t *__p = (uint32_t *)((h) + (o)); \
244 uint32_t *__dst = (ptr); \
245 for (__i = 0; __i < (cnt); __i++) \
246 *__dst++ = *__p; \
247 } \
248 } while (/* CONSTCOND */ 0)
249
250 #define bus_space_read_multi_8(t, h, o, ptr, cnt) \
251 do { \
252 __BUS_SPACE_ADDRESS_SANITY((ptr), uint64_t, "buffer"); \
253 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr"); \
254 if ((t) == IA64_BUS_SPACE_IO) { \
255 printf("%s: can't read 8bytes from I/O space\n", \
256 __FUNCTION__); \
257 } else { \
258 int __i; \
259 volatile uint64_t *__p = (uint64_t *)((h) + (o)); \
260 uint64_t *__dst = (ptr); \
261 for (__i = 0; __i < (cnt); __i++) \
262 *__dst++ = *__p; \
263 } \
264 } while (/* CONSTCOND */ 0)
265
266 #define bus_space_read_multi_stream_1 bus_space_read_multi_1
267 #define bus_space_read_multi_stream_2 bus_space_read_multi_2
268 #define bus_space_read_multi_stream_4 bus_space_read_multi_4
269 #define bus_space_read_multi_stream_8 bus_space_read_multi_8
270
271
272 /*
273 * void bus_space_read_region_N(bus_space_tag_t tag,
274 * bus_space_handle_t bsh, bus_size_t offset,
275 * uintN_t *addr, size_t count);
276 *
277 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
278 * described by tag/handle and starting at `offset' and copy into
279 * buffer provided.
280 */
281
282 #define bus_space_read_region_1(t, h, o, ptr, cnt) \
283 do { \
284 if ((t) == IA64_BUS_SPACE_IO) { \
285 int __i; \
286 volatile bus_addr_t __port = (h) + (o); \
287 uint8_t *__dst = (ptr); \
288 for (__i = 0; __i < (cnt); __i++) { \
289 *__dst++ = inb(__port); \
290 __port++; \
291 } \
292 } else { \
293 int __i; \
294 volatile uint8_t *__p = (uint8_t *)((h) + (o)); \
295 uint8_t *__dst = (ptr); \
296 for (__i = 0; __i < (cnt); __i++) \
297 *__dst++ = *__p++; \
298 } \
299 } while (/* CONSTCOND */ 0)
300
301 #define bus_space_read_region_2(t, h, o, ptr, cnt) \
302 do { \
303 __BUS_SPACE_ADDRESS_SANITY((ptr), uint16_t, "buffer"); \
304 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr"); \
305 if ((t) == IA64_BUS_SPACE_IO) { \
306 int __i; \
307 volatile bus_addr_t __port = (h) + (o); \
308 uint8_t *__dst = (ptr); \
309 for (__i = 0; __i < (cnt); __i++) { \
310 *__dst++ = inb(__port); \
311 __port += 2; \
312 } \
313 } else { \
314 int __i; \
315 volatile uint16_t *__p = (uint16_t *)((h) + (o)); \
316 uint16_t *__dst = (ptr); \
317 for (__i = 0; __i < (cnt); __i++) \
318 *__dst++ = *__p++; \
319 } \
320 } while (/* CONSTCOND */ 0)
321
322 #define bus_space_read_region_4(t, h, o, ptr, cnt) \
323 do { \
324 __BUS_SPACE_ADDRESS_SANITY((ptr), uint32_t, "buffer"); \
325 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr"); \
326 if ((t) == IA64_BUS_SPACE_IO) { \
327 int __i; \
328 volatile bus_addr_t __port = (h) + (o); \
329 uint8_t *__dst = (ptr); \
330 for (__i = 0; __i < (cnt); __i++) { \
331 *__dst++ = inb(__port); \
332 __port += 4; \
333 } \
334 } else { \
335 volatile uint32_t *__p = (uint32_t *)((h) + (o)); \
336 uint32_t *__dst = (ptr); \
337 for (__i = 0; __i < (cnt); __i++) \
338 *__dst++ = *__p++; \
339 } \
340 } while (/* CONSTCOND */ 0)
341
342 #define bus_space_read_region_8(t, h, o, ptr, cnt) \
343 do { \
344 __BUS_SPACE_ADDRESS_SANITY((ptr), uint64_t, "buffer"); \
345 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr"); \
346 if ((t) == IA64_BUS_SPACE_IO) { \
347 printf("%s: can't read 8bytes from I/O space\n", \
348 __FUNCTION__); \
349 } else { \
350 volatile uint64_t *__p = (uint64_t *)((h) + (o)); \
351 uint64_t *__dst = (ptr); \
352 for (__i = 0; __i < (cnt); __i++) \
353 *__dst++ = *__p++; \
354 } \
355 } while (/* CONSTCOND */ 0)
356
357 #define bus_space_read_region_stream_1 bus_space_read_region_1
358 #define bus_space_read_region_stream_2 bus_space_read_region_2
359 #define bus_space_read_region_stream_4 bus_space_read_region_4
360 #define bus_space_read_region_stream_8 bus_space_read_region_8
361
362
363 /*
364 * void bus_space_write_N(bus_space_tag_t tag,
365 * bus_space_handle_t bsh, bus_size_t offset,
366 * uintN_t value);
367 *
368 * Write the 1, 2, 4, or 8 byte value `value' to bus space
369 * described by tag/handle/offset.
370 */
371
372 #define bus_space_write_1(t, h, o, v) \
373 do { \
374 if ((t) == IA64_BUS_SPACE_IO) \
375 outb((h) + (o), (v)); \
376 else \
377 ((void)(*(volatile uint8_t *)((h) + (o)) = (v))); \
378 } while (/* CONSTCOND */ 0)
379
380 #define bus_space_write_2(t, h, o, v) \
381 do { \
382 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr"); \
383 if ((t) == IA64_BUS_SPACE_IO) \
384 outw((h) + (o), (v)); \
385 else \
386 ((void)(*(volatile uint16_t *)((h) + (o)) = (v))); \
387 } while (/* CONSTCOND */ 0)
388
389 #define bus_space_write_4(t, h, o, v) \
390 do { \
391 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr"); \
392 if ((t) == IA64_BUS_SPACE_IO) \
393 outl((h) + (o), (v)); \
394 else \
395 ((void)(*(volatile uint32_t *)((h) + (o)) = (v))); \
396 } while (/* CONSTCOND */ 0)
397
398 #define bus_space_write_8(t, h, o, v) \
399 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr"); \
400 if ((t) == IA64_BUS_SPACE_IO ? \
401 printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__); : \
402 (*(volatile uint64_t *)((h) + (o)) = (v)))
403
404 #define bus_space_write_stream_1 bus_space_write_1
405 #define bus_space_write_stream_2 bus_space_write_2
406 #define bus_space_write_stream_4 bus_space_write_4
407 #define bus_space_write_stream_8 bus_space_write_8
408
409 /*
410 * void bus_space_write_multi_N(bus_space_tag_t tag,
411 * bus_space_handle_t bsh, bus_size_t offset,
412 * const uintN_t *addr, size_t count);
413 *
414 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
415 * provided to bus space described by tag/handle/offset.
416 */
417
418 #define bus_space_write_multi_1(t, h, o, ptr, cnt) \
419 do { \
420 if ((t) == IA64_BUS_SPACE_IO) { \
421 outsb((h) + (o), (ptr), (cnt)); \
422 } else { \
423 int __i; \
424 volatile uint8_t *__p = (uint8_t *)((h) + (o)); \
425 uint8_t *__src = (ptr); \
426 for (__i = 0; __i < (cnt); __i++) \
427 *__p = *__src++; \
428 } \
429 } while (/* CONSTCOND */ 0)
430
431 #define bus_space_write_multi_2(t, h, o, ptr, cnt) \
432 do { \
433 __BUS_SPACE_ADDRESS_SANITY((ptr), uint16_t, "buffer"); \
434 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr"); \
435 if ((t) == IA64_BUS_SPACE_IO) { \
436 outsw((h) + (o), (ptr), (cnt)); \
437 } else { \
438 int __i; \
439 volatile uint16_t *__p = (uint16_t *)((h) + (o)); \
440 uint16_t *__src = (ptr); \
441 for (__i = 0; __i < (cnt); __i++) \
442 *__p = *__src++; \
443 } \
444 } while (/* CONSTCOND */ 0)
445
446 #define bus_space_write_multi_4(t, h, o, ptr, cnt) \
447 do { \
448 __BUS_SPACE_ADDRESS_SANITY((ptr), uint32_t, "buffer"); \
449 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr"); \
450 if ((t) == IA64_BUS_SPACE_IO) { \
451 outsl((h) + (o), (ptr), (cnt)); \
452 } else { \
453 int __i; \
454 volatile uint32_t *__p = (uint32_t *)((h) + (o)); \
455 uint32_t *__src = (ptr); \
456 for (__i = 0; __i < (cnt); __i++) \
457 *__p = *__src++; \
458 } \
459 } while (/* CONSTCOND */ 0)
460
461 #define bus_space_write_multi_8(t, h, o, ptr, cnt) \
462 do { \
463 __BUS_SPACE_ADDRESS_SANITY((ptr), uint64_t, "buffer"); \
464 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr"); \
465 if ((t) == IA64_BUS_SPACE_IO) { \
466 printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__);\
467 } else { \
468 int __i; \
469 volatile uint64_t *__p = (uint64_t *)((h) + (o)); \
470 uint64_t *__src = (ptr); \
471 for (__i = 0; __i < (cnt); __i++) \
472 *__p = *__src++; \
473 } \
474 } while (/* CONSTCOND */ 0)
475
476 #define bus_space_write_multi_stream_1 bus_space_write_multi_1
477 #define bus_space_write_multi_stream_2 bus_space_write_multi_2
478 #define bus_space_write_multi_stream_4 bus_space_write_multi_4
479 #define bus_space_write_multi_stream_8 bus_space_write_multi_8
480
481
482 /*
483 * void bus_space_write_region_N(bus_space_tag_t tag,
484 * bus_space_handle_t bsh, bus_size_t offset,
485 * const uintN_t *addr, size_t count);
486 *
487 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
488 * to bus space described by tag/handle starting at `offset'.
489 */
490
491 #define bus_space_write_region_1(t, h, o, ptr, cnt) \
492 do { \
493 if ((t) == IA64_BUS_SPACE_IO) { \
494 int __i; \
495 volatile bus_addr_t __port = (h) + (o); \
496 uint8_t *__src = (ptr); \
497 for (__i = 0; __i < (cnt); __i++) { \
498 outb(__port, *__src); \
499 __port++; \
500 __src++; \
501 } \
502 } else { \
503 int __i; \
504 volatile uint8_t *__p = (uint8_t *)((h) + (o)); \
505 uint8_t *__src = (ptr); \
506 for (__i = 0; __i < (cnt); __i++) \
507 *__p++ = *__src++; \
508 } \
509 } while (/* CONSTCOND */ 0)
510
511 #define bus_space_write_region_2(t, h, o, ptr, cnt) \
512 do { \
513 __BUS_SPACE_ADDRESS_SANITY((ptr), uint16_t, "buffer"); \
514 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr"); \
515 if ((t) == IA64_BUS_SPACE_IO) { \
516 int __i; \
517 volatile bus_addr_t __port = (h) + (o); \
518 uint16_t *__src = (ptr); \
519 for (__i = 0; __i < (cnt); __i++) { \
520 outw(__port, *__src); \
521 __port += 2; \
522 __src++; \
523 } \
524 } else { \
525 int __i; \
526 volatile uint16_t *__p = (uint16_t *)((h) + (o)); \
527 uint16_t *__src = (ptr); \
528 for (__i = 0; __i < (cnt); __i++) \
529 *__p++ = *__src++; \
530 } \
531 } while (/* CONSTCOND */ 0)
532
533 #define bus_space_write_region_4(t, h, o, ptr, cnt) \
534 do { \
535 __BUS_SPACE_ADDRESS_SANITY((ptr), uint32_t, "buffer"); \
536 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr"); \
537 if ((t) == IA64_BUS_SPACE_IO) { \
538 int __i; \
539 volatile bus_addr_t __port = (h) + (o); \
540 uint32_t *__src = (ptr); \
541 for (__i = 0; __i < (cnt); __i++) { \
542 outl(__port, *__src); \
543 __port += 4; \
544 __src++; \
545 } \
546 } else { \
547 int __i; \
548 volatile uint32_t *__p = (uint32_t *)(h) + (o); \
549 uint32_t *__src = (ptr); \
550 for (__i = 0; __i < (cnt); __i++) \
551 *__p++ = *__src++; \
552 } \
553 } while (/* CONSTCOND */ 0)
554
555 #define bus_space_write_region_8(t, h, o, ptr, cnt) \
556 do { \
557 __BUS_SPACE_ADDRESS_SANITY((ptr), uint64_t, "buffer"); \
558 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr"); \
559 if ((t) == IA64_BUS_SPACE_IO) { \
560 printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__);\
561 } else { \
562 int __i; \
563 volatile uint64_t *__p = (uint64_t *)((h) + (o)); \
564 uint64_t *__src = (ptr); \
565 for (__i = 0; __i < (cnt); __i++) \
566 *__p++ = *__src++; \
567 } \
568 } while (/* CONSTCOND */ 0)
569
570 #define bus_space_write_region_stream_1 bus_space_write_region_1
571 #define bus_space_write_region_stream_2 bus_space_write_region_2
572 #define bus_space_write_region_stream_4 bus_space_write_region_4
573 #define bus_space_write_region_stream_8 bus_space_write_region_8
574
575
576 /*
577 * void bus_space_set_multi_N(bus_space_tag_t tag,
578 * bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
579 * size_t count);
580 *
581 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
582 * by tag/handle/offset `count' times.
583 */
584
585 static __inline void ia64_bus_space_set_multi_1(bus_space_tag_t,
586 bus_space_handle_t, bus_size_t, uint8_t, size_t);
587 static __inline void ia64_bus_space_set_multi_2(bus_space_tag_t,
588 bus_space_handle_t, bus_size_t, uint16_t, size_t);
589 static __inline void ia64_bus_space_set_multi_4(bus_space_tag_t,
590 bus_space_handle_t, bus_size_t, uint32_t, size_t);
591 static __inline void ia64_bus_space_set_multi_8(bus_space_tag_t,
592 bus_space_handle_t, bus_size_t, uint64_t, size_t);
593
594 #define bus_space_set_multi_1(t, h, o, v, c) \
595 ia64_bus_space_set_multi_1((t), (h), (o), (v), (c))
596
597 #define bus_space_set_multi_2(t, h, o, v, c) \
598 do { \
599 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr"); \
600 ia64_bus_space_set_multi_2((t), (h), (o), (v), (c)); \
601 } while (/* CONSTCOND */ 0)
602
603 #define bus_space_set_multi_4(t, h, o, v, c) \
604 do { \
605 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr"); \
606 ia64_bus_space_set_multi_4((t), (h), (o), (v), (c)); \
607 } while (/* CONSTCOND */ 0)
608
609 #define bus_space_set_multi_8(t, h, o, v, c) \
610 do { \
611 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr"); \
612 ia64_bus_space_set_multi_8((t), (h), (o), (v), (c)); \
613 } while (/* CONSTCOND */ 0)
614
615 static __inline void
616 ia64_bus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h,
617 bus_size_t o, uint8_t v, size_t c)
618 {
619 bus_addr_t addr = h + o;
620
621 if (t == IA64_BUS_SPACE_IO)
622 while (c--)
623 outb(addr, v);
624 else
625 while (c--)
626 *(volatile uint8_t *)(addr) = v;
627 }
628
629 static __inline void
630 ia64_bus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h,
631 bus_size_t o, uint16_t v, size_t c)
632 {
633 bus_addr_t addr = h + o;
634
635 if (t == IA64_BUS_SPACE_IO)
636 while (c--)
637 outw(addr, v);
638 else
639 while (c--)
640 *(volatile uint16_t *)(addr) = v;
641 }
642
643 static __inline void
644 ia64_bus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h,
645 bus_size_t o, uint32_t v, size_t c)
646 {
647 bus_addr_t addr = h + o;
648
649 if (t == IA64_BUS_SPACE_IO)
650 while (c--)
651 outl(addr, v);
652 else
653 while (c--)
654 *(volatile uint32_t *)(addr) = v;
655 }
656
657 static __inline void
658 ia64_bus_space_set_multi_8(bus_space_tag_t t, bus_space_handle_t h,
659 bus_size_t o, uint64_t v, size_t c)
660 {
661 bus_addr_t addr = h + o;
662
663 if (t == IA64_BUS_SPACE_IO)
664 printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__);
665 else
666 while (c--)
667 *(volatile uint64_t *)(addr) = v;
668 }
669
670
671 /*
672 * void bus_space_set_region_N(bus_space_tag_t tag,
673 * bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
674 * size_t count);
675 *
676 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
677 * by tag/handle starting at `offset'.
678 */
679
680 static __inline void ia64_bus_space_set_region_1(bus_space_tag_t,
681 bus_space_handle_t, bus_size_t, uint8_t, size_t);
682 static __inline void ia64_bus_space_set_region_2(bus_space_tag_t,
683 bus_space_handle_t, bus_size_t, uint16_t, size_t);
684 static __inline void ia64_bus_space_set_region_4(bus_space_tag_t,
685 bus_space_handle_t, bus_size_t, uint32_t, size_t);
686
687 #define bus_space_set_region_1(t, h, o, v, c) \
688 ia64_bus_space_set_region_1((t), (h), (o), (v), (c))
689
690 #define bus_space_set_region_2(t, h, o, v, c) \
691 do { \
692 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr"); \
693 ia64_bus_space_set_region_2((t), (h), (o), (v), (c)); \
694 } while (/* CONSTCOND */ 0)
695
696 #define bus_space_set_region_4(t, h, o, v, c) \
697 do { \
698 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr"); \
699 ia64_bus_space_set_region_4((t), (h), (o), (v), (c)); \
700 } while (/* CONSTCOND */ 0)
701
702 #define bus_space_set_region_8(t, h, o, v, c) \
703 do { \
704 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr"); \
705 ia64_bus_space_set_region_8((t), (h), (o), (v), (c)); \
706 } while (/* CONSTCOND */ 0)
707
708 static __inline void
709 ia64_bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h,
710 bus_size_t o, uint8_t v, size_t c)
711 {
712 bus_addr_t addr = h + o;
713
714 if (t == IA64_BUS_SPACE_IO)
715 for (; c != 0; c--, addr++)
716 outb(addr, v);
717 else
718 for (; c != 0; c--, addr++)
719 *(volatile uint8_t *)(addr) = v;
720 }
721
722 static __inline void
723 ia64_bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h,
724 bus_size_t o, uint16_t v, size_t c)
725 {
726 bus_addr_t addr = h + o;
727
728 if (t == IA64_BUS_SPACE_IO)
729 for (; c != 0; c--, addr += 2)
730 outw(addr, v);
731 else
732 for (; c != 0; c--, addr += 2)
733 *(volatile uint16_t *)(addr) = v;
734 }
735
736 static __inline void
737 ia64_bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h,
738 bus_size_t o, uint32_t v, size_t c)
739 {
740 bus_addr_t addr = h + o;
741
742 if (t == IA64_BUS_SPACE_IO)
743 for (; c != 0; c--, addr += 4)
744 outl(addr, v);
745 else
746 for (; c != 0; c--, addr += 4)
747 *(volatile uint32_t *)(addr) = v;
748 }
749
750 static __inline void
751 ia64_bus_space_set_region_8(bus_space_tag_t t, bus_space_handle_t h,
752 bus_size_t o, uint64_t v, size_t c)
753 {
754 bus_addr_t addr = h + o;
755
756 if (t == IA64_BUS_SPACE_IO)
757 printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__);
758 else
759 for (; c != 0; c--, addr += 8)
760 *(volatile uint32_t *)(addr) = v;
761 }
762
763
764 /*
765 * void bus_space_copy_region_N(bus_space_tag_t tag,
766 * bus_space_handle_t bsh1, bus_size_t off1,
767 * bus_space_handle_t bsh2, bus_size_t off2,
768 * size_t count);
769 *
770 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
771 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
772 */
773
774 static __inline void ia64_bus_space_copy_region_1(bus_space_tag_t,
775 bus_space_handle_t, bus_size_t, bus_space_handle_t,
776 bus_size_t, size_t);
777 static __inline void ia64_bus_space_copy_region_2(bus_space_tag_t,
778 bus_space_handle_t, bus_size_t, bus_space_handle_t,
779 bus_size_t, size_t);
780 static __inline void ia64_bus_space_copy_region_4(bus_space_tag_t,
781 bus_space_handle_t, bus_size_t, bus_space_handle_t,
782 bus_size_t, size_t);
783
784 #define bus_space_copy_region_1(t, h1, o1, h2, o2, c) \
785 ia64_bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
786
787 #define bus_space_copy_region_2(t, h1, o1, h2, o2, c) \
788 do { \
789 __BUS_SPACE_ADDRESS_SANITY((h1) + (o1), uint16_t, "bus addr 1"); \
790 __BUS_SPACE_ADDRESS_SANITY((h2) + (o2), uint16_t, "bus addr 2"); \
791 ia64_bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c)); \
792 } while (/* CONSTCOND */ 0)
793
794 #define bus_space_copy_region_4(t, h1, o1, h2, o2, c) \
795 do { \
796 __BUS_SPACE_ADDRESS_SANITY((h1) + (o1), uint32_t, "bus addr 1"); \
797 __BUS_SPACE_ADDRESS_SANITY((h2) + (o2), uint32_t, "bus addr 2"); \
798 ia64_bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c)); \
799 } while (/* CONSTCOND */ 0)
800
801 #define bus_space_copy_region_8(t, h1, o1, h2, o2, c) \
802 do { \
803 __BUS_SPACE_ADDRESS_SANITY((h1) + (o1), uint64_t, "bus addr 1"); \
804 __BUS_SPACE_ADDRESS_SANITY((h2) + (o2), uint64_t, "bus addr 2"); \
805 ia64_bus_space_copy_region_8((t), (h1), (o1), (h2), (o2), (c)); \
806 } while (/* CONSTCOND */ 0)
807
808 static __inline void
809 ia64_bus_space_copy_region_1(bus_space_tag_t t,
810 bus_space_handle_t h1, bus_size_t o1,
811 bus_space_handle_t h2, bus_size_t o2, size_t c)
812 {
813 bus_addr_t addr1 = h1 + o1;
814 bus_addr_t addr2 = h2 + o2;
815
816 if (t == IA64_BUS_SPACE_IO) {
817 if (addr1 >= addr2) {
818 /* src after dest: copy forward */
819 for (; c != 0; c--, addr1++, addr2++)
820 outb(addr2, inb(addr1));
821 } else {
822 /* dest after src: copy backwards */
823 for (addr1 += (c - 1), addr2 += (c - 1);
824 c != 0; c--, addr1--, addr2--)
825 outb(addr2, inb(addr1));
826 }
827 } else {
828 if (addr1 >= addr2) {
829 /* src after dest: copy forward */
830 for (; c != 0; c--, addr1++, addr2++)
831 *(volatile uint8_t *)(addr2) =
832 *(volatile uint8_t *)(addr1);
833 } else {
834 /* dest after src: copy backwards */
835 for (addr1 += (c - 1), addr2 += (c - 1);
836 c != 0; c--, addr1--, addr2--)
837 *(volatile uint8_t *)(addr2) =
838 *(volatile uint8_t *)(addr1);
839 }
840 }
841 }
842
843 static __inline void
844 ia64_bus_space_copy_region_2(bus_space_tag_t t,
845 bus_space_handle_t h1, bus_size_t o1,
846 bus_space_handle_t h2, bus_size_t o2, size_t c)
847 {
848 bus_addr_t addr1 = h1 + o1;
849 bus_addr_t addr2 = h2 + o2;
850
851 if (t == IA64_BUS_SPACE_IO) {
852 if (addr1 >= addr2) {
853 /* src after dest: copy forward */
854 for (; c != 0; c--, addr1 += 2, addr2 += 2)
855 outw(addr2, inw(addr1));
856 } else {
857 /* dest after src: copy backwards */
858 for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
859 c != 0; c--, addr1 -= 2, addr2 -= 2)
860 outw(addr2, inw(addr1));
861 }
862 } else {
863 if (addr1 >= addr2) {
864 /* src after dest: copy forward */
865 for (; c != 0; c--, addr1 += 2, addr2 += 2)
866 *(volatile uint16_t *)(addr2) =
867 *(volatile uint16_t *)(addr1);
868 } else {
869 /* dest after src: copy backwards */
870 for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
871 c != 0; c--, addr1 -= 2, addr2 -= 2)
872 *(volatile uint16_t *)(addr2) =
873 *(volatile uint16_t *)(addr1);
874 }
875 }
876 }
877
878 static __inline void
879 ia64_bus_space_copy_region_4(bus_space_tag_t t,
880 bus_space_handle_t h1, bus_size_t o1,
881 bus_space_handle_t h2, bus_size_t o2, size_t c)
882 {
883 bus_addr_t addr1 = h1 + o1;
884 bus_addr_t addr2 = h2 + o2;
885
886 if (t == IA64_BUS_SPACE_IO) {
887 if (addr1 >= addr2) {
888 /* src after dest: copy forward */
889 for (; c != 0; c--, addr1 += 4, addr2 += 4)
890 outl(addr2, inl(addr1));
891 } else {
892 /* dest after src: copy backwards */
893 for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
894 c != 0; c--, addr1 -= 4, addr2 -= 4)
895 outl(addr2, inl(addr1));
896 }
897 } else {
898 if (addr1 >= addr2) {
899 /* src after dest: copy forward */
900 for (; c != 0; c--, addr1 += 4, addr2 += 4)
901 *(volatile uint32_t *)(addr2) =
902 *(volatile uint32_t *)(addr1);
903 } else {
904 /* dest after src: copy backwards */
905 for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
906 c != 0; c--, addr1 -= 4, addr2 -= 4)
907 *(volatile uint32_t *)(addr2) =
908 *(volatile uint32_t *)(addr1);
909 }
910 }
911 }
912
913 static __inline void
914 ia64_bus_space_copy_region_8(bus_space_tag_t t,
915 bus_space_handle_t h1, bus_size_t o1,
916 bus_space_handle_t h2, bus_size_t o2, size_t c)
917 {
918 bus_addr_t addr1 = h1 + o1;
919 bus_addr_t addr2 = h2 + o2;
920
921 if (t == IA64_BUS_SPACE_IO) {
922 printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__);
923 } else {
924 if (addr1 >= addr2) {
925 /* src after dest: copy forward */
926 for (; c != 0; c--, addr1 += 8, addr2 += 8)
927 *(volatile uint64_t *)(addr2) =
928 *(volatile uint64_t *)(addr1);
929 } else {
930 /* dest after src: copy backwards */
931 for (addr1 += 8 * (c - 1), addr2 += 8 * (c - 1);
932 c != 0; c--, addr1 -= 8, addr2 -= 8)
933 *(volatile uint64_t *)(addr2) =
934 *(volatile uint64_t *)(addr1);
935 }
936 }
937 }
938
939
940 /*
941 * Bus read/write barrier methods.
942 *
943 * void bus_space_barrier(bus_space_tag_t tag,
944 * bus_space_handle_t bsh, bus_size_t offset,
945 * bus_size_t len, int flags);
946 *
947 * Note: the x86 does not currently require barriers, but we must
948 * provide the flags to MI code.
949 */
950 #define bus_space_barrier(t, h, o, l, f) \
951 ia64_bus_space_barrier((t), (h), (o), (l), (f))
952
953 #define BUS_SPACE_BARRIER_READ 0x01
954 #define BUS_SPACE_BARRIER_WRITE 0x02
955
956 static __inline void
957 ia64_bus_space_barrier(bus_space_tag_t t, bus_space_handle_t handle,
958 bus_size_t offset, bus_size_t length, int flags)
959 {
960 if (t == IA64_BUS_SPACE_IO)
961 return;
962
963 switch (flags) {
964 case BUS_SPACE_BARRIER_READ:
965 __asm volatile("mf" ::: "memory");
966 break;
967 case BUS_SPACE_BARRIER_WRITE:
968 __asm volatile("mf" ::: "memory");
969 break;
970 case BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE:
971 __asm volatile("mf" ::: "memory");
972 break;
973 default:
974 printf("%s: Unknown barrier %d\n", __FUNCTION__, flags);
975 break;
976 }
977 }
978
979
980 /*
981 * Flags used in various bus DMA methods.
982 */
983 #define BUS_DMA_WAITOK 0x000 /* safe to sleep (pseudo-flag) */
984 #define BUS_DMA_NOWAIT 0x001 /* not safe to sleep */
985 #define BUS_DMA_ALLOCNOW 0x002 /* perform resource allocation now */
986 #define BUS_DMA_COHERENT 0x004 /* hint: map memory DMA coherent */
987 #define BUS_DMA_STREAMING 0x008 /* hint: sequential, unidirectional */
988 #define BUS_DMA_BUS1 0x010 /* placeholders for bus functions... */
989 #define BUS_DMA_BUS2 0x020
990 #define BUS_DMA_BUS3 0x040
991 #define BUS_DMA_BUS4 0x080
992 #define BUS_DMA_READ 0x100 /* mapping is device -> memory only */
993 #define BUS_DMA_WRITE 0x200 /* mapping is memory -> device only */
994 #define BUS_DMA_NOCACHE 0x400 /* hint: map non-cached memory */
995
996 /* Forwards needed by prototypes below. */
997 struct mbuf;
998 struct uio;
999
1000 /*
1001 * Operations performed by bus_dmamap_sync().
1002 */
1003 #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */
1004 #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */
1005 #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */
1006 #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */
1007
1008 typedef struct ia64_bus_dma_tag *bus_dma_tag_t;
1009 typedef struct ia64_bus_dmamap *bus_dmamap_t;
1010
1011 #define BUS_DMA_TAG_VALID(t) ((t) != (bus_dma_tag_t)0)
1012
1013 /*
1014 * bus_dma_segment_t
1015 *
1016 * Describes a single contiguous DMA transaction. Values
1017 * are suitable for programming into DMA registers.
1018 */
1019 struct ia64_bus_dma_segment {
1020 bus_addr_t ds_addr; /* DMA address */
1021 bus_size_t ds_len; /* length of transfer */
1022 };
1023 typedef struct ia64_bus_dma_segment bus_dma_segment_t;
1024
1025 /*
1026 * bus_dma_tag_t
1027 *
1028 * A machine-dependent opaque type describing the implementation of
1029 * DMA for a given bus.
1030 */
1031
1032 struct ia64_bus_dma_tag {
1033 /*
1034 * The `bounce threshold' is checked while we are loading
1035 * the DMA map. If the physical address of the segment
1036 * exceeds the threshold, an error will be returned. The
1037 * caller can then take whatever action is necessary to
1038 * bounce the transfer. If this value is 0, it will be
1039 * ignored.
1040 */
1041 bus_addr_t _bounce_thresh;
1042 bus_addr_t _bounce_alloc_lo;
1043 bus_addr_t _bounce_alloc_hi;
1044 int (*_may_bounce)(bus_dma_tag_t, bus_dmamap_t, int, int *);
1045
1046 /*
1047 * DMA mapping methods.
1048 */
1049 int (*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
1050 bus_size_t, bus_size_t, int, bus_dmamap_t *);
1051 void (*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
1052 int (*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
1053 bus_size_t, struct proc *, int);
1054 int (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
1055 struct mbuf *, int);
1056 int (*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
1057 struct uio *, int);
1058 int (*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
1059 bus_dma_segment_t *, int, bus_size_t, int);
1060 void (*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
1061 void (*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
1062 bus_addr_t, bus_size_t, int);
1063
1064 /*
1065 * DMA memory utility functions.
1066 */
1067 int (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
1068 bus_size_t, bus_dma_segment_t *, int, int *, int);
1069 void (*_dmamem_free)(bus_dma_tag_t, bus_dma_segment_t *, int);
1070 int (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
1071 int, size_t, void **, int);
1072 void (*_dmamem_unmap)(bus_dma_tag_t, void *, size_t);
1073 paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
1074 int, off_t, int, int);
1075 };
1076
1077 static __inline void bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t,
1078 bus_addr_t, bus_size_t, int) __attribute__((__unused__));
1079
1080 #define bus_dmamap_create(t, s, n, m, b, f, p) \
1081 (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
1082 #define bus_dmamap_destroy(t, p) \
1083 (*(t)->_dmamap_destroy)((t), (p))
1084 #define bus_dmamap_load(t, m, b, s, p, f) \
1085 (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
1086 #define bus_dmamap_load_mbuf(t, m, b, f) \
1087 (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
1088 #define bus_dmamap_load_uio(t, m, u, f) \
1089 (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
1090 #define bus_dmamap_load_raw(t, m, sg, n, s, f) \
1091 (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
1092 #define bus_dmamap_unload(t, p) \
1093 (*(t)->_dmamap_unload)((t), (p))
1094 static __inline void
1095 bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t p, bus_addr_t o, bus_size_t l,
1096 int ops)
1097 {
1098 /* if (ops & BUS_DMASYNC_POSTREAD)
1099 x86_lfence(); */
1100 if (t->_dmamap_sync)
1101 (*t->_dmamap_sync)(t, p, o, l, ops);
1102 }
1103
1104 #define bus_dmamem_alloc(t, s, a, b, sg, n, r, f) \
1105 (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
1106 #define bus_dmamem_free(t, sg, n) \
1107 (*(t)->_dmamem_free)((t), (sg), (n))
1108 #define bus_dmamem_map(t, sg, n, s, k, f) \
1109 (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
1110 #define bus_dmamem_unmap(t, k, s) \
1111 (*(t)->_dmamem_unmap)((t), (k), (s))
1112 #define bus_dmamem_mmap(t, sg, n, o, p, f) \
1113 (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
1114
1115 /*
1116 * bus_dmamap_t
1117 *
1118 * Describes a DMA mapping.
1119 */
1120 struct ia64_bus_dmamap {
1121 /*
1122 * PRIVATE MEMBERS: not for use by machine-independent code.
1123 */
1124 bus_size_t _dm_size; /* largest DMA transfer mappable */
1125 int _dm_segcnt; /* number of segs this map can map */
1126 bus_size_t _dm_maxmaxsegsz; /* fixed largest possible segment */
1127 bus_size_t _dm_boundary; /* don't cross this */
1128 bus_addr_t _dm_bounce_thresh; /* bounce threshold; see tag */
1129 int _dm_flags; /* misc. flags */
1130
1131 void *_dm_cookie; /* cookie for bus-specific functions */
1132
1133 /*
1134 * PUBLIC MEMBERS: these are used by machine-independent code.
1135 */
1136 bus_size_t dm_maxsegsz; /* largest possible segment */
1137 bus_size_t dm_mapsize; /* size of the mapping */
1138 int dm_nsegs; /* # valid segments in mapping */
1139 bus_dma_segment_t dm_segs[1]; /* segments; variable length */
1140 };
1141
1142 #endif /* _IA64_BUS_H_ */
1143