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