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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 /* 25 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved. 26 */ 27 28 /* 29 * Common x86 and SPARC PCI-E to PCI bus bridge nexus driver 30 */ 31 32 #include <sys/sysmacros.h> 33 #include <sys/conf.h> 34 #include <sys/kmem.h> 35 #include <sys/debug.h> 36 #include <sys/modctl.h> 37 #include <sys/autoconf.h> 38 #include <sys/ddi_impldefs.h> 39 #include <sys/pci.h> 40 #include <sys/ddi.h> 41 #include <sys/sunddi.h> 42 #include <sys/sunndi.h> 43 #include <sys/fm/util.h> 44 #include <sys/pci_cap.h> 45 #include <sys/pci_impl.h> 46 #include <sys/pcie_impl.h> 47 #include <sys/open.h> 48 #include <sys/stat.h> 49 #include <sys/file.h> 50 #include <sys/promif.h> /* prom_printf */ 51 #include <sys/disp.h> 52 #include <sys/pcie_pwr.h> 53 #include <sys/hotplug/pci/pcie_hp.h> 54 #include "pcieb.h" 55 #ifdef PX_PLX 56 #include <io/pciex/pcieb_plx.h> 57 #endif /* PX_PLX */ 58 59 /*LINTLIBRARY*/ 60 61 /* panic flag */ 62 int pcieb_die = PF_ERR_FATAL_FLAGS; 63 int pcieb_disable_41210_wkarnd = 0; 64 65 /* flag to turn on MSI support */ 66 int pcieb_enable_msi = 1; 67 68 #if defined(DEBUG) 69 uint_t pcieb_dbg_print = 0; 70 71 static char *pcieb_debug_sym [] = { /* same sequence as pcieb_debug_bit */ 72 /* 0 */ "attach", 73 /* 1 */ "pwr", 74 /* 2 */ "intr" 75 }; 76 #endif /* DEBUG */ 77 78 static int pcieb_bus_map(dev_info_t *, dev_info_t *, ddi_map_req_t *, off_t, 79 off_t, caddr_t *); 80 static int pcieb_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *, 81 void *); 82 static int pcieb_fm_init(pcieb_devstate_t *pcieb_p); 83 static void pcieb_fm_fini(pcieb_devstate_t *pcieb_p); 84 static int pcieb_fm_init_child(dev_info_t *dip, dev_info_t *cdip, int cap, 85 ddi_iblock_cookie_t *ibc_p); 86 static int pcieb_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, 87 ddi_dma_attr_t *attr_p, int (*waitfp)(caddr_t), caddr_t arg, 88 ddi_dma_handle_t *handlep); 89 static int pcieb_dma_mctl(dev_info_t *dip, dev_info_t *rdip, 90 ddi_dma_handle_t handle, enum ddi_dma_ctlops cmd, off_t *offp, 91 size_t *lenp, caddr_t *objp, uint_t cache_flags); 92 static int pcieb_intr_ops(dev_info_t *dip, dev_info_t *rdip, 93 ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, void *result); 94 95 static struct bus_ops pcieb_bus_ops = { 96 BUSO_REV, 97 pcieb_bus_map, 98 0, 99 0, 100 0, 101 i_ddi_map_fault, 102 0, 103 pcieb_dma_allochdl, 104 ddi_dma_freehdl, 105 ddi_dma_bindhdl, 106 ddi_dma_unbindhdl, 107 ddi_dma_flush, 108 ddi_dma_win, 109 pcieb_dma_mctl, 110 pcieb_ctlops, 111 ddi_bus_prop_op, 112 ndi_busop_get_eventcookie, /* (*bus_get_eventcookie)(); */ 113 ndi_busop_add_eventcall, /* (*bus_add_eventcall)(); */ 114 ndi_busop_remove_eventcall, /* (*bus_remove_eventcall)(); */ 115 ndi_post_event, /* (*bus_post_event)(); */ 116 NULL, /* (*bus_intr_ctl)(); */ 117 NULL, /* (*bus_config)(); */ 118 NULL, /* (*bus_unconfig)(); */ 119 pcieb_fm_init_child, /* (*bus_fm_init)(); */ 120 NULL, /* (*bus_fm_fini)(); */ 121 i_ndi_busop_access_enter, /* (*bus_fm_access_enter)(); */ 122 i_ndi_busop_access_exit, /* (*bus_fm_access_exit)(); */ 123 pcie_bus_power, /* (*bus_power)(); */ 124 pcieb_intr_ops, /* (*bus_intr_op)(); */ 125 pcie_hp_common_ops /* (*bus_hp_op)(); */ 126 }; 127 128 static int pcieb_open(dev_t *, int, int, cred_t *); 129 static int pcieb_close(dev_t, int, int, cred_t *); 130 static int pcieb_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 131 static int pcieb_info(dev_info_t *, ddi_info_cmd_t, void *, void **); 132 static uint_t pcieb_intr_handler(caddr_t arg1, caddr_t arg2); 133 134 /* PM related functions */ 135 static int pcieb_pwr_setup(dev_info_t *dip); 136 static int pcieb_pwr_init_and_raise(dev_info_t *dip, pcie_pwr_t *pwr_p); 137 static void pcieb_pwr_teardown(dev_info_t *dip); 138 static int pcieb_pwr_disable(dev_info_t *dip); 139 140 /* Hotplug related functions */ 141 static void pcieb_id_props(pcieb_devstate_t *pcieb); 142 143 /* 144 * soft state pointer 145 */ 146 void *pcieb_state; 147 148 static struct cb_ops pcieb_cb_ops = { 149 pcieb_open, /* open */ 150 pcieb_close, /* close */ 151 nodev, /* strategy */ 152 nodev, /* print */ 153 nodev, /* dump */ 154 nodev, /* read */ 155 nodev, /* write */ 156 pcieb_ioctl, /* ioctl */ 157 nodev, /* devmap */ 158 nodev, /* mmap */ 159 nodev, /* segmap */ 160 nochpoll, /* poll */ 161 pcie_prop_op, /* cb_prop_op */ 162 NULL, /* streamtab */ 163 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */ 164 CB_REV, /* rev */ 165 nodev, /* int (*cb_aread)() */ 166 nodev /* int (*cb_awrite)() */ 167 }; 168 169 static int pcieb_probe(dev_info_t *); 170 static int pcieb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd); 171 static int pcieb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 172 173 static struct dev_ops pcieb_ops = { 174 DEVO_REV, /* devo_rev */ 175 0, /* refcnt */ 176 pcieb_info, /* info */ 177 nulldev, /* identify */ 178 pcieb_probe, /* probe */ 179 pcieb_attach, /* attach */ 180 pcieb_detach, /* detach */ 181 nulldev, /* reset */ 182 &pcieb_cb_ops, /* driver operations */ 183 &pcieb_bus_ops, /* bus operations */ 184 pcie_power, /* power */ 185 ddi_quiesce_not_needed, /* quiesce */ 186 }; 187 188 /* 189 * Module linkage information for the kernel. 190 */ 191 192 static struct modldrv modldrv = { 193 &mod_driverops, /* Type of module */ 194 "PCIe bridge/switch driver", 195 &pcieb_ops, /* driver ops */ 196 }; 197 198 static struct modlinkage modlinkage = { 199 MODREV_1, 200 { (void *)&modldrv, NULL } 201 }; 202 203 /* 204 * forward function declarations: 205 */ 206 static void pcieb_uninitchild(dev_info_t *); 207 static int pcieb_initchild(dev_info_t *child); 208 static void pcieb_create_ranges_prop(dev_info_t *, ddi_acc_handle_t); 209 static boolean_t pcieb_is_pcie_device_type(dev_info_t *dip); 210 211 /* interrupt related declarations */ 212 static int pcieb_msi_supported(dev_info_t *); 213 static int pcieb_intr_attach(pcieb_devstate_t *pcieb); 214 static int pcieb_intr_init(pcieb_devstate_t *pcieb_p, int intr_type); 215 static void pcieb_intr_fini(pcieb_devstate_t *pcieb_p); 216 217 int 218 _init(void) 219 { 220 int e; 221 222 if ((e = ddi_soft_state_init(&pcieb_state, sizeof (pcieb_devstate_t), 223 1)) == 0 && (e = mod_install(&modlinkage)) != 0) 224 ddi_soft_state_fini(&pcieb_state); 225 return (e); 226 } 227 228 int 229 _fini(void) 230 { 231 int e; 232 233 if ((e = mod_remove(&modlinkage)) == 0) { 234 ddi_soft_state_fini(&pcieb_state); 235 } 236 return (e); 237 } 238 239 int 240 _info(struct modinfo *modinfop) 241 { 242 return (mod_info(&modlinkage, modinfop)); 243 } 244 245 /* ARGSUSED */ 246 static int 247 pcieb_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 248 { 249 minor_t minor = getminor((dev_t)arg); 250 int instance = PCI_MINOR_NUM_TO_INSTANCE(minor); 251 pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state, instance); 252 int ret = DDI_SUCCESS; 253 254 switch (infocmd) { 255 case DDI_INFO_DEVT2INSTANCE: 256 *result = (void *)(intptr_t)instance; 257 break; 258 case DDI_INFO_DEVT2DEVINFO: 259 if (pcieb == NULL) { 260 ret = DDI_FAILURE; 261 break; 262 } 263 264 *result = (void *)pcieb->pcieb_dip; 265 break; 266 default: 267 ret = DDI_FAILURE; 268 break; 269 } 270 271 return (ret); 272 } 273 274 275 /*ARGSUSED*/ 276 static int 277 pcieb_probe(dev_info_t *devi) 278 { 279 return (DDI_PROBE_SUCCESS); 280 } 281 282 /* 283 * This is a workaround for an undocumented HW erratum with the 284 * multi-function, F0 and F2, Intel 41210 PCIe-to-PCI bridge. When 285 * Fn (cdip) attaches, this workaround is called to initialize Fn's 286 * sibling (sdip) with MPS/MRRS if it isn't already configured. 287 * Doing so prevents a malformed TLP panic. 288 */ 289 static void 290 pcieb_41210_mps_wkrnd(dev_info_t *cdip) 291 { 292 dev_info_t *sdip; 293 ddi_acc_handle_t cfg_hdl; 294 uint16_t cdip_dev_ctrl, cdip_mrrs_mps; 295 pcie_bus_t *cdip_bus_p = PCIE_DIP2BUS(cdip); 296 297 /* Get cdip's MPS/MRRS already setup by pcie_initchild_mps() */ 298 ASSERT(cdip_bus_p); 299 cdip_dev_ctrl = PCIE_CAP_GET(16, cdip_bus_p, PCIE_DEVCTL); 300 cdip_mrrs_mps = cdip_dev_ctrl & 301 (PCIE_DEVCTL_MAX_READ_REQ_MASK | PCIE_DEVCTL_MAX_PAYLOAD_MASK); 302 303 /* Locate sdip and set its MPS/MRRS when applicable */ 304 for (sdip = ddi_get_child(ddi_get_parent(cdip)); sdip; 305 sdip = ddi_get_next_sibling(sdip)) { 306 uint16_t sdip_dev_ctrl, sdip_mrrs_mps, cap_ptr; 307 uint32_t bus_dev_ven_id; 308 309 if (sdip == cdip || pci_config_setup(sdip, &cfg_hdl) 310 != DDI_SUCCESS) 311 continue; 312 313 /* must be an Intel 41210 bridge */ 314 bus_dev_ven_id = pci_config_get32(cfg_hdl, PCI_CONF_VENID); 315 if (!PCIEB_IS_41210_BRIDGE(bus_dev_ven_id)) { 316 pci_config_teardown(&cfg_hdl); 317 continue; 318 } 319 320 if (PCI_CAP_LOCATE(cfg_hdl, PCI_CAP_ID_PCI_E, &cap_ptr) 321 != DDI_SUCCESS) { 322 pci_config_teardown(&cfg_hdl); 323 continue; 324 } 325 326 /* get sdip's MPS/MRRS to compare to cdip's */ 327 sdip_dev_ctrl = PCI_CAP_GET16(cfg_hdl, NULL, cap_ptr, 328 PCIE_DEVCTL); 329 sdip_mrrs_mps = sdip_dev_ctrl & 330 (PCIE_DEVCTL_MAX_READ_REQ_MASK | 331 PCIE_DEVCTL_MAX_PAYLOAD_MASK); 332 333 /* if sdip already attached then its MPS/MRRS is configured */ 334 if (i_ddi_devi_attached(sdip)) { 335 ASSERT(sdip_mrrs_mps == cdip_mrrs_mps); 336 pci_config_teardown(&cfg_hdl); 337 continue; 338 } 339 340 /* otherwise, update sdip's MPS/MRRS if different from cdip's */ 341 if (sdip_mrrs_mps != cdip_mrrs_mps) { 342 sdip_dev_ctrl = (sdip_dev_ctrl & 343 ~(PCIE_DEVCTL_MAX_READ_REQ_MASK | 344 PCIE_DEVCTL_MAX_PAYLOAD_MASK)) | cdip_mrrs_mps; 345 346 PCI_CAP_PUT16(cfg_hdl, NULL, cap_ptr, PCIE_DEVCTL, 347 sdip_dev_ctrl); 348 } 349 350 /* 351 * note: sdip's bus_mps will be updated by 352 * pcie_initchild_mps() 353 */ 354 355 pci_config_teardown(&cfg_hdl); 356 357 break; 358 } 359 } 360 361 static int 362 pcieb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 363 { 364 int instance; 365 char device_type[8]; 366 pcieb_devstate_t *pcieb; 367 pcie_bus_t *bus_p = PCIE_DIP2UPBUS(devi); 368 ddi_acc_handle_t config_handle = bus_p->bus_cfg_hdl; 369 370 switch (cmd) { 371 case DDI_RESUME: 372 (void) pcie_pwr_resume(devi); 373 return (DDI_SUCCESS); 374 375 default: 376 return (DDI_FAILURE); 377 378 case DDI_ATTACH: 379 break; 380 } 381 382 if (!(PCIE_IS_BDG(bus_p))) { 383 PCIEB_DEBUG(DBG_ATTACH, devi, "This is not a switch or" 384 " bridge\n"); 385 return (DDI_FAILURE); 386 } 387 388 /* 389 * If PCIE_LINKCTL_LINK_DISABLE bit in the PCIe Config 390 * Space (PCIe Capability Link Control Register) is set, 391 * then do not bind the driver. 392 */ 393 if (PCIE_CAP_GET(16, bus_p, PCIE_LINKCTL) & PCIE_LINKCTL_LINK_DISABLE) 394 return (DDI_FAILURE); 395 396 /* 397 * Allocate and get soft state structure. 398 */ 399 instance = ddi_get_instance(devi); 400 if (ddi_soft_state_zalloc(pcieb_state, instance) != DDI_SUCCESS) 401 return (DDI_FAILURE); 402 pcieb = ddi_get_soft_state(pcieb_state, instance); 403 pcieb->pcieb_dip = devi; 404 405 if ((pcieb_fm_init(pcieb)) != DDI_SUCCESS) { 406 PCIEB_DEBUG(DBG_ATTACH, devi, "Failed in pcieb_fm_init\n"); 407 goto fail; 408 } 409 pcieb->pcieb_init_flags |= PCIEB_INIT_FM; 410 411 mutex_init(&pcieb->pcieb_mutex, NULL, MUTEX_DRIVER, NULL); 412 mutex_init(&pcieb->pcieb_err_mutex, NULL, MUTEX_DRIVER, 413 (void *)pcieb->pcieb_fm_ibc); 414 mutex_init(&pcieb->pcieb_peek_poke_mutex, NULL, MUTEX_DRIVER, 415 (void *)pcieb->pcieb_fm_ibc); 416 417 /* create special properties for device identification */ 418 pcieb_id_props(pcieb); 419 420 /* 421 * Power management setup. This also makes sure that switch/bridge 422 * is at D0 during attach. 423 */ 424 if (pwr_common_setup(devi) != DDI_SUCCESS) { 425 PCIEB_DEBUG(DBG_PWR, devi, "pwr_common_setup failed\n"); 426 goto fail; 427 } 428 429 if (pcieb_pwr_setup(devi) != DDI_SUCCESS) { 430 PCIEB_DEBUG(DBG_PWR, devi, "pxb_pwr_setup failed \n"); 431 goto fail; 432 } 433 434 /* 435 * Make sure the "device_type" property exists. 436 */ 437 if (pcieb_is_pcie_device_type(devi)) 438 (void) strcpy(device_type, "pciex"); 439 else 440 (void) strcpy(device_type, "pci"); 441 442 (void) ddi_prop_update_string(DDI_DEV_T_NONE, devi, 443 "device_type", device_type); 444 445 /* 446 * Check whether the "ranges" property is present. 447 * Otherwise create the ranges property by reading 448 * the configuration registers 449 */ 450 if (ddi_prop_exists(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS, 451 "ranges") == 0) { 452 pcieb_create_ranges_prop(devi, config_handle); 453 } 454 455 if (PCIE_IS_PCI_BDG(bus_p)) 456 pcieb_set_pci_perf_parameters(devi, config_handle); 457 458 #ifdef PX_PLX 459 pcieb_attach_plx_workarounds(pcieb); 460 #endif /* PX_PLX */ 461 462 if (pcie_init(devi, NULL) != DDI_SUCCESS) 463 goto fail; 464 465 /* Intel PCIe-to-PCI 41210 bridge workaround -- if applicable */ 466 if (pcieb_disable_41210_wkarnd == 0 && 467 PCIEB_IS_41210_BRIDGE(bus_p->bus_dev_ven_id)) 468 pcieb_41210_mps_wkrnd(devi); 469 470 /* 471 * Initialize interrupt handlers. Ignore return value. 472 */ 473 (void) pcieb_intr_attach(pcieb); 474 475 (void) pcie_hpintr_enable(devi); 476 477 /* Do any platform specific workarounds needed at this time */ 478 pcieb_plat_attach_workaround(devi); 479 480 /* 481 * If this is a root port, determine and set the max payload size. 482 * Since this will involve scanning the fabric, all error enabling 483 * and sw workarounds should be in place before doing this. 484 */ 485 if (PCIE_IS_RP(bus_p)) 486 pcie_init_root_port_mps(devi); 487 488 ddi_report_dev(devi); 489 return (DDI_SUCCESS); 490 491 fail: 492 (void) pcieb_detach(devi, DDI_DETACH); 493 return (DDI_FAILURE); 494 } 495 496 static int 497 pcieb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 498 { 499 pcieb_devstate_t *pcieb; 500 int error = DDI_SUCCESS; 501 502 switch (cmd) { 503 case DDI_SUSPEND: 504 error = pcie_pwr_suspend(devi); 505 return (error); 506 507 case DDI_DETACH: 508 break; 509 510 default: 511 return (DDI_FAILURE); 512 } 513 514 pcieb = ddi_get_soft_state(pcieb_state, ddi_get_instance(devi)); 515 516 /* disable hotplug interrupt */ 517 (void) pcie_hpintr_disable(devi); 518 519 /* remove interrupt handlers */ 520 pcieb_intr_fini(pcieb); 521 522 /* uninitialize inband PCI-E HPC if present */ 523 (void) pcie_uninit(devi); 524 525 (void) ddi_prop_remove(DDI_DEV_T_NONE, devi, "device_type"); 526 527 (void) ndi_prop_remove(DDI_DEV_T_NONE, pcieb->pcieb_dip, 528 "pcie_ce_mask"); 529 530 if (pcieb->pcieb_init_flags & PCIEB_INIT_FM) 531 pcieb_fm_fini(pcieb); 532 533 pcieb_pwr_teardown(devi); 534 pwr_common_teardown(devi); 535 536 mutex_destroy(&pcieb->pcieb_peek_poke_mutex); 537 mutex_destroy(&pcieb->pcieb_err_mutex); 538 mutex_destroy(&pcieb->pcieb_mutex); 539 540 /* 541 * And finally free the per-pci soft state. 542 */ 543 ddi_soft_state_free(pcieb_state, ddi_get_instance(devi)); 544 545 return (DDI_SUCCESS); 546 } 547 548 static int 549 pcieb_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 550 off_t offset, off_t len, caddr_t *vaddrp) 551 { 552 dev_info_t *pdip; 553 554 if (PCIE_IS_RP(PCIE_DIP2BUS(dip)) && mp->map_handlep != NULL) { 555 ddi_acc_impl_t *hdlp = 556 (ddi_acc_impl_t *)(mp->map_handlep)->ah_platform_private; 557 558 pcieb_set_prot_scan(dip, hdlp); 559 } 560 pdip = (dev_info_t *)DEVI(dip)->devi_parent; 561 return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map)(pdip, rdip, mp, 562 offset, len, vaddrp)); 563 } 564 565 static int 566 pcieb_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop, 567 void *arg, void *result) 568 { 569 pci_regspec_t *drv_regp; 570 int reglen; 571 int rn; 572 int totreg; 573 pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state, 574 ddi_get_instance(dip)); 575 struct detachspec *ds; 576 struct attachspec *as; 577 578 switch (ctlop) { 579 case DDI_CTLOPS_REPORTDEV: 580 if (rdip == (dev_info_t *)0) 581 return (DDI_FAILURE); 582 583 if (ddi_get_parent(rdip) == dip) { 584 cmn_err(CE_CONT, "?PCIE-device: %s@%s, %s%d\n", 585 ddi_node_name(rdip), ddi_get_name_addr(rdip), 586 ddi_driver_name(rdip), ddi_get_instance(rdip)); 587 } 588 589 /* Pass it up for fabric sync */ 590 (void) ddi_ctlops(dip, rdip, ctlop, arg, result); 591 return (DDI_SUCCESS); 592 593 case DDI_CTLOPS_INITCHILD: 594 return (pcieb_initchild((dev_info_t *)arg)); 595 596 case DDI_CTLOPS_UNINITCHILD: 597 pcieb_uninitchild((dev_info_t *)arg); 598 return (DDI_SUCCESS); 599 600 case DDI_CTLOPS_SIDDEV: 601 return (DDI_SUCCESS); 602 603 case DDI_CTLOPS_REGSIZE: 604 case DDI_CTLOPS_NREGS: 605 if (rdip == (dev_info_t *)0) 606 return (DDI_FAILURE); 607 break; 608 609 case DDI_CTLOPS_PEEK: 610 case DDI_CTLOPS_POKE: 611 return (pcieb_plat_peekpoke(dip, rdip, ctlop, arg, result)); 612 case DDI_CTLOPS_ATTACH: 613 if (!pcie_is_child(dip, rdip)) 614 return (DDI_SUCCESS); 615 616 as = (struct attachspec *)arg; 617 switch (as->when) { 618 case DDI_PRE: 619 if (as->cmd == DDI_RESUME) { 620 pcie_clear_errors(rdip); 621 if (pcieb_plat_ctlops(rdip, ctlop, arg) != 622 DDI_SUCCESS) 623 return (DDI_FAILURE); 624 } 625 626 if (as->cmd == DDI_ATTACH) 627 return (pcie_pm_hold(dip)); 628 629 return (DDI_SUCCESS); 630 631 case DDI_POST: 632 if (as->cmd == DDI_ATTACH && 633 as->result != DDI_SUCCESS) { 634 /* 635 * Attach failed for the child device. The child 636 * driver may have made PM calls before the 637 * attach failed. pcie_pm_remove_child() should 638 * cleanup PM state and holds (if any) 639 * associated with the child device. 640 */ 641 return (pcie_pm_remove_child(dip, rdip)); 642 } 643 644 if (as->result == DDI_SUCCESS) { 645 pf_init(rdip, (void *)pcieb->pcieb_fm_ibc, 646 as->cmd); 647 648 (void) pcieb_plat_ctlops(rdip, ctlop, arg); 649 } 650 651 /* 652 * For empty hotplug-capable slots, we should explicitly 653 * disable the errors, so that we won't panic upon 654 * unsupported hotplug messages. 655 */ 656 if ((!ddi_prop_exists(DDI_DEV_T_ANY, rdip, 657 DDI_PROP_DONTPASS, "hotplug-capable")) || 658 ddi_get_child(rdip)) { 659 (void) pcie_postattach_child(rdip); 660 return (DDI_SUCCESS); 661 } 662 663 pcie_disable_errors(rdip); 664 665 return (DDI_SUCCESS); 666 default: 667 break; 668 } 669 return (DDI_SUCCESS); 670 671 case DDI_CTLOPS_DETACH: 672 if (!pcie_is_child(dip, rdip)) 673 return (DDI_SUCCESS); 674 675 ds = (struct detachspec *)arg; 676 switch (ds->when) { 677 case DDI_PRE: 678 pf_fini(rdip, ds->cmd); 679 return (DDI_SUCCESS); 680 681 case DDI_POST: 682 if (pcieb_plat_ctlops(rdip, ctlop, arg) != DDI_SUCCESS) 683 return (DDI_FAILURE); 684 if (ds->cmd == DDI_DETACH && 685 ds->result == DDI_SUCCESS) { 686 return (pcie_pm_remove_child(dip, rdip)); 687 } 688 return (DDI_SUCCESS); 689 default: 690 break; 691 } 692 return (DDI_SUCCESS); 693 default: 694 return (ddi_ctlops(dip, rdip, ctlop, arg, result)); 695 } 696 697 *(int *)result = 0; 698 if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, 699 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "reg", (caddr_t)&drv_regp, 700 ®len) != DDI_SUCCESS) 701 return (DDI_FAILURE); 702 703 totreg = reglen / sizeof (pci_regspec_t); 704 if (ctlop == DDI_CTLOPS_NREGS) 705 *(int *)result = totreg; 706 else if (ctlop == DDI_CTLOPS_REGSIZE) { 707 rn = *(int *)arg; 708 if (rn >= totreg) { 709 kmem_free(drv_regp, reglen); 710 return (DDI_FAILURE); 711 } 712 713 *(off_t *)result = drv_regp[rn].pci_size_low | 714 ((uint64_t)drv_regp[rn].pci_size_hi << 32); 715 } 716 717 kmem_free(drv_regp, reglen); 718 return (DDI_SUCCESS); 719 } 720 721 /* 722 * name_child 723 * 724 * This function is called from init_child to name a node. It is 725 * also passed as a callback for node merging functions. 726 * 727 * return value: DDI_SUCCESS, DDI_FAILURE 728 */ 729 static int 730 pcieb_name_child(dev_info_t *child, char *name, int namelen) 731 { 732 pci_regspec_t *pci_rp; 733 uint_t device, func; 734 char **unit_addr; 735 uint_t n; 736 737 /* 738 * For .conf nodes, use unit-address property as name 739 */ 740 if (ndi_dev_is_persistent_node(child) == 0) { 741 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, child, 742 DDI_PROP_DONTPASS, "unit-address", &unit_addr, &n) != 743 DDI_PROP_SUCCESS) { 744 cmn_err(CE_WARN, 745 "cannot find unit-address in %s.conf", 746 ddi_driver_name(child)); 747 return (DDI_FAILURE); 748 } 749 if (n != 1 || *unit_addr == NULL || **unit_addr == 0) { 750 cmn_err(CE_WARN, "unit-address property in %s.conf" 751 " not well-formed", ddi_driver_name(child)); 752 ddi_prop_free(unit_addr); 753 return (DDI_FAILURE); 754 } 755 (void) snprintf(name, namelen, "%s", *unit_addr); 756 ddi_prop_free(unit_addr); 757 return (DDI_SUCCESS); 758 } 759 760 /* 761 * Get the address portion of the node name based on 762 * the function and device number. 763 */ 764 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, 765 DDI_PROP_DONTPASS, "reg", (int **)&pci_rp, &n) != DDI_SUCCESS) { 766 return (DDI_FAILURE); 767 } 768 769 /* copy the device identifications */ 770 device = PCI_REG_DEV_G(pci_rp[0].pci_phys_hi); 771 func = PCI_REG_FUNC_G(pci_rp[0].pci_phys_hi); 772 773 if (pcie_ari_is_enabled(ddi_get_parent(child)) 774 == PCIE_ARI_FORW_ENABLED) { 775 func = (device << 3) | func; 776 device = 0; 777 } 778 779 if (func != 0) 780 (void) snprintf(name, namelen, "%x,%x", device, func); 781 else 782 (void) snprintf(name, namelen, "%x", device); 783 784 ddi_prop_free(pci_rp); 785 return (DDI_SUCCESS); 786 } 787 788 static int 789 pcieb_initchild(dev_info_t *child) 790 { 791 char name[MAXNAMELEN]; 792 int result = DDI_FAILURE; 793 pcieb_devstate_t *pcieb = 794 (pcieb_devstate_t *)ddi_get_soft_state(pcieb_state, 795 ddi_get_instance(ddi_get_parent(child))); 796 797 /* 798 * Name the child 799 */ 800 if (pcieb_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS) { 801 result = DDI_FAILURE; 802 goto done; 803 } 804 ddi_set_name_addr(child, name); 805 806 /* 807 * Pseudo nodes indicate a prototype node with per-instance 808 * properties to be merged into the real h/w device node. 809 * The interpretation of the unit-address is DD[,F] 810 * where DD is the device id and F is the function. 811 */ 812 if (ndi_dev_is_persistent_node(child) == 0) { 813 extern int pci_allow_pseudo_children; 814 815 /* 816 * Try to merge the properties from this prototype 817 * node into real h/w nodes. 818 */ 819 if (ndi_merge_node(child, pcieb_name_child) == DDI_SUCCESS) { 820 /* 821 * Merged ok - return failure to remove the node. 822 */ 823 ddi_set_name_addr(child, NULL); 824 result = DDI_FAILURE; 825 goto done; 826 } 827 828 /* workaround for ddivs to run under PCI-E */ 829 if (pci_allow_pseudo_children) { 830 result = DDI_SUCCESS; 831 goto done; 832 } 833 834 /* 835 * The child was not merged into a h/w node, 836 * but there's not much we can do with it other 837 * than return failure to cause the node to be removed. 838 */ 839 cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged", 840 ddi_driver_name(child), ddi_get_name_addr(child), 841 ddi_driver_name(child)); 842 ddi_set_name_addr(child, NULL); 843 result = DDI_NOT_WELL_FORMED; 844 goto done; 845 } 846 847 /* platform specific initchild */ 848 pcieb_plat_initchild(child); 849 850 if (pcie_pm_hold(pcieb->pcieb_dip) != DDI_SUCCESS) { 851 PCIEB_DEBUG(DBG_PWR, pcieb->pcieb_dip, 852 "INITCHILD: px_pm_hold failed\n"); 853 result = DDI_FAILURE; 854 goto done; 855 } 856 /* Any return from here must call pcie_pm_release */ 857 858 /* 859 * If configuration registers were previously saved by 860 * child (before it entered D3), then let the child do the 861 * restore to set up the config regs as it'll first need to 862 * power the device out of D3. 863 */ 864 if (ddi_prop_exists(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, 865 "config-regs-saved-by-child") == 1) { 866 PCIEB_DEBUG(DBG_PWR, ddi_get_parent(child), 867 "INITCHILD: config regs to be restored by child" 868 " for %s@%s\n", ddi_node_name(child), 869 ddi_get_name_addr(child)); 870 871 result = DDI_SUCCESS; 872 goto cleanup; 873 } 874 875 PCIEB_DEBUG(DBG_PWR, ddi_get_parent(child), 876 "INITCHILD: config regs setup for %s@%s\n", 877 ddi_node_name(child), ddi_get_name_addr(child)); 878 879 pcie_init_dom(child); 880 881 if (pcie_initchild(child) != DDI_SUCCESS) { 882 result = DDI_FAILURE; 883 pcie_fini_dom(child); 884 goto cleanup; 885 } 886 887 #ifdef PX_PLX 888 if (pcieb_init_plx_workarounds(pcieb, child) == DDI_FAILURE) { 889 result = DDI_FAILURE; 890 pcie_fini_dom(child); 891 goto cleanup; 892 } 893 #endif /* PX_PLX */ 894 895 result = DDI_SUCCESS; 896 cleanup: 897 pcie_pm_release(pcieb->pcieb_dip); 898 done: 899 return (result); 900 } 901 902 static void 903 pcieb_uninitchild(dev_info_t *dip) 904 { 905 906 pcie_uninitchild(dip); 907 908 pcieb_plat_uninitchild(dip); 909 910 ddi_set_name_addr(dip, NULL); 911 912 /* 913 * Strip the node to properly convert it back to prototype form 914 */ 915 ddi_remove_minor_node(dip, NULL); 916 917 ddi_prop_remove_all(dip); 918 } 919 920 static boolean_t 921 pcieb_is_pcie_device_type(dev_info_t *dip) 922 { 923 pcie_bus_t *bus_p = PCIE_DIP2BUS(dip); 924 925 if (PCIE_IS_SW(bus_p) || PCIE_IS_RP(bus_p) || PCIE_IS_PCI2PCIE(bus_p)) 926 return (B_TRUE); 927 928 return (B_FALSE); 929 } 930 931 static int 932 pcieb_intr_attach(pcieb_devstate_t *pcieb) 933 { 934 int intr_types; 935 dev_info_t *dip = pcieb->pcieb_dip; 936 937 /* Allow platform specific code to do any initialization first */ 938 pcieb_plat_intr_attach(pcieb); 939 940 /* 941 * Initialize interrupt handlers. 942 * If both MSI and FIXED are supported, try to attach MSI first. 943 * If MSI fails for any reason, then try FIXED, but only allow one 944 * type to be attached. 945 */ 946 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) { 947 PCIEB_DEBUG(DBG_ATTACH, dip, "ddi_intr_get_supported_types" 948 " failed\n"); 949 goto FAIL; 950 } 951 952 if ((intr_types & DDI_INTR_TYPE_MSI) && 953 (pcieb_msi_supported(dip) == DDI_SUCCESS)) { 954 if (pcieb_intr_init(pcieb, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) 955 intr_types = DDI_INTR_TYPE_MSI; 956 else { 957 PCIEB_DEBUG(DBG_ATTACH, dip, "Unable to attach MSI" 958 " handler\n"); 959 } 960 } 961 962 if (intr_types != DDI_INTR_TYPE_MSI) { 963 /* 964 * MSIs are not supported or MSI initialization failed. For Root 965 * Ports mark this so error handling might try to fallback to 966 * some other mechanism if available (machinecheck etc.). 967 */ 968 if (PCIE_IS_RP(PCIE_DIP2UPBUS(dip))) 969 pcieb->pcieb_no_aer_msi = B_TRUE; 970 } 971 972 if (intr_types & DDI_INTR_TYPE_FIXED) { 973 if (pcieb_intr_init(pcieb, DDI_INTR_TYPE_FIXED) != 974 DDI_SUCCESS) { 975 PCIEB_DEBUG(DBG_ATTACH, dip, 976 "Unable to attach INTx handler\n"); 977 goto FAIL; 978 } 979 } 980 return (DDI_SUCCESS); 981 982 FAIL: 983 return (DDI_FAILURE); 984 } 985 986 /* 987 * This function initializes internally generated interrupts only. 988 * It does not affect any interrupts generated by downstream devices 989 * or the forwarding of them. 990 * 991 * Enable Device Specific Interrupts or Hotplug features here. 992 * Enabling features may change how many interrupts are requested 993 * by the device. If features are not enabled first, the 994 * device might not ask for any interrupts. 995 */ 996 997 static int 998 pcieb_intr_init(pcieb_devstate_t *pcieb, int intr_type) 999 { 1000 dev_info_t *dip = pcieb->pcieb_dip; 1001 int nintrs, request, count, x; 1002 int intr_cap = 0; 1003 int inum = 0; 1004 int ret, hp_msi_off; 1005 pcie_bus_t *bus_p = PCIE_DIP2UPBUS(dip); 1006 uint16_t vendorid = bus_p->bus_dev_ven_id & 0xFFFF; 1007 boolean_t is_hp = B_FALSE; 1008 boolean_t is_pme = B_FALSE; 1009 1010 PCIEB_DEBUG(DBG_ATTACH, dip, "pcieb_intr_init: Attaching %s handler\n", 1011 (intr_type == DDI_INTR_TYPE_MSI) ? "MSI" : "INTx"); 1012 1013 request = 0; 1014 if (PCIE_IS_HOTPLUG_ENABLED(dip)) { 1015 request++; 1016 is_hp = B_TRUE; 1017 } 1018 1019 /* 1020 * Hotplug and PME share the same MSI vector. If hotplug is not 1021 * supported check if MSI is needed for PME. 1022 */ 1023 if ((intr_type == DDI_INTR_TYPE_MSI) && PCIE_IS_RP(bus_p) && 1024 (vendorid == NVIDIA_VENDOR_ID)) { 1025 is_pme = B_TRUE; 1026 if (!is_hp) 1027 request++; 1028 } 1029 1030 /* 1031 * Setup MSI if this device is a Rootport and has AER. Currently no 1032 * SPARC Root Port supports fabric errors being reported through it. 1033 */ 1034 if (intr_type == DDI_INTR_TYPE_MSI) { 1035 if (PCIE_IS_RP(bus_p) && PCIE_HAS_AER(bus_p)) 1036 request++; 1037 } 1038 1039 if (request == 0) 1040 return (DDI_SUCCESS); 1041 1042 /* 1043 * Get number of supported interrupts. 1044 * 1045 * Several Bridges/Switches will not have this property set, resulting 1046 * in a FAILURE, if the device is not configured in a way that 1047 * interrupts are needed. (eg. hotplugging) 1048 */ 1049 ret = ddi_intr_get_nintrs(dip, intr_type, &nintrs); 1050 if ((ret != DDI_SUCCESS) || (nintrs == 0)) { 1051 PCIEB_DEBUG(DBG_ATTACH, dip, "ddi_intr_get_nintrs ret:%d" 1052 " req:%d\n", ret, nintrs); 1053 return (DDI_FAILURE); 1054 } 1055 1056 PCIEB_DEBUG(DBG_ATTACH, dip, "bdf 0x%x: ddi_intr_get_nintrs: nintrs %d", 1057 " request %d\n", bus_p->bus_bdf, nintrs, request); 1058 1059 if (request > nintrs) 1060 request = nintrs; 1061 1062 /* Allocate an array of interrupt handlers */ 1063 pcieb->pcieb_htable_size = sizeof (ddi_intr_handle_t) * request; 1064 pcieb->pcieb_htable = kmem_zalloc(pcieb->pcieb_htable_size, 1065 KM_SLEEP); 1066 pcieb->pcieb_init_flags |= PCIEB_INIT_HTABLE; 1067 1068 ret = ddi_intr_alloc(dip, pcieb->pcieb_htable, intr_type, inum, 1069 request, &count, DDI_INTR_ALLOC_NORMAL); 1070 if ((ret != DDI_SUCCESS) || (count == 0)) { 1071 PCIEB_DEBUG(DBG_ATTACH, dip, "ddi_intr_alloc() ret: %d ask: %d" 1072 " actual: %d\n", ret, request, count); 1073 goto FAIL; 1074 } 1075 pcieb->pcieb_init_flags |= PCIEB_INIT_ALLOC; 1076 1077 /* Save the actual number of interrupts allocated */ 1078 pcieb->pcieb_intr_count = count; 1079 if (count < request) { 1080 PCIEB_DEBUG(DBG_ATTACH, dip, "bdf 0%x: Requested Intr: %d" 1081 " Received: %d\n", bus_p->bus_bdf, request, count); 1082 } 1083 1084 /* 1085 * NVidia (MCP55 and other) chipsets have a errata that if the number 1086 * of requested MSI intrs is not allocated we have to fall back to INTx. 1087 */ 1088 if (intr_type == DDI_INTR_TYPE_MSI) { 1089 if (PCIE_IS_RP(bus_p) && (vendorid == NVIDIA_VENDOR_ID)) { 1090 if (request != count) 1091 goto FAIL; 1092 } 1093 } 1094 1095 /* Get interrupt priority */ 1096 ret = ddi_intr_get_pri(pcieb->pcieb_htable[0], 1097 &pcieb->pcieb_intr_priority); 1098 if (ret != DDI_SUCCESS) { 1099 PCIEB_DEBUG(DBG_ATTACH, dip, "ddi_intr_get_pri() ret: %d\n", 1100 ret); 1101 goto FAIL; 1102 } 1103 1104 if (pcieb->pcieb_intr_priority >= LOCK_LEVEL) { 1105 pcieb->pcieb_intr_priority = LOCK_LEVEL - 1; 1106 ret = ddi_intr_set_pri(pcieb->pcieb_htable[0], 1107 pcieb->pcieb_intr_priority); 1108 if (ret != DDI_SUCCESS) { 1109 PCIEB_DEBUG(DBG_ATTACH, dip, "ddi_intr_set_pri() ret:" 1110 " %d\n", ret); 1111 1112 goto FAIL; 1113 } 1114 } 1115 1116 mutex_init(&pcieb->pcieb_intr_mutex, NULL, MUTEX_DRIVER, NULL); 1117 1118 pcieb->pcieb_init_flags |= PCIEB_INIT_MUTEX; 1119 1120 for (count = 0; count < pcieb->pcieb_intr_count; count++) { 1121 ret = ddi_intr_add_handler(pcieb->pcieb_htable[count], 1122 pcieb_intr_handler, (caddr_t)pcieb, 1123 (caddr_t)(uintptr_t)(inum + count)); 1124 1125 if (ret != DDI_SUCCESS) { 1126 PCIEB_DEBUG(DBG_ATTACH, dip, "Cannot add " 1127 "interrupt(%d)\n", ret); 1128 break; 1129 } 1130 } 1131 1132 /* If unsucessful, remove the added handlers */ 1133 if (ret != DDI_SUCCESS) { 1134 for (x = 0; x < count; x++) { 1135 (void) ddi_intr_remove_handler(pcieb->pcieb_htable[x]); 1136 } 1137 goto FAIL; 1138 } 1139 1140 pcieb->pcieb_init_flags |= PCIEB_INIT_HANDLER; 1141 1142 (void) ddi_intr_get_cap(pcieb->pcieb_htable[0], &intr_cap); 1143 1144 /* 1145 * Get this intr lock because we are not quite ready to handle 1146 * interrupts immediately after enabling it. The MSI multi register 1147 * gets programmed in ddi_intr_enable after which we need to get the 1148 * MSI offsets for Hotplug/AER. 1149 */ 1150 mutex_enter(&pcieb->pcieb_intr_mutex); 1151 1152 if (intr_cap & DDI_INTR_FLAG_BLOCK) { 1153 (void) ddi_intr_block_enable(pcieb->pcieb_htable, 1154 pcieb->pcieb_intr_count); 1155 pcieb->pcieb_init_flags |= PCIEB_INIT_BLOCK; 1156 } else { 1157 for (count = 0; count < pcieb->pcieb_intr_count; count++) { 1158 (void) ddi_intr_enable(pcieb->pcieb_htable[count]); 1159 } 1160 } 1161 pcieb->pcieb_init_flags |= PCIEB_INIT_ENABLE; 1162 1163 /* Save the interrupt type */ 1164 pcieb->pcieb_intr_type = intr_type; 1165 1166 /* Get the MSI offset for hotplug/PME from the PCIe cap reg */ 1167 if (intr_type == DDI_INTR_TYPE_MSI) { 1168 hp_msi_off = PCI_CAP_GET16(bus_p->bus_cfg_hdl, NULL, 1169 bus_p->bus_pcie_off, PCIE_PCIECAP) & 1170 PCIE_PCIECAP_INT_MSG_NUM; 1171 1172 if (hp_msi_off >= count) { 1173 PCIEB_DEBUG(DBG_ATTACH, dip, "MSI number %d in PCIe " 1174 "cap > max allocated %d\n", hp_msi_off, count); 1175 mutex_exit(&pcieb->pcieb_intr_mutex); 1176 goto FAIL; 1177 } 1178 1179 if (is_hp) 1180 pcieb->pcieb_isr_tab[hp_msi_off] |= PCIEB_INTR_SRC_HP; 1181 1182 if (is_pme) 1183 pcieb->pcieb_isr_tab[hp_msi_off] |= PCIEB_INTR_SRC_PME; 1184 } else { 1185 /* INTx handles only Hotplug interrupts */ 1186 if (is_hp) 1187 pcieb->pcieb_isr_tab[0] |= PCIEB_INTR_SRC_HP; 1188 } 1189 1190 1191 /* 1192 * Get the MSI offset for errors from the AER Root Error status 1193 * register. 1194 */ 1195 if ((intr_type == DDI_INTR_TYPE_MSI) && PCIE_IS_RP(bus_p)) { 1196 if (PCIE_HAS_AER(bus_p)) { 1197 int aer_msi_off; 1198 aer_msi_off = (PCI_XCAP_GET32(bus_p->bus_cfg_hdl, NULL, 1199 bus_p->bus_aer_off, PCIE_AER_RE_STS) >> 1200 PCIE_AER_RE_STS_MSG_NUM_SHIFT) & 1201 PCIE_AER_RE_STS_MSG_NUM_MASK; 1202 1203 if (aer_msi_off >= count) { 1204 PCIEB_DEBUG(DBG_ATTACH, dip, "MSI number %d in" 1205 " AER cap > max allocated %d\n", 1206 aer_msi_off, count); 1207 mutex_exit(&pcieb->pcieb_intr_mutex); 1208 goto FAIL; 1209 } 1210 pcieb->pcieb_isr_tab[aer_msi_off] |= PCIEB_INTR_SRC_AER; 1211 } else { 1212 /* 1213 * This RP does not have AER. Fallback to the 1214 * SERR+Machinecheck approach if available. 1215 */ 1216 pcieb->pcieb_no_aer_msi = B_TRUE; 1217 } 1218 } 1219 1220 mutex_exit(&pcieb->pcieb_intr_mutex); 1221 return (DDI_SUCCESS); 1222 1223 FAIL: 1224 pcieb_intr_fini(pcieb); 1225 return (DDI_FAILURE); 1226 } 1227 1228 static void 1229 pcieb_intr_fini(pcieb_devstate_t *pcieb) 1230 { 1231 int x; 1232 int count = pcieb->pcieb_intr_count; 1233 int flags = pcieb->pcieb_init_flags; 1234 1235 if ((flags & PCIEB_INIT_ENABLE) && 1236 (flags & PCIEB_INIT_BLOCK)) { 1237 (void) ddi_intr_block_disable(pcieb->pcieb_htable, count); 1238 flags &= ~(PCIEB_INIT_ENABLE | 1239 PCIEB_INIT_BLOCK); 1240 } 1241 1242 if (flags & PCIEB_INIT_MUTEX) 1243 mutex_destroy(&pcieb->pcieb_intr_mutex); 1244 1245 for (x = 0; x < count; x++) { 1246 if (flags & PCIEB_INIT_ENABLE) 1247 (void) ddi_intr_disable(pcieb->pcieb_htable[x]); 1248 1249 if (flags & PCIEB_INIT_HANDLER) 1250 (void) ddi_intr_remove_handler(pcieb->pcieb_htable[x]); 1251 1252 if (flags & PCIEB_INIT_ALLOC) 1253 (void) ddi_intr_free(pcieb->pcieb_htable[x]); 1254 } 1255 1256 flags &= ~(PCIEB_INIT_ENABLE | PCIEB_INIT_HANDLER | PCIEB_INIT_ALLOC | 1257 PCIEB_INIT_MUTEX); 1258 1259 if (flags & PCIEB_INIT_HTABLE) 1260 kmem_free(pcieb->pcieb_htable, pcieb->pcieb_htable_size); 1261 1262 flags &= ~PCIEB_INIT_HTABLE; 1263 1264 pcieb->pcieb_init_flags &= flags; 1265 } 1266 1267 /* 1268 * Checks if this device needs MSIs enabled or not. 1269 */ 1270 /*ARGSUSED*/ 1271 static int 1272 pcieb_msi_supported(dev_info_t *dip) 1273 { 1274 return ((pcieb_enable_msi && pcieb_plat_msi_supported(dip)) ? 1275 DDI_SUCCESS: DDI_FAILURE); 1276 } 1277 1278 /*ARGSUSED*/ 1279 static int 1280 pcieb_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap, 1281 ddi_iblock_cookie_t *ibc) 1282 { 1283 pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state, 1284 ddi_get_instance(dip)); 1285 1286 ASSERT(ibc != NULL); 1287 *ibc = pcieb->pcieb_fm_ibc; 1288 1289 return (DEVI(dip)->devi_fmhdl->fh_cap | DDI_FM_ACCCHK_CAPABLE | 1290 DDI_FM_DMACHK_CAPABLE); 1291 } 1292 1293 static int 1294 pcieb_fm_init(pcieb_devstate_t *pcieb_p) 1295 { 1296 dev_info_t *dip = pcieb_p->pcieb_dip; 1297 int fm_cap = DDI_FM_EREPORT_CAPABLE; 1298 1299 /* 1300 * Request our capability level and get our parents capability 1301 * and ibc. 1302 */ 1303 ddi_fm_init(dip, &fm_cap, &pcieb_p->pcieb_fm_ibc); 1304 1305 return (DDI_SUCCESS); 1306 } 1307 1308 /* 1309 * Breakdown our FMA resources 1310 */ 1311 static void 1312 pcieb_fm_fini(pcieb_devstate_t *pcieb_p) 1313 { 1314 /* 1315 * Clean up allocated fm structures 1316 */ 1317 ddi_fm_fini(pcieb_p->pcieb_dip); 1318 } 1319 1320 static int 1321 pcieb_open(dev_t *devp, int flags, int otyp, cred_t *credp) 1322 { 1323 int inst = PCI_MINOR_NUM_TO_INSTANCE(getminor(*devp)); 1324 pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state, inst); 1325 int rv; 1326 1327 if (pcieb == NULL) 1328 return (ENXIO); 1329 1330 mutex_enter(&pcieb->pcieb_mutex); 1331 rv = pcie_open(pcieb->pcieb_dip, devp, flags, otyp, credp); 1332 mutex_exit(&pcieb->pcieb_mutex); 1333 1334 return (rv); 1335 } 1336 1337 static int 1338 pcieb_close(dev_t dev, int flags, int otyp, cred_t *credp) 1339 { 1340 int inst = PCI_MINOR_NUM_TO_INSTANCE(getminor(dev)); 1341 pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state, inst); 1342 int rv; 1343 1344 if (pcieb == NULL) 1345 return (ENXIO); 1346 1347 mutex_enter(&pcieb->pcieb_mutex); 1348 rv = pcie_close(pcieb->pcieb_dip, dev, flags, otyp, credp); 1349 mutex_exit(&pcieb->pcieb_mutex); 1350 1351 return (rv); 1352 } 1353 1354 static int 1355 pcieb_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, 1356 int *rvalp) 1357 { 1358 int inst = PCI_MINOR_NUM_TO_INSTANCE(getminor(dev)); 1359 pcieb_devstate_t *pcieb = ddi_get_soft_state(pcieb_state, inst); 1360 int rv; 1361 1362 if (pcieb == NULL) 1363 return (ENXIO); 1364 1365 /* To handle devctl and hotplug related ioctls */ 1366 rv = pcie_ioctl(pcieb->pcieb_dip, dev, cmd, arg, mode, credp, rvalp); 1367 1368 return (rv); 1369 } 1370 1371 /* 1372 * Common interrupt handler for hotplug, PME and errors. 1373 */ 1374 static uint_t 1375 pcieb_intr_handler(caddr_t arg1, caddr_t arg2) 1376 { 1377 pcieb_devstate_t *pcieb_p = (pcieb_devstate_t *)arg1; 1378 dev_info_t *dip = pcieb_p->pcieb_dip; 1379 ddi_fm_error_t derr; 1380 int sts = 0; 1381 int ret = DDI_INTR_UNCLAIMED; 1382 int isrc; 1383 1384 if (!(pcieb_p->pcieb_init_flags & PCIEB_INIT_ENABLE)) 1385 goto FAIL; 1386 1387 mutex_enter(&pcieb_p->pcieb_intr_mutex); 1388 isrc = pcieb_p->pcieb_isr_tab[(int)(uintptr_t)arg2]; 1389 mutex_exit(&pcieb_p->pcieb_intr_mutex); 1390 1391 PCIEB_DEBUG(DBG_INTR, dip, "Received intr number %d\n", 1392 (int)(uintptr_t)arg2); 1393 1394 if (isrc == PCIEB_INTR_SRC_UNKNOWN) 1395 goto FAIL; 1396 1397 if (isrc & PCIEB_INTR_SRC_HP) 1398 ret = pcie_intr(dip); 1399 1400 if (isrc & PCIEB_INTR_SRC_PME) 1401 ret = DDI_INTR_CLAIMED; 1402 1403 /* AER Error */ 1404 if (isrc & PCIEB_INTR_SRC_AER) { 1405 /* 1406 * If MSI is shared with PME/hotplug then check Root Error 1407 * Status Reg before claiming it. For now it's ok since 1408 * we know we get 2 MSIs. 1409 */ 1410 ret = DDI_INTR_CLAIMED; 1411 bzero(&derr, sizeof (ddi_fm_error_t)); 1412 derr.fme_version = DDI_FME_VERSION; 1413 mutex_enter(&pcieb_p->pcieb_peek_poke_mutex); 1414 mutex_enter(&pcieb_p->pcieb_err_mutex); 1415 1416 pf_eh_enter(PCIE_DIP2BUS(dip)); 1417 PCIE_ROOT_EH_SRC(PCIE_DIP2PFD(dip))->intr_type = 1418 PF_INTR_TYPE_AER; 1419 1420 if ((DEVI(dip)->devi_fmhdl->fh_cap) & DDI_FM_EREPORT_CAPABLE) 1421 sts = pf_scan_fabric(dip, &derr, NULL); 1422 pf_eh_exit(PCIE_DIP2BUS(dip)); 1423 1424 mutex_exit(&pcieb_p->pcieb_err_mutex); 1425 mutex_exit(&pcieb_p->pcieb_peek_poke_mutex); 1426 if (pcieb_die & sts) 1427 fm_panic("%s-%d: PCI(-X) Express Fatal Error. (0x%x)", 1428 ddi_driver_name(dip), ddi_get_instance(dip), sts); 1429 } 1430 FAIL: 1431 return (ret); 1432 } 1433 1434 /* 1435 * Some PCI-X to PCI-E bridges do not support full 64-bit addressing on the 1436 * PCI-X side of the bridge. We build a special version of this driver for 1437 * those bridges, which uses PCIEB_ADDR_LIMIT_LO and/or PCIEB_ADDR_LIMIT_HI 1438 * to define the range of values which the chip can handle. The code below 1439 * then clamps the DMA address range supplied by the driver, preventing the 1440 * PCI-E nexus driver from allocating any memory the bridge can't deal 1441 * with. 1442 */ 1443 static int 1444 pcieb_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, 1445 ddi_dma_attr_t *attr_p, int (*waitfp)(caddr_t), caddr_t arg, 1446 ddi_dma_handle_t *handlep) 1447 { 1448 int ret; 1449 #ifdef PCIEB_BCM 1450 uint64_t lim; 1451 1452 /* 1453 * If the leaf device's limits are outside than what the Broadcom 1454 * bridge can handle, we need to clip the values passed up the chain. 1455 */ 1456 lim = attr_p->dma_attr_addr_lo; 1457 attr_p->dma_attr_addr_lo = MAX(lim, PCIEB_ADDR_LIMIT_LO); 1458 1459 lim = attr_p->dma_attr_addr_hi; 1460 attr_p->dma_attr_addr_hi = MIN(lim, PCIEB_ADDR_LIMIT_HI); 1461 1462 #endif /* PCIEB_BCM */ 1463 1464 /* 1465 * This is a software workaround to fix the Broadcom 5714/5715 PCIe-PCI 1466 * bridge prefetch bug. Intercept the DMA alloc handle request and set 1467 * PX_DMAI_FLAGS_MAP_BUFZONE flag in the handle. If this flag is set, 1468 * the px nexus driver will allocate an extra page & make it valid one, 1469 * for any DVMA request that comes from any of the Broadcom bridge child 1470 * devices. 1471 */ 1472 if ((ret = ddi_dma_allochdl(dip, rdip, attr_p, waitfp, arg, 1473 handlep)) == DDI_SUCCESS) { 1474 ddi_dma_impl_t *mp = (ddi_dma_impl_t *)*handlep; 1475 #ifdef PCIEB_BCM 1476 mp->dmai_inuse |= PX_DMAI_FLAGS_MAP_BUFZONE; 1477 #endif /* PCIEB_BCM */ 1478 /* 1479 * For a given rdip, update mp->dmai_bdf with the bdf value 1480 * of pcieb's immediate child or secondary bus-id of the 1481 * PCIe2PCI bridge. 1482 */ 1483 mp->dmai_minxfer = pcie_get_bdf_for_dma_xfer(dip, rdip); 1484 } 1485 1486 return (ret); 1487 } 1488 1489 /* 1490 * FDVMA feature is not supported for any child device of Broadcom 5714/5715 1491 * PCIe-PCI bridge due to prefetch bug. Return failure immediately, so that 1492 * these drivers will switch to regular DVMA path. 1493 */ 1494 /*ARGSUSED*/ 1495 static int 1496 pcieb_dma_mctl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handle, 1497 enum ddi_dma_ctlops cmd, off_t *offp, size_t *lenp, caddr_t *objp, 1498 uint_t cache_flags) 1499 { 1500 int ret; 1501 1502 #ifdef PCIEB_BCM 1503 if (cmd == DDI_DMA_RESERVE) 1504 return (DDI_FAILURE); 1505 #endif /* PCIEB_BCM */ 1506 1507 if (((ret = ddi_dma_mctl(dip, rdip, handle, cmd, offp, lenp, objp, 1508 cache_flags)) == DDI_SUCCESS) && (cmd == DDI_DMA_RESERVE)) { 1509 ddi_dma_impl_t *mp = (ddi_dma_impl_t *)*objp; 1510 1511 /* 1512 * For a given rdip, update mp->dmai_bdf with the bdf value 1513 * of pcieb's immediate child or secondary bus-id of the 1514 * PCIe2PCI bridge. 1515 */ 1516 mp->dmai_minxfer = pcie_get_bdf_for_dma_xfer(dip, rdip); 1517 } 1518 1519 return (ret); 1520 } 1521 1522 static int 1523 pcieb_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op, 1524 ddi_intr_handle_impl_t *hdlp, void *result) 1525 { 1526 return (pcieb_plat_intr_ops(dip, rdip, intr_op, hdlp, result)); 1527 1528 } 1529 1530 /* 1531 * Power management related initialization specific to pcieb. 1532 * Called by pcieb_attach() 1533 */ 1534 static int 1535 pcieb_pwr_setup(dev_info_t *dip) 1536 { 1537 char *comp_array[5]; 1538 int i; 1539 ddi_acc_handle_t conf_hdl; 1540 uint16_t pmcap, cap_ptr; 1541 pcie_pwr_t *pwr_p; 1542 1543 /* Some platforms/devices may choose to disable PM */ 1544 if (pcieb_plat_pwr_disable(dip)) { 1545 (void) pcieb_pwr_disable(dip); 1546 return (DDI_SUCCESS); 1547 } 1548 1549 ASSERT(PCIE_PMINFO(dip)); 1550 pwr_p = PCIE_NEXUS_PMINFO(dip); 1551 ASSERT(pwr_p); 1552 1553 /* Code taken from pci_pci driver */ 1554 if (pci_config_setup(dip, &pwr_p->pwr_conf_hdl) != DDI_SUCCESS) { 1555 PCIEB_DEBUG(DBG_PWR, dip, "pcieb_pwr_setup: pci_config_setup " 1556 "failed\n"); 1557 return (DDI_FAILURE); 1558 } 1559 conf_hdl = pwr_p->pwr_conf_hdl; 1560 1561 /* 1562 * Walk the capabilities searching for a PM entry. 1563 */ 1564 if ((PCI_CAP_LOCATE(conf_hdl, PCI_CAP_ID_PM, &cap_ptr)) == 1565 DDI_FAILURE) { 1566 PCIEB_DEBUG(DBG_PWR, dip, "switch/bridge does not support PM. " 1567 " PCI PM data structure not found in config header\n"); 1568 pci_config_teardown(&conf_hdl); 1569 return (DDI_SUCCESS); 1570 } 1571 /* 1572 * Save offset to pmcsr for future references. 1573 */ 1574 pwr_p->pwr_pmcsr_offset = cap_ptr + PCI_PMCSR; 1575 pmcap = PCI_CAP_GET16(conf_hdl, NULL, cap_ptr, PCI_PMCAP); 1576 if (pmcap & PCI_PMCAP_D1) { 1577 PCIEB_DEBUG(DBG_PWR, dip, "D1 state supported\n"); 1578 pwr_p->pwr_pmcaps |= PCIE_SUPPORTS_D1; 1579 } 1580 if (pmcap & PCI_PMCAP_D2) { 1581 PCIEB_DEBUG(DBG_PWR, dip, "D2 state supported\n"); 1582 pwr_p->pwr_pmcaps |= PCIE_SUPPORTS_D2; 1583 } 1584 1585 i = 0; 1586 comp_array[i++] = "NAME=PCIe switch/bridge PM"; 1587 comp_array[i++] = "0=Power Off (D3)"; 1588 if (pwr_p->pwr_pmcaps & PCIE_SUPPORTS_D2) 1589 comp_array[i++] = "1=D2"; 1590 if (pwr_p->pwr_pmcaps & PCIE_SUPPORTS_D1) 1591 comp_array[i++] = "2=D1"; 1592 comp_array[i++] = "3=Full Power D0"; 1593 1594 /* 1595 * Create pm-components property, if it does not exist already. 1596 */ 1597 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip, 1598 "pm-components", comp_array, i) != DDI_PROP_SUCCESS) { 1599 PCIEB_DEBUG(DBG_PWR, dip, "could not create pm-components " 1600 " prop\n"); 1601 pci_config_teardown(&conf_hdl); 1602 return (DDI_FAILURE); 1603 } 1604 return (pcieb_pwr_init_and_raise(dip, pwr_p)); 1605 } 1606 1607 /* 1608 * undo whatever is done in pcieb_pwr_setup. called by pcieb_detach() 1609 */ 1610 static void 1611 pcieb_pwr_teardown(dev_info_t *dip) 1612 { 1613 pcie_pwr_t *pwr_p; 1614 1615 if (!PCIE_PMINFO(dip) || !(pwr_p = PCIE_NEXUS_PMINFO(dip))) 1616 return; 1617 1618 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components"); 1619 if (pwr_p->pwr_conf_hdl) 1620 pci_config_teardown(&pwr_p->pwr_conf_hdl); 1621 } 1622 1623 /* 1624 * Initializes the power level and raise the power to D0, if it is 1625 * not at D0. 1626 */ 1627 static int 1628 pcieb_pwr_init_and_raise(dev_info_t *dip, pcie_pwr_t *pwr_p) 1629 { 1630 uint16_t pmcsr; 1631 int ret = DDI_SUCCESS; 1632 1633 /* 1634 * Intialize our power level from PMCSR. The common code initializes 1635 * this to UNKNOWN. There is no guarantee that we will be at full 1636 * power at attach. If we are not at D0, raise the power. 1637 */ 1638 pmcsr = pci_config_get16(pwr_p->pwr_conf_hdl, pwr_p->pwr_pmcsr_offset); 1639 pmcsr &= PCI_PMCSR_STATE_MASK; 1640 switch (pmcsr) { 1641 case PCI_PMCSR_D0: 1642 pwr_p->pwr_func_lvl = PM_LEVEL_D0; 1643 break; 1644 1645 case PCI_PMCSR_D1: 1646 pwr_p->pwr_func_lvl = PM_LEVEL_D1; 1647 break; 1648 1649 case PCI_PMCSR_D2: 1650 pwr_p->pwr_func_lvl = PM_LEVEL_D2; 1651 break; 1652 1653 case PCI_PMCSR_D3HOT: 1654 pwr_p->pwr_func_lvl = PM_LEVEL_D3; 1655 break; 1656 1657 default: 1658 break; 1659 } 1660 1661 /* Raise the power to D0. */ 1662 if (pwr_p->pwr_func_lvl != PM_LEVEL_D0 && 1663 ((ret = pm_raise_power(dip, 0, PM_LEVEL_D0)) != DDI_SUCCESS)) { 1664 /* 1665 * Read PMCSR again. If it is at D0, ignore the return 1666 * value from pm_raise_power. 1667 */ 1668 pmcsr = pci_config_get16(pwr_p->pwr_conf_hdl, 1669 pwr_p->pwr_pmcsr_offset); 1670 if ((pmcsr & PCI_PMCSR_STATE_MASK) == PCI_PMCSR_D0) 1671 ret = DDI_SUCCESS; 1672 else { 1673 PCIEB_DEBUG(DBG_PWR, dip, "pcieb_pwr_setup: could not " 1674 "raise power to D0 \n"); 1675 } 1676 } 1677 if (ret == DDI_SUCCESS) 1678 pwr_p->pwr_func_lvl = PM_LEVEL_D0; 1679 return (ret); 1680 } 1681 1682 /* 1683 * Disable PM for x86 and PLX 8532 switch. 1684 * For PLX Transitioning one port on this switch to low power causes links 1685 * on other ports on the same station to die. Due to PLX erratum #34, we 1686 * can't allow the downstream device go to non-D0 state. 1687 */ 1688 static int 1689 pcieb_pwr_disable(dev_info_t *dip) 1690 { 1691 pcie_pwr_t *pwr_p; 1692 1693 ASSERT(PCIE_PMINFO(dip)); 1694 pwr_p = PCIE_NEXUS_PMINFO(dip); 1695 ASSERT(pwr_p); 1696 PCIEB_DEBUG(DBG_PWR, dip, "pcieb_pwr_disable: disabling PM\n"); 1697 pwr_p->pwr_func_lvl = PM_LEVEL_D0; 1698 pwr_p->pwr_flags = PCIE_NO_CHILD_PM; 1699 return (DDI_SUCCESS); 1700 } 1701 1702 #ifdef DEBUG 1703 int pcieb_dbg_intr_print = 0; 1704 void 1705 pcieb_dbg(uint_t bit, dev_info_t *dip, char *fmt, ...) 1706 { 1707 va_list ap; 1708 1709 if (!pcieb_dbg_print) 1710 return; 1711 1712 if (dip) 1713 prom_printf("%s(%d): %s", ddi_driver_name(dip), 1714 ddi_get_instance(dip), pcieb_debug_sym[bit]); 1715 1716 va_start(ap, fmt); 1717 if (servicing_interrupt()) { 1718 if (pcieb_dbg_intr_print) 1719 prom_vprintf(fmt, ap); 1720 } else { 1721 prom_vprintf(fmt, ap); 1722 } 1723 1724 va_end(ap); 1725 } 1726 #endif 1727 1728 static void 1729 pcieb_id_props(pcieb_devstate_t *pcieb) 1730 { 1731 uint64_t serialid = 0; /* 40b field of EUI-64 serial no. register */ 1732 uint16_t cap_ptr; 1733 uint8_t fic = 0; /* 1 = first in chassis device */ 1734 pcie_bus_t *bus_p = PCIE_DIP2BUS(pcieb->pcieb_dip); 1735 ddi_acc_handle_t config_handle = bus_p->bus_cfg_hdl; 1736 1737 /* 1738 * Identify first in chassis. In the special case of a Sun branded 1739 * PLX device, it obviously is first in chassis. Otherwise, in the 1740 * general case, look for an Expansion Slot Register and check its 1741 * first-in-chassis bit. 1742 */ 1743 #ifdef PX_PLX 1744 uint16_t vendor_id = bus_p->bus_dev_ven_id & 0xFFFF; 1745 uint16_t device_id = bus_p->bus_dev_ven_id >> 16; 1746 if ((vendor_id == PXB_VENDOR_SUN) && 1747 ((device_id == PXB_DEVICE_PLX_PCIX) || 1748 (device_id == PXB_DEVICE_PLX_PCIE))) { 1749 fic = 1; 1750 } 1751 #endif /* PX_PLX */ 1752 if ((fic == 0) && ((PCI_CAP_LOCATE(config_handle, 1753 PCI_CAP_ID_SLOT_ID, &cap_ptr)) != DDI_FAILURE)) { 1754 uint8_t esr = PCI_CAP_GET8(config_handle, NULL, 1755 cap_ptr, PCI_CAP_ID_REGS_OFF); 1756 if (PCI_CAPSLOT_FIC(esr)) 1757 fic = 1; 1758 } 1759 1760 if ((PCI_CAP_LOCATE(config_handle, 1761 PCI_CAP_XCFG_SPC(PCIE_EXT_CAP_ID_SER), &cap_ptr)) != DDI_FAILURE) { 1762 /* Serialid can be 0 thru a full 40b number */ 1763 serialid = PCI_XCAP_GET32(config_handle, NULL, 1764 cap_ptr, PCIE_SER_SID_UPPER_DW); 1765 serialid <<= 32; 1766 serialid |= PCI_XCAP_GET32(config_handle, NULL, 1767 cap_ptr, PCIE_SER_SID_LOWER_DW); 1768 } 1769 1770 if (fic) 1771 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, pcieb->pcieb_dip, 1772 "first-in-chassis"); 1773 if (serialid) 1774 (void) ddi_prop_update_int64(DDI_DEV_T_NONE, pcieb->pcieb_dip, 1775 "serialid#", serialid); 1776 } 1777 1778 static void 1779 pcieb_create_ranges_prop(dev_info_t *dip, 1780 ddi_acc_handle_t config_handle) 1781 { 1782 uint32_t base, limit; 1783 ppb_ranges_t ranges[PCIEB_RANGE_LEN]; 1784 uint8_t io_base_lo, io_limit_lo; 1785 uint16_t io_base_hi, io_limit_hi, mem_base, mem_limit; 1786 int i = 0, rangelen = sizeof (ppb_ranges_t)/sizeof (int); 1787 1788 io_base_lo = pci_config_get8(config_handle, PCI_BCNF_IO_BASE_LOW); 1789 io_limit_lo = pci_config_get8(config_handle, PCI_BCNF_IO_LIMIT_LOW); 1790 io_base_hi = pci_config_get16(config_handle, PCI_BCNF_IO_BASE_HI); 1791 io_limit_hi = pci_config_get16(config_handle, PCI_BCNF_IO_LIMIT_HI); 1792 mem_base = pci_config_get16(config_handle, PCI_BCNF_MEM_BASE); 1793 mem_limit = pci_config_get16(config_handle, PCI_BCNF_MEM_LIMIT); 1794 1795 /* 1796 * Create ranges for IO space 1797 */ 1798 ranges[i].size_low = ranges[i].size_high = 0; 1799 ranges[i].parent_mid = ranges[i].child_mid = ranges[i].parent_high = 0; 1800 ranges[i].child_high = ranges[i].parent_high |= 1801 (PCI_REG_REL_M | PCI_ADDR_IO); 1802 base = PCIEB_16bit_IOADDR(io_base_lo); 1803 limit = PCIEB_16bit_IOADDR(io_limit_lo); 1804 1805 if ((io_base_lo & 0xf) == PCIEB_32BIT_IO) { 1806 base = PCIEB_LADDR(base, io_base_hi); 1807 } 1808 if ((io_limit_lo & 0xf) == PCIEB_32BIT_IO) { 1809 limit = PCIEB_LADDR(limit, io_limit_hi); 1810 } 1811 1812 if ((io_base_lo & PCIEB_32BIT_IO) && (io_limit_hi > 0)) { 1813 base = PCIEB_LADDR(base, io_base_hi); 1814 limit = PCIEB_LADDR(limit, io_limit_hi); 1815 } 1816 1817 /* 1818 * Create ranges for 32bit memory space 1819 */ 1820 base = PCIEB_32bit_MEMADDR(mem_base); 1821 limit = PCIEB_32bit_MEMADDR(mem_limit); 1822 ranges[i].size_low = ranges[i].size_high = 0; 1823 ranges[i].parent_mid = ranges[i].child_mid = ranges[i].parent_high = 0; 1824 ranges[i].child_high = ranges[i].parent_high |= 1825 (PCI_REG_REL_M | PCI_ADDR_MEM32); 1826 ranges[i].child_low = ranges[i].parent_low = base; 1827 if (limit >= base) { 1828 ranges[i].size_low = limit - base + PCIEB_MEMGRAIN; 1829 i++; 1830 } 1831 1832 if (i) { 1833 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "ranges", 1834 (int *)ranges, i * rangelen); 1835 } 1836 } 1837 1838 /* 1839 * For PCI and PCI-X devices including PCIe2PCI bridge, initialize 1840 * cache-line-size and latency timer configuration registers. 1841 */ 1842 void 1843 pcieb_set_pci_perf_parameters(dev_info_t *dip, ddi_acc_handle_t cfg_hdl) 1844 { 1845 uint_t n; 1846 1847 /* Initialize cache-line-size configuration register if needed */ 1848 if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1849 "cache-line-size", 0) == 0) { 1850 pci_config_put8(cfg_hdl, PCI_CONF_CACHE_LINESZ, 1851 PCIEB_CACHE_LINE_SIZE); 1852 n = pci_config_get8(cfg_hdl, PCI_CONF_CACHE_LINESZ); 1853 if (n != 0) { 1854 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 1855 "cache-line-size", n); 1856 } 1857 } 1858 1859 /* Initialize latency timer configuration registers if needed */ 1860 if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1861 "latency-timer", 0) == 0) { 1862 uchar_t min_gnt, latency_timer; 1863 uchar_t header_type; 1864 1865 /* Determine the configuration header type */ 1866 header_type = pci_config_get8(cfg_hdl, PCI_CONF_HEADER); 1867 1868 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { 1869 latency_timer = PCIEB_LATENCY_TIMER; 1870 pci_config_put8(cfg_hdl, PCI_BCNF_LATENCY_TIMER, 1871 latency_timer); 1872 } else { 1873 min_gnt = pci_config_get8(cfg_hdl, PCI_CONF_MIN_G); 1874 latency_timer = min_gnt * 8; 1875 } 1876 1877 pci_config_put8(cfg_hdl, PCI_CONF_LATENCY_TIMER, 1878 latency_timer); 1879 n = pci_config_get8(cfg_hdl, PCI_CONF_LATENCY_TIMER); 1880 if (n != 0) { 1881 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 1882 "latency-timer", n); 1883 } 1884 } 1885 }