1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * Host to PCI local bus driver 31 */ 32 33 #include <sys/conf.h> 34 #include <sys/modctl.h> 35 #include <sys/pci.h> 36 #include <sys/pci_impl.h> 37 #include <sys/sysmacros.h> 38 #include <sys/sunndi.h> 39 #include <sys/hotplug/pci/pcihp.h> 40 #include <sys/pci_cfgspace.h> 41 #include <io/pci/pci_common.h> 42 #include <io/pci/pci_tools_ext.h> 43 #include <io/pci/pci_var.h> 44 45 /* Save minimal state. */ 46 void *pci_statep; 47 48 /* 49 * Bus Operation functions 50 */ 51 static int pci_bus_map(dev_info_t *, dev_info_t *, ddi_map_req_t *, 52 off_t, off_t, caddr_t *); 53 static int pci_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, 54 void *, void *); 55 static int pci_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t, 56 ddi_intr_handle_impl_t *, void *); 57 58 struct bus_ops pci_bus_ops = { 59 BUSO_REV, 60 pci_bus_map, 61 NULL, 62 NULL, 63 NULL, 64 i_ddi_map_fault, 65 ddi_dma_map, 66 ddi_dma_allochdl, 67 ddi_dma_freehdl, 68 ddi_dma_bindhdl, 69 ddi_dma_unbindhdl, 70 ddi_dma_flush, 71 ddi_dma_win, 72 ddi_dma_mctl, 73 pci_ctlops, 74 ddi_bus_prop_op, 75 0, /* (*bus_get_eventcookie)(); */ 76 0, /* (*bus_add_eventcall)(); */ 77 0, /* (*bus_remove_eventcall)(); */ 78 0, /* (*bus_post_event)(); */ 79 0, /* (*bus_intr_ctl)(); */ 80 0, /* (*bus_config)(); */ 81 0, /* (*bus_unconfig)(); */ 82 NULL, /* (*bus_fm_init)(); */ 83 NULL, /* (*bus_fm_fini)(); */ 84 NULL, /* (*bus_fm_access_enter)(); */ 85 NULL, /* (*bus_fm_access_exit)(); */ 86 NULL, /* (*bus_power)(); */ 87 pci_intr_ops /* (*bus_intr_op)(); */ 88 }; 89 90 /* 91 * One goal here is to leverage off of the pcihp.c source without making 92 * changes to it. Call into it's cb_ops directly if needed, piggybacking 93 * anything else needed by the pci_tools.c module. Only pci_tools and pcihp 94 * will be opening PCI nexus driver file descriptors. 95 */ 96 static int pci_open(dev_t *, int, int, cred_t *); 97 static int pci_close(dev_t, int, int, cred_t *); 98 static int pci_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 99 static int pci_prop_op(dev_t, dev_info_t *, ddi_prop_op_t, int, char *, 100 caddr_t, int *); 101 static int pci_info(dev_info_t *, ddi_info_cmd_t, void *, void **); 102 103 struct cb_ops pci_cb_ops = { 104 pci_open, /* open */ 105 pci_close, /* close */ 106 nodev, /* strategy */ 107 nodev, /* print */ 108 nodev, /* dump */ 109 nodev, /* read */ 110 nodev, /* write */ 111 pci_ioctl, /* ioctl */ 112 nodev, /* devmap */ 113 nodev, /* mmap */ 114 nodev, /* segmap */ 115 nochpoll, /* poll */ 116 pci_prop_op, /* cb_prop_op */ 117 NULL, /* streamtab */ 118 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */ 119 CB_REV, /* rev */ 120 nodev, /* int (*cb_aread)() */ 121 nodev /* int (*cb_awrite)() */ 122 }; 123 124 /* 125 * Device Node Operation functions 126 */ 127 static int pci_attach(dev_info_t *devi, ddi_attach_cmd_t cmd); 128 static int pci_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 129 130 struct dev_ops pci_ops = { 131 DEVO_REV, /* devo_rev */ 132 0, /* refcnt */ 133 pci_info, /* info */ 134 nulldev, /* identify */ 135 nulldev, /* probe */ 136 pci_attach, /* attach */ 137 pci_detach, /* detach */ 138 nulldev, /* reset */ 139 &pci_cb_ops, /* driver operations */ 140 &pci_bus_ops /* bus operations */ 141 }; 142 143 /* 144 * This variable controls the default setting of the command register 145 * for pci devices. See pci_initchild() for details. 146 */ 147 static ushort_t pci_command_default = PCI_COMM_ME | 148 PCI_COMM_MAE | 149 PCI_COMM_IO; 150 151 /* 152 * Internal routines in support of particular pci_ctlops. 153 */ 154 static int pci_removechild(dev_info_t *child); 155 static int pci_initchild(dev_info_t *child); 156 157 /* 158 * These are the access routines. The pci_bus_map sets the handle 159 * to point to these. 160 */ 161 static uint8_t pci_config_rd8(ddi_acc_impl_t *hdlp, uint8_t *addr); 162 static uint16_t pci_config_rd16(ddi_acc_impl_t *hdlp, uint16_t *addr); 163 static uint32_t pci_config_rd32(ddi_acc_impl_t *hdlp, uint32_t *addr); 164 static uint64_t pci_config_rd64(ddi_acc_impl_t *hdlp, uint64_t *addr); 165 166 static void pci_config_wr8(ddi_acc_impl_t *hdlp, uint8_t *addr, 167 uint8_t value); 168 static void pci_config_wr16(ddi_acc_impl_t *hdlp, uint16_t *addr, 169 uint16_t value); 170 static void pci_config_wr32(ddi_acc_impl_t *hdlp, uint32_t *addr, 171 uint32_t value); 172 static void pci_config_wr64(ddi_acc_impl_t *hdlp, uint64_t *addr, 173 uint64_t value); 174 175 static void pci_config_rep_rd8(ddi_acc_impl_t *hdlp, uint8_t *host_addr, 176 uint8_t *dev_addr, size_t repcount, uint_t flags); 177 static void pci_config_rep_rd16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 178 uint16_t *dev_addr, size_t repcount, uint_t flags); 179 static void pci_config_rep_rd32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 180 uint32_t *dev_addr, size_t repcount, uint_t flags); 181 static void pci_config_rep_rd64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 182 uint64_t *dev_addr, size_t repcount, uint_t flags); 183 184 static void pci_config_rep_wr8(ddi_acc_impl_t *hdlp, uint8_t *host_addr, 185 uint8_t *dev_addr, size_t repcount, uint_t flags); 186 static void pci_config_rep_wr16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 187 uint16_t *dev_addr, size_t repcount, uint_t flags); 188 static void pci_config_rep_wr32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 189 uint32_t *dev_addr, size_t repcount, uint_t flags); 190 static void pci_config_rep_wr64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 191 uint64_t *dev_addr, size_t repcount, uint_t flags); 192 193 /* 194 * Module linkage information for the kernel. 195 */ 196 197 static struct modldrv modldrv = { 198 &mod_driverops, /* Type of module */ 199 "host to PCI nexus driver %I%", 200 &pci_ops, /* driver ops */ 201 }; 202 203 static struct modlinkage modlinkage = { 204 MODREV_1, 205 (void *)&modldrv, 206 NULL 207 }; 208 209 int 210 _init(void) 211 { 212 int e; 213 214 /* 215 * Initialize per-pci bus soft state pointer. 216 */ 217 e = ddi_soft_state_init(&pci_statep, sizeof (pci_state_t), 1); 218 if (e != 0) 219 return (e); 220 221 if ((e = mod_install(&modlinkage)) != 0) 222 ddi_soft_state_fini(&pci_statep); 223 224 return (e); 225 } 226 227 int 228 _fini(void) 229 { 230 int rc; 231 232 rc = mod_remove(&modlinkage); 233 if (rc != 0) 234 return (rc); 235 236 ddi_soft_state_fini(&pci_statep); 237 238 return (rc); 239 } 240 241 int 242 _info(struct modinfo *modinfop) 243 { 244 return (mod_info(&modlinkage, modinfop)); 245 } 246 247 /*ARGSUSED*/ 248 static int 249 pci_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 250 { 251 /* 252 * Use the minor number as constructed by pcihp, as the index value to 253 * ddi_soft_state_zalloc. 254 */ 255 int instance = ddi_get_instance(devi); 256 pci_state_t *pcip = NULL; 257 258 if (ddi_prop_update_string(DDI_DEV_T_NONE, devi, "device_type", "pci") 259 != DDI_PROP_SUCCESS) { 260 cmn_err(CE_WARN, "pci: 'device_type' prop create failed"); 261 } 262 263 if (ddi_soft_state_zalloc(pci_statep, instance) == DDI_SUCCESS) { 264 pcip = ddi_get_soft_state(pci_statep, instance); 265 } 266 267 if (pcip == NULL) { 268 goto bad_soft_state; 269 } 270 271 pcip->pci_dip = devi; 272 273 /* 274 * Initialize hotplug support on this bus. At minimum 275 * (for non hotplug bus) this would create ":devctl" minor 276 * node to support DEVCTL_DEVICE_* and DEVCTL_BUS_* ioctls 277 * to this bus. 278 */ 279 if (pcihp_init(devi) != DDI_SUCCESS) { 280 cmn_err(CE_WARN, "pci: Failed to setup hotplug framework"); 281 goto bad_pcihp_init; 282 } 283 284 /* Second arg: initialize for pci, not pci_express */ 285 if (pcitool_init(devi, B_FALSE) != DDI_SUCCESS) { 286 goto bad_pcitool_init; 287 } 288 289 ddi_report_dev(devi); 290 291 return (DDI_SUCCESS); 292 293 bad_pcitool_init: 294 (void) pcihp_uninit(devi); 295 bad_pcihp_init: 296 ddi_soft_state_free(pci_statep, instance); 297 bad_soft_state: 298 return (DDI_FAILURE); 299 } 300 301 /*ARGSUSED*/ 302 static int 303 pci_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 304 { 305 /* Uninitialize pcitool support. */ 306 pcitool_uninit(devi); 307 308 /* Uninitialize hotplug support on this bus. */ 309 (void) pcihp_uninit(devi); 310 311 ddi_soft_state_free(pci_statep, DIP_TO_MINOR(devi)); 312 313 return (DDI_SUCCESS); 314 } 315 316 static int 317 pci_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 318 off_t offset, off_t len, caddr_t *vaddrp) 319 { 320 struct regspec reg; 321 ddi_map_req_t mr; 322 ddi_acc_hdl_t *hp; 323 ddi_acc_impl_t *ap; 324 pci_regspec_t pci_reg; 325 pci_regspec_t *pci_rp; 326 int rnumber; 327 int length; 328 pci_acc_cfblk_t *cfp; 329 int space; 330 331 332 mr = *mp; /* Get private copy of request */ 333 mp = &mr; 334 335 /* 336 * check for register number 337 */ 338 switch (mp->map_type) { 339 case DDI_MT_REGSPEC: 340 pci_reg = *(pci_regspec_t *)(mp->map_obj.rp); 341 pci_rp = &pci_reg; 342 if (pci_common_get_reg_prop(rdip, pci_rp) != DDI_SUCCESS) 343 return (DDI_FAILURE); 344 break; 345 case DDI_MT_RNUMBER: 346 rnumber = mp->map_obj.rnumber; 347 /* 348 * get ALL "reg" properties for dip, select the one of 349 * of interest. In x86, "assigned-addresses" property 350 * is identical to the "reg" property, so there is no 351 * need to cross check the two to determine the physical 352 * address of the registers. 353 * This routine still performs some validity checks to 354 * make sure that everything is okay. 355 */ 356 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, rdip, 357 DDI_PROP_DONTPASS, "reg", (int **)&pci_rp, 358 (uint_t *)&length) != DDI_PROP_SUCCESS) 359 return (DDI_FAILURE); 360 361 /* 362 * validate the register number. 363 */ 364 length /= (sizeof (pci_regspec_t) / sizeof (int)); 365 if (rnumber >= length) { 366 ddi_prop_free(pci_rp); 367 return (DDI_FAILURE); 368 } 369 370 /* 371 * copy the required entry. 372 */ 373 pci_reg = pci_rp[rnumber]; 374 375 /* 376 * free the memory allocated by ddi_prop_lookup_int_array 377 */ 378 ddi_prop_free(pci_rp); 379 380 pci_rp = &pci_reg; 381 if (pci_common_get_reg_prop(rdip, pci_rp) != DDI_SUCCESS) 382 return (DDI_FAILURE); 383 mp->map_type = DDI_MT_REGSPEC; 384 break; 385 default: 386 return (DDI_ME_INVAL); 387 } 388 389 space = pci_rp->pci_phys_hi & PCI_REG_ADDR_M; 390 391 /* 392 * check for unmap and unlock of address space 393 */ 394 if ((mp->map_op == DDI_MO_UNMAP) || (mp->map_op == DDI_MO_UNLOCK)) { 395 /* 396 * Adjust offset and length 397 * A non-zero length means override the one in the regspec. 398 */ 399 pci_rp->pci_phys_low += (uint_t)offset; 400 if (len != 0) 401 pci_rp->pci_size_low = len; 402 403 switch (space) { 404 case PCI_ADDR_CONFIG: 405 /* No work required on unmap of Config space */ 406 return (DDI_SUCCESS); 407 408 case PCI_ADDR_IO: 409 reg.regspec_bustype = 1; 410 break; 411 412 case PCI_ADDR_MEM64: 413 /* 414 * MEM64 requires special treatment on map, to check 415 * that the device is below 4G. On unmap, however, 416 * we can assume that everything is OK... the map 417 * must have succeeded. 418 */ 419 /* FALLTHROUGH */ 420 case PCI_ADDR_MEM32: 421 reg.regspec_bustype = 0; 422 break; 423 424 default: 425 return (DDI_FAILURE); 426 } 427 reg.regspec_addr = pci_rp->pci_phys_low; 428 reg.regspec_size = pci_rp->pci_size_low; 429 430 mp->map_obj.rp = ® 431 return (ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp)); 432 433 } 434 435 /* check for user mapping request - not legal for Config */ 436 if (mp->map_op == DDI_MO_MAP_HANDLE && space == PCI_ADDR_CONFIG) { 437 return (DDI_FAILURE); 438 } 439 440 /* 441 * check for config space 442 * On x86, CONFIG is not mapped via MMU and there is 443 * no endian-ness issues. Set the attr field in the handle to 444 * indicate that the common routines to call the nexus driver. 445 */ 446 if (space == PCI_ADDR_CONFIG) { 447 hp = (ddi_acc_hdl_t *)mp->map_handlep; 448 449 /* Can't map config space without a handle */ 450 if (hp == NULL) 451 return (DDI_FAILURE); 452 453 ap = (ddi_acc_impl_t *)hp->ah_platform_private; 454 455 /* endian-ness check */ 456 if (hp->ah_acc.devacc_attr_endian_flags == DDI_STRUCTURE_BE_ACC) 457 return (DDI_FAILURE); 458 459 /* 460 * range check 461 */ 462 if ((offset >= 256) || (len > 256) || (offset + len > 256)) 463 return (DDI_FAILURE); 464 *vaddrp = (caddr_t)offset; 465 466 ap->ahi_acc_attr |= DDI_ACCATTR_CONFIG_SPACE; 467 ap->ahi_put8 = pci_config_wr8; 468 ap->ahi_get8 = pci_config_rd8; 469 ap->ahi_put64 = pci_config_wr64; 470 ap->ahi_get64 = pci_config_rd64; 471 ap->ahi_rep_put8 = pci_config_rep_wr8; 472 ap->ahi_rep_get8 = pci_config_rep_rd8; 473 ap->ahi_rep_put64 = pci_config_rep_wr64; 474 ap->ahi_rep_get64 = pci_config_rep_rd64; 475 ap->ahi_get16 = pci_config_rd16; 476 ap->ahi_get32 = pci_config_rd32; 477 ap->ahi_put16 = pci_config_wr16; 478 ap->ahi_put32 = pci_config_wr32; 479 ap->ahi_rep_get16 = pci_config_rep_rd16; 480 ap->ahi_rep_get32 = pci_config_rep_rd32; 481 ap->ahi_rep_put16 = pci_config_rep_wr16; 482 ap->ahi_rep_put32 = pci_config_rep_wr32; 483 484 /* Initialize to default check/notify functions */ 485 ap->ahi_fault_check = i_ddi_acc_fault_check; 486 ap->ahi_fault_notify = i_ddi_acc_fault_notify; 487 ap->ahi_fault = 0; 488 impl_acc_err_init(hp); 489 490 /* record the device address for future reference */ 491 cfp = (pci_acc_cfblk_t *)&hp->ah_bus_private; 492 cfp->c_busnum = PCI_REG_BUS_G(pci_rp->pci_phys_hi); 493 cfp->c_devnum = PCI_REG_DEV_G(pci_rp->pci_phys_hi); 494 cfp->c_funcnum = PCI_REG_FUNC_G(pci_rp->pci_phys_hi); 495 496 return (DDI_SUCCESS); 497 } 498 499 /* 500 * range check 501 */ 502 if ((offset >= pci_rp->pci_size_low) || 503 (len > pci_rp->pci_size_low) || 504 (offset + len > pci_rp->pci_size_low)) { 505 return (DDI_FAILURE); 506 } 507 508 /* 509 * Adjust offset and length 510 * A non-zero length means override the one in the regspec. 511 */ 512 pci_rp->pci_phys_low += (uint_t)offset; 513 if (len != 0) 514 pci_rp->pci_size_low = len; 515 516 /* 517 * convert the pci regsec into the generic regspec used by the 518 * parent root nexus driver. 519 */ 520 switch (space) { 521 case PCI_ADDR_IO: 522 reg.regspec_bustype = 1; 523 break; 524 case PCI_ADDR_MEM64: 525 /* 526 * We can't handle 64-bit devices that are mapped above 527 * 4G or that are larger than 4G. 528 */ 529 if (pci_rp->pci_phys_mid != 0 || 530 pci_rp->pci_size_hi != 0) 531 return (DDI_FAILURE); 532 /* 533 * Other than that, we can treat them as 32-bit mappings 534 */ 535 /* FALLTHROUGH */ 536 case PCI_ADDR_MEM32: 537 reg.regspec_bustype = 0; 538 break; 539 default: 540 return (DDI_FAILURE); 541 } 542 reg.regspec_addr = pci_rp->pci_phys_low; 543 reg.regspec_size = pci_rp->pci_size_low; 544 545 mp->map_obj.rp = ® 546 return (ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp)); 547 } 548 549 550 /*ARGSUSED*/ 551 static int 552 pci_ctlops(dev_info_t *dip, dev_info_t *rdip, 553 ddi_ctl_enum_t ctlop, void *arg, void *result) 554 { 555 pci_regspec_t *drv_regp; 556 uint_t reglen; 557 int rn; 558 int totreg; 559 560 switch (ctlop) { 561 case DDI_CTLOPS_REPORTDEV: 562 if (rdip == (dev_info_t *)0) 563 return (DDI_FAILURE); 564 cmn_err(CE_CONT, "?PCI-device: %s@%s, %s%d\n", 565 ddi_node_name(rdip), ddi_get_name_addr(rdip), 566 ddi_driver_name(rdip), 567 ddi_get_instance(rdip)); 568 return (DDI_SUCCESS); 569 570 case DDI_CTLOPS_INITCHILD: 571 return (pci_initchild((dev_info_t *)arg)); 572 573 case DDI_CTLOPS_UNINITCHILD: 574 return (pci_removechild((dev_info_t *)arg)); 575 576 case DDI_CTLOPS_SIDDEV: 577 return (DDI_SUCCESS); 578 579 case DDI_CTLOPS_REGSIZE: 580 case DDI_CTLOPS_NREGS: 581 if (rdip == (dev_info_t *)0) 582 return (DDI_FAILURE); 583 584 *(int *)result = 0; 585 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, rdip, 586 DDI_PROP_DONTPASS, "reg", (int **)&drv_regp, 587 ®len) != DDI_PROP_SUCCESS) { 588 return (DDI_FAILURE); 589 } 590 591 totreg = (reglen * sizeof (int)) / sizeof (pci_regspec_t); 592 if (ctlop == DDI_CTLOPS_NREGS) 593 *(int *)result = totreg; 594 else if (ctlop == DDI_CTLOPS_REGSIZE) { 595 rn = *(int *)arg; 596 if (rn >= totreg) { 597 ddi_prop_free(drv_regp); 598 return (DDI_FAILURE); 599 } 600 *(off_t *)result = drv_regp[rn].pci_size_low; 601 } 602 ddi_prop_free(drv_regp); 603 604 return (DDI_SUCCESS); 605 606 case DDI_CTLOPS_POWER: { 607 power_req_t *reqp = (power_req_t *)arg; 608 /* 609 * We currently understand reporting of PCI_PM_IDLESPEED 610 * capability. Everything else is passed up. 611 */ 612 if ((reqp->request_type == PMR_REPORT_PMCAP) && 613 (reqp->req.report_pmcap_req.cap == PCI_PM_IDLESPEED)) { 614 615 return (DDI_SUCCESS); 616 } 617 return (ddi_ctlops(dip, rdip, ctlop, arg, result)); 618 } 619 620 default: 621 return (ddi_ctlops(dip, rdip, ctlop, arg, result)); 622 } 623 624 /* NOTREACHED */ 625 626 } 627 628 /* 629 * pci_intr_ops 630 */ 631 static int 632 pci_intr_ops(dev_info_t *pdip, dev_info_t *rdip, ddi_intr_op_t intr_op, 633 ddi_intr_handle_impl_t *hdlp, void *result) 634 { 635 return (pci_common_intr_ops(pdip, rdip, intr_op, hdlp, result)); 636 } 637 638 639 static int 640 pci_initchild(dev_info_t *child) 641 { 642 char name[80]; 643 ddi_acc_handle_t config_handle; 644 ushort_t command_preserve, command; 645 646 if (pci_common_name_child(child, name, 80) != DDI_SUCCESS) { 647 return (DDI_FAILURE); 648 } 649 ddi_set_name_addr(child, name); 650 651 /* 652 * Pseudo nodes indicate a prototype node with per-instance 653 * properties to be merged into the real h/w device node. 654 * The interpretation of the unit-address is DD[,F] 655 * where DD is the device id and F is the function. 656 */ 657 if (ndi_dev_is_persistent_node(child) == 0) { 658 extern int pci_allow_pseudo_children; 659 660 ddi_set_parent_data(child, NULL); 661 662 /* 663 * Try to merge the properties from this prototype 664 * node into real h/w nodes. 665 */ 666 if (ndi_merge_node(child, pci_common_name_child) == 667 DDI_SUCCESS) { 668 /* 669 * Merged ok - return failure to remove the node. 670 */ 671 ddi_set_name_addr(child, NULL); 672 return (DDI_FAILURE); 673 } 674 675 /* workaround for ddivs to run under PCI */ 676 if (pci_allow_pseudo_children) { 677 /* 678 * If the "interrupts" property doesn't exist, 679 * this must be the ddivs no-intr case, and it returns 680 * DDI_SUCCESS instead of DDI_FAILURE. 681 */ 682 if (ddi_prop_get_int(DDI_DEV_T_ANY, child, 683 DDI_PROP_DONTPASS, "interrupts", -1) == -1) 684 return (DDI_SUCCESS); 685 /* 686 * Create the ddi_parent_private_data for a pseudo 687 * child. 688 */ 689 pci_common_set_parent_private_data(child); 690 return (DDI_SUCCESS); 691 } 692 693 /* 694 * The child was not merged into a h/w node, 695 * but there's not much we can do with it other 696 * than return failure to cause the node to be removed. 697 */ 698 cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged", 699 ddi_get_name(child), ddi_get_name_addr(child), 700 ddi_get_name(child)); 701 ddi_set_name_addr(child, NULL); 702 return (DDI_NOT_WELL_FORMED); 703 } 704 705 if (ddi_prop_get_int(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, 706 "interrupts", -1) != -1) 707 pci_common_set_parent_private_data(child); 708 else 709 ddi_set_parent_data(child, NULL); 710 711 /* 712 * initialize command register 713 */ 714 if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) 715 return (DDI_FAILURE); 716 717 /* 718 * Support for the "command-preserve" property. 719 */ 720 command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child, 721 DDI_PROP_DONTPASS, 722 "command-preserve", 0); 723 command = pci_config_get16(config_handle, PCI_CONF_COMM); 724 command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB); 725 command |= (pci_command_default & ~command_preserve); 726 pci_config_put16(config_handle, PCI_CONF_COMM, command); 727 728 pci_config_teardown(&config_handle); 729 return (DDI_SUCCESS); 730 } 731 732 static int 733 pci_removechild(dev_info_t *dip) 734 { 735 struct ddi_parent_private_data *pdptr; 736 737 if ((pdptr = ddi_get_parent_data(dip)) != NULL) { 738 kmem_free(pdptr, (sizeof (*pdptr) + sizeof (struct intrspec))); 739 ddi_set_parent_data(dip, NULL); 740 } 741 ddi_set_name_addr(dip, NULL); 742 743 /* 744 * Strip the node to properly convert it back to prototype form 745 */ 746 ddi_remove_minor_node(dip, NULL); 747 748 impl_rem_dev_props(dip); 749 750 return (DDI_SUCCESS); 751 } 752 753 754 /* 755 * These are the get and put functions to be shared with drivers. The 756 * mutex locking is done inside the functions referenced, rather than 757 * here, and is thus shared across PCI child drivers and any other 758 * consumers of PCI config space (such as the ACPI subsystem). 759 * 760 * The configuration space addresses come in as pointers. This is fine on 761 * a 32-bit system, where the VM space and configuration space are the same 762 * size. It's not such a good idea on a 64-bit system, where memory 763 * addresses are twice as large as configuration space addresses. At some 764 * point in the call tree we need to take a stand and say "you are 32-bit 765 * from this time forth", and this seems like a nice self-contained place. 766 */ 767 768 static uint8_t 769 pci_config_rd8(ddi_acc_impl_t *hdlp, uint8_t *addr) 770 { 771 pci_acc_cfblk_t *cfp; 772 uint8_t rval; 773 int reg; 774 775 ASSERT64(((uintptr_t)addr >> 32) == 0); 776 777 reg = (int)(uintptr_t)addr; 778 779 cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private; 780 781 rval = (*pci_getb_func)(cfp->c_busnum, cfp->c_devnum, cfp->c_funcnum, 782 reg); 783 784 return (rval); 785 } 786 787 static void 788 pci_config_rep_rd8(ddi_acc_impl_t *hdlp, uint8_t *host_addr, 789 uint8_t *dev_addr, size_t repcount, uint_t flags) 790 { 791 uint8_t *h, *d; 792 793 h = host_addr; 794 d = dev_addr; 795 796 if (flags == DDI_DEV_AUTOINCR) 797 for (; repcount; repcount--) 798 *h++ = pci_config_rd8(hdlp, d++); 799 else 800 for (; repcount; repcount--) 801 *h++ = pci_config_rd8(hdlp, d); 802 } 803 804 static uint16_t 805 pci_config_rd16(ddi_acc_impl_t *hdlp, uint16_t *addr) 806 { 807 pci_acc_cfblk_t *cfp; 808 uint16_t rval; 809 int reg; 810 811 ASSERT64(((uintptr_t)addr >> 32) == 0); 812 813 reg = (int)(uintptr_t)addr; 814 815 cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private; 816 817 rval = (*pci_getw_func)(cfp->c_busnum, cfp->c_devnum, cfp->c_funcnum, 818 reg); 819 820 return (rval); 821 } 822 823 static void 824 pci_config_rep_rd16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 825 uint16_t *dev_addr, size_t repcount, uint_t flags) 826 { 827 uint16_t *h, *d; 828 829 h = host_addr; 830 d = dev_addr; 831 832 if (flags == DDI_DEV_AUTOINCR) 833 for (; repcount; repcount--) 834 *h++ = pci_config_rd16(hdlp, d++); 835 else 836 for (; repcount; repcount--) 837 *h++ = pci_config_rd16(hdlp, d); 838 } 839 840 static uint32_t 841 pci_config_rd32(ddi_acc_impl_t *hdlp, uint32_t *addr) 842 { 843 pci_acc_cfblk_t *cfp; 844 uint32_t rval; 845 int reg; 846 847 ASSERT64(((uintptr_t)addr >> 32) == 0); 848 849 reg = (int)(uintptr_t)addr; 850 851 cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private; 852 853 rval = (*pci_getl_func)(cfp->c_busnum, cfp->c_devnum, 854 cfp->c_funcnum, reg); 855 856 return (rval); 857 } 858 859 static void 860 pci_config_rep_rd32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 861 uint32_t *dev_addr, size_t repcount, uint_t flags) 862 { 863 uint32_t *h, *d; 864 865 h = host_addr; 866 d = dev_addr; 867 868 if (flags == DDI_DEV_AUTOINCR) 869 for (; repcount; repcount--) 870 *h++ = pci_config_rd32(hdlp, d++); 871 else 872 for (; repcount; repcount--) 873 *h++ = pci_config_rd32(hdlp, d); 874 } 875 876 877 static void 878 pci_config_wr8(ddi_acc_impl_t *hdlp, uint8_t *addr, uint8_t value) 879 { 880 pci_acc_cfblk_t *cfp; 881 int reg; 882 883 ASSERT64(((uintptr_t)addr >> 32) == 0); 884 885 reg = (int)(uintptr_t)addr; 886 887 cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private; 888 889 (*pci_putb_func)(cfp->c_busnum, cfp->c_devnum, 890 cfp->c_funcnum, reg, value); 891 } 892 893 static void 894 pci_config_rep_wr8(ddi_acc_impl_t *hdlp, uint8_t *host_addr, 895 uint8_t *dev_addr, size_t repcount, uint_t flags) 896 { 897 uint8_t *h, *d; 898 899 h = host_addr; 900 d = dev_addr; 901 902 if (flags == DDI_DEV_AUTOINCR) 903 for (; repcount; repcount--) 904 pci_config_wr8(hdlp, d++, *h++); 905 else 906 for (; repcount; repcount--) 907 pci_config_wr8(hdlp, d, *h++); 908 } 909 910 static void 911 pci_config_wr16(ddi_acc_impl_t *hdlp, uint16_t *addr, uint16_t value) 912 { 913 pci_acc_cfblk_t *cfp; 914 int reg; 915 916 ASSERT64(((uintptr_t)addr >> 32) == 0); 917 918 reg = (int)(uintptr_t)addr; 919 920 cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private; 921 922 (*pci_putw_func)(cfp->c_busnum, cfp->c_devnum, 923 cfp->c_funcnum, reg, value); 924 } 925 926 static void 927 pci_config_rep_wr16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 928 uint16_t *dev_addr, size_t repcount, uint_t flags) 929 { 930 uint16_t *h, *d; 931 932 h = host_addr; 933 d = dev_addr; 934 935 if (flags == DDI_DEV_AUTOINCR) 936 for (; repcount; repcount--) 937 pci_config_wr16(hdlp, d++, *h++); 938 else 939 for (; repcount; repcount--) 940 pci_config_wr16(hdlp, d, *h++); 941 } 942 943 static void 944 pci_config_wr32(ddi_acc_impl_t *hdlp, uint32_t *addr, uint32_t value) 945 { 946 pci_acc_cfblk_t *cfp; 947 int reg; 948 949 ASSERT64(((uintptr_t)addr >> 32) == 0); 950 951 reg = (int)(uintptr_t)addr; 952 953 cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private; 954 955 (*pci_putl_func)(cfp->c_busnum, cfp->c_devnum, 956 cfp->c_funcnum, reg, value); 957 } 958 959 static void 960 pci_config_rep_wr32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 961 uint32_t *dev_addr, size_t repcount, uint_t flags) 962 { 963 uint32_t *h, *d; 964 965 h = host_addr; 966 d = dev_addr; 967 968 if (flags == DDI_DEV_AUTOINCR) 969 for (; repcount; repcount--) 970 pci_config_wr32(hdlp, d++, *h++); 971 else 972 for (; repcount; repcount--) 973 pci_config_wr32(hdlp, d, *h++); 974 } 975 976 static uint64_t 977 pci_config_rd64(ddi_acc_impl_t *hdlp, uint64_t *addr) 978 { 979 uint32_t lw_val; 980 uint32_t hi_val; 981 uint32_t *dp; 982 uint64_t val; 983 984 dp = (uint32_t *)addr; 985 lw_val = pci_config_rd32(hdlp, dp); 986 dp++; 987 hi_val = pci_config_rd32(hdlp, dp); 988 val = ((uint64_t)hi_val << 32) | lw_val; 989 return (val); 990 } 991 992 static void 993 pci_config_wr64(ddi_acc_impl_t *hdlp, uint64_t *addr, uint64_t value) 994 { 995 uint32_t lw_val; 996 uint32_t hi_val; 997 uint32_t *dp; 998 999 dp = (uint32_t *)addr; 1000 lw_val = (uint32_t)(value & 0xffffffff); 1001 hi_val = (uint32_t)(value >> 32); 1002 pci_config_wr32(hdlp, dp, lw_val); 1003 dp++; 1004 pci_config_wr32(hdlp, dp, hi_val); 1005 } 1006 1007 static void 1008 pci_config_rep_rd64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 1009 uint64_t *dev_addr, size_t repcount, uint_t flags) 1010 { 1011 if (flags == DDI_DEV_AUTOINCR) { 1012 for (; repcount; repcount--) 1013 *host_addr++ = pci_config_rd64(hdlp, dev_addr++); 1014 } else { 1015 for (; repcount; repcount--) 1016 *host_addr++ = pci_config_rd64(hdlp, dev_addr); 1017 } 1018 } 1019 1020 static void 1021 pci_config_rep_wr64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 1022 uint64_t *dev_addr, size_t repcount, uint_t flags) 1023 { 1024 if (flags == DDI_DEV_AUTOINCR) { 1025 for (; repcount; repcount--) 1026 pci_config_wr64(hdlp, host_addr++, *dev_addr++); 1027 } else { 1028 for (; repcount; repcount--) 1029 pci_config_wr64(hdlp, host_addr++, *dev_addr); 1030 } 1031 } 1032 1033 1034 /* 1035 * When retrofitting this module for pci_tools, functions such as open, close, 1036 * and ioctl are now pulled into this module. Before this, the functions in 1037 * the pcihp module were referenced directly. Now they are called or 1038 * referenced through the pcihp cb_ops structure from functions in this module. 1039 */ 1040 1041 static int 1042 pci_open(dev_t *devp, int flags, int otyp, cred_t *credp) 1043 { 1044 return ((pcihp_get_cb_ops())->cb_open(devp, flags, otyp, credp)); 1045 } 1046 1047 static int 1048 pci_close(dev_t dev, int flags, int otyp, cred_t *credp) 1049 { 1050 return ((pcihp_get_cb_ops())->cb_close(dev, flags, otyp, credp)); 1051 } 1052 1053 static int 1054 pci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp) 1055 { 1056 minor_t minor = getminor(dev); 1057 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor); 1058 pci_state_t *pci_p = ddi_get_soft_state(pci_statep, instance); 1059 1060 if (pci_p == NULL) 1061 return (ENXIO); 1062 1063 return (pci_common_ioctl(pci_p->pci_dip, 1064 dev, cmd, arg, mode, credp, rvalp)); 1065 } 1066 1067 1068 static int 1069 pci_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, 1070 int flags, char *name, caddr_t valuep, int *lengthp) 1071 { 1072 return ((pcihp_get_cb_ops())->cb_prop_op(dev, dip, prop_op, flags, 1073 name, valuep, lengthp)); 1074 } 1075 1076 static int 1077 pci_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 1078 { 1079 return (pcihp_info(dip, cmd, arg, result)); 1080 } 1081