1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/conf.h> 30 #include <sys/kmem.h> 31 #include <sys/ddi_impldefs.h> 32 #include <sys/ddi.h> 33 #include <sys/sunddi.h> 34 #include <sys/ddifm.h> 35 36 37 /* 38 * DDI DMA Engine functions for x86. 39 * These functions are more naturally generic, but do not apply to SPARC. 40 */ 41 42 int 43 ddi_dmae_alloc(dev_info_t *dip, int chnl, int (*dmae_waitfp)(), caddr_t arg) 44 { 45 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_ACQUIRE, 46 (off_t *)dmae_waitfp, (size_t *)arg, 47 (caddr_t *)(uintptr_t)chnl, 0)); 48 } 49 50 int 51 ddi_dmae_release(dev_info_t *dip, int chnl) 52 { 53 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_FREE, 0, 0, 54 (caddr_t *)(uintptr_t)chnl, 0)); 55 } 56 57 int 58 ddi_dmae_getlim(dev_info_t *dip, ddi_dma_lim_t *limitsp) 59 { 60 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_GETLIM, 0, 0, 61 (caddr_t *)limitsp, 0)); 62 } 63 64 int 65 ddi_dmae_getattr(dev_info_t *dip, ddi_dma_attr_t *attrp) 66 { 67 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_GETATTR, 0, 0, 68 (caddr_t *)attrp, 0)); 69 } 70 71 int 72 ddi_dmae_1stparty(dev_info_t *dip, int chnl) 73 { 74 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_1STPTY, 0, 0, 75 (caddr_t *)(uintptr_t)chnl, 0)); 76 } 77 78 int 79 ddi_dmae_prog(dev_info_t *dip, struct ddi_dmae_req *dmaereqp, 80 ddi_dma_cookie_t *cookiep, int chnl) 81 { 82 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_PROG, (off_t *)dmaereqp, 83 (size_t *)cookiep, (caddr_t *)(uintptr_t)chnl, 0)); 84 } 85 86 int 87 ddi_dmae_swsetup(dev_info_t *dip, struct ddi_dmae_req *dmaereqp, 88 ddi_dma_cookie_t *cookiep, int chnl) 89 { 90 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_SWSETUP, (off_t *)dmaereqp, 91 (size_t *)cookiep, (caddr_t *)(uintptr_t)chnl, 0)); 92 } 93 94 int 95 ddi_dmae_swstart(dev_info_t *dip, int chnl) 96 { 97 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_SWSTART, 0, 0, 98 (caddr_t *)(uintptr_t)chnl, 0)); 99 } 100 101 int 102 ddi_dmae_stop(dev_info_t *dip, int chnl) 103 { 104 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_STOP, 0, 0, 105 (caddr_t *)(uintptr_t)chnl, 0)); 106 } 107 108 int 109 ddi_dmae_enable(dev_info_t *dip, int chnl) 110 { 111 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_ENABLE, 0, 0, 112 (caddr_t *)(uintptr_t)chnl, 0)); 113 } 114 115 int 116 ddi_dmae_disable(dev_info_t *dip, int chnl) 117 { 118 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_DISABLE, 0, 0, 119 (caddr_t *)(uintptr_t)chnl, 0)); 120 } 121 122 int 123 ddi_dmae_getcnt(dev_info_t *dip, int chnl, int *countp) 124 { 125 return (ddi_dma_mctl(dip, dip, 0, DDI_DMA_E_GETCNT, 0, (size_t *)countp, 126 (caddr_t *)(uintptr_t)chnl, 0)); 127 } 128 129 /* 130 * implementation specific access handle and routines: 131 */ 132 133 static uintptr_t impl_acc_hdl_id = 0; 134 135 /* 136 * access handle allocator 137 */ 138 ddi_acc_hdl_t * 139 impl_acc_hdl_get(ddi_acc_handle_t hdl) 140 { 141 /* 142 * recast to ddi_acc_hdl_t instead of 143 * casting to ddi_acc_impl_t and then return the ah_platform_private 144 * 145 * this optimization based on the ddi_acc_hdl_t is the 146 * first member of the ddi_acc_impl_t. 147 */ 148 return ((ddi_acc_hdl_t *)hdl); 149 } 150 151 ddi_acc_handle_t 152 impl_acc_hdl_alloc(int (*waitfp)(caddr_t), caddr_t arg) 153 { 154 ddi_acc_impl_t *hp; 155 int sleepflag; 156 157 sleepflag = ((waitfp == (int (*)())KM_SLEEP) ? KM_SLEEP : KM_NOSLEEP); 158 /* 159 * Allocate and initialize the data access handle. 160 */ 161 hp = kmem_zalloc(sizeof (ddi_acc_impl_t), sleepflag); 162 if (!hp) { 163 if ((waitfp != (int (*)())KM_SLEEP) && 164 (waitfp != (int (*)())KM_NOSLEEP)) 165 ddi_set_callback(waitfp, arg, &impl_acc_hdl_id); 166 return (NULL); 167 } 168 hp->ahi_common.ah_platform_private = (void *)hp; 169 return ((ddi_acc_handle_t)hp); 170 } 171 172 void 173 impl_acc_hdl_free(ddi_acc_handle_t handle) 174 { 175 ddi_acc_impl_t *hp; 176 177 hp = (ddi_acc_impl_t *)handle; 178 if (hp) { 179 kmem_free(hp, sizeof (*hp)); 180 if (impl_acc_hdl_id) 181 ddi_run_callback(&impl_acc_hdl_id); 182 } 183 } 184 185 void 186 impl_acc_err_init(ddi_acc_hdl_t *handlep) 187 { 188 /* Error handling not supported */ 189 handlep->ah_acc.devacc_attr_access = DDI_DEFAULT_ACC; 190 } 191 192 void 193 impl_acc_hdl_init(ddi_acc_hdl_t *handlep) 194 { 195 ddi_acc_impl_t *hp; 196 197 if (!handlep) 198 return; 199 hp = (ddi_acc_impl_t *)handlep->ah_platform_private; 200 201 if (hp->ahi_acc_attr & DDI_ACCATTR_IO_SPACE) { 202 hp->ahi_get8 = i_ddi_io_get8; 203 hp->ahi_put8 = i_ddi_io_put8; 204 hp->ahi_rep_get8 = i_ddi_io_rep_get8; 205 hp->ahi_rep_put8 = i_ddi_io_rep_put8; 206 207 /* temporary set these 64 functions to no-ops */ 208 hp->ahi_get64 = i_ddi_io_get64; 209 hp->ahi_put64 = i_ddi_io_put64; 210 hp->ahi_rep_get64 = i_ddi_io_rep_get64; 211 hp->ahi_rep_put64 = i_ddi_io_rep_put64; 212 213 /* 214 * check for BIG endian access 215 */ 216 if (handlep->ah_acc.devacc_attr_endian_flags == 217 DDI_STRUCTURE_BE_ACC) { 218 hp->ahi_get16 = i_ddi_io_swap_get16; 219 hp->ahi_get32 = i_ddi_io_swap_get32; 220 hp->ahi_put16 = i_ddi_io_swap_put16; 221 hp->ahi_put32 = i_ddi_io_swap_put32; 222 hp->ahi_rep_get16 = i_ddi_io_swap_rep_get16; 223 hp->ahi_rep_get32 = i_ddi_io_swap_rep_get32; 224 hp->ahi_rep_put16 = i_ddi_io_swap_rep_put16; 225 hp->ahi_rep_put32 = i_ddi_io_swap_rep_put32; 226 } else { 227 hp->ahi_acc_attr |= DDI_ACCATTR_DIRECT; 228 hp->ahi_get16 = i_ddi_io_get16; 229 hp->ahi_get32 = i_ddi_io_get32; 230 hp->ahi_put16 = i_ddi_io_put16; 231 hp->ahi_put32 = i_ddi_io_put32; 232 hp->ahi_rep_get16 = i_ddi_io_rep_get16; 233 hp->ahi_rep_get32 = i_ddi_io_rep_get32; 234 hp->ahi_rep_put16 = i_ddi_io_rep_put16; 235 hp->ahi_rep_put32 = i_ddi_io_rep_put32; 236 } 237 238 } else if (hp->ahi_acc_attr & DDI_ACCATTR_CPU_VADDR) { 239 240 hp->ahi_get8 = i_ddi_vaddr_get8; 241 hp->ahi_put8 = i_ddi_vaddr_put8; 242 hp->ahi_rep_get8 = i_ddi_vaddr_rep_get8; 243 hp->ahi_rep_put8 = i_ddi_vaddr_rep_put8; 244 245 /* 246 * check for BIG endian access 247 */ 248 if (handlep->ah_acc.devacc_attr_endian_flags == 249 DDI_STRUCTURE_BE_ACC) { 250 251 hp->ahi_get16 = i_ddi_vaddr_swap_get16; 252 hp->ahi_get32 = i_ddi_vaddr_swap_get32; 253 hp->ahi_get64 = i_ddi_vaddr_swap_get64; 254 hp->ahi_put16 = i_ddi_vaddr_swap_put16; 255 hp->ahi_put32 = i_ddi_vaddr_swap_put32; 256 hp->ahi_put64 = i_ddi_vaddr_swap_put64; 257 hp->ahi_rep_get16 = i_ddi_vaddr_swap_rep_get16; 258 hp->ahi_rep_get32 = i_ddi_vaddr_swap_rep_get32; 259 hp->ahi_rep_get64 = i_ddi_vaddr_swap_rep_get64; 260 hp->ahi_rep_put16 = i_ddi_vaddr_swap_rep_put16; 261 hp->ahi_rep_put32 = i_ddi_vaddr_swap_rep_put32; 262 hp->ahi_rep_put64 = i_ddi_vaddr_swap_rep_put64; 263 } else { 264 hp->ahi_acc_attr |= DDI_ACCATTR_DIRECT; 265 hp->ahi_get16 = i_ddi_vaddr_get16; 266 hp->ahi_get32 = i_ddi_vaddr_get32; 267 hp->ahi_get64 = i_ddi_vaddr_get64; 268 hp->ahi_put16 = i_ddi_vaddr_put16; 269 hp->ahi_put32 = i_ddi_vaddr_put32; 270 hp->ahi_put64 = i_ddi_vaddr_put64; 271 hp->ahi_rep_get16 = i_ddi_vaddr_rep_get16; 272 hp->ahi_rep_get32 = i_ddi_vaddr_rep_get32; 273 hp->ahi_rep_get64 = i_ddi_vaddr_rep_get64; 274 hp->ahi_rep_put16 = i_ddi_vaddr_rep_put16; 275 hp->ahi_rep_put32 = i_ddi_vaddr_rep_put32; 276 hp->ahi_rep_put64 = i_ddi_vaddr_rep_put64; 277 } 278 } 279 hp->ahi_fault_check = i_ddi_acc_fault_check; 280 hp->ahi_fault_notify = i_ddi_acc_fault_notify; 281 hp->ahi_fault = 0; 282 impl_acc_err_init(handlep); 283 } 284 285 /* 286 * The followings are low-level routines for data access. 287 * 288 * All of these routines should be implemented in assembly. Those 289 * that have been rewritten be found in ~ml/ddi_i86_asm.s 290 */ 291 292 /*ARGSUSED*/ 293 uint16_t 294 i_ddi_vaddr_swap_get16(ddi_acc_impl_t *hdlp, uint16_t *addr) 295 { 296 return (ddi_swap16(*addr)); 297 } 298 299 /*ARGSUSED*/ 300 uint16_t 301 i_ddi_io_swap_get16(ddi_acc_impl_t *hdlp, uint16_t *addr) 302 { 303 return (ddi_swap16(inw((uintptr_t)addr))); 304 } 305 306 /*ARGSUSED*/ 307 uint32_t 308 i_ddi_vaddr_swap_get32(ddi_acc_impl_t *hdlp, uint32_t *addr) 309 { 310 return (ddi_swap32(*addr)); 311 } 312 313 /*ARGSUSED*/ 314 uint32_t 315 i_ddi_io_swap_get32(ddi_acc_impl_t *hdlp, uint32_t *addr) 316 { 317 return (ddi_swap32(inl((uintptr_t)addr))); 318 } 319 320 /*ARGSUSED*/ 321 uint64_t 322 i_ddi_vaddr_swap_get64(ddi_acc_impl_t *hdlp, uint64_t *addr) 323 { 324 return (ddi_swap64(*addr)); 325 } 326 327 /*ARGSUSED*/ 328 void 329 i_ddi_vaddr_swap_put16(ddi_acc_impl_t *hdlp, uint16_t *addr, uint16_t value) 330 { 331 *addr = ddi_swap16(value); 332 } 333 334 /*ARGSUSED*/ 335 void 336 i_ddi_io_swap_put16(ddi_acc_impl_t *hdlp, uint16_t *addr, uint16_t value) 337 { 338 outw((uintptr_t)addr, ddi_swap16(value)); 339 } 340 341 /*ARGSUSED*/ 342 void 343 i_ddi_vaddr_swap_put32(ddi_acc_impl_t *hdlp, uint32_t *addr, uint32_t value) 344 { 345 *addr = ddi_swap32(value); 346 } 347 348 /*ARGSUSED*/ 349 void 350 i_ddi_io_swap_put32(ddi_acc_impl_t *hdlp, uint32_t *addr, uint32_t value) 351 { 352 outl((uintptr_t)addr, ddi_swap32(value)); 353 } 354 355 /*ARGSUSED*/ 356 void 357 i_ddi_vaddr_swap_put64(ddi_acc_impl_t *hdlp, uint64_t *addr, uint64_t value) 358 { 359 *addr = ddi_swap64(value); 360 } 361 362 /*ARGSUSED*/ 363 void 364 i_ddi_vaddr_rep_get8(ddi_acc_impl_t *hdlp, uint8_t *host_addr, 365 uint8_t *dev_addr, size_t repcount, uint_t flags) 366 { 367 uint8_t *h, *d; 368 369 h = host_addr; 370 d = dev_addr; 371 372 if (flags == DDI_DEV_AUTOINCR) 373 for (; repcount; repcount--) 374 *h++ = *d++; 375 else 376 for (; repcount; repcount--) 377 *h++ = *d; 378 } 379 380 /*ARGSUSED*/ 381 void 382 i_ddi_vaddr_rep_get16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 383 uint16_t *dev_addr, size_t repcount, uint_t flags) 384 { 385 uint16_t *h, *d; 386 387 h = host_addr; 388 d = dev_addr; 389 390 if (flags == DDI_DEV_AUTOINCR) 391 for (; repcount; repcount--) 392 *h++ = *d++; 393 else 394 for (; repcount; repcount--) 395 *h++ = *d; 396 } 397 398 /*ARGSUSED*/ 399 void 400 i_ddi_vaddr_swap_rep_get16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 401 uint16_t *dev_addr, size_t repcount, uint_t flags) 402 { 403 uint16_t *h, *d; 404 405 h = host_addr; 406 d = dev_addr; 407 408 if (flags == DDI_DEV_AUTOINCR) 409 for (; repcount; repcount--) 410 *h++ = ddi_swap16(*d++); 411 else 412 for (; repcount; repcount--) 413 *h++ = ddi_swap16(*d); 414 } 415 416 /*ARGSUSED*/ 417 void 418 i_ddi_io_swap_rep_get16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 419 uint16_t *dev_addr, size_t repcount, uint_t flags) 420 { 421 uint16_t *h; 422 uintptr_t port; 423 424 h = host_addr; 425 port = (uintptr_t)dev_addr; 426 427 if (flags == DDI_DEV_AUTOINCR) 428 for (; repcount; repcount--, port += 2) 429 *h++ = ddi_swap16(inw(port)); 430 else 431 for (; repcount; repcount--) 432 *h++ = ddi_swap16(inw(port)); 433 } 434 435 /*ARGSUSED*/ 436 void 437 i_ddi_vaddr_rep_get32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 438 uint32_t *dev_addr, size_t repcount, uint_t flags) 439 { 440 uint32_t *h, *d; 441 442 h = host_addr; 443 d = dev_addr; 444 445 if (flags == DDI_DEV_AUTOINCR) 446 for (; repcount; repcount--) 447 *h++ = *d++; 448 else 449 for (; repcount; repcount--) 450 *h++ = *d; 451 } 452 453 /*ARGSUSED*/ 454 void 455 i_ddi_vaddr_swap_rep_get32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 456 uint32_t *dev_addr, size_t repcount, uint_t flags) 457 { 458 uint32_t *h, *d; 459 460 h = host_addr; 461 d = dev_addr; 462 463 if (flags == DDI_DEV_AUTOINCR) 464 for (; repcount; repcount--) 465 *h++ = ddi_swap32(*d++); 466 else 467 for (; repcount; repcount--) 468 *h++ = ddi_swap32(*d); 469 } 470 471 /*ARGSUSED*/ 472 void 473 i_ddi_io_swap_rep_get32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 474 uint32_t *dev_addr, size_t repcount, uint_t flags) 475 { 476 uint32_t *h; 477 uintptr_t port; 478 479 h = host_addr; 480 port = (uintptr_t)dev_addr; 481 482 if (flags == DDI_DEV_AUTOINCR) 483 for (; repcount; repcount--, port += 4) 484 *h++ = ddi_swap32(inl(port)); 485 else 486 for (; repcount; repcount--) 487 *h++ = ddi_swap32(inl(port)); 488 } 489 490 /*ARGSUSED*/ 491 void 492 i_ddi_vaddr_rep_get64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 493 uint64_t *dev_addr, size_t repcount, uint_t flags) 494 { 495 uint64_t *h, *d; 496 497 h = host_addr; 498 d = dev_addr; 499 500 if (flags == DDI_DEV_AUTOINCR) 501 for (; repcount; repcount--) 502 *h++ = *d++; 503 else 504 for (; repcount; repcount--) 505 *h++ = *d; 506 } 507 508 /*ARGSUSED*/ 509 void 510 i_ddi_vaddr_swap_rep_get64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 511 uint64_t *dev_addr, size_t repcount, uint_t flags) 512 { 513 uint64_t *h, *d; 514 515 h = host_addr; 516 d = dev_addr; 517 518 if (flags == DDI_DEV_AUTOINCR) 519 for (; repcount; repcount--) 520 *h++ = ddi_swap64(*d++); 521 else 522 for (; repcount; repcount--) 523 *h++ = ddi_swap64(*d); 524 } 525 526 /*ARGSUSED*/ 527 void 528 i_ddi_vaddr_rep_put8(ddi_acc_impl_t *hdlp, uint8_t *host_addr, 529 uint8_t *dev_addr, size_t repcount, uint_t flags) 530 { 531 uint8_t *h, *d; 532 533 h = host_addr; 534 d = dev_addr; 535 536 if (flags == DDI_DEV_AUTOINCR) 537 for (; repcount; repcount--) 538 *d++ = *h++; 539 else 540 for (; repcount; repcount--) 541 *d = *h++; 542 } 543 544 /*ARGSUSED*/ 545 void 546 i_ddi_vaddr_rep_put16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 547 uint16_t *dev_addr, size_t repcount, uint_t flags) 548 { 549 uint16_t *h, *d; 550 551 h = host_addr; 552 d = dev_addr; 553 554 if (flags == DDI_DEV_AUTOINCR) 555 for (; repcount; repcount--) 556 *d++ = *h++; 557 else 558 for (; repcount; repcount--) 559 *d = *h++; 560 } 561 562 /*ARGSUSED*/ 563 void 564 i_ddi_vaddr_swap_rep_put16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 565 uint16_t *dev_addr, size_t repcount, uint_t flags) 566 { 567 uint16_t *h, *d; 568 569 h = host_addr; 570 d = dev_addr; 571 572 if (flags == DDI_DEV_AUTOINCR) 573 for (; repcount; repcount--) 574 *d++ = ddi_swap16(*h++); 575 else 576 for (; repcount; repcount--) 577 *d = ddi_swap16(*h++); 578 } 579 580 /*ARGSUSED*/ 581 void 582 i_ddi_io_swap_rep_put16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 583 uint16_t *dev_addr, size_t repcount, uint_t flags) 584 { 585 uint16_t *h; 586 uintptr_t port; 587 588 h = host_addr; 589 port = (uintptr_t)dev_addr; 590 591 if (flags == DDI_DEV_AUTOINCR) 592 for (; repcount; repcount--, port += 2) 593 outw(port, ddi_swap16(*h++)); 594 else 595 for (; repcount; repcount--) 596 outw(port, ddi_swap16(*h++)); 597 } 598 599 /*ARGSUSED*/ 600 void 601 i_ddi_vaddr_rep_put32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 602 uint32_t *dev_addr, size_t repcount, uint_t flags) 603 { 604 uint32_t *h, *d; 605 606 h = host_addr; 607 d = dev_addr; 608 609 if (flags == DDI_DEV_AUTOINCR) 610 for (; repcount; repcount--) 611 *d++ = *h++; 612 else 613 for (; repcount; repcount--) 614 *d = *h++; 615 } 616 617 /*ARGSUSED*/ 618 void 619 i_ddi_vaddr_swap_rep_put32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 620 uint32_t *dev_addr, size_t repcount, uint_t flags) 621 { 622 uint32_t *h, *d; 623 624 h = host_addr; 625 d = dev_addr; 626 627 if (flags == DDI_DEV_AUTOINCR) 628 for (; repcount; repcount--) 629 *d++ = ddi_swap32(*h++); 630 else 631 for (; repcount; repcount--) 632 *d = ddi_swap32(*h++); 633 } 634 635 /*ARGSUSED*/ 636 void 637 i_ddi_io_swap_rep_put32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 638 uint32_t *dev_addr, size_t repcount, uint_t flags) 639 { 640 uint32_t *h; 641 uintptr_t port; 642 643 h = host_addr; 644 port = (uintptr_t)dev_addr; 645 646 if (flags == DDI_DEV_AUTOINCR) 647 for (; repcount; repcount--, port += 4) 648 outl(port, ddi_swap32(*h++)); 649 else 650 for (; repcount; repcount--) 651 outl(port, ddi_swap32(*h++)); 652 } 653 654 /*ARGSUSED*/ 655 void 656 i_ddi_vaddr_rep_put64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 657 uint64_t *dev_addr, size_t repcount, uint_t flags) 658 { 659 uint64_t *h, *d; 660 661 h = host_addr; 662 d = dev_addr; 663 664 if (flags == DDI_DEV_AUTOINCR) 665 for (; repcount; repcount--) 666 *d++ = *h++; 667 else 668 for (; repcount; repcount--) 669 *d = *h++; 670 } 671 672 /*ARGSUSED*/ 673 void 674 i_ddi_vaddr_swap_rep_put64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 675 uint64_t *dev_addr, size_t repcount, uint_t flags) 676 { 677 uint64_t *h, *d; 678 679 h = host_addr; 680 d = dev_addr; 681 682 if (flags == DDI_DEV_AUTOINCR) 683 for (; repcount; repcount--) 684 *d++ = ddi_swap64(*h++); 685 else 686 for (; repcount; repcount--) 687 *d = ddi_swap64(*h++); 688 } 689 690 /*ARGSUSED*/ 691 uint64_t 692 i_ddi_io_get64(ddi_acc_impl_t *hdlp, uint64_t *addr) 693 { 694 panic("ddi_get64 from i/o space"); 695 /*NOTREACHED*/ 696 return (0); 697 } 698 699 /*ARGSUSED*/ 700 void 701 i_ddi_io_put64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, uint64_t value) 702 { 703 panic("ddi_put64 to i/o space"); 704 /*NOTREACHED*/ 705 } 706 707 void 708 ddi_io_rep_get8(ddi_acc_handle_t handle, 709 uint8_t *host_addr, uint8_t *dev_addr, size_t repcount) 710 { 711 (((ddi_acc_impl_t *)handle)->ahi_rep_get8) 712 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 713 repcount, DDI_DEV_NO_AUTOINCR); 714 } 715 716 void 717 ddi_io_rep_get16(ddi_acc_handle_t handle, 718 uint16_t *host_addr, uint16_t *dev_addr, size_t repcount) 719 { 720 (((ddi_acc_impl_t *)handle)->ahi_rep_get16) 721 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 722 repcount, DDI_DEV_NO_AUTOINCR); 723 } 724 725 void 726 ddi_io_rep_get32(ddi_acc_handle_t handle, 727 uint32_t *host_addr, uint32_t *dev_addr, size_t repcount) 728 { 729 (((ddi_acc_impl_t *)handle)->ahi_rep_get32) 730 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 731 repcount, DDI_DEV_NO_AUTOINCR); 732 } 733 734 /*ARGSUSED*/ 735 void 736 i_ddi_io_rep_get64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 737 uint64_t *dev_addr, size_t repcount, uint_t flags) 738 { 739 cmn_err(CE_PANIC, "ddi_rep_get64 from i/o space"); 740 } 741 742 void 743 ddi_io_rep_put8(ddi_acc_handle_t handle, 744 uint8_t *host_addr, uint8_t *dev_addr, size_t repcount) 745 { 746 (((ddi_acc_impl_t *)handle)->ahi_rep_put8) 747 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 748 repcount, DDI_DEV_NO_AUTOINCR); 749 } 750 751 void 752 ddi_io_rep_put16(ddi_acc_handle_t handle, 753 uint16_t *host_addr, uint16_t *dev_addr, size_t repcount) 754 { 755 (((ddi_acc_impl_t *)handle)->ahi_rep_put16) 756 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 757 repcount, DDI_DEV_NO_AUTOINCR); 758 } 759 760 void 761 ddi_io_rep_put32(ddi_acc_handle_t handle, 762 uint32_t *host_addr, uint32_t *dev_addr, size_t repcount) 763 { 764 (((ddi_acc_impl_t *)handle)->ahi_rep_put32) 765 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 766 repcount, DDI_DEV_NO_AUTOINCR); 767 } 768 769 /*ARGSUSED*/ 770 void 771 i_ddi_io_rep_put64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 772 uint64_t *dev_addr, size_t repcount, uint_t flags) 773 { 774 cmn_err(CE_PANIC, "ddi_rep_put64 to i/o space"); 775 } 776 777 /* 778 * We need to separate the old interfaces from the new ones and leave them 779 * in here for a while. Previous versions of the OS defined the new interfaces 780 * to the old interfaces. This way we can fix things up so that we can 781 * eventually remove these interfaces. 782 * e.g. A 3rd party module/driver using ddi_io_rep_get8 and built against S10 783 * or earlier will actually have a reference to ddi_io_rep_getb in the binary. 784 */ 785 #ifdef _ILP32 786 void 787 ddi_io_rep_getb(ddi_acc_handle_t handle, 788 uint8_t *host_addr, uint8_t *dev_addr, size_t repcount) 789 { 790 (((ddi_acc_impl_t *)handle)->ahi_rep_get8) 791 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 792 repcount, DDI_DEV_NO_AUTOINCR); 793 } 794 795 void 796 ddi_io_rep_getw(ddi_acc_handle_t handle, 797 uint16_t *host_addr, uint16_t *dev_addr, size_t repcount) 798 { 799 (((ddi_acc_impl_t *)handle)->ahi_rep_get16) 800 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 801 repcount, DDI_DEV_NO_AUTOINCR); 802 } 803 804 void 805 ddi_io_rep_getl(ddi_acc_handle_t handle, 806 uint32_t *host_addr, uint32_t *dev_addr, size_t repcount) 807 { 808 (((ddi_acc_impl_t *)handle)->ahi_rep_get32) 809 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 810 repcount, DDI_DEV_NO_AUTOINCR); 811 } 812 813 void 814 ddi_io_rep_putb(ddi_acc_handle_t handle, 815 uint8_t *host_addr, uint8_t *dev_addr, size_t repcount) 816 { 817 (((ddi_acc_impl_t *)handle)->ahi_rep_put8) 818 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 819 repcount, DDI_DEV_NO_AUTOINCR); 820 } 821 822 void 823 ddi_io_rep_putw(ddi_acc_handle_t handle, 824 uint16_t *host_addr, uint16_t *dev_addr, size_t repcount) 825 { 826 (((ddi_acc_impl_t *)handle)->ahi_rep_put16) 827 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 828 repcount, DDI_DEV_NO_AUTOINCR); 829 } 830 831 void 832 ddi_io_rep_putl(ddi_acc_handle_t handle, 833 uint32_t *host_addr, uint32_t *dev_addr, size_t repcount) 834 { 835 (((ddi_acc_impl_t *)handle)->ahi_rep_put32) 836 ((ddi_acc_impl_t *)handle, host_addr, dev_addr, 837 repcount, DDI_DEV_NO_AUTOINCR); 838 } 839 #endif /* _ILP32 */ 840 841 /* 842 * These next two functions could be translated into assembler someday 843 */ 844 int 845 ddi_check_acc_handle(ddi_acc_handle_t handle) 846 { 847 ddi_acc_impl_t *hdlp = (ddi_acc_impl_t *)handle; 848 return (((*hdlp->ahi_fault_check)(hdlp) == DDI_SUCCESS) ? DDI_SUCCESS : 849 DDI_FAILURE); 850 } 851 852 int 853 i_ddi_acc_fault_check(ddi_acc_impl_t *hdlp) 854 { 855 /* Default version, just returns flag value */ 856 return (hdlp->ahi_fault); 857 } 858 859 /*ARGSUSED*/ 860 void 861 i_ddi_acc_fault_notify(ddi_acc_impl_t *hdlp) 862 { 863 /* Default version, does nothing for now */ 864 } 865 866 void 867 i_ddi_acc_set_fault(ddi_acc_handle_t handle) 868 { 869 ddi_acc_impl_t *hdlp = (ddi_acc_impl_t *)handle; 870 871 if (!hdlp->ahi_fault) { 872 hdlp->ahi_fault = 1; 873 (*hdlp->ahi_fault_notify)(hdlp); 874 } 875 } 876 877 void 878 i_ddi_acc_clr_fault(ddi_acc_handle_t handle) 879 { 880 ddi_acc_impl_t *hdlp = (ddi_acc_impl_t *)handle; 881 882 if (hdlp->ahi_fault) { 883 hdlp->ahi_fault = 0; 884 (*hdlp->ahi_fault_notify)(hdlp); 885 } 886 } 887