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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * PCI to PCI bus bridge nexus driver 30 */ 31 32 #include <sys/conf.h> 33 #include <sys/kmem.h> 34 #include <sys/debug.h> 35 #include <sys/modctl.h> 36 #include <sys/autoconf.h> 37 #include <sys/ddi_impldefs.h> 38 #include <sys/ddi_subrdefs.h> 39 #include <sys/ddifm.h> 40 #include <sys/fm/util.h> 41 #include <sys/fm/protocol.h> 42 #include <sys/fm/io/pci.h> 43 #include <sys/pci.h> 44 #include <sys/pci/pci_nexus.h> 45 #include <sys/pci/pci_regs.h> 46 #include <sys/pci/pci_simba.h> 47 #include <sys/ddi.h> 48 #include <sys/sunddi.h> 49 #include <sys/sunndi.h> 50 #include <sys/promif.h> /* prom_printf */ 51 #include <sys/open.h> 52 #include <sys/stat.h> 53 #include <sys/file.h> 54 55 #if defined(DEBUG) && !defined(lint) 56 static uint_t simba_debug_flags = 0; 57 #define D_IDENTIFY 0x00000001 58 #define D_ATTACH 0x00000002 59 #define D_DETACH 0x00000004 60 #define D_MAP 0x00000008 61 #define D_CTLOPS 0x00000010 62 #define D_G_ISPEC 0x00000020 63 #define D_A_ISPEC 0x00000040 64 #define D_INIT_CLD 0x00400000 65 #define D_FAULT 0x00000080 66 67 #define DEBUG0(f, s) if ((f)& simba_debug_flags) \ 68 prom_printf("simba: " s "\n") 69 70 #define DEBUG1(f, s, a) if ((f)& simba_debug_flags) \ 71 prom_printf("simba: " s "\n", a) 72 73 #define DEBUG2(f, s, a, b) if ((f)& simba_debug_flags) \ 74 prom_printf("simba: " s "\n", a, b) 75 76 #define DEBUG3(f, s, a, b, c) if ((f)& simba_debug_flags) \ 77 prom_printf("simba: " s "\n", a, b, c) 78 79 #define DEBUG4(f, s, a, b, c, d) if ((f)& simba_debug_flags) \ 80 prom_printf("simba: " s "\n", a, b, c, d) 81 82 #define DEBUG5(f, s, a, b, c, d, e) if ((f)& simba_debug_flags) \ 83 prom_printf("simba: " s "\n", a, b, c, d, e) 84 85 #define DEBUG6(f, s, a, b, c, d, e, ff) if ((f)& simba_debug_flags) \ 86 prom_printf("simba: " s "\n", a, b, c, d, e, ff) 87 88 #else 89 90 #define DEBUG0(f, s) 91 #define DEBUG1(f, s, a) 92 #define DEBUG2(f, s, a, b) 93 #define DEBUG3(f, s, a, b, c) 94 #define DEBUG4(f, s, a, b, c, d) 95 #define DEBUG5(f, s, a, b, c, d, e) 96 #define DEBUG6(f, s, a, b, c, d, e, ff) 97 98 #endif 99 100 /* 101 * The variable controls the default setting of the command register 102 * for pci devices. See simba_initchild() for details. 103 */ 104 static ushort_t simba_command_default = PCI_COMM_SERR_ENABLE | 105 PCI_COMM_WAIT_CYC_ENAB | 106 PCI_COMM_PARITY_DETECT | 107 PCI_COMM_ME | 108 PCI_COMM_MAE | 109 PCI_COMM_IO; 110 111 static int simba_bus_map(dev_info_t *, dev_info_t *, ddi_map_req_t *, 112 off_t, off_t, caddr_t *); 113 static int simba_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, 114 void *, void *); 115 static int simba_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap, 116 ddi_iblock_cookie_t *ibc); 117 static void simba_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle); 118 static void simba_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle); 119 120 struct bus_ops simba_bus_ops = { 121 BUSO_REV, 122 simba_bus_map, 123 0, 124 0, 125 0, 126 i_ddi_map_fault, 127 ddi_dma_map, 128 ddi_dma_allochdl, 129 ddi_dma_freehdl, 130 ddi_dma_bindhdl, 131 ddi_dma_unbindhdl, 132 ddi_dma_flush, 133 ddi_dma_win, 134 ddi_dma_mctl, 135 simba_ctlops, 136 ddi_bus_prop_op, 137 ndi_busop_get_eventcookie, 138 ndi_busop_add_eventcall, 139 ndi_busop_remove_eventcall, 140 ndi_post_event, 141 0, 142 0, 143 0, 144 simba_fm_init_child, 145 NULL, 146 simba_bus_enter, 147 simba_bus_exit, 148 0, 149 i_ddi_intr_ops 150 }; 151 152 static int simba_open(dev_t *devp, int flags, int otyp, cred_t *credp); 153 static int simba_close(dev_t dev, int flags, int otyp, cred_t *credp); 154 static int simba_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 155 cred_t *credp, int *rvalp); 156 157 static struct cb_ops simba_cb_ops = { 158 simba_open, /* open */ 159 simba_close, /* close */ 160 nulldev, /* strategy */ 161 nulldev, /* print */ 162 nulldev, /* dump */ 163 nulldev, /* read */ 164 nulldev, /* write */ 165 simba_ioctl, /* ioctl */ 166 nodev, /* devmap */ 167 nodev, /* mmap */ 168 nodev, /* segmap */ 169 nochpoll, /* poll */ 170 ddi_prop_op, /* cb_prop_op */ 171 NULL, /* streamtab */ 172 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */ 173 CB_REV, /* rev */ 174 nodev, /* int (*cb_aread)() */ 175 nodev /* int (*cb_awrite)() */ 176 }; 177 178 static int simba_probe(dev_info_t *); 179 static int simba_attach(dev_info_t *devi, ddi_attach_cmd_t cmd); 180 static int simba_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 181 static int simba_info(dev_info_t *dip, ddi_info_cmd_t infocmd, 182 void *arg, void **result); 183 184 struct dev_ops simba_ops = { 185 DEVO_REV, /* devo_rev */ 186 0, /* refcnt */ 187 simba_info, /* info */ 188 nulldev, /* identify */ 189 simba_probe, /* probe */ 190 simba_attach, /* attach */ 191 simba_detach, /* detach */ 192 nulldev, /* reset */ 193 &simba_cb_ops, /* driver operations */ 194 &simba_bus_ops /* bus operations */ 195 196 }; 197 198 /* 199 * Module linkage information for the kernel. 200 */ 201 202 static struct modldrv modldrv = { 203 &mod_driverops, /* Type of module */ 204 "SIMBA PCI to PCI bridge nexus driver %I%", 205 &simba_ops, /* driver ops */ 206 }; 207 208 static struct modlinkage modlinkage = { 209 MODREV_1, 210 (void *)&modldrv, 211 NULL 212 }; 213 214 /* 215 * Simba specific error state structure 216 */ 217 struct simba_errstate { 218 char *error; 219 ushort_t pci_cfg_stat; 220 ushort_t pci_cfg_sec_stat; 221 uint64_t afsr; 222 uint64_t afar; 223 int bridge_secondary; 224 }; 225 226 struct simba_cfg_state { 227 dev_info_t *dip; 228 ushort_t command; 229 uchar_t cache_line_size; 230 uchar_t latency_timer; 231 uchar_t header_type; 232 uchar_t bus_number; 233 uchar_t sec_bus_number; 234 uchar_t sub_bus_number; 235 uchar_t sec_latency_timer; 236 ushort_t bridge_control; 237 }; 238 239 /* 240 * soft state pointer and structure template: 241 */ 242 static void *simba_state; 243 244 typedef struct { 245 246 dev_info_t *dip; 247 248 /* 249 * configuration register state for the bus: 250 */ 251 ddi_acc_handle_t config_handle; 252 uchar_t simba_cache_line_size; 253 uchar_t simba_latency_timer; 254 255 /* 256 * cpr support: 257 */ 258 uint_t config_state_index; 259 struct simba_cfg_state *simba_config_state_p; 260 ddi_iblock_cookie_t fm_ibc; 261 int fm_cap; 262 kmutex_t simba_mutex; 263 uint_t simba_soft_state; 264 #define SIMBA_SOFT_STATE_CLOSED 0x00 265 #define SIMBA_SOFT_STATE_OPEN 0x01 266 #define SIMBA_SOFT_STATE_OPEN_EXCL 0x02 267 } simba_devstate_t; 268 269 /* 270 * The following variable enables a workaround for the following obp bug: 271 * 272 * 1234181 - obp should set latency timer registers in pci 273 * configuration header 274 * 275 * Until this bug gets fixed in the obp, the following workaround should 276 * be enabled. 277 */ 278 static uint_t simba_set_latency_timer_register = 1; 279 280 /* 281 * The following variable enables a workaround for an obp bug to be 282 * submitted. A bug requesting a workaround fof this problem has 283 * been filed: 284 * 285 * 1235094 - need workarounds on positron nexus drivers to set cache 286 * line size registers 287 * 288 * Until this bug gets fixed in the obp, the following workaround should 289 * be enabled. 290 */ 291 static uint_t simba_set_cache_line_size_register = 1; 292 293 294 /* 295 * forward function declarations: 296 */ 297 static void simba_uninitchild(dev_info_t *); 298 static int simba_initchild(dev_info_t *child); 299 static void simba_save_config_regs(simba_devstate_t *simba_p); 300 static void simba_restore_config_regs(simba_devstate_t *simba_p); 301 static int simba_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, 302 const void *impl_data); 303 304 int 305 _init(void) 306 { 307 int e; 308 309 DEBUG0(D_ATTACH, "_init() installing module...\n"); 310 if ((e = ddi_soft_state_init(&simba_state, sizeof (simba_devstate_t), 311 1)) == 0 && (e = mod_install(&modlinkage)) != 0) 312 ddi_soft_state_fini(&simba_state); 313 314 DEBUG0(D_ATTACH, "_init() module installed\n"); 315 return (e); 316 } 317 318 int 319 _fini(void) 320 { 321 int e; 322 DEBUG0(D_ATTACH, "_fini() removing module...\n"); 323 if ((e = mod_remove(&modlinkage)) == 0) 324 ddi_soft_state_fini(&simba_state); 325 return (e); 326 } 327 328 int 329 _info(struct modinfo *modinfop) 330 { 331 DEBUG0(D_ATTACH, "_info() called.\n"); 332 return (mod_info(&modlinkage, modinfop)); 333 } 334 335 /*ARGSUSED*/ 336 static int 337 simba_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 338 { 339 simba_devstate_t *simba_p; /* per simba state pointer */ 340 int instance; 341 342 instance = getminor((dev_t)arg); 343 simba_p = (simba_devstate_t *)ddi_get_soft_state(simba_state, 344 instance); 345 346 switch (infocmd) { 347 default: 348 return (DDI_FAILURE); 349 350 case DDI_INFO_DEVT2INSTANCE: 351 *result = (void *)(uintptr_t)instance; 352 return (DDI_SUCCESS); 353 354 case DDI_INFO_DEVT2DEVINFO: 355 if (simba_p == NULL) 356 return (DDI_FAILURE); 357 *result = (void *)simba_p->dip; 358 return (DDI_SUCCESS); 359 } 360 } 361 362 /*ARGSUSED*/ 363 static int 364 simba_probe(register dev_info_t *devi) 365 { 366 DEBUG0(D_ATTACH, "simba_probe() called.\n"); 367 return (DDI_PROBE_SUCCESS); 368 } 369 370 /*ARGSUSED*/ 371 static int 372 simba_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 373 { 374 int instance; 375 simba_devstate_t *simba; 376 377 switch (cmd) { 378 case DDI_ATTACH: 379 380 DEBUG1(D_ATTACH, "attach(%p) ATTACH\n", devi); 381 382 /* 383 * Make sure the "device_type" property exists. 384 */ 385 (void) ddi_prop_update_string(DDI_DEV_T_NONE, devi, 386 "device_type", "pci"); 387 388 /* 389 * Allocate and get soft state structure. 390 */ 391 instance = ddi_get_instance(devi); 392 if (ddi_soft_state_zalloc(simba_state, instance) != DDI_SUCCESS) 393 return (DDI_FAILURE); 394 simba = (simba_devstate_t *)ddi_get_soft_state(simba_state, 395 instance); 396 simba->dip = devi; 397 mutex_init(&simba->simba_mutex, NULL, MUTEX_DRIVER, NULL); 398 simba->simba_soft_state = SIMBA_SOFT_STATE_CLOSED; 399 400 /* 401 * create minor node for devctl interfaces 402 */ 403 if (ddi_create_minor_node(devi, "devctl", S_IFCHR, instance, 404 DDI_NT_NEXUS, 0) != DDI_SUCCESS) { 405 mutex_destroy(&simba->simba_mutex); 406 ddi_soft_state_free(simba_state, instance); 407 return (DDI_FAILURE); 408 } 409 410 if (pci_config_setup(devi, &simba->config_handle) != 411 DDI_SUCCESS) { 412 ddi_remove_minor_node(devi, "devctl"); 413 mutex_destroy(&simba->simba_mutex); 414 ddi_soft_state_free(simba_state, instance); 415 return (DDI_FAILURE); 416 } 417 418 /* 419 * Simba cache line size is 64 bytes and hardwired. 420 */ 421 simba->simba_cache_line_size = 422 pci_config_get8(simba->config_handle, 423 PCI_CONF_CACHE_LINESZ); 424 simba->simba_latency_timer = 425 pci_config_get8(simba->config_handle, 426 PCI_CONF_LATENCY_TIMER); 427 428 /* simba specific, clears up the pri/sec status registers */ 429 pci_config_put16(simba->config_handle, 0x6, 0xffff); 430 pci_config_put16(simba->config_handle, 0x1e, 0xffff); 431 432 DEBUG2(D_ATTACH, "simba_attach(): clsz=%x, lt=%x\n", 433 simba->simba_cache_line_size, 434 simba->simba_latency_timer); 435 436 /* 437 * Initialize FMA support 438 */ 439 simba->fm_cap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE | 440 DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE; 441 442 /* 443 * Call parent to get it's capablity 444 */ 445 ddi_fm_init(devi, &simba->fm_cap, &simba->fm_ibc); 446 447 ASSERT((simba->fm_cap & DDI_FM_ERRCB_CAPABLE) && 448 (simba->fm_cap & DDI_FM_EREPORT_CAPABLE)); 449 450 pci_ereport_setup(devi); 451 452 ddi_fm_handler_register(devi, simba_err_callback, simba); 453 454 ddi_report_dev(devi); 455 DEBUG0(D_ATTACH, "attach(): ATTACH done\n"); 456 return (DDI_SUCCESS); 457 458 case DDI_RESUME: 459 460 /* 461 * Get the soft state structure for the bridge. 462 */ 463 simba = (simba_devstate_t *) 464 ddi_get_soft_state(simba_state, ddi_get_instance(devi)); 465 simba_restore_config_regs(simba); 466 return (DDI_SUCCESS); 467 } 468 return (DDI_FAILURE); 469 } 470 471 /*ARGSUSED*/ 472 static int 473 simba_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 474 { 475 simba_devstate_t *simba; 476 simba = (simba_devstate_t *) 477 ddi_get_soft_state(simba_state, ddi_get_instance(devi)); 478 479 switch (cmd) { 480 case DDI_DETACH: 481 DEBUG0(D_DETACH, "detach() called\n"); 482 ddi_fm_handler_unregister(devi); 483 pci_ereport_teardown(devi); 484 ddi_fm_fini(devi); 485 pci_config_teardown(&simba->config_handle); 486 (void) ddi_prop_remove(DDI_DEV_T_NONE, devi, "device_type"); 487 ddi_remove_minor_node(devi, "devctl"); 488 mutex_destroy(&simba->simba_mutex); 489 ddi_soft_state_free(simba_state, ddi_get_instance(devi)); 490 return (DDI_SUCCESS); 491 492 case DDI_SUSPEND: 493 simba_save_config_regs(simba); 494 return (DDI_SUCCESS); 495 } 496 return (DDI_FAILURE); 497 } 498 499 /*ARGSUSED*/ 500 static int 501 simba_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 502 off_t offset, off_t len, caddr_t *vaddrp) 503 { 504 register dev_info_t *pdip; 505 506 DEBUG3(D_MAP, "simba_bus_map(): dip=%p, rdip=%p, mp=%p", dip, rdip, mp); 507 DEBUG3(D_MAP, "simba_bus_map(): offset=%lx, len=%lx, vaddrp=%p", 508 offset, len, vaddrp); 509 510 pdip = (dev_info_t *)DEVI(dip)->devi_parent; 511 return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map) 512 (pdip, rdip, mp, offset, len, vaddrp)); 513 } 514 515 /* 516 * Registered error handling callback with our parent 517 */ 518 static int 519 simba_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *impl_data) 520 { 521 simba_devstate_t *simba = (simba_devstate_t *)impl_data; 522 struct simba_errstate simba_err; 523 int ret = 0; 524 525 bzero(&simba_err, sizeof (struct simba_errstate)); 526 simba_err.afsr = pci_config_get64(simba->config_handle, 0xe8); 527 simba_err.afar = pci_config_get64(simba->config_handle, 0xf0); 528 derr->fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 529 530 pci_ereport_post(dip, derr, NULL); 531 ret = derr->fme_status; 532 533 DEBUG6(D_FAULT, "%s-%d: cleaning up fault bits %x %x %x.%8x\n", 534 ddi_driver_name(simba->dip), ddi_get_instance(simba->dip), 535 simba_err.pci_cfg_stat, simba_err.pci_cfg_sec_stat, 536 (uint_t)(simba_err.afsr >> 32), (uint_t)simba_err.afsr); 537 pci_config_put64(simba->config_handle, 0xe8, simba_err.afsr); 538 539 return (ret); 540 } 541 542 #if defined(DEBUG) && !defined(lint) 543 static char *ops[] = 544 { 545 "DDI_CTLOPS_DMAPMAPC", 546 "DDI_CTLOPS_INITCHILD", 547 "DDI_CTLOPS_UNINITCHILD", 548 "DDI_CTLOPS_REPORTDEV", 549 "DDI_CTLOPS_REPORTINT", 550 "DDI_CTLOPS_REGSIZE", 551 "DDI_CTLOPS_NREGS", 552 "DDI_CTLOPS_RESERVED0", 553 "DDI_CTLOPS_SIDDEV", 554 "DDI_CTLOPS_SLAVEONLY", 555 "DDI_CTLOPS_AFFINITY", 556 "DDI_CTLOPS_IOMIN", 557 "DDI_CTLOPS_PTOB", 558 "DDI_CTLOPS_BTOP", 559 "DDI_CTLOPS_BTOPR", 560 "DDI_CTLOPS_RESERVED1", 561 "DDI_CTLOPS_RESERVED2", 562 "DDI_CTLOPS_RESERVED3", 563 "DDI_CTLOPS_RESERVED4", 564 "DDI_CTLOPS_RESERVED5", 565 "DDI_CTLOPS_DVMAPAGESIZE", 566 "DDI_CTLOPS_POWER", 567 "DDI_CTLOPS_ATTACH", 568 "DDI_CTLOPS_DETACH", 569 "DDI_CTLOPS_POKE", 570 "DDI_CTLOPS_PEEK" 571 }; 572 #endif 573 574 /*ARGSUSED*/ 575 static int 576 simba_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop, 577 void *arg, void *result) 578 { 579 int reglen; 580 int rn; 581 int totreg; 582 pci_regspec_t *drv_regp; 583 584 DEBUG6(D_CTLOPS, 585 "simba_ctlops(): dip=%p rdip=%p ctlop=%x-%s arg=%p result=%p", 586 dip, rdip, ctlop, ctlop < (sizeof (ops) / sizeof (ops[0])) ? 587 ops[ctlop] : "Unknown", arg, result); 588 589 switch (ctlop) { 590 case DDI_CTLOPS_REPORTDEV: 591 if (rdip == (dev_info_t *)0) 592 return (DDI_FAILURE); 593 cmn_err(CE_CONT, "?PCI-device: %s@%s, %s%d\n", 594 ddi_node_name(rdip), ddi_get_name_addr(rdip), 595 ddi_driver_name(rdip), 596 ddi_get_instance(rdip)); 597 return (DDI_SUCCESS); 598 599 case DDI_CTLOPS_INITCHILD: 600 return (simba_initchild((dev_info_t *)arg)); 601 602 case DDI_CTLOPS_UNINITCHILD: 603 simba_uninitchild((dev_info_t *)arg); 604 return (DDI_SUCCESS); 605 606 case DDI_CTLOPS_SIDDEV: 607 return (DDI_SUCCESS); 608 609 case DDI_CTLOPS_REGSIZE: 610 case DDI_CTLOPS_NREGS: 611 if (rdip == (dev_info_t *)0) 612 return (DDI_FAILURE); 613 break; 614 615 default: 616 DEBUG0(D_CTLOPS, "simba_ctlops(): calling ddi_ctlops()"); 617 return (ddi_ctlops(dip, rdip, ctlop, arg, result)); 618 } 619 620 *(int *)result = 0; 621 if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, 622 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "reg", 623 (caddr_t)&drv_regp, ®len) != DDI_SUCCESS) 624 return (DDI_FAILURE); 625 626 totreg = reglen / sizeof (pci_regspec_t); 627 if (ctlop == DDI_CTLOPS_NREGS) 628 *(int *)result = totreg; 629 else if (ctlop == DDI_CTLOPS_REGSIZE) { 630 rn = *(int *)arg; 631 if (rn >= totreg) { 632 kmem_free(drv_regp, reglen); 633 return (DDI_FAILURE); 634 } 635 *(off_t *)result = drv_regp[rn].pci_size_low | 636 ((uint64_t)drv_regp[rn].pci_size_hi << 32); 637 } 638 639 kmem_free(drv_regp, reglen); 640 DEBUG1(D_CTLOPS, "simba_ctlops(): *result=%lx\n", *(off_t *)result); 641 return (DDI_SUCCESS); 642 } 643 644 static int 645 simba_name_child(dev_info_t *child, char *name, int namelen) 646 { 647 uint_t n, slot, func; 648 pci_regspec_t *pci_rp; 649 650 if (ndi_dev_is_persistent_node(child) == 0) { 651 char **unit_addr; 652 653 /* name .conf nodes by "unit-address" property" */ 654 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, child, 655 DDI_PROP_DONTPASS, "unit-address", &unit_addr, &n) != 656 DDI_PROP_SUCCESS) { 657 cmn_err(CE_WARN, "cannot name node from %s.conf", 658 ddi_driver_name(child)); 659 return (DDI_FAILURE); 660 } 661 if (n != 1 || *unit_addr == NULL || **unit_addr == 0) { 662 cmn_err(CE_WARN, "unit-address property in %s.conf" 663 " not well-formed", ddi_driver_name(child)); 664 ddi_prop_free(unit_addr); 665 return (DDI_FAILURE); 666 } 667 668 (void) snprintf(name, namelen, "%s", *unit_addr); 669 ddi_prop_free(unit_addr); 670 return (DDI_SUCCESS); 671 } 672 673 /* name hardware nodes by "reg" property */ 674 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, 0, "reg", 675 (int **)&pci_rp, &n) != DDI_SUCCESS) 676 return (DDI_FAILURE); 677 678 /* get the device identifications */ 679 slot = PCI_REG_DEV_G(pci_rp->pci_phys_hi); 680 func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi); 681 682 if (func != 0) 683 (void) snprintf(name, namelen, "%x,%x", slot, func); 684 else 685 (void) snprintf(name, namelen, "%x", slot); 686 687 ddi_prop_free(pci_rp); 688 return (DDI_SUCCESS); 689 } 690 691 static int 692 simba_initchild(dev_info_t *child) 693 { 694 char name[MAXNAMELEN]; 695 int i; 696 ddi_acc_handle_t config_handle; 697 ushort_t command_preserve, command; 698 uchar_t header_type; 699 uchar_t min_gnt, latency_timer; 700 simba_devstate_t *simba; 701 uint_t n; 702 703 DEBUG1(D_INIT_CLD, "simba_initchild(): child=%p\n", child); 704 705 /* 706 * Pseudo nodes indicate a prototype node with per-instance 707 * properties to be merged into the real h/w device node. 708 * The interpretation of the unit-address is DD[,F] 709 * where DD is the device id and F is the function. 710 */ 711 if (ndi_dev_is_persistent_node(child) == 0) { 712 extern int pci_allow_pseudo_children; 713 pci_regspec_t *pci_rp; 714 715 if (ddi_getlongprop(DDI_DEV_T_ANY, child, 716 DDI_PROP_DONTPASS, "reg", (caddr_t)&pci_rp, &i) == 717 DDI_SUCCESS) { 718 cmn_err(CE_WARN, 719 "cannot merge prototype from %s.conf", 720 ddi_driver_name(child)); 721 kmem_free(pci_rp, i); 722 return (DDI_NOT_WELL_FORMED); 723 } 724 725 if (simba_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS) 726 return (DDI_NOT_WELL_FORMED); 727 728 ddi_set_name_addr(child, name); 729 ddi_set_parent_data(child, NULL); 730 731 /* 732 * Try to merge the properties from this prototype 733 * node into real h/w nodes. 734 */ 735 if (ndi_merge_node(child, simba_name_child) == DDI_SUCCESS) { 736 /* 737 * Merged ok - return failure to remove the node. 738 */ 739 simba_uninitchild(child); 740 return (DDI_FAILURE); 741 } 742 743 /* workaround for ddivs to run under PCI */ 744 if (pci_allow_pseudo_children) 745 return (DDI_SUCCESS); 746 747 /* 748 * The child was not merged into a h/w node, 749 * but there's not much we can do with it other 750 * than return failure to cause the node to be removed. 751 */ 752 cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged", 753 ddi_driver_name(child), ddi_get_name_addr(child), 754 ddi_driver_name(child)); 755 simba_uninitchild(child); 756 return (DDI_NOT_WELL_FORMED); 757 } 758 759 /* 760 * Initialize real h/w nodes 761 */ 762 if (simba_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS) 763 return (DDI_FAILURE); 764 765 ddi_set_name_addr(child, name); 766 ddi_set_parent_data(child, NULL); 767 768 if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) { 769 simba_uninitchild(child); 770 return (DDI_FAILURE); 771 } 772 773 DEBUG0(D_INIT_CLD, "simba_initchild(): pci_config_setup success!\n"); 774 775 /* 776 * Determine the configuration header type. 777 */ 778 header_type = pci_config_get8(config_handle, PCI_CONF_HEADER); 779 780 /* 781 * Support for the "command-preserve" property. 782 */ 783 command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child, 784 DDI_PROP_DONTPASS, "command-preserve", 0); 785 command = pci_config_get16(config_handle, PCI_CONF_COMM); 786 command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB); 787 command |= (simba_command_default & ~command_preserve); 788 pci_config_put16(config_handle, PCI_CONF_COMM, command); 789 790 /* clean up all PCI child devices status register */ 791 pci_config_put16(config_handle, PCI_CONF_STAT, 0xffff); 792 793 /* 794 * If the device has a primary bus control register then program it 795 * based on the settings in the command register. 796 */ 797 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { 798 ushort_t bcr = 799 pci_config_get16(config_handle, PCI_BCNF_BCNTRL); 800 if (simba_command_default & PCI_COMM_PARITY_DETECT) 801 bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE; 802 if (simba_command_default & PCI_COMM_SERR_ENABLE) 803 bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE; 804 bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE; 805 pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr); 806 } 807 808 simba = (simba_devstate_t *)ddi_get_soft_state(simba_state, 809 ddi_get_instance(ddi_get_parent(child))); 810 /* 811 * Initialize cache-line-size configuration register if needed. 812 */ 813 if (simba_set_cache_line_size_register && 814 ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, 815 "cache-line-size", 0) == 0) { 816 pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ, 817 simba->simba_cache_line_size); 818 n = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ); 819 if (n != 0) 820 (void) ndi_prop_update_int(DDI_DEV_T_NONE, child, 821 "cache-line-size", n); 822 } 823 824 /* 825 * Initialize latency timer configuration registers if needed. 826 */ 827 if (simba_set_latency_timer_register && 828 ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, 829 "latency-timer", 0) == 0) { 830 831 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { 832 latency_timer = simba->simba_latency_timer; 833 pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER, 834 simba->simba_latency_timer); 835 } else { 836 min_gnt = pci_config_get8(config_handle, 837 PCI_CONF_MIN_G); 838 latency_timer = min_gnt * 8; 839 } 840 pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER, 841 latency_timer); 842 n = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER); 843 if (n != 0) 844 (void) ndi_prop_update_int(DDI_DEV_T_NONE, child, 845 "latency-timer", n); 846 } 847 848 pci_config_teardown(&config_handle); 849 DEBUG0(D_INIT_CLD, "simba_initchild(): pci_config_teardown called\n"); 850 return (DDI_SUCCESS); 851 } 852 853 static void 854 simba_uninitchild(dev_info_t *dip) 855 { 856 ddi_set_name_addr(dip, NULL); 857 858 /* 859 * Strip the node to properly convert it back to prototype form 860 */ 861 impl_rem_dev_props(dip); 862 } 863 864 /* 865 * simba_save_config_regs 866 * 867 * This routine saves the state of the configuration registers of all 868 * the child nodes of each PBM. 869 * 870 * used by: simba_detach() on suspends 871 * 872 * return value: none 873 */ 874 static void 875 simba_save_config_regs(simba_devstate_t *simba_p) 876 { 877 int i; 878 dev_info_t *dip; 879 ddi_acc_handle_t ch; 880 struct simba_cfg_state *statep; 881 882 for (i = 0, dip = ddi_get_child(simba_p->dip); dip != NULL; 883 dip = ddi_get_next_sibling(dip)) { 884 if (i_ddi_devi_attached(dip)) 885 i++; 886 } 887 if (!i) 888 return; 889 simba_p->simba_config_state_p = 890 kmem_zalloc(i * sizeof (struct simba_cfg_state), KM_NOSLEEP); 891 if (!simba_p->simba_config_state_p) { 892 cmn_err(CE_WARN, "not enough memrory to save simba child\n"); 893 return; 894 } 895 simba_p->config_state_index = i; 896 897 for (statep = simba_p->simba_config_state_p, 898 dip = ddi_get_child(simba_p->dip); 899 dip != NULL; 900 dip = ddi_get_next_sibling(dip)) { 901 902 if (!i_ddi_devi_attached(dip)) { 903 DEBUG4(D_DETACH, "%s%d: skipping unattached %s%d\n", 904 ddi_driver_name(simba_p->dip), 905 ddi_get_instance(simba_p->dip), 906 ddi_driver_name(dip), 907 ddi_get_instance(dip)); 908 continue; 909 } 910 911 DEBUG4(D_DETACH, "%s%d: saving regs for %s%d\n", 912 ddi_driver_name(simba_p->dip), 913 ddi_get_instance(simba_p->dip), 914 ddi_driver_name(dip), 915 ddi_get_instance(dip)); 916 917 if (pci_config_setup(dip, &ch) != DDI_SUCCESS) { 918 DEBUG4(D_DETACH, "%s%d: can't config space for %s%d\n", 919 ddi_driver_name(simba_p->dip), 920 ddi_get_instance(simba_p->dip), 921 ddi_driver_name(dip), 922 ddi_get_instance(dip)); 923 continue; 924 } 925 926 DEBUG3(D_DETACH, "%s%d: saving child dip=%p\n", 927 ddi_driver_name(simba_p->dip), 928 ddi_get_instance(simba_p->dip), 929 dip); 930 931 statep->dip = dip; 932 statep->command = pci_config_get16(ch, PCI_CONF_COMM); 933 statep->header_type = pci_config_get8(ch, PCI_CONF_HEADER); 934 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) 935 statep->bridge_control = 936 pci_config_get16(ch, PCI_BCNF_BCNTRL); 937 statep->cache_line_size = 938 pci_config_get8(ch, PCI_CONF_CACHE_LINESZ); 939 statep->latency_timer = 940 pci_config_get8(ch, PCI_CONF_LATENCY_TIMER); 941 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) 942 statep->sec_latency_timer = 943 pci_config_get8(ch, PCI_BCNF_LATENCY_TIMER); 944 /* 945 * Simba specific. 946 */ 947 if (pci_config_get16(ch, PCI_CONF_VENID) == PCI_SIMBA_VENID && 948 pci_config_get16(ch, PCI_CONF_DEVID) == PCI_SIMBA_DEVID) { 949 950 statep->bus_number = 951 pci_config_get8(ch, PCI_BCNF_PRIBUS); 952 statep->sec_bus_number = 953 pci_config_get8(ch, PCI_BCNF_SECBUS); 954 statep->sub_bus_number = 955 pci_config_get8(ch, PCI_BCNF_SUBBUS); 956 statep->bridge_control = 957 pci_config_get16(ch, PCI_BCNF_BCNTRL); 958 } 959 pci_config_teardown(&ch); 960 statep++; 961 } 962 } 963 964 965 /* 966 * simba_restore_config_regs 967 * 968 * This routine restores the state of the configuration registers of all 969 * the child nodes of each PBM. 970 * 971 * used by: simba_attach() on resume 972 * 973 * return value: none 974 */ 975 static void 976 simba_restore_config_regs(simba_devstate_t *simba_p) 977 { 978 int i; 979 dev_info_t *dip; 980 ddi_acc_handle_t ch; 981 struct simba_cfg_state *statep = simba_p->simba_config_state_p; 982 if (!simba_p->config_state_index) 983 return; 984 985 for (i = 0; i < simba_p->config_state_index; i++, statep++) { 986 dip = statep->dip; 987 if (!dip) { 988 cmn_err(CE_WARN, 989 "%s%d: skipping bad dev info (%d)\n", 990 ddi_driver_name(simba_p->dip), 991 ddi_get_instance(simba_p->dip), 992 i); 993 continue; 994 } 995 996 DEBUG5(D_ATTACH, "%s%d: restoring regs for %p-%s%d\n", 997 ddi_driver_name(simba_p->dip), 998 ddi_get_instance(simba_p->dip), 999 dip, 1000 ddi_driver_name(dip), 1001 ddi_get_instance(dip)); 1002 1003 if (pci_config_setup(dip, &ch) != DDI_SUCCESS) { 1004 DEBUG4(D_ATTACH, "%s%d: can't config space for %s%d\n", 1005 ddi_driver_name(simba_p->dip), 1006 ddi_get_instance(simba_p->dip), 1007 ddi_driver_name(dip), 1008 ddi_get_instance(dip)); 1009 continue; 1010 } 1011 pci_config_put16(ch, PCI_CONF_COMM, statep->command); 1012 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) 1013 pci_config_put16(ch, PCI_BCNF_BCNTRL, 1014 statep->bridge_control); 1015 /* 1016 * Simba specific. 1017 */ 1018 if (pci_config_get16(ch, PCI_CONF_VENID) == PCI_SIMBA_VENID && 1019 pci_config_get16(ch, PCI_CONF_DEVID) == PCI_SIMBA_DEVID) { 1020 pci_config_put8(ch, PCI_BCNF_PRIBUS, 1021 statep->bus_number); 1022 pci_config_put8(ch, PCI_BCNF_SECBUS, 1023 statep->sec_bus_number); 1024 pci_config_put8(ch, PCI_BCNF_SUBBUS, 1025 statep->sub_bus_number); 1026 pci_config_put16(ch, PCI_BCNF_BCNTRL, 1027 statep->bridge_control); 1028 } 1029 1030 pci_config_put8(ch, PCI_CONF_CACHE_LINESZ, 1031 statep->cache_line_size); 1032 pci_config_put8(ch, PCI_CONF_LATENCY_TIMER, 1033 statep->latency_timer); 1034 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) 1035 pci_config_put8(ch, PCI_BCNF_LATENCY_TIMER, 1036 statep->sec_latency_timer); 1037 pci_config_teardown(&ch); 1038 } 1039 1040 kmem_free(simba_p->simba_config_state_p, 1041 simba_p->config_state_index * sizeof (struct simba_cfg_state)); 1042 simba_p->simba_config_state_p = NULL; 1043 simba_p->config_state_index = 0; 1044 } 1045 1046 /* ARGSUSED */ 1047 static int 1048 simba_open(dev_t *devp, int flags, int otyp, cred_t *credp) 1049 { 1050 simba_devstate_t *simba_p; 1051 1052 /* 1053 * Make sure the open is for the right file type. 1054 */ 1055 if (otyp != OTYP_CHR) 1056 return (EINVAL); 1057 1058 /* 1059 * Get the soft state structure for the device. 1060 */ 1061 simba_p = (simba_devstate_t *)ddi_get_soft_state(simba_state, 1062 getminor(*devp)); 1063 if (simba_p == NULL) 1064 return (ENXIO); 1065 1066 /* 1067 * Handle the open by tracking the device state. 1068 */ 1069 mutex_enter(&simba_p->simba_mutex); 1070 if (flags & FEXCL) { 1071 if (simba_p->simba_soft_state != SIMBA_SOFT_STATE_CLOSED) { 1072 mutex_exit(&simba_p->simba_mutex); 1073 return (EBUSY); 1074 } 1075 simba_p->simba_soft_state = SIMBA_SOFT_STATE_OPEN_EXCL; 1076 } else { 1077 if (simba_p->simba_soft_state == SIMBA_SOFT_STATE_OPEN_EXCL) { 1078 mutex_exit(&simba_p->simba_mutex); 1079 return (EBUSY); 1080 } 1081 simba_p->simba_soft_state = SIMBA_SOFT_STATE_OPEN; 1082 } 1083 mutex_exit(&simba_p->simba_mutex); 1084 return (0); 1085 } 1086 1087 1088 /* ARGSUSED */ 1089 static int 1090 simba_close(dev_t dev, int flags, int otyp, cred_t *credp) 1091 { 1092 simba_devstate_t *simba_p; 1093 1094 if (otyp != OTYP_CHR) 1095 return (EINVAL); 1096 1097 simba_p = (simba_devstate_t *)ddi_get_soft_state(simba_state, 1098 getminor(dev)); 1099 if (simba_p == NULL) 1100 return (ENXIO); 1101 1102 mutex_enter(&simba_p->simba_mutex); 1103 simba_p->simba_soft_state = SIMBA_SOFT_STATE_CLOSED; 1104 mutex_exit(&simba_p->simba_mutex); 1105 return (0); 1106 } 1107 1108 1109 /* 1110 * simba_ioctl: devctl hotplug controls 1111 */ 1112 /* ARGSUSED */ 1113 static int 1114 simba_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, 1115 int *rvalp) 1116 { 1117 simba_devstate_t *simba_p; 1118 dev_info_t *self; 1119 struct devctl_iocdata *dcp; 1120 uint_t bus_state; 1121 int rv = 0; 1122 1123 simba_p = (simba_devstate_t *)ddi_get_soft_state(simba_state, 1124 getminor(dev)); 1125 if (simba_p == NULL) 1126 return (ENXIO); 1127 1128 self = simba_p->dip; 1129 1130 /* 1131 * We can use the generic implementation for these ioctls 1132 */ 1133 switch (cmd) { 1134 case DEVCTL_DEVICE_GETSTATE: 1135 case DEVCTL_DEVICE_ONLINE: 1136 case DEVCTL_DEVICE_OFFLINE: 1137 case DEVCTL_BUS_GETSTATE: 1138 return (ndi_devctl_ioctl(self, cmd, arg, mode, 0)); 1139 } 1140 1141 /* 1142 * read devctl ioctl data 1143 */ 1144 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS) 1145 return (EFAULT); 1146 1147 switch (cmd) { 1148 1149 case DEVCTL_DEVICE_RESET: 1150 rv = ENOTSUP; 1151 break; 1152 1153 1154 case DEVCTL_BUS_QUIESCE: 1155 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) 1156 if (bus_state == BUS_QUIESCED) 1157 break; 1158 (void) ndi_set_bus_state(self, BUS_QUIESCED); 1159 break; 1160 1161 case DEVCTL_BUS_UNQUIESCE: 1162 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) 1163 if (bus_state == BUS_ACTIVE) 1164 break; 1165 (void) ndi_set_bus_state(self, BUS_ACTIVE); 1166 break; 1167 1168 case DEVCTL_BUS_RESET: 1169 rv = ENOTSUP; 1170 break; 1171 1172 case DEVCTL_BUS_RESETALL: 1173 rv = ENOTSUP; 1174 break; 1175 1176 default: 1177 rv = ENOTTY; 1178 } 1179 1180 ndi_dc_freehdl(dcp); 1181 return (rv); 1182 } 1183 1184 /* 1185 * Initialize FMA resources for children devices. Called when 1186 * child calls ddi_fm_init(). 1187 */ 1188 /*ARGSUSED*/ 1189 static int 1190 simba_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap, 1191 ddi_iblock_cookie_t *ibc) 1192 { 1193 simba_devstate_t *simba_p = ddi_get_soft_state(simba_state, 1194 ddi_get_instance(dip)); 1195 1196 *ibc = simba_p->fm_ibc; 1197 return (simba_p->fm_cap); 1198 } 1199 1200 static void 1201 simba_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle) 1202 { 1203 i_ndi_busop_access_enter(dip, handle); 1204 } 1205 1206 /* ARGSUSED */ 1207 static void 1208 simba_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle) 1209 { 1210 i_ndi_busop_access_exit(dip, handle); 1211 } 1212