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