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