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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 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/types.h> 30 #include <sys/conf.h> 31 #include <sys/ddi.h> 32 #include <sys/sunddi.h> 33 #include <sys/ddi_impldefs.h> 34 #include <sys/ddi_subrdefs.h> 35 #include <sys/pci.h> 36 #include <sys/autoconf.h> 37 #include <sys/cmn_err.h> 38 #include <sys/errno.h> 39 #include <sys/kmem.h> 40 #include <sys/debug.h> 41 #include <sys/sysmacros.h> 42 #include <sys/ebus.h> 43 #include <sys/open.h> 44 #include <sys/stat.h> 45 #include <sys/file.h> 46 #include <sys/sunndi.h> 47 48 #ifdef DEBUG 49 uint64_t ebus_debug_flags = 0; 50 #endif 51 52 /* 53 * The values of the following variables are used to initialize 54 * the cache line size and latency timer registers in the ebus 55 * configuration header. Variables are used instead of constants 56 * to allow tuning from the /etc/system file. 57 */ 58 static uint8_t ebus_cache_line_size = 0x10; /* 64 bytes */ 59 static uint8_t ebus_latency_timer = 0x40; /* 64 PCI cycles */ 60 61 /* 62 * function prototypes for bus ops routines: 63 */ 64 static int 65 ebus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 66 off_t offset, off_t len, caddr_t *addrp); 67 static int 68 ebus_ctlops(dev_info_t *dip, dev_info_t *rdip, 69 ddi_ctl_enum_t op, void *arg, void *result); 70 static int 71 ebus_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op, 72 ddi_intr_handle_impl_t *hdlp, void *result); 73 74 /* 75 * function prototypes for dev ops routines: 76 */ 77 static int ebus_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 78 static int ebus_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 79 static int ebus_info(dev_info_t *dip, ddi_info_cmd_t infocmd, 80 void *arg, void **result); 81 82 /* 83 * general function prototypes: 84 */ 85 static int ebus_config(ebus_devstate_t *ebus_p); 86 static int ebus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip, 87 ebus_regspec_t *ebus_rp, pci_regspec_t *rp); 88 static int febus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip, 89 ebus_regspec_t *ebus_rp, struct regspec *rp); 90 int get_ranges_prop(ebus_devstate_t *ebus_p); 91 92 #define getprop(dip, name, addr, intp) \ 93 ddi_getlongprop(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \ 94 (name), (caddr_t)(addr), (intp)) 95 96 static int ebus_open(dev_t *devp, int flags, int otyp, cred_t *credp); 97 static int ebus_close(dev_t dev, int flags, int otyp, cred_t *credp); 98 static int ebus_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 99 cred_t *credp, int *rvalp); 100 struct cb_ops ebus_cb_ops = { 101 ebus_open, /* open */ 102 ebus_close, /* close */ 103 nodev, /* strategy */ 104 nodev, /* print */ 105 nodev, /* dump */ 106 nodev, /* read */ 107 nodev, /* write */ 108 ebus_ioctl, /* ioctl */ 109 nodev, /* devmap */ 110 nodev, /* mmap */ 111 nodev, /* segmap */ 112 nochpoll, /* poll */ 113 ddi_prop_op, /* cb_prop_op */ 114 NULL, /* streamtab */ 115 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */ 116 CB_REV, /* rev */ 117 nodev, /* int (*cb_aread)() */ 118 nodev /* int (*cb_awrite)() */ 119 }; 120 121 /* 122 * bus ops and dev ops structures: 123 */ 124 static struct bus_ops ebus_bus_ops = { 125 BUSO_REV, 126 ebus_map, 127 NULL, 128 NULL, 129 NULL, 130 i_ddi_map_fault, 131 ddi_dma_map, 132 ddi_dma_allochdl, 133 ddi_dma_freehdl, 134 ddi_dma_bindhdl, 135 ddi_dma_unbindhdl, 136 ddi_dma_flush, 137 ddi_dma_win, 138 ddi_dma_mctl, 139 ebus_ctlops, 140 ddi_bus_prop_op, 141 ndi_busop_get_eventcookie, 142 ndi_busop_add_eventcall, 143 ndi_busop_remove_eventcall, 144 ndi_post_event, 145 0, 146 0, 147 0, 148 0, 149 0, 150 0, 151 0, 152 0, 153 ebus_intr_ops 154 }; 155 156 static struct dev_ops ebus_ops = { 157 DEVO_REV, 158 0, 159 ebus_info, 160 nulldev, 161 nulldev, 162 ebus_attach, 163 ebus_detach, 164 nodev, 165 &ebus_cb_ops, 166 &ebus_bus_ops 167 }; 168 169 /* 170 * module definitions: 171 */ 172 #include <sys/modctl.h> 173 extern struct mod_ops mod_driverops; 174 175 static struct modldrv modldrv = { 176 &mod_driverops, /* Type of module. This one is a driver */ 177 "ebus nexus driver %I%", /* Name of module. */ 178 &ebus_ops, /* driver ops */ 179 }; 180 181 static struct modlinkage modlinkage = { 182 MODREV_1, (void *)&modldrv, NULL 183 }; 184 185 /* 186 * driver global data: 187 */ 188 static void *per_ebus_state; /* per-ebus soft state pointer */ 189 190 191 int 192 _init(void) 193 { 194 int e; 195 196 /* 197 * Initialize per-ebus soft state pointer. 198 */ 199 e = ddi_soft_state_init(&per_ebus_state, sizeof (ebus_devstate_t), 1); 200 if (e != 0) 201 return (e); 202 203 /* 204 * Install the module. 205 */ 206 e = mod_install(&modlinkage); 207 if (e != 0) 208 ddi_soft_state_fini(&per_ebus_state); 209 return (e); 210 } 211 212 int 213 _fini(void) 214 { 215 int e; 216 217 /* 218 * Remove the module. 219 */ 220 e = mod_remove(&modlinkage); 221 if (e != 0) 222 return (e); 223 224 /* 225 * Free the soft state info. 226 */ 227 ddi_soft_state_fini(&per_ebus_state); 228 return (e); 229 } 230 231 int 232 _info(struct modinfo *modinfop) 233 { 234 return (mod_info(&modlinkage, modinfop)); 235 } 236 237 /* device driver entry points */ 238 239 /*ARGSUSED*/ 240 static int 241 ebus_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 242 { 243 ebus_devstate_t *ebus_p; /* per ebus state pointer */ 244 int instance; 245 246 instance = getminor((dev_t)arg); 247 ebus_p = get_ebus_soft_state(instance); 248 249 switch (infocmd) { 250 default: 251 return (DDI_FAILURE); 252 253 case DDI_INFO_DEVT2INSTANCE: 254 *result = (void *)instance; 255 return (DDI_SUCCESS); 256 257 case DDI_INFO_DEVT2DEVINFO: 258 if (ebus_p == NULL) 259 return (DDI_FAILURE); 260 *result = (void *)ebus_p->dip; 261 return (DDI_SUCCESS); 262 } 263 } 264 265 /* 266 * attach entry point: 267 * 268 * normal attach: 269 * 270 * create soft state structure (dip, reg, nreg and state fields) 271 * map in configuration header 272 * make sure device is properly configured 273 * report device 274 */ 275 static int 276 ebus_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 277 { 278 ebus_devstate_t *ebus_p; /* per ebus state pointer */ 279 int instance; 280 281 DBG1(D_ATTACH, NULL, "dip=%p\n", dip); 282 283 switch (cmd) { 284 case DDI_ATTACH: 285 286 /* 287 * Allocate soft state for this instance. 288 */ 289 instance = ddi_get_instance(dip); 290 if (ddi_soft_state_zalloc(per_ebus_state, instance) 291 != DDI_SUCCESS) { 292 DBG(D_ATTACH, NULL, "failed to alloc soft state\n"); 293 return (DDI_FAILURE); 294 } 295 ebus_p = get_ebus_soft_state(instance); 296 ebus_p->dip = dip; 297 mutex_init(&ebus_p->ebus_mutex, NULL, MUTEX_DRIVER, NULL); 298 ebus_p->ebus_soft_state = EBUS_SOFT_STATE_CLOSED; 299 300 /* Set ebus type field based on ddi name info */ 301 if (strcmp(ddi_get_name(dip), "jbus-ebus") == 0) { 302 ebus_p->type = FEBUS_TYPE; 303 } else { 304 ebus_p->type = EBUS_TYPE; 305 } 306 307 (void) ddi_prop_create(DDI_DEV_T_NONE, dip, 308 DDI_PROP_CANSLEEP, "no-dma-interrupt-sync", NULL, 0); 309 /* Get our ranges property for mapping child registers. */ 310 if (get_ranges_prop(ebus_p) != DDI_SUCCESS) { 311 mutex_destroy(&ebus_p->ebus_mutex); 312 free_ebus_soft_state(instance); 313 return (DDI_FAILURE); 314 } 315 316 /* 317 * create minor node for devctl interfaces 318 */ 319 if (ddi_create_minor_node(dip, "devctl", S_IFCHR, instance, 320 DDI_NT_NEXUS, 0) != DDI_SUCCESS) { 321 mutex_destroy(&ebus_p->ebus_mutex); 322 free_ebus_soft_state(instance); 323 return (DDI_FAILURE); 324 } 325 /* 326 * Make sure the master enable and memory access enable 327 * bits are set in the config command register. 328 */ 329 if (ebus_p->type == EBUS_TYPE) { 330 if (!ebus_config(ebus_p)) { 331 ddi_remove_minor_node(dip, "devctl"); 332 mutex_destroy(&ebus_p->ebus_mutex); 333 free_ebus_soft_state(instance); 334 return (DDI_FAILURE); 335 } 336 } 337 338 /* 339 * Make the pci_report_pmcap() call only for RIO 340 * implementations. 341 */ 342 if (IS_RIO(dip)) { 343 (void) pci_report_pmcap(dip, PCI_PM_IDLESPEED, 344 (void *)EBUS_4MHZ); 345 } 346 347 /* 348 * Make the state as attached and report the device. 349 */ 350 ebus_p->state = ATTACHED; 351 ddi_report_dev(dip); 352 DBG(D_ATTACH, ebus_p, "returning\n"); 353 354 return (DDI_SUCCESS); 355 356 case DDI_RESUME: 357 358 instance = ddi_get_instance(dip); 359 ebus_p = get_ebus_soft_state(instance); 360 361 /* 362 * Make sure the master enable and memory access enable 363 * bits are set in the config command register. 364 */ 365 if (ebus_p->type == EBUS_TYPE) { 366 if (!ebus_config(ebus_p)) { 367 free_ebus_soft_state(instance); 368 return (DDI_FAILURE); 369 } 370 } 371 372 ebus_p->state = RESUMED; 373 return (DDI_SUCCESS); 374 } 375 return (DDI_FAILURE); 376 } 377 378 /* 379 * detach entry point: 380 */ 381 static int 382 ebus_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 383 { 384 int instance = ddi_get_instance(dip); 385 ebus_devstate_t *ebus_p = get_ebus_soft_state(instance); 386 387 switch (cmd) { 388 case DDI_DETACH: 389 DBG1(D_DETACH, ebus_p, "DDI_DETACH dip=%p\n", dip); 390 391 switch (ebus_p->type) { 392 case EBUS_TYPE: 393 kmem_free(ebus_p->rangespec.rangep, ebus_p->range_cnt * 394 sizeof (struct ebus_pci_rangespec)); 395 break; 396 case FEBUS_TYPE: 397 kmem_free(ebus_p->rangespec.ferangep, 398 ebus_p->range_cnt * 399 sizeof (struct febus_rangespec)); 400 break; 401 default: 402 DBG(D_ATTACH, NULL, "failed to recognize ebus type\n"); 403 return (DDI_FAILURE); 404 } 405 406 ddi_remove_minor_node(dip, "devctl"); 407 mutex_destroy(&ebus_p->ebus_mutex); 408 free_ebus_soft_state(instance); 409 return (DDI_SUCCESS); 410 411 case DDI_SUSPEND: 412 DBG1(D_DETACH, ebus_p, "DDI_SUSPEND dip=%p\n", dip); 413 ebus_p->state = SUSPENDED; 414 return (DDI_SUCCESS); 415 } 416 DBG(D_ATTACH, NULL, "failed to recognize ebus detach command\n"); 417 return (DDI_FAILURE); 418 } 419 420 421 int 422 get_ranges_prop(ebus_devstate_t *ebus_p) 423 { 424 int nrange, range_len; 425 struct ebus_pci_rangespec *rangep; 426 struct febus_rangespec *ferangep; 427 428 switch (ebus_p->type) { 429 case EBUS_TYPE: 430 if (ddi_getlongprop(DDI_DEV_T_ANY, 431 ebus_p->dip, DDI_PROP_DONTPASS, 432 "ranges", (caddr_t)&rangep, 433 &range_len) != DDI_SUCCESS) { 434 cmn_err(CE_WARN, "Can't get %s ranges property", 435 ddi_get_name(ebus_p->dip)); 436 return (DDI_ME_REGSPEC_RANGE); 437 } 438 439 nrange = range_len / sizeof (struct ebus_pci_rangespec); 440 441 if (nrange == 0) { 442 kmem_free(rangep, range_len); 443 DBG(D_ATTACH, NULL, "range is equal to zero\n"); 444 return (DDI_FAILURE); 445 } 446 447 #ifdef DEBUG 448 { 449 int i; 450 451 for (i = 0; i < nrange; i++) { 452 DBG5(D_MAP, ebus_p, 453 "ebus range addr 0x%x.0x%x PCI range " 454 "addr 0x%x.0x%x.0x%x ", 455 rangep[i].ebus_phys_hi, 456 rangep[i].ebus_phys_low, 457 rangep[i].pci_phys_hi, 458 rangep[i].pci_phys_mid, 459 rangep[i].pci_phys_low); 460 DBG1(D_MAP, ebus_p, 461 "Size 0x%x\n", rangep[i].rng_size); 462 } 463 } 464 #endif /* DEBUG */ 465 466 ebus_p->rangespec.rangep = rangep; 467 ebus_p->range_cnt = nrange; 468 return (DDI_SUCCESS); 469 470 case FEBUS_TYPE: 471 if (ddi_getlongprop(DDI_DEV_T_ANY, ebus_p->dip, 472 DDI_PROP_DONTPASS, "ranges", 473 (caddr_t)&ferangep, &range_len) != DDI_SUCCESS) { 474 cmn_err(CE_WARN, "Can't get %s ranges property", 475 ddi_get_name(ebus_p->dip)); 476 return (DDI_ME_REGSPEC_RANGE); 477 } 478 479 nrange = range_len / sizeof (struct febus_rangespec); 480 481 if (nrange == 0) { 482 kmem_free(ferangep, range_len); 483 return (DDI_FAILURE); 484 } 485 486 #ifdef DEBUG 487 { 488 int i; 489 490 for (i = 0; i < nrange; i++) { 491 DBG4(D_MAP, ebus_p, 492 "ebus range addr 0x%x.0x%x" 493 " Parent range " 494 "addr 0x%x.0x%x ", 495 ferangep[i].febus_phys_hi, 496 ferangep[i].febus_phys_low, 497 ferangep[i].parent_phys_hi, 498 ferangep[i].parent_phys_low); 499 DBG1(D_MAP, ebus_p, "Size 0x%x\n", 500 ferangep[i].rng_size); 501 } 502 } 503 #endif /* DEBUG */ 504 ebus_p->rangespec.ferangep = ferangep; 505 ebus_p->range_cnt = nrange; 506 return (DDI_SUCCESS); 507 508 default: 509 DBG(D_MAP, NULL, "failed to recognize ebus type\n"); 510 return (DDI_FAILURE); 511 } 512 } 513 514 /* bus driver entry points */ 515 516 /* 517 * bus map entry point: 518 * 519 * if map request is for an rnumber 520 * get the corresponding regspec from device node 521 * build a new regspec in our parent's format 522 * build a new map_req with the new regspec 523 * call up the tree to complete the mapping 524 */ 525 static int 526 ebus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 527 off_t off, off_t len, caddr_t *addrp) 528 { 529 ebus_devstate_t *ebus_p = get_ebus_soft_state(ddi_get_instance(dip)); 530 ebus_regspec_t *ebus_rp, *ebus_regs; 531 struct regspec reg; 532 pci_regspec_t pci_reg; 533 ddi_map_req_t p_map_request; 534 int rnumber, i, n; 535 int rval = DDI_SUCCESS; 536 537 /* 538 * Handle the mapping according to its type. 539 */ 540 DBG4(D_MAP, ebus_p, "rdip=%s%d: off=%x len=%x\n", 541 ddi_get_name(rdip), ddi_get_instance(rdip), off, len); 542 switch (mp->map_type) { 543 case DDI_MT_REGSPEC: 544 545 /* 546 * We assume the register specification is in ebus format. 547 * We must convert it into a PCI format regspec and pass 548 * the request to our parent. 549 */ 550 DBG3(D_MAP, ebus_p, "rdip=%s%d: REGSPEC - handlep=%p\n", 551 ddi_get_name(rdip), ddi_get_instance(rdip), 552 mp->map_handlep); 553 ebus_rp = (ebus_regspec_t *)mp->map_obj.rp; 554 break; 555 556 case DDI_MT_RNUMBER: 557 558 /* 559 * Get the "reg" property from the device node and convert 560 * it to our parent's format. 561 */ 562 rnumber = mp->map_obj.rnumber; 563 DBG4(D_MAP, ebus_p, "rdip=%s%d: rnumber=%x handlep=%p\n", 564 ddi_get_name(rdip), ddi_get_instance(rdip), 565 rnumber, mp->map_handlep); 566 567 if (getprop(rdip, "reg", &ebus_regs, &i) != DDI_SUCCESS) { 568 DBG(D_MAP, ebus_p, "can't get reg property\n"); 569 return (DDI_ME_RNUMBER_RANGE); 570 } 571 n = i / sizeof (ebus_regspec_t); 572 573 if (rnumber < 0 || rnumber >= n) { 574 DBG(D_MAP, ebus_p, "rnumber out of range\n"); 575 return (DDI_ME_RNUMBER_RANGE); 576 } 577 ebus_rp = &ebus_regs[rnumber]; 578 break; 579 580 default: 581 return (DDI_ME_INVAL); 582 583 } 584 585 /* Adjust our reg property with offset and length */ 586 ebus_rp->addr_low += off; 587 if (len) 588 ebus_rp->size = len; 589 590 /* 591 * Now we have a copy the "reg" entry we're attempting to map. 592 * Translate this into our parents PCI address using the ranges 593 * property. 594 */ 595 switch (ebus_p->type) { 596 case EBUS_TYPE: 597 rval = ebus_apply_range(ebus_p, rdip, ebus_rp, &pci_reg); 598 break; 599 case FEBUS_TYPE: 600 rval = febus_apply_range(ebus_p, rdip, ebus_rp, ®); 601 break; 602 default: 603 DBG(D_MAP, NULL, "failed to recognize ebus type\n"); 604 rval = DDI_FAILURE; 605 } 606 607 if (mp->map_type == DDI_MT_RNUMBER) 608 kmem_free(ebus_regs, i); 609 610 if (rval != DDI_SUCCESS) 611 return (rval); 612 613 #ifdef DEBUG 614 switch (ebus_p->type) { 615 case EBUS_TYPE: 616 DBG5(D_MAP, ebus_p, "(%x,%x,%x)(%x,%x)\n", 617 pci_reg.pci_phys_hi, 618 pci_reg.pci_phys_mid, 619 pci_reg.pci_phys_low, 620 pci_reg.pci_size_hi, 621 pci_reg.pci_size_low); 622 break; 623 624 case FEBUS_TYPE: 625 DBG3(D_MAP, ebus_p, "%x,%x,%x\n", 626 reg.regspec_bustype, 627 reg.regspec_addr, 628 reg.regspec_size); 629 break; 630 } 631 #endif 632 633 p_map_request = *mp; 634 p_map_request.map_type = DDI_MT_REGSPEC; 635 636 switch (ebus_p->type) { 637 case EBUS_TYPE: 638 p_map_request.map_obj.rp = (struct regspec *)&pci_reg; 639 break; 640 case FEBUS_TYPE: 641 p_map_request.map_obj.rp = ® 642 break; 643 default: 644 DBG(D_MAP, NULL, "failed to recognize ebus type\n"); 645 return (DDI_FAILURE); 646 } 647 648 rval = ddi_map(dip, &p_map_request, 0, 0, addrp); 649 DBG1(D_MAP, ebus_p, "parent returned %x\n", rval); 650 return (rval); 651 } 652 653 654 static int 655 ebus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip, 656 ebus_regspec_t *ebus_rp, pci_regspec_t *rp) 657 { 658 int b; 659 int rval = DDI_SUCCESS; 660 struct ebus_pci_rangespec *rangep = ebus_p->rangespec.rangep; 661 int nrange = ebus_p->range_cnt; 662 static char out_of_range[] = 663 "Out of range register specification from device node <%s>"; 664 665 DBG3(D_MAP, ebus_p, "Range Matching Addr 0x%x.%x size 0x%x\n", 666 ebus_rp->addr_hi, ebus_rp->addr_low, ebus_rp->size); 667 668 for (b = 0; b < nrange; ++b, ++rangep) { 669 670 /* Check for the correct space */ 671 if (ebus_rp->addr_hi == rangep->ebus_phys_hi) 672 /* See if we fit in this range */ 673 if ((ebus_rp->addr_low >= 674 rangep->ebus_phys_low) && 675 ((ebus_rp->addr_low + ebus_rp->size - 1) 676 <= (rangep->ebus_phys_low + 677 rangep->rng_size - 1))) { 678 uint_t addr_offset = ebus_rp->addr_low - 679 rangep->ebus_phys_low; 680 /* 681 * Use the range entry to translate 682 * the EBUS physical address into the 683 * parents PCI space. 684 */ 685 rp->pci_phys_hi = 686 rangep->pci_phys_hi; 687 rp->pci_phys_mid = rangep->pci_phys_mid; 688 rp->pci_phys_low = 689 rangep->pci_phys_low + addr_offset; 690 rp->pci_size_hi = 0; 691 rp->pci_size_low = 692 min(ebus_rp->size, (rangep->rng_size - 693 addr_offset)); 694 695 DBG2(D_MAP, ebus_p, "Child hi0x%x lo0x%x ", 696 rangep->ebus_phys_hi, 697 rangep->ebus_phys_low); 698 DBG4(D_MAP, ebus_p, "Parent hi0x%x " 699 "mid0x%x lo0x%x size 0x%x\n", 700 rangep->pci_phys_hi, 701 rangep->pci_phys_mid, 702 rangep->pci_phys_low, 703 rangep->rng_size); 704 705 break; 706 } 707 } 708 709 if (b == nrange) { 710 cmn_err(CE_WARN, out_of_range, ddi_get_name(rdip)); 711 return (DDI_ME_REGSPEC_RANGE); 712 } 713 714 return (rval); 715 } 716 717 static int 718 febus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip, 719 ebus_regspec_t *ebus_rp, struct regspec *rp) { 720 int b; 721 int rval = DDI_SUCCESS; 722 struct febus_rangespec *rangep = ebus_p->rangespec.ferangep; 723 int nrange = ebus_p->range_cnt; 724 static char out_of_range[] = 725 "Out of range register specification from device node <%s>"; 726 727 DBG3(D_MAP, ebus_p, "Range Matching Addr 0x%x.%x size 0x%x\n", 728 ebus_rp->addr_hi, ebus_rp->addr_low, ebus_rp->size); 729 730 for (b = 0; b < nrange; ++b, ++rangep) { 731 /* Check for the correct space */ 732 if (ebus_rp->addr_hi == rangep->febus_phys_hi) 733 /* See if we fit in this range */ 734 if ((ebus_rp->addr_low >= 735 rangep->febus_phys_low) && 736 ((ebus_rp->addr_low + ebus_rp->size - 1) 737 <= (rangep->febus_phys_low + 738 rangep->rng_size - 1))) { 739 uint_t addr_offset = ebus_rp->addr_low - 740 rangep->febus_phys_low; 741 742 /* 743 * Use the range entry to translate 744 * the FEBUS physical address into the 745 * parents space. 746 */ 747 rp->regspec_bustype = 748 rangep->parent_phys_hi; 749 rp->regspec_addr = 750 rangep->parent_phys_low + addr_offset; 751 rp->regspec_size = 752 min(ebus_rp->size, (rangep->rng_size - 753 addr_offset)); 754 755 DBG2(D_MAP, ebus_p, "Child hi0x%x lo0x%x ", 756 rangep->febus_phys_hi, 757 rangep->febus_phys_low); 758 DBG3(D_MAP, ebus_p, "Parent hi0x%x " 759 "lo0x%x size 0x%x\n", 760 rangep->parent_phys_hi, 761 rangep->parent_phys_low, 762 rangep->rng_size); 763 764 break; 765 } 766 } 767 768 if (b == nrange) { 769 cmn_err(CE_WARN, out_of_range, ddi_get_name(rdip)); 770 return (DDI_ME_REGSPEC_RANGE); 771 } 772 773 return (rval); 774 } 775 776 777 static int 778 ebus_name_child(dev_info_t *child, char *name, int namelen) 779 { 780 ebus_regspec_t *ebus_rp; 781 int reglen; 782 783 /* 784 * Get the address portion of the node name based on the 785 * address/offset. 786 */ 787 if (ddi_getlongprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, 788 "reg", (caddr_t)&ebus_rp, ®len) != DDI_SUCCESS) { 789 return (DDI_FAILURE); 790 } 791 792 (void) snprintf(name, namelen, "%x,%x", ebus_rp->addr_hi, 793 ebus_rp->addr_low); 794 kmem_free(ebus_rp, reglen); 795 796 return (DDI_SUCCESS); 797 } 798 799 /* 800 * control ops entry point: 801 * 802 * Requests handled completely: 803 * DDI_CTLOPS_INITCHILD 804 * DDI_CTLOPS_UNINITCHILD 805 * DDI_CTLOPS_REPORTDEV 806 * DDI_CTLOPS_REGSIZE 807 * DDI_CTLOPS_NREGS 808 * 809 * All others passed to parent. 810 */ 811 static int 812 ebus_ctlops(dev_info_t *dip, dev_info_t *rdip, 813 ddi_ctl_enum_t op, void *arg, void *result) 814 { 815 #ifdef DEBUG 816 ebus_devstate_t *ebus_p = get_ebus_soft_state(ddi_get_instance(dip)); 817 #endif 818 ebus_regspec_t *ebus_rp; 819 int i, n; 820 char name[10]; 821 822 switch (op) { 823 case DDI_CTLOPS_INITCHILD: { 824 dev_info_t *child = (dev_info_t *)arg; 825 /* 826 * Set the address portion of the node name based on the 827 * address/offset. 828 */ 829 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_INITCHILD: rdip=%s%d\n", 830 ddi_get_name(child), ddi_get_instance(child)); 831 832 if (ebus_name_child(child, name, 10) != DDI_SUCCESS) { 833 DBG(D_CTLOPS, ebus_p, "can't name child\n"); 834 return (DDI_FAILURE); 835 } 836 837 ddi_set_name_addr(child, name); 838 ddi_set_parent_data(child, NULL); 839 return (DDI_SUCCESS); 840 } 841 842 case DDI_CTLOPS_UNINITCHILD: 843 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_UNINITCHILD: rdip=%s%d\n", 844 ddi_get_name((dev_info_t *)arg), 845 ddi_get_instance((dev_info_t *)arg)); 846 ddi_set_name_addr((dev_info_t *)arg, NULL); 847 ddi_remove_minor_node((dev_info_t *)arg, NULL); 848 impl_rem_dev_props((dev_info_t *)arg); 849 return (DDI_SUCCESS); 850 851 case DDI_CTLOPS_REPORTDEV: 852 853 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_REPORTDEV: rdip=%s%d\n", 854 ddi_get_name(rdip), ddi_get_instance(rdip)); 855 cmn_err(CE_CONT, "?%s%d at %s%d: offset %s\n", 856 ddi_driver_name(rdip), ddi_get_instance(rdip), 857 ddi_driver_name(dip), ddi_get_instance(dip), 858 ddi_get_name_addr(rdip)); 859 return (DDI_SUCCESS); 860 861 case DDI_CTLOPS_REGSIZE: 862 863 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_REGSIZE: rdip=%s%d\n", 864 ddi_get_name(rdip), ddi_get_instance(rdip)); 865 if (getprop(rdip, "reg", &ebus_rp, &i) != DDI_SUCCESS) { 866 DBG(D_CTLOPS, ebus_p, "can't get reg property\n"); 867 return (DDI_FAILURE); 868 } 869 n = i / sizeof (ebus_regspec_t); 870 if (*(int *)arg < 0 || *(int *)arg >= n) { 871 DBG(D_MAP, ebus_p, "rnumber out of range\n"); 872 kmem_free(ebus_rp, i); 873 return (DDI_FAILURE); 874 } 875 *((off_t *)result) = ebus_rp[*(int *)arg].size; 876 kmem_free(ebus_rp, i); 877 return (DDI_SUCCESS); 878 879 case DDI_CTLOPS_NREGS: 880 881 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_NREGS: rdip=%s%d\n", 882 ddi_get_name(rdip), ddi_get_instance(rdip)); 883 if (getprop(rdip, "reg", &ebus_rp, &i) != DDI_SUCCESS) { 884 DBG(D_CTLOPS, ebus_p, "can't get reg property\n"); 885 return (DDI_FAILURE); 886 } 887 *((uint_t *)result) = i / sizeof (ebus_regspec_t); 888 kmem_free(ebus_rp, i); 889 return (DDI_SUCCESS); 890 } 891 892 /* 893 * Now pass the request up to our parent. 894 */ 895 DBG2(D_CTLOPS, ebus_p, "passing request to parent: rdip=%s%d\n", 896 ddi_get_name(rdip), ddi_get_instance(rdip)); 897 return (ddi_ctlops(dip, rdip, op, arg, result)); 898 } 899 900 struct ebus_string_to_pil { 901 int8_t *string; 902 uint32_t pil; 903 }; 904 905 static struct ebus_string_to_pil ebus_name_to_pil[] = {{"SUNW,CS4231", 9}, 906 {"audio", 9}, 907 {"fdthree", 8}, 908 {"floppy", 8}, 909 {"ecpp", 3}, 910 {"parallel", 3}, 911 {"su", 12}, 912 {"se", 12}, 913 {"serial", 12}, 914 {"power", 14}}; 915 916 static struct ebus_string_to_pil ebus_device_type_to_pil[] = {{"serial", 12}, 917 {"block", 8}}; 918 919 static int 920 ebus_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op, 921 ddi_intr_handle_impl_t *hdlp, void *result) 922 { 923 #ifdef DEBUG 924 ebus_devstate_t *ebus_p = get_ebus_soft_state(ddi_get_instance(dip)); 925 #endif 926 ddi_ispec_t *ip = (ddi_ispec_t *)hdlp->ih_private; 927 int32_t i, max_children, max_device_types, len; 928 char *name_p, *device_type_p; 929 930 DBG1(D_INTR, ebus_p, "ip 0x%p\n", ip); 931 932 /* 933 * NOTE: These ops below will never be supported in this nexus 934 * driver, hence they always return immediately. 935 */ 936 switch (intr_op) { 937 case DDI_INTROP_GETCAP: 938 *(int *)result = 0; 939 return (DDI_SUCCESS); 940 case DDI_INTROP_SETCAP: 941 case DDI_INTROP_SETMASK: 942 case DDI_INTROP_CLRMASK: 943 case DDI_INTROP_GETPENDING: 944 return (DDI_ENOTSUP); 945 default: 946 break; 947 } 948 949 if ((intr_op == DDI_INTROP_SUPPORTED_TYPES) || ip->is_pil) 950 goto done; 951 952 /* 953 * This is a hack to set the PIL for the devices under ebus. 954 * We first look up a device by it's specific name, if we can't 955 * match the name, we try and match it's device_type property. 956 * Lastly we default a PIL level of 1. 957 */ 958 name_p = ddi_node_name(rdip); 959 max_children = sizeof (ebus_name_to_pil) / 960 sizeof (struct ebus_string_to_pil); 961 962 for (i = 0; i < max_children; i++) { 963 if (strcmp(ebus_name_to_pil[i].string, name_p) == 0) { 964 DBG2(D_INTR, ebus_p, "child name %s; match PIL %d\n", 965 ebus_name_to_pil[i].string, 966 ebus_name_to_pil[i].pil); 967 968 ip->is_pil = ebus_name_to_pil[i].pil; 969 goto done; 970 } 971 } 972 973 if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, DDI_PROP_DONTPASS, 974 "device_type", (caddr_t)&device_type_p, &len) == DDI_SUCCESS) { 975 976 max_device_types = sizeof (ebus_device_type_to_pil) / 977 sizeof (struct ebus_string_to_pil); 978 979 for (i = 0; i < max_device_types; i++) { 980 if (strcmp(ebus_device_type_to_pil[i].string, 981 device_type_p) == 0) { 982 DBG2(D_INTR, ebus_p, "Device type %s; match " 983 "PIL %d\n", ebus_device_type_to_pil[i]. 984 string, ebus_device_type_to_pil[i].pil); 985 986 ip->is_pil = ebus_device_type_to_pil[i].pil; 987 break; 988 } 989 } 990 991 kmem_free(device_type_p, len); 992 } 993 994 /* 995 * If we get here, we need to set a default value 996 * for the PIL. 997 */ 998 if (ip->is_pil == 0) { 999 ip->is_pil = 1; 1000 1001 cmn_err(CE_WARN, "%s%d assigning default interrupt level %d " 1002 "for device %s%d", ddi_get_name(dip), ddi_get_instance(dip), 1003 ip->is_pil, ddi_get_name(rdip), ddi_get_instance(rdip)); 1004 } 1005 1006 done: 1007 /* Pass up the request to our parent. */ 1008 return (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result)); 1009 } 1010 1011 1012 static int 1013 ebus_config(ebus_devstate_t *ebus_p) 1014 { 1015 ddi_acc_handle_t conf_handle; 1016 uint16_t comm; 1017 1018 /* 1019 * Make sure the master enable and memory access enable 1020 * bits are set in the config command register. 1021 */ 1022 if (pci_config_setup(ebus_p->dip, &conf_handle) != DDI_SUCCESS) 1023 return (0); 1024 1025 comm = pci_config_get16(conf_handle, PCI_CONF_COMM), 1026 #ifdef DEBUG 1027 DBG1(D_MAP, ebus_p, "command register was 0x%x\n", comm); 1028 #endif 1029 comm |= (PCI_COMM_ME|PCI_COMM_MAE|PCI_COMM_SERR_ENABLE| 1030 PCI_COMM_PARITY_DETECT); 1031 pci_config_put16(conf_handle, PCI_CONF_COMM, comm), 1032 #ifdef DEBUG 1033 DBG1(D_MAP, ebus_p, "command register is now 0x%x\n", comm); 1034 #endif 1035 pci_config_put8(conf_handle, PCI_CONF_CACHE_LINESZ, 1036 (uchar_t)ebus_cache_line_size); 1037 pci_config_put8(conf_handle, PCI_CONF_LATENCY_TIMER, 1038 (uchar_t)ebus_latency_timer); 1039 pci_config_teardown(&conf_handle); 1040 return (1); 1041 } 1042 1043 #ifdef DEBUG 1044 extern void prom_printf(const char *, ...); 1045 1046 static void 1047 ebus_debug(uint_t flag, ebus_devstate_t *ebus_p, char *fmt, 1048 uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5) 1049 { 1050 char *s; 1051 1052 if (ebus_debug_flags & flag) { 1053 switch (flag) { 1054 case D_ATTACH: 1055 s = "attach"; break; 1056 case D_DETACH: 1057 s = "detach"; break; 1058 case D_MAP: 1059 s = "map"; break; 1060 case D_CTLOPS: 1061 s = "ctlops"; break; 1062 case D_INTR: 1063 s = "intr"; break; 1064 } 1065 if (ebus_p) 1066 cmn_err(CE_CONT, "%s%d: %s: ", 1067 ddi_get_name(ebus_p->dip), 1068 ddi_get_instance(ebus_p->dip), s); 1069 else 1070 cmn_err(CE_CONT, "ebus: "); 1071 cmn_err(CE_CONT, fmt, a1, a2, a3, a4, a5); 1072 } 1073 } 1074 #endif 1075 1076 /* ARGSUSED3 */ 1077 static int 1078 ebus_open(dev_t *devp, int flags, int otyp, cred_t *credp) 1079 { 1080 ebus_devstate_t *ebus_p; 1081 1082 /* 1083 * Make sure the open is for the right file type. 1084 */ 1085 if (otyp != OTYP_CHR) 1086 return (EINVAL); 1087 1088 /* 1089 * Get the soft state structure for the device. 1090 */ 1091 ebus_p = get_ebus_soft_state(getminor(*devp)); 1092 if (ebus_p == NULL) 1093 return (ENXIO); 1094 1095 /* 1096 * Handle the open by tracking the device state. 1097 */ 1098 mutex_enter(&ebus_p->ebus_mutex); 1099 if (flags & FEXCL) { 1100 if (ebus_p->ebus_soft_state != EBUS_SOFT_STATE_CLOSED) { 1101 mutex_exit(&ebus_p->ebus_mutex); 1102 return (EBUSY); 1103 } 1104 ebus_p->ebus_soft_state = EBUS_SOFT_STATE_OPEN_EXCL; 1105 } else { 1106 if (ebus_p->ebus_soft_state == EBUS_SOFT_STATE_OPEN_EXCL) { 1107 mutex_exit(&ebus_p->ebus_mutex); 1108 return (EBUSY); 1109 } 1110 ebus_p->ebus_soft_state = EBUS_SOFT_STATE_OPEN; 1111 } 1112 mutex_exit(&ebus_p->ebus_mutex); 1113 return (0); 1114 } 1115 1116 1117 /* ARGSUSED */ 1118 static int 1119 ebus_close(dev_t dev, int flags, int otyp, cred_t *credp) 1120 { 1121 ebus_devstate_t *ebus_p; 1122 1123 if (otyp != OTYP_CHR) 1124 return (EINVAL); 1125 1126 ebus_p = get_ebus_soft_state(getminor(dev)); 1127 if (ebus_p == NULL) 1128 return (ENXIO); 1129 1130 mutex_enter(&ebus_p->ebus_mutex); 1131 ebus_p->ebus_soft_state = EBUS_SOFT_STATE_CLOSED; 1132 mutex_exit(&ebus_p->ebus_mutex); 1133 return (0); 1134 } 1135 1136 1137 /* 1138 * ebus_ioctl: devctl hotplug controls 1139 */ 1140 /* ARGSUSED */ 1141 static int 1142 ebus_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, 1143 int *rvalp) 1144 { 1145 ebus_devstate_t *ebus_p; 1146 dev_info_t *self; 1147 struct devctl_iocdata *dcp; 1148 uint_t bus_state; 1149 int rv = 0; 1150 1151 ebus_p = get_ebus_soft_state(getminor(dev)); 1152 if (ebus_p == NULL) 1153 return (ENXIO); 1154 1155 self = ebus_p->dip; 1156 1157 /* 1158 * We can use the generic implementation for these ioctls 1159 */ 1160 switch (cmd) { 1161 case DEVCTL_DEVICE_GETSTATE: 1162 case DEVCTL_DEVICE_ONLINE: 1163 case DEVCTL_DEVICE_OFFLINE: 1164 case DEVCTL_BUS_GETSTATE: 1165 return (ndi_devctl_ioctl(self, cmd, arg, mode, 0)); 1166 } 1167 1168 /* 1169 * read devctl ioctl data 1170 */ 1171 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS) 1172 return (EFAULT); 1173 1174 switch (cmd) { 1175 1176 case DEVCTL_DEVICE_RESET: 1177 rv = ENOTSUP; 1178 break; 1179 1180 case DEVCTL_BUS_QUIESCE: 1181 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) 1182 if (bus_state == BUS_QUIESCED) 1183 break; 1184 (void) ndi_set_bus_state(self, BUS_QUIESCED); 1185 break; 1186 1187 case DEVCTL_BUS_UNQUIESCE: 1188 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) 1189 if (bus_state == BUS_ACTIVE) 1190 break; 1191 (void) ndi_set_bus_state(self, BUS_ACTIVE); 1192 break; 1193 1194 case DEVCTL_BUS_RESET: 1195 rv = ENOTSUP; 1196 break; 1197 1198 case DEVCTL_BUS_RESETALL: 1199 rv = ENOTSUP; 1200 break; 1201 1202 default: 1203 rv = ENOTTY; 1204 } 1205 1206 ndi_dc_freehdl(dcp); 1207 return (rv); 1208 } 1209