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 * Intel 21554 PCI to PCI bus bridge nexus driver for sun4u platforms. 31 * Please note that 21554 is not a transparent bridge. 32 * This driver can be used when the 21554 bridge is used like a 33 * transparent bridge. The host OBP or the OS PCI Resource Allocator 34 * (during a hotplug/hotswap operation) must represent this device 35 * as a nexus and do the device tree representation of the child 36 * nodes underneath. 37 * Interrupt routing of the children must be done as per the PCI 38 * specifications recommendation similar to that of a transparent 39 * bridge. 40 * Address translations from secondary across primary can be 1:1 41 * or non 1:1. Currently only 1:1 translations are supported. 42 * Configuration cycles are indirect. Memory and IO cycles are direct. 43 */ 44 45 /* 46 * INCLUDES 47 */ 48 #include <sys/stat.h> 49 #include <sys/conf.h> 50 #include <sys/kmem.h> 51 #include <sys/debug.h> 52 #include <sys/modctl.h> 53 #include <sys/autoconf.h> 54 #include <sys/ddi_impldefs.h> 55 #include <sys/ddi_subrdefs.h> 56 #include <sys/pci.h> 57 #include <sys/pci/pci_nexus.h> 58 #include <sys/pci/pci_regs.h> 59 #include <sys/pci/db21554_config.h> /* 21554 configuration space registers */ 60 #include <sys/pci/db21554_csr.h> /* 21554 control status register layout */ 61 #include <sys/pci/db21554_ctrl.h> /* driver private control structure */ 62 #include <sys/pci/db21554_debug.h> /* driver debug declarations */ 63 #include <sys/ddi.h> 64 #include <sys/sunddi.h> 65 #include <sys/sunndi.h> 66 #include <sys/fm/protocol.h> 67 #include <sys/ddifm.h> 68 #include <sys/promif.h> 69 #include <sys/file.h> 70 #include <sys/hotplug/pci/pcihp.h> 71 72 /* 73 * DEFINES. 74 */ 75 #define DB_DEBUG 76 #define DB_MODINFO_DESCRIPTION "Intel/21554 pci-pci nexus:v%I%" 77 #define DB_DVMA_START 0xc0000000 78 #define DB_DVMA_LEN 0x20000000 79 80 #ifdef DB_DEBUG 81 /* ioctl definitions */ 82 #define DB_PCI_READ_CONF_HEADER 1 83 #define DEF_INVALID_REG_VAL -1 84 85 /* Default values for secondary cache line and latency timer */ 86 #define DB_SEC_LATENCY_TIMER_VAL 0x40 87 #define DB_SEC_CACHELN_SIZE_VAL 0x10 88 89 /* complete chip status information */ 90 typedef struct db_pci_data { 91 char name[256]; 92 uint32_t instance; 93 db_pci_header_t pri_hdr; 94 db_pci_header_t sec_hdr; 95 db_conf_regs_t conf_regs; 96 } db_pci_data_t; 97 #endif 98 99 /* 100 * LOCALS 101 */ 102 103 /* 104 * The next set of variables are control parameters for debug purposes only. 105 * Changing the default values as assigned below are not recommended. 106 * In some cases, the non-default values are mostly application specific and 107 * hence may not have been tested yet. 108 * 109 * db_conf_map_mode : specifies the access method used for generating 110 * configuration cycles. Default value indicates 111 * the indirect configuration method. 112 * db_io_map_mode : specifies the access method used for generating 113 * IO cycles. Default value indicates the direct 114 * method. 115 * db_pci_own_wait : For indirect cycles, indicates the wait period 116 * for acquiring the bus, when the bus is busy. 117 * db_pci_release_wait:For indirect cycles, indicates the wait period 118 * for releasing the bus when the bus is busy. 119 * db_pci_max_wait : max. wait time when bus is busy for indirect cycles 120 * db_set_latency_timer_register : 121 * when 1, the driver overwrites the OBP assigned 122 * latency timer register setting for every child 123 * device during child initialization. 124 * db_set_cache_line_size_register : 125 * when 1, the driver overwrites the OBP assigned 126 * cache line register setting for every child 127 * device during child initialization. 128 * db_use_config_own_bit: 129 * when 1, the driver will use the "config own bit" 130 * for accessing the configuration address and data 131 * registers. 132 */ 133 static uint32_t db_pci_own_wait = DB_PCI_WAIT_MS; 134 static uint32_t db_pci_release_wait = DB_PCI_WAIT_MS; 135 static uint32_t db_pci_max_wait = DB_PCI_TIMEOUT; 136 static uint32_t db_conf_map_mode = DB_CONF_MAP_INDIRECT_CONF; 137 static uint32_t db_io_map_mode = DB_IO_MAP_DIRECT; 138 static uint32_t db_set_latency_timer_register = 1; 139 static uint32_t db_set_cache_line_size_register = 1; 140 static uint32_t db_use_config_own_bit = 0; 141 142 /* 143 * Properties that can be set via .conf files. 144 */ 145 146 /* 147 * By default, we forward SERR# from secondary to primary. This behavior 148 * can be controlled via a property "serr-fwd-enable", type integer. 149 * Values are 0 or 1. 150 * 0 means 'do not forward SERR#'. 151 * 1 means forwards SERR# to the host. Should be the default. 152 */ 153 static uint32_t db_serr_fwd_enable = 1; 154 155 /* 156 * The next set of parameters are performance tuning parameters. 157 * These are in the form of properties settable through a .conf file. 158 * In case if the properties are absent the following defaults are assumed. 159 * These initial default values can be overwritten via /etc/system also. 160 * 161 * -1 means no setting is done ie. we either get OBP assigned value 162 * or reset values (at hotplug time for example). 163 */ 164 165 /* primary latency timer: property "p-latency-timer" : type integer */ 166 static int8_t p_latency_timer = DEF_INVALID_REG_VAL; 167 168 /* secondary latency timer: property "s-latency-timer": type integer */ 169 /* 170 * Currently on the secondary side the latency timer is not 171 * set by the serial PROM which causes performance degradation. 172 * Set the secondary latency timer register. 173 */ 174 static int8_t s_latency_timer = DB_SEC_LATENCY_TIMER_VAL; 175 176 /* primary cache line size: property "p-cache-line-size" : type integer */ 177 static int8_t p_cache_line_size = DEF_INVALID_REG_VAL; 178 179 /* secondary cache line size: property "s-cache-line-size" : type integer */ 180 /* 181 * Currently on the secondary side the cache line size is not 182 * set by the serial PROM which causes performance degradation. 183 * Set the secondary cache line size register. 184 */ 185 static int8_t s_cache_line_size = DB_SEC_CACHELN_SIZE_VAL; 186 187 /* 188 * control primary posted write queue threshold limit: 189 * property "p-pwrite-threshold" : type integer : values are 0 or 1. 190 * 1 enables control. 0 does not, and is the default reset value. 191 */ 192 static int8_t p_pwrite_threshold = DEF_INVALID_REG_VAL; 193 194 /* 195 * control secondary posted write queue threshold limit: 196 * property "s-pwrite-threshold" : type integer : values are 0 or 1. 197 * 1 enables control. 0 does not, and is the default reset value. 198 */ 199 static int8_t s_pwrite_threshold = DEF_INVALID_REG_VAL; 200 201 /* 202 * control read queue threshold for initiating delayed read transaction 203 * on primary bus. 204 * property "p-dread-threshold" : type integer: values are 205 * 206 * 0 : reset value, default behavior: at least 8DWords free for all MR 207 * 1 : reserved 208 * 2 : at least one cache line free for MRL and MRM, 8 DWords free for MR 209 * 3 : at least one cache line free for all MR 210 */ 211 static int8_t p_dread_threshold = DEF_INVALID_REG_VAL; 212 213 /* 214 * control read queue threshold for initiating delayed read transaction 215 * on secondary bus. 216 * property "s-dread-threshold" : type integer: values are 217 * 218 * 0 : reset value, default behavior: at least 8DWords free for all MR 219 * 1 : reserved 220 * 2 : at least one cache line free for MRL and MRM, 8 DWords free for MR 221 * 3 : at least one cache line free for all MR 222 */ 223 static int8_t s_dread_threshold = DEF_INVALID_REG_VAL; 224 225 /* 226 * control how 21554 issues delayed transactions on the target bus. 227 * property "delayed-trans-order" : type integer: values are 0 or 1. 228 * 1 means repeat transaction on same target on target retries. 229 * 0 is the reset/default value, and means enable round robin based 230 * reads on other targets in read queue on any target retries. 231 */ 232 static int8_t delayed_trans_order = DEF_INVALID_REG_VAL; 233 234 /* 235 * In case if the system DVMA information is not available, as it is 236 * prior to s28q1, the system dvma range can be set via these parameters. 237 */ 238 static uint32_t db_dvma_start = DB_DVMA_START; 239 static uint32_t db_dvma_len = DB_DVMA_LEN; 240 241 /* 242 * Default command register settings for all PCI nodes this nexus initializes. 243 */ 244 static uint16_t db_command_default = 245 PCI_COMM_SERR_ENABLE | 246 PCI_COMM_PARITY_DETECT | 247 PCI_COMM_ME | 248 PCI_COMM_MAE | 249 PCI_COMM_IO | 250 PCI_COMM_BACK2BACK_ENAB | 251 PCI_COMM_MEMWR_INVAL; 252 253 static int db_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 254 static int db_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 255 static void db_get_perf_parameters(db_ctrl_t *dbp); 256 static void db_set_perf_parameters(db_ctrl_t *dbp); 257 static void db_enable_io(db_ctrl_t *dbp); 258 static void db_orientation(db_ctrl_t *dbp); 259 static void db_set_dvma_range(db_ctrl_t *dbp); 260 static int db_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 261 void **result); 262 static int db_pci_map(dev_info_t *, dev_info_t *, ddi_map_req_t *, 263 off_t, off_t, caddr_t *); 264 static int db_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, 265 void *, void *); 266 static int db_intr_ops(dev_info_t *dip, dev_info_t *rdip, 267 ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, 268 void *result); 269 static dev_info_t *db_get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip); 270 static int db_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap, 271 ddi_iblock_cookie_t *ibc); 272 static void db_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle); 273 static void db_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle); 274 275 struct bus_ops db_bus_ops = { 276 BUSO_REV, 277 db_pci_map, 278 0, 279 0, 280 0, 281 i_ddi_map_fault, 282 ddi_dma_map, 283 ddi_dma_allochdl, 284 ddi_dma_freehdl, 285 ddi_dma_bindhdl, 286 ddi_dma_unbindhdl, 287 ddi_dma_flush, 288 ddi_dma_win, 289 ddi_dma_mctl, 290 db_ctlops, 291 ddi_bus_prop_op, 292 ndi_busop_get_eventcookie, 293 ndi_busop_add_eventcall, 294 ndi_busop_remove_eventcall, 295 ndi_post_event, 296 0, 297 0, 298 0, 299 db_fm_init_child, 300 NULL, 301 db_bus_enter, 302 db_bus_exit, 303 0, 304 db_intr_ops 305 }; 306 307 static int db_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p); 308 static int db_close(dev_t dev, int flag, int otyp, cred_t *cred_p); 309 static int db_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, 310 cred_t *cred_p, int *rval_p); 311 #ifdef DB_DEBUG 312 static dev_info_t *db_lookup_child_name(db_ctrl_t *dbp, char *name, 313 int instance); 314 static void db_pci_get_header(ddi_acc_handle_t config_handle, 315 db_pci_header_t *ph, off_t hdr_off); 316 static void db_pci_get_conf_regs(ddi_acc_handle_t config_handle, 317 db_conf_regs_t *cr); 318 #endif /* DB_DEBUG */ 319 320 #ifdef DEBUG 321 static void 322 db_debug(uint64_t func_id, dev_info_t *dip, char *fmt, 323 uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5); 324 #endif 325 326 static int db_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, 327 int flags, char *name, caddr_t valuep, int *lengthp); 328 329 static struct cb_ops db_cb_ops = { 330 db_open, /* open */ 331 db_close, /* close */ 332 nulldev, /* strategy */ 333 nulldev, /* print */ 334 nulldev, /* dump */ 335 nulldev, /* read */ 336 nulldev, /* write */ 337 db_ioctl, /* ioctl */ 338 nodev, /* devmap */ 339 nodev, /* mmap */ 340 nodev, /* segmap */ 341 nochpoll, /* poll */ 342 db_prop_op, /* cb_prop_op */ 343 NULL, /* streamtab */ 344 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */ 345 CB_REV, /* rev */ 346 nodev, /* int (*cb_aread)() */ 347 nodev /* int (*cb_awrite)() */ 348 }; 349 350 static uint8_t db_ddi_get8(ddi_acc_impl_t *handle, uint8_t *addr); 351 static uint16_t db_ddi_get16(ddi_acc_impl_t *handle, uint16_t *addr); 352 static uint32_t db_ddi_get32(ddi_acc_impl_t *handle, uint32_t *addr); 353 static uint64_t db_ddi_get64(ddi_acc_impl_t *handle, uint64_t *addr); 354 static void db_ddi_put8(ddi_acc_impl_t *handle, uint8_t *addr, 355 uint8_t data); 356 static void db_ddi_put16(ddi_acc_impl_t *handle, uint16_t *addr, 357 uint16_t data); 358 static void db_ddi_put32(ddi_acc_impl_t *handle, uint32_t *addr, 359 uint32_t data); 360 static void db_ddi_put64(ddi_acc_impl_t *handle, uint64_t *addr, 361 uint64_t data); 362 static void db_ddi_rep_get8(ddi_acc_impl_t *handle, uint8_t *host_addr, 363 uint8_t *dev_addr, size_t repcount, uint_t flags); 364 static void db_ddi_rep_get16(ddi_acc_impl_t *handle, uint16_t *host_addr, 365 uint16_t *dev_addr, size_t repcount, uint_t flags); 366 static void db_ddi_rep_get32(ddi_acc_impl_t *handle, uint32_t *host_addr, 367 uint32_t *dev_addr, size_t repcount, uint_t flags); 368 static void db_ddi_rep_get64(ddi_acc_impl_t *handle, uint64_t *host_addr, 369 uint64_t *dev_addr, size_t repcount, uint_t flags); 370 static void db_ddi_rep_put8(ddi_acc_impl_t *handle, uint8_t *host_addr, 371 uint8_t *dev_addr, size_t repcount, uint_t flags); 372 static void db_ddi_rep_put16(ddi_acc_impl_t *handle, uint16_t *host_addr, 373 uint16_t *dev_addr, size_t repcount, uint_t flags); 374 static void db_ddi_rep_put32(ddi_acc_impl_t *handle, uint32_t *host_addr, 375 uint32_t *dev_addr, size_t repcount, uint_t flags); 376 static void db_ddi_rep_put64(ddi_acc_impl_t *handle, uint64_t *host_addr, 377 uint64_t *dev_addr, size_t repcount, uint_t flags); 378 379 static struct dev_ops db_dev_ops = { 380 DEVO_REV, /* devo_rev */ 381 0, /* refcnt */ 382 db_getinfo, /* info */ 383 nulldev, /* identify */ 384 nulldev, /* probe */ 385 db_attach, /* attach */ 386 db_detach, /* detach */ 387 nulldev, /* reset */ 388 &db_cb_ops, /* driver operations */ 389 &db_bus_ops, /* bus operations */ 390 ddi_power 391 }; 392 393 394 /* 395 * Module linkage information for the kernel. 396 */ 397 398 static struct modldrv modldrv = { 399 &mod_driverops, /* Type of module */ 400 DB_MODINFO_DESCRIPTION, 401 &db_dev_ops /* driver ops */ 402 }; 403 404 static struct modlinkage modlinkage = { 405 MODREV_1, 406 (void *)&modldrv, 407 NULL 408 }; 409 410 /* soft state pointer and structure template. */ 411 static void *db_state; 412 413 /* 414 * forward function declarations: 415 */ 416 static void db_uninitchild(dev_info_t *); 417 static int db_initchild(dev_info_t *child); 418 static int db_create_pci_prop(dev_info_t *child); 419 static int db_save_config_regs(db_ctrl_t *dbp); 420 static int db_restore_config_regs(db_ctrl_t *dbp); 421 422 /* 423 * FMA error callback 424 * Register error handling callback with our parent. We will just call 425 * our children's error callbacks and return their status. 426 */ 427 static int db_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, 428 const void *impl_data); 429 430 /* 431 * init/fini routines to alloc/dealloc fm structures and 432 * register/unregister our callback. 433 */ 434 static void db_fm_init(db_ctrl_t *db_p); 435 static void db_fm_fini(db_ctrl_t *db_p); 436 437 int 438 _init(void) 439 { 440 int rc; 441 442 DB_DEBUG0(DB_INIT|DB_DONT_DISPLAY_DIP, NULL, "enter\n"); 443 if (((rc = ddi_soft_state_init(&db_state, 444 sizeof (db_ctrl_t), 1)) == 0) && 445 ((rc = mod_install(&modlinkage)) != 0)) 446 ddi_soft_state_fini(&db_state); 447 DB_DEBUG1(DB_INIT|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc); 448 return (rc); 449 } 450 451 452 int 453 _fini(void) 454 { 455 int rc; 456 457 DB_DEBUG0(DB_FINI|DB_DONT_DISPLAY_DIP, NULL, "enter\n"); 458 if ((rc = mod_remove(&modlinkage)) == 0) 459 ddi_soft_state_fini(&db_state); 460 DB_DEBUG1(DB_FINI|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc); 461 return (rc); 462 } 463 464 int 465 _info(struct modinfo *modinfop) 466 { 467 int rc; 468 rc = mod_info(&modlinkage, modinfop); 469 DB_DEBUG1(DB_INFO|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc); 470 return (rc); 471 } 472 473 /*ARGSUSED*/ 474 static int 475 db_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 476 { 477 db_ctrl_t *dbp; 478 int rc = DDI_FAILURE; 479 minor_t minor = getminor((dev_t)arg); 480 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor); 481 482 DB_DEBUG1(DB_GETINFO|DB_DONT_DISPLAY_DIP, dip, "enter:cmd=%d\n", 483 infocmd); 484 485 switch (infocmd) { 486 case DDI_INFO_DEVT2DEVINFO: 487 488 if ((dbp = ddi_get_soft_state(db_state, 489 instance)) != NULL) { 490 *result = dbp->dip; 491 rc = DDI_SUCCESS; 492 } else 493 *result = NULL; 494 break; 495 496 case DDI_INFO_DEVT2INSTANCE: 497 *result = (void *)(uintptr_t)instance; 498 rc = DDI_SUCCESS; 499 break; 500 501 default: 502 break; 503 } 504 DB_DEBUG2(DB_GETINFO|DB_DONT_DISPLAY_DIP, dip, 505 "exit: result=%x, rc=%d\n", *result, rc); 506 507 return (rc); 508 } 509 510 static int 511 db_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 512 { 513 int instance = ddi_get_instance(dip); 514 db_ctrl_t *dbp; 515 int rc = DDI_SUCCESS; 516 ddi_device_acc_attr_t db_csr_attr = { /* CSR map attributes */ 517 DDI_DEVICE_ATTR_V0, 518 DDI_STRUCTURE_LE_ACC, 519 DDI_STRICTORDER_ACC 520 }; 521 off_t bar_size; 522 int range_size; 523 char name[32]; 524 525 DB_DEBUG1(DB_ATTACH, dip, "enter: cmd=%d\n", cmd); 526 switch (cmd) { 527 528 case DDI_ATTACH: 529 if (ddi_soft_state_zalloc(db_state, instance) != DDI_SUCCESS) { 530 rc = DDI_FAILURE; 531 break; 532 } 533 534 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 535 536 dbp->dip = dip; 537 mutex_init(&dbp->db_mutex, NULL, MUTEX_DRIVER, NULL); 538 dbp->db_soft_state = DB_SOFT_STATE_CLOSED; 539 540 /* 541 * Cannot use pci_config_setup here as we'd need 542 * to get a pointer to the address map to be able 543 * to set the bus private handle during child map 544 * operation. 545 */ 546 if ((rc = ddi_regs_map_setup(dip, DB_PCI_CONF_RNUMBER, 547 (caddr_t *)&dbp->conf_io, DB_PCI_CONF_OFFSET, 548 PCI_CONF_HDR_SIZE, &db_csr_attr, &dbp->conf_handle)) 549 != DDI_SUCCESS) { 550 551 cmn_err(CE_WARN, 552 "%s#%d: cannot map configuration space", 553 ddi_driver_name(dip), ddi_get_instance(dip)); 554 mutex_destroy(&dbp->db_mutex); 555 ddi_soft_state_free(db_state, instance); 556 rc = DDI_FAILURE; 557 break; 558 } 559 560 db_get_perf_parameters(dbp); 561 562 if (ddi_dev_regsize(dip, DB_CSR_MEMBAR_RNUMBER, &bar_size) 563 != DDI_SUCCESS) { 564 cmn_err(CE_WARN, "%s#%d: cannot get memory CSR size", 565 ddi_driver_name(dbp->dip), 566 ddi_get_instance(dbp->dip)); 567 ddi_regs_map_free(&dbp->conf_handle); 568 mutex_destroy(&dbp->db_mutex); 569 ddi_soft_state_free(db_state, instance); 570 rc = DDI_FAILURE; 571 break; 572 } 573 574 /* map memory CSR space */ 575 if (ddi_regs_map_setup(dip, DB_CSR_MEMBAR_RNUMBER, 576 (caddr_t *)&dbp->csr_mem, DB_CSR_MEM_OFFSET, bar_size, 577 &db_csr_attr, &dbp->csr_mem_handle) != DDI_SUCCESS) { 578 579 cmn_err(CE_WARN, "%s#%d: cannot map memory CSR space", 580 ddi_driver_name(dbp->dip), 581 ddi_get_instance(dbp->dip)); 582 ddi_regs_map_free(&dbp->conf_handle); 583 mutex_destroy(&dbp->db_mutex); 584 ddi_soft_state_free(db_state, instance); 585 rc = DDI_FAILURE; 586 break; 587 } 588 589 if (ddi_dev_regsize(dip, DB_CSR_IOBAR_RNUMBER, &bar_size) 590 != DDI_SUCCESS) { 591 cmn_err(CE_WARN, "%s#%d: cannot get IO CSR size", 592 ddi_driver_name(dbp->dip), 593 ddi_get_instance(dbp->dip)); 594 ddi_regs_map_free(&dbp->csr_mem_handle); 595 ddi_regs_map_free(&dbp->conf_handle); 596 mutex_destroy(&dbp->db_mutex); 597 ddi_soft_state_free(db_state, instance); 598 rc = DDI_FAILURE; 599 break; 600 } 601 602 /* 603 * map IO CSR space. We need this map to initiate 604 * indirect configuration transactions as this is a better 605 * option than doing through configuration space map. 606 */ 607 if (ddi_regs_map_setup(dip, DB_CSR_IOBAR_RNUMBER, 608 (caddr_t *)&dbp->csr_io, DB_CSR_IO_OFFSET, bar_size, 609 &db_csr_attr, &dbp->csr_io_handle) != DDI_SUCCESS) { 610 611 cmn_err(CE_WARN, "%s#%d: cannot map IO CSR space", 612 ddi_driver_name(dbp->dip), 613 ddi_get_instance(dbp->dip)); 614 ddi_regs_map_free(&dbp->csr_mem_handle); 615 ddi_regs_map_free(&dbp->conf_handle); 616 mutex_destroy(&dbp->db_mutex); 617 ddi_soft_state_free(db_state, instance); 618 rc = DDI_FAILURE; 619 break; 620 } 621 622 db_orientation(dbp); 623 624 if (dbp->dev_state & DB_SECONDARY_NEXUS) { 625 if (pcihp_init(dip) != DDI_SUCCESS) 626 cmn_err(CE_WARN, 627 "%s#%d: could not register with hotplug", 628 ddi_driver_name(dbp->dip), 629 ddi_get_instance(dbp->dip)); 630 } else { 631 /* 632 * create minor node for devctl interfaces 633 */ 634 if (ddi_create_minor_node(dip, "devctl", S_IFCHR, 635 PCIHP_AP_MINOR_NUM(instance, PCIHP_DEVCTL_MINOR), 636 DDI_NT_NEXUS, 0) != DDI_SUCCESS) { 637 ddi_regs_map_free(&dbp->csr_io_handle); 638 ddi_regs_map_free(&dbp->csr_mem_handle); 639 ddi_regs_map_free(&dbp->conf_handle); 640 mutex_destroy(&dbp->db_mutex); 641 ddi_soft_state_free(db_state, instance); 642 rc = DDI_FAILURE; 643 break; 644 } 645 } 646 647 db_enable_io(dbp); 648 649 range_size = sizeof (dbp->range); 650 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 651 DDI_PROP_DONTPASS, "bus-range", (caddr_t)&dbp->range, 652 &range_size) != DDI_SUCCESS) { 653 654 cmn_err(CE_WARN, 655 "%s#%d: cannot get bus-range property", 656 ddi_driver_name(dip), ddi_get_instance(dip)); 657 658 if (dbp->dev_state & DB_SECONDARY_NEXUS) 659 (void) pcihp_uninit(dip); 660 else 661 ddi_remove_minor_node(dip, "devctl"); 662 663 ddi_regs_map_free(&dbp->csr_mem_handle); 664 ddi_regs_map_free(&dbp->csr_io_handle); 665 ddi_regs_map_free(&dbp->conf_handle); 666 mutex_destroy(&dbp->db_mutex); 667 ddi_soft_state_free(db_state, instance); 668 rc = DDI_FAILURE; 669 break; 670 } 671 672 (void) sprintf(name, "%d", instance); 673 674 if (ddi_create_minor_node(dip, name, S_IFCHR, 675 PCIHP_AP_MINOR_NUM(instance, PCIHP_DEBUG_MINOR), 676 NULL, NULL) == DDI_FAILURE) { 677 cmn_err(CE_NOTE, "%s#%d: node creation failure", 678 ddi_driver_name(dbp->dip), instance); 679 } 680 681 mutex_init(&dbp->db_busown, NULL, MUTEX_DRIVER, NULL); 682 683 db_fm_init(dbp); 684 ddi_report_dev(dip); 685 dbp->dev_state |= DB_ATTACHED; 686 687 break; 688 689 case DDI_RESUME: 690 691 /* 692 * Get the soft state structure for the bridge. 693 */ 694 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 695 db_enable_io(dbp); 696 (void) db_restore_config_regs(dbp); 697 dbp->dev_state &= ~DB_SUSPENDED; 698 break; 699 700 default: 701 rc = DDI_FAILURE; /* not supported yet */ 702 break; 703 } 704 705 DB_DEBUG1(DB_ATTACH, dip, "exit: rc=%d\n", rc); 706 return (rc); 707 } 708 709 static int 710 db_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 711 { 712 int instance = ddi_get_instance(dip); 713 db_ctrl_t *dbp; 714 int rc = DDI_SUCCESS; 715 char name[32]; 716 717 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 718 719 DB_DEBUG1(DB_DETACH, dip, "enter: cmd=%d\n", cmd); 720 721 switch (cmd) { 722 723 case DDI_DETACH : 724 db_fm_fini(dbp); 725 if (dbp->dev_state & DB_SECONDARY_NEXUS) 726 if (pcihp_uninit(dip) == DDI_FAILURE) 727 return (DDI_FAILURE); 728 else 729 ddi_remove_minor_node(dip, "devctl"); 730 731 mutex_destroy(&dbp->db_busown); 732 ddi_regs_map_free(&dbp->csr_mem_handle); 733 ddi_regs_map_free(&dbp->csr_io_handle); 734 735 ddi_regs_map_free(&dbp->conf_handle); 736 dbp->dev_state &= ~DB_ATTACHED; 737 (void) sprintf(name, "%d", instance); 738 ddi_remove_minor_node(dip, name); 739 mutex_destroy(&dbp->db_mutex); 740 ddi_soft_state_free(db_state, instance); 741 break; 742 743 case DDI_SUSPEND : 744 if (db_save_config_regs(dbp) != DDI_SUCCESS) { 745 cmn_err(CE_WARN, 746 "%s#%d: Ignoring Child state Suspend Error", 747 ddi_driver_name(dbp->dip), 748 ddi_get_instance(dbp->dip)); 749 } 750 dbp->dev_state |= DB_SUSPENDED; 751 break; 752 753 default : 754 rc = DDI_FAILURE; 755 break; 756 } 757 758 DB_DEBUG1(DB_DETACH, dip, "exit: rc=%d\n", rc); 759 return (rc); 760 } 761 762 static void 763 db_get_perf_parameters(db_ctrl_t *dbp) 764 { 765 dbp->p_latency_timer = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 766 dbp->dip, 0, "p-latency-timer", p_latency_timer); 767 dbp->s_latency_timer = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 768 dbp->dip, 0, "s-latency-timer", s_latency_timer); 769 dbp->p_cache_line_size = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 770 dbp->dip, 0, "p-cache-line-size", p_cache_line_size); 771 dbp->s_cache_line_size = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 772 dbp->dip, 0, "s-cache-line-size", s_cache_line_size); 773 dbp->p_pwrite_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 774 dbp->dip, 0, "p-pwrite-threshold", p_pwrite_threshold); 775 dbp->s_pwrite_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 776 dbp->dip, 0, "s-pwrite-threshold", s_pwrite_threshold); 777 dbp->p_dread_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 778 dbp->dip, 0, "p-dread-threshold", p_dread_threshold); 779 dbp->s_dread_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 780 dbp->dip, 0, "s-dread-threshold", s_dread_threshold); 781 dbp->delayed_trans_order = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 782 dbp->dip, 0, "delayed-trans-order", delayed_trans_order); 783 } 784 785 static void 786 db_set_perf_parameters(db_ctrl_t *dbp) 787 { 788 uint_t poffset = 0, soffset = 0; 789 790 if (dbp->dev_state & DB_SECONDARY_NEXUS) 791 poffset = DB_SCONF_PRI_HDR_OFF; 792 else 793 soffset = DB_PCONF_SEC_HDR_OFF; 794 795 if ((dbp->p_latency_timer != (int8_t)DEF_INVALID_REG_VAL) && 796 (dbp->p_latency_timer != -1)) 797 ddi_put8(dbp->conf_handle, 798 (uint8_t *)dbp->conf_io+poffset+PCI_CONF_LATENCY_TIMER, 799 dbp->p_latency_timer); 800 if ((dbp->s_latency_timer != (int8_t)DEF_INVALID_REG_VAL) && 801 (dbp->s_latency_timer != -1)) 802 ddi_put8(dbp->conf_handle, 803 (uint8_t *)dbp->conf_io+soffset+PCI_CONF_LATENCY_TIMER, 804 dbp->s_latency_timer); 805 if ((dbp->p_cache_line_size != (int8_t)DEF_INVALID_REG_VAL) && 806 (dbp->p_cache_line_size != -1)) 807 ddi_put8(dbp->conf_handle, 808 (uint8_t *)dbp->conf_io+poffset+PCI_CONF_CACHE_LINESZ, 809 dbp->p_cache_line_size); 810 if ((dbp->s_cache_line_size != (int8_t)DEF_INVALID_REG_VAL) && 811 (dbp->s_cache_line_size != -1)) 812 ddi_put8(dbp->conf_handle, 813 (uint8_t *)dbp->conf_io+soffset+PCI_CONF_CACHE_LINESZ, 814 dbp->s_cache_line_size); 815 if ((dbp->p_pwrite_threshold != (int8_t)DEF_INVALID_REG_VAL) && 816 (dbp->p_pwrite_threshold != -1)) 817 ddi_put16(dbp->conf_handle, (uint16_t *) 818 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1), 819 (ddi_get16(dbp->conf_handle, (uint16_t *) 820 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) & 821 ~P_PW_THRESHOLD) | 822 (dbp->p_pwrite_threshold?P_PW_THRESHOLD:0)); 823 if ((dbp->s_pwrite_threshold != (int8_t)DEF_INVALID_REG_VAL) && 824 (dbp->s_pwrite_threshold != -1)) 825 ddi_put16(dbp->conf_handle, (uint16_t *) 826 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1), 827 (ddi_get16(dbp->conf_handle, (uint16_t *) 828 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) & 829 ~S_PW_THRESHOLD) | 830 (dbp->s_pwrite_threshold?S_PW_THRESHOLD:0)); 831 /* primary delayed read threshold. 0x01 is reserved ?. */ 832 if ((dbp->p_dread_threshold != (int8_t)DEF_INVALID_REG_VAL) && 833 (dbp->p_dread_threshold != -1)) 834 ddi_put16(dbp->conf_handle, (uint16_t *) 835 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1), 836 ((ddi_get16(dbp->conf_handle, (uint16_t *) 837 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) & 838 ~P_DREAD_THRESHOLD_MASK) | 839 ((dbp->p_dread_threshold & 840 DREAD_THRESHOLD_VALBITS)<<2))); 841 /* secondary delayed read threshold. 0x01 is reserved ?. */ 842 if ((dbp->s_dread_threshold != (int8_t)DEF_INVALID_REG_VAL) && 843 (dbp->s_dread_threshold != -1)) 844 ddi_put16(dbp->conf_handle, (uint16_t *) 845 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1), 846 ((ddi_get16(dbp->conf_handle, (uint16_t *) 847 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) & 848 ~S_DREAD_THRESHOLD_MASK) | 849 ((dbp->s_dread_threshold & 850 DREAD_THRESHOLD_VALBITS)<<4))); 851 if ((dbp->delayed_trans_order != (int8_t)DEF_INVALID_REG_VAL) && 852 (dbp->delayed_trans_order != -1)) 853 ddi_put16(dbp->conf_handle, (uint16_t *) 854 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL0), 855 (ddi_get16(dbp->conf_handle, (uint16_t *) 856 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL0)) & 857 ~DELAYED_TRANS_ORDER) | 858 (dbp->delayed_trans_order?DELAYED_TRANS_ORDER:0)); 859 } 860 861 static void 862 db_orientation(db_ctrl_t *dbp) 863 { 864 dev_info_t *dip = dbp->dip; 865 uint8_t pif; 866 uint32_t mem1; 867 uint32_t newval; 868 869 /* 870 * determine orientation of drawbridge and enable 871 * Upstream or Downstream path. 872 */ 873 874 /* 875 * if PIF is set correctly, use it to determine orientation 876 */ 877 pif = ddi_get8(dbp->conf_handle, (uchar_t *)dbp->conf_io + 878 PCI_CONF_PROGCLASS); 879 if (pif & 0xff) { 880 if (pif & DB_PIF_SECONDARY_TO_HOST) { 881 dbp->dev_state = DB_SECONDARY_NEXUS; 882 DB_DEBUG0(DB_ATTACH, dip, 883 "db_orientation: pif secondary\n"); 884 return; 885 } 886 if (pif & DB_PIF_PRIMARY_TO_HOST) { 887 dbp->dev_state = DB_PRIMARY_NEXUS; 888 DB_DEBUG0(DB_ATTACH, dip, 889 "db_orientation: pif primary\n"); 890 return; 891 } 892 /* otherwise, fall through */ 893 } 894 895 /* 896 * otherwise, test the chip directly by trying to write 897 * downstream mem1 setup register, only writeable from 898 * secondary. 899 */ 900 mem1 = ddi_get32(dbp->conf_handle, 901 (uint32_t *)((uchar_t *)dbp->conf_io + 902 DB_CONF_DS_IO_MEM1_SETUP)); 903 904 ddi_put32(dbp->conf_handle, 905 (uint32_t *)((uchar_t *)(dbp->conf_io + 906 DB_CONF_DS_IO_MEM1_SETUP)), ~mem1); 907 908 newval = ddi_get32(dbp->conf_handle, 909 (uint32_t *)((uchar_t *)dbp->conf_io + 910 DB_CONF_DS_IO_MEM1_SETUP)); 911 912 if (newval == mem1) 913 /* we couldn't write it, orientation is primary */ 914 dbp->dev_state = DB_PRIMARY_NEXUS; 915 else { 916 /* 917 * we could write it, therefore orientation secondary. 918 * restore mem1 value. 919 */ 920 dbp->dev_state = DB_SECONDARY_NEXUS; 921 ddi_put32(dbp->conf_handle, 922 (uint32_t *)((uchar_t *)(dbp->conf_io + 923 DB_CONF_DS_IO_MEM1_SETUP)), mem1); 924 } 925 926 927 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 928 DB_DEBUG0(DB_ATTACH, dip, "db_orientation: chip primary\n"); 929 } else { 930 DB_DEBUG0(DB_ATTACH, dip, "db_orientation: chip secondary\n"); 931 } 932 } 933 934 static void 935 db_enable_io(db_ctrl_t *dbp) 936 { 937 dev_info_t *dip = dbp->dip; 938 pci_regspec_t *reg; 939 int rcount, length, i; 940 uint32_t offset; 941 uint32_t p_offset, s_offset; 942 uint16_t regval; 943 uint16_t enable; 944 945 /* 946 * Step 0: 947 * setup the primary and secondary offset and enable 948 * values based on the orientation of 21554. 949 */ 950 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 951 DB_DEBUG0(DB_ATTACH, dip, "db_enable_io: primary\n"); 952 p_offset = 0; 953 s_offset = DB_SCONF_HDR_OFF; 954 enable = DS_ENABLE; 955 } else { 956 DB_DEBUG0(DB_ATTACH, dip, "db_enable_io: secondary\n"); 957 p_offset = DB_SCONF_HDR_OFF; 958 s_offset = 0; 959 enable = US_ENABLE; 960 } 961 962 db_set_perf_parameters(dbp); 963 db_set_dvma_range(dbp); 964 965 /* 966 * Step 1: 967 * setup latency timer and cache line size parameters 968 * which are used for child initialization. 969 */ 970 dbp->latency_timer = ddi_get8(dbp->conf_handle, (uint8_t *) 971 ((caddr_t)dbp->conf_io+PCI_CONF_LATENCY_TIMER)); 972 973 dbp->cache_line_size = ddi_get8(dbp->conf_handle, (uint8_t *) 974 ((caddr_t)dbp->conf_io+PCI_CONF_CACHE_LINESZ)); 975 976 DB_DEBUG2(DB_ATTACH, dip, 977 "db_enable_io: latency %d, cache line size %d\n", 978 dbp->latency_timer, dbp->cache_line_size); 979 980 /* 981 * Step 2: program command reg on both primary and secondary 982 * interfaces. 983 */ 984 ddi_put16(dbp->conf_handle, (uint16_t *)((caddr_t)dbp->conf_io + 985 (off_t)(p_offset + PCI_CONF_COMM)), db_command_default); 986 987 ddi_put16(dbp->conf_handle, (uint16_t *)((caddr_t)dbp->conf_io + 988 (off_t)(s_offset + PCI_CONF_COMM)), db_command_default); 989 990 /* 991 * Step 3: 992 * set up translated base registers, using the primary/ 993 * secondary interface pci configuration Base Address 994 * Registers (BAR's). 995 */ 996 997 /* mem0 translated base is setup for primary orientation only. */ 998 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 999 /* 1000 * And only if the 21554 device node property indicates 1001 * the size of base0 register to be larger than csr map 1002 * space, DB_CSR_SIZE=4K. 1003 * 1004 * Note : Setting up 1:1 translations only (for now:), i.e. 1005 * no look up table. 1006 */ 1007 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 1008 DDI_PROP_DONTPASS, "reg", (caddr_t)®, 1009 &length) != DDI_PROP_SUCCESS) { 1010 DB_DEBUG0(DB_ATTACH, dip, 1011 "Failed to read reg property\n"); 1012 return; 1013 } 1014 1015 /* Find device node's base0 reg property and check its size */ 1016 rcount = length / sizeof (pci_regspec_t); 1017 for (i = 0; i < rcount; i++) { 1018 offset = PCI_REG_REG_G(reg[i].pci_phys_hi); 1019 if ((offset == PCI_CONF_BASE0) && 1020 (reg[i].pci_size_low > DB_CSR_SIZE)) 1021 break; 1022 } 1023 1024 /* 1025 * set up mem0 translated base, if base0 register was 1026 * found and its size was larger than csr map space. 1027 */ 1028 if (i != rcount) { 1029 DB_DEBUG0(DB_ATTACH, dip, 1030 "db_enable_io: setting up MEM0_TR_BASE\n"); 1031 DB_DEBUG1(DB_ATTACH, dip, "BASE0 register = %x\n", 1032 pci_config_get32(dbp->conf_handle, 1033 (off_t)(p_offset + PCI_CONF_BASE0))); 1034 1035 pci_config_put32(dbp->conf_handle, 1036 (off_t)DB_CONF_DS_MEM0_TR_BASE, 1037 pci_config_get32(dbp->conf_handle, 1038 (off_t)(p_offset + PCI_CONF_BASE0))); 1039 1040 DB_DEBUG1(DB_ATTACH, dip, 1041 "db_enable_io: MEM0_TR_BASE set value = %x\n", 1042 pci_config_get32(dbp->conf_handle, 1043 (off_t)DB_CONF_DS_MEM0_TR_BASE)); 1044 } 1045 kmem_free(reg, length); 1046 } 1047 1048 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_IO_MEM1_TR_BASE, 1049 ((pci_config_get32(dbp->conf_handle, 1050 (off_t)(p_offset + PCI_CONF_BASE2))) & ~DB_IO_BIT)); 1051 1052 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_MEM2_TR_BASE, 1053 ((pci_config_get32(dbp->conf_handle, 1054 (off_t)(p_offset + PCI_CONF_BASE3))) & ~DB_IO_BIT)); 1055 1056 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_MEM3_TR_BASE, 1057 ((pci_config_get32(dbp->conf_handle, 1058 (off_t)(p_offset + PCI_CONF_BASE4))) & ~DB_IO_BIT)); 1059 1060 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_US_IO_MEM0_TR_BASE, 1061 ((pci_config_get32(dbp->conf_handle, 1062 (off_t)(s_offset + PCI_CONF_BASE2))) & ~DB_IO_BIT)); 1063 1064 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_US_MEM1_TR_BASE, 1065 ((pci_config_get32(dbp->conf_handle, 1066 (off_t)(s_offset + PCI_CONF_BASE3))) & ~DB_IO_BIT)); 1067 1068 /* 1069 * Step 4: enable downstream (for primary orientation) or upstream 1070 * (for secondary orientation) bits in Configuration Control 1071 * and Status register, if not already enabled. 1072 */ 1073 regval = pci_config_get16(dbp->conf_handle, (off_t)DB_CONF_CONF_CSR); 1074 1075 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: CSR value before: %x\n", 1076 regval); 1077 1078 if (!(regval & enable)) { 1079 /* enable down/upstream configuration transactions */ 1080 regval |= enable; 1081 pci_config_put16(dbp->conf_handle, (off_t)DB_CONF_CONF_CSR, 1082 regval); 1083 regval = pci_config_get16(dbp->conf_handle, 1084 (off_t)DB_CONF_CONF_CSR); 1085 } 1086 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: CSR value after: %x\n", 1087 regval); 1088 1089 /* 1090 * Step 5: enable downstream/upstream I/O (through CSR space) 1091 */ 1092 regval = ddi_get16(dbp->csr_mem_handle, 1093 (uint16_t *)((uchar_t *)dbp->csr_mem + DB_CSR_IO_CSR)); 1094 1095 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: IO_CSR value before: %x\n", 1096 regval); 1097 if (!(regval & enable)) { 1098 regval |= enable; 1099 ddi_put16(dbp->csr_mem_handle, 1100 (uint16_t *)((uchar_t *)dbp->csr_mem + 1101 DB_CSR_IO_CSR), regval); 1102 1103 regval = ddi_get16(dbp->csr_mem_handle, 1104 (uint16_t *)((uchar_t *)dbp->csr_mem + DB_CSR_IO_CSR)); 1105 } 1106 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: IO_CSR value after: %x\n", 1107 regval); 1108 1109 /* 1110 * Step 6: if 21554 orientation is primary to host, 1111 * forward SERR# to host. 1112 */ 1113 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 1114 dbp->serr_fwd_enable = ddi_prop_get_int(DDI_DEV_T_ANY, 1115 dbp->dip, 0, "serr-fwd-enable", db_serr_fwd_enable); 1116 1117 regval = ddi_get16(dbp->conf_handle, 1118 (uint16_t *)((uchar_t *)dbp->conf_io + 1119 DB_CONF_CHIP_CTRL0)); 1120 1121 DB_DEBUG1(DB_ATTACH, dip, 1122 "db_enable_io: CHIP_CTRL0 value before: %x\n", regval); 1123 1124 ddi_put16(dbp->conf_handle, 1125 (uint16_t *)((uchar_t *)dbp->conf_io + 1126 DB_CONF_CHIP_CTRL0), 1127 (regval & ~SERR_FWD) | 1128 (dbp->serr_fwd_enable?SERR_FWD:0)); 1129 1130 regval = ddi_get16(dbp->conf_handle, 1131 (uint16_t *)((uchar_t *)dbp->conf_io + 1132 DB_CONF_CHIP_CTRL0)); 1133 1134 DB_DEBUG1(DB_ATTACH, dip, 1135 "db_enable_io: CHIP_CTRL0 value after: %x\n", regval); 1136 } 1137 1138 /* 1139 * Step 7: if orientation is secondary, make sure primary lockout 1140 * disable is reset. 1141 */ 1142 1143 if (dbp->dev_state & DB_SECONDARY_NEXUS) { 1144 regval = pci_config_get16(dbp->conf_handle, 1145 (off_t)DB_CONF_CHIP_CTRL0); 1146 DB_DEBUG1(DB_ATTACH, dip, 1147 "db_enable_io: chip ctrl (0x%x) before\n", regval); 1148 if (regval & PLOCKOUT) 1149 pci_config_put16(dbp->conf_handle, 1150 (off_t)DB_CONF_CHIP_CTRL0, 1151 (regval & ~PLOCKOUT)); 1152 regval = pci_config_get16(dbp->conf_handle, 1153 (off_t)DB_CONF_CHIP_CTRL0); 1154 DB_DEBUG1(DB_ATTACH, dip, 1155 "db_enable_io: chip ctrl (0x%x) after\n", regval); 1156 } 1157 } 1158 1159 /* 1160 * Set DVMA Address Range. 1161 * This code is common to both orientations of the nexus driver. 1162 */ 1163 static void 1164 db_set_dvma_range(db_ctrl_t *dbp) 1165 { 1166 uint32_t dvma_start = 0; 1167 uint32_t dvma_len = 0; 1168 uint64_t db_allocd = 0; 1169 uint32_t *dvma_prop; 1170 uint32_t dvma_size[2]; /* dvma size may span over 2 BARs */ 1171 uint32_t dvma_bar[2]; /* dvma range may span over 2 BARs */ 1172 int dvma_prop_len; 1173 uint64_t new_dvma_start, new_dvma_len, new_dvma_end; 1174 1175 /* 1176 * Need to traverse up the tree looking for a 1177 * "virtual-dma" property that specifies the 1178 * HPB DVMA range. 1179 */ 1180 if (ddi_getlongprop(DDI_DEV_T_ANY, ddi_get_parent(dbp->dip), 0, 1181 "virtual-dma", (caddr_t)&dvma_prop, &dvma_prop_len) 1182 == DDI_SUCCESS) { 1183 dvma_start = dvma_prop[0]; 1184 dvma_len = dvma_prop[1]; 1185 kmem_free((caddr_t)dvma_prop, dvma_prop_len); 1186 } else { 1187 /* 1188 * For initial implementation, lets avoid a warning since this 1189 * change has not been implemented in the host-pci nexus 1190 * driver. 1191 */ 1192 cmn_err(CE_WARN, 1193 "%s#%d: Could not get \"virtual-dma\" property", 1194 ddi_driver_name(dbp->dip), 1195 ddi_get_instance(dbp->dip)); 1196 dvma_start = db_dvma_start; 1197 dvma_len = db_dvma_len; 1198 } 1199 1200 DB_DEBUG2(DB_DVMA, dbp->dip, 1201 "DVMA Range is %lx,%lx\n", dvma_start, dvma_len); 1202 1203 dvma_size[0] = dvma_size[1] = 0; 1204 /* Validate DVMA size programming and system requirements. */ 1205 if (dbp->dev_state & DB_SECONDARY_NEXUS) { 1206 dvma_size[0] = pci_config_get32(dbp->conf_handle, 1207 DB_CONF_DS_IO_MEM1_SETUP); 1208 if (!(dvma_size[0] & 1)) /* make sure it is not a IO BAR */ 1209 dvma_size[0] = ((~dvma_size[0]) + 1) & 0xfffff000; 1210 else 1211 dvma_size[0] = 0; 1212 dvma_size[1] = db_dvma_len; 1213 } else { 1214 dvma_size[0] = pci_config_get32(dbp->conf_handle, 1215 DB_CONF_US_IO_MEM0_SETUP); 1216 if (!(dvma_size[0] & 1)) /* make sure it is not a IO BAR */ 1217 dvma_size[0] = ((~dvma_size[0]) + 1) & 0xfffff000; 1218 else 1219 dvma_size[0] = 0; 1220 dvma_size[1] = ((~(pci_config_get32(dbp->conf_handle, 1221 DB_CONF_US_MEM1_SETUP))) + 1) & 0xfffff000; 1222 } 1223 DB_DEBUG2(DB_DVMA, dbp->dip, "DVMA size register pair %lx, %lx\n", 1224 dvma_size[0], dvma_size[1]); 1225 1226 #ifdef DEBUG 1227 if ((dvma_size[0] + dvma_size[1]) < dvma_len) 1228 cmn_err(CE_WARN, "%s#%d: DVMA window (%u) does not coincide" 1229 " with system requirements", 1230 ddi_driver_name(dbp->dip), ddi_get_instance(dbp->dip), 1231 (dvma_size[0] + dvma_size[1])); 1232 #endif 1233 dvma_bar[0] = dvma_bar[1] = 0xFFFFFFFF; 1234 db_allocd = 0; 1235 new_dvma_start = dvma_start; 1236 new_dvma_len = dvma_len; 1237 1238 /* now, program the correct DVMA range over the 2 BARs. Max 4GB */ 1239 if (dvma_size[0]) { 1240 dvma_bar[0] = (uint32_t)(dvma_start & (~(dvma_size[0] - 1))); 1241 new_dvma_end = (uint64_t)((uint64_t)dvma_bar[0] + 1242 (uint64_t)dvma_size[0]); 1243 if (new_dvma_end > (new_dvma_start + new_dvma_len)) 1244 new_dvma_end = new_dvma_start + new_dvma_len; 1245 db_allocd += (new_dvma_end - new_dvma_start); 1246 new_dvma_start = new_dvma_end; 1247 new_dvma_len = dvma_len - db_allocd; 1248 } 1249 /* 1250 * It does not serve any purpose to set the other DVMA register 1251 * when we have already met the memory requirements so leave it 1252 * disabled. 1253 */ 1254 if ((db_allocd != dvma_len) && dvma_size[1]) { 1255 dvma_bar[1] = (uint32_t)((dvma_start + db_allocd) & 1256 (~(dvma_size[1] - 1))); 1257 new_dvma_end = (uint64_t)((uint64_t)dvma_bar[1] + 1258 (uint64_t)dvma_size[1]); 1259 if (new_dvma_end > (new_dvma_start + new_dvma_len)) 1260 new_dvma_end = new_dvma_start + new_dvma_len; 1261 db_allocd += (new_dvma_end - new_dvma_start); 1262 } 1263 1264 /* In case of secondary orientation, DVMA BAR0 is 0. */ 1265 if (dbp->dev_state & DB_SECONDARY_NEXUS) 1266 dvma_bar[0] = 0; 1267 1268 if (db_allocd != dvma_len) { 1269 cmn_err(CE_WARN, "%s#%d: dvma range error!", 1270 ddi_driver_name(dbp->dip), ddi_get_instance(dbp->dip)); 1271 } 1272 1273 DB_DEBUG2(DB_DVMA, dbp->dip, "DVMA BARs set as %x, %x\n", 1274 dvma_bar[0], dvma_bar[1]); 1275 1276 /* configure the setup register and DVMA BARs. */ 1277 if (dbp->dev_state & DB_SECONDARY_NEXUS) { 1278 if (dvma_bar[0] != 0xFFFFFFFF) { 1279 #ifdef DB_SEC_SETUP_WRITE 1280 /* 1281 * No need to program the setup register 1282 * as the PROM would have done it. 1283 */ 1284 pci_config_put32(dbp->conf_handle, 1285 DB_CONF_DS_MEM1_SETUP, 1286 (uint32_t)(((~(dvma_size[0] - 1)) | 1287 (pci_config_get32(dbp->conf_handle, 1288 DB_CONF_DS_MEM1_SETUP) & 0xF)) | 0x80000000)); 1289 #endif 1290 /* 1291 * when translations are to be provided, this will 1292 * change. 1293 */ 1294 pci_config_put32(dbp->conf_handle, 1295 DB_CONF_DS_IO_MEM1_TR_BASE, 1296 (uint32_t)dvma_bar[0]); 1297 pci_config_put32(dbp->conf_handle, 1298 DB_SCONF_DS_IO_MEM1, dvma_bar[0]); 1299 } 1300 if (dvma_bar[1] != 0xFFFFFFFF) { 1301 #ifdef DB_SEC_SETUP_WRITE 1302 /* 1303 * No need to program the setup register 1304 * as the PROM would have done it. 1305 */ 1306 pci_config_put32(dbp->conf_handle, 1307 DB_CONF_DS_MEM2_SETUP, 1308 (uint32_t)(((~(dvma_size[1] - 1)) | 1309 (pci_config_get32(dbp->conf_handle, 1310 DB_CONF_DS_MEM2_SETUP) & 0xF)) | 0x80000000)); 1311 #endif 1312 /* 1313 * when translations are to be provided, this will 1314 * change. 1315 */ 1316 pci_config_put32(dbp->conf_handle, 1317 DB_CONF_DS_MEM2_TR_BASE, (uint32_t)dvma_bar[1]); 1318 pci_config_put32(dbp->conf_handle, 1319 DB_SCONF_DS_MEM2, dvma_bar[1]); 1320 } 1321 1322 } else { 1323 if (dvma_bar[0] != 0xFFFFFFFF) { 1324 #ifdef DB_CONF_P2S_WRITE_ENABLED /* primary to secondary write enabled */ 1325 /* 1326 * We have a problem with this setup, because the 1327 * US_MEM1 setup register cannot be written from the 1328 * primary interface...!!! Hence in this configuration, 1329 * we cannot dynamically program the DVMA range! 1330 */ 1331 pci_config_put32(dbp->conf_handle, 1332 DB_CONF_US_IO_MEM0_SETUP, 1333 (uint32_t)(((~(dvma_size[0] - 1)) | 1334 (pci_config_get32(dbp->conf_handle, 1335 DB_CONF_US_IO_MEM0_SETUP) & 0xF)) | 1336 0x80000000)); 1337 #endif 1338 /* 1339 * when translations are to be provided, this will 1340 * change. 1341 */ 1342 pci_config_put32(dbp->conf_handle, 1343 DB_CONF_US_IO_MEM0_TR_BASE, 1344 (uint32_t)dvma_bar[0]); 1345 pci_config_put32(dbp->conf_handle, 1346 DB_PCONF_US_IO_MEM0, dvma_bar[0]); 1347 } 1348 if (dvma_bar[1] != 0xFFFFFFFF) { 1349 #ifdef DB_CONF_P2S_WRITE_ENABLED /* primary to secondary write enabled */ 1350 /* 1351 * We have a problem with this setup, because the 1352 * US_MEM1 setup register cannot be written from the 1353 * primary interface...!!! Hence in this configuration, 1354 * we cannot dynamically program the DVMA range! 1355 */ 1356 pci_config_put32(dbp->conf_handle, 1357 DB_CONF_US_MEM1_SETUP, 1358 (uint32_t)(((~(dvma_size[1] - 1)) | 1359 (pci_config_get32(dbp->conf_handle, 1360 DB_CONF_US_MEM1_SETUP) & 0xF)) | 0x80000000)); 1361 #endif 1362 /* 1363 * when translations are to be provided, this will 1364 * change. 1365 */ 1366 pci_config_put32(dbp->conf_handle, 1367 DB_CONF_US_MEM1_TR_BASE, (uint32_t)dvma_bar[1]); 1368 pci_config_put32(dbp->conf_handle, 1369 DB_PCONF_US_MEM1, dvma_bar[1]); 1370 } 1371 } 1372 } 1373 1374 /*ARGSUSED*/ 1375 static int 1376 db_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p) 1377 { 1378 minor_t minor = getminor(*dev_p); 1379 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor); 1380 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 1381 1382 if (dbp == (db_ctrl_t *)NULL) 1383 return (ENXIO); 1384 1385 /* 1386 * check for debug node 1387 */ 1388 if ((minor & 0xff) == 0xfe) 1389 return (0); 1390 1391 if (dbp->dev_state & DB_SECONDARY_NEXUS) 1392 return ((pcihp_get_cb_ops())->cb_open(dev_p, flag, 1393 otyp, cred_p)); 1394 /* 1395 * Handle the open by tracking the device state. 1396 */ 1397 mutex_enter(&dbp->db_mutex); 1398 if (flag & FEXCL) { 1399 if (dbp->db_soft_state != DB_SOFT_STATE_CLOSED) { 1400 mutex_exit(&dbp->db_mutex); 1401 return (EBUSY); 1402 } 1403 dbp->db_soft_state = DB_SOFT_STATE_OPEN_EXCL; 1404 } else { 1405 if (dbp->db_soft_state == DB_SOFT_STATE_OPEN_EXCL) { 1406 mutex_exit(&dbp->db_mutex); 1407 return (EBUSY); 1408 } 1409 dbp->db_soft_state = DB_SOFT_STATE_OPEN; 1410 } 1411 mutex_exit(&dbp->db_mutex); 1412 return (0); 1413 } 1414 1415 /*ARGSUSED*/ 1416 static int 1417 db_close(dev_t dev, int flag, int otyp, cred_t *cred_p) 1418 { 1419 minor_t minor = getminor(dev); 1420 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor); 1421 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 1422 1423 if (dbp == (db_ctrl_t *)NULL) 1424 return (ENXIO); 1425 1426 /* 1427 * check for debug node 1428 */ 1429 if ((minor & 0xff) == 0xfe) 1430 return (0); 1431 1432 if (dbp->dev_state & DB_SECONDARY_NEXUS) 1433 return ((pcihp_get_cb_ops())->cb_close(dev, flag, 1434 otyp, cred_p)); 1435 mutex_enter(&dbp->db_mutex); 1436 dbp->db_soft_state = DB_SOFT_STATE_CLOSED; 1437 mutex_exit(&dbp->db_mutex); 1438 return (0); 1439 } 1440 1441 /*ARGSUSED*/ 1442 static int 1443 db_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p, 1444 int *rval_p) 1445 { 1446 int rc = DDI_SUCCESS; 1447 #ifdef DB_DEBUG 1448 ddi_acc_handle_t config_handle; 1449 db_pci_data_t pci_data; 1450 dev_info_t *child_dip; 1451 #endif 1452 dev_info_t *self; 1453 minor_t minor = getminor(dev); 1454 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor); 1455 struct devctl_iocdata *dcp; 1456 uint_t bus_state; 1457 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 1458 1459 #ifdef DB_DEBUG 1460 /* 1461 * try this first whether were SECONDARY_NEXUS or not 1462 */ 1463 if (cmd == DB_PCI_READ_CONF_HEADER) { 1464 if (ddi_copyin((caddr_t)arg, (caddr_t)&pci_data, 1465 sizeof (db_pci_data_t), mode)) { 1466 rc = EFAULT; 1467 return (rc); 1468 } 1469 1470 if (strcmp(pci_data.name, "") == 0) { 1471 child_dip = dbp->dip; 1472 (void) strcpy(pci_data.name, 1473 ddi_get_name(dbp->dip)); 1474 } else { 1475 1476 if ((child_dip = db_lookup_child_name(dbp, 1477 pci_data.name, pci_data.instance)) 1478 == (dev_info_t *)NULL) { 1479 rc = ENXIO; 1480 return (rc); 1481 } else { 1482 if (ddi_getprop(DDI_DEV_T_ANY, 1483 child_dip, DDI_PROP_DONTPASS, 1484 "vendor-id", DB_INVAL_VEND) 1485 == DB_INVAL_VEND) { 1486 /* non PCI device */ 1487 rc = EINVAL; 1488 return (rc); 1489 } 1490 } 1491 } 1492 pci_data.instance = ddi_get_instance(child_dip); 1493 (void) pci_config_setup(child_dip, &config_handle); 1494 db_pci_get_header(config_handle, &pci_data.pri_hdr, 0); 1495 1496 /* if it is the drawbridge itself, read sec header */ 1497 if (child_dip == dbp->dip) { 1498 db_pci_get_header(config_handle, 1499 &pci_data.sec_hdr, DB_PCONF_SEC_HDR_OFF); 1500 db_pci_get_conf_regs(config_handle, 1501 &pci_data.conf_regs); 1502 } 1503 pci_config_teardown(&config_handle); 1504 1505 if (ddi_copyout((caddr_t)&pci_data, (caddr_t)arg, 1506 sizeof (db_pci_data_t), mode)) { 1507 rc = EFAULT; 1508 return (rc); 1509 } 1510 1511 return (rc); 1512 } 1513 #endif /* DB_DEBUG */ 1514 1515 /* 1516 * if secondary nexus (hotplug), then use pcihp_ioctl to do everything 1517 */ 1518 if (dbp->dev_state & DB_SECONDARY_NEXUS) 1519 return ((pcihp_get_cb_ops())->cb_ioctl(dev, cmd, 1520 arg, mode, cred_p, rval_p)); 1521 1522 /* 1523 * if not secondary nexus, we do DEVCTL_DEVICE and DEVCTL_BUS ourselves 1524 */ 1525 self = dbp->dip; 1526 1527 /* 1528 * We can use the generic implementation for these ioctls 1529 */ 1530 switch (cmd) { 1531 case DEVCTL_DEVICE_GETSTATE: 1532 case DEVCTL_DEVICE_ONLINE: 1533 case DEVCTL_DEVICE_OFFLINE: 1534 case DEVCTL_BUS_GETSTATE: 1535 return (ndi_devctl_ioctl(self, cmd, arg, mode, 0)); 1536 } 1537 1538 /* 1539 * read devctl ioctl data 1540 */ 1541 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS) 1542 return (EFAULT); 1543 1544 switch (cmd) { 1545 1546 case DEVCTL_DEVICE_RESET: 1547 rc = ENOTSUP; 1548 break; 1549 1550 1551 case DEVCTL_BUS_QUIESCE: 1552 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) 1553 if (bus_state == BUS_QUIESCED) 1554 break; 1555 (void) ndi_set_bus_state(self, BUS_QUIESCED); 1556 break; 1557 1558 case DEVCTL_BUS_UNQUIESCE: 1559 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) 1560 if (bus_state == BUS_ACTIVE) 1561 break; 1562 (void) ndi_set_bus_state(self, BUS_ACTIVE); 1563 break; 1564 1565 case DEVCTL_BUS_RESET: 1566 rc = ENOTSUP; 1567 break; 1568 1569 case DEVCTL_BUS_RESETALL: 1570 rc = ENOTSUP; 1571 break; 1572 1573 default: 1574 rc = ENOTTY; 1575 } 1576 1577 ndi_dc_freehdl(dcp); 1578 return (rc); 1579 } 1580 1581 #ifdef DB_DEBUG 1582 static dev_info_t * 1583 db_lookup_child_name(db_ctrl_t *dbp, char *name, int instance) 1584 { 1585 dev_info_t *cdip, *pdip = dbp->dip; 1586 1587 for (cdip = ddi_get_child(pdip); cdip; 1588 cdip = ddi_get_next_sibling(pdip)) { 1589 1590 do { 1591 if (strcmp(ddi_node_name(cdip), name) == 0) { 1592 if (instance != -1) { 1593 if (ddi_get_instance(cdip) == instance) 1594 return (cdip); 1595 } else 1596 return (cdip); 1597 } 1598 pdip = cdip; 1599 } while ((cdip = ddi_get_child(pdip))); 1600 cdip = ddi_get_next_sibling(pdip); 1601 if (cdip == NULL) { 1602 pdip = ddi_get_parent(pdip); 1603 if (pdip == dbp->dip) 1604 break; 1605 } 1606 } 1607 return (NULL); 1608 } 1609 1610 static void 1611 db_pci_get_header(ddi_acc_handle_t config_handle, db_pci_header_t *ph, 1612 off_t hdr_off) 1613 { 1614 ph->venid = pci_config_get16(config_handle, hdr_off + PCI_CONF_VENID); 1615 ph->devid = pci_config_get16(config_handle, hdr_off + PCI_CONF_DEVID); 1616 ph->command = pci_config_get16(config_handle, hdr_off + PCI_CONF_COMM); 1617 ph->status = pci_config_get16(config_handle, hdr_off + PCI_CONF_STAT); 1618 ph->revid = pci_config_get8(config_handle, hdr_off + PCI_CONF_REVID); 1619 ph->pif = pci_config_get8(config_handle, hdr_off + PCI_CONF_PROGCLASS); 1620 ph->subclass = pci_config_get8(config_handle, 1621 hdr_off + PCI_CONF_SUBCLASS); 1622 ph->class = pci_config_get8(config_handle, 1623 hdr_off + PCI_CONF_BASCLASS); 1624 ph->cacheline = pci_config_get8(config_handle, 1625 hdr_off + PCI_CONF_CACHE_LINESZ); 1626 ph->lat = pci_config_get8(config_handle, 1627 hdr_off + PCI_CONF_LATENCY_TIMER); 1628 ph->hdr_type = pci_config_get8(config_handle, 1629 hdr_off + PCI_CONF_HEADER); 1630 ph->bist = pci_config_get8(config_handle, hdr_off + PCI_CONF_BIST); 1631 ph->bar0 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE0); 1632 ph->bar1 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE1); 1633 ph->bar2 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE2); 1634 ph->bar3 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE3); 1635 ph->bar4 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE4); 1636 ph->bar5 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE5); 1637 ph->cardbus_cisp = pci_config_get32(config_handle, 1638 hdr_off + PCI_CONF_CIS); 1639 ph->sub_venid = pci_config_get16(config_handle, 1640 hdr_off + PCI_CONF_SUBVENID); 1641 ph->sub_devid = pci_config_get16(config_handle, 1642 hdr_off + PCI_CONF_SUBSYSID); 1643 ph->exprom_bar = pci_config_get32(config_handle, 1644 hdr_off + PCI_CONF_ROM); 1645 ph->int_line = pci_config_get8(config_handle, hdr_off + PCI_CONF_ILINE); 1646 ph->int_pin = pci_config_get8(config_handle, hdr_off + PCI_CONF_IPIN); 1647 ph->min_gnt = pci_config_get8(config_handle, hdr_off + PCI_CONF_MIN_G); 1648 ph->max_lat = pci_config_get8(config_handle, hdr_off + PCI_CONF_MAX_L); 1649 } 1650 1651 static void 1652 db_pci_get_conf_regs(ddi_acc_handle_t config_handle, db_conf_regs_t *cr) 1653 { 1654 cr->ds_mem0_tr_base = pci_config_get32(config_handle, 1655 DB_CONF_DS_MEM0_TR_BASE); 1656 cr->ds_io_mem1_tr_base = pci_config_get32(config_handle, 1657 DB_CONF_DS_IO_MEM1_TR_BASE); 1658 cr->ds_mem2_tr_base = pci_config_get32(config_handle, 1659 DB_CONF_DS_MEM2_TR_BASE); 1660 cr->ds_mem3_tr_base = pci_config_get32(config_handle, 1661 DB_CONF_DS_MEM3_TR_BASE); 1662 cr->us_io_mem0_tr_base = pci_config_get32(config_handle, 1663 DB_CONF_US_IO_MEM0_TR_BASE); 1664 cr->us_mem1_tr_base = pci_config_get32(config_handle, 1665 DB_CONF_US_MEM1_TR_BASE); 1666 cr->ds_mem0_setup_reg = pci_config_get32(config_handle, 1667 DB_CONF_DS_MEM0_SETUP); 1668 cr->ds_io_mem1_setup_reg = pci_config_get32(config_handle, 1669 DB_CONF_DS_IO_MEM1_SETUP); 1670 cr->ds_mem2_setup_reg = pci_config_get32(config_handle, 1671 DB_CONF_DS_MEM2_SETUP); 1672 cr->ds_mem3_setup_reg = pci_config_get64(config_handle, 1673 DB_CONF_DS_MEM3_SETUP); 1674 cr->p_exp_rom_setup = pci_config_get32(config_handle, 1675 DB_CONF_PRIM_EXP_ROM_SETUP); 1676 cr->us_io_mem0_setup_reg = pci_config_get32(config_handle, 1677 DB_CONF_US_IO_MEM0_SETUP); 1678 cr->us_mem1_setup_reg = pci_config_get32(config_handle, 1679 DB_CONF_US_MEM1_SETUP); 1680 cr->chip_control0 = pci_config_get16(config_handle, DB_CONF_CHIP_CTRL0); 1681 cr->chip_control1 = pci_config_get16(config_handle, DB_CONF_CHIP_CTRL1); 1682 cr->chip_status = pci_config_get16(config_handle, DB_CONF_STATUS); 1683 cr->arb_control = pci_config_get16(config_handle, DB_CONF_ARBITER_CTRL); 1684 cr->p_serr_disables = pci_config_get8(config_handle, 1685 DB_CONF_PRIM_SERR_DISABLES); 1686 cr->s_serr_disables = pci_config_get8(config_handle, 1687 DB_CONF_PRIM_SERR_DISABLES); 1688 cr->config_csr = pci_config_get16(config_handle, DB_CONF_CONF_CSR); 1689 cr->reset_control = pci_config_get32(config_handle, DB_CONF_RESET_CTRL); 1690 cr->pm_cap = pci_config_get16(config_handle, DB_CONF_PM_CAP); 1691 cr->pm_csr = pci_config_get16(config_handle, DB_CONF_PM_CSR); 1692 cr->hs_csr = pci_config_get8(config_handle, DB_CONF_HS_CSR); 1693 } 1694 #endif /* DB_DEBUG */ 1695 1696 /* 1697 * Function: db_pci_map 1698 * 1699 * Note: Only memory accesses are direct. IO could be direct 1700 * or indirect. Config accesses are always indirect. 1701 * The question here is, does the "assigned-addresses" 1702 * property entry represents the addresses in the 1703 * local domain or the host domain itself. 1704 * Strictly speaking, the assumption should be that 1705 * it is in the local domain, as the transactions 1706 * upstream or downstream are automatically 1707 * translated by the bridge chip anyway. 1708 * 1709 * Return values: 1710 * DDI_SUCCESS: map call by child device success 1711 * DDI_FAILURE: map operation failed. 1712 */ 1713 1714 static int 1715 db_pci_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 1716 off_t offset, off_t len, caddr_t *addrp) 1717 { 1718 register dev_info_t *pdip; 1719 int reg_proplen, num_regs, rnumber; 1720 uint_t addr_space_type; 1721 pci_regspec_t *pci_regsetp, pci_reg; 1722 db_ctrl_t *dbp; 1723 db_acc_pvt_t *db_pvt; 1724 ddi_acc_impl_t *ap; 1725 ddi_acc_hdl_t *hp; 1726 db_acc_cfg_addr_t *pci_addr; 1727 int instance = ddi_get_instance(dip); 1728 1729 DB_DEBUG0(DB_PCI_MAP, dip, "enter\n"); 1730 1731 /* get map type. check for config space */ 1732 switch (mp->map_type) { 1733 1734 case DDI_MT_RNUMBER : 1735 /* get the reg number */ 1736 rnumber = mp->map_obj.rnumber; 1737 1738 if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, 1739 DDI_PROP_DONTPASS, "reg", 1740 (caddr_t)&pci_regsetp, ®_proplen) 1741 != DDI_SUCCESS) 1742 return (DDI_FAILURE); 1743 1744 num_regs = reg_proplen / (int)sizeof (pci_regspec_t); 1745 if (rnumber >= num_regs) { 1746 /* this is a DDI_ME_RNUMBER_RANGE error */ 1747 kmem_free(pci_regsetp, reg_proplen); 1748 return (DDI_FAILURE); 1749 } 1750 1751 pci_reg = pci_regsetp[rnumber]; 1752 kmem_free(pci_regsetp, reg_proplen); 1753 /* FALLTHROUGH */ 1754 case DDI_MT_REGSPEC : 1755 if (mp->map_type == DDI_MT_REGSPEC) 1756 pci_reg = *(pci_regspec_t *)mp->map_obj.rp; 1757 1758 /* 1759 * Intercept config space accesses only. All other 1760 * requests go to the parent. 1761 */ 1762 addr_space_type = pci_reg.pci_phys_hi & PCI_ADDR_MASK; 1763 1764 DB_DEBUG3(DB_PCI_MAP, dip, "rdip=%lx, rnum=%d(%d)\n", 1765 rdip, rnumber, num_regs); 1766 1767 /* if we do direct map IO, then lets break here */ 1768 if ((db_io_map_mode & DB_IO_MAP_DIRECT) && 1769 (addr_space_type == PCI_ADDR_IO)) 1770 break; 1771 1772 if ((addr_space_type != PCI_ADDR_CONFIG) && 1773 (addr_space_type != PCI_ADDR_IO)) 1774 break; 1775 1776 /* 1777 * User mapping requests not legal for indirect 1778 * IO/Config Space 1779 */ 1780 if (mp->map_op == DDI_MO_MAP_HANDLE) 1781 return (DDI_FAILURE); 1782 1783 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, 1784 instance); 1785 /* get our common access handle */ 1786 hp = (ddi_acc_hdl_t *)mp->map_handlep; 1787 1788 /* Check for unmap operation */ 1789 if ((mp->map_op == DDI_MO_UNMAP) || 1790 (mp->map_op == DDI_MO_UNLOCK)) { 1791 /* 1792 * free up memory allocated for our 1793 * private access handle. 1794 */ 1795 db_pvt = (db_acc_pvt_t *) 1796 hp->ah_bus_private; 1797 DB_DEBUG1(DB_PCI_MAP, dip, 1798 "unmap rdip=%lx\n", rdip); 1799 kmem_free((void *)db_pvt, 1800 sizeof (db_acc_pvt_t)); 1801 1802 /* 1803 * unmap operation of PCI IO/config 1804 * space. 1805 */ 1806 return (DDI_SUCCESS); 1807 } 1808 1809 if (addr_space_type == PCI_ADDR_CONFIG) { 1810 /* Config space access range check */ 1811 if ((offset >= PCI_CONF_HDR_SIZE) || 1812 (len > PCI_CONF_HDR_SIZE) || 1813 (offset + len > PCI_CONF_HDR_SIZE)) { 1814 1815 return (DDI_FAILURE); 1816 } 1817 } 1818 1819 /* define the complete access handle */ 1820 hp = (ddi_acc_hdl_t *)mp->map_handlep; 1821 1822 ap = (ddi_acc_impl_t *)hp->ah_platform_private; 1823 1824 ap->ahi_get8 = db_ddi_get8; 1825 ap->ahi_get16 = db_ddi_get16; 1826 ap->ahi_get32 = db_ddi_get32; 1827 ap->ahi_get64 = db_ddi_get64; 1828 ap->ahi_put8 = db_ddi_put8; 1829 ap->ahi_put16 = db_ddi_put16; 1830 ap->ahi_put32 = db_ddi_put32; 1831 ap->ahi_put64 = db_ddi_put64; 1832 ap->ahi_rep_get8 = db_ddi_rep_get8; 1833 ap->ahi_rep_get16 = db_ddi_rep_get16; 1834 ap->ahi_rep_get32 = db_ddi_rep_get32; 1835 ap->ahi_rep_get64 = db_ddi_rep_get64; 1836 ap->ahi_rep_put8 = db_ddi_rep_put8; 1837 ap->ahi_rep_put16 = db_ddi_rep_put16; 1838 ap->ahi_rep_put32 = db_ddi_rep_put32; 1839 ap->ahi_rep_put64 = db_ddi_rep_put64; 1840 1841 /* Initialize to default check/notify functions */ 1842 ap->ahi_fault = 0; 1843 ap->ahi_fault_check = i_ddi_acc_fault_check; 1844 ap->ahi_fault_notify = i_ddi_acc_fault_notify; 1845 1846 /* allocate memory for our private handle */ 1847 db_pvt = kmem_zalloc(sizeof (db_acc_pvt_t), KM_SLEEP); 1848 hp->ah_bus_private = (void *)db_pvt; 1849 db_pvt->dbp = dbp; 1850 1851 /* record the device address for future use */ 1852 pci_addr = &db_pvt->dev_addr; 1853 pci_addr->c_busnum = 1854 PCI_REG_BUS_G(pci_reg.pci_phys_hi); 1855 pci_addr->c_devnum = 1856 PCI_REG_DEV_G(pci_reg.pci_phys_hi); 1857 pci_addr->c_funcnum = 1858 PCI_REG_FUNC_G(pci_reg.pci_phys_hi); 1859 /* 1860 * We should keep the upstream or 1861 * downstream info in our own ah_bus_private 1862 * structure, so that we do not waste our 1863 * time in the actual IO routines, figuring out 1864 * if we should use upstream or downstream 1865 * configuration addr/data register. 1866 * So, check orientation and setup registers 1867 * right now. 1868 */ 1869 switch (addr_space_type) { 1870 1871 case PCI_ADDR_CONFIG : 1872 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 1873 DB_DEBUG0(DB_PCI_MAP, dip, "primary\n"); 1874 db_pvt->mask = DS8_CONF_OWN; 1875 if (db_conf_map_mode & 1876 DB_CONF_MAP_INDIRECT_IO) { 1877 DB_DEBUG0(DB_PCI_MAP, dip, 1878 "INDIRECT_CONF\n"); 1879 1880 db_pvt->handle = 1881 dbp->csr_io_handle; 1882 db_pvt->addr = 1883 (uint32_t *) 1884 ((uchar_t *)dbp->csr_io 1885 + DB_CSR_DS_CONF_ADDR); 1886 db_pvt->data = 1887 (uint32_t *) 1888 ((uchar_t *)dbp->csr_io 1889 + DB_CSR_DS_CONF_DATA); 1890 db_pvt->bus_own = 1891 (uint8_t *) 1892 ((uchar_t *)dbp->csr_io 1893 + DB_CSR8_DS_CONF_OWN); 1894 db_pvt->bus_release = 1895 (uint8_t *) 1896 ((uchar_t *)dbp->csr_io 1897 + DB_CSR8_DS_CONF_CSR); 1898 } else { 1899 DB_DEBUG0(DB_PCI_MAP, dip, 1900 "DIRECT_CONF\n"); 1901 1902 db_pvt->handle = 1903 dbp->conf_handle; 1904 db_pvt->addr = 1905 (uint32_t *) 1906 ((uchar_t *)dbp->conf_io 1907 + DB_CONF_DS_CONF_ADDR); 1908 db_pvt->data = (uint32_t *) 1909 ((uchar_t *)dbp->conf_io 1910 + DB_CONF_DS_CONF_DATA); 1911 db_pvt->bus_own = 1912 (uint8_t *) 1913 ((uchar_t *)dbp->conf_io 1914 + DB_CONF8_DS_CONF_OWN); 1915 db_pvt->bus_release = 1916 (uint8_t *) 1917 ((uchar_t *)dbp->conf_io 1918 + DB_CONF8_DS_CONF_CSR); 1919 } 1920 } else { 1921 DB_DEBUG0(DB_PCI_MAP, dip, 1922 "secondary\n"); 1923 db_pvt->mask = US8_CONF_OWN; 1924 if (db_conf_map_mode & 1925 DB_CONF_MAP_INDIRECT_IO) { 1926 DB_DEBUG0(DB_PCI_MAP, dip, 1927 "INDIRECT_CONF\n"); 1928 1929 db_pvt->handle = 1930 dbp->csr_io_handle; 1931 db_pvt->addr = 1932 (uint32_t *) 1933 ((uchar_t *)dbp->csr_io 1934 + DB_CSR_US_CONF_ADDR); 1935 db_pvt->data = 1936 (uint32_t *) 1937 ((uchar_t *)dbp->csr_io 1938 + DB_CSR_US_CONF_DATA); 1939 db_pvt->bus_own = 1940 (uint8_t *) 1941 ((uchar_t *)dbp->csr_io 1942 + DB_CSR8_US_CONF_OWN); 1943 db_pvt->bus_release = 1944 (uint8_t *) 1945 ((uchar_t *)dbp->csr_io 1946 + DB_CSR8_US_CONF_CSR); 1947 } else { 1948 DB_DEBUG0(DB_PCI_MAP, dip, 1949 "DIRECT_CONF\n"); 1950 1951 db_pvt->handle = 1952 dbp->conf_handle; 1953 db_pvt->addr = 1954 (uint32_t *) 1955 ((uchar_t *)dbp->conf_io 1956 + DB_CONF_US_CONF_ADDR); 1957 db_pvt->data = 1958 (uint32_t *) 1959 ((uchar_t *)dbp->conf_io 1960 + DB_CONF_US_CONF_DATA); 1961 db_pvt->bus_own = 1962 (uint8_t *) 1963 ((uchar_t *)dbp->conf_io 1964 + DB_CONF8_US_CONF_OWN); 1965 db_pvt->bus_release = 1966 (uint8_t *) 1967 ((uchar_t *)dbp->conf_io 1968 + DB_CONF8_US_CONF_CSR); 1969 } 1970 } 1971 break; 1972 1973 case PCI_ADDR_IO : 1974 DB_DEBUG0(DB_PCI_MAP, dip, "PCI_ADDR_IO\n"); 1975 1976 /* ap->ahi_acc_attr |= DDI_ACCATTR_IO_SPACE; */ 1977 db_pvt->handle = dbp->csr_io_handle; 1978 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 1979 DB_DEBUG0(DB_PCI_MAP, dip, "primary\n"); 1980 db_pvt->addr = (uint32_t *) 1981 ((uchar_t *)dbp->csr_io 1982 + DB_CSR_DS_IO_ADDR); 1983 db_pvt->data = (uint32_t *) 1984 ((uchar_t *)dbp->csr_io 1985 + DB_CSR_DS_IO_DATA); 1986 db_pvt->bus_own = (uint8_t *) 1987 ((uchar_t *)dbp->csr_io 1988 + DB_CSR8_DS_IO_OWN); 1989 db_pvt->bus_release = (uint8_t *) 1990 ((uchar_t *)dbp->csr_io 1991 + DB_CSR8_DS_IO_CSR); 1992 db_pvt->mask = DS8_IO_OWN; 1993 } else { 1994 DB_DEBUG0(DB_PCI_MAP, dip, 1995 "secondary\n"); 1996 db_pvt->addr = (uint32_t *) 1997 ((uchar_t *)dbp->csr_io 1998 + DB_CSR_US_IO_ADDR); 1999 db_pvt->data = (uint32_t *) 2000 ((uchar_t *)dbp->csr_io 2001 + DB_CSR_US_IO_DATA); 2002 db_pvt->bus_own = (uint8_t *) 2003 ((uchar_t *)dbp->csr_io 2004 + DB_CSR8_US_IO_OWN); 2005 db_pvt->bus_release = (uint8_t *) 2006 ((uchar_t *)dbp->csr_io 2007 + DB_CSR8_US_IO_CSR); 2008 db_pvt->mask = US8_IO_OWN; 2009 } 2010 break; 2011 2012 default : 2013 DB_DEBUG0(DB_PCI_MAP, dip, 2014 "PCI_ADDR unknown\n"); 2015 break; 2016 } 2017 2018 /* make and store a type 0/1 address in the *addrp */ 2019 if (pci_addr->c_busnum == dbp->range.lo) { 2020 *addrp = (caddr_t)DB_PCI_REG_ADDR_TYPE0( 2021 pci_addr->c_busnum, 2022 pci_addr->c_devnum, 2023 pci_addr->c_funcnum, 2024 offset); 2025 db_pvt->access_mode |= DB_PCI_CONF_CYCLE_TYPE0; 2026 DB_DEBUG0(DB_PCI_MAP, dip, 2027 "access mode type 0\n"); 2028 } else { 2029 *addrp = (caddr_t)DB_PCI_REG_ADDR_TYPE1( 2030 pci_addr->c_busnum, 2031 pci_addr->c_devnum, 2032 pci_addr->c_funcnum, 2033 offset); 2034 db_pvt->access_mode |= DB_PCI_CONF_CYCLE_TYPE1; 2035 DB_DEBUG0(DB_PCI_MAP, dip, 2036 "access mode type 1\n"); 2037 } 2038 DB_DEBUG4(DB_PCI_MAP, dip, "addrp<%x,%x,%x> = %lx\n", 2039 pci_addr->c_busnum, pci_addr->c_devnum, 2040 pci_addr->c_funcnum, *addrp); 2041 2042 return (DDI_SUCCESS); 2043 2044 default : 2045 DB_DEBUG1(DB_PCI_MAP, dip, "DDI other %x\n", 2046 mp->map_type); 2047 break; 2048 } 2049 DB_DEBUG0(DB_PCI_MAP, dip, "exit\n"); 2050 2051 pdip = (dev_info_t *)DEVI(dip)->devi_parent; 2052 return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map) 2053 (pdip, rdip, mp, offset, len, addrp)); 2054 } 2055 2056 #ifdef DB_DEBUG 2057 char *db_ctlop_name[] = { 2058 "DDI_CTLOPS_DMAPMAPC", 2059 "DDI_CTLOPS_INITCHILD", 2060 "DDI_CTLOPS_UNINITCHILD", 2061 "DDI_CTLOPS_REPORTDEV", 2062 "DDI_CTLOPS_REPORTINT", 2063 "DDI_CTLOPS_REGSIZE", 2064 "DDI_CTLOPS_NREGS", 2065 "DDI_CTLOPS_RESERVED0", 2066 "DDI_CTLOPS_SIDDEV", 2067 "DDI_CTLOPS_SLAVEONLY", 2068 "DDI_CTLOPS_AFFINITY", 2069 "DDI_CTLOPS_IOMIN", 2070 "DDI_CTLOPS_PTOB", 2071 "DDI_CTLOPS_BTOP", 2072 "DDI_CTLOPS_BTOPR", 2073 "DDI_CTLOPS_RESERVED1", 2074 "DDI_CTLOPS_RESERVED2", 2075 "DDI_CTLOPS_RESERVED3", 2076 "DDI_CTLOPS_RESERVED4", 2077 "DDI_CTLOPS_RESERVED5", 2078 "DDI_CTLOPS_DVMAPAGESIZE", 2079 "DDI_CTLOPS_POWER", 2080 "DDI_CTLOPS_ATTACH", 2081 "DDI_CTLOPS_DETACH", 2082 "DDI_CTLOPS_POKE", 2083 "DDI_CTLOPS_PEEK" 2084 }; 2085 #endif 2086 2087 static int 2088 db_ctlops(dev_info_t *dip, dev_info_t *rdip, 2089 ddi_ctl_enum_t ctlop, void *arg, void *result) 2090 { 2091 2092 if ((ctlop >= DDI_CTLOPS_DMAPMAPC) && 2093 (ctlop <= DDI_CTLOPS_DETACH)) { 2094 DB_DEBUG1(DB_CTLOPS, dip, "ctlop=%s\n", db_ctlop_name[ctlop]); 2095 } else { 2096 DB_DEBUG1(DB_CTLOPS, dip, "ctlop=%d\n", ctlop); 2097 } 2098 2099 switch (ctlop) { 2100 case DDI_CTLOPS_REPORTDEV : 2101 if (rdip == (dev_info_t *)0) 2102 return (DDI_FAILURE); 2103 cmn_err(CE_CONT, "?PCI-device: %s@%s, %s#%d\n", 2104 ddi_node_name(rdip), ddi_get_name_addr(rdip), 2105 ddi_driver_name(rdip), 2106 ddi_get_instance(rdip)); 2107 return (DDI_SUCCESS); 2108 2109 case DDI_CTLOPS_INITCHILD : 2110 return (db_initchild((dev_info_t *)arg)); 2111 2112 case DDI_CTLOPS_UNINITCHILD : 2113 db_uninitchild((dev_info_t *)arg); 2114 return (DDI_SUCCESS); 2115 2116 case DDI_CTLOPS_SIDDEV : 2117 return (DDI_SUCCESS); 2118 2119 case DDI_CTLOPS_REGSIZE : 2120 case DDI_CTLOPS_NREGS : 2121 if (rdip == (dev_info_t *)0) 2122 return (DDI_FAILURE); 2123 /* fall through */ 2124 2125 default : 2126 return (ddi_ctlops(dip, rdip, ctlop, arg, result)); 2127 } 2128 2129 } 2130 2131 static dev_info_t * 2132 db_get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip) 2133 { 2134 dev_info_t *cdip = rdip; 2135 2136 for (; ddi_get_parent(cdip) != dip; cdip = ddi_get_parent(cdip)) 2137 ; 2138 2139 return (cdip); 2140 } 2141 2142 static int 2143 db_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op, 2144 ddi_intr_handle_impl_t *hdlp, void *result) 2145 { 2146 dev_info_t *cdip = rdip; 2147 pci_regspec_t *pci_rp; 2148 int reglen, len; 2149 uint32_t d, intr; 2150 2151 DB_DEBUG1(DB_INTR_OPS, dip, "intr_op=%d\n", intr_op); 2152 2153 if (hdlp->ih_type != DDI_INTR_TYPE_FIXED) 2154 goto done; 2155 2156 /* 2157 * If the interrupt-map property is defined at this 2158 * node, it will have performed the interrupt 2159 * translation as part of the property, so no 2160 * rotation needs to be done. 2161 */ 2162 2163 if (ddi_getproplen(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 2164 "interrupt-map", &len) == DDI_PROP_SUCCESS) 2165 goto done; 2166 2167 cdip = db_get_my_childs_dip(dip, rdip); 2168 2169 /* 2170 * Use the devices reg property to determine it's 2171 * PCI bus number and device number. 2172 */ 2173 if (ddi_getlongprop(DDI_DEV_T_ANY, cdip, DDI_PROP_DONTPASS, 2174 "reg", (caddr_t)&pci_rp, ®len) != DDI_SUCCESS) 2175 return (DDI_FAILURE); 2176 2177 intr = hdlp->ih_vector; 2178 2179 /* Spin the interrupt */ 2180 d = PCI_REG_DEV_G(pci_rp[0].pci_phys_hi); 2181 2182 if ((intr >= PCI_INTA) && (intr <= PCI_INTD)) 2183 hdlp->ih_vector = ((intr - 1 + (d % 4)) % 4 + 1); 2184 else 2185 cmn_err(CE_WARN, "%s#%d: %s: PCI intr=%x out of range", 2186 ddi_driver_name(rdip), ddi_get_instance(rdip), 2187 ddi_driver_name(dip), intr); 2188 2189 DB_DEBUG3(DB_INTR_OPS, dip, "intr=%d, d=%d, is_intr=%d\n", 2190 intr, d, hdlp->ih_vector); 2191 2192 kmem_free(pci_rp, reglen); 2193 2194 done: 2195 /* Pass up the request to our parent. */ 2196 return (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result)); 2197 } 2198 2199 static int 2200 db_name_child(dev_info_t *child, char *name, int namelen) 2201 { 2202 uint_t n, slot, func; 2203 pci_regspec_t *pci_rp; 2204 2205 if (ndi_dev_is_persistent_node(child) == 0) { 2206 char **unit_addr; 2207 2208 /* name .conf nodes by "unit-address" property" */ 2209 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, child, 2210 DDI_PROP_DONTPASS, "unit-address", &unit_addr, &n) != 2211 DDI_PROP_SUCCESS) { 2212 cmn_err(CE_WARN, "cannot name node from %s.conf", 2213 ddi_driver_name(child)); 2214 return (DDI_FAILURE); 2215 } 2216 if (n != 1 || *unit_addr == NULL || **unit_addr == 0) { 2217 cmn_err(CE_WARN, "unit-address property in %s.conf" 2218 " not well-formed", ddi_driver_name(child)); 2219 ddi_prop_free(unit_addr); 2220 return (DDI_FAILURE); 2221 } 2222 2223 (void) snprintf(name, namelen, "%s", *unit_addr); 2224 ddi_prop_free(unit_addr); 2225 return (DDI_SUCCESS); 2226 } 2227 2228 /* name hardware nodes by "reg" property */ 2229 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, 0, "reg", 2230 (int **)&pci_rp, &n) != DDI_SUCCESS) 2231 return (DDI_FAILURE); 2232 2233 /* get the device identifications */ 2234 slot = PCI_REG_DEV_G(pci_rp->pci_phys_hi); 2235 func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi); 2236 2237 if (func != 0) 2238 (void) snprintf(name, namelen, "%x,%x", slot, func); 2239 else 2240 (void) snprintf(name, namelen, "%x", slot); 2241 2242 ddi_prop_free(pci_rp); 2243 return (DDI_SUCCESS); 2244 } 2245 2246 static int 2247 db_initchild(dev_info_t *child) 2248 { 2249 char name[MAXNAMELEN]; 2250 ddi_acc_handle_t config_handle; 2251 ushort_t command_preserve, command; 2252 uint_t n; 2253 ushort_t bcr; 2254 uchar_t header_type, min_gnt, latency_timer; 2255 db_ctrl_t *dbp; 2256 2257 if (db_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS) 2258 return (DDI_FAILURE); 2259 2260 ddi_set_name_addr(child, name); 2261 ddi_set_parent_data(child, NULL); 2262 2263 /* 2264 * Pseudo nodes indicate a prototype node with per-instance 2265 * properties to be merged into the real h/w device node. 2266 * The interpretation of the unit-address is DD[,F] 2267 * where DD is the device id and F is the function. 2268 */ 2269 if (ndi_dev_is_persistent_node(child) == 0) { 2270 extern int pci_allow_pseudo_children; 2271 2272 /* 2273 * Try to merge the properties from this prototype 2274 * node into real h/w nodes. 2275 */ 2276 if (ndi_merge_node(child, db_name_child) == DDI_SUCCESS) { 2277 /* 2278 * Merged ok - return failure to remove the node. 2279 */ 2280 return (DDI_FAILURE); 2281 } 2282 2283 /* workaround for ddivs to run under PCI */ 2284 if (pci_allow_pseudo_children) { 2285 return (DDI_SUCCESS); 2286 } 2287 2288 /* 2289 * The child was not merged into a h/w node, 2290 * but there's not much we can do with it other 2291 * than return failure to cause the node to be removed. 2292 */ 2293 cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged", 2294 ddi_driver_name(child), ddi_get_name_addr(child), 2295 ddi_driver_name(child)); 2296 return (DDI_NOT_WELL_FORMED); 2297 } 2298 2299 2300 if ((db_create_pci_prop(child) != DDI_SUCCESS) || 2301 (pci_config_setup(child, &config_handle) != DDI_SUCCESS)) { 2302 db_uninitchild(child); 2303 return (DDI_FAILURE); 2304 } 2305 2306 /* 2307 * Determine the configuration header type. 2308 */ 2309 header_type = pci_config_get8(config_handle, PCI_CONF_HEADER); 2310 2311 /* 2312 * Support for the "command-preserve" property. 2313 */ 2314 command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child, 2315 DDI_PROP_DONTPASS, "command-preserve", 0); 2316 command = pci_config_get16(config_handle, PCI_CONF_COMM); 2317 command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB); 2318 command |= (db_command_default & ~command_preserve); 2319 pci_config_put16(config_handle, PCI_CONF_COMM, command); 2320 2321 DB_DEBUG2(DB_INITCHILD, ddi_get_parent(child), 2322 "initializing device vend=%x, devid=%x\n", 2323 pci_config_get16(config_handle, PCI_CONF_VENID), 2324 pci_config_get16(config_handle, PCI_CONF_DEVID)); 2325 /* 2326 * If the device has a bus control register then program it 2327 * based on the settings in the command register. 2328 */ 2329 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { 2330 bcr = pci_config_get8(config_handle, PCI_BCNF_BCNTRL); 2331 if (db_command_default & PCI_COMM_PARITY_DETECT) 2332 bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE; 2333 if (db_command_default & PCI_COMM_SERR_ENABLE) 2334 bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE; 2335 bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE; 2336 pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr); 2337 } 2338 2339 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, 2340 ddi_get_instance(ddi_get_parent(child))); 2341 2342 /* 2343 * Initialize cache-line-size configuration register if needed. 2344 */ 2345 if (db_set_cache_line_size_register && 2346 ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, 2347 "cache-line-size", 0) == 0) { 2348 pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ, 2349 dbp->cache_line_size); 2350 n = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ); 2351 if (n != 0) { 2352 (void) ndi_prop_update_int(DDI_DEV_T_NONE, child, 2353 "cache-line-size", n); 2354 } 2355 DB_DEBUG1(DB_INITCHILD, ddi_get_parent(child), 2356 "\nChild Device Cache Size %x\n", dbp->cache_line_size); 2357 } 2358 2359 /* 2360 * Initialize latency timer configuration registers if needed. 2361 */ 2362 if (db_set_latency_timer_register && 2363 ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS, 2364 "latency-timer", 0) == 0) { 2365 2366 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) { 2367 latency_timer = dbp->p_latency_timer; 2368 pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER, 2369 dbp->latency_timer); 2370 } else { 2371 min_gnt = pci_config_get8(config_handle, 2372 PCI_CONF_MIN_G); 2373 latency_timer = min_gnt * 8; 2374 } 2375 pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER, 2376 latency_timer); 2377 n = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER); 2378 if (n != 0) { 2379 (void) ndi_prop_update_int(DDI_DEV_T_NONE, child, 2380 "latency-timer", n); 2381 } 2382 DB_DEBUG1(DB_INITCHILD, ddi_get_parent(child), 2383 "\nChild Device latency %x\n", latency_timer); 2384 } 2385 2386 pci_config_teardown(&config_handle); 2387 return (DDI_SUCCESS); 2388 } 2389 2390 static void 2391 db_uninitchild(dev_info_t *dip) 2392 { 2393 ddi_set_name_addr(dip, NULL); 2394 2395 /* 2396 * Strip the node to properly convert it back to prototype form 2397 */ 2398 impl_rem_dev_props(dip); 2399 } 2400 2401 static int 2402 db_create_pci_prop(dev_info_t *child) 2403 { 2404 pci_regspec_t *pci_rp; 2405 int length; 2406 int value; 2407 2408 /* get child "reg" property */ 2409 value = ddi_getlongprop(DDI_DEV_T_ANY, child, DDI_PROP_CANSLEEP, 2410 "reg", (caddr_t)&pci_rp, &length); 2411 if (value != DDI_SUCCESS) 2412 return (value); 2413 2414 (void) ndi_prop_update_byte_array(DDI_DEV_T_NONE, child, "reg", 2415 (uchar_t *)pci_rp, length); 2416 2417 /* 2418 * free the memory allocated by ddi_getlongprop (). 2419 */ 2420 kmem_free(pci_rp, length); 2421 2422 /* 2423 * No need to create any 1275 properties here, because either 2424 * the OBP creates them or the hotplug framework creates it 2425 * during a hotplug operation. So lets return here. 2426 */ 2427 return (DDI_SUCCESS); 2428 } 2429 2430 /* 2431 * db_save_config_regs 2432 * 2433 * This routine saves the state of the configuration registers of all 2434 * immediate child nodes. 2435 * 2436 * used by: db_detach() on suspends 2437 * 2438 * return value: DDI_SUCCESS: ALl children state saved. 2439 * DDI_FAILURE: Child device state could not be saved. 2440 */ 2441 static int 2442 db_save_config_regs(db_ctrl_t *dbp) 2443 { 2444 int i; 2445 dev_info_t *dip; 2446 ddi_acc_handle_t config_handle; 2447 db_cfg_state_t *statep; 2448 2449 for (i = 0, dip = ddi_get_child(dbp->dip); dip != NULL; 2450 dip = ddi_get_next_sibling(dip)) { 2451 if (i_ddi_node_state(dip) >= DS_ATTACHED) 2452 i++; 2453 } 2454 dbp->config_state_index = i; 2455 2456 if (!i) { 2457 /* no children */ 2458 dbp->db_config_state_p = NULL; 2459 return (DDI_SUCCESS); 2460 } 2461 2462 /* i now equals the total number of child devices */ 2463 dbp->db_config_state_p = 2464 kmem_zalloc(i * sizeof (db_cfg_state_t), KM_NOSLEEP); 2465 if (!dbp->db_config_state_p) { 2466 cmn_err(CE_WARN, 2467 "%s#%d: No memory to save state for child %s#%d\n", 2468 ddi_driver_name(dbp->dip), 2469 ddi_get_instance(dbp->dip), 2470 ddi_get_name(dip), ddi_get_instance(dip)); 2471 return (DDI_FAILURE); 2472 } 2473 2474 for (statep = dbp->db_config_state_p, 2475 dip = ddi_get_child(dbp->dip); 2476 dip != NULL; 2477 dip = ddi_get_next_sibling(dip)) { 2478 2479 if (i_ddi_node_state(dip) < DS_ATTACHED) 2480 continue; 2481 2482 if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) { 2483 cmn_err(CE_WARN, 2484 "%s#%d: can't config space for %s#%d", 2485 ddi_driver_name(dbp->dip), 2486 ddi_get_instance(dbp->dip), 2487 ddi_driver_name(dip), 2488 ddi_get_instance(dip)); 2489 continue; 2490 } 2491 2492 statep->dip = dip; 2493 statep->command = 2494 pci_config_get16(config_handle, PCI_CONF_COMM); 2495 statep->header_type = 2496 pci_config_get8(config_handle, PCI_CONF_HEADER); 2497 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) 2498 statep->bridge_control = 2499 pci_config_get16(config_handle, PCI_BCNF_BCNTRL); 2500 statep->cache_line_size = 2501 pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ); 2502 statep->latency_timer = 2503 pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER); 2504 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) 2505 statep->sec_latency_timer = 2506 pci_config_get8(config_handle, 2507 PCI_BCNF_LATENCY_TIMER); 2508 pci_config_teardown(&config_handle); 2509 statep++; 2510 } 2511 return (DDI_SUCCESS); 2512 } 2513 2514 2515 /* 2516 * db_restore_config_regs 2517 * 2518 * This routine restores the state of the configuration registers of 2519 * all immediate child nodes. 2520 * 2521 * used by: db_attach() on resume 2522 * 2523 * return value: none 2524 */ 2525 static int 2526 db_restore_config_regs(db_ctrl_t *dbp) 2527 { 2528 int i; 2529 dev_info_t *dip; 2530 ddi_acc_handle_t config_handle; 2531 db_cfg_state_t *statep = dbp->db_config_state_p; 2532 2533 for (i = 0; i < dbp->config_state_index; i++, statep++) { 2534 dip = statep->dip; 2535 if (!dip) { 2536 cmn_err(CE_WARN, 2537 "%s#%d: skipping bad dev info (index %d)", 2538 ddi_driver_name(dbp->dip), 2539 ddi_get_instance(dbp->dip), i); 2540 continue; 2541 } 2542 if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) { 2543 cmn_err(CE_WARN, 2544 "%s#%d: can't config space for %s#%d", 2545 ddi_driver_name(dbp->dip), 2546 ddi_get_instance(dbp->dip), 2547 ddi_driver_name(dip), 2548 ddi_get_instance(dip)); 2549 continue; 2550 } 2551 pci_config_put16(config_handle, PCI_CONF_COMM, statep->command); 2552 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) 2553 pci_config_put16(config_handle, PCI_BCNF_BCNTRL, 2554 statep->bridge_control); 2555 pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ, 2556 statep->cache_line_size); 2557 pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER, 2558 statep->latency_timer); 2559 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) 2560 pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER, 2561 statep->sec_latency_timer); 2562 pci_config_teardown(&config_handle); 2563 } 2564 2565 kmem_free(dbp->db_config_state_p, 2566 dbp->config_state_index * sizeof (db_cfg_state_t)); 2567 dbp->db_config_state_p = NULL; 2568 dbp->config_state_index = 0; 2569 2570 return (DDI_SUCCESS); 2571 } 2572 2573 /* put a type 0/1 address on the bus */ 2574 static void 2575 db_put_reg_conf_addr(db_acc_pvt_t *db_pvt, uint32_t conf_addr) 2576 { 2577 if (db_pvt->access_mode & DB_PCI_CONF_CYCLE_TYPE0)\ 2578 ddi_put32(db_pvt->handle, db_pvt->addr, (uint32_t)\ 2579 DB_PCI_CONF_CYCLE_TYPE0_ADDR((conf_addr)));\ 2580 else /* type 1 cycle */\ 2581 ddi_put32(db_pvt->handle, db_pvt->addr, (uint32_t)\ 2582 DB_PCI_CONF_CYCLE_TYPE1_ADDR((conf_addr))); 2583 } 2584 2585 /* Get 8bits data off the 32bit data */ 2586 static uint8_t 2587 db_get_data8(uint32_t addr, uint32_t data) 2588 { 2589 return (((data) >> (((addr) & 3) * 8)) & 0xff); 2590 } 2591 2592 /* Get 16bits data off the 32bit data */ 2593 static uint16_t 2594 db_get_data16(uint32_t addr, uint32_t data) 2595 { 2596 return (((data) >> (((addr) & 3) * 8)) & 0xffff); 2597 } 2598 2599 /* merge 8bit data into the 32bit data */ 2600 static uint32_t 2601 db_put_data8(uint32_t addr, uint32_t rdata, uint8_t wdata) 2602 { 2603 return ((rdata & (~((0xff << ((((addr) & 3) * 8))) & 0xffffffff))) | 2604 (((wdata) & 0xff)<<((((addr) & 3))*8))); 2605 } 2606 2607 /* merge 16bit data into the 32bit data */ 2608 static uint32_t 2609 db_put_data16(uint32_t addr, uint32_t rdata, uint16_t wdata) 2610 { 2611 return ((rdata & (~((0xffff << ((((addr) & 3) * 8))) & 0xffffffff))) | 2612 (((wdata) & 0xffff) << ((((addr) & 3))*8))); 2613 } 2614 2615 2616 /* 2617 * For the next set of PCI configuration IO calls, we need 2618 * to make sure we own the bus before generating the config cycles, 2619 * using the drawbridge's semaphore method. 2620 */ 2621 2622 /* 2623 * Function to read 8 bit data off the PCI configuration space behind 2624 * the 21554's host interface. 2625 */ 2626 static uint8_t 2627 db_ddi_get8(ddi_acc_impl_t *handle, uint8_t *addr) 2628 { 2629 uint32_t data; 2630 2631 data = db_ddi_get32(handle, (uint32_t *)addr); 2632 return (db_get_data8((uint32_t)(uintptr_t)addr, data)); 2633 } 2634 2635 /* 2636 * Function to read 16 bit data off the PCI configuration space behind 2637 * the 21554's host interface. 2638 */ 2639 static uint16_t 2640 db_ddi_get16(ddi_acc_impl_t *handle, uint16_t *addr) 2641 { 2642 uint32_t data; 2643 2644 data = db_ddi_get32(handle, (uint32_t *)addr); 2645 return (db_get_data16((uint32_t)(uintptr_t)addr, data)); 2646 } 2647 2648 /* 2649 * Function to read 32 bit data off the PCI configuration space behind 2650 * the 21554's host interface. 2651 */ 2652 static uint32_t 2653 db_ddi_get32(ddi_acc_impl_t *handle, uint32_t *addr) 2654 { 2655 db_acc_pvt_t *db_pvt = (db_acc_pvt_t *) 2656 handle->ahi_common.ah_bus_private; 2657 uint32_t wait_count = 0; 2658 uint32_t data; 2659 db_ctrl_t *dbp; 2660 2661 dbp = db_pvt->dbp; 2662 2663 mutex_enter(&dbp->db_busown); 2664 2665 if (db_use_config_own_bit) { 2666 /* 2667 * check if (upstream/downstream)configuration address own 2668 * bit set. With this set, we cannot proceed. 2669 */ 2670 while (((ddi_get8(db_pvt->handle, db_pvt->bus_own)) & 2671 db_pvt->mask) == db_pvt->mask) { 2672 #ifdef DEBUG 2673 if (dbp->db_pci_max_wait_count < wait_count) 2674 dbp->db_pci_max_wait_count = wait_count; 2675 #endif 2676 drv_usecwait(db_pci_own_wait); 2677 if (++wait_count == db_pci_max_wait) { 2678 /* 2679 * the man page for pci_config_* routines do 2680 * Not specify any error condition values. 2681 */ 2682 cmn_err(CE_WARN, 2683 "%s#%d: pci config bus own error", 2684 ddi_driver_name(dbp->dip), 2685 ddi_get_instance(dbp->dip)); 2686 dbp->db_pci_err_count++; 2687 mutex_exit(&dbp->db_busown); 2688 return ((uint32_t)DB_CONF_FAILURE); 2689 } 2690 } 2691 wait_count = 0; 2692 } 2693 2694 db_put_reg_conf_addr(db_pvt, (uint32_t)(uintptr_t)addr); 2695 data = ddi_get32(db_pvt->handle, (uint32_t *)db_pvt->data); 2696 2697 if (db_use_config_own_bit) { 2698 while (((ddi_get8(db_pvt->handle, db_pvt->bus_release)) & 2699 db_pvt->mask) == db_pvt->mask) { 2700 #ifdef DEBUG 2701 if (dbp->db_pci_max_wait_count < wait_count) 2702 dbp->db_pci_max_wait_count = wait_count; 2703 #endif 2704 drv_usecwait(db_pci_release_wait); 2705 if (++wait_count == db_pci_max_wait) { 2706 /* 2707 * the man page for pci_config_* routines do 2708 * not specify any error condition values. 2709 */ 2710 cmn_err(CE_WARN, 2711 "%s#%d: pci config bus release error", 2712 ddi_driver_name(dbp->dip), 2713 ddi_get_instance(dbp->dip)); 2714 dbp->db_pci_err_count++; 2715 mutex_exit(&dbp->db_busown); 2716 return ((uint32_t)DB_CONF_FAILURE); 2717 } 2718 data = ddi_get32(db_pvt->handle, 2719 (uint32_t *)db_pvt->data); 2720 } 2721 } 2722 2723 mutex_exit(&dbp->db_busown); 2724 2725 return (data); 2726 } 2727 2728 /* 2729 * Function to read 64 bit data off the PCI configuration space behind 2730 * the 21554's host interface. 2731 */ 2732 static uint64_t 2733 db_ddi_get64(ddi_acc_impl_t *handle, uint64_t *addr) 2734 { 2735 uint64_t udata, ldata; 2736 2737 ldata = (uint32_t)db_ddi_get32(handle, (uint32_t *)addr); 2738 udata = (uint32_t)db_ddi_get32(handle, (uint32_t *)addr + 1); 2739 return (ldata | (udata << 32)); 2740 } 2741 2742 /* 2743 * Function to write 8 bit data into the PCI configuration space behind 2744 * the 21554's host interface. 2745 */ 2746 static void 2747 db_ddi_put8(ddi_acc_impl_t *handle, uint8_t *addr, uint8_t data) 2748 { 2749 uint32_t rdata; 2750 2751 rdata = db_ddi_get32(handle, (uint32_t *)addr); 2752 db_ddi_put32(handle, (uint32_t *)addr, 2753 db_put_data8((uint32_t)(uintptr_t)addr, rdata, data)); 2754 } 2755 2756 /* 2757 * Function to write 16 bit data into the PCI configuration space behind 2758 * the 21554's host interface. 2759 */ 2760 static void 2761 db_ddi_put16(ddi_acc_impl_t *handle, uint16_t *addr, uint16_t data) 2762 { 2763 uint32_t rdata; 2764 2765 rdata = db_ddi_get32(handle, (uint32_t *)addr); 2766 db_ddi_put32(handle, (uint32_t *)addr, 2767 db_put_data16((uint32_t)(uintptr_t)addr, rdata, data)); 2768 } 2769 2770 /* 2771 * Function to write 32 bit data into the PCI configuration space behind 2772 * the 21554's host interface. 2773 */ 2774 static void 2775 db_ddi_put32(ddi_acc_impl_t *handle, uint32_t *addr, uint32_t data) 2776 { 2777 db_acc_pvt_t *db_pvt = (db_acc_pvt_t *) 2778 handle->ahi_common.ah_bus_private; 2779 db_ctrl_t *dbp; 2780 uint32_t wait_count = 0; 2781 2782 dbp = db_pvt->dbp; 2783 2784 mutex_enter(&dbp->db_busown); 2785 2786 if (db_use_config_own_bit) { 2787 /* 2788 * check if (upstream/downstream)configuration address own 2789 * bit set. with this set, we cannot proceed. 2790 */ 2791 while (((ddi_get8(db_pvt->handle, db_pvt->bus_own)) & 2792 db_pvt->mask) == db_pvt->mask) { 2793 #ifdef DEBUG 2794 if (dbp->db_pci_max_wait_count < wait_count) 2795 dbp->db_pci_max_wait_count = wait_count; 2796 #endif 2797 drv_usecwait(db_pci_own_wait); 2798 if (++wait_count == db_pci_max_wait) { 2799 /* 2800 * Since the return value is void here, 2801 * we may need to print a message, as this 2802 * could be a serious situation. 2803 */ 2804 cmn_err(CE_WARN, 2805 "%s#%d: pci config bus own error", 2806 ddi_driver_name(dbp->dip), 2807 ddi_get_instance(dbp->dip)); 2808 dbp->db_pci_err_count++; 2809 mutex_exit(&dbp->db_busown); 2810 return; 2811 } 2812 } 2813 wait_count = 0; 2814 } 2815 2816 db_put_reg_conf_addr(db_pvt, (uint32_t)(uintptr_t)addr); 2817 ddi_put32(db_pvt->handle, (uint32_t *)db_pvt->data, data); 2818 2819 if (db_use_config_own_bit) { 2820 while (((ddi_get8(db_pvt->handle, db_pvt->bus_release)) & 2821 db_pvt->mask) == db_pvt->mask) { 2822 #ifdef DEBUG 2823 if (dbp->db_pci_max_wait_count < wait_count) 2824 dbp->db_pci_max_wait_count = wait_count; 2825 #endif 2826 drv_usecwait(db_pci_release_wait); 2827 if (++wait_count == db_pci_max_wait) { 2828 /* 2829 * the man page for pci_config_* routines do 2830 * Not specify any error condition values. 2831 */ 2832 cmn_err(CE_WARN, 2833 "%s#%d: pci config bus release error", 2834 ddi_driver_name(dbp->dip), 2835 ddi_get_instance(dbp->dip)); 2836 dbp->db_pci_err_count++; 2837 mutex_exit(&dbp->db_busown); 2838 return; 2839 } 2840 ddi_put32(db_pvt->handle, (uint32_t *)db_pvt->data, 2841 data); 2842 } 2843 } 2844 2845 mutex_exit(&dbp->db_busown); 2846 } 2847 2848 /* 2849 * Function to write 64 bit data into the PCI configuration space behind 2850 * the 21554's host interface. 2851 */ 2852 static void 2853 db_ddi_put64(ddi_acc_impl_t *handle, uint64_t *addr, uint64_t data) 2854 { 2855 db_ddi_put32(handle, (uint32_t *)addr, (uint32_t)(data & 0xffffffff)); 2856 db_ddi_put32(handle, (uint32_t *)addr + 1, (uint32_t)(data >> 32)); 2857 } 2858 2859 /* 2860 * Function to rep read 8 bit data off the PCI configuration space behind 2861 * the 21554's host interface. 2862 */ 2863 static void 2864 db_ddi_rep_get8(ddi_acc_impl_t *handle, uint8_t *host_addr, 2865 uint8_t *dev_addr, size_t repcount, uint_t flags) 2866 { 2867 if (flags == DDI_DEV_AUTOINCR) 2868 for (; repcount; repcount--) 2869 *host_addr++ = db_ddi_get8(handle, dev_addr++); 2870 else 2871 for (; repcount; repcount--) 2872 *host_addr++ = db_ddi_get8(handle, dev_addr); 2873 } 2874 2875 /* 2876 * Function to rep read 16 bit data off the PCI configuration space behind 2877 * the 21554's host interface. 2878 */ 2879 static void 2880 db_ddi_rep_get16(ddi_acc_impl_t *handle, uint16_t *host_addr, 2881 uint16_t *dev_addr, size_t repcount, uint_t flags) 2882 { 2883 if (flags == DDI_DEV_AUTOINCR) 2884 for (; repcount; repcount--) 2885 *host_addr++ = db_ddi_get16(handle, dev_addr++); 2886 else 2887 for (; repcount; repcount--) 2888 *host_addr++ = db_ddi_get16(handle, dev_addr); 2889 } 2890 2891 /* 2892 * Function to rep read 32 bit data off the PCI configuration space behind 2893 * the 21554's host interface. 2894 */ 2895 static void 2896 db_ddi_rep_get32(ddi_acc_impl_t *handle, uint32_t *host_addr, 2897 uint32_t *dev_addr, size_t repcount, uint_t flags) 2898 { 2899 if (flags == DDI_DEV_AUTOINCR) 2900 for (; repcount; repcount--) 2901 *host_addr++ = db_ddi_get32(handle, dev_addr++); 2902 else 2903 for (; repcount; repcount--) 2904 *host_addr++ = db_ddi_get32(handle, dev_addr); 2905 } 2906 2907 /* 2908 * Function to rep read 64 bit data off the PCI configuration space behind 2909 * the 21554's host interface. 2910 */ 2911 static void 2912 db_ddi_rep_get64(ddi_acc_impl_t *handle, uint64_t *host_addr, 2913 uint64_t *dev_addr, size_t repcount, uint_t flags) 2914 { 2915 if (flags == DDI_DEV_AUTOINCR) 2916 for (; repcount; repcount--) 2917 *host_addr++ = db_ddi_get64(handle, dev_addr++); 2918 else 2919 for (; repcount; repcount--) 2920 *host_addr++ = db_ddi_get64(handle, dev_addr); 2921 } 2922 2923 /* 2924 * Function to rep write 8 bit data into the PCI configuration space behind 2925 * the 21554's host interface. 2926 */ 2927 static void 2928 db_ddi_rep_put8(ddi_acc_impl_t *handle, uint8_t *host_addr, 2929 uint8_t *dev_addr, size_t repcount, uint_t flags) 2930 { 2931 if (flags == DDI_DEV_AUTOINCR) 2932 for (; repcount; repcount--) 2933 db_ddi_put8(handle, dev_addr++, *host_addr++); 2934 else 2935 for (; repcount; repcount--) 2936 db_ddi_put8(handle, dev_addr, *host_addr++); 2937 } 2938 2939 /* 2940 * Function to rep write 16 bit data into the PCI configuration space behind 2941 * the 21554's host interface. 2942 */ 2943 static void 2944 db_ddi_rep_put16(ddi_acc_impl_t *handle, uint16_t *host_addr, 2945 uint16_t *dev_addr, size_t repcount, uint_t flags) 2946 { 2947 if (flags == DDI_DEV_AUTOINCR) 2948 for (; repcount; repcount--) 2949 db_ddi_put16(handle, dev_addr++, *host_addr++); 2950 else 2951 for (; repcount; repcount--) 2952 db_ddi_put16(handle, dev_addr, *host_addr++); 2953 } 2954 2955 /* 2956 * Function to rep write 32 bit data into the PCI configuration space behind 2957 * the 21554's host interface. 2958 */ 2959 static void 2960 db_ddi_rep_put32(ddi_acc_impl_t *handle, uint32_t *host_addr, 2961 uint32_t *dev_addr, size_t repcount, uint_t flags) 2962 { 2963 if (flags == DDI_DEV_AUTOINCR) 2964 for (; repcount; repcount--) 2965 db_ddi_put32(handle, dev_addr++, *host_addr++); 2966 else 2967 for (; repcount; repcount--) 2968 db_ddi_put32(handle, dev_addr, *host_addr++); 2969 } 2970 2971 /* 2972 * Function to rep write 64 bit data into the PCI configuration space behind 2973 * the 21554's host interface. 2974 */ 2975 static void 2976 db_ddi_rep_put64(ddi_acc_impl_t *handle, uint64_t *host_addr, 2977 uint64_t *dev_addr, size_t repcount, uint_t flags) 2978 { 2979 if (flags == DDI_DEV_AUTOINCR) 2980 for (; repcount; repcount--) 2981 db_ddi_put64(handle, dev_addr++, *host_addr++); 2982 else 2983 for (; repcount; repcount--) 2984 db_ddi_put64(handle, dev_addr, *host_addr++); 2985 } 2986 2987 #ifdef DEBUG 2988 2989 static void 2990 db_debug(uint64_t func_id, dev_info_t *dip, char *fmt, 2991 uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5) 2992 { 2993 char *s = NULL; 2994 uint_t dip_no_disp = 0; 2995 2996 if (func_id & DB_DONT_DISPLAY_DIP) { 2997 dip_no_disp = 1; 2998 } 2999 if (db_debug_funcs & func_id) { 3000 switch (func_id) { 3001 case DB_INIT: s = "_init"; break; 3002 case DB_FINI: s = "_fini"; break; 3003 case DB_INFO: s = "_info"; break; 3004 case DB_GETINFO: s = "getinfo"; break; 3005 case DB_ATTACH: s = "attach"; break; 3006 case DB_DETACH: s = "detach"; break; 3007 case DB_CTLOPS: s = "ctlops"; break; 3008 case DB_INITCHILD: s = "initchild"; break; 3009 case DB_REMOVECHILD: s = "removechild"; break; 3010 case DB_INTR_OPS: s = "intr_ops"; break; 3011 case DB_PCI_MAP: s = "map"; break; 3012 case DB_SAVE_CONF_REGS: s = "save_conf_regs"; break; 3013 case DB_REST_CONF_REGS: s = "restore_conf_regs"; break; 3014 case DB_INTR: s = "intr"; break; 3015 case DB_OPEN: s = "open"; break; 3016 case DB_CLOSE: s = "close"; break; 3017 case DB_IOCTL: s = "ioctl"; break; 3018 case DB_DVMA: s = "set_dvma_range"; break; 3019 3020 default: s = "PCI debug unknown"; break; 3021 } 3022 3023 if (s && !dip_no_disp) { 3024 prom_printf("%s(%d): %s: ", ddi_driver_name(dip), 3025 ddi_get_instance(dip), s); 3026 } 3027 prom_printf(fmt, a1, a2, a3, a4, a5); 3028 } 3029 } 3030 #endif 3031 3032 static int db_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, 3033 int flags, char *name, caddr_t valuep, int *lengthp) 3034 { 3035 minor_t minor = getminor(dev); 3036 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor); 3037 3038 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 3039 3040 3041 if (dbp == NULL) 3042 return (ENXIO); 3043 3044 if (dbp->dev_state & DB_SECONDARY_NEXUS) 3045 return ((pcihp_get_cb_ops())->cb_prop_op(dev, dip, 3046 prop_op, flags, name, valuep, lengthp)); 3047 3048 return (ddi_prop_op(dev, dip, prop_op, flags, name, valuep, lengthp)); 3049 } 3050 3051 /* 3052 * Initialize our FMA resources 3053 */ 3054 static void 3055 db_fm_init(db_ctrl_t *db_p) 3056 { 3057 ddi_fm_error_t derr; 3058 3059 db_p->fm_cap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE | 3060 DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE; 3061 3062 /* 3063 * Request our capability level and get our parents capability 3064 * and ibc. 3065 */ 3066 ddi_fm_init(db_p->dip, &db_p->fm_cap, &db_p->fm_ibc); 3067 ASSERT((db_p->fm_cap & DDI_FM_EREPORT_CAPABLE) && 3068 (db_p->fm_cap & DDI_FM_ERRCB_CAPABLE)); 3069 3070 pci_ereport_setup(db_p->dip); 3071 3072 /* 3073 * clear any outstanding error bits 3074 */ 3075 bzero(&derr, sizeof (ddi_fm_error_t)); 3076 derr.fme_version = DDI_FME_VERSION; 3077 derr.fme_flag = DDI_FM_ERR_EXPECTED; 3078 pci_ereport_post(db_p->dip, &derr, NULL); 3079 pci_bdg_ereport_post(db_p->dip, &derr, NULL); 3080 3081 /* 3082 * Register error callback with our parent. 3083 */ 3084 ddi_fm_handler_register(db_p->dip, db_err_callback, NULL); 3085 } 3086 3087 /* 3088 * Breakdown our FMA resources 3089 */ 3090 static void 3091 db_fm_fini(db_ctrl_t *db_p) 3092 { 3093 /* 3094 * Clean up allocated fm structures 3095 */ 3096 ddi_fm_handler_unregister(db_p->dip); 3097 pci_ereport_teardown(db_p->dip); 3098 ddi_fm_fini(db_p->dip); 3099 } 3100 3101 /* 3102 * Initialize FMA resources for children devices. Called when 3103 * child calls ddi_fm_init(). 3104 */ 3105 /*ARGSUSED*/ 3106 static int 3107 db_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap, 3108 ddi_iblock_cookie_t *ibc) 3109 { 3110 db_ctrl_t *db_p = (db_ctrl_t *)ddi_get_soft_state(db_state, 3111 ddi_get_instance(dip)); 3112 *ibc = db_p->fm_ibc; 3113 return (db_p->fm_cap); 3114 } 3115 3116 /* 3117 * FMA registered error callback 3118 */ 3119 static int 3120 db_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *impl_data) 3121 { 3122 uint16_t pci_cfg_stat, pci_cfg_sec_stat; 3123 3124 ASSERT(impl_data == NULL); 3125 pci_ereport_post(dip, derr, &pci_cfg_stat); 3126 pci_bdg_ereport_post(dip, derr, &pci_cfg_sec_stat); 3127 return (pci_bdg_check_status(dip, derr, pci_cfg_stat, 3128 pci_cfg_sec_stat)); 3129 } 3130 3131 static void 3132 db_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle) 3133 { 3134 i_ndi_busop_access_enter(dip, handle); 3135 } 3136 3137 /* ARGSUSED */ 3138 static void 3139 db_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle) 3140 { 3141 i_ndi_busop_access_exit(dip, handle); 3142 } 3143