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