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