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