1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Intel 21554 PCI to PCI bus bridge nexus driver for sun4u platforms. 30 * Please note that 21554 is not a transparent bridge. 31 * This driver can be used when the 21554 bridge is used like a 32 * transparent bridge. The host OBP or the OS PCI Resource Allocator 33 * (during a hotplug/hotswap operation) must represent this device 34 * as a nexus and do the device tree representation of the child 35 * nodes underneath. 36 * Interrupt routing of the children must be done as per the PCI 37 * specifications recommendation similar to that of a transparent 38 * bridge. 39 * Address translations from secondary across primary can be 1:1 40 * or non 1:1. Currently only 1:1 translations are supported. 41 * Configuration cycles are indirect. Memory and IO cycles are direct. 42 */ 43 44 /* 45 * INCLUDES 46 */ 47 #include <sys/stat.h> 48 #include <sys/conf.h> 49 #include <sys/kmem.h> 50 #include <sys/debug.h> 51 #include <sys/modctl.h> 52 #include <sys/autoconf.h> 53 #include <sys/ddi_impldefs.h> 54 #include <sys/ddi_subrdefs.h> 55 #include <sys/pci.h> 56 #include <sys/pci/pci_nexus.h> 57 #include <sys/pci/pci_regs.h> 58 #include <sys/pci/db21554_config.h> /* 21554 configuration space registers */ 59 #include <sys/pci/db21554_csr.h> /* 21554 control status register layout */ 60 #include <sys/pci/db21554_ctrl.h> /* driver private control structure */ 61 #include <sys/pci/db21554_debug.h> /* driver debug declarations */ 62 #include <sys/ddi.h> 63 #include <sys/sunddi.h> 64 #include <sys/sunndi.h> 65 #include <sys/fm/protocol.h> 66 #include <sys/ddifm.h> 67 #include <sys/promif.h> 68 #include <sys/file.h> 69 #include <sys/hotplug/pci/pcihp.h> 70 71 /* 72 * DEFINES. 73 */ 74 #define DB_DEBUG 75 #define DB_MODINFO_DESCRIPTION "Intel/21554 pci-pci nexus:v%I%" 76 #define DB_DVMA_START 0xc0000000 77 #define DB_DVMA_LEN 0x20000000 78 79 #ifdef DB_DEBUG 80 /* ioctl definitions */ 81 #define DB_PCI_READ_CONF_HEADER 1 82 #define DEF_INVALID_REG_VAL -1 83 84 /* Default values for secondary cache line and latency timer */ 85 #define DB_SEC_LATENCY_TIMER_VAL 0x40 86 #define DB_SEC_CACHELN_SIZE_VAL 0x10 87 88 /* complete chip status information */ 89 typedef struct db_pci_data { 90 char name[256]; 91 uint32_t instance; 92 db_pci_header_t pri_hdr; 93 db_pci_header_t sec_hdr; 94 db_conf_regs_t conf_regs; 95 } db_pci_data_t; 96 #endif 97 98 /* 99 * LOCALS 100 */ 101 102 /* 103 * The next set of variables are control parameters for debug purposes only. 104 * Changing the default values as assigned below are not recommended. 105 * In some cases, the non-default values are mostly application specific and 106 * hence may not have been tested yet. 107 * 108 * db_conf_map_mode : specifies the access method used for generating 109 * configuration cycles. Default value indicates 110 * the indirect configuration method. 111 * db_io_map_mode : specifies the access method used for generating 112 * IO cycles. Default value indicates the direct 113 * method. 114 * db_pci_own_wait : For indirect cycles, indicates the wait period 115 * for acquiring the bus, when the bus is busy. 116 * db_pci_release_wait:For indirect cycles, indicates the wait period 117 * for releasing the bus when the bus is busy. 118 * db_pci_max_wait : max. wait time when bus is busy for indirect cycles 119 * db_set_latency_timer_register : 120 * when 1, the driver overwrites the OBP assigned 121 * latency timer register setting for every child 122 * device during child initialization. 123 * db_set_cache_line_size_register : 124 * when 1, the driver overwrites the OBP assigned 125 * cache line register setting for every child 126 * device during child initialization. 127 * db_use_config_own_bit: 128 * when 1, the driver will use the "config own bit" 129 * for accessing the configuration address and data 130 * registers. 131 */ 132 static uint32_t db_pci_own_wait = DB_PCI_WAIT_MS; 133 static uint32_t db_pci_release_wait = DB_PCI_WAIT_MS; 134 static uint32_t db_pci_max_wait = DB_PCI_TIMEOUT; 135 static uint32_t db_conf_map_mode = DB_CONF_MAP_INDIRECT_CONF; 136 static uint32_t db_io_map_mode = DB_IO_MAP_DIRECT; 137 static uint32_t db_set_latency_timer_register = 1; 138 static uint32_t db_set_cache_line_size_register = 1; 139 static uint32_t db_use_config_own_bit = 0; 140 141 /* 142 * Properties that can be set via .conf files. 143 */ 144 145 /* 146 * By default, we forward SERR# from secondary to primary. This behavior 147 * can be controlled via a property "serr-fwd-enable", type integer. 148 * Values are 0 or 1. 149 * 0 means 'do not forward SERR#'. 150 * 1 means forwards SERR# to the host. Should be the default. 151 */ 152 static uint32_t db_serr_fwd_enable = 1; 153 154 /* 155 * The next set of parameters are performance tuning parameters. 156 * These are in the form of properties settable through a .conf file. 157 * In case if the properties are absent the following defaults are assumed. 158 * These initial default values can be overwritten via /etc/system also. 159 * 160 * -1 means no setting is done ie. we either get OBP assigned value 161 * or reset values (at hotplug time for example). 162 */ 163 164 /* primary latency timer: property "p-latency-timer" : type integer */ 165 static int8_t p_latency_timer = DEF_INVALID_REG_VAL; 166 167 /* secondary latency timer: property "s-latency-timer": type integer */ 168 /* 169 * Currently on the secondary side the latency timer is not 170 * set by the serial PROM which causes performance degradation. 171 * Set the secondary latency timer register. 172 */ 173 static int8_t s_latency_timer = DB_SEC_LATENCY_TIMER_VAL; 174 175 /* primary cache line size: property "p-cache-line-size" : type integer */ 176 static int8_t p_cache_line_size = DEF_INVALID_REG_VAL; 177 178 /* secondary cache line size: property "s-cache-line-size" : type integer */ 179 /* 180 * Currently on the secondary side the cache line size is not 181 * set by the serial PROM which causes performance degradation. 182 * Set the secondary cache line size register. 183 */ 184 static int8_t s_cache_line_size = DB_SEC_CACHELN_SIZE_VAL; 185 186 /* 187 * control primary posted write queue threshold limit: 188 * property "p-pwrite-threshold" : type integer : values are 0 or 1. 189 * 1 enables control. 0 does not, and is the default reset value. 190 */ 191 static int8_t p_pwrite_threshold = DEF_INVALID_REG_VAL; 192 193 /* 194 * control secondary posted write queue threshold limit: 195 * property "s-pwrite-threshold" : type integer : values are 0 or 1. 196 * 1 enables control. 0 does not, and is the default reset value. 197 */ 198 static int8_t s_pwrite_threshold = DEF_INVALID_REG_VAL; 199 200 /* 201 * control read queue threshold for initiating delayed read transaction 202 * on primary bus. 203 * property "p-dread-threshold" : type integer: values are 204 * 205 * 0 : reset value, default behavior: at least 8DWords free for all MR 206 * 1 : reserved 207 * 2 : at least one cache line free for MRL and MRM, 8 DWords free for MR 208 * 3 : at least one cache line free for all MR 209 */ 210 static int8_t p_dread_threshold = DEF_INVALID_REG_VAL; 211 212 /* 213 * control read queue threshold for initiating delayed read transaction 214 * on secondary bus. 215 * property "s-dread-threshold" : type integer: values are 216 * 217 * 0 : reset value, default behavior: at least 8DWords free for all MR 218 * 1 : reserved 219 * 2 : at least one cache line free for MRL and MRM, 8 DWords free for MR 220 * 3 : at least one cache line free for all MR 221 */ 222 static int8_t s_dread_threshold = DEF_INVALID_REG_VAL; 223 224 /* 225 * control how 21554 issues delayed transactions on the target bus. 226 * property "delayed-trans-order" : type integer: values are 0 or 1. 227 * 1 means repeat transaction on same target on target retries. 228 * 0 is the reset/default value, and means enable round robin based 229 * reads on other targets in read queue on any target retries. 230 */ 231 static int8_t delayed_trans_order = DEF_INVALID_REG_VAL; 232 233 /* 234 * In case if the system DVMA information is not available, as it is 235 * prior to s28q1, the system dvma range can be set via these parameters. 236 */ 237 static uint32_t db_dvma_start = DB_DVMA_START; 238 static uint32_t db_dvma_len = DB_DVMA_LEN; 239 240 /* 241 * Default command register settings for all PCI nodes this nexus initializes. 242 */ 243 static uint16_t db_command_default = 244 PCI_COMM_SERR_ENABLE | 245 PCI_COMM_PARITY_DETECT | 246 PCI_COMM_ME | 247 PCI_COMM_MAE | 248 PCI_COMM_IO | 249 PCI_COMM_BACK2BACK_ENAB | 250 PCI_COMM_MEMWR_INVAL; 251 252 static int db_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 253 static int db_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 254 static void db_get_perf_parameters(db_ctrl_t *dbp); 255 static void db_set_perf_parameters(db_ctrl_t *dbp); 256 static void db_enable_io(db_ctrl_t *dbp); 257 static void db_orientation(db_ctrl_t *dbp); 258 static void db_set_dvma_range(db_ctrl_t *dbp); 259 static int db_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 260 void **result); 261 static int db_pci_map(dev_info_t *, dev_info_t *, ddi_map_req_t *, 262 off_t, off_t, caddr_t *); 263 static int db_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, 264 void *, void *); 265 static int db_intr_ops(dev_info_t *dip, dev_info_t *rdip, 266 ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, 267 void *result); 268 static dev_info_t *db_get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip); 269 static int db_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap, 270 ddi_iblock_cookie_t *ibc); 271 static void db_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle); 272 static void db_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle); 273 274 struct bus_ops db_bus_ops = { 275 BUSO_REV, 276 db_pci_map, 277 0, 278 0, 279 0, 280 i_ddi_map_fault, 281 ddi_dma_map, 282 ddi_dma_allochdl, 283 ddi_dma_freehdl, 284 ddi_dma_bindhdl, 285 ddi_dma_unbindhdl, 286 ddi_dma_flush, 287 ddi_dma_win, 288 ddi_dma_mctl, 289 db_ctlops, 290 ddi_bus_prop_op, 291 ndi_busop_get_eventcookie, 292 ndi_busop_add_eventcall, 293 ndi_busop_remove_eventcall, 294 ndi_post_event, 295 0, 296 0, 297 0, 298 db_fm_init_child, 299 NULL, 300 db_bus_enter, 301 db_bus_exit, 302 0, 303 db_intr_ops 304 }; 305 306 static int db_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p); 307 static int db_close(dev_t dev, int flag, int otyp, cred_t *cred_p); 308 static int db_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, 309 cred_t *cred_p, int *rval_p); 310 #ifdef DB_DEBUG 311 static dev_info_t *db_lookup_child_name(db_ctrl_t *dbp, char *name, 312 int instance); 313 static void db_pci_get_header(ddi_acc_handle_t config_handle, 314 db_pci_header_t *ph, off_t hdr_off); 315 static void db_pci_get_conf_regs(ddi_acc_handle_t config_handle, 316 db_conf_regs_t *cr); 317 #endif /* DB_DEBUG */ 318 319 #ifdef DEBUG 320 static void 321 db_debug(uint64_t func_id, dev_info_t *dip, char *fmt, 322 uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5); 323 #endif 324 325 static int db_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, 326 int flags, char *name, caddr_t valuep, int *lengthp); 327 328 static struct cb_ops db_cb_ops = { 329 db_open, /* open */ 330 db_close, /* close */ 331 nulldev, /* strategy */ 332 nulldev, /* print */ 333 nulldev, /* dump */ 334 nulldev, /* read */ 335 nulldev, /* write */ 336 db_ioctl, /* ioctl */ 337 nodev, /* devmap */ 338 nodev, /* mmap */ 339 nodev, /* segmap */ 340 nochpoll, /* poll */ 341 db_prop_op, /* cb_prop_op */ 342 NULL, /* streamtab */ 343 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */ 344 CB_REV, /* rev */ 345 nodev, /* int (*cb_aread)() */ 346 nodev /* int (*cb_awrite)() */ 347 }; 348 349 static uint8_t db_ddi_get8(ddi_acc_impl_t *handle, uint8_t *addr); 350 static uint16_t db_ddi_get16(ddi_acc_impl_t *handle, uint16_t *addr); 351 static uint32_t db_ddi_get32(ddi_acc_impl_t *handle, uint32_t *addr); 352 static uint64_t db_ddi_get64(ddi_acc_impl_t *handle, uint64_t *addr); 353 static void db_ddi_put8(ddi_acc_impl_t *handle, uint8_t *addr, 354 uint8_t data); 355 static void db_ddi_put16(ddi_acc_impl_t *handle, uint16_t *addr, 356 uint16_t data); 357 static void db_ddi_put32(ddi_acc_impl_t *handle, uint32_t *addr, 358 uint32_t data); 359 static void db_ddi_put64(ddi_acc_impl_t *handle, uint64_t *addr, 360 uint64_t data); 361 static void db_ddi_rep_get8(ddi_acc_impl_t *handle, uint8_t *host_addr, 362 uint8_t *dev_addr, size_t repcount, uint_t flags); 363 static void db_ddi_rep_get16(ddi_acc_impl_t *handle, uint16_t *host_addr, 364 uint16_t *dev_addr, size_t repcount, uint_t flags); 365 static void db_ddi_rep_get32(ddi_acc_impl_t *handle, uint32_t *host_addr, 366 uint32_t *dev_addr, size_t repcount, uint_t flags); 367 static void db_ddi_rep_get64(ddi_acc_impl_t *handle, uint64_t *host_addr, 368 uint64_t *dev_addr, size_t repcount, uint_t flags); 369 static void db_ddi_rep_put8(ddi_acc_impl_t *handle, uint8_t *host_addr, 370 uint8_t *dev_addr, size_t repcount, uint_t flags); 371 static void db_ddi_rep_put16(ddi_acc_impl_t *handle, uint16_t *host_addr, 372 uint16_t *dev_addr, size_t repcount, uint_t flags); 373 static void db_ddi_rep_put32(ddi_acc_impl_t *handle, uint32_t *host_addr, 374 uint32_t *dev_addr, size_t repcount, uint_t flags); 375 static void db_ddi_rep_put64(ddi_acc_impl_t *handle, uint64_t *host_addr, 376 uint64_t *dev_addr, size_t repcount, uint_t flags); 377 378 static struct dev_ops db_dev_ops = { 379 DEVO_REV, /* devo_rev */ 380 0, /* refcnt */ 381 db_getinfo, /* info */ 382 nulldev, /* identify */ 383 nulldev, /* probe */ 384 db_attach, /* attach */ 385 db_detach, /* detach */ 386 nulldev, /* reset */ 387 &db_cb_ops, /* driver operations */ 388 &db_bus_ops, /* bus operations */ 389 ddi_power 390 }; 391 392 393 /* 394 * Module linkage information for the kernel. 395 */ 396 397 static struct modldrv modldrv = { 398 &mod_driverops, /* Type of module */ 399 DB_MODINFO_DESCRIPTION, 400 &db_dev_ops /* driver ops */ 401 }; 402 403 static struct modlinkage modlinkage = { 404 MODREV_1, 405 (void *)&modldrv, 406 NULL 407 }; 408 409 /* soft state pointer and structure template. */ 410 static void *db_state; 411 412 /* 413 * forward function declarations: 414 */ 415 static void db_uninitchild(dev_info_t *); 416 static int db_initchild(dev_info_t *child); 417 static int db_create_pci_prop(dev_info_t *child); 418 static int db_save_config_regs(db_ctrl_t *dbp); 419 static int db_restore_config_regs(db_ctrl_t *dbp); 420 421 /* 422 * FMA error callback 423 * Register error handling callback with our parent. We will just call 424 * our children's error callbacks and return their status. 425 */ 426 static int db_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, 427 const void *impl_data); 428 429 /* 430 * init/fini routines to alloc/dealloc fm structures and 431 * register/unregister our callback. 432 */ 433 static void db_fm_init(db_ctrl_t *db_p); 434 static void db_fm_fini(db_ctrl_t *db_p); 435 436 int 437 _init(void) 438 { 439 int rc; 440 441 DB_DEBUG0(DB_INIT|DB_DONT_DISPLAY_DIP, NULL, "enter\n"); 442 if (((rc = ddi_soft_state_init(&db_state, 443 sizeof (db_ctrl_t), 1)) == 0) && 444 ((rc = mod_install(&modlinkage)) != 0)) 445 ddi_soft_state_fini(&db_state); 446 DB_DEBUG1(DB_INIT|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc); 447 return (rc); 448 } 449 450 451 int 452 _fini(void) 453 { 454 int rc; 455 456 DB_DEBUG0(DB_FINI|DB_DONT_DISPLAY_DIP, NULL, "enter\n"); 457 if ((rc = mod_remove(&modlinkage)) == 0) 458 ddi_soft_state_fini(&db_state); 459 DB_DEBUG1(DB_FINI|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc); 460 return (rc); 461 } 462 463 int 464 _info(struct modinfo *modinfop) 465 { 466 int rc; 467 rc = mod_info(&modlinkage, modinfop); 468 DB_DEBUG1(DB_INFO|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc); 469 return (rc); 470 } 471 472 /*ARGSUSED*/ 473 static int 474 db_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 475 { 476 db_ctrl_t *dbp; 477 int rc = DDI_FAILURE; 478 minor_t minor = getminor((dev_t)arg); 479 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor); 480 481 DB_DEBUG1(DB_GETINFO|DB_DONT_DISPLAY_DIP, dip, "enter:cmd=%d\n", 482 infocmd); 483 484 switch (infocmd) { 485 case DDI_INFO_DEVT2DEVINFO: 486 487 if ((dbp = ddi_get_soft_state(db_state, 488 instance)) != NULL) { 489 *result = dbp->dip; 490 rc = DDI_SUCCESS; 491 } else 492 *result = NULL; 493 break; 494 495 case DDI_INFO_DEVT2INSTANCE: 496 *result = (void *)(uintptr_t)instance; 497 rc = DDI_SUCCESS; 498 break; 499 500 default: 501 break; 502 } 503 DB_DEBUG2(DB_GETINFO|DB_DONT_DISPLAY_DIP, dip, 504 "exit: result=%x, rc=%d\n", *result, rc); 505 506 return (rc); 507 } 508 509 static int 510 db_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 511 { 512 int instance = ddi_get_instance(dip); 513 db_ctrl_t *dbp; 514 int rc = DDI_SUCCESS; 515 ddi_device_acc_attr_t db_csr_attr = { /* CSR map attributes */ 516 DDI_DEVICE_ATTR_V0, 517 DDI_STRUCTURE_LE_ACC, 518 DDI_STRICTORDER_ACC 519 }; 520 off_t bar_size; 521 int range_size; 522 char name[32]; 523 524 DB_DEBUG1(DB_ATTACH, dip, "enter: cmd=%d\n", cmd); 525 switch (cmd) { 526 527 case DDI_ATTACH: 528 if (ddi_soft_state_zalloc(db_state, instance) != DDI_SUCCESS) { 529 rc = DDI_FAILURE; 530 break; 531 } 532 533 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 534 535 dbp->dip = dip; 536 mutex_init(&dbp->db_mutex, NULL, MUTEX_DRIVER, NULL); 537 dbp->db_soft_state = DB_SOFT_STATE_CLOSED; 538 539 /* 540 * Cannot use pci_config_setup here as we'd need 541 * to get a pointer to the address map to be able 542 * to set the bus private handle during child map 543 * operation. 544 */ 545 if ((rc = ddi_regs_map_setup(dip, DB_PCI_CONF_RNUMBER, 546 (caddr_t *)&dbp->conf_io, DB_PCI_CONF_OFFSET, 547 PCI_CONF_HDR_SIZE, &db_csr_attr, &dbp->conf_handle)) 548 != DDI_SUCCESS) { 549 550 cmn_err(CE_WARN, 551 "%s#%d: cannot map configuration space", 552 ddi_driver_name(dip), ddi_get_instance(dip)); 553 mutex_destroy(&dbp->db_mutex); 554 ddi_soft_state_free(db_state, instance); 555 rc = DDI_FAILURE; 556 break; 557 } 558 559 db_get_perf_parameters(dbp); 560 561 if (ddi_dev_regsize(dip, DB_CSR_MEMBAR_RNUMBER, &bar_size) 562 != DDI_SUCCESS) { 563 cmn_err(CE_WARN, "%s#%d: cannot get memory CSR size", 564 ddi_driver_name(dbp->dip), 565 ddi_get_instance(dbp->dip)); 566 ddi_regs_map_free(&dbp->conf_handle); 567 mutex_destroy(&dbp->db_mutex); 568 ddi_soft_state_free(db_state, instance); 569 rc = DDI_FAILURE; 570 break; 571 } 572 573 /* map memory CSR space */ 574 if (ddi_regs_map_setup(dip, DB_CSR_MEMBAR_RNUMBER, 575 (caddr_t *)&dbp->csr_mem, DB_CSR_MEM_OFFSET, bar_size, 576 &db_csr_attr, &dbp->csr_mem_handle) != DDI_SUCCESS) { 577 578 cmn_err(CE_WARN, "%s#%d: cannot map memory CSR space", 579 ddi_driver_name(dbp->dip), 580 ddi_get_instance(dbp->dip)); 581 ddi_regs_map_free(&dbp->conf_handle); 582 mutex_destroy(&dbp->db_mutex); 583 ddi_soft_state_free(db_state, instance); 584 rc = DDI_FAILURE; 585 break; 586 } 587 588 if (ddi_dev_regsize(dip, DB_CSR_IOBAR_RNUMBER, &bar_size) 589 != DDI_SUCCESS) { 590 cmn_err(CE_WARN, "%s#%d: cannot get IO CSR size", 591 ddi_driver_name(dbp->dip), 592 ddi_get_instance(dbp->dip)); 593 ddi_regs_map_free(&dbp->csr_mem_handle); 594 ddi_regs_map_free(&dbp->conf_handle); 595 mutex_destroy(&dbp->db_mutex); 596 ddi_soft_state_free(db_state, instance); 597 rc = DDI_FAILURE; 598 break; 599 } 600 601 /* 602 * map IO CSR space. We need this map to initiate 603 * indirect configuration transactions as this is a better 604 * option than doing through configuration space map. 605 */ 606 if (ddi_regs_map_setup(dip, DB_CSR_IOBAR_RNUMBER, 607 (caddr_t *)&dbp->csr_io, DB_CSR_IO_OFFSET, bar_size, 608 &db_csr_attr, &dbp->csr_io_handle) != DDI_SUCCESS) { 609 610 cmn_err(CE_WARN, "%s#%d: cannot map IO CSR space", 611 ddi_driver_name(dbp->dip), 612 ddi_get_instance(dbp->dip)); 613 ddi_regs_map_free(&dbp->csr_mem_handle); 614 ddi_regs_map_free(&dbp->conf_handle); 615 mutex_destroy(&dbp->db_mutex); 616 ddi_soft_state_free(db_state, instance); 617 rc = DDI_FAILURE; 618 break; 619 } 620 621 db_orientation(dbp); 622 623 if (dbp->dev_state & DB_SECONDARY_NEXUS) { 624 if (pcihp_init(dip) != DDI_SUCCESS) 625 cmn_err(CE_WARN, 626 "%s#%d: could not register with hotplug", 627 ddi_driver_name(dbp->dip), 628 ddi_get_instance(dbp->dip)); 629 } else { 630 /* 631 * create minor node for devctl interfaces 632 */ 633 if (ddi_create_minor_node(dip, "devctl", S_IFCHR, 634 PCIHP_AP_MINOR_NUM(instance, PCIHP_DEVCTL_MINOR), 635 DDI_NT_NEXUS, 0) != DDI_SUCCESS) { 636 ddi_regs_map_free(&dbp->csr_io_handle); 637 ddi_regs_map_free(&dbp->csr_mem_handle); 638 ddi_regs_map_free(&dbp->conf_handle); 639 mutex_destroy(&dbp->db_mutex); 640 ddi_soft_state_free(db_state, instance); 641 rc = DDI_FAILURE; 642 break; 643 } 644 } 645 646 db_enable_io(dbp); 647 648 range_size = sizeof (dbp->range); 649 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 650 DDI_PROP_DONTPASS, "bus-range", (caddr_t)&dbp->range, 651 &range_size) != DDI_SUCCESS) { 652 653 cmn_err(CE_WARN, 654 "%s#%d: cannot get bus-range property", 655 ddi_driver_name(dip), ddi_get_instance(dip)); 656 657 if (dbp->dev_state & DB_SECONDARY_NEXUS) 658 (void) pcihp_uninit(dip); 659 else 660 ddi_remove_minor_node(dip, "devctl"); 661 662 ddi_regs_map_free(&dbp->csr_mem_handle); 663 ddi_regs_map_free(&dbp->csr_io_handle); 664 ddi_regs_map_free(&dbp->conf_handle); 665 mutex_destroy(&dbp->db_mutex); 666 ddi_soft_state_free(db_state, instance); 667 rc = DDI_FAILURE; 668 break; 669 } 670 671 (void) sprintf(name, "%d", instance); 672 673 if (ddi_create_minor_node(dip, name, S_IFCHR, 674 PCIHP_AP_MINOR_NUM(instance, PCIHP_DEBUG_MINOR), 675 NULL, NULL) == DDI_FAILURE) { 676 cmn_err(CE_NOTE, "%s#%d: node creation failure", 677 ddi_driver_name(dbp->dip), instance); 678 } 679 680 mutex_init(&dbp->db_busown, NULL, MUTEX_DRIVER, NULL); 681 682 db_fm_init(dbp); 683 ddi_report_dev(dip); 684 dbp->dev_state |= DB_ATTACHED; 685 686 break; 687 688 case DDI_RESUME: 689 690 /* 691 * Get the soft state structure for the bridge. 692 */ 693 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 694 db_enable_io(dbp); 695 (void) db_restore_config_regs(dbp); 696 dbp->dev_state &= ~DB_SUSPENDED; 697 break; 698 699 default: 700 rc = DDI_FAILURE; /* not supported yet */ 701 break; 702 } 703 704 DB_DEBUG1(DB_ATTACH, dip, "exit: rc=%d\n", rc); 705 return (rc); 706 } 707 708 static int 709 db_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 710 { 711 int instance = ddi_get_instance(dip); 712 db_ctrl_t *dbp; 713 int rc = DDI_SUCCESS; 714 char name[32]; 715 716 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 717 718 DB_DEBUG1(DB_DETACH, dip, "enter: cmd=%d\n", cmd); 719 720 switch (cmd) { 721 722 case DDI_DETACH : 723 db_fm_fini(dbp); 724 if (dbp->dev_state & DB_SECONDARY_NEXUS) 725 if (pcihp_uninit(dip) == DDI_FAILURE) 726 return (DDI_FAILURE); 727 else 728 ddi_remove_minor_node(dip, "devctl"); 729 730 mutex_destroy(&dbp->db_busown); 731 ddi_regs_map_free(&dbp->csr_mem_handle); 732 ddi_regs_map_free(&dbp->csr_io_handle); 733 734 ddi_regs_map_free(&dbp->conf_handle); 735 dbp->dev_state &= ~DB_ATTACHED; 736 (void) sprintf(name, "%d", instance); 737 ddi_remove_minor_node(dip, name); 738 mutex_destroy(&dbp->db_mutex); 739 ddi_soft_state_free(db_state, instance); 740 break; 741 742 case DDI_SUSPEND : 743 if (db_save_config_regs(dbp) != DDI_SUCCESS) { 744 cmn_err(CE_WARN, 745 "%s#%d: Ignoring Child state Suspend Error", 746 ddi_driver_name(dbp->dip), 747 ddi_get_instance(dbp->dip)); 748 } 749 dbp->dev_state |= DB_SUSPENDED; 750 break; 751 752 default : 753 rc = DDI_FAILURE; 754 break; 755 } 756 757 DB_DEBUG1(DB_DETACH, dip, "exit: rc=%d\n", rc); 758 return (rc); 759 } 760 761 static void 762 db_get_perf_parameters(db_ctrl_t *dbp) 763 { 764 dbp->p_latency_timer = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 765 dbp->dip, 0, "p-latency-timer", p_latency_timer); 766 dbp->s_latency_timer = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 767 dbp->dip, 0, "s-latency-timer", s_latency_timer); 768 dbp->p_cache_line_size = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 769 dbp->dip, 0, "p-cache-line-size", p_cache_line_size); 770 dbp->s_cache_line_size = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 771 dbp->dip, 0, "s-cache-line-size", s_cache_line_size); 772 dbp->p_pwrite_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 773 dbp->dip, 0, "p-pwrite-threshold", p_pwrite_threshold); 774 dbp->s_pwrite_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 775 dbp->dip, 0, "s-pwrite-threshold", s_pwrite_threshold); 776 dbp->p_dread_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 777 dbp->dip, 0, "p-dread-threshold", p_dread_threshold); 778 dbp->s_dread_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 779 dbp->dip, 0, "s-dread-threshold", s_dread_threshold); 780 dbp->delayed_trans_order = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY, 781 dbp->dip, 0, "delayed-trans-order", delayed_trans_order); 782 } 783 784 static void 785 db_set_perf_parameters(db_ctrl_t *dbp) 786 { 787 uint_t poffset = 0, soffset = 0; 788 789 if (dbp->dev_state & DB_SECONDARY_NEXUS) 790 poffset = DB_SCONF_PRI_HDR_OFF; 791 else 792 soffset = DB_PCONF_SEC_HDR_OFF; 793 794 if ((dbp->p_latency_timer != (int8_t)DEF_INVALID_REG_VAL) && 795 (dbp->p_latency_timer != -1)) 796 ddi_put8(dbp->conf_handle, 797 (uint8_t *)dbp->conf_io+poffset+PCI_CONF_LATENCY_TIMER, 798 dbp->p_latency_timer); 799 if ((dbp->s_latency_timer != (int8_t)DEF_INVALID_REG_VAL) && 800 (dbp->s_latency_timer != -1)) 801 ddi_put8(dbp->conf_handle, 802 (uint8_t *)dbp->conf_io+soffset+PCI_CONF_LATENCY_TIMER, 803 dbp->s_latency_timer); 804 if ((dbp->p_cache_line_size != (int8_t)DEF_INVALID_REG_VAL) && 805 (dbp->p_cache_line_size != -1)) 806 ddi_put8(dbp->conf_handle, 807 (uint8_t *)dbp->conf_io+poffset+PCI_CONF_CACHE_LINESZ, 808 dbp->p_cache_line_size); 809 if ((dbp->s_cache_line_size != (int8_t)DEF_INVALID_REG_VAL) && 810 (dbp->s_cache_line_size != -1)) 811 ddi_put8(dbp->conf_handle, 812 (uint8_t *)dbp->conf_io+soffset+PCI_CONF_CACHE_LINESZ, 813 dbp->s_cache_line_size); 814 if ((dbp->p_pwrite_threshold != (int8_t)DEF_INVALID_REG_VAL) && 815 (dbp->p_pwrite_threshold != -1)) 816 ddi_put16(dbp->conf_handle, (uint16_t *) 817 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1), 818 (ddi_get16(dbp->conf_handle, (uint16_t *) 819 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) & 820 ~P_PW_THRESHOLD) | 821 (dbp->p_pwrite_threshold?P_PW_THRESHOLD:0)); 822 if ((dbp->s_pwrite_threshold != (int8_t)DEF_INVALID_REG_VAL) && 823 (dbp->s_pwrite_threshold != -1)) 824 ddi_put16(dbp->conf_handle, (uint16_t *) 825 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1), 826 (ddi_get16(dbp->conf_handle, (uint16_t *) 827 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) & 828 ~S_PW_THRESHOLD) | 829 (dbp->s_pwrite_threshold?S_PW_THRESHOLD:0)); 830 /* primary delayed read threshold. 0x01 is reserved ?. */ 831 if ((dbp->p_dread_threshold != (int8_t)DEF_INVALID_REG_VAL) && 832 (dbp->p_dread_threshold != -1)) 833 ddi_put16(dbp->conf_handle, (uint16_t *) 834 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1), 835 ((ddi_get16(dbp->conf_handle, (uint16_t *) 836 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) & 837 ~P_DREAD_THRESHOLD_MASK) | 838 ((dbp->p_dread_threshold & 839 DREAD_THRESHOLD_VALBITS)<<2))); 840 /* secondary delayed read threshold. 0x01 is reserved ?. */ 841 if ((dbp->s_dread_threshold != (int8_t)DEF_INVALID_REG_VAL) && 842 (dbp->s_dread_threshold != -1)) 843 ddi_put16(dbp->conf_handle, (uint16_t *) 844 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1), 845 ((ddi_get16(dbp->conf_handle, (uint16_t *) 846 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) & 847 ~S_DREAD_THRESHOLD_MASK) | 848 ((dbp->s_dread_threshold & 849 DREAD_THRESHOLD_VALBITS)<<4))); 850 if ((dbp->delayed_trans_order != (int8_t)DEF_INVALID_REG_VAL) && 851 (dbp->delayed_trans_order != -1)) 852 ddi_put16(dbp->conf_handle, (uint16_t *) 853 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL0), 854 (ddi_get16(dbp->conf_handle, (uint16_t *) 855 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL0)) & 856 ~DELAYED_TRANS_ORDER) | 857 (dbp->delayed_trans_order?DELAYED_TRANS_ORDER:0)); 858 } 859 860 static void 861 db_orientation(db_ctrl_t *dbp) 862 { 863 dev_info_t *dip = dbp->dip; 864 uint8_t pif; 865 uint32_t mem1; 866 uint32_t newval; 867 868 /* 869 * determine orientation of drawbridge and enable 870 * Upstream or Downstream path. 871 */ 872 873 /* 874 * if PIF is set correctly, use it to determine orientation 875 */ 876 pif = ddi_get8(dbp->conf_handle, (uchar_t *)dbp->conf_io + 877 PCI_CONF_PROGCLASS); 878 if (pif & 0xff) { 879 if (pif & DB_PIF_SECONDARY_TO_HOST) { 880 dbp->dev_state = DB_SECONDARY_NEXUS; 881 DB_DEBUG0(DB_ATTACH, dip, 882 "db_orientation: pif secondary\n"); 883 return; 884 } 885 if (pif & DB_PIF_PRIMARY_TO_HOST) { 886 dbp->dev_state = DB_PRIMARY_NEXUS; 887 DB_DEBUG0(DB_ATTACH, dip, 888 "db_orientation: pif primary\n"); 889 return; 890 } 891 /* otherwise, fall through */ 892 } 893 894 /* 895 * otherwise, test the chip directly by trying to write 896 * downstream mem1 setup register, only writeable from 897 * secondary. 898 */ 899 mem1 = ddi_get32(dbp->conf_handle, 900 (uint32_t *)((uchar_t *)dbp->conf_io + 901 DB_CONF_DS_IO_MEM1_SETUP)); 902 903 ddi_put32(dbp->conf_handle, 904 (uint32_t *)((uchar_t *)(dbp->conf_io + 905 DB_CONF_DS_IO_MEM1_SETUP)), ~mem1); 906 907 newval = ddi_get32(dbp->conf_handle, 908 (uint32_t *)((uchar_t *)dbp->conf_io + 909 DB_CONF_DS_IO_MEM1_SETUP)); 910 911 if (newval == mem1) 912 /* we couldn't write it, orientation is primary */ 913 dbp->dev_state = DB_PRIMARY_NEXUS; 914 else { 915 /* 916 * we could write it, therefore orientation secondary. 917 * restore mem1 value. 918 */ 919 dbp->dev_state = DB_SECONDARY_NEXUS; 920 ddi_put32(dbp->conf_handle, 921 (uint32_t *)((uchar_t *)(dbp->conf_io + 922 DB_CONF_DS_IO_MEM1_SETUP)), mem1); 923 } 924 925 926 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 927 DB_DEBUG0(DB_ATTACH, dip, "db_orientation: chip primary\n"); 928 } else { 929 DB_DEBUG0(DB_ATTACH, dip, "db_orientation: chip secondary\n"); 930 } 931 } 932 933 static void 934 db_enable_io(db_ctrl_t *dbp) 935 { 936 dev_info_t *dip = dbp->dip; 937 pci_regspec_t *reg; 938 int rcount, length, i; 939 uint32_t offset; 940 uint32_t p_offset, s_offset; 941 uint16_t regval; 942 uint16_t enable; 943 944 /* 945 * Step 0: 946 * setup the primary and secondary offset and enable 947 * values based on the orientation of 21554. 948 */ 949 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 950 DB_DEBUG0(DB_ATTACH, dip, "db_enable_io: primary\n"); 951 p_offset = 0; 952 s_offset = DB_SCONF_HDR_OFF; 953 enable = DS_ENABLE; 954 } else { 955 DB_DEBUG0(DB_ATTACH, dip, "db_enable_io: secondary\n"); 956 p_offset = DB_SCONF_HDR_OFF; 957 s_offset = 0; 958 enable = US_ENABLE; 959 } 960 961 db_set_perf_parameters(dbp); 962 db_set_dvma_range(dbp); 963 964 /* 965 * Step 1: 966 * setup latency timer and cache line size parameters 967 * which are used for child initialization. 968 */ 969 dbp->latency_timer = ddi_get8(dbp->conf_handle, (uint8_t *) 970 ((caddr_t)dbp->conf_io+PCI_CONF_LATENCY_TIMER)); 971 972 dbp->cache_line_size = ddi_get8(dbp->conf_handle, (uint8_t *) 973 ((caddr_t)dbp->conf_io+PCI_CONF_CACHE_LINESZ)); 974 975 DB_DEBUG2(DB_ATTACH, dip, 976 "db_enable_io: latency %d, cache line size %d\n", 977 dbp->latency_timer, dbp->cache_line_size); 978 979 /* 980 * Step 2: program command reg on both primary and secondary 981 * interfaces. 982 */ 983 ddi_put16(dbp->conf_handle, (uint16_t *)((caddr_t)dbp->conf_io + 984 (off_t)(p_offset + PCI_CONF_COMM)), db_command_default); 985 986 ddi_put16(dbp->conf_handle, (uint16_t *)((caddr_t)dbp->conf_io + 987 (off_t)(s_offset + PCI_CONF_COMM)), db_command_default); 988 989 /* 990 * Step 3: 991 * set up translated base registers, using the primary/ 992 * secondary interface pci configuration Base Address 993 * Registers (BAR's). 994 */ 995 996 /* mem0 translated base is setup for primary orientation only. */ 997 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 998 /* 999 * And only if the 21554 device node property indicates 1000 * the size of base0 register to be larger than csr map 1001 * space, DB_CSR_SIZE=4K. 1002 * 1003 * Note : Setting up 1:1 translations only (for now:), i.e. 1004 * no look up table. 1005 */ 1006 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 1007 DDI_PROP_DONTPASS, "reg", (caddr_t)®, 1008 &length) != DDI_PROP_SUCCESS) { 1009 DB_DEBUG0(DB_ATTACH, dip, 1010 "Failed to read reg property\n"); 1011 return; 1012 } 1013 1014 /* Find device node's base0 reg property and check its size */ 1015 rcount = length / sizeof (pci_regspec_t); 1016 for (i = 0; i < rcount; i++) { 1017 offset = PCI_REG_REG_G(reg[i].pci_phys_hi); 1018 if ((offset == PCI_CONF_BASE0) && 1019 (reg[i].pci_size_low > DB_CSR_SIZE)) 1020 break; 1021 } 1022 1023 /* 1024 * set up mem0 translated base, if base0 register was 1025 * found and its size was larger than csr map space. 1026 */ 1027 if (i != rcount) { 1028 DB_DEBUG0(DB_ATTACH, dip, 1029 "db_enable_io: setting up MEM0_TR_BASE\n"); 1030 DB_DEBUG1(DB_ATTACH, dip, "BASE0 register = %x\n", 1031 pci_config_get32(dbp->conf_handle, 1032 (off_t)(p_offset + PCI_CONF_BASE0))); 1033 1034 pci_config_put32(dbp->conf_handle, 1035 (off_t)DB_CONF_DS_MEM0_TR_BASE, 1036 pci_config_get32(dbp->conf_handle, 1037 (off_t)(p_offset + PCI_CONF_BASE0))); 1038 1039 DB_DEBUG1(DB_ATTACH, dip, 1040 "db_enable_io: MEM0_TR_BASE set value = %x\n", 1041 pci_config_get32(dbp->conf_handle, 1042 (off_t)DB_CONF_DS_MEM0_TR_BASE)); 1043 } 1044 kmem_free(reg, length); 1045 } 1046 1047 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_IO_MEM1_TR_BASE, 1048 ((pci_config_get32(dbp->conf_handle, 1049 (off_t)(p_offset + PCI_CONF_BASE2))) & ~DB_IO_BIT)); 1050 1051 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_MEM2_TR_BASE, 1052 ((pci_config_get32(dbp->conf_handle, 1053 (off_t)(p_offset + PCI_CONF_BASE3))) & ~DB_IO_BIT)); 1054 1055 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_MEM3_TR_BASE, 1056 ((pci_config_get32(dbp->conf_handle, 1057 (off_t)(p_offset + PCI_CONF_BASE4))) & ~DB_IO_BIT)); 1058 1059 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_US_IO_MEM0_TR_BASE, 1060 ((pci_config_get32(dbp->conf_handle, 1061 (off_t)(s_offset + PCI_CONF_BASE2))) & ~DB_IO_BIT)); 1062 1063 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_US_MEM1_TR_BASE, 1064 ((pci_config_get32(dbp->conf_handle, 1065 (off_t)(s_offset + PCI_CONF_BASE3))) & ~DB_IO_BIT)); 1066 1067 /* 1068 * Step 4: enable downstream (for primary orientation) or upstream 1069 * (for secondary orientation) bits in Configuration Control 1070 * and Status register, if not already enabled. 1071 */ 1072 regval = pci_config_get16(dbp->conf_handle, (off_t)DB_CONF_CONF_CSR); 1073 1074 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: CSR value before: %x\n", 1075 regval); 1076 1077 if (!(regval & enable)) { 1078 /* enable down/upstream configuration transactions */ 1079 regval |= enable; 1080 pci_config_put16(dbp->conf_handle, (off_t)DB_CONF_CONF_CSR, 1081 regval); 1082 regval = pci_config_get16(dbp->conf_handle, 1083 (off_t)DB_CONF_CONF_CSR); 1084 } 1085 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: CSR value after: %x\n", 1086 regval); 1087 1088 /* 1089 * Step 5: enable downstream/upstream I/O (through CSR space) 1090 */ 1091 regval = ddi_get16(dbp->csr_mem_handle, 1092 (uint16_t *)((uchar_t *)dbp->csr_mem + DB_CSR_IO_CSR)); 1093 1094 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: IO_CSR value before: %x\n", 1095 regval); 1096 if (!(regval & enable)) { 1097 regval |= enable; 1098 ddi_put16(dbp->csr_mem_handle, 1099 (uint16_t *)((uchar_t *)dbp->csr_mem + 1100 DB_CSR_IO_CSR), regval); 1101 1102 regval = ddi_get16(dbp->csr_mem_handle, 1103 (uint16_t *)((uchar_t *)dbp->csr_mem + DB_CSR_IO_CSR)); 1104 } 1105 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: IO_CSR value after: %x\n", 1106 regval); 1107 1108 /* 1109 * Step 6: if 21554 orientation is primary to host, 1110 * forward SERR# to host. 1111 */ 1112 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 1113 dbp->serr_fwd_enable = ddi_prop_get_int(DDI_DEV_T_ANY, 1114 dbp->dip, 0, "serr-fwd-enable", db_serr_fwd_enable); 1115 1116 regval = ddi_get16(dbp->conf_handle, 1117 (uint16_t *)((uchar_t *)dbp->conf_io + 1118 DB_CONF_CHIP_CTRL0)); 1119 1120 DB_DEBUG1(DB_ATTACH, dip, 1121 "db_enable_io: CHIP_CTRL0 value before: %x\n", regval); 1122 1123 ddi_put16(dbp->conf_handle, 1124 (uint16_t *)((uchar_t *)dbp->conf_io + 1125 DB_CONF_CHIP_CTRL0), 1126 (regval & ~SERR_FWD) | 1127 (dbp->serr_fwd_enable?SERR_FWD:0)); 1128 1129 regval = ddi_get16(dbp->conf_handle, 1130 (uint16_t *)((uchar_t *)dbp->conf_io + 1131 DB_CONF_CHIP_CTRL0)); 1132 1133 DB_DEBUG1(DB_ATTACH, dip, 1134 "db_enable_io: CHIP_CTRL0 value after: %x\n", regval); 1135 } 1136 1137 /* 1138 * Step 7: if orientation is secondary, make sure primary lockout 1139 * disable is reset. 1140 */ 1141 1142 if (dbp->dev_state & DB_SECONDARY_NEXUS) { 1143 regval = pci_config_get16(dbp->conf_handle, 1144 (off_t)DB_CONF_CHIP_CTRL0); 1145 DB_DEBUG1(DB_ATTACH, dip, 1146 "db_enable_io: chip ctrl (0x%x) before\n", regval); 1147 if (regval & PLOCKOUT) 1148 pci_config_put16(dbp->conf_handle, 1149 (off_t)DB_CONF_CHIP_CTRL0, 1150 (regval & ~PLOCKOUT)); 1151 regval = pci_config_get16(dbp->conf_handle, 1152 (off_t)DB_CONF_CHIP_CTRL0); 1153 DB_DEBUG1(DB_ATTACH, dip, 1154 "db_enable_io: chip ctrl (0x%x) after\n", regval); 1155 } 1156 } 1157 1158 /* 1159 * Set DVMA Address Range. 1160 * This code is common to both orientations of the nexus driver. 1161 */ 1162 static void 1163 db_set_dvma_range(db_ctrl_t *dbp) 1164 { 1165 uint32_t dvma_start = 0; 1166 uint32_t dvma_len = 0; 1167 uint64_t db_allocd = 0; 1168 uint32_t *dvma_prop; 1169 uint32_t dvma_size[2]; /* dvma size may span over 2 BARs */ 1170 uint32_t dvma_bar[2]; /* dvma range may span over 2 BARs */ 1171 int dvma_prop_len; 1172 uint64_t new_dvma_start, new_dvma_len, new_dvma_end; 1173 1174 /* 1175 * Need to traverse up the tree looking for a 1176 * "virtual-dma" property that specifies the 1177 * HPB DVMA range. 1178 */ 1179 if (ddi_getlongprop(DDI_DEV_T_ANY, ddi_get_parent(dbp->dip), 0, 1180 "virtual-dma", (caddr_t)&dvma_prop, &dvma_prop_len) 1181 == DDI_SUCCESS) { 1182 dvma_start = dvma_prop[0]; 1183 dvma_len = dvma_prop[1]; 1184 kmem_free((caddr_t)dvma_prop, dvma_prop_len); 1185 } else { 1186 /* 1187 * For initial implementation, lets avoid a warning since this 1188 * change has not been implemented in the host-pci nexus 1189 * driver. 1190 */ 1191 cmn_err(CE_WARN, 1192 "%s#%d: Could not get \"virtual-dma\" property", 1193 ddi_driver_name(dbp->dip), 1194 ddi_get_instance(dbp->dip)); 1195 dvma_start = db_dvma_start; 1196 dvma_len = db_dvma_len; 1197 } 1198 1199 DB_DEBUG2(DB_DVMA, dbp->dip, 1200 "DVMA Range is %lx,%lx\n", dvma_start, dvma_len); 1201 1202 dvma_size[0] = dvma_size[1] = 0; 1203 /* Validate DVMA size programming and system requirements. */ 1204 if (dbp->dev_state & DB_SECONDARY_NEXUS) { 1205 dvma_size[0] = pci_config_get32(dbp->conf_handle, 1206 DB_CONF_DS_IO_MEM1_SETUP); 1207 if (!(dvma_size[0] & 1)) /* make sure it is not a IO BAR */ 1208 dvma_size[0] = ((~dvma_size[0]) + 1) & 0xfffff000; 1209 else 1210 dvma_size[0] = 0; 1211 dvma_size[1] = db_dvma_len; 1212 } else { 1213 dvma_size[0] = pci_config_get32(dbp->conf_handle, 1214 DB_CONF_US_IO_MEM0_SETUP); 1215 if (!(dvma_size[0] & 1)) /* make sure it is not a IO BAR */ 1216 dvma_size[0] = ((~dvma_size[0]) + 1) & 0xfffff000; 1217 else 1218 dvma_size[0] = 0; 1219 dvma_size[1] = ((~(pci_config_get32(dbp->conf_handle, 1220 DB_CONF_US_MEM1_SETUP))) + 1) & 0xfffff000; 1221 } 1222 DB_DEBUG2(DB_DVMA, dbp->dip, "DVMA size register pair %lx, %lx\n", 1223 dvma_size[0], dvma_size[1]); 1224 1225 #ifdef DEBUG 1226 if ((dvma_size[0] + dvma_size[1]) < dvma_len) 1227 cmn_err(CE_WARN, "%s#%d: DVMA window (%u) does not coincide" 1228 " with system requirements", 1229 ddi_driver_name(dbp->dip), ddi_get_instance(dbp->dip), 1230 (dvma_size[0] + dvma_size[1])); 1231 #endif 1232 dvma_bar[0] = dvma_bar[1] = 0xFFFFFFFF; 1233 db_allocd = 0; 1234 new_dvma_start = dvma_start; 1235 new_dvma_len = dvma_len; 1236 1237 /* now, program the correct DVMA range over the 2 BARs. Max 4GB */ 1238 if (dvma_size[0]) { 1239 dvma_bar[0] = (uint32_t)(dvma_start & (~(dvma_size[0] - 1))); 1240 new_dvma_end = (uint64_t)((uint64_t)dvma_bar[0] + 1241 (uint64_t)dvma_size[0]); 1242 if (new_dvma_end > (new_dvma_start + new_dvma_len)) 1243 new_dvma_end = new_dvma_start + new_dvma_len; 1244 db_allocd += (new_dvma_end - new_dvma_start); 1245 new_dvma_start = new_dvma_end; 1246 new_dvma_len = dvma_len - db_allocd; 1247 } 1248 /* 1249 * It does not serve any purpose to set the other DVMA register 1250 * when we have already met the memory requirements so leave it 1251 * disabled. 1252 */ 1253 if ((db_allocd != dvma_len) && dvma_size[1]) { 1254 dvma_bar[1] = (uint32_t)((dvma_start + db_allocd) & 1255 (~(dvma_size[1] - 1))); 1256 new_dvma_end = (uint64_t)((uint64_t)dvma_bar[1] + 1257 (uint64_t)dvma_size[1]); 1258 if (new_dvma_end > (new_dvma_start + new_dvma_len)) 1259 new_dvma_end = new_dvma_start + new_dvma_len; 1260 db_allocd += (new_dvma_end - new_dvma_start); 1261 } 1262 1263 /* In case of secondary orientation, DVMA BAR0 is 0. */ 1264 if (dbp->dev_state & DB_SECONDARY_NEXUS) 1265 dvma_bar[0] = 0; 1266 1267 if (db_allocd != dvma_len) { 1268 cmn_err(CE_WARN, "%s#%d: dvma range error!", 1269 ddi_driver_name(dbp->dip), ddi_get_instance(dbp->dip)); 1270 } 1271 1272 DB_DEBUG2(DB_DVMA, dbp->dip, "DVMA BARs set as %x, %x\n", 1273 dvma_bar[0], dvma_bar[1]); 1274 1275 /* configure the setup register and DVMA BARs. */ 1276 if (dbp->dev_state & DB_SECONDARY_NEXUS) { 1277 if (dvma_bar[0] != 0xFFFFFFFF) { 1278 #ifdef DB_SEC_SETUP_WRITE 1279 /* 1280 * No need to program the setup register 1281 * as the PROM would have done it. 1282 */ 1283 pci_config_put32(dbp->conf_handle, 1284 DB_CONF_DS_MEM1_SETUP, 1285 (uint32_t)(((~(dvma_size[0] - 1)) | 1286 (pci_config_get32(dbp->conf_handle, 1287 DB_CONF_DS_MEM1_SETUP) & 0xF)) | 0x80000000)); 1288 #endif 1289 /* 1290 * when translations are to be provided, this will 1291 * change. 1292 */ 1293 pci_config_put32(dbp->conf_handle, 1294 DB_CONF_DS_IO_MEM1_TR_BASE, 1295 (uint32_t)dvma_bar[0]); 1296 pci_config_put32(dbp->conf_handle, 1297 DB_SCONF_DS_IO_MEM1, dvma_bar[0]); 1298 } 1299 if (dvma_bar[1] != 0xFFFFFFFF) { 1300 #ifdef DB_SEC_SETUP_WRITE 1301 /* 1302 * No need to program the setup register 1303 * as the PROM would have done it. 1304 */ 1305 pci_config_put32(dbp->conf_handle, 1306 DB_CONF_DS_MEM2_SETUP, 1307 (uint32_t)(((~(dvma_size[1] - 1)) | 1308 (pci_config_get32(dbp->conf_handle, 1309 DB_CONF_DS_MEM2_SETUP) & 0xF)) | 0x80000000)); 1310 #endif 1311 /* 1312 * when translations are to be provided, this will 1313 * change. 1314 */ 1315 pci_config_put32(dbp->conf_handle, 1316 DB_CONF_DS_MEM2_TR_BASE, (uint32_t)dvma_bar[1]); 1317 pci_config_put32(dbp->conf_handle, 1318 DB_SCONF_DS_MEM2, dvma_bar[1]); 1319 } 1320 1321 } else { 1322 if (dvma_bar[0] != 0xFFFFFFFF) { 1323 #ifdef DB_CONF_P2S_WRITE_ENABLED /* primary to secondary write enabled */ 1324 /* 1325 * We have a problem with this setup, because the 1326 * US_MEM1 setup register cannot be written from the 1327 * primary interface...!!! Hence in this configuration, 1328 * we cannot dynamically program the DVMA range! 1329 */ 1330 pci_config_put32(dbp->conf_handle, 1331 DB_CONF_US_IO_MEM0_SETUP, 1332 (uint32_t)(((~(dvma_size[0] - 1)) | 1333 (pci_config_get32(dbp->conf_handle, 1334 DB_CONF_US_IO_MEM0_SETUP) & 0xF)) | 1335 0x80000000)); 1336 #endif 1337 /* 1338 * when translations are to be provided, this will 1339 * change. 1340 */ 1341 pci_config_put32(dbp->conf_handle, 1342 DB_CONF_US_IO_MEM0_TR_BASE, 1343 (uint32_t)dvma_bar[0]); 1344 pci_config_put32(dbp->conf_handle, 1345 DB_PCONF_US_IO_MEM0, dvma_bar[0]); 1346 } 1347 if (dvma_bar[1] != 0xFFFFFFFF) { 1348 #ifdef DB_CONF_P2S_WRITE_ENABLED /* primary to secondary write enabled */ 1349 /* 1350 * We have a problem with this setup, because the 1351 * US_MEM1 setup register cannot be written from the 1352 * primary interface...!!! Hence in this configuration, 1353 * we cannot dynamically program the DVMA range! 1354 */ 1355 pci_config_put32(dbp->conf_handle, 1356 DB_CONF_US_MEM1_SETUP, 1357 (uint32_t)(((~(dvma_size[1] - 1)) | 1358 (pci_config_get32(dbp->conf_handle, 1359 DB_CONF_US_MEM1_SETUP) & 0xF)) | 0x80000000)); 1360 #endif 1361 /* 1362 * when translations are to be provided, this will 1363 * change. 1364 */ 1365 pci_config_put32(dbp->conf_handle, 1366 DB_CONF_US_MEM1_TR_BASE, (uint32_t)dvma_bar[1]); 1367 pci_config_put32(dbp->conf_handle, 1368 DB_PCONF_US_MEM1, dvma_bar[1]); 1369 } 1370 } 1371 } 1372 1373 /*ARGSUSED*/ 1374 static int 1375 db_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p) 1376 { 1377 minor_t minor = getminor(*dev_p); 1378 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor); 1379 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 1380 1381 if (dbp == (db_ctrl_t *)NULL) 1382 return (ENXIO); 1383 1384 /* 1385 * check for debug node 1386 */ 1387 if ((minor & 0xff) == 0xfe) 1388 return (0); 1389 1390 if (dbp->dev_state & DB_SECONDARY_NEXUS) 1391 return ((pcihp_get_cb_ops())->cb_open(dev_p, flag, 1392 otyp, cred_p)); 1393 /* 1394 * Handle the open by tracking the device state. 1395 */ 1396 mutex_enter(&dbp->db_mutex); 1397 if (flag & FEXCL) { 1398 if (dbp->db_soft_state != DB_SOFT_STATE_CLOSED) { 1399 mutex_exit(&dbp->db_mutex); 1400 return (EBUSY); 1401 } 1402 dbp->db_soft_state = DB_SOFT_STATE_OPEN_EXCL; 1403 } else { 1404 if (dbp->db_soft_state == DB_SOFT_STATE_OPEN_EXCL) { 1405 mutex_exit(&dbp->db_mutex); 1406 return (EBUSY); 1407 } 1408 dbp->db_soft_state = DB_SOFT_STATE_OPEN; 1409 } 1410 mutex_exit(&dbp->db_mutex); 1411 return (0); 1412 } 1413 1414 /*ARGSUSED*/ 1415 static int 1416 db_close(dev_t dev, int flag, int otyp, cred_t *cred_p) 1417 { 1418 minor_t minor = getminor(dev); 1419 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor); 1420 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 1421 1422 if (dbp == (db_ctrl_t *)NULL) 1423 return (ENXIO); 1424 1425 /* 1426 * check for debug node 1427 */ 1428 if ((minor & 0xff) == 0xfe) 1429 return (0); 1430 1431 if (dbp->dev_state & DB_SECONDARY_NEXUS) 1432 return ((pcihp_get_cb_ops())->cb_close(dev, flag, 1433 otyp, cred_p)); 1434 mutex_enter(&dbp->db_mutex); 1435 dbp->db_soft_state = DB_SOFT_STATE_CLOSED; 1436 mutex_exit(&dbp->db_mutex); 1437 return (0); 1438 } 1439 1440 /*ARGSUSED*/ 1441 static int 1442 db_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p, 1443 int *rval_p) 1444 { 1445 int rc = DDI_SUCCESS; 1446 #ifdef DB_DEBUG 1447 ddi_acc_handle_t config_handle; 1448 db_pci_data_t pci_data; 1449 dev_info_t *child_dip; 1450 #endif 1451 dev_info_t *self; 1452 minor_t minor = getminor(dev); 1453 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor); 1454 struct devctl_iocdata *dcp; 1455 uint_t bus_state; 1456 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance); 1457 1458 #ifdef DB_DEBUG 1459 /* 1460 * try this first whether were SECONDARY_NEXUS or not 1461 */ 1462 if (cmd == DB_PCI_READ_CONF_HEADER) { 1463 if (ddi_copyin((caddr_t)arg, (caddr_t)&pci_data, 1464 sizeof (db_pci_data_t), mode)) { 1465 rc = EFAULT; 1466 return (rc); 1467 } 1468 1469 if (strcmp(pci_data.name, "") == 0) { 1470 child_dip = dbp->dip; 1471 (void) strcpy(pci_data.name, 1472 ddi_get_name(dbp->dip)); 1473 } else { 1474 1475 if ((child_dip = db_lookup_child_name(dbp, 1476 pci_data.name, pci_data.instance)) 1477 == (dev_info_t *)NULL) { 1478 rc = ENXIO; 1479 return (rc); 1480 } else { 1481 if (ddi_getprop(DDI_DEV_T_ANY, 1482 child_dip, DDI_PROP_DONTPASS, 1483 "vendor-id", DB_INVAL_VEND) 1484 == DB_INVAL_VEND) { 1485 /* non PCI device */ 1486 rc = EINVAL; 1487 return (rc); 1488 } 1489 } 1490 } 1491 pci_data.instance = ddi_get_instance(child_dip); 1492 (void) pci_config_setup(child_dip, &config_handle); 1493 db_pci_get_header(config_handle, &pci_data.pri_hdr, 0); 1494 1495 /* if it is the drawbridge itself, read sec header */ 1496 if (child_dip == dbp->dip) { 1497 db_pci_get_header(config_handle, 1498 &pci_data.sec_hdr, DB_PCONF_SEC_HDR_OFF); 1499 db_pci_get_conf_regs(config_handle, 1500 &pci_data.conf_regs); 1501 } 1502 pci_config_teardown(&config_handle); 1503 1504 if (ddi_copyout((caddr_t)&pci_data, (caddr_t)arg, 1505 sizeof (db_pci_data_t), mode)) { 1506 rc = EFAULT; 1507 return (rc); 1508 } 1509 1510 return (rc); 1511 } 1512 #endif /* DB_DEBUG */ 1513 1514 /* 1515 * if secondary nexus (hotplug), then use pcihp_ioctl to do everything 1516 */ 1517 if (dbp->dev_state & DB_SECONDARY_NEXUS) 1518 return ((pcihp_get_cb_ops())->cb_ioctl(dev, cmd, 1519 arg, mode, cred_p, rval_p)); 1520 1521 /* 1522 * if not secondary nexus, we do DEVCTL_DEVICE and DEVCTL_BUS ourselves 1523 */ 1524 self = dbp->dip; 1525 1526 /* 1527 * We can use the generic implementation for these ioctls 1528 */ 1529 switch (cmd) { 1530 case DEVCTL_DEVICE_GETSTATE: 1531 case DEVCTL_DEVICE_ONLINE: 1532 case DEVCTL_DEVICE_OFFLINE: 1533 case DEVCTL_BUS_GETSTATE: 1534 return (ndi_devctl_ioctl(self, cmd, arg, mode, 0)); 1535 } 1536 1537 /* 1538 * read devctl ioctl data 1539 */ 1540 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS) 1541 return (EFAULT); 1542 1543 switch (cmd) { 1544 1545 case DEVCTL_DEVICE_RESET: 1546 rc = ENOTSUP; 1547 break; 1548 1549 1550 case DEVCTL_BUS_QUIESCE: 1551 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) 1552 if (bus_state == BUS_QUIESCED) 1553 break; 1554 (void) ndi_set_bus_state(self, BUS_QUIESCED); 1555 break; 1556 1557 case DEVCTL_BUS_UNQUIESCE: 1558 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS) 1559 if (bus_state == BUS_ACTIVE) 1560 break; 1561 (void) ndi_set_bus_state(self, BUS_ACTIVE); 1562 break; 1563 1564 case DEVCTL_BUS_RESET: 1565 rc = ENOTSUP; 1566 break; 1567 1568 case DEVCTL_BUS_RESETALL: 1569 rc = ENOTSUP; 1570 break; 1571 1572 default: 1573 rc = ENOTTY; 1574 } 1575 1576 ndi_dc_freehdl(dcp); 1577 return (rc); 1578 } 1579 1580 #ifdef DB_DEBUG 1581 static dev_info_t * 1582 db_lookup_child_name(db_ctrl_t *dbp, char *name, int instance) 1583 { 1584 dev_info_t *cdip, *pdip = dbp->dip; 1585 1586 for (cdip = ddi_get_child(pdip); cdip; 1587 cdip = ddi_get_next_sibling(pdip)) { 1588 1589 do { 1590 if (strcmp(ddi_node_name(cdip), name) == 0) { 1591 if (instance != -1) { 1592 if (ddi_get_instance(cdip) == instance) 1593 return (cdip); 1594 } else 1595 return (cdip); 1596 } 1597 pdip = cdip; 1598 } while ((cdip = ddi_get_child(pdip))); 1599 cdip = ddi_get_next_sibling(pdip); 1600 if (cdip == NULL) { 1601 pdip = ddi_get_parent(pdip); 1602 if (pdip == dbp->dip) 1603 break; 1604 } 1605 } 1606 return (NULL); 1607 } 1608 1609 static void 1610 db_pci_get_header(ddi_acc_handle_t config_handle, db_pci_header_t *ph, 1611 off_t hdr_off) 1612 { 1613 ph->venid = pci_config_get16(config_handle, hdr_off + PCI_CONF_VENID); 1614 ph->devid = pci_config_get16(config_handle, hdr_off + PCI_CONF_DEVID); 1615 ph->command = pci_config_get16(config_handle, hdr_off + PCI_CONF_COMM); 1616 ph->status = pci_config_get16(config_handle, hdr_off + PCI_CONF_STAT); 1617 ph->revid = pci_config_get8(config_handle, hdr_off + PCI_CONF_REVID); 1618 ph->pif = pci_config_get8(config_handle, hdr_off + PCI_CONF_PROGCLASS); 1619 ph->subclass = pci_config_get8(config_handle, 1620 hdr_off + PCI_CONF_SUBCLASS); 1621 ph->class = pci_config_get8(config_handle, 1622 hdr_off + PCI_CONF_BASCLASS); 1623 ph->cacheline = pci_config_get8(config_handle, 1624 hdr_off + PCI_CONF_CACHE_LINESZ); 1625 ph->lat = pci_config_get8(config_handle, 1626 hdr_off + PCI_CONF_LATENCY_TIMER); 1627 ph->hdr_type = pci_config_get8(config_handle, 1628 hdr_off + PCI_CONF_HEADER); 1629 ph->bist = pci_config_get8(config_handle, hdr_off + PCI_CONF_BIST); 1630 ph->bar0 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE0); 1631 ph->bar1 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE1); 1632 ph->bar2 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE2); 1633 ph->bar3 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE3); 1634 ph->bar4 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE4); 1635 ph->bar5 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE5); 1636 ph->cardbus_cisp = pci_config_get32(config_handle, 1637 hdr_off + PCI_CONF_CIS); 1638 ph->sub_venid = pci_config_get16(config_handle, 1639 hdr_off + PCI_CONF_SUBVENID); 1640 ph->sub_devid = pci_config_get16(config_handle, 1641 hdr_off + PCI_CONF_SUBSYSID); 1642 ph->exprom_bar = pci_config_get32(config_handle, 1643 hdr_off + PCI_CONF_ROM); 1644 ph->int_line = pci_config_get8(config_handle, hdr_off + PCI_CONF_ILINE); 1645 ph->int_pin = pci_config_get8(config_handle, hdr_off + PCI_CONF_IPIN); 1646 ph->min_gnt = pci_config_get8(config_handle, hdr_off + PCI_CONF_MIN_G); 1647 ph->max_lat = pci_config_get8(config_handle, hdr_off + PCI_CONF_MAX_L); 1648 } 1649 1650 static void 1651 db_pci_get_conf_regs(ddi_acc_handle_t config_handle, db_conf_regs_t *cr) 1652 { 1653 cr->ds_mem0_tr_base = pci_config_get32(config_handle, 1654 DB_CONF_DS_MEM0_TR_BASE); 1655 cr->ds_io_mem1_tr_base = pci_config_get32(config_handle, 1656 DB_CONF_DS_IO_MEM1_TR_BASE); 1657 cr->ds_mem2_tr_base = pci_config_get32(config_handle, 1658 DB_CONF_DS_MEM2_TR_BASE); 1659 cr->ds_mem3_tr_base = pci_config_get32(config_handle, 1660 DB_CONF_DS_MEM3_TR_BASE); 1661 cr->us_io_mem0_tr_base = pci_config_get32(config_handle, 1662 DB_CONF_US_IO_MEM0_TR_BASE); 1663 cr->us_mem1_tr_base = pci_config_get32(config_handle, 1664 DB_CONF_US_MEM1_TR_BASE); 1665 cr->ds_mem0_setup_reg = pci_config_get32(config_handle, 1666 DB_CONF_DS_MEM0_SETUP); 1667 cr->ds_io_mem1_setup_reg = pci_config_get32(config_handle, 1668 DB_CONF_DS_IO_MEM1_SETUP); 1669 cr->ds_mem2_setup_reg = pci_config_get32(config_handle, 1670 DB_CONF_DS_MEM2_SETUP); 1671 cr->ds_mem3_setup_reg = pci_config_get64(config_handle, 1672 DB_CONF_DS_MEM3_SETUP); 1673 cr->p_exp_rom_setup = pci_config_get32(config_handle, 1674 DB_CONF_PRIM_EXP_ROM_SETUP); 1675 cr->us_io_mem0_setup_reg = pci_config_get32(config_handle, 1676 DB_CONF_US_IO_MEM0_SETUP); 1677 cr->us_mem1_setup_reg = pci_config_get32(config_handle, 1678 DB_CONF_US_MEM1_SETUP); 1679 cr->chip_control0 = pci_config_get16(config_handle, DB_CONF_CHIP_CTRL0); 1680 cr->chip_control1 = pci_config_get16(config_handle, DB_CONF_CHIP_CTRL1); 1681 cr->chip_status = pci_config_get16(config_handle, DB_CONF_STATUS); 1682 cr->arb_control = pci_config_get16(config_handle, DB_CONF_ARBITER_CTRL); 1683 cr->p_serr_disables = pci_config_get8(config_handle, 1684 DB_CONF_PRIM_SERR_DISABLES); 1685 cr->s_serr_disables = pci_config_get8(config_handle, 1686 DB_CONF_PRIM_SERR_DISABLES); 1687 cr->config_csr = pci_config_get16(config_handle, DB_CONF_CONF_CSR); 1688 cr->reset_control = pci_config_get32(config_handle, DB_CONF_RESET_CTRL); 1689 cr->pm_cap = pci_config_get16(config_handle, DB_CONF_PM_CAP); 1690 cr->pm_csr = pci_config_get16(config_handle, DB_CONF_PM_CSR); 1691 cr->hs_csr = pci_config_get8(config_handle, DB_CONF_HS_CSR); 1692 } 1693 #endif /* DB_DEBUG */ 1694 1695 /* 1696 * Function: db_pci_map 1697 * 1698 * Note: Only memory accesses are direct. IO could be direct 1699 * or indirect. Config accesses are always indirect. 1700 * The question here is, does the "assigned-addresses" 1701 * property entry represents the addresses in the 1702 * local domain or the host domain itself. 1703 * Strictly speaking, the assumption should be that 1704 * it is in the local domain, as the transactions 1705 * upstream or downstream are automatically 1706 * translated by the bridge chip anyway. 1707 * 1708 * Return values: 1709 * DDI_SUCCESS: map call by child device success 1710 * DDI_FAILURE: map operation failed. 1711 */ 1712 1713 static int 1714 db_pci_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 1715 off_t offset, off_t len, caddr_t *addrp) 1716 { 1717 register dev_info_t *pdip; 1718 int reg_proplen, num_regs, rnumber; 1719 uint_t addr_space_type; 1720 pci_regspec_t *pci_regsetp, pci_reg; 1721 db_ctrl_t *dbp; 1722 db_acc_pvt_t *db_pvt; 1723 ddi_acc_impl_t *ap; 1724 ddi_acc_hdl_t *hp; 1725 db_acc_cfg_addr_t *pci_addr; 1726 int instance = ddi_get_instance(dip); 1727 1728 DB_DEBUG0(DB_PCI_MAP, dip, "enter\n"); 1729 1730 /* get map type. check for config space */ 1731 switch (mp->map_type) { 1732 1733 case DDI_MT_RNUMBER : 1734 /* get the reg number */ 1735 rnumber = mp->map_obj.rnumber; 1736 1737 if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, 1738 DDI_PROP_DONTPASS, "reg", 1739 (caddr_t)&pci_regsetp, ®_proplen) 1740 != DDI_SUCCESS) 1741 return (DDI_FAILURE); 1742 1743 num_regs = reg_proplen / (int)sizeof (pci_regspec_t); 1744 if (rnumber >= num_regs) { 1745 /* this is a DDI_ME_RNUMBER_RANGE error */ 1746 kmem_free(pci_regsetp, reg_proplen); 1747 return (DDI_FAILURE); 1748 } 1749 1750 pci_reg = pci_regsetp[rnumber]; 1751 kmem_free(pci_regsetp, reg_proplen); 1752 /* FALLTHROUGH */ 1753 case DDI_MT_REGSPEC : 1754 if (mp->map_type == DDI_MT_REGSPEC) 1755 pci_reg = *(pci_regspec_t *)mp->map_obj.rp; 1756 1757 /* 1758 * Intercept config space accesses only. All other 1759 * requests go to the parent. 1760 */ 1761 addr_space_type = pci_reg.pci_phys_hi & PCI_ADDR_MASK; 1762 1763 DB_DEBUG3(DB_PCI_MAP, dip, "rdip=%lx, rnum=%d(%d)\n", 1764 rdip, rnumber, num_regs); 1765 1766 /* if we do direct map IO, then lets break here */ 1767 if ((db_io_map_mode & DB_IO_MAP_DIRECT) && 1768 (addr_space_type == PCI_ADDR_IO)) 1769 break; 1770 1771 if ((addr_space_type != PCI_ADDR_CONFIG) && 1772 (addr_space_type != PCI_ADDR_IO)) 1773 break; 1774 1775 /* 1776 * User mapping requests not legal for indirect 1777 * IO/Config Space 1778 */ 1779 if (mp->map_op == DDI_MO_MAP_HANDLE) 1780 return (DDI_FAILURE); 1781 1782 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, 1783 instance); 1784 /* get our common access handle */ 1785 hp = (ddi_acc_hdl_t *)mp->map_handlep; 1786 1787 /* Check for unmap operation */ 1788 if ((mp->map_op == DDI_MO_UNMAP) || 1789 (mp->map_op == DDI_MO_UNLOCK)) { 1790 /* 1791 * free up memory allocated for our 1792 * private access handle. 1793 */ 1794 db_pvt = (db_acc_pvt_t *) 1795 hp->ah_bus_private; 1796 DB_DEBUG1(DB_PCI_MAP, dip, 1797 "unmap rdip=%lx\n", rdip); 1798 kmem_free((void *)db_pvt, 1799 sizeof (db_acc_pvt_t)); 1800 1801 /* 1802 * unmap operation of PCI IO/config 1803 * space. 1804 */ 1805 return (DDI_SUCCESS); 1806 } 1807 1808 if (addr_space_type == PCI_ADDR_CONFIG) { 1809 /* Config space access range check */ 1810 if ((offset >= PCI_CONF_HDR_SIZE) || 1811 (len > PCI_CONF_HDR_SIZE) || 1812 (offset + len > PCI_CONF_HDR_SIZE)) { 1813 1814 return (DDI_FAILURE); 1815 } 1816 } 1817 1818 /* define the complete access handle */ 1819 hp = (ddi_acc_hdl_t *)mp->map_handlep; 1820 1821 ap = (ddi_acc_impl_t *)hp->ah_platform_private; 1822 1823 ap->ahi_get8 = db_ddi_get8; 1824 ap->ahi_get16 = db_ddi_get16; 1825 ap->ahi_get32 = db_ddi_get32; 1826 ap->ahi_get64 = db_ddi_get64; 1827 ap->ahi_put8 = db_ddi_put8; 1828 ap->ahi_put16 = db_ddi_put16; 1829 ap->ahi_put32 = db_ddi_put32; 1830 ap->ahi_put64 = db_ddi_put64; 1831 ap->ahi_rep_get8 = db_ddi_rep_get8; 1832 ap->ahi_rep_get16 = db_ddi_rep_get16; 1833 ap->ahi_rep_get32 = db_ddi_rep_get32; 1834 ap->ahi_rep_get64 = db_ddi_rep_get64; 1835 ap->ahi_rep_put8 = db_ddi_rep_put8; 1836 ap->ahi_rep_put16 = db_ddi_rep_put16; 1837 ap->ahi_rep_put32 = db_ddi_rep_put32; 1838 ap->ahi_rep_put64 = db_ddi_rep_put64; 1839 1840 /* Initialize to default check/notify functions */ 1841 ap->ahi_fault = 0; 1842 ap->ahi_fault_check = i_ddi_acc_fault_check; 1843 ap->ahi_fault_notify = i_ddi_acc_fault_notify; 1844 1845 /* allocate memory for our private handle */ 1846 db_pvt = kmem_zalloc(sizeof (db_acc_pvt_t), KM_SLEEP); 1847 hp->ah_bus_private = (void *)db_pvt; 1848 db_pvt->dbp = dbp; 1849 1850 /* record the device address for future use */ 1851 pci_addr = &db_pvt->dev_addr; 1852 pci_addr->c_busnum = 1853 PCI_REG_BUS_G(pci_reg.pci_phys_hi); 1854 pci_addr->c_devnum = 1855 PCI_REG_DEV_G(pci_reg.pci_phys_hi); 1856 pci_addr->c_funcnum = 1857 PCI_REG_FUNC_G(pci_reg.pci_phys_hi); 1858 /* 1859 * We should keep the upstream or 1860 * downstream info in our own ah_bus_private 1861 * structure, so that we do not waste our 1862 * time in the actual IO routines, figuring out 1863 * if we should use upstream or downstream 1864 * configuration addr/data register. 1865 * So, check orientation and setup registers 1866 * right now. 1867 */ 1868 switch (addr_space_type) { 1869 1870 case PCI_ADDR_CONFIG : 1871 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 1872 DB_DEBUG0(DB_PCI_MAP, dip, "primary\n"); 1873 db_pvt->mask = DS8_CONF_OWN; 1874 if (db_conf_map_mode & 1875 DB_CONF_MAP_INDIRECT_IO) { 1876 DB_DEBUG0(DB_PCI_MAP, dip, 1877 "INDIRECT_CONF\n"); 1878 1879 db_pvt->handle = 1880 dbp->csr_io_handle; 1881 db_pvt->addr = 1882 (uint32_t *) 1883 ((uchar_t *)dbp->csr_io 1884 + DB_CSR_DS_CONF_ADDR); 1885 db_pvt->data = 1886 (uint32_t *) 1887 ((uchar_t *)dbp->csr_io 1888 + DB_CSR_DS_CONF_DATA); 1889 db_pvt->bus_own = 1890 (uint8_t *) 1891 ((uchar_t *)dbp->csr_io 1892 + DB_CSR8_DS_CONF_OWN); 1893 db_pvt->bus_release = 1894 (uint8_t *) 1895 ((uchar_t *)dbp->csr_io 1896 + DB_CSR8_DS_CONF_CSR); 1897 } else { 1898 DB_DEBUG0(DB_PCI_MAP, dip, 1899 "DIRECT_CONF\n"); 1900 1901 db_pvt->handle = 1902 dbp->conf_handle; 1903 db_pvt->addr = 1904 (uint32_t *) 1905 ((uchar_t *)dbp->conf_io 1906 + DB_CONF_DS_CONF_ADDR); 1907 db_pvt->data = (uint32_t *) 1908 ((uchar_t *)dbp->conf_io 1909 + DB_CONF_DS_CONF_DATA); 1910 db_pvt->bus_own = 1911 (uint8_t *) 1912 ((uchar_t *)dbp->conf_io 1913 + DB_CONF8_DS_CONF_OWN); 1914 db_pvt->bus_release = 1915 (uint8_t *) 1916 ((uchar_t *)dbp->conf_io 1917 + DB_CONF8_DS_CONF_CSR); 1918 } 1919 } else { 1920 DB_DEBUG0(DB_PCI_MAP, dip, 1921 "secondary\n"); 1922 db_pvt->mask = US8_CONF_OWN; 1923 if (db_conf_map_mode & 1924 DB_CONF_MAP_INDIRECT_IO) { 1925 DB_DEBUG0(DB_PCI_MAP, dip, 1926 "INDIRECT_CONF\n"); 1927 1928 db_pvt->handle = 1929 dbp->csr_io_handle; 1930 db_pvt->addr = 1931 (uint32_t *) 1932 ((uchar_t *)dbp->csr_io 1933 + DB_CSR_US_CONF_ADDR); 1934 db_pvt->data = 1935 (uint32_t *) 1936 ((uchar_t *)dbp->csr_io 1937 + DB_CSR_US_CONF_DATA); 1938 db_pvt->bus_own = 1939 (uint8_t *) 1940 ((uchar_t *)dbp->csr_io 1941 + DB_CSR8_US_CONF_OWN); 1942 db_pvt->bus_release = 1943 (uint8_t *) 1944 ((uchar_t *)dbp->csr_io 1945 + DB_CSR8_US_CONF_CSR); 1946 } else { 1947 DB_DEBUG0(DB_PCI_MAP, dip, 1948 "DIRECT_CONF\n"); 1949 1950 db_pvt->handle = 1951 dbp->conf_handle; 1952 db_pvt->addr = 1953 (uint32_t *) 1954 ((uchar_t *)dbp->conf_io 1955 + DB_CONF_US_CONF_ADDR); 1956 db_pvt->data = 1957 (uint32_t *) 1958 ((uchar_t *)dbp->conf_io 1959 + DB_CONF_US_CONF_DATA); 1960 db_pvt->bus_own = 1961 (uint8_t *) 1962 ((uchar_t *)dbp->conf_io 1963 + DB_CONF8_US_CONF_OWN); 1964 db_pvt->bus_release = 1965 (uint8_t *) 1966 ((uchar_t *)dbp->conf_io 1967 + DB_CONF8_US_CONF_CSR); 1968 } 1969 } 1970 break; 1971 1972 case PCI_ADDR_IO : 1973 DB_DEBUG0(DB_PCI_MAP, dip, "PCI_ADDR_IO\n"); 1974 1975 /* ap->ahi_acc_attr |= DDI_ACCATTR_IO_SPACE; */ 1976 db_pvt->handle = dbp->csr_io_handle; 1977 if (dbp->dev_state & DB_PRIMARY_NEXUS) { 1978 DB_DEBUG0(DB_PCI_MAP, dip, "primary\n"); 1979 db_pvt->addr = (uint32_t *) 1980 ((uchar_t *)dbp->csr_io 1981 + DB_CSR_DS_IO_ADDR); 1982 db_pvt->data = (uint32_t *) 1983 ((uchar_t *)dbp->csr_io 1984 + DB_CSR_DS_IO_DATA); 1985 db_pvt->bus_own = (uint8_t *) 1986 ((uchar_t *)dbp->csr_io 1987 + DB_CSR8_DS_IO_OWN); 1988 db_pvt->bus_release = (uint8_t *) 1989 ((uchar_t *)dbp->csr_io 1990 + DB_CSR8_DS_IO_CSR); 1991 db_pvt->mask = DS8_IO_OWN; 1992 } else { 1993 DB_DEBUG0(DB_PCI_MAP, dip, 1994 "secondary\n"); 1995 db_pvt->addr = (uint32_t *) 1996 ((uchar_t *)dbp->csr_io 1997 + DB_CSR_US_IO_ADDR); 1998 db_pvt->data = (uint32_t *) 1999 ((uchar_t *)dbp->csr_io 2000 + DB_CSR_US_IO_DATA); 2001 db_pvt->bus_own = (uint8_t *) 2002 ((uchar_t *)dbp->csr_io 2003 + DB_CSR8_US_IO_OWN); 2004 db_pvt->bus_release = (uint8_t *) 2005 ((uchar_t *)dbp->csr_io 2006 + DB_CSR8_US_IO_CSR); 2007 db_pvt->mask = US8_IO_OWN; 2008 } 2009 break; 2010 2011 default : 2012 DB_DEBUG0(DB_PCI_MAP, dip, 2013 "PCI_ADDR unknown\n"); 2014 break; 2015 } 2016 2017 /* make and store a type 0/1 address in the *addrp */ 2018 if (pci_addr->c_busnum == dbp->range.lo) { 2019 *addrp = (caddr_t)DB_PCI_REG_ADDR_TYPE0( 2020 pci_addr->c_busnum, 2021 pci_addr->c_devnum, 2022 pci_addr->c_funcnum, 2023 offset); 2024 db_pvt->access_mode |= DB_PCI_CONF_CYCLE_TYPE0; 2025 DB_DEBUG0(DB_PCI_MAP, dip, 2026 "access mode type 0\n"); 2027 } else { 2028 *addrp = (caddr_t)DB_PCI_REG_ADDR_TYPE1( 2029 pci_addr->c_busnum, 2030 pci_addr->c_devnum, 2031 pci_addr->c_funcnum, 2032 offset); 2033 db_pvt->access_mode |= DB_PCI_CONF_CYCLE_TYPE1; 2034 DB_DEBUG0(DB_PCI_MAP, dip, 2035 "access mode type 1\n"); 2036 } 2037 DB_DEBUG4(DB_PCI_MAP, dip, "addrp<%x,%x,%x> = %lx\n", 2038 pci_addr->c_busnum, pci_addr->c_devnum, 2039 pci_addr->c_funcnum, *addrp); 2040 2041 return (DDI_SUCCESS); 2042 2043 default : 2044 DB_DEBUG1(DB_PCI_MAP, dip, "DDI other %x\n", 2045 mp->map_type); 2046 break; 2047 } 2048 DB_DEBUG0(DB_PCI_MAP, dip, "exit\n"); 2049 2050 pdip = (dev_info_t *)DEVI(dip)->devi_parent; 2051 return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map) 2052 (pdip, rdip, mp, offset, len, addrp)); 2053 } 2054 2055 #ifdef DB_DEBUG 2056 char *db_ctlop_name[] = { 2057 "DDI_CTLOPS_DMAPMAPC", 2058 "DDI_CTLOPS_INITCHILD", 2059 "DDI_CTLOPS_UNINITCHILD", 2060 "DDI_CTLOPS_REPORTDEV", 2061 "DDI_CTLOPS_REPORTINT", 2062 "DDI_CTLOPS_REGSIZE", 2063 "DDI_CTLOPS_NREGS", 2064 "DDI_CTLOPS_RESERVED0", 2065 "DDI_CTLOPS_SIDDEV", 2066 "DDI_CTLOPS_SLAVEONLY", 2067 "DDI_CTLOPS_AFFINITY", 2068 "DDI_CTLOPS_IOMIN", 2069 "DDI_CTLOPS_PTOB", 2070 "DDI_CTLOPS_BTOP", 2071 "DDI_CTLOPS_BTOPR", 2072 "DDI_CTLOPS_RESERVED1", 2073 "DDI_CTLOPS_RESERVED2", 2074 "DDI_CTLOPS_RESERVED3", 2075 "DDI_CTLOPS_RESERVED4", 2076 "DDI_CTLOPS_RESERVED5", 2077 "DDI_CTLOPS_DVMAPAGESIZE", 2078 "DDI_CTLOPS_POWER", 2079 "DDI_CTLOPS_ATTACH", 2080 "DDI_CTLOPS_DETACH", 2081 "DDI_CTLOPS_POKE", 2082 "DDI_CTLOPS_PEEK" 2083 }; 2084 #endif 2085 2086 static int 2087 db_ctlops(dev_info_t *dip, dev_info_t *rdip, 2088 ddi_ctl_enum_t ctlop, void *arg, void *result) 2089 { 2090 2091 if ((ctlop >= DDI_CTLOPS_DMAPMAPC) && 2092 (ctlop <= DDI_CTLOPS_DETACH)) { 2093 DB_DEBUG1(DB_CTLOPS, dip, "ctlop=%s\n", db_ctlop_name[ctlop]); 2094 } else { 2095 DB_DEBUG1(DB_CTLOPS, dip, "ctlop=%d\n", ctlop); 2096 } 2097 2098 switch (ctlop) { 2099 case DDI_CTLOPS_REPORTDEV : 2100 if (rdip == (dev_info_t *)0) 2101 return (DDI_FAILURE); 2102 cmn_err(CE_CONT, "?PCI-device: %s@%s, %s#%d\n", 2103 ddi_node_name(rdip), ddi_get_name_addr(rdip), 2104 ddi_driver_name(rdip), 2105 ddi_get_instance(rdip)); 2106 return (DDI_SUCCESS); 2107 2108 case DDI_CTLOPS_INITCHILD : 2109 return (db_initchild((dev_info_t *)arg)); 2110 2111 case DDI_CTLOPS_UNINITCHILD : 2112 db_uninitchild((dev_info_t *)arg); 2113 return (DDI_SUCCESS); 2114 2115 case DDI_CTLOPS_SIDDEV : 2116 return (DDI_SUCCESS); 2117 2118 case DDI_CTLOPS_REGSIZE : 2119 case DDI_CTLOPS_NREGS : 2120 if (rdip == (dev_info_t *)0) 2121 return (DDI_FAILURE); 2122 /* fall through */ 2123 2124 default : 2125 return (ddi_ctlops(dip, rdip, ctlop, arg, result)); 2126 } 2127 2128 } 2129 2130 static dev_info_t * 2131 db_get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip) 2132 { 2133 dev_info_t *cdip = rdip; 2134 2135 for (; ddi_get_parent(cdip) != dip; cdip = ddi_get_parent(cdip)) 2136 ; 2137 2138 return (cdip); 2139 } 2140 2141 static int 2142 db_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op, 2143 ddi_intr_handle_impl_t *hdlp, void *result) 2144 { 2145 dev_info_t *cdip = rdip; 2146 pci_regspec_t *pci_rp; 2147 int reglen, len; 2148 uint32_t d, intr; 2149 2150 DB_DEBUG1(DB_INTR_OPS, dip, "intr_op=%d\n", intr_op); 2151 2152 if ((intr_op == DDI_INTROP_SUPPORTED_TYPES) || 2153 (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_devi_attached(dip)) 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_devi_attached(dip)) 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 db_p->fm_cap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE | 3058 DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE; 3059 3060 /* 3061 * Request our capability level and get our parents capability 3062 * and ibc. 3063 */ 3064 ddi_fm_init(db_p->dip, &db_p->fm_cap, &db_p->fm_ibc); 3065 ASSERT((db_p->fm_cap & DDI_FM_EREPORT_CAPABLE) && 3066 (db_p->fm_cap & DDI_FM_ERRCB_CAPABLE)); 3067 3068 pci_ereport_setup(db_p->dip); 3069 3070 /* 3071 * Register error callback with our parent. 3072 */ 3073 ddi_fm_handler_register(db_p->dip, db_err_callback, NULL); 3074 } 3075 3076 /* 3077 * Breakdown our FMA resources 3078 */ 3079 static void 3080 db_fm_fini(db_ctrl_t *db_p) 3081 { 3082 /* 3083 * Clean up allocated fm structures 3084 */ 3085 ddi_fm_handler_unregister(db_p->dip); 3086 pci_ereport_teardown(db_p->dip); 3087 ddi_fm_fini(db_p->dip); 3088 } 3089 3090 /* 3091 * Initialize FMA resources for children devices. Called when 3092 * child calls ddi_fm_init(). 3093 */ 3094 /*ARGSUSED*/ 3095 static int 3096 db_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap, 3097 ddi_iblock_cookie_t *ibc) 3098 { 3099 db_ctrl_t *db_p = (db_ctrl_t *)ddi_get_soft_state(db_state, 3100 ddi_get_instance(dip)); 3101 *ibc = db_p->fm_ibc; 3102 return (db_p->fm_cap); 3103 } 3104 3105 /* 3106 * FMA registered error callback 3107 */ 3108 static int 3109 db_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *impl_data) 3110 { 3111 ASSERT(impl_data == NULL); 3112 pci_ereport_post(dip, derr, NULL); 3113 return (derr->fme_status); 3114 } 3115 3116 static void 3117 db_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle) 3118 { 3119 i_ndi_busop_access_enter(dip, handle); 3120 } 3121 3122 /* ARGSUSED */ 3123 static void 3124 db_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle) 3125 { 3126 i_ndi_busop_access_exit(dip, handle); 3127 } 3128