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