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