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