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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* 27 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved. 28 */ 29 30 31 #include <sys/types.h> 32 #include <sys/conf.h> 33 #include <sys/ddi.h> 34 #include <sys/sunddi.h> 35 #include <sys/ddi_impldefs.h> 36 #include <sys/ddi_subrdefs.h> 37 #include <sys/pci.h> 38 #include <sys/pci/pci_nexus.h> 39 #include <sys/autoconf.h> 40 #include <sys/cmn_err.h> 41 #include <sys/errno.h> 42 #include <sys/kmem.h> 43 #include <sys/debug.h> 44 #include <sys/sysmacros.h> 45 #include <sys/acebus.h> 46 47 #ifdef DEBUG 48 static uint_t acebus_debug_flags = 0; 49 #endif 50 51 /* 52 * The values of the following variables are used to initialize 53 * the cache line size and latency timer registers in the ebus 54 * configuration header. Variables are used instead of constants 55 * to allow tuning from the /etc/system file. 56 */ 57 static uint8_t acebus_cache_line_size = 0x10; /* 64 bytes */ 58 static uint8_t acebus_latency_timer = 0x40; /* 64 PCI cycles */ 59 60 /* 61 * function prototypes for bus ops routines: 62 */ 63 static int 64 acebus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 65 off_t offset, off_t len, caddr_t *addrp); 66 static int 67 acebus_ctlops(dev_info_t *dip, dev_info_t *rdip, 68 ddi_ctl_enum_t op, void *arg, void *result); 69 static int 70 acebus_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op, 71 ddi_intr_handle_impl_t *hdlp, void *result); 72 73 /* 74 * function prototypes for dev ops routines: 75 */ 76 static int acebus_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 77 static int acebus_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 78 79 /* 80 * general function prototypes: 81 */ 82 static int acebus_config(ebus_devstate_t *ebus_p); 83 static int acebus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip, 84 ebus_regspec_t *ebus_rp, pci_regspec_t *rp); 85 static int acebus_get_ranges_prop(ebus_devstate_t *ebus_p); 86 #ifdef ACEBUS_HOTPLUG 87 static int acebus_update_props(ebus_devstate_t *ebus_p); 88 static int acebus_set_imap(dev_info_t *dip); 89 #endif 90 91 #define getprop(dip, name, addr, intp) \ 92 ddi_getlongprop(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \ 93 (name), (caddr_t)(addr), (intp)) 94 95 /* 96 * bus ops and dev ops structures: 97 */ 98 static struct bus_ops acebus_bus_ops = { 99 BUSO_REV, 100 acebus_map, 101 NULL, 102 NULL, 103 NULL, 104 i_ddi_map_fault, 105 NULL, 106 ddi_dma_allochdl, 107 ddi_dma_freehdl, 108 ddi_dma_bindhdl, 109 ddi_dma_unbindhdl, 110 ddi_dma_flush, 111 ddi_dma_win, 112 ddi_dma_mctl, 113 acebus_ctlops, 114 ddi_bus_prop_op, 115 0, /* (*bus_get_eventcookie)(); */ 116 0, /* (*bus_add_eventcall)(); */ 117 0, /* (*bus_remove_eventcall)(); */ 118 0, /* (*bus_post_event)(); */ 119 0, /* (*bus_intr_ctl)(); */ 120 NULL, /* (*bus_config)(); */ 121 NULL, /* (*bus_unconfig)(); */ 122 NULL, /* (*bus_fm_init)(); */ 123 NULL, /* (*bus_fm_fini)(); */ 124 NULL, /* (*bus_fm_access_enter)(); */ 125 NULL, /* (*bus_fm_access_fini)(); */ 126 NULL, /* (*bus_power)(); */ 127 acebus_intr_ops /* (*bus_intr_op)(); */ 128 }; 129 130 static struct dev_ops acebus_ops = { 131 DEVO_REV, 132 0, 133 ddi_no_info, 134 nulldev, 135 nulldev, 136 acebus_attach, 137 acebus_detach, 138 nodev, 139 (struct cb_ops *)0, 140 &acebus_bus_ops, 141 NULL, 142 ddi_quiesce_not_supported, /* devo_quiesce */ 143 }; 144 145 /* 146 * module definitions: 147 */ 148 #include <sys/modctl.h> 149 extern struct mod_ops mod_driverops; 150 151 static struct modldrv modldrv = { 152 &mod_driverops, /* Type of module. This one is a driver */ 153 "Alarm Card ebus nexus", /* Name of module. */ 154 &acebus_ops, /* driver ops */ 155 }; 156 157 static struct modlinkage modlinkage = { 158 MODREV_1, (void *)&modldrv, NULL 159 }; 160 161 /* 162 * driver global data: 163 */ 164 static void *per_acebus_state; /* per-ebus soft state pointer */ 165 166 167 int 168 _init(void) 169 { 170 int e; 171 172 /* 173 * Initialize per-ebus soft state pointer. 174 */ 175 e = ddi_soft_state_init(&per_acebus_state, sizeof (ebus_devstate_t), 1); 176 if (e != 0) 177 return (e); 178 179 /* 180 * Install the module. 181 */ 182 e = mod_install(&modlinkage); 183 if (e != 0) 184 ddi_soft_state_fini(&per_acebus_state); 185 return (e); 186 } 187 188 int 189 _fini(void) 190 { 191 int e; 192 193 /* 194 * Remove the module. 195 */ 196 e = mod_remove(&modlinkage); 197 if (e != 0) 198 return (e); 199 200 /* 201 * Free the soft state info. 202 */ 203 ddi_soft_state_fini(&per_acebus_state); 204 return (e); 205 } 206 207 int 208 _info(struct modinfo *modinfop) 209 { 210 return (mod_info(&modlinkage, modinfop)); 211 } 212 213 /* device driver entry points */ 214 215 /* 216 * attach entry point: 217 * 218 * normal attach: 219 * 220 * create soft state structure (dip, reg, nreg and state fields) 221 * map in configuration header 222 * make sure device is properly configured 223 * report device 224 */ 225 static int 226 acebus_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 227 { 228 ebus_devstate_t *ebus_p; /* per ebus state pointer */ 229 int instance; 230 231 DBG1(D_ATTACH, NULL, "dip=%x\n", dip); 232 switch (cmd) { 233 case DDI_ATTACH: 234 235 /* 236 * Allocate soft state for this instance. 237 */ 238 instance = ddi_get_instance(dip); 239 if (ddi_soft_state_zalloc(per_acebus_state, instance) 240 != DDI_SUCCESS) { 241 DBG(D_ATTACH, NULL, "failed to alloc soft state\n"); 242 return (DDI_FAILURE); 243 } 244 ebus_p = get_acebus_soft_state(instance); 245 ebus_p->dip = dip; 246 247 /* 248 * Make sure the master enable and memory access enable 249 * bits are set in the config command register. 250 */ 251 if (!acebus_config(ebus_p)) { 252 free_acebus_soft_state(instance); 253 return (DDI_FAILURE); 254 } 255 256 (void) ddi_prop_create(DDI_DEV_T_NONE, dip, 257 DDI_PROP_CANSLEEP, "no-dma-interrupt-sync", NULL, 0); 258 /* Get our ranges property for mapping child registers. */ 259 if (acebus_get_ranges_prop(ebus_p) != DDI_SUCCESS) { 260 free_acebus_soft_state(instance); 261 return (DDI_FAILURE); 262 } 263 264 /* 265 * Make the state as attached and report the device. 266 */ 267 ebus_p->state = ATTACHED; 268 ddi_report_dev(dip); 269 DBG(D_ATTACH, ebus_p, "returning\n"); 270 return (DDI_SUCCESS); 271 272 case DDI_RESUME: 273 274 instance = ddi_get_instance(dip); 275 ebus_p = get_acebus_soft_state(instance); 276 277 /* 278 * Make sure the master enable and memory access enable 279 * bits are set in the config command register. 280 */ 281 if (!acebus_config(ebus_p)) { 282 free_acebus_soft_state(instance); 283 return (DDI_FAILURE); 284 } 285 286 ebus_p->state = RESUMED; 287 return (DDI_SUCCESS); 288 } 289 return (DDI_FAILURE); 290 } 291 292 /* 293 * detach entry point: 294 */ 295 static int 296 acebus_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 297 { 298 int instance = ddi_get_instance(dip); 299 ebus_devstate_t *ebus_p = get_acebus_soft_state(instance); 300 301 switch (cmd) { 302 case DDI_DETACH: 303 DBG1(D_DETACH, ebus_p, "DDI_DETACH dip=%p\n", dip); 304 ddi_prop_remove_all(dip); 305 kmem_free(ebus_p->rangep, ebus_p->range_cnt * 306 sizeof (struct ebus_pci_rangespec)); 307 free_acebus_soft_state(instance); 308 return (DDI_SUCCESS); 309 310 case DDI_SUSPEND: 311 DBG1(D_DETACH, ebus_p, "DDI_SUSPEND dip=%p\n", dip); 312 ebus_p->state = SUSPENDED; 313 return (DDI_SUCCESS); 314 } 315 return (DDI_FAILURE); 316 } 317 318 319 static int 320 acebus_get_ranges_prop(ebus_devstate_t *ebus_p) 321 { 322 struct ebus_pci_rangespec *rangep; 323 int nrange, range_len; 324 325 if (ddi_getlongprop(DDI_DEV_T_ANY, ebus_p->dip, DDI_PROP_DONTPASS, 326 "ranges", (caddr_t)&rangep, &range_len) != DDI_SUCCESS) { 327 328 cmn_err(CE_WARN, "%s%d: can't get ranges property", 329 ddi_get_name(ebus_p->dip), ddi_get_instance(ebus_p->dip)); 330 return (DDI_ME_REGSPEC_RANGE); 331 } 332 333 nrange = range_len / sizeof (struct ebus_pci_rangespec); 334 335 if (nrange == 0) { 336 kmem_free(rangep, range_len); 337 return (DDI_FAILURE); 338 } 339 340 #ifdef DEBUG 341 { 342 int i; 343 344 for (i = 0; i < nrange; i++) { 345 DBG5(D_MAP, ebus_p, 346 "ebus range addr 0x%x.0x%x PCI range " 347 "addr 0x%x.0x%x.0x%x ", rangep[i].ebus_phys_hi, 348 rangep[i].ebus_phys_low, rangep[i].pci_phys_hi, 349 rangep[i].pci_phys_mid, rangep[i].pci_phys_low); 350 DBG1(D_MAP, ebus_p, "Size 0x%x\n", rangep[i].rng_size); 351 } 352 } 353 #endif /* DEBUG */ 354 355 ebus_p->rangep = rangep; 356 ebus_p->range_cnt = nrange; 357 358 return (DDI_SUCCESS); 359 } 360 361 362 /* bus driver entry points */ 363 364 /* 365 * bus map entry point: 366 * 367 * if map request is for an rnumber 368 * get the corresponding regspec from device node 369 * build a new regspec in our parent's format 370 * build a new map_req with the new regspec 371 * call up the tree to complete the mapping 372 */ 373 static int 374 acebus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 375 off_t off, off_t len, caddr_t *addrp) 376 { 377 ebus_devstate_t *ebus_p = get_acebus_soft_state(ddi_get_instance(dip)); 378 ebus_regspec_t *ebus_rp, *ebus_regs; 379 pci_regspec_t pci_reg; 380 ddi_map_req_t p_map_request; 381 int rnumber, i, n; 382 int rval = DDI_SUCCESS; 383 384 /* 385 * Handle the mapping according to its type. 386 */ 387 DBG4(D_MAP, ebus_p, "rdip=%s%d: off=%x len=%x\n", 388 ddi_get_name(rdip), ddi_get_instance(rdip), off, len); 389 switch (mp->map_type) { 390 case DDI_MT_REGSPEC: 391 392 /* 393 * We assume the register specification is in ebus format. 394 * We must convert it into a PCI format regspec and pass 395 * the request to our parent. 396 */ 397 DBG3(D_MAP, ebus_p, "rdip=%s%d: REGSPEC - handlep=%x\n", 398 ddi_get_name(rdip), ddi_get_instance(rdip), 399 mp->map_handlep); 400 ebus_rp = (ebus_regspec_t *)mp->map_obj.rp; 401 break; 402 403 case DDI_MT_RNUMBER: 404 405 /* 406 * Get the "reg" property from the device node and convert 407 * it to our parent's format. 408 */ 409 rnumber = mp->map_obj.rnumber; 410 DBG4(D_MAP, ebus_p, "rdip=%s%d: rnumber=%x handlep=%x\n", 411 ddi_get_name(rdip), ddi_get_instance(rdip), 412 rnumber, mp->map_handlep); 413 414 if (getprop(rdip, "reg", &ebus_regs, &i) != DDI_SUCCESS) { 415 DBG(D_MAP, ebus_p, "can't get reg property\n"); 416 return (DDI_ME_RNUMBER_RANGE); 417 } 418 n = i / sizeof (ebus_regspec_t); 419 420 if (rnumber < 0 || rnumber >= n) { 421 DBG(D_MAP, ebus_p, "rnumber out of range\n"); 422 return (DDI_ME_RNUMBER_RANGE); 423 } 424 ebus_rp = &ebus_regs[rnumber]; 425 break; 426 427 default: 428 return (DDI_ME_INVAL); 429 430 } 431 432 /* Adjust our reg property with offset and length */ 433 ebus_rp->addr_low += off; 434 if (len) 435 ebus_rp->size = len; 436 437 /* 438 * Now we have a copy the "reg" entry we're attempting to map. 439 * Translate this into our parents PCI address using the ranges 440 * property. 441 */ 442 rval = acebus_apply_range(ebus_p, rdip, ebus_rp, &pci_reg); 443 444 if (mp->map_type == DDI_MT_RNUMBER) 445 kmem_free((caddr_t)ebus_regs, i); 446 447 if (rval != DDI_SUCCESS) 448 return (rval); 449 450 #ifdef ACEBUS_HOTPLUG 451 /* 452 * The map operation provides a translated (not a re-assigned, or 453 * relocated) ebus address for the child in its address space(range). 454 * Ebus address space is relocatible but its child address space 455 * is not. As specified by their 'reg' properties, they reside 456 * at a fixed offset in their parent's (ebus's) space. 457 * 458 * By setting this bit, we will not run into HostPCI nexus 459 * trying to relocate a translated ebus address (which is already 460 * relocated) and failing the operation. 461 * The reason for doing this here is that the PCI hotplug configurator 462 * always marks the ebus space as relocatible (unlike OBP) and that 463 * information is implied for the child too, which is wrong. 464 */ 465 pci_reg.pci_phys_hi |= PCI_RELOCAT_B; 466 #endif 467 #ifdef DEBUG 468 DBG5(D_MAP, ebus_p, "(%x,%x,%x)(%x,%x)\n", 469 pci_reg.pci_phys_hi, 470 pci_reg.pci_phys_mid, 471 pci_reg.pci_phys_low, 472 pci_reg.pci_size_hi, 473 pci_reg.pci_size_low); 474 #endif 475 476 p_map_request = *mp; 477 p_map_request.map_type = DDI_MT_REGSPEC; 478 p_map_request.map_obj.rp = (struct regspec *)&pci_reg; 479 rval = ddi_map(dip, &p_map_request, 0, 0, addrp); 480 DBG1(D_MAP, ebus_p, "parent returned %x\n", rval); 481 return (rval); 482 } 483 484 485 static int 486 acebus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip, 487 ebus_regspec_t *ebus_rp, pci_regspec_t *rp) 488 { 489 int b; 490 int rval = DDI_SUCCESS; 491 struct ebus_pci_rangespec *rangep = ebus_p->rangep; 492 int nrange = ebus_p->range_cnt; 493 static const char out_of_range[] = 494 "Out of range register specification from device node <%s>"; 495 496 DBG3(D_MAP, ebus_p, "Range Matching Addr 0x%x.%x size 0x%x\n", 497 ebus_rp->addr_hi, ebus_rp->addr_low, ebus_rp->size); 498 499 for (b = 0; b < nrange; ++b, ++rangep) { 500 501 /* Check for the correct space */ 502 if (ebus_rp->addr_hi == rangep->ebus_phys_hi) 503 /* See if we fit in this range */ 504 if ((ebus_rp->addr_low >= 505 rangep->ebus_phys_low) && 506 ((ebus_rp->addr_low + ebus_rp->size - 1) 507 <= (rangep->ebus_phys_low + 508 rangep->rng_size - 1))) { 509 uint_t addr_offset = ebus_rp->addr_low - 510 rangep->ebus_phys_low; 511 /* 512 * Use the range entry to translate 513 * the EBUS physical address into the 514 * parents PCI space. 515 */ 516 rp->pci_phys_hi = 517 rangep->pci_phys_hi; 518 rp->pci_phys_mid = rangep->pci_phys_mid; 519 rp->pci_phys_low = 520 rangep->pci_phys_low + addr_offset; 521 rp->pci_size_hi = 0; 522 rp->pci_size_low = 523 min(ebus_rp->size, (rangep->rng_size - 524 addr_offset)); 525 526 DBG2(D_MAP, ebus_p, "Child hi0x%x lo0x%x ", 527 rangep->ebus_phys_hi, 528 rangep->ebus_phys_low); 529 DBG4(D_MAP, ebus_p, "Parent hi0x%x " 530 "mid0x%x lo0x%x size 0x%x\n", 531 rangep->pci_phys_hi, 532 rangep->pci_phys_mid, 533 rangep->pci_phys_low, 534 rangep->rng_size); 535 536 break; 537 } 538 } 539 540 if (b == nrange) { 541 cmn_err(CE_WARN, out_of_range, ddi_get_name(rdip)); 542 return (DDI_ME_REGSPEC_RANGE); 543 } 544 545 return (rval); 546 } 547 548 549 /* 550 * control ops entry point: 551 * 552 * Requests handled completely: 553 * DDI_CTLOPS_INITCHILD 554 * DDI_CTLOPS_UNINITCHILD 555 * DDI_CTLOPS_REPORTDEV 556 * DDI_CTLOPS_REGSIZE 557 * DDI_CTLOPS_NREGS 558 * 559 * All others passed to parent. 560 */ 561 static int 562 acebus_ctlops(dev_info_t *dip, dev_info_t *rdip, 563 ddi_ctl_enum_t op, void *arg, void *result) 564 { 565 #ifdef DEBUG 566 ebus_devstate_t *ebus_p = get_acebus_soft_state(ddi_get_instance(dip)); 567 #endif 568 ebus_regspec_t *ebus_rp; 569 int32_t reglen; 570 int i, n; 571 char name[10]; 572 573 switch (op) { 574 case DDI_CTLOPS_INITCHILD: { 575 dev_info_t *child = (dev_info_t *)arg; 576 /* 577 * Set the address portion of the node name based on the 578 * address/offset. 579 */ 580 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_INITCHILD: rdip=%s%d\n", 581 ddi_get_name(child), ddi_get_instance(child)); 582 583 if (ddi_getlongprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, 584 "reg", (caddr_t)&ebus_rp, ®len) != DDI_SUCCESS) { 585 586 DBG(D_CTLOPS, ebus_p, "can't get reg property\n"); 587 return (DDI_FAILURE); 588 589 } 590 591 (void) sprintf(name, "%x,%x", ebus_rp->addr_hi, 592 ebus_rp->addr_low); 593 ddi_set_name_addr(child, name); 594 kmem_free((caddr_t)ebus_rp, reglen); 595 596 ddi_set_parent_data(child, NULL); 597 598 return (DDI_SUCCESS); 599 600 } 601 602 case DDI_CTLOPS_UNINITCHILD: 603 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_UNINITCHILD: rdip=%s%d\n", 604 ddi_get_name((dev_info_t *)arg), 605 ddi_get_instance((dev_info_t *)arg)); 606 ddi_set_name_addr((dev_info_t *)arg, NULL); 607 ddi_remove_minor_node((dev_info_t *)arg, NULL); 608 impl_rem_dev_props((dev_info_t *)arg); 609 return (DDI_SUCCESS); 610 611 case DDI_CTLOPS_REPORTDEV: 612 613 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_REPORTDEV: rdip=%s%d\n", 614 ddi_get_name(rdip), ddi_get_instance(rdip)); 615 cmn_err(CE_CONT, "?%s%d at %s%d: offset %s\n", 616 ddi_driver_name(rdip), ddi_get_instance(rdip), 617 ddi_driver_name(dip), ddi_get_instance(dip), 618 ddi_get_name_addr(rdip)); 619 return (DDI_SUCCESS); 620 621 case DDI_CTLOPS_REGSIZE: 622 623 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_REGSIZE: rdip=%s%d\n", 624 ddi_get_name(rdip), ddi_get_instance(rdip)); 625 if (getprop(rdip, "reg", &ebus_rp, &i) != DDI_SUCCESS) { 626 DBG(D_CTLOPS, ebus_p, "can't get reg property\n"); 627 return (DDI_FAILURE); 628 } 629 n = i / sizeof (ebus_regspec_t); 630 if (*(int *)arg < 0 || *(int *)arg >= n) { 631 DBG(D_MAP, ebus_p, "rnumber out of range\n"); 632 kmem_free((caddr_t)ebus_rp, i); 633 return (DDI_FAILURE); 634 } 635 *((off_t *)result) = ebus_rp[*(int *)arg].size; 636 kmem_free((caddr_t)ebus_rp, i); 637 return (DDI_SUCCESS); 638 639 case DDI_CTLOPS_NREGS: 640 641 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_NREGS: rdip=%s%d\n", 642 ddi_get_name(rdip), ddi_get_instance(rdip)); 643 if (getprop(rdip, "reg", &ebus_rp, &i) != DDI_SUCCESS) { 644 DBG(D_CTLOPS, ebus_p, "can't get reg property\n"); 645 return (DDI_FAILURE); 646 } 647 *((uint_t *)result) = i / sizeof (ebus_regspec_t); 648 kmem_free((caddr_t)ebus_rp, i); 649 return (DDI_SUCCESS); 650 } 651 652 /* 653 * Now pass the request up to our parent. 654 */ 655 DBG2(D_CTLOPS, ebus_p, "passing request to parent: rdip=%s%d\n", 656 ddi_get_name(rdip), ddi_get_instance(rdip)); 657 return (ddi_ctlops(dip, rdip, op, arg, result)); 658 } 659 660 struct ebus_string_to_pil { 661 int8_t *string; 662 uint32_t pil; 663 }; 664 665 static struct ebus_string_to_pil acebus_name_to_pil[] = {{"SUNW,CS4231", 9}, 666 {"fdthree", 8}, 667 {"ecpp", 3}, 668 {"su", 12}, 669 {"se", 12}, 670 {"power", 14}}; 671 672 static struct ebus_string_to_pil acebus_device_type_to_pil[] = {{"serial", 12}, 673 {"block", 8}}; 674 675 static int 676 acebus_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op, 677 ddi_intr_handle_impl_t *hdlp, void *result) 678 { 679 #ifdef DEBUG 680 ebus_devstate_t *ebus_p = get_acebus_soft_state(ddi_get_instance(dip)); 681 #endif 682 int8_t *name, *device_type; 683 int32_t i, max_children, max_device_types, len; 684 685 /* 686 * NOTE: These ops below will never be supported in this nexus 687 * driver, hence they always return immediately. 688 */ 689 switch (intr_op) { 690 case DDI_INTROP_GETCAP: 691 *(int *)result = DDI_INTR_FLAG_LEVEL; 692 return (DDI_SUCCESS); 693 case DDI_INTROP_SUPPORTED_TYPES: 694 *(int *)result = i_ddi_get_intx_nintrs(rdip) ? 695 DDI_INTR_TYPE_FIXED : 0; 696 return (DDI_SUCCESS); 697 case DDI_INTROP_SETCAP: 698 case DDI_INTROP_SETMASK: 699 case DDI_INTROP_CLRMASK: 700 case DDI_INTROP_GETPENDING: 701 return (DDI_ENOTSUP); 702 default: 703 break; 704 } 705 706 if (hdlp->ih_pri) 707 goto done; 708 709 /* 710 * This is a hack to set the PIL for the devices under ebus. 711 * We first look up a device by it's specific name, if we can't 712 * match the name, we try and match it's device_type property. 713 * Lastly we default a PIL level of 1. 714 */ 715 DBG1(D_INTR, ebus_p, "ebus_p %p\n", ebus_p); 716 717 name = ddi_get_name(rdip); 718 max_children = sizeof (acebus_name_to_pil) / 719 sizeof (struct ebus_string_to_pil); 720 721 for (i = 0; i < max_children; i++) { 722 if (strcmp(acebus_name_to_pil[i].string, name) == 0) { 723 DBG2(D_INTR, ebus_p, "child name %s; match PIL %d\n", 724 acebus_name_to_pil[i].string, 725 acebus_name_to_pil[i].pil); 726 727 hdlp->ih_pri = acebus_name_to_pil[i].pil; 728 goto done; 729 } 730 } 731 732 if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, DDI_PROP_DONTPASS, 733 "device_type", (caddr_t)&device_type, &len) == DDI_SUCCESS) { 734 735 max_device_types = sizeof (acebus_device_type_to_pil) / 736 sizeof (struct ebus_string_to_pil); 737 738 for (i = 0; i < max_device_types; i++) { 739 if (strcmp(acebus_device_type_to_pil[i].string, 740 device_type) == 0) { 741 DBG2(D_INTR, ebus_p, 742 "Device type %s; match PIL %d\n", 743 acebus_device_type_to_pil[i].string, 744 acebus_device_type_to_pil[i].pil); 745 746 hdlp->ih_pri = acebus_device_type_to_pil[i].pil; 747 break; 748 } 749 } 750 751 kmem_free(device_type, len); 752 } 753 754 /* 755 * If we get here, we need to set a default value 756 * for the PIL. 757 */ 758 if (hdlp->ih_pri == 0) { 759 hdlp->ih_pri = 1; 760 cmn_err(CE_WARN, "%s%d assigning default interrupt level %d " 761 "for device %s%d", ddi_driver_name(dip), 762 ddi_get_instance(dip), hdlp->ih_pri, ddi_driver_name(rdip), 763 ddi_get_instance(rdip)); 764 } 765 766 done: 767 /* Pass up the request to our parent. */ 768 return (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result)); 769 } 770 771 772 static int 773 acebus_config(ebus_devstate_t *ebus_p) 774 { 775 ddi_acc_handle_t conf_handle; 776 uint16_t comm; 777 #ifdef ACEBUS_HOTPLUG 778 int tcr_reg; 779 caddr_t csr_io; 780 ddi_device_acc_attr_t csr_attr = { /* CSR map attributes */ 781 DDI_DEVICE_ATTR_V0, 782 DDI_STRUCTURE_LE_ACC, 783 DDI_STRICTORDER_ACC 784 }; 785 ddi_acc_handle_t csr_handle; 786 #endif 787 788 /* 789 * Make sure the master enable and memory access enable 790 * bits are set in the config command register. 791 */ 792 if (pci_config_setup(ebus_p->dip, &conf_handle) != DDI_SUCCESS) 793 return (0); 794 795 comm = pci_config_get16(conf_handle, PCI_CONF_COMM), 796 #ifdef DEBUG 797 DBG1(D_ATTACH, ebus_p, "command register was 0x%x\n", comm); 798 #endif 799 comm |= (PCI_COMM_ME|PCI_COMM_MAE|PCI_COMM_SERR_ENABLE| 800 PCI_COMM_PARITY_DETECT); 801 pci_config_put16(conf_handle, PCI_CONF_COMM, comm), 802 #ifdef DEBUG 803 DBG1(D_MAP, ebus_p, "command register is now 0x%x\n", 804 pci_config_get16(conf_handle, PCI_CONF_COMM)); 805 #endif 806 pci_config_put8(conf_handle, PCI_CONF_CACHE_LINESZ, 807 (uchar_t)acebus_cache_line_size); 808 pci_config_put8(conf_handle, PCI_CONF_LATENCY_TIMER, 809 (uchar_t)acebus_latency_timer); 810 pci_config_teardown(&conf_handle); 811 812 #ifdef ACEBUS_HOTPLUG 813 if (acebus_update_props(ebus_p) != DDI_SUCCESS) { 814 cmn_err(CE_WARN, "%s%d: Could not update special properties.", 815 ddi_driver_name(ebus_p->dip), 816 ddi_get_instance(ebus_p->dip)); 817 return (0); 818 } 819 820 if (ddi_regs_map_setup(ebus_p->dip, CSR_IO_RINDEX, 821 (caddr_t *)&csr_io, 0, CSR_SIZE, &csr_attr, 822 &csr_handle) != DDI_SUCCESS) { 823 cmn_err(CE_WARN, "%s%d: Could not map Ebus CSR.", 824 ddi_driver_name(ebus_p->dip), 825 ddi_get_instance(ebus_p->dip)); 826 } 827 #ifdef DEBUG 828 if (acebus_debug_flags) { 829 DBG3(D_ATTACH, ebus_p, "tcr[123] = %x,%x,%x\n", 830 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 831 TCR1_OFF)), 832 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 833 TCR2_OFF)), 834 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 835 TCR3_OFF))); 836 DBG2(D_ATTACH, ebus_p, "pmd-aux=%x, freq-aux=%x\n", 837 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 838 PMD_AUX_OFF)), 839 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 840 FREQ_AUX_OFF))); 841 #ifdef ACEBUS_DEBUG 842 for (comm = 0; comm < 4; comm++) 843 prom_printf("dcsr%d=%x, dacr%d=%x, dbcr%d=%x\n", comm, 844 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 845 0x700000+(0x2000*comm))), comm, 846 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 847 0x700000+(0x2000*comm)+4)), comm, 848 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 849 0x700000+(0x2000*comm)+8))); 850 #endif 851 } /* acebus_debug_flags */ 852 #endif 853 /* If TCR registers are not initialized, initialize them here */ 854 tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 855 TCR1_OFF)); 856 if ((tcr_reg == 0) || (tcr_reg == -1)) 857 ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR1_OFF), 858 TCR1_REGVAL); 859 tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 860 TCR2_OFF)); 861 if ((tcr_reg == 0) || (tcr_reg == -1)) 862 ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR2_OFF), 863 TCR2_REGVAL); 864 tcr_reg = ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 865 TCR3_OFF)); 866 if ((tcr_reg == 0) || (tcr_reg == -1)) 867 ddi_put32(csr_handle, (uint32_t *)((caddr_t)csr_io + TCR3_OFF), 868 TCR3_REGVAL); 869 #ifdef DEBUG 870 if (acebus_debug_flags) { 871 DBG3(D_ATTACH, ebus_p, "wrote tcr[123] = %x,%x,%x\n", 872 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 873 TCR1_OFF)), 874 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 875 TCR2_OFF)), 876 ddi_get32(csr_handle, (uint32_t *)((caddr_t)csr_io + 877 TCR3_OFF))); 878 } 879 #endif 880 881 ddi_regs_map_free(&csr_handle); 882 #endif /* ACEBUS_HOTPLUG */ 883 return (1); /* return success */ 884 } 885 886 #ifdef DEBUG 887 extern void prom_printf(const char *, ...); 888 889 static void 890 acebus_debug(uint_t flag, ebus_devstate_t *ebus_p, char *fmt, 891 uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5) 892 { 893 char *s; 894 895 if (acebus_debug_flags & flag) { 896 switch (flag) { 897 case D_ATTACH: 898 s = "attach"; break; 899 case D_DETACH: 900 s = "detach"; break; 901 case D_MAP: 902 s = "map"; break; 903 case D_CTLOPS: 904 s = "ctlops"; break; 905 case D_INTR: 906 s = "intr"; break; 907 } 908 if (ebus_p) 909 cmn_err(CE_CONT, "%s%d: %s: ", 910 ddi_get_name(ebus_p->dip), 911 ddi_get_instance(ebus_p->dip), s); 912 else 913 cmn_err(CE_CONT, "ebus: "); 914 cmn_err(CE_CONT, fmt, a1, a2, a3, a4, a5); 915 } 916 } 917 #endif 918 919 #ifdef ACEBUS_HOTPLUG 920 #define EBUS_CHILD_PHYS_LOW_RANGE 0x10 921 #define EBUS_CHILD_PHYS_HI_RANGE 0x14 922 923 static int 924 acebus_update_props(ebus_devstate_t *ebus_p) 925 { 926 dev_info_t *dip = ebus_p->dip; 927 struct ebus_pci_rangespec er[2], *erp; 928 pci_regspec_t *pci_rp, *prp; 929 int length, rnums, imask[3], i, found = 0; 930 931 /* 932 * If "ranges" property is found, then the device is initialized 933 * by OBP, hence simply return. 934 * Otherwise we create all the properties here. 935 */ 936 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 937 "ranges", (int **)&erp, (uint_t *)&length) == DDI_PROP_SUCCESS) { 938 ddi_prop_free(erp); 939 return (DDI_SUCCESS); 940 } 941 942 /* 943 * interrupt-map is the only property that comes from a .conf file. 944 * Since it doesn't have the nodeid field set, it must be done here. 945 * Other properties can come from OBP or created here. 946 */ 947 if (acebus_set_imap(dip) != DDI_SUCCESS) { 948 return (DDI_FAILURE); 949 } 950 951 /* 952 * Create the "ranges" property. 953 * Ebus has BAR0 and BAR1 allocated (both in memory space). 954 * Other BARs are 0. 955 * Hence there are 2 memory ranges it operates in. (one for each BAR). 956 * ie. there are 2 entries in its ranges property. 957 */ 958 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 959 DDI_PROP_DONTPASS, "assigned-addresses", 960 (int **)&pci_rp, (uint_t *)&length) != DDI_PROP_SUCCESS) { 961 cmn_err(CE_WARN, "%s%d: Could not get assigned-addresses", 962 ddi_driver_name(dip), ddi_get_instance(dip)); 963 return (DDI_FAILURE); 964 } 965 /* 966 * Create the 1st mem range in which it operates corresponding 967 * to BAR0 968 */ 969 er[0].ebus_phys_hi = EBUS_CHILD_PHYS_LOW_RANGE; 970 rnums = (length * sizeof (int))/sizeof (pci_regspec_t); 971 for (i = 0; i < rnums; i++) { 972 prp = pci_rp + i; 973 if (PCI_REG_REG_G(prp->pci_phys_hi) == er[0].ebus_phys_hi) { 974 found = 1; 975 break; 976 } 977 } 978 if (!found) { 979 cmn_err(CE_WARN, "No assigned space for memory range 0."); 980 ddi_prop_free(pci_rp); 981 return (DDI_FAILURE); 982 } 983 found = 0; 984 er[0].ebus_phys_low = 0; 985 er[0].pci_phys_hi = prp->pci_phys_hi; 986 er[0].pci_phys_mid = prp->pci_phys_mid; 987 er[0].pci_phys_low = prp->pci_phys_low; 988 er[0].rng_size = prp->pci_size_low; 989 990 /* 991 * Create the 2nd mem range in which it operates corresponding 992 * to BAR1 993 */ 994 er[1].ebus_phys_hi = EBUS_CHILD_PHYS_HI_RANGE; 995 for (i = 0; i < rnums; i++) { 996 prp = pci_rp + i; 997 if (PCI_REG_REG_G(prp->pci_phys_hi) == er[1].ebus_phys_hi) { 998 found = 1; 999 break; 1000 } 1001 } 1002 if (!found) { 1003 cmn_err(CE_WARN, "No assigned space for memory range 1."); 1004 ddi_prop_free(pci_rp); 1005 return (DDI_FAILURE); 1006 } 1007 er[1].ebus_phys_low = 0; 1008 er[1].pci_phys_hi = prp->pci_phys_hi; 1009 er[1].pci_phys_mid = prp->pci_phys_mid; 1010 er[1].pci_phys_low = prp->pci_phys_low; 1011 er[1].rng_size = prp->pci_size_low; 1012 1013 ddi_prop_free(pci_rp); 1014 length = sizeof (er) / sizeof (int); 1015 if (ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1016 "ranges", (int *)er, length) != DDI_PROP_SUCCESS) { 1017 cmn_err(CE_WARN, "%s%d: Could not create ranges property", 1018 ddi_driver_name(dip), ddi_get_instance(dip)); 1019 return (DDI_FAILURE); 1020 } 1021 /* The following properties are as defined by PCI 1275 bindings. */ 1022 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 1023 "#address-cells", 2) != DDI_PROP_SUCCESS) 1024 return (DDI_FAILURE); 1025 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 1026 "#size-cells", 1) != DDI_PROP_SUCCESS) 1027 return (DDI_FAILURE); 1028 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 1029 "#interrupt-cells", 1) != DDI_PROP_SUCCESS) 1030 return (DDI_FAILURE); 1031 1032 imask[0] = 0x1f; 1033 imask[1] = 0x00ffffff; 1034 imask[2] = 0x00000003; 1035 length = sizeof (imask) / sizeof (int); 1036 if (ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1037 "interrupt-map-mask", (int *)imask, length) != DDI_PROP_SUCCESS) { 1038 cmn_err(CE_WARN, "%s%d: Could not update imap mask property", 1039 ddi_driver_name(dip), ddi_get_instance(dip)); 1040 return (DDI_FAILURE); 1041 } 1042 1043 return (DDI_SUCCESS); 1044 } 1045 1046 /* 1047 * This function takes in the ac-interrupt-map property from the .conf file, 1048 * fills in the 'nodeid' information and then creates the 'interrupt-map' 1049 * property. 1050 */ 1051 static int 1052 acebus_set_imap(dev_info_t *dip) 1053 { 1054 int *imapp, *timapp, length, num, i, default_ival = 0; 1055 dev_info_t *tdip = dip; 1056 int *port_id, imap_ok = 1; 1057 int ilength; 1058 int acebus_default_se_imap[5]; 1059 1060 /* 1061 * interrupt-map is specified via .conf file in hotplug mode, 1062 * since the child configuration is static. 1063 * It could even be hardcoded in the driver. 1064 */ 1065 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1066 "ac-interrupt-map", (int **)&imapp, (uint_t *)&ilength) != 1067 DDI_PROP_SUCCESS) { 1068 /* assume default implementation */ 1069 acebus_default_se_imap[0] = 0x14; 1070 acebus_default_se_imap[1] = 0x400000; 1071 acebus_default_se_imap[2] = 1; 1072 acebus_default_se_imap[3] = 0; 1073 acebus_default_se_imap[4] = 2; 1074 imapp = acebus_default_se_imap; 1075 ilength = 5; 1076 default_ival = 1; 1077 } 1078 num = ilength / 5; /* there are 5 integer cells in our property */ 1079 timapp = imapp; 1080 for (i = 0; i < num; i++) { 1081 if (*(timapp+i*5+3) == 0) 1082 imap_ok = 0; 1083 } 1084 if (imap_ok) { 1085 if (!default_ival) 1086 ddi_prop_free(imapp); 1087 return (DDI_SUCCESS); 1088 } 1089 1090 while (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, tdip, 1091 DDI_PROP_DONTPASS, "upa-portid", (int **)&port_id, 1092 (uint_t *)&length) != DDI_PROP_SUCCESS) { 1093 tdip = ddi_get_parent(tdip); 1094 if (tdip == NULL) { 1095 cmn_err(CE_WARN, "%s%d: Could not get imap parent", 1096 ddi_driver_name(dip), ddi_get_instance(dip)); 1097 if (!default_ival) 1098 ddi_prop_free(imapp); 1099 return (DDI_FAILURE); 1100 } 1101 } 1102 timapp = imapp; 1103 for (i = 0; i < num; i++) { 1104 *(timapp+i*5+3) = ddi_get_nodeid(tdip); 1105 } 1106 1107 if (ddi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1108 "interrupt-map", imapp, ilength) != DDI_PROP_SUCCESS) { 1109 cmn_err(CE_WARN, "%s%d: Could not update AC imap property", 1110 ddi_driver_name(dip), ddi_get_instance(dip)); 1111 if (!default_ival) 1112 ddi_prop_free(imapp); 1113 return (DDI_FAILURE); 1114 } 1115 if (!default_ival) 1116 ddi_prop_free(imapp); 1117 return (DDI_SUCCESS); 1118 } 1119 #endif /* ACEBUS_HOTPLUG */ 1120