1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Host to PCI-Express local bus driver 29 */ 30 31 #include <sys/conf.h> 32 #include <sys/modctl.h> 33 #include <sys/file.h> 34 #include <sys/pci_impl.h> 35 #include <sys/pcie_impl.h> 36 #include <sys/sysmacros.h> 37 #include <sys/ddi_intr.h> 38 #include <sys/sunndi.h> 39 #include <sys/sunddi.h> 40 #include <sys/ddifm.h> 41 #include <sys/ndifm.h> 42 #include <sys/fm/util.h> 43 #include <sys/hotplug/pci/pcie_hp.h> 44 #include <io/pci/pci_tools_ext.h> 45 #include <io/pci/pci_common.h> 46 #include <io/pciex/pcie_nvidia.h> 47 48 /* 49 * Helper Macros 50 */ 51 #define NPE_IS_HANDLE_FOR_STDCFG_ACC(hp) \ 52 ((hp) != NULL && \ 53 ((ddi_acc_hdl_t *)(hp))->ah_platform_private != NULL && \ 54 (((ddi_acc_impl_t *)((ddi_acc_hdl_t *)(hp))-> \ 55 ah_platform_private)-> \ 56 ahi_acc_attr &(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_CONFIG_SPACE)) \ 57 == DDI_ACCATTR_CONFIG_SPACE) 58 59 /* 60 * Bus Operation functions 61 */ 62 static int npe_bus_map(dev_info_t *, dev_info_t *, ddi_map_req_t *, 63 off_t, off_t, caddr_t *); 64 static int npe_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, 65 void *, void *); 66 static int npe_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t, 67 ddi_intr_handle_impl_t *, void *); 68 static int npe_fm_init(dev_info_t *, dev_info_t *, int, 69 ddi_iblock_cookie_t *); 70 71 static int npe_fm_callback(dev_info_t *, ddi_fm_error_t *, const void *); 72 73 /* 74 * Disable URs and Received MA for all PCIe devices. Until x86 SW is changed so 75 * that random drivers do not do PIO accesses on devices that it does not own, 76 * these error bits must be disabled. SERR must also be disabled if URs have 77 * been masked. 78 */ 79 uint32_t npe_aer_uce_mask = PCIE_AER_UCE_UR; 80 uint32_t npe_aer_ce_mask = 0; 81 uint32_t npe_aer_suce_mask = PCIE_AER_SUCE_RCVD_MA; 82 83 struct bus_ops npe_bus_ops = { 84 BUSO_REV, 85 npe_bus_map, 86 NULL, 87 NULL, 88 NULL, 89 i_ddi_map_fault, 90 ddi_dma_map, 91 ddi_dma_allochdl, 92 ddi_dma_freehdl, 93 ddi_dma_bindhdl, 94 ddi_dma_unbindhdl, 95 ddi_dma_flush, 96 ddi_dma_win, 97 ddi_dma_mctl, 98 npe_ctlops, 99 ddi_bus_prop_op, 100 0, /* (*bus_get_eventcookie)(); */ 101 0, /* (*bus_add_eventcall)(); */ 102 0, /* (*bus_remove_eventcall)(); */ 103 0, /* (*bus_post_event)(); */ 104 0, /* (*bus_intr_ctl)(); */ 105 0, /* (*bus_config)(); */ 106 0, /* (*bus_unconfig)(); */ 107 npe_fm_init, /* (*bus_fm_init)(); */ 108 NULL, /* (*bus_fm_fini)(); */ 109 NULL, /* (*bus_fm_access_enter)(); */ 110 NULL, /* (*bus_fm_access_exit)(); */ 111 NULL, /* (*bus_power)(); */ 112 npe_intr_ops, /* (*bus_intr_op)(); */ 113 pcie_hp_common_ops /* (*bus_hp_op)(); */ 114 }; 115 116 static int npe_open(dev_t *, int, int, cred_t *); 117 static int npe_close(dev_t, int, int, cred_t *); 118 static int npe_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 119 120 struct cb_ops npe_cb_ops = { 121 npe_open, /* open */ 122 npe_close, /* close */ 123 nodev, /* strategy */ 124 nodev, /* print */ 125 nodev, /* dump */ 126 nodev, /* read */ 127 nodev, /* write */ 128 npe_ioctl, /* ioctl */ 129 nodev, /* devmap */ 130 nodev, /* mmap */ 131 nodev, /* segmap */ 132 nochpoll, /* poll */ 133 pcie_prop_op, /* cb_prop_op */ 134 NULL, /* streamtab */ 135 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */ 136 CB_REV, /* rev */ 137 nodev, /* int (*cb_aread)() */ 138 nodev /* int (*cb_awrite)() */ 139 }; 140 141 142 /* 143 * Device Node Operation functions 144 */ 145 static int npe_attach(dev_info_t *devi, ddi_attach_cmd_t cmd); 146 static int npe_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 147 static int npe_info(dev_info_t *, ddi_info_cmd_t, void *, void **); 148 149 struct dev_ops npe_ops = { 150 DEVO_REV, /* devo_rev */ 151 0, /* refcnt */ 152 npe_info, /* info */ 153 nulldev, /* identify */ 154 nulldev, /* probe */ 155 npe_attach, /* attach */ 156 npe_detach, /* detach */ 157 nulldev, /* reset */ 158 &npe_cb_ops, /* driver operations */ 159 &npe_bus_ops, /* bus operations */ 160 NULL, /* power */ 161 ddi_quiesce_not_needed, /* quiesce */ 162 }; 163 164 /* 165 * Internal routines in support of particular npe_ctlops. 166 */ 167 static int npe_removechild(dev_info_t *child); 168 static int npe_initchild(dev_info_t *child); 169 170 /* 171 * External support routine 172 */ 173 extern void npe_query_acpi_mcfg(dev_info_t *dip); 174 extern void npe_ck804_fix_aer_ptr(ddi_acc_handle_t cfg_hdl); 175 extern int npe_disable_empty_bridges_workaround(dev_info_t *child); 176 extern void npe_nvidia_error_workaround(ddi_acc_handle_t cfg_hdl); 177 extern void npe_intel_error_workaround(ddi_acc_handle_t cfg_hdl); 178 extern boolean_t npe_is_mmcfg_supported(dev_info_t *dip); 179 extern void npe_enable_htmsi_children(dev_info_t *dip); 180 extern int npe_save_htconfig_children(dev_info_t *dip); 181 extern int npe_restore_htconfig_children(dev_info_t *dip); 182 183 /* 184 * Module linkage information for the kernel. 185 */ 186 static struct modldrv modldrv = { 187 &mod_driverops, /* Type of module */ 188 "Host to PCIe nexus driver", /* Name of module */ 189 &npe_ops, /* driver ops */ 190 }; 191 192 static struct modlinkage modlinkage = { 193 MODREV_1, 194 (void *)&modldrv, 195 NULL 196 }; 197 198 /* Save minimal state. */ 199 void *npe_statep; 200 201 int 202 _init(void) 203 { 204 int e; 205 206 /* 207 * Initialize per-pci bus soft state pointer. 208 */ 209 e = ddi_soft_state_init(&npe_statep, sizeof (pci_state_t), 1); 210 if (e != 0) 211 return (e); 212 213 if ((e = mod_install(&modlinkage)) != 0) 214 ddi_soft_state_fini(&npe_statep); 215 216 return (e); 217 } 218 219 220 int 221 _fini(void) 222 { 223 int rc; 224 225 rc = mod_remove(&modlinkage); 226 if (rc != 0) 227 return (rc); 228 229 ddi_soft_state_fini(&npe_statep); 230 return (rc); 231 } 232 233 234 int 235 _info(struct modinfo *modinfop) 236 { 237 return (mod_info(&modlinkage, modinfop)); 238 } 239 240 /*ARGSUSED*/ 241 static int 242 npe_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 243 { 244 minor_t minor = getminor((dev_t)arg); 245 int instance = PCI_MINOR_NUM_TO_INSTANCE(minor); 246 pci_state_t *pcip = ddi_get_soft_state(npe_statep, instance); 247 int ret = DDI_SUCCESS; 248 249 switch (cmd) { 250 case DDI_INFO_DEVT2INSTANCE: 251 *result = (void *)(intptr_t)instance; 252 break; 253 case DDI_INFO_DEVT2DEVINFO: 254 if (pcip == NULL) { 255 ret = DDI_FAILURE; 256 break; 257 } 258 259 *result = (void *)pcip->pci_dip; 260 break; 261 default: 262 ret = DDI_FAILURE; 263 break; 264 } 265 266 return (ret); 267 } 268 269 /*ARGSUSED*/ 270 static int 271 npe_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 272 { 273 int instance = ddi_get_instance(devi); 274 pci_state_t *pcip = NULL; 275 276 if (cmd == DDI_RESUME) { 277 /* 278 * the system might still be able to resume even if this fails 279 */ 280 (void) npe_restore_htconfig_children(devi); 281 return (DDI_SUCCESS); 282 } 283 284 /* 285 * We must do this here in order to ensure that all top level devices 286 * get their HyperTransport MSI mapping regs programmed first. 287 * "Memory controller" and "hostbridge" class devices are leaf devices 288 * that may affect MSI translation functionality for devices 289 * connected to the same link/bus. 290 * 291 * This will also program HT MSI mapping registers on root buses 292 * devices (basically sitting on an HT bus) that are not dependent 293 * on the aforementioned HT devices for MSI translation. 294 */ 295 npe_enable_htmsi_children(devi); 296 297 if (ddi_prop_update_string(DDI_DEV_T_NONE, devi, "device_type", 298 "pciex") != DDI_PROP_SUCCESS) { 299 cmn_err(CE_WARN, "npe: 'device_type' prop create failed"); 300 } 301 302 if (ddi_soft_state_zalloc(npe_statep, instance) == DDI_SUCCESS) 303 pcip = ddi_get_soft_state(npe_statep, instance); 304 305 if (pcip == NULL) 306 return (DDI_FAILURE); 307 308 pcip->pci_dip = devi; 309 pcip->pci_soft_state = PCI_SOFT_STATE_CLOSED; 310 311 if (pcie_init(devi, NULL) != DDI_SUCCESS) 312 goto fail1; 313 314 /* Second arg: initialize for pci_express root nexus */ 315 if (pcitool_init(devi, B_TRUE) != DDI_SUCCESS) 316 goto fail2; 317 318 pcip->pci_fmcap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE | 319 DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE; 320 ddi_fm_init(devi, &pcip->pci_fmcap, &pcip->pci_fm_ibc); 321 322 if (pcip->pci_fmcap & DDI_FM_ERRCB_CAPABLE) { 323 ddi_fm_handler_register(devi, npe_fm_callback, NULL); 324 } 325 326 PCIE_DIP2PFD(devi) = kmem_zalloc(sizeof (pf_data_t), KM_SLEEP); 327 pcie_rc_init_pfd(devi, PCIE_DIP2PFD(devi)); 328 329 npe_query_acpi_mcfg(devi); 330 ddi_report_dev(devi); 331 pcie_fab_init_bus(devi, PCIE_BUS_FINAL); 332 333 return (DDI_SUCCESS); 334 335 fail2: 336 (void) pcie_uninit(devi); 337 fail1: 338 pcie_rc_fini_bus(devi); 339 ddi_soft_state_free(npe_statep, instance); 340 341 return (DDI_FAILURE); 342 } 343 344 /*ARGSUSED*/ 345 static int 346 npe_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 347 { 348 int instance = ddi_get_instance(devi); 349 pci_state_t *pcip; 350 351 pcip = ddi_get_soft_state(npe_statep, ddi_get_instance(devi)); 352 353 switch (cmd) { 354 case DDI_DETACH: 355 pcie_fab_fini_bus(devi, PCIE_BUS_INITIAL); 356 357 /* Uninitialize pcitool support. */ 358 pcitool_uninit(devi); 359 360 if (pcie_uninit(devi) != DDI_SUCCESS) 361 return (DDI_FAILURE); 362 363 if (pcip->pci_fmcap & DDI_FM_ERRCB_CAPABLE) 364 ddi_fm_handler_unregister(devi); 365 366 pcie_rc_fini_pfd(PCIE_DIP2PFD(devi)); 367 kmem_free(PCIE_DIP2PFD(devi), sizeof (pf_data_t)); 368 369 ddi_fm_fini(devi); 370 ddi_soft_state_free(npe_statep, instance); 371 return (DDI_SUCCESS); 372 373 case DDI_SUSPEND: 374 /* 375 * the system might still be able to suspend/resume even if 376 * this fails 377 */ 378 (void) npe_save_htconfig_children(devi); 379 return (DDI_SUCCESS); 380 default: 381 return (DDI_FAILURE); 382 } 383 } 384 385 /* 386 * Configure the access handle for standard configuration space 387 * access (see pci_fm_acc_setup for code that initializes the 388 * access-function pointers). 389 */ 390 static int 391 npe_setup_std_pcicfg_acc(dev_info_t *rdip, ddi_map_req_t *mp, 392 ddi_acc_hdl_t *hp, off_t offset, off_t len) 393 { 394 int ret; 395 396 if ((ret = pci_fm_acc_setup(hp, offset, len)) == 397 DDI_SUCCESS) { 398 if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) && 399 mp->map_handlep->ah_acc.devacc_attr_access 400 != DDI_DEFAULT_ACC) { 401 ndi_fmc_insert(rdip, ACC_HANDLE, 402 (void *)mp->map_handlep, NULL); 403 } 404 } 405 return (ret); 406 } 407 408 static int 409 npe_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 410 off_t offset, off_t len, caddr_t *vaddrp) 411 { 412 int rnumber; 413 int length; 414 int space; 415 ddi_acc_impl_t *ap; 416 ddi_acc_hdl_t *hp; 417 ddi_map_req_t mr; 418 pci_regspec_t pci_reg; 419 pci_regspec_t *pci_rp; 420 struct regspec reg; 421 pci_acc_cfblk_t *cfp; 422 int retval; 423 int64_t *ecfginfo; 424 uint_t nelem; 425 426 mr = *mp; /* Get private copy of request */ 427 mp = &mr; 428 429 /* 430 * check for register number 431 */ 432 switch (mp->map_type) { 433 case DDI_MT_REGSPEC: 434 pci_reg = *(pci_regspec_t *)(mp->map_obj.rp); 435 pci_rp = &pci_reg; 436 if (pci_common_get_reg_prop(rdip, pci_rp) != DDI_SUCCESS) 437 return (DDI_FAILURE); 438 break; 439 case DDI_MT_RNUMBER: 440 rnumber = mp->map_obj.rnumber; 441 /* 442 * get ALL "reg" properties for dip, select the one of 443 * of interest. In x86, "assigned-addresses" property 444 * is identical to the "reg" property, so there is no 445 * need to cross check the two to determine the physical 446 * address of the registers. 447 * This routine still performs some validity checks to 448 * make sure that everything is okay. 449 */ 450 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, rdip, 451 DDI_PROP_DONTPASS, "reg", (int **)&pci_rp, 452 (uint_t *)&length) != DDI_PROP_SUCCESS) 453 return (DDI_FAILURE); 454 455 /* 456 * validate the register number. 457 */ 458 length /= (sizeof (pci_regspec_t) / sizeof (int)); 459 if (rnumber >= length) { 460 ddi_prop_free(pci_rp); 461 return (DDI_FAILURE); 462 } 463 464 /* 465 * copy the required entry. 466 */ 467 pci_reg = pci_rp[rnumber]; 468 469 /* 470 * free the memory allocated by ddi_prop_lookup_int_array 471 */ 472 ddi_prop_free(pci_rp); 473 474 pci_rp = &pci_reg; 475 if (pci_common_get_reg_prop(rdip, pci_rp) != DDI_SUCCESS) 476 return (DDI_FAILURE); 477 mp->map_type = DDI_MT_REGSPEC; 478 break; 479 default: 480 return (DDI_ME_INVAL); 481 } 482 483 space = pci_rp->pci_phys_hi & PCI_REG_ADDR_M; 484 485 /* 486 * check for unmap and unlock of address space 487 */ 488 if ((mp->map_op == DDI_MO_UNMAP) || (mp->map_op == DDI_MO_UNLOCK)) { 489 switch (space) { 490 case PCI_ADDR_IO: 491 reg.regspec_bustype = 1; 492 break; 493 494 case PCI_ADDR_CONFIG: 495 /* 496 * If this is an unmap/unlock of a standard config 497 * space mapping (memory-mapped config space mappings 498 * would have the DDI_ACCATTR_CPU_VADDR bit set in the 499 * acc_attr), undo that setup here. 500 */ 501 if (NPE_IS_HANDLE_FOR_STDCFG_ACC(mp->map_handlep)) { 502 503 if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) && 504 mp->map_handlep->ah_acc.devacc_attr_access 505 != DDI_DEFAULT_ACC) { 506 ndi_fmc_remove(rdip, ACC_HANDLE, 507 (void *)mp->map_handlep); 508 } 509 return (DDI_SUCCESS); 510 } 511 512 pci_rp->pci_size_low = PCIE_CONF_HDR_SIZE; 513 514 /* FALLTHROUGH */ 515 case PCI_ADDR_MEM64: 516 /* 517 * MEM64 requires special treatment on map, to check 518 * that the device is below 4G. On unmap, however, 519 * we can assume that everything is OK... the map 520 * must have succeeded. 521 */ 522 /* FALLTHROUGH */ 523 case PCI_ADDR_MEM32: 524 reg.regspec_bustype = 0; 525 break; 526 527 default: 528 return (DDI_FAILURE); 529 } 530 531 /* 532 * Adjust offset and length 533 * A non-zero length means override the one in the regspec. 534 */ 535 pci_rp->pci_phys_low += (uint_t)offset; 536 if (len != 0) 537 pci_rp->pci_size_low = len; 538 539 reg.regspec_addr = pci_rp->pci_phys_low; 540 reg.regspec_size = pci_rp->pci_size_low; 541 542 mp->map_obj.rp = ® 543 retval = ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp); 544 if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) && 545 mp->map_handlep->ah_acc.devacc_attr_access != 546 DDI_DEFAULT_ACC) { 547 ndi_fmc_remove(rdip, ACC_HANDLE, 548 (void *)mp->map_handlep); 549 } 550 return (retval); 551 552 } 553 554 /* check for user mapping request - not legal for Config */ 555 if (mp->map_op == DDI_MO_MAP_HANDLE && space == PCI_ADDR_CONFIG) { 556 cmn_err(CE_NOTE, "npe: Config mapping request from user\n"); 557 return (DDI_FAILURE); 558 } 559 560 561 /* 562 * Note that pci_fm_acc_setup() is called to serve two purposes 563 * i) enable legacy PCI I/O style config space access 564 * ii) register with FMA 565 */ 566 if (space == PCI_ADDR_CONFIG) { 567 568 /* Can't map config space without a handle */ 569 hp = (ddi_acc_hdl_t *)mp->map_handlep; 570 if (hp == NULL) 571 return (DDI_FAILURE); 572 573 /* record the device address for future reference */ 574 cfp = (pci_acc_cfblk_t *)&hp->ah_bus_private; 575 cfp->c_busnum = PCI_REG_BUS_G(pci_rp->pci_phys_hi); 576 cfp->c_devnum = PCI_REG_DEV_G(pci_rp->pci_phys_hi); 577 cfp->c_funcnum = PCI_REG_FUNC_G(pci_rp->pci_phys_hi); 578 579 *vaddrp = (caddr_t)offset; 580 581 /* Check if MMCFG is supported */ 582 if (!npe_is_mmcfg_supported(rdip)) { 583 return (npe_setup_std_pcicfg_acc(rdip, mp, hp, 584 offset, len)); 585 } 586 587 588 if (ddi_prop_lookup_int64_array(DDI_DEV_T_ANY, rdip, 0, 589 "ecfg", &ecfginfo, &nelem) == DDI_PROP_SUCCESS) { 590 591 if (nelem != 4 || 592 cfp->c_busnum < ecfginfo[2] || 593 cfp->c_busnum > ecfginfo[3]) { 594 /* 595 * Invalid property or Doesn't contain the 596 * requested bus; fall back to standard 597 * (I/O-based) config access. 598 */ 599 ddi_prop_free(ecfginfo); 600 return (npe_setup_std_pcicfg_acc(rdip, mp, hp, 601 offset, len)); 602 } else { 603 pci_rp->pci_phys_low = ecfginfo[0]; 604 605 ddi_prop_free(ecfginfo); 606 607 pci_rp->pci_phys_low += ((cfp->c_busnum << 20) | 608 (cfp->c_devnum) << 15 | 609 (cfp->c_funcnum << 12)); 610 611 pci_rp->pci_size_low = PCIE_CONF_HDR_SIZE; 612 } 613 } else { 614 /* 615 * Couldn't find the MMCFG property -- fall back to 616 * standard config access 617 */ 618 return (npe_setup_std_pcicfg_acc(rdip, mp, hp, 619 offset, len)); 620 } 621 } 622 623 length = pci_rp->pci_size_low; 624 625 /* 626 * range check 627 */ 628 if ((offset >= length) || (len > length) || (offset + len > length)) 629 return (DDI_FAILURE); 630 631 /* 632 * Adjust offset and length 633 * A non-zero length means override the one in the regspec. 634 */ 635 pci_rp->pci_phys_low += (uint_t)offset; 636 if (len != 0) 637 pci_rp->pci_size_low = len; 638 639 /* 640 * convert the pci regsec into the generic regspec used by the 641 * parent root nexus driver. 642 */ 643 switch (space) { 644 case PCI_ADDR_IO: 645 reg.regspec_bustype = 1; 646 break; 647 case PCI_ADDR_CONFIG: 648 case PCI_ADDR_MEM64: 649 /* 650 * We can't handle 64-bit devices that are mapped above 651 * 4G or that are larger than 4G. 652 */ 653 if (pci_rp->pci_phys_mid != 0 || pci_rp->pci_size_hi != 0) 654 return (DDI_FAILURE); 655 /* 656 * Other than that, we can treat them as 32-bit mappings 657 */ 658 /* FALLTHROUGH */ 659 case PCI_ADDR_MEM32: 660 reg.regspec_bustype = 0; 661 break; 662 default: 663 return (DDI_FAILURE); 664 } 665 666 reg.regspec_addr = pci_rp->pci_phys_low; 667 reg.regspec_size = pci_rp->pci_size_low; 668 669 mp->map_obj.rp = ® 670 retval = ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp); 671 if (retval == DDI_SUCCESS) { 672 /* 673 * For config space gets force use of cautious access routines. 674 * These will handle default and protected mode accesses too. 675 */ 676 if (space == PCI_ADDR_CONFIG) { 677 ap = (ddi_acc_impl_t *)mp->map_handlep; 678 ap->ahi_acc_attr &= ~DDI_ACCATTR_DIRECT; 679 ap->ahi_acc_attr |= DDI_ACCATTR_CONFIG_SPACE; 680 ap->ahi_get8 = i_ddi_caut_get8; 681 ap->ahi_get16 = i_ddi_caut_get16; 682 ap->ahi_get32 = i_ddi_caut_get32; 683 ap->ahi_get64 = i_ddi_caut_get64; 684 ap->ahi_rep_get8 = i_ddi_caut_rep_get8; 685 ap->ahi_rep_get16 = i_ddi_caut_rep_get16; 686 ap->ahi_rep_get32 = i_ddi_caut_rep_get32; 687 ap->ahi_rep_get64 = i_ddi_caut_rep_get64; 688 } 689 if (DDI_FM_ACC_ERR_CAP(ddi_fm_capable(rdip)) && 690 mp->map_handlep->ah_acc.devacc_attr_access != 691 DDI_DEFAULT_ACC) { 692 ndi_fmc_insert(rdip, ACC_HANDLE, 693 (void *)mp->map_handlep, NULL); 694 } 695 } 696 return (retval); 697 } 698 699 700 701 /*ARGSUSED*/ 702 static int 703 npe_ctlops(dev_info_t *dip, dev_info_t *rdip, 704 ddi_ctl_enum_t ctlop, void *arg, void *result) 705 { 706 int rn; 707 int totreg; 708 uint_t reglen; 709 pci_regspec_t *drv_regp; 710 struct attachspec *asp; 711 struct detachspec *dsp; 712 pci_state_t *pci_p = ddi_get_soft_state(npe_statep, 713 ddi_get_instance(dip)); 714 715 switch (ctlop) { 716 case DDI_CTLOPS_REPORTDEV: 717 if (rdip == (dev_info_t *)0) 718 return (DDI_FAILURE); 719 cmn_err(CE_CONT, "?PCI Express-device: %s@%s, %s%d\n", 720 ddi_node_name(rdip), ddi_get_name_addr(rdip), 721 ddi_driver_name(rdip), ddi_get_instance(rdip)); 722 return (DDI_SUCCESS); 723 724 case DDI_CTLOPS_INITCHILD: 725 return (npe_initchild((dev_info_t *)arg)); 726 727 case DDI_CTLOPS_UNINITCHILD: 728 return (npe_removechild((dev_info_t *)arg)); 729 730 case DDI_CTLOPS_SIDDEV: 731 return (DDI_SUCCESS); 732 733 case DDI_CTLOPS_REGSIZE: 734 case DDI_CTLOPS_NREGS: 735 if (rdip == (dev_info_t *)0) 736 return (DDI_FAILURE); 737 738 *(int *)result = 0; 739 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, rdip, 740 DDI_PROP_DONTPASS, "reg", (int **)&drv_regp, 741 ®len) != DDI_PROP_SUCCESS) { 742 return (DDI_FAILURE); 743 } 744 745 totreg = (reglen * sizeof (int)) / sizeof (pci_regspec_t); 746 if (ctlop == DDI_CTLOPS_NREGS) 747 *(int *)result = totreg; 748 else if (ctlop == DDI_CTLOPS_REGSIZE) { 749 rn = *(int *)arg; 750 if (rn >= totreg) { 751 ddi_prop_free(drv_regp); 752 return (DDI_FAILURE); 753 } 754 *(off_t *)result = drv_regp[rn].pci_size_low; 755 } 756 ddi_prop_free(drv_regp); 757 758 return (DDI_SUCCESS); 759 760 case DDI_CTLOPS_POWER: 761 { 762 power_req_t *reqp = (power_req_t *)arg; 763 /* 764 * We currently understand reporting of PCI_PM_IDLESPEED 765 * capability. Everything else is passed up. 766 */ 767 if ((reqp->request_type == PMR_REPORT_PMCAP) && 768 (reqp->req.report_pmcap_req.cap == PCI_PM_IDLESPEED)) 769 return (DDI_SUCCESS); 770 771 break; 772 } 773 774 case DDI_CTLOPS_PEEK: 775 case DDI_CTLOPS_POKE: 776 return (pci_common_peekpoke(dip, rdip, ctlop, arg, result)); 777 778 /* X86 systems support PME wakeup from suspended state */ 779 case DDI_CTLOPS_ATTACH: 780 if (!pcie_is_child(dip, rdip)) 781 return (DDI_SUCCESS); 782 783 asp = (struct attachspec *)arg; 784 if ((asp->when == DDI_POST) && (asp->result == DDI_SUCCESS)) { 785 pf_init(rdip, (void *)pci_p->pci_fm_ibc, asp->cmd); 786 (void) pcie_postattach_child(rdip); 787 } 788 789 /* only do this for immediate children */ 790 if (asp->cmd == DDI_RESUME && asp->when == DDI_PRE && 791 ddi_get_parent(rdip) == dip) 792 if (pci_pre_resume(rdip) != DDI_SUCCESS) { 793 /* Not good, better stop now. */ 794 cmn_err(CE_PANIC, 795 "Couldn't pre-resume device %p", 796 (void *) dip); 797 /* NOTREACHED */ 798 } 799 800 return (DDI_SUCCESS); 801 802 case DDI_CTLOPS_DETACH: 803 if (!pcie_is_child(dip, rdip)) 804 return (DDI_SUCCESS); 805 806 dsp = (struct detachspec *)arg; 807 808 if (dsp->when == DDI_PRE) 809 pf_fini(rdip, dsp->cmd); 810 811 /* only do this for immediate children */ 812 if (dsp->cmd == DDI_SUSPEND && dsp->when == DDI_POST && 813 ddi_get_parent(rdip) == dip) 814 if (pci_post_suspend(rdip) != DDI_SUCCESS) 815 return (DDI_FAILURE); 816 817 return (DDI_SUCCESS); 818 819 default: 820 break; 821 } 822 823 return (ddi_ctlops(dip, rdip, ctlop, arg, result)); 824 825 } 826 827 828 /* 829 * npe_intr_ops 830 */ 831 static int 832 npe_intr_ops(dev_info_t *pdip, dev_info_t *rdip, ddi_intr_op_t intr_op, 833 ddi_intr_handle_impl_t *hdlp, void *result) 834 { 835 return (pci_common_intr_ops(pdip, rdip, intr_op, hdlp, result)); 836 } 837 838 839 static int 840 npe_initchild(dev_info_t *child) 841 { 842 char name[80]; 843 pcie_bus_t *bus_p; 844 uint32_t regs; 845 ddi_acc_handle_t cfg_hdl; 846 847 /* 848 * Do not bind drivers to empty bridges. 849 * Fail above, if the bridge is found to be hotplug capable 850 */ 851 if (npe_disable_empty_bridges_workaround(child) == 1) 852 return (DDI_FAILURE); 853 854 if (pci_common_name_child(child, name, 80) != DDI_SUCCESS) 855 return (DDI_FAILURE); 856 857 ddi_set_name_addr(child, name); 858 859 /* 860 * Pseudo nodes indicate a prototype node with per-instance 861 * properties to be merged into the real h/w device node. 862 * The interpretation of the unit-address is DD[,F] 863 * where DD is the device id and F is the function. 864 */ 865 if (ndi_dev_is_persistent_node(child) == 0) { 866 extern int pci_allow_pseudo_children; 867 868 ddi_set_parent_data(child, NULL); 869 870 /* 871 * Try to merge the properties from this prototype 872 * node into real h/w nodes. 873 */ 874 if (ndi_merge_node(child, pci_common_name_child) == 875 DDI_SUCCESS) { 876 /* 877 * Merged ok - return failure to remove the node. 878 */ 879 ddi_set_name_addr(child, NULL); 880 return (DDI_FAILURE); 881 } 882 883 /* workaround for DDIVS to run under PCI Express */ 884 if (pci_allow_pseudo_children) { 885 /* 886 * If the "interrupts" property doesn't exist, 887 * this must be the ddivs no-intr case, and it returns 888 * DDI_SUCCESS instead of DDI_FAILURE. 889 */ 890 if (ddi_prop_get_int(DDI_DEV_T_ANY, child, 891 DDI_PROP_DONTPASS, "interrupts", -1) == -1) 892 return (DDI_SUCCESS); 893 /* 894 * Create the ddi_parent_private_data for a pseudo 895 * child. 896 */ 897 pci_common_set_parent_private_data(child); 898 return (DDI_SUCCESS); 899 } 900 901 /* 902 * The child was not merged into a h/w node, 903 * but there's not much we can do with it other 904 * than return failure to cause the node to be removed. 905 */ 906 cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged", 907 ddi_get_name(child), ddi_get_name_addr(child), 908 ddi_get_name(child)); 909 ddi_set_name_addr(child, NULL); 910 return (DDI_NOT_WELL_FORMED); 911 } 912 913 if (ddi_prop_get_int(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, 914 "interrupts", -1) != -1) 915 pci_common_set_parent_private_data(child); 916 else 917 ddi_set_parent_data(child, NULL); 918 919 /* Disable certain errors on PCIe drivers for x86 platforms */ 920 regs = pcie_get_aer_uce_mask() | npe_aer_uce_mask; 921 pcie_set_aer_uce_mask(regs); 922 regs = pcie_get_aer_ce_mask() | npe_aer_ce_mask; 923 pcie_set_aer_ce_mask(regs); 924 regs = pcie_get_aer_suce_mask() | npe_aer_suce_mask; 925 pcie_set_aer_suce_mask(regs); 926 927 /* 928 * If URs are disabled, mask SERRs as well, otherwise the system will 929 * still be notified of URs 930 */ 931 if (npe_aer_uce_mask & PCIE_AER_UCE_UR) 932 pcie_set_serr_mask(1); 933 934 if (pci_config_setup(child, &cfg_hdl) == DDI_SUCCESS) { 935 npe_ck804_fix_aer_ptr(cfg_hdl); 936 npe_nvidia_error_workaround(cfg_hdl); 937 npe_intel_error_workaround(cfg_hdl); 938 pci_config_teardown(&cfg_hdl); 939 } 940 941 bus_p = PCIE_DIP2BUS(child); 942 if (bus_p) { 943 uint16_t device_id = (uint16_t)(bus_p->bus_dev_ven_id >> 16); 944 uint16_t vendor_id = (uint16_t)(bus_p->bus_dev_ven_id & 0xFFFF); 945 uint16_t rev_id = bus_p->bus_rev_id; 946 947 /* Disable AER for certain NVIDIA Chipsets */ 948 if ((vendor_id == NVIDIA_VENDOR_ID) && 949 (device_id == NVIDIA_CK804_DEVICE_ID) && 950 (rev_id < NVIDIA_CK804_AER_VALID_REVID)) 951 bus_p->bus_aer_off = 0; 952 953 (void) pcie_initchild(child); 954 } 955 956 return (DDI_SUCCESS); 957 } 958 959 960 static int 961 npe_removechild(dev_info_t *dip) 962 { 963 pcie_uninitchild(dip); 964 965 ddi_set_name_addr(dip, NULL); 966 967 /* 968 * Strip the node to properly convert it back to prototype form 969 */ 970 ddi_remove_minor_node(dip, NULL); 971 972 ddi_prop_remove_all(dip); 973 974 return (DDI_SUCCESS); 975 } 976 977 static int 978 npe_open(dev_t *devp, int flags, int otyp, cred_t *credp) 979 { 980 minor_t minor = getminor(*devp); 981 int instance = PCI_MINOR_NUM_TO_INSTANCE(minor); 982 pci_state_t *pci_p = ddi_get_soft_state(npe_statep, instance); 983 int rv; 984 985 /* 986 * Make sure the open is for the right file type. 987 */ 988 if (otyp != OTYP_CHR) 989 return (EINVAL); 990 991 if (pci_p == NULL) 992 return (ENXIO); 993 994 mutex_enter(&pci_p->pci_mutex); 995 switch (PCI_MINOR_NUM_TO_PCI_DEVNUM(minor)) { 996 case PCI_TOOL_REG_MINOR_NUM: 997 case PCI_TOOL_INTR_MINOR_NUM: 998 break; 999 default: 1000 /* Handle devctl ioctls */ 1001 rv = pcie_open(pci_p->pci_dip, devp, flags, otyp, credp); 1002 mutex_exit(&pci_p->pci_mutex); 1003 return (rv); 1004 } 1005 1006 /* Handle pcitool ioctls */ 1007 if (flags & FEXCL) { 1008 if (pci_p->pci_soft_state != PCI_SOFT_STATE_CLOSED) { 1009 mutex_exit(&pci_p->pci_mutex); 1010 cmn_err(CE_NOTE, "npe_open: busy"); 1011 return (EBUSY); 1012 } 1013 pci_p->pci_soft_state = PCI_SOFT_STATE_OPEN_EXCL; 1014 } else { 1015 if (pci_p->pci_soft_state == PCI_SOFT_STATE_OPEN_EXCL) { 1016 mutex_exit(&pci_p->pci_mutex); 1017 cmn_err(CE_NOTE, "npe_open: busy"); 1018 return (EBUSY); 1019 } 1020 pci_p->pci_soft_state = PCI_SOFT_STATE_OPEN; 1021 } 1022 mutex_exit(&pci_p->pci_mutex); 1023 1024 return (0); 1025 } 1026 1027 static int 1028 npe_close(dev_t dev, int flags, int otyp, cred_t *credp) 1029 { 1030 minor_t minor = getminor(dev); 1031 int instance = PCI_MINOR_NUM_TO_INSTANCE(minor); 1032 pci_state_t *pci_p = ddi_get_soft_state(npe_statep, instance); 1033 int rv; 1034 1035 if (pci_p == NULL) 1036 return (ENXIO); 1037 1038 mutex_enter(&pci_p->pci_mutex); 1039 1040 switch (PCI_MINOR_NUM_TO_PCI_DEVNUM(minor)) { 1041 case PCI_TOOL_REG_MINOR_NUM: 1042 case PCI_TOOL_INTR_MINOR_NUM: 1043 break; 1044 default: 1045 /* Handle devctl ioctls */ 1046 rv = pcie_close(pci_p->pci_dip, dev, flags, otyp, credp); 1047 mutex_exit(&pci_p->pci_mutex); 1048 return (rv); 1049 } 1050 1051 /* Handle pcitool ioctls */ 1052 pci_p->pci_soft_state = PCI_SOFT_STATE_CLOSED; 1053 mutex_exit(&pci_p->pci_mutex); 1054 return (0); 1055 } 1056 1057 static int 1058 npe_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp) 1059 { 1060 minor_t minor = getminor(dev); 1061 int instance = PCI_MINOR_NUM_TO_INSTANCE(minor); 1062 pci_state_t *pci_p = ddi_get_soft_state(npe_statep, instance); 1063 int ret = ENOTTY; 1064 1065 if (pci_p == NULL) 1066 return (ENXIO); 1067 1068 switch (PCI_MINOR_NUM_TO_PCI_DEVNUM(minor)) { 1069 case PCI_TOOL_REG_MINOR_NUM: 1070 case PCI_TOOL_INTR_MINOR_NUM: 1071 /* To handle pcitool related ioctls */ 1072 ret = pci_common_ioctl(pci_p->pci_dip, dev, cmd, arg, mode, 1073 credp, rvalp); 1074 break; 1075 default: 1076 /* To handle devctl and hotplug related ioctls */ 1077 ret = pcie_ioctl(pci_p->pci_dip, dev, cmd, arg, mode, credp, 1078 rvalp); 1079 break; 1080 } 1081 1082 return (ret); 1083 } 1084 1085 /*ARGSUSED*/ 1086 static int 1087 npe_fm_init(dev_info_t *dip, dev_info_t *tdip, int cap, 1088 ddi_iblock_cookie_t *ibc) 1089 { 1090 pci_state_t *pcip = ddi_get_soft_state(npe_statep, 1091 ddi_get_instance(dip)); 1092 1093 ASSERT(ibc != NULL); 1094 *ibc = pcip->pci_fm_ibc; 1095 1096 return (pcip->pci_fmcap); 1097 } 1098 1099 /*ARGSUSED*/ 1100 static int 1101 npe_fm_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *no_used) 1102 { 1103 /* 1104 * On current x86 systems, npe's callback does not get called for failed 1105 * loads. If in the future this feature is used, the fault PA should be 1106 * logged in the derr->fme_bus_specific field. The appropriate PCIe 1107 * error handling code should be called and needs to be coordinated with 1108 * safe access handling. 1109 */ 1110 1111 return (DDI_FM_OK); 1112 } 1113