1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 #include <sys/scsi/adapters/pmcs/pmcs.h> 26 27 #define PMCS_DRIVER_VERSION "pmcs HBA device driver" 28 29 static char *pmcs_driver_rev = PMCS_DRIVER_VERSION; 30 31 /* 32 * Non-DDI Compliant stuff 33 */ 34 extern char hw_serial[]; 35 36 /* 37 * Global driver data 38 */ 39 void *pmcs_softc_state = NULL; 40 void *pmcs_iport_softstate = NULL; 41 42 /* 43 * Tracing and Logging info 44 */ 45 pmcs_tbuf_t *pmcs_tbuf = NULL; 46 uint32_t pmcs_tbuf_num_elems = 0; 47 pmcs_tbuf_t *pmcs_tbuf_ptr; 48 uint32_t pmcs_tbuf_idx = 0; 49 boolean_t pmcs_tbuf_wrap = B_FALSE; 50 static kmutex_t pmcs_trace_lock; 51 52 /* 53 * If pmcs_force_syslog value is non-zero, all messages put in the trace log 54 * will also be sent to system log. 55 */ 56 int pmcs_force_syslog = 0; 57 int pmcs_console = 0; 58 59 /* 60 * External References 61 */ 62 extern int ncpus_online; 63 64 /* 65 * Local static data 66 */ 67 static int fwlog_level = 3; 68 static int physpeed = PHY_LINK_ALL; 69 static int phymode = PHY_LM_AUTO; 70 static int block_mask = 0; 71 static int phymap_usec = 3 * MICROSEC; 72 static int iportmap_usec = 2 * MICROSEC; 73 74 #ifdef DEBUG 75 static int debug_mask = 1; 76 #else 77 static int debug_mask = 0; 78 #endif 79 80 #ifdef DISABLE_MSIX 81 static int disable_msix = 1; 82 #else 83 static int disable_msix = 0; 84 #endif 85 86 #ifdef DISABLE_MSI 87 static int disable_msi = 1; 88 #else 89 static int disable_msi = 0; 90 #endif 91 92 static uint16_t maxqdepth = 0xfffe; 93 94 /* 95 * Local prototypes 96 */ 97 static int pmcs_attach(dev_info_t *, ddi_attach_cmd_t); 98 static int pmcs_detach(dev_info_t *, ddi_detach_cmd_t); 99 static int pmcs_unattach(pmcs_hw_t *); 100 static int pmcs_iport_unattach(pmcs_iport_t *); 101 static int pmcs_add_more_chunks(pmcs_hw_t *, unsigned long); 102 static void pmcs_watchdog(void *); 103 static int pmcs_setup_intr(pmcs_hw_t *); 104 static int pmcs_teardown_intr(pmcs_hw_t *); 105 106 static uint_t pmcs_nonio_ix(caddr_t, caddr_t); 107 static uint_t pmcs_general_ix(caddr_t, caddr_t); 108 static uint_t pmcs_event_ix(caddr_t, caddr_t); 109 static uint_t pmcs_iodone_ix(caddr_t, caddr_t); 110 static uint_t pmcs_fatal_ix(caddr_t, caddr_t); 111 static uint_t pmcs_all_intr(caddr_t, caddr_t); 112 static int pmcs_quiesce(dev_info_t *dip); 113 static boolean_t pmcs_fabricate_wwid(pmcs_hw_t *); 114 115 static void pmcs_create_phy_stats(pmcs_iport_t *); 116 int pmcs_update_phy_stats(kstat_t *, int); 117 static void pmcs_destroy_phy_stats(pmcs_iport_t *); 118 119 static void pmcs_fm_fini(pmcs_hw_t *pwp); 120 static void pmcs_fm_init(pmcs_hw_t *pwp); 121 static int pmcs_fm_error_cb(dev_info_t *dip, 122 ddi_fm_error_t *err, const void *impl_data); 123 124 /* 125 * Local configuration data 126 */ 127 static struct dev_ops pmcs_ops = { 128 DEVO_REV, /* devo_rev, */ 129 0, /* refcnt */ 130 ddi_no_info, /* info */ 131 nulldev, /* identify */ 132 nulldev, /* probe */ 133 pmcs_attach, /* attach */ 134 pmcs_detach, /* detach */ 135 nodev, /* reset */ 136 NULL, /* driver operations */ 137 NULL, /* bus operations */ 138 ddi_power, /* power management */ 139 pmcs_quiesce /* quiesce */ 140 }; 141 142 static struct modldrv modldrv = { 143 &mod_driverops, 144 PMCS_DRIVER_VERSION, 145 &pmcs_ops, /* driver ops */ 146 }; 147 static struct modlinkage modlinkage = { 148 MODREV_1, &modldrv, NULL 149 }; 150 151 const ddi_dma_attr_t pmcs_dattr = { 152 DMA_ATTR_V0, /* dma_attr version */ 153 0x0000000000000000ull, /* dma_attr_addr_lo */ 154 0xFFFFFFFFFFFFFFFFull, /* dma_attr_addr_hi */ 155 0x00000000FFFFFFFFull, /* dma_attr_count_max */ 156 0x0000000000000001ull, /* dma_attr_align */ 157 0x00000078, /* dma_attr_burstsizes */ 158 0x00000001, /* dma_attr_minxfer */ 159 0x00000000FFFFFFFFull, /* dma_attr_maxxfer */ 160 0x00000000FFFFFFFFull, /* dma_attr_seg */ 161 1, /* dma_attr_sgllen */ 162 512, /* dma_attr_granular */ 163 0 /* dma_attr_flags */ 164 }; 165 166 static ddi_device_acc_attr_t rattr = { 167 DDI_DEVICE_ATTR_V0, 168 DDI_STRUCTURE_LE_ACC, 169 DDI_STRICTORDER_ACC, 170 DDI_DEFAULT_ACC 171 }; 172 173 174 /* 175 * Attach/Detach functions 176 */ 177 178 int 179 _init(void) 180 { 181 int ret; 182 183 ret = ddi_soft_state_init(&pmcs_softc_state, sizeof (pmcs_hw_t), 1); 184 if (ret != 0) { 185 cmn_err(CE_WARN, "?soft state init failed for pmcs"); 186 return (ret); 187 } 188 189 if ((ret = scsi_hba_init(&modlinkage)) != 0) { 190 cmn_err(CE_WARN, "?scsi_hba_init failed for pmcs"); 191 ddi_soft_state_fini(&pmcs_softc_state); 192 return (ret); 193 } 194 195 /* 196 * Allocate soft state for iports 197 */ 198 ret = ddi_soft_state_init(&pmcs_iport_softstate, 199 sizeof (pmcs_iport_t), 2); 200 if (ret != 0) { 201 cmn_err(CE_WARN, "?iport soft state init failed for pmcs"); 202 ddi_soft_state_fini(&pmcs_softc_state); 203 return (ret); 204 } 205 206 ret = mod_install(&modlinkage); 207 if (ret != 0) { 208 cmn_err(CE_WARN, "?mod_install failed for pmcs (%d)", ret); 209 scsi_hba_fini(&modlinkage); 210 ddi_soft_state_fini(&pmcs_iport_softstate); 211 ddi_soft_state_fini(&pmcs_softc_state); 212 return (ret); 213 } 214 215 /* Initialize the global trace lock */ 216 mutex_init(&pmcs_trace_lock, NULL, MUTEX_DRIVER, NULL); 217 218 return (0); 219 } 220 221 int 222 _fini(void) 223 { 224 int ret; 225 if ((ret = mod_remove(&modlinkage)) != 0) { 226 return (ret); 227 } 228 scsi_hba_fini(&modlinkage); 229 230 /* Free pmcs log buffer and destroy the global lock */ 231 if (pmcs_tbuf) { 232 kmem_free(pmcs_tbuf, 233 pmcs_tbuf_num_elems * sizeof (pmcs_tbuf_t)); 234 pmcs_tbuf = NULL; 235 } 236 mutex_destroy(&pmcs_trace_lock); 237 238 ddi_soft_state_fini(&pmcs_iport_softstate); 239 ddi_soft_state_fini(&pmcs_softc_state); 240 return (0); 241 } 242 243 int 244 _info(struct modinfo *modinfop) 245 { 246 return (mod_info(&modlinkage, modinfop)); 247 } 248 249 static int 250 pmcs_iport_attach(dev_info_t *dip) 251 { 252 pmcs_iport_t *iport; 253 pmcs_hw_t *pwp; 254 scsi_hba_tran_t *tran; 255 void *ua_priv = NULL; 256 char *iport_ua; 257 char *init_port; 258 int hba_inst; 259 int inst; 260 261 hba_inst = ddi_get_instance(ddi_get_parent(dip)); 262 inst = ddi_get_instance(dip); 263 264 pwp = ddi_get_soft_state(pmcs_softc_state, hba_inst); 265 if (pwp == NULL) { 266 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 267 "%s: iport%d attach invoked with NULL parent (HBA) node)", 268 __func__, inst); 269 return (DDI_FAILURE); 270 } 271 272 if ((pwp->state == STATE_UNPROBING) || (pwp->state == STATE_DEAD)) { 273 return (DDI_FAILURE); 274 } 275 276 if ((iport_ua = scsi_hba_iport_unit_address(dip)) == NULL) { 277 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 278 "%s: invoked with NULL unit address, inst (%d)", 279 __func__, inst); 280 return (DDI_FAILURE); 281 } 282 283 if (ddi_soft_state_zalloc(pmcs_iport_softstate, inst) != DDI_SUCCESS) { 284 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 285 "Failed to alloc soft state for iport %d", inst); 286 return (DDI_FAILURE); 287 } 288 289 iport = ddi_get_soft_state(pmcs_iport_softstate, inst); 290 if (iport == NULL) { 291 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 292 "cannot get iport soft state"); 293 goto iport_attach_fail1; 294 } 295 296 mutex_init(&iport->lock, NULL, MUTEX_DRIVER, 297 DDI_INTR_PRI(pwp->intr_pri)); 298 cv_init(&iport->refcnt_cv, NULL, CV_DEFAULT, NULL); 299 mutex_init(&iport->refcnt_lock, NULL, MUTEX_DRIVER, 300 DDI_INTR_PRI(pwp->intr_pri)); 301 302 /* Set some data on the iport handle */ 303 iport->dip = dip; 304 iport->pwp = pwp; 305 306 /* Dup the UA into the iport handle */ 307 iport->ua = strdup(iport_ua); 308 309 tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip); 310 tran->tran_hba_private = iport; 311 312 list_create(&iport->phys, sizeof (pmcs_phy_t), 313 offsetof(pmcs_phy_t, list_node)); 314 315 /* 316 * If our unit address is active in the phymap, configure our 317 * iport's phylist. 318 */ 319 mutex_enter(&iport->lock); 320 ua_priv = sas_phymap_lookup_uapriv(pwp->hss_phymap, iport->ua); 321 if (ua_priv) { 322 /* Non-NULL private data indicates the unit address is active */ 323 iport->ua_state = UA_ACTIVE; 324 if (pmcs_iport_configure_phys(iport) != DDI_SUCCESS) { 325 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 326 "%s: failed to " 327 "configure phys on iport handle (0x%p), " 328 " unit address [%s]", __func__, 329 (void *)iport, iport_ua); 330 mutex_exit(&iport->lock); 331 goto iport_attach_fail2; 332 } 333 } else { 334 iport->ua_state = UA_INACTIVE; 335 } 336 mutex_exit(&iport->lock); 337 338 /* Allocate string-based soft state pool for targets */ 339 iport->tgt_sstate = NULL; 340 if (ddi_soft_state_bystr_init(&iport->tgt_sstate, 341 sizeof (pmcs_xscsi_t), PMCS_TGT_SSTATE_SZ) != 0) { 342 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 343 "cannot get iport tgt soft state"); 344 goto iport_attach_fail2; 345 } 346 347 /* Create this iport's target map */ 348 if (pmcs_iport_tgtmap_create(iport) == B_FALSE) { 349 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 350 "Failed to create tgtmap on iport %d", inst); 351 goto iport_attach_fail3; 352 } 353 354 /* Set up the 'initiator-port' DDI property on this iport */ 355 init_port = kmem_zalloc(PMCS_MAX_UA_SIZE, KM_SLEEP); 356 if (pwp->separate_ports) { 357 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 358 "%s: separate ports not supported", __func__); 359 } else { 360 /* Set initiator-port value to the HBA's base WWN */ 361 (void) scsi_wwn_to_wwnstr(pwp->sas_wwns[0], 1, 362 init_port); 363 } 364 365 mutex_enter(&iport->lock); 366 pmcs_smhba_add_iport_prop(iport, DATA_TYPE_STRING, 367 SCSI_ADDR_PROP_INITIATOR_PORT, init_port); 368 kmem_free(init_port, PMCS_MAX_UA_SIZE); 369 370 /* Set up a 'num-phys' DDI property for the iport node */ 371 pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, PMCS_NUM_PHYS, 372 &iport->nphy); 373 mutex_exit(&iport->lock); 374 375 /* Create kstats for each of the phys in this port */ 376 pmcs_create_phy_stats(iport); 377 378 /* 379 * Insert this iport handle into our list and set 380 * iports_attached on the HBA node. 381 */ 382 rw_enter(&pwp->iports_lock, RW_WRITER); 383 ASSERT(!list_link_active(&iport->list_node)); 384 list_insert_tail(&pwp->iports, iport); 385 pwp->iports_attached = 1; 386 pwp->num_iports++; 387 rw_exit(&pwp->iports_lock); 388 389 pmcs_prt(pwp, PMCS_PRT_DEBUG_IPORT, NULL, NULL, 390 "iport%d attached", inst); 391 ddi_report_dev(dip); 392 return (DDI_SUCCESS); 393 394 /* teardown and fail */ 395 iport_attach_fail3: 396 ddi_soft_state_bystr_fini(&iport->tgt_sstate); 397 iport_attach_fail2: 398 list_destroy(&iport->phys); 399 strfree(iport->ua); 400 mutex_destroy(&iport->refcnt_lock); 401 cv_destroy(&iport->refcnt_cv); 402 mutex_destroy(&iport->lock); 403 iport_attach_fail1: 404 ddi_soft_state_free(pmcs_iport_softstate, inst); 405 return (DDI_FAILURE); 406 } 407 408 static int 409 pmcs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 410 { 411 scsi_hba_tran_t *tran; 412 char chiprev, *fwsupport, hw_rev[24], fw_rev[24]; 413 off_t set3size; 414 int inst, i; 415 int sm_hba = 1; 416 int protocol = 0; 417 int num_phys = 0; 418 pmcs_hw_t *pwp; 419 pmcs_phy_t *phyp; 420 uint32_t num_threads; 421 char buf[64]; 422 423 switch (cmd) { 424 case DDI_ATTACH: 425 break; 426 427 case DDI_PM_RESUME: 428 case DDI_RESUME: 429 tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip); 430 if (!tran) { 431 return (DDI_FAILURE); 432 } 433 /* No DDI_?_RESUME on iport nodes */ 434 if (scsi_hba_iport_unit_address(dip) != NULL) { 435 return (DDI_SUCCESS); 436 } 437 pwp = TRAN2PMC(tran); 438 if (pwp == NULL) { 439 return (DDI_FAILURE); 440 } 441 442 mutex_enter(&pwp->lock); 443 pwp->suspended = 0; 444 if (pwp->tq) { 445 ddi_taskq_resume(pwp->tq); 446 } 447 mutex_exit(&pwp->lock); 448 return (DDI_SUCCESS); 449 450 default: 451 return (DDI_FAILURE); 452 } 453 454 /* 455 * If this is an iport node, invoke iport attach. 456 */ 457 if (scsi_hba_iport_unit_address(dip) != NULL) { 458 return (pmcs_iport_attach(dip)); 459 } 460 461 /* 462 * From here on is attach for the HBA node 463 */ 464 465 #ifdef DEBUG 466 /* 467 * Check to see if this unit is to be disabled. We can't disable 468 * on a per-iport node. It's either the entire HBA or nothing. 469 */ 470 (void) snprintf(buf, sizeof (buf), 471 "disable-instance-%d", ddi_get_instance(dip)); 472 if (ddi_prop_get_int(DDI_DEV_T_ANY, dip, 473 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, buf, 0)) { 474 cmn_err(CE_NOTE, "pmcs%d: disabled by configuration", 475 ddi_get_instance(dip)); 476 return (DDI_FAILURE); 477 } 478 #endif 479 480 /* 481 * Allocate softstate 482 */ 483 inst = ddi_get_instance(dip); 484 if (ddi_soft_state_zalloc(pmcs_softc_state, inst) != DDI_SUCCESS) { 485 cmn_err(CE_WARN, "pmcs%d: Failed to alloc soft state", inst); 486 return (DDI_FAILURE); 487 } 488 489 pwp = ddi_get_soft_state(pmcs_softc_state, inst); 490 if (pwp == NULL) { 491 cmn_err(CE_WARN, "pmcs%d: cannot get soft state", inst); 492 ddi_soft_state_free(pmcs_softc_state, inst); 493 return (DDI_FAILURE); 494 } 495 pwp->dip = dip; 496 STAILQ_INIT(&pwp->dq); 497 STAILQ_INIT(&pwp->cq); 498 STAILQ_INIT(&pwp->wf); 499 STAILQ_INIT(&pwp->pf); 500 /* 501 * Create the list for iports 502 */ 503 list_create(&pwp->iports, sizeof (pmcs_iport_t), 504 offsetof(pmcs_iport_t, list_node)); 505 506 pwp->state = STATE_PROBING; 507 508 /* 509 * Get driver.conf properties 510 */ 511 pwp->debug_mask = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 512 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-debug-mask", 513 debug_mask); 514 pwp->phyid_block_mask = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 515 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-phyid-block-mask", 516 block_mask); 517 pwp->physpeed = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 518 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-physpeed", physpeed); 519 pwp->phymode = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 520 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-phymode", phymode); 521 pwp->fwlog = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 522 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-fwlog", fwlog_level); 523 if (pwp->fwlog > PMCS_FWLOG_MAX) { 524 pwp->fwlog = PMCS_FWLOG_MAX; 525 } 526 527 mutex_enter(&pmcs_trace_lock); 528 if (pmcs_tbuf == NULL) { 529 /* Allocate trace buffer */ 530 pmcs_tbuf_num_elems = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 531 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-tbuf-num-elems", 532 PMCS_TBUF_NUM_ELEMS_DEF); 533 if ((pmcs_tbuf_num_elems == DDI_PROP_NOT_FOUND) || 534 (pmcs_tbuf_num_elems == 0)) { 535 pmcs_tbuf_num_elems = PMCS_TBUF_NUM_ELEMS_DEF; 536 } 537 538 pmcs_tbuf = kmem_zalloc(pmcs_tbuf_num_elems * 539 sizeof (pmcs_tbuf_t), KM_SLEEP); 540 pmcs_tbuf_ptr = pmcs_tbuf; 541 pmcs_tbuf_idx = 0; 542 } 543 mutex_exit(&pmcs_trace_lock); 544 545 disable_msix = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 546 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-disable-msix", 547 disable_msix); 548 disable_msi = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 549 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-disable-msi", 550 disable_msi); 551 maxqdepth = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 552 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-maxqdepth", maxqdepth); 553 pwp->fw_force_update = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 554 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-fw-force-update", 0); 555 if (pwp->fw_force_update == 0) { 556 pwp->fw_disable_update = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 557 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 558 "pmcs-fw-disable-update", 0); 559 } 560 pwp->ioq_depth = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 561 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-num-io-qentries", 562 PMCS_NQENTRY); 563 564 /* 565 * Initialize FMA 566 */ 567 pwp->dev_acc_attr = pwp->reg_acc_attr = rattr; 568 pwp->iqp_dma_attr = pwp->oqp_dma_attr = 569 pwp->regdump_dma_attr = pwp->cip_dma_attr = 570 pwp->fwlog_dma_attr = pmcs_dattr; 571 pwp->fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, pwp->dip, 572 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, "fm-capable", 573 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE | 574 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE); 575 pmcs_fm_init(pwp); 576 577 /* 578 * Map registers 579 */ 580 if (pci_config_setup(dip, &pwp->pci_acc_handle)) { 581 pmcs_prt(pwp, PMCS_PRT_WARN, NULL, NULL, 582 "pci config setup failed"); 583 ddi_soft_state_free(pmcs_softc_state, inst); 584 return (DDI_FAILURE); 585 } 586 587 /* 588 * Get the size of register set 3. 589 */ 590 if (ddi_dev_regsize(dip, PMCS_REGSET_3, &set3size) != DDI_SUCCESS) { 591 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 592 "unable to get size of register set %d", PMCS_REGSET_3); 593 pci_config_teardown(&pwp->pci_acc_handle); 594 ddi_soft_state_free(pmcs_softc_state, inst); 595 return (DDI_FAILURE); 596 } 597 598 /* 599 * Map registers 600 */ 601 pwp->reg_acc_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 602 603 if (ddi_regs_map_setup(dip, PMCS_REGSET_0, (caddr_t *)&pwp->msg_regs, 604 0, 0, &pwp->reg_acc_attr, &pwp->msg_acc_handle)) { 605 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 606 "failed to map Message Unit registers"); 607 pci_config_teardown(&pwp->pci_acc_handle); 608 ddi_soft_state_free(pmcs_softc_state, inst); 609 return (DDI_FAILURE); 610 } 611 612 if (ddi_regs_map_setup(dip, PMCS_REGSET_1, (caddr_t *)&pwp->top_regs, 613 0, 0, &pwp->reg_acc_attr, &pwp->top_acc_handle)) { 614 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 615 "failed to map TOP registers"); 616 ddi_regs_map_free(&pwp->msg_acc_handle); 617 pci_config_teardown(&pwp->pci_acc_handle); 618 ddi_soft_state_free(pmcs_softc_state, inst); 619 return (DDI_FAILURE); 620 } 621 622 if (ddi_regs_map_setup(dip, PMCS_REGSET_2, (caddr_t *)&pwp->gsm_regs, 623 0, 0, &pwp->reg_acc_attr, &pwp->gsm_acc_handle)) { 624 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 625 "failed to map GSM registers"); 626 ddi_regs_map_free(&pwp->top_acc_handle); 627 ddi_regs_map_free(&pwp->msg_acc_handle); 628 pci_config_teardown(&pwp->pci_acc_handle); 629 ddi_soft_state_free(pmcs_softc_state, inst); 630 return (DDI_FAILURE); 631 } 632 633 if (ddi_regs_map_setup(dip, PMCS_REGSET_3, (caddr_t *)&pwp->mpi_regs, 634 0, 0, &pwp->reg_acc_attr, &pwp->mpi_acc_handle)) { 635 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 636 "failed to map MPI registers"); 637 ddi_regs_map_free(&pwp->top_acc_handle); 638 ddi_regs_map_free(&pwp->gsm_acc_handle); 639 ddi_regs_map_free(&pwp->msg_acc_handle); 640 pci_config_teardown(&pwp->pci_acc_handle); 641 ddi_soft_state_free(pmcs_softc_state, inst); 642 return (DDI_FAILURE); 643 } 644 pwp->mpibar = 645 (((5U << 2) + 0x10) << PMCS_MSGU_MPI_BAR_SHIFT) | set3size; 646 647 /* 648 * Make sure we can support this card. 649 */ 650 pwp->chiprev = pmcs_rd_topunit(pwp, PMCS_DEVICE_REVISION); 651 652 switch (pwp->chiprev) { 653 case PMCS_PM8001_REV_A: 654 case PMCS_PM8001_REV_B: 655 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, 656 "Rev A/B Card no longer supported"); 657 goto failure; 658 case PMCS_PM8001_REV_C: 659 break; 660 default: 661 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, 662 "Unknown chip revision (%d)", pwp->chiprev); 663 goto failure; 664 } 665 666 /* 667 * Allocate DMA addressable area for Inbound and Outbound Queue indices 668 * that the chip needs to access plus a space for scratch usage 669 */ 670 pwp->cip_dma_attr.dma_attr_align = sizeof (uint32_t); 671 if (pmcs_dma_setup(pwp, &pwp->cip_dma_attr, &pwp->cip_acchdls, 672 &pwp->cip_handles, ptob(1), (caddr_t *)&pwp->cip, 673 &pwp->ciaddr) == B_FALSE) { 674 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 675 "Failed to setup DMA for index/scratch"); 676 goto failure; 677 } 678 679 bzero(pwp->cip, ptob(1)); 680 pwp->scratch = &pwp->cip[PMCS_INDICES_SIZE]; 681 pwp->scratch_dma = pwp->ciaddr + PMCS_INDICES_SIZE; 682 683 /* 684 * Allocate DMA S/G list chunks 685 */ 686 (void) pmcs_add_more_chunks(pwp, ptob(1) * PMCS_MIN_CHUNK_PAGES); 687 688 /* 689 * Allocate a DMA addressable area for the firmware log (if needed) 690 */ 691 if (pwp->fwlog) { 692 /* 693 * Align to event log header and entry size 694 */ 695 pwp->fwlog_dma_attr.dma_attr_align = 32; 696 if (pmcs_dma_setup(pwp, &pwp->fwlog_dma_attr, 697 &pwp->fwlog_acchdl, 698 &pwp->fwlog_hndl, PMCS_FWLOG_SIZE, 699 (caddr_t *)&pwp->fwlogp, 700 &pwp->fwaddr) == B_FALSE) { 701 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 702 "Failed to setup DMA for fwlog area"); 703 pwp->fwlog = 0; 704 } else { 705 bzero(pwp->fwlogp, PMCS_FWLOG_SIZE); 706 } 707 } 708 709 if (pwp->flash_chunk_addr == NULL) { 710 pwp->regdump_dma_attr.dma_attr_align = PMCS_FLASH_CHUNK_SIZE; 711 if (pmcs_dma_setup(pwp, &pwp->regdump_dma_attr, 712 &pwp->regdump_acchdl, 713 &pwp->regdump_hndl, PMCS_FLASH_CHUNK_SIZE, 714 (caddr_t *)&pwp->flash_chunkp, &pwp->flash_chunk_addr) == 715 B_FALSE) { 716 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 717 "Failed to setup DMA for register dump area"); 718 goto failure; 719 } 720 bzero(pwp->flash_chunkp, PMCS_FLASH_CHUNK_SIZE); 721 } 722 723 /* 724 * More bits of local initialization... 725 */ 726 pwp->tq = ddi_taskq_create(dip, "_tq", 4, TASKQ_DEFAULTPRI, 0); 727 if (pwp->tq == NULL) { 728 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 729 "unable to create worker taskq"); 730 goto failure; 731 } 732 733 /* 734 * Cache of structures for dealing with I/O completion callbacks. 735 */ 736 (void) snprintf(buf, sizeof (buf), "pmcs_iocomp_cb_cache%d", inst); 737 pwp->iocomp_cb_cache = kmem_cache_create(buf, 738 sizeof (pmcs_iocomp_cb_t), 16, NULL, NULL, NULL, NULL, NULL, 0); 739 740 /* 741 * Cache of PHY structures 742 */ 743 (void) snprintf(buf, sizeof (buf), "pmcs_phy_cache%d", inst); 744 pwp->phy_cache = kmem_cache_create(buf, sizeof (pmcs_phy_t), 8, 745 pmcs_phy_constructor, pmcs_phy_destructor, NULL, (void *)pwp, 746 NULL, 0); 747 748 /* 749 * Allocate space for the I/O completion threads 750 */ 751 num_threads = ncpus_online; 752 if (num_threads > PMCS_MAX_CQ_THREADS) { 753 num_threads = PMCS_MAX_CQ_THREADS; 754 } 755 756 pwp->cq_info.cq_thr_info = kmem_zalloc(sizeof (pmcs_cq_thr_info_t) * 757 num_threads, KM_SLEEP); 758 pwp->cq_info.cq_threads = num_threads; 759 pwp->cq_info.cq_next_disp_thr = 0; 760 pwp->cq_info.cq_stop = B_FALSE; 761 762 /* 763 * Set the quantum value in clock ticks for the I/O interrupt 764 * coalescing timer. 765 */ 766 pwp->io_intr_coal.quantum = drv_usectohz(PMCS_QUANTUM_TIME_USECS); 767 768 /* 769 * We have a delicate dance here. We need to set up 770 * interrupts so we know how to set up some OQC 771 * tables. However, while we're setting up table 772 * access, we may need to flash new firmware and 773 * reset the card, which will take some finessing. 774 */ 775 776 /* 777 * Set up interrupts here. 778 */ 779 switch (pmcs_setup_intr(pwp)) { 780 case 0: 781 break; 782 case EIO: 783 pwp->stuck = 1; 784 /* FALLTHROUGH */ 785 default: 786 goto failure; 787 } 788 789 /* 790 * Set these up now becuase they are used to initialize the OQC tables. 791 * 792 * If we have MSI or MSI-X interrupts set up and we have enough 793 * vectors for each OQ, the Outbound Queue vectors can all be the 794 * same as the appropriate interrupt routine will have been called 795 * and the doorbell register automatically cleared. 796 * This keeps us from having to check the Outbound Doorbell register 797 * when the routines for these interrupts are called. 798 * 799 * If we have Legacy INT-X interrupts set up or we didn't have enough 800 * MSI/MSI-X vectors to uniquely identify each OQ, we point these 801 * vectors to the bits we would like to have set in the Outbound 802 * Doorbell register because pmcs_all_intr will read the doorbell 803 * register to find out why we have an interrupt and write the 804 * corresponding 'clear' bit for that interrupt. 805 */ 806 807 switch (pwp->intr_cnt) { 808 case 1: 809 /* 810 * Only one vector, so we must check all OQs for MSI. For 811 * INT-X, there's only one vector anyway, so we can just 812 * use the outbound queue bits to keep from having to 813 * check each queue for each interrupt. 814 */ 815 if (pwp->int_type == PMCS_INT_FIXED) { 816 pwp->oqvec[PMCS_OQ_IODONE] = PMCS_OQ_IODONE; 817 pwp->oqvec[PMCS_OQ_GENERAL] = PMCS_OQ_GENERAL; 818 pwp->oqvec[PMCS_OQ_EVENTS] = PMCS_OQ_EVENTS; 819 } else { 820 pwp->oqvec[PMCS_OQ_IODONE] = PMCS_OQ_IODONE; 821 pwp->oqvec[PMCS_OQ_GENERAL] = PMCS_OQ_IODONE; 822 pwp->oqvec[PMCS_OQ_EVENTS] = PMCS_OQ_IODONE; 823 } 824 break; 825 case 2: 826 /* With 2, we can at least isolate IODONE */ 827 pwp->oqvec[PMCS_OQ_IODONE] = PMCS_OQ_IODONE; 828 pwp->oqvec[PMCS_OQ_GENERAL] = PMCS_OQ_GENERAL; 829 pwp->oqvec[PMCS_OQ_EVENTS] = PMCS_OQ_GENERAL; 830 break; 831 case 4: 832 /* With 4 vectors, everybody gets one */ 833 pwp->oqvec[PMCS_OQ_IODONE] = PMCS_OQ_IODONE; 834 pwp->oqvec[PMCS_OQ_GENERAL] = PMCS_OQ_GENERAL; 835 pwp->oqvec[PMCS_OQ_EVENTS] = PMCS_OQ_EVENTS; 836 break; 837 } 838 839 /* 840 * Do the first part of setup 841 */ 842 if (pmcs_setup(pwp)) { 843 goto failure; 844 } 845 pmcs_report_fwversion(pwp); 846 847 /* 848 * Now do some additonal allocations based upon information 849 * gathered during MPI setup. 850 */ 851 pwp->root_phys = kmem_zalloc(pwp->nphy * sizeof (pmcs_phy_t), KM_SLEEP); 852 ASSERT(pwp->nphy < SAS2_PHYNUM_MAX); 853 phyp = pwp->root_phys; 854 for (i = 0; i < pwp->nphy; i++) { 855 if (i < pwp->nphy-1) { 856 phyp->sibling = (phyp + 1); 857 } 858 mutex_init(&phyp->phy_lock, NULL, MUTEX_DRIVER, 859 DDI_INTR_PRI(pwp->intr_pri)); 860 phyp->phynum = i & SAS2_PHYNUM_MASK; 861 pmcs_phy_name(pwp, phyp, phyp->path, sizeof (phyp->path)); 862 phyp->pwp = pwp; 863 phyp->device_id = PMCS_INVALID_DEVICE_ID; 864 phyp++; 865 } 866 867 pwp->work = kmem_zalloc(pwp->max_cmd * sizeof (pmcwork_t), KM_SLEEP); 868 for (i = 0; i < pwp->max_cmd - 1; i++) { 869 pmcwork_t *pwrk = &pwp->work[i]; 870 mutex_init(&pwrk->lock, NULL, MUTEX_DRIVER, 871 DDI_INTR_PRI(pwp->intr_pri)); 872 cv_init(&pwrk->sleep_cv, NULL, CV_DRIVER, NULL); 873 STAILQ_INSERT_TAIL(&pwp->wf, pwrk, next); 874 875 } 876 pwp->targets = (pmcs_xscsi_t **) 877 kmem_zalloc(pwp->max_dev * sizeof (pmcs_xscsi_t *), KM_SLEEP); 878 879 pwp->iqpt = (pmcs_iqp_trace_t *) 880 kmem_zalloc(sizeof (pmcs_iqp_trace_t), KM_SLEEP); 881 pwp->iqpt->head = kmem_zalloc(PMCS_IQP_TRACE_BUFFER_SIZE, KM_SLEEP); 882 pwp->iqpt->curpos = pwp->iqpt->head; 883 pwp->iqpt->size_left = PMCS_IQP_TRACE_BUFFER_SIZE; 884 885 /* 886 * Start MPI communication. 887 */ 888 if (pmcs_start_mpi(pwp)) { 889 if (pmcs_soft_reset(pwp, B_FALSE)) { 890 goto failure; 891 } 892 } 893 894 /* 895 * Do some initial acceptance tests. 896 * This tests interrupts and queues. 897 */ 898 if (pmcs_echo_test(pwp)) { 899 goto failure; 900 } 901 902 /* Read VPD - if it exists */ 903 if (pmcs_get_nvmd(pwp, PMCS_NVMD_VPD, PMCIN_NVMD_VPD, 0, NULL, 0)) { 904 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 905 "%s: Unable to read VPD: " 906 "attempting to fabricate", __func__); 907 /* 908 * When we release, this must goto failure and the call 909 * to pmcs_fabricate_wwid is removed. 910 */ 911 /* goto failure; */ 912 if (!pmcs_fabricate_wwid(pwp)) { 913 goto failure; 914 } 915 } 916 917 /* 918 * We're now officially running 919 */ 920 pwp->state = STATE_RUNNING; 921 922 /* 923 * Check firmware versions and load new firmware 924 * if needed and reset. 925 */ 926 if (pmcs_firmware_update(pwp)) { 927 pmcs_prt(pwp, PMCS_PRT_WARN, NULL, NULL, 928 "%s: Firmware update failed", __func__); 929 goto failure; 930 } 931 932 /* 933 * Create completion threads. 934 */ 935 for (i = 0; i < pwp->cq_info.cq_threads; i++) { 936 pwp->cq_info.cq_thr_info[i].cq_pwp = pwp; 937 pwp->cq_info.cq_thr_info[i].cq_thread = 938 thread_create(NULL, 0, pmcs_scsa_cq_run, 939 &pwp->cq_info.cq_thr_info[i], 0, &p0, TS_RUN, minclsyspri); 940 } 941 942 /* 943 * Create one thread to deal with the updating of the interrupt 944 * coalescing timer. 945 */ 946 pwp->ict_thread = thread_create(NULL, 0, pmcs_check_intr_coal, 947 pwp, 0, &p0, TS_RUN, minclsyspri); 948 949 /* 950 * Kick off the watchdog 951 */ 952 pwp->wdhandle = timeout(pmcs_watchdog, pwp, 953 drv_usectohz(PMCS_WATCH_INTERVAL)); 954 /* 955 * Do the SCSI attachment code (before starting phys) 956 */ 957 if (pmcs_scsa_init(pwp, &pmcs_dattr)) { 958 goto failure; 959 } 960 pwp->hba_attached = 1; 961 962 /* 963 * Initialize the rwlock for the iport elements. 964 */ 965 rw_init(&pwp->iports_lock, NULL, RW_DRIVER, NULL); 966 967 /* Check all acc & dma handles allocated in attach */ 968 if (pmcs_check_acc_dma_handle(pwp)) { 969 ddi_fm_service_impact(pwp->dip, DDI_SERVICE_LOST); 970 goto failure; 971 } 972 973 /* 974 * Create the phymap for this HBA instance 975 */ 976 if (sas_phymap_create(dip, phymap_usec, PHYMAP_MODE_SIMPLE, NULL, 977 pwp, pmcs_phymap_activate, pmcs_phymap_deactivate, 978 &pwp->hss_phymap) != DDI_SUCCESS) { 979 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 980 "%s: pmcs%d phymap_create failed", __func__, inst); 981 goto failure; 982 } 983 ASSERT(pwp->hss_phymap); 984 985 /* 986 * Create the iportmap for this HBA instance 987 */ 988 if (scsi_hba_iportmap_create(dip, iportmap_usec, 989 &pwp->hss_iportmap) != DDI_SUCCESS) { 990 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 991 "%s: pmcs%d iportmap_create failed", __func__, inst); 992 goto failure; 993 } 994 ASSERT(pwp->hss_iportmap); 995 996 /* 997 * Start the PHYs. 998 */ 999 if (pmcs_start_phys(pwp)) { 1000 goto failure; 1001 } 1002 1003 /* 1004 * From this point on, we can't fail. 1005 */ 1006 ddi_report_dev(dip); 1007 1008 /* SM-HBA */ 1009 pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_INT32, PMCS_SMHBA_SUPPORTED, 1010 &sm_hba); 1011 1012 /* SM-HBA */ 1013 pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_STRING, PMCS_DRV_VERSION, 1014 pmcs_driver_rev); 1015 1016 /* SM-HBA */ 1017 chiprev = 'A' + pwp->chiprev; 1018 (void) snprintf(hw_rev, 2, "%s", &chiprev); 1019 pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_STRING, PMCS_HWARE_VERSION, 1020 hw_rev); 1021 1022 /* SM-HBA */ 1023 switch (PMCS_FW_TYPE(pwp)) { 1024 case PMCS_FW_TYPE_RELEASED: 1025 fwsupport = "Released"; 1026 break; 1027 case PMCS_FW_TYPE_DEVELOPMENT: 1028 fwsupport = "Development"; 1029 break; 1030 case PMCS_FW_TYPE_ALPHA: 1031 fwsupport = "Alpha"; 1032 break; 1033 case PMCS_FW_TYPE_BETA: 1034 fwsupport = "Beta"; 1035 break; 1036 default: 1037 fwsupport = "Special"; 1038 break; 1039 } 1040 (void) snprintf(fw_rev, sizeof (fw_rev), "%x.%x.%x %s", 1041 PMCS_FW_MAJOR(pwp), PMCS_FW_MINOR(pwp), PMCS_FW_MICRO(pwp), 1042 fwsupport); 1043 pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_STRING, PMCS_FWARE_VERSION, 1044 fw_rev); 1045 1046 /* SM-HBA */ 1047 num_phys = pwp->nphy; 1048 pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_INT32, PMCS_NUM_PHYS_HBA, 1049 &num_phys); 1050 1051 /* SM-HBA */ 1052 protocol = SAS_SSP_SUPPORT | SAS_SATA_SUPPORT | SAS_SMP_SUPPORT; 1053 pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_INT32, PMCS_SUPPORTED_PROTOCOL, 1054 &protocol); 1055 1056 return (DDI_SUCCESS); 1057 1058 failure: 1059 if (pmcs_unattach(pwp)) { 1060 pwp->stuck = 1; 1061 } 1062 return (DDI_FAILURE); 1063 } 1064 1065 int 1066 pmcs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1067 { 1068 int inst = ddi_get_instance(dip); 1069 pmcs_iport_t *iport = NULL; 1070 pmcs_hw_t *pwp = NULL; 1071 scsi_hba_tran_t *tran; 1072 1073 if (scsi_hba_iport_unit_address(dip) != NULL) { 1074 /* iport node */ 1075 iport = ddi_get_soft_state(pmcs_iport_softstate, inst); 1076 ASSERT(iport); 1077 if (iport == NULL) { 1078 return (DDI_FAILURE); 1079 } 1080 pwp = iport->pwp; 1081 } else { 1082 /* hba node */ 1083 pwp = (pmcs_hw_t *)ddi_get_soft_state(pmcs_softc_state, inst); 1084 ASSERT(pwp); 1085 if (pwp == NULL) { 1086 return (DDI_FAILURE); 1087 } 1088 } 1089 1090 switch (cmd) { 1091 case DDI_DETACH: 1092 if (iport) { 1093 /* iport detach */ 1094 if (pmcs_iport_unattach(iport)) { 1095 return (DDI_FAILURE); 1096 } 1097 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1098 "iport%d detached", inst); 1099 return (DDI_SUCCESS); 1100 } else { 1101 /* HBA detach */ 1102 if (pmcs_unattach(pwp)) { 1103 return (DDI_FAILURE); 1104 } 1105 return (DDI_SUCCESS); 1106 } 1107 1108 case DDI_SUSPEND: 1109 case DDI_PM_SUSPEND: 1110 /* No DDI_SUSPEND on iport nodes */ 1111 if (iport) { 1112 return (DDI_SUCCESS); 1113 } 1114 1115 if (pwp->stuck) { 1116 return (DDI_FAILURE); 1117 } 1118 tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip); 1119 if (!tran) { 1120 return (DDI_FAILURE); 1121 } 1122 1123 pwp = TRAN2PMC(tran); 1124 if (pwp == NULL) { 1125 return (DDI_FAILURE); 1126 } 1127 mutex_enter(&pwp->lock); 1128 if (pwp->tq) { 1129 ddi_taskq_suspend(pwp->tq); 1130 } 1131 pwp->suspended = 1; 1132 mutex_exit(&pwp->lock); 1133 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "PMC8X6G suspending"); 1134 return (DDI_SUCCESS); 1135 1136 default: 1137 return (DDI_FAILURE); 1138 } 1139 } 1140 1141 static int 1142 pmcs_iport_unattach(pmcs_iport_t *iport) 1143 { 1144 pmcs_hw_t *pwp = iport->pwp; 1145 1146 /* 1147 * First, check if there are still any configured targets on this 1148 * iport. If so, we fail detach. 1149 */ 1150 if (pmcs_iport_has_targets(pwp, iport)) { 1151 pmcs_prt(pwp, PMCS_PRT_DEBUG_IPORT, NULL, NULL, 1152 "iport%d detach failure: iport has targets (luns)", 1153 ddi_get_instance(iport->dip)); 1154 return (DDI_FAILURE); 1155 } 1156 1157 /* 1158 * Remove this iport from our list if it is inactive in the phymap. 1159 */ 1160 rw_enter(&pwp->iports_lock, RW_WRITER); 1161 mutex_enter(&iport->lock); 1162 1163 if (iport->ua_state == UA_ACTIVE) { 1164 mutex_exit(&iport->lock); 1165 rw_exit(&pwp->iports_lock); 1166 pmcs_prt(pwp, PMCS_PRT_DEBUG_IPORT, NULL, NULL, 1167 "iport%d detach failure: " 1168 "iport unit address active in phymap", 1169 ddi_get_instance(iport->dip)); 1170 return (DDI_FAILURE); 1171 } 1172 1173 /* If it's our only iport, clear iports_attached */ 1174 ASSERT(pwp->num_iports >= 1); 1175 if (--pwp->num_iports == 0) { 1176 pwp->iports_attached = 0; 1177 } 1178 1179 ASSERT(list_link_active(&iport->list_node)); 1180 list_remove(&pwp->iports, iport); 1181 rw_exit(&pwp->iports_lock); 1182 1183 /* 1184 * We have removed the iport handle from the HBA's iports list, 1185 * there will be no new references to it. Two things must be 1186 * guarded against here. First, we could have PHY up events, 1187 * adding themselves to the iport->phys list and grabbing ref's 1188 * on our iport handle. Second, we could have existing references 1189 * to this iport handle from a point in time prior to the list 1190 * removal above. 1191 * 1192 * So first, destroy the phys list. Remove any phys that have snuck 1193 * in after the phymap deactivate, dropping the refcnt accordingly. 1194 * If these PHYs are still up if and when the phymap reactivates 1195 * (i.e. when this iport reattaches), we'll populate the list with 1196 * them and bump the refcnt back up. 1197 */ 1198 pmcs_remove_phy_from_iport(iport, NULL); 1199 ASSERT(list_is_empty(&iport->phys)); 1200 list_destroy(&iport->phys); 1201 mutex_exit(&iport->lock); 1202 1203 /* 1204 * Second, wait for any other references to this iport to be 1205 * dropped, then continue teardown. 1206 */ 1207 mutex_enter(&iport->refcnt_lock); 1208 while (iport->refcnt != 0) { 1209 cv_wait(&iport->refcnt_cv, &iport->refcnt_lock); 1210 } 1211 mutex_exit(&iport->refcnt_lock); 1212 1213 /* Delete kstats */ 1214 pmcs_destroy_phy_stats(iport); 1215 1216 /* Destroy the iport target map */ 1217 if (pmcs_iport_tgtmap_destroy(iport) == B_FALSE) { 1218 return (DDI_FAILURE); 1219 } 1220 1221 /* Free the tgt soft state */ 1222 if (iport->tgt_sstate != NULL) { 1223 ddi_soft_state_bystr_fini(&iport->tgt_sstate); 1224 } 1225 1226 /* Free our unit address string */ 1227 strfree(iport->ua); 1228 1229 /* Finish teardown and free the softstate */ 1230 mutex_destroy(&iport->refcnt_lock); 1231 ASSERT(iport->refcnt == 0); 1232 cv_destroy(&iport->refcnt_cv); 1233 mutex_destroy(&iport->lock); 1234 ddi_soft_state_free(pmcs_iport_softstate, ddi_get_instance(iport->dip)); 1235 1236 return (DDI_SUCCESS); 1237 } 1238 1239 static int 1240 pmcs_unattach(pmcs_hw_t *pwp) 1241 { 1242 int i; 1243 enum pwpstate curstate; 1244 pmcs_cq_thr_info_t *cqti; 1245 1246 /* 1247 * Tear down the interrupt infrastructure. 1248 */ 1249 if (pmcs_teardown_intr(pwp)) { 1250 pwp->stuck = 1; 1251 } 1252 pwp->intr_cnt = 0; 1253 1254 /* 1255 * Grab a lock, if initted, to set state. 1256 */ 1257 if (pwp->locks_initted) { 1258 mutex_enter(&pwp->lock); 1259 if (pwp->state != STATE_DEAD) { 1260 pwp->state = STATE_UNPROBING; 1261 } 1262 curstate = pwp->state; 1263 mutex_exit(&pwp->lock); 1264 1265 /* 1266 * Stop the I/O completion threads. 1267 */ 1268 mutex_enter(&pwp->cq_lock); 1269 pwp->cq_info.cq_stop = B_TRUE; 1270 for (i = 0; i < pwp->cq_info.cq_threads; i++) { 1271 if (pwp->cq_info.cq_thr_info[i].cq_thread) { 1272 cqti = &pwp->cq_info.cq_thr_info[i]; 1273 mutex_enter(&cqti->cq_thr_lock); 1274 cv_signal(&cqti->cq_cv); 1275 mutex_exit(&cqti->cq_thr_lock); 1276 mutex_exit(&pwp->cq_lock); 1277 thread_join(cqti->cq_thread->t_did); 1278 mutex_enter(&pwp->cq_lock); 1279 } 1280 } 1281 mutex_exit(&pwp->cq_lock); 1282 1283 /* 1284 * Stop the interrupt coalescing timer thread 1285 */ 1286 if (pwp->ict_thread) { 1287 mutex_enter(&pwp->ict_lock); 1288 pwp->io_intr_coal.stop_thread = B_TRUE; 1289 cv_signal(&pwp->ict_cv); 1290 mutex_exit(&pwp->ict_lock); 1291 thread_join(pwp->ict_thread->t_did); 1292 } 1293 } else { 1294 if (pwp->state != STATE_DEAD) { 1295 pwp->state = STATE_UNPROBING; 1296 } 1297 curstate = pwp->state; 1298 } 1299 1300 if (&pwp->iports != NULL) { 1301 /* Destroy the iports lock */ 1302 rw_destroy(&pwp->iports_lock); 1303 /* Destroy the iports list */ 1304 ASSERT(list_is_empty(&pwp->iports)); 1305 list_destroy(&pwp->iports); 1306 } 1307 1308 if (pwp->hss_iportmap != NULL) { 1309 /* Destroy the iportmap */ 1310 scsi_hba_iportmap_destroy(pwp->hss_iportmap); 1311 } 1312 1313 if (pwp->hss_phymap != NULL) { 1314 /* Destroy the phymap */ 1315 sas_phymap_destroy(pwp->hss_phymap); 1316 } 1317 1318 /* 1319 * Make sure that any pending watchdog won't 1320 * be called from this point on out. 1321 */ 1322 (void) untimeout(pwp->wdhandle); 1323 /* 1324 * After the above action, the watchdog 1325 * timer that starts up the worker task 1326 * may trigger but will exit immediately 1327 * on triggering. 1328 * 1329 * Now that this is done, we can destroy 1330 * the task queue, which will wait if we're 1331 * running something on it. 1332 */ 1333 if (pwp->tq) { 1334 ddi_taskq_destroy(pwp->tq); 1335 pwp->tq = NULL; 1336 } 1337 1338 pmcs_fm_fini(pwp); 1339 1340 if (pwp->hba_attached) { 1341 (void) scsi_hba_detach(pwp->dip); 1342 pwp->hba_attached = 0; 1343 } 1344 1345 /* 1346 * If the chip hasn't been marked dead, shut it down now 1347 * to bring it back to a known state without attempting 1348 * a soft reset. 1349 */ 1350 if (curstate != STATE_DEAD && pwp->locks_initted) { 1351 /* 1352 * De-register all registered devices 1353 */ 1354 pmcs_deregister_devices(pwp, pwp->root_phys); 1355 1356 /* 1357 * Stop all the phys. 1358 */ 1359 pmcs_stop_phys(pwp); 1360 1361 /* 1362 * Shut Down Message Passing 1363 */ 1364 (void) pmcs_stop_mpi(pwp); 1365 1366 /* 1367 * Reset chip 1368 */ 1369 (void) pmcs_soft_reset(pwp, B_FALSE); 1370 } 1371 1372 /* 1373 * Turn off interrupts on the chip 1374 */ 1375 if (pwp->mpi_acc_handle) { 1376 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_MASK, 0xffffffff); 1377 } 1378 1379 /* Destroy pwp's lock */ 1380 if (pwp->locks_initted) { 1381 mutex_destroy(&pwp->lock); 1382 mutex_destroy(&pwp->dma_lock); 1383 mutex_destroy(&pwp->axil_lock); 1384 mutex_destroy(&pwp->cq_lock); 1385 mutex_destroy(&pwp->config_lock); 1386 mutex_destroy(&pwp->ict_lock); 1387 mutex_destroy(&pwp->wfree_lock); 1388 mutex_destroy(&pwp->pfree_lock); 1389 mutex_destroy(&pwp->dead_phylist_lock); 1390 #ifdef DEBUG 1391 mutex_destroy(&pwp->dbglock); 1392 #endif 1393 cv_destroy(&pwp->ict_cv); 1394 cv_destroy(&pwp->drain_cv); 1395 pwp->locks_initted = 0; 1396 } 1397 1398 /* 1399 * Free DMA handles and associated consistent memory 1400 */ 1401 if (pwp->regdump_hndl) { 1402 if (ddi_dma_unbind_handle(pwp->regdump_hndl) != DDI_SUCCESS) { 1403 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1404 "Condition check failed " 1405 "at %s():%d", __func__, __LINE__); 1406 } 1407 ddi_dma_free_handle(&pwp->regdump_hndl); 1408 ddi_dma_mem_free(&pwp->regdump_acchdl); 1409 pwp->regdump_hndl = 0; 1410 } 1411 if (pwp->fwlog_hndl) { 1412 if (ddi_dma_unbind_handle(pwp->fwlog_hndl) != DDI_SUCCESS) { 1413 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1414 "Condition check failed " 1415 "at %s():%d", __func__, __LINE__); 1416 } 1417 ddi_dma_free_handle(&pwp->fwlog_hndl); 1418 ddi_dma_mem_free(&pwp->fwlog_acchdl); 1419 pwp->fwlog_hndl = 0; 1420 } 1421 if (pwp->cip_handles) { 1422 if (ddi_dma_unbind_handle(pwp->cip_handles) != DDI_SUCCESS) { 1423 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1424 "Condition check failed " 1425 "at %s():%d", __func__, __LINE__); 1426 } 1427 ddi_dma_free_handle(&pwp->cip_handles); 1428 ddi_dma_mem_free(&pwp->cip_acchdls); 1429 pwp->cip_handles = 0; 1430 } 1431 for (i = 0; i < PMCS_NOQ; i++) { 1432 if (pwp->oqp_handles[i]) { 1433 if (ddi_dma_unbind_handle(pwp->oqp_handles[i]) != 1434 DDI_SUCCESS) { 1435 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1436 "Condition check failed at %s():%d", 1437 __func__, __LINE__); 1438 } 1439 ddi_dma_free_handle(&pwp->oqp_handles[i]); 1440 ddi_dma_mem_free(&pwp->oqp_acchdls[i]); 1441 pwp->oqp_handles[i] = 0; 1442 } 1443 } 1444 for (i = 0; i < PMCS_NIQ; i++) { 1445 if (pwp->iqp_handles[i]) { 1446 if (ddi_dma_unbind_handle(pwp->iqp_handles[i]) != 1447 DDI_SUCCESS) { 1448 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1449 "Condition check failed at %s():%d", 1450 __func__, __LINE__); 1451 } 1452 ddi_dma_free_handle(&pwp->iqp_handles[i]); 1453 ddi_dma_mem_free(&pwp->iqp_acchdls[i]); 1454 pwp->iqp_handles[i] = 0; 1455 } 1456 } 1457 1458 pmcs_free_dma_chunklist(pwp); 1459 1460 /* 1461 * Unmap registers and destroy access handles 1462 */ 1463 if (pwp->mpi_acc_handle) { 1464 ddi_regs_map_free(&pwp->mpi_acc_handle); 1465 pwp->mpi_acc_handle = 0; 1466 } 1467 if (pwp->top_acc_handle) { 1468 ddi_regs_map_free(&pwp->top_acc_handle); 1469 pwp->top_acc_handle = 0; 1470 } 1471 if (pwp->gsm_acc_handle) { 1472 ddi_regs_map_free(&pwp->gsm_acc_handle); 1473 pwp->gsm_acc_handle = 0; 1474 } 1475 if (pwp->msg_acc_handle) { 1476 ddi_regs_map_free(&pwp->msg_acc_handle); 1477 pwp->msg_acc_handle = 0; 1478 } 1479 if (pwp->pci_acc_handle) { 1480 pci_config_teardown(&pwp->pci_acc_handle); 1481 pwp->pci_acc_handle = 0; 1482 } 1483 1484 /* 1485 * Do memory allocation cleanup. 1486 */ 1487 while (pwp->dma_freelist) { 1488 pmcs_dmachunk_t *this = pwp->dma_freelist; 1489 pwp->dma_freelist = this->nxt; 1490 kmem_free(this, sizeof (pmcs_dmachunk_t)); 1491 } 1492 1493 /* 1494 * Free pools 1495 */ 1496 if (pwp->iocomp_cb_cache) { 1497 kmem_cache_destroy(pwp->iocomp_cb_cache); 1498 } 1499 1500 /* 1501 * Free all PHYs (at level > 0), then free the cache 1502 */ 1503 pmcs_free_all_phys(pwp, pwp->root_phys); 1504 if (pwp->phy_cache) { 1505 kmem_cache_destroy(pwp->phy_cache); 1506 } 1507 1508 /* 1509 * Free root PHYs 1510 */ 1511 if (pwp->root_phys) { 1512 pmcs_phy_t *phyp = pwp->root_phys; 1513 for (i = 0; i < pwp->nphy; i++) { 1514 mutex_destroy(&phyp->phy_lock); 1515 phyp = phyp->sibling; 1516 } 1517 kmem_free(pwp->root_phys, pwp->nphy * sizeof (pmcs_phy_t)); 1518 pwp->root_phys = NULL; 1519 pwp->nphy = 0; 1520 } 1521 1522 /* Free the targets list */ 1523 if (pwp->targets) { 1524 kmem_free(pwp->targets, 1525 sizeof (pmcs_xscsi_t *) * pwp->max_dev); 1526 } 1527 1528 /* 1529 * Free work structures 1530 */ 1531 1532 if (pwp->work && pwp->max_cmd) { 1533 for (i = 0; i < pwp->max_cmd - 1; i++) { 1534 pmcwork_t *pwrk = &pwp->work[i]; 1535 mutex_destroy(&pwrk->lock); 1536 cv_destroy(&pwrk->sleep_cv); 1537 } 1538 kmem_free(pwp->work, sizeof (pmcwork_t) * pwp->max_cmd); 1539 pwp->work = NULL; 1540 pwp->max_cmd = 0; 1541 } 1542 1543 /* 1544 * Do last property and SCSA cleanup 1545 */ 1546 if (pwp->tran) { 1547 scsi_hba_tran_free(pwp->tran); 1548 pwp->tran = NULL; 1549 } 1550 if (pwp->reset_notify_listf) { 1551 scsi_hba_reset_notify_tear_down(pwp->reset_notify_listf); 1552 pwp->reset_notify_listf = NULL; 1553 } 1554 ddi_prop_remove_all(pwp->dip); 1555 if (pwp->stuck) { 1556 return (-1); 1557 } 1558 1559 /* Free register dump area if allocated */ 1560 if (pwp->regdumpp) { 1561 kmem_free(pwp->regdumpp, PMCS_REG_DUMP_SIZE); 1562 pwp->regdumpp = NULL; 1563 } 1564 if (pwp->iqpt && pwp->iqpt->head) { 1565 kmem_free(pwp->iqpt->head, PMCS_IQP_TRACE_BUFFER_SIZE); 1566 pwp->iqpt->head = pwp->iqpt->curpos = NULL; 1567 } 1568 if (pwp->iqpt) { 1569 kmem_free(pwp->iqpt, sizeof (pmcs_iqp_trace_t)); 1570 pwp->iqpt = NULL; 1571 } 1572 1573 ddi_soft_state_free(pmcs_softc_state, ddi_get_instance(pwp->dip)); 1574 return (0); 1575 } 1576 1577 /* 1578 * quiesce (9E) entry point 1579 * 1580 * This function is called when the system is single-threaded at high PIL 1581 * with preemption disabled. Therefore, the function must not block/wait/sleep. 1582 * 1583 * Returns DDI_SUCCESS or DDI_FAILURE. 1584 * 1585 */ 1586 static int 1587 pmcs_quiesce(dev_info_t *dip) 1588 { 1589 pmcs_hw_t *pwp; 1590 scsi_hba_tran_t *tran; 1591 1592 if ((tran = ddi_get_driver_private(dip)) == NULL) 1593 return (DDI_SUCCESS); 1594 1595 /* No quiesce necessary on a per-iport basis */ 1596 if (scsi_hba_iport_unit_address(dip) != NULL) { 1597 return (DDI_SUCCESS); 1598 } 1599 1600 if ((pwp = TRAN2PMC(tran)) == NULL) 1601 return (DDI_SUCCESS); 1602 1603 /* Stop MPI & Reset chip (no need to re-initialize) */ 1604 (void) pmcs_stop_mpi(pwp); 1605 (void) pmcs_soft_reset(pwp, B_TRUE); 1606 1607 return (DDI_SUCCESS); 1608 } 1609 1610 /* 1611 * Called with xp->statlock and PHY lock and scratch acquired. 1612 */ 1613 static int 1614 pmcs_add_sata_device(pmcs_hw_t *pwp, pmcs_xscsi_t *xp) 1615 { 1616 ata_identify_t *ati; 1617 int result, i; 1618 pmcs_phy_t *pptr; 1619 uint16_t *a; 1620 union { 1621 uint8_t nsa[8]; 1622 uint16_t nsb[4]; 1623 } u; 1624 1625 /* 1626 * Safe defaults - use only if this target is brand new (i.e. doesn't 1627 * already have these settings configured) 1628 */ 1629 if (xp->capacity == 0) { 1630 xp->capacity = (uint64_t)-1; 1631 xp->ca = 1; 1632 xp->qdepth = 1; 1633 xp->pio = 1; 1634 } 1635 1636 pptr = xp->phy; 1637 1638 /* 1639 * We only try and issue an IDENTIFY for first level 1640 * (direct attached) devices. We don't try and 1641 * set other quirks here (this will happen later, 1642 * if the device is fully configured) 1643 */ 1644 if (pptr->level) { 1645 return (0); 1646 } 1647 1648 mutex_exit(&xp->statlock); 1649 result = pmcs_sata_identify(pwp, pptr); 1650 mutex_enter(&xp->statlock); 1651 1652 if (result) { 1653 return (result); 1654 } 1655 ati = pwp->scratch; 1656 a = &ati->word108; 1657 for (i = 0; i < 4; i++) { 1658 u.nsb[i] = ddi_swap16(*a++); 1659 } 1660 1661 /* 1662 * Check the returned data for being a valid (NAA=5) WWN. 1663 * If so, use that and override the SAS address we were 1664 * given at Link Up time. 1665 */ 1666 if ((u.nsa[0] >> 4) == 5) { 1667 (void) memcpy(pptr->sas_address, u.nsa, 8); 1668 } 1669 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 1670 "%s: %s has SAS ADDRESS " SAS_ADDR_FMT, 1671 __func__, pptr->path, SAS_ADDR_PRT(pptr->sas_address)); 1672 return (0); 1673 } 1674 1675 /* 1676 * Called with PHY lock and target statlock held and scratch acquired 1677 */ 1678 static boolean_t 1679 pmcs_add_new_device(pmcs_hw_t *pwp, pmcs_xscsi_t *target) 1680 { 1681 ASSERT(target != NULL); 1682 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, target, "%s: target = 0x%p", 1683 __func__, (void *) target); 1684 1685 switch (target->phy->dtype) { 1686 case SATA: 1687 if (pmcs_add_sata_device(pwp, target) != 0) { 1688 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, target->phy, 1689 target, "%s: add_sata_device failed for tgt 0x%p", 1690 __func__, (void *) target); 1691 return (B_FALSE); 1692 } 1693 break; 1694 case SAS: 1695 target->qdepth = maxqdepth; 1696 break; 1697 case EXPANDER: 1698 target->qdepth = 1; 1699 break; 1700 } 1701 1702 target->new = 0; 1703 target->assigned = 1; 1704 target->dev_state = PMCS_DEVICE_STATE_OPERATIONAL; 1705 target->dtype = target->phy->dtype; 1706 1707 /* 1708 * Set the PHY's config stop time to 0. This is one of the final 1709 * stops along the config path, so we're indicating that we 1710 * successfully configured the PHY. 1711 */ 1712 target->phy->config_stop = 0; 1713 1714 return (B_TRUE); 1715 } 1716 1717 void 1718 pmcs_worker(void *arg) 1719 { 1720 pmcs_hw_t *pwp = arg; 1721 ulong_t work_flags; 1722 1723 DTRACE_PROBE2(pmcs__worker, ulong_t, pwp->work_flags, boolean_t, 1724 pwp->config_changed); 1725 1726 if (pwp->state != STATE_RUNNING) { 1727 return; 1728 } 1729 1730 work_flags = atomic_swap_ulong(&pwp->work_flags, 0); 1731 1732 if (work_flags & PMCS_WORK_FLAG_SAS_HW_ACK) { 1733 pmcs_ack_events(pwp); 1734 } 1735 1736 if (work_flags & PMCS_WORK_FLAG_SPINUP_RELEASE) { 1737 mutex_enter(&pwp->lock); 1738 pmcs_spinup_release(pwp, NULL); 1739 mutex_exit(&pwp->lock); 1740 } 1741 1742 if (work_flags & PMCS_WORK_FLAG_SSP_EVT_RECOVERY) { 1743 pmcs_ssp_event_recovery(pwp); 1744 } 1745 1746 if (work_flags & PMCS_WORK_FLAG_DS_ERR_RECOVERY) { 1747 pmcs_dev_state_recovery(pwp, NULL); 1748 } 1749 1750 if (work_flags & PMCS_WORK_FLAG_DISCOVER) { 1751 pmcs_discover(pwp); 1752 } 1753 1754 if (work_flags & PMCS_WORK_FLAG_ABORT_HANDLE) { 1755 if (pmcs_abort_handler(pwp)) { 1756 SCHEDULE_WORK(pwp, PMCS_WORK_ABORT_HANDLE); 1757 } 1758 } 1759 1760 if (work_flags & PMCS_WORK_FLAG_SATA_RUN) { 1761 pmcs_sata_work(pwp); 1762 } 1763 1764 if (work_flags & PMCS_WORK_FLAG_RUN_QUEUES) { 1765 pmcs_scsa_wq_run(pwp); 1766 mutex_enter(&pwp->lock); 1767 PMCS_CQ_RUN(pwp); 1768 mutex_exit(&pwp->lock); 1769 } 1770 1771 if (work_flags & PMCS_WORK_FLAG_ADD_DMA_CHUNKS) { 1772 if (pmcs_add_more_chunks(pwp, 1773 ptob(1) * PMCS_ADDTL_CHUNK_PAGES)) { 1774 SCHEDULE_WORK(pwp, PMCS_WORK_ADD_DMA_CHUNKS); 1775 } else { 1776 SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES); 1777 } 1778 } 1779 } 1780 1781 static int 1782 pmcs_add_more_chunks(pmcs_hw_t *pwp, unsigned long nsize) 1783 { 1784 pmcs_dmachunk_t *dc; 1785 unsigned long dl; 1786 pmcs_chunk_t *pchunk = NULL; 1787 1788 pwp->cip_dma_attr.dma_attr_align = sizeof (uint32_t); 1789 1790 pchunk = kmem_zalloc(sizeof (pmcs_chunk_t), KM_SLEEP); 1791 if (pchunk == NULL) { 1792 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1793 "Not enough memory for DMA chunks"); 1794 return (-1); 1795 } 1796 1797 if (pmcs_dma_setup(pwp, &pwp->cip_dma_attr, &pchunk->acc_handle, 1798 &pchunk->dma_handle, nsize, (caddr_t *)&pchunk->addrp, 1799 &pchunk->dma_addr) == B_FALSE) { 1800 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1801 "Failed to setup DMA for chunks"); 1802 kmem_free(pchunk, sizeof (pmcs_chunk_t)); 1803 return (-1); 1804 } 1805 1806 if ((pmcs_check_acc_handle(pchunk->acc_handle) != DDI_SUCCESS) || 1807 (pmcs_check_dma_handle(pchunk->dma_handle) != DDI_SUCCESS)) { 1808 ddi_fm_service_impact(pwp->dip, DDI_SERVICE_UNAFFECTED); 1809 return (-1); 1810 } 1811 1812 bzero(pchunk->addrp, nsize); 1813 dc = NULL; 1814 for (dl = 0; dl < (nsize / PMCS_SGL_CHUNKSZ); dl++) { 1815 pmcs_dmachunk_t *tmp; 1816 tmp = kmem_alloc(sizeof (pmcs_dmachunk_t), KM_SLEEP); 1817 tmp->nxt = dc; 1818 dc = tmp; 1819 } 1820 mutex_enter(&pwp->dma_lock); 1821 pmcs_idma_chunks(pwp, dc, pchunk, nsize); 1822 pwp->nchunks++; 1823 mutex_exit(&pwp->dma_lock); 1824 return (0); 1825 } 1826 1827 1828 static void 1829 pmcs_check_commands(pmcs_hw_t *pwp) 1830 { 1831 pmcs_cmd_t *sp; 1832 size_t amt; 1833 char path[32]; 1834 pmcwork_t *pwrk; 1835 pmcs_xscsi_t *target; 1836 pmcs_phy_t *phyp; 1837 1838 for (pwrk = pwp->work; pwrk < &pwp->work[pwp->max_cmd]; pwrk++) { 1839 mutex_enter(&pwrk->lock); 1840 1841 /* 1842 * If the command isn't active, we can't be timing it still. 1843 * Active means the tag is not free and the state is "on chip". 1844 */ 1845 if (!PMCS_COMMAND_ACTIVE(pwrk)) { 1846 mutex_exit(&pwrk->lock); 1847 continue; 1848 } 1849 1850 /* 1851 * No timer active for this command. 1852 */ 1853 if (pwrk->timer == 0) { 1854 mutex_exit(&pwrk->lock); 1855 continue; 1856 } 1857 1858 /* 1859 * Knock off bits for the time interval. 1860 */ 1861 if (pwrk->timer >= US2WT(PMCS_WATCH_INTERVAL)) { 1862 pwrk->timer -= US2WT(PMCS_WATCH_INTERVAL); 1863 } else { 1864 pwrk->timer = 0; 1865 } 1866 if (pwrk->timer > 0) { 1867 mutex_exit(&pwrk->lock); 1868 continue; 1869 } 1870 1871 /* 1872 * The command has now officially timed out. 1873 * Get the path for it. If it doesn't have 1874 * a phy pointer any more, it's really dead 1875 * and can just be put back on the free list. 1876 * There should *not* be any commands associated 1877 * with it any more. 1878 */ 1879 if (pwrk->phy == NULL) { 1880 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1881 "dead command with gone phy being recycled"); 1882 ASSERT(pwrk->xp == NULL); 1883 pmcs_pwork(pwp, pwrk); 1884 continue; 1885 } 1886 amt = sizeof (path); 1887 amt = min(sizeof (pwrk->phy->path), amt); 1888 (void) memcpy(path, pwrk->phy->path, amt); 1889 1890 /* 1891 * If this is a non-SCSA command, stop here. Eventually 1892 * we might do something with non-SCSA commands here- 1893 * but so far their timeout mechanisms are handled in 1894 * the WAIT_FOR macro. 1895 */ 1896 if (pwrk->xp == NULL) { 1897 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1898 "%s: non-SCSA cmd tag 0x%x timed out", 1899 path, pwrk->htag); 1900 mutex_exit(&pwrk->lock); 1901 continue; 1902 } 1903 1904 sp = pwrk->arg; 1905 ASSERT(sp != NULL); 1906 1907 /* 1908 * Mark it as timed out. 1909 */ 1910 CMD2PKT(sp)->pkt_reason = CMD_TIMEOUT; 1911 CMD2PKT(sp)->pkt_statistics |= STAT_TIMEOUT; 1912 #ifdef DEBUG 1913 pmcs_prt(pwp, PMCS_PRT_DEBUG, pwrk->phy, pwrk->xp, 1914 "%s: SCSA cmd tag 0x%x timed out (state %x) onwire=%d", 1915 path, pwrk->htag, pwrk->state, pwrk->onwire); 1916 #else 1917 pmcs_prt(pwp, PMCS_PRT_DEBUG, pwrk->phy, pwrk->xp, 1918 "%s: SCSA cmd tag 0x%x timed out (state %x)", 1919 path, pwrk->htag, pwrk->state); 1920 #endif 1921 /* 1922 * Mark the work structure as timed out. 1923 */ 1924 pwrk->state = PMCS_WORK_STATE_TIMED_OUT; 1925 phyp = pwrk->phy; 1926 target = pwrk->xp; 1927 mutex_exit(&pwrk->lock); 1928 1929 pmcs_lock_phy(phyp); 1930 mutex_enter(&target->statlock); 1931 1932 /* 1933 * No point attempting recovery if the device is gone 1934 */ 1935 if (target->dev_gone) { 1936 mutex_exit(&target->statlock); 1937 pmcs_unlock_phy(phyp); 1938 pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, target, 1939 "%s: tgt(0x%p) is gone. Returning CMD_DEV_GONE " 1940 "for htag 0x%08x", __func__, 1941 (void *)target, pwrk->htag); 1942 mutex_enter(&pwrk->lock); 1943 if (!PMCS_COMMAND_DONE(pwrk)) { 1944 /* Complete this command here */ 1945 pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, target, 1946 "%s: Completing cmd (htag 0x%08x) " 1947 "anyway", __func__, pwrk->htag); 1948 pwrk->dead = 1; 1949 CMD2PKT(sp)->pkt_reason = CMD_DEV_GONE; 1950 CMD2PKT(sp)->pkt_state = STATE_GOT_BUS; 1951 pmcs_complete_work_impl(pwp, pwrk, NULL, 0); 1952 } else { 1953 mutex_exit(&pwrk->lock); 1954 } 1955 continue; 1956 } 1957 1958 /* 1959 * See if we're already waiting for device state recovery 1960 */ 1961 if (target->recover_wait) { 1962 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, phyp, target, 1963 "%s: Target %p already in recovery", __func__, 1964 (void *)target); 1965 mutex_exit(&target->statlock); 1966 pmcs_unlock_phy(phyp); 1967 continue; 1968 } 1969 1970 pmcs_start_dev_state_recovery(target, phyp); 1971 mutex_exit(&target->statlock); 1972 pmcs_unlock_phy(phyp); 1973 } 1974 /* 1975 * Run any completions that may have been queued up. 1976 */ 1977 PMCS_CQ_RUN(pwp); 1978 } 1979 1980 static void 1981 pmcs_watchdog(void *arg) 1982 { 1983 pmcs_hw_t *pwp = arg; 1984 1985 DTRACE_PROBE2(pmcs__watchdog, ulong_t, pwp->work_flags, boolean_t, 1986 pwp->config_changed); 1987 1988 mutex_enter(&pwp->lock); 1989 1990 if (pwp->state != STATE_RUNNING) { 1991 mutex_exit(&pwp->lock); 1992 return; 1993 } 1994 1995 if (atomic_cas_ulong(&pwp->work_flags, 0, 0) != 0) { 1996 if (ddi_taskq_dispatch(pwp->tq, pmcs_worker, pwp, 1997 DDI_NOSLEEP) != DDI_SUCCESS) { 1998 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1999 "Could not dispatch to worker thread"); 2000 } 2001 } 2002 pwp->wdhandle = timeout(pmcs_watchdog, pwp, 2003 drv_usectohz(PMCS_WATCH_INTERVAL)); 2004 mutex_exit(&pwp->lock); 2005 pmcs_check_commands(pwp); 2006 pmcs_handle_dead_phys(pwp); 2007 } 2008 2009 static int 2010 pmcs_remove_ihandlers(pmcs_hw_t *pwp, int icnt) 2011 { 2012 int i, r, rslt = 0; 2013 for (i = 0; i < icnt; i++) { 2014 r = ddi_intr_remove_handler(pwp->ih_table[i]); 2015 if (r == DDI_SUCCESS) { 2016 continue; 2017 } 2018 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2019 "%s: unable to remove interrupt handler %d", __func__, i); 2020 rslt = -1; 2021 break; 2022 } 2023 return (rslt); 2024 } 2025 2026 static int 2027 pmcs_disable_intrs(pmcs_hw_t *pwp, int icnt) 2028 { 2029 if (pwp->intr_cap & DDI_INTR_FLAG_BLOCK) { 2030 int r = ddi_intr_block_disable(&pwp->ih_table[0], 2031 pwp->intr_cnt); 2032 if (r != DDI_SUCCESS) { 2033 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2034 "unable to disable interrupt block"); 2035 return (-1); 2036 } 2037 } else { 2038 int i; 2039 for (i = 0; i < icnt; i++) { 2040 if (ddi_intr_disable(pwp->ih_table[i]) == DDI_SUCCESS) { 2041 continue; 2042 } 2043 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2044 "unable to disable interrupt %d", i); 2045 return (-1); 2046 } 2047 } 2048 return (0); 2049 } 2050 2051 static int 2052 pmcs_free_intrs(pmcs_hw_t *pwp, int icnt) 2053 { 2054 int i; 2055 for (i = 0; i < icnt; i++) { 2056 if (ddi_intr_free(pwp->ih_table[i]) == DDI_SUCCESS) { 2057 continue; 2058 } 2059 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2060 "unable to free interrupt %d", i); 2061 return (-1); 2062 } 2063 kmem_free(pwp->ih_table, pwp->ih_table_size); 2064 pwp->ih_table_size = 0; 2065 return (0); 2066 } 2067 2068 /* 2069 * Try to set up interrupts of type "type" with a minimum number of interrupts 2070 * of "min". 2071 */ 2072 static void 2073 pmcs_setup_intr_impl(pmcs_hw_t *pwp, int type, int min) 2074 { 2075 int rval, avail, count, actual, max; 2076 2077 rval = ddi_intr_get_nintrs(pwp->dip, type, &count); 2078 if ((rval != DDI_SUCCESS) || (count < min)) { 2079 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2080 "%s: get_nintrs failed; type: %d rc: %d count: %d min: %d", 2081 __func__, type, rval, count, min); 2082 return; 2083 } 2084 2085 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2086 "%s: nintrs = %d for type: %d", __func__, count, type); 2087 2088 rval = ddi_intr_get_navail(pwp->dip, type, &avail); 2089 if ((rval != DDI_SUCCESS) || (avail < min)) { 2090 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2091 "%s: get_navail failed; type: %d rc: %d avail: %d min: %d", 2092 __func__, type, rval, avail, min); 2093 return; 2094 } 2095 2096 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2097 "%s: navail = %d for type: %d", __func__, avail, type); 2098 2099 pwp->ih_table_size = avail * sizeof (ddi_intr_handle_t); 2100 pwp->ih_table = kmem_alloc(pwp->ih_table_size, KM_SLEEP); 2101 2102 switch (type) { 2103 case DDI_INTR_TYPE_MSIX: 2104 pwp->int_type = PMCS_INT_MSIX; 2105 max = PMCS_MAX_MSIX; 2106 break; 2107 case DDI_INTR_TYPE_MSI: 2108 pwp->int_type = PMCS_INT_MSI; 2109 max = PMCS_MAX_MSI; 2110 break; 2111 case DDI_INTR_TYPE_FIXED: 2112 default: 2113 pwp->int_type = PMCS_INT_FIXED; 2114 max = PMCS_MAX_FIXED; 2115 break; 2116 } 2117 2118 rval = ddi_intr_alloc(pwp->dip, pwp->ih_table, type, 0, max, &actual, 2119 DDI_INTR_ALLOC_NORMAL); 2120 if (rval != DDI_SUCCESS) { 2121 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2122 "%s: ddi_intr_alloc failed; type: %d rc: %d", 2123 __func__, type, rval); 2124 kmem_free(pwp->ih_table, pwp->ih_table_size); 2125 pwp->ih_table = NULL; 2126 pwp->ih_table_size = 0; 2127 pwp->intr_cnt = 0; 2128 pwp->int_type = PMCS_INT_NONE; 2129 return; 2130 } 2131 2132 pwp->intr_cnt = actual; 2133 } 2134 2135 /* 2136 * Set up interrupts. 2137 * We return one of three values: 2138 * 2139 * 0 - success 2140 * EAGAIN - failure to set up interrupts 2141 * EIO - "" + we're now stuck partly enabled 2142 * 2143 * If EIO is returned, we can't unload the driver. 2144 */ 2145 static int 2146 pmcs_setup_intr(pmcs_hw_t *pwp) 2147 { 2148 int i, r, itypes, oqv_count; 2149 ddi_intr_handler_t **iv_table; 2150 size_t iv_table_size; 2151 uint_t pri; 2152 2153 if (ddi_intr_get_supported_types(pwp->dip, &itypes) != DDI_SUCCESS) { 2154 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2155 "cannot get interrupt types"); 2156 return (EAGAIN); 2157 } 2158 2159 if (disable_msix) { 2160 itypes &= ~DDI_INTR_TYPE_MSIX; 2161 } 2162 if (disable_msi) { 2163 itypes &= ~DDI_INTR_TYPE_MSI; 2164 } 2165 2166 /* 2167 * We won't know what firmware we're running until we call pmcs_setup, 2168 * and we can't call pmcs_setup until we establish interrupts. 2169 */ 2170 2171 pwp->int_type = PMCS_INT_NONE; 2172 2173 /* 2174 * We want PMCS_MAX_MSIX vectors for MSI-X. Anything less would be 2175 * uncivilized. 2176 */ 2177 if (itypes & DDI_INTR_TYPE_MSIX) { 2178 pmcs_setup_intr_impl(pwp, DDI_INTR_TYPE_MSIX, PMCS_MAX_MSIX); 2179 if (pwp->int_type == PMCS_INT_MSIX) { 2180 itypes = 0; 2181 } 2182 } 2183 2184 if (itypes & DDI_INTR_TYPE_MSI) { 2185 pmcs_setup_intr_impl(pwp, DDI_INTR_TYPE_MSI, 1); 2186 if (pwp->int_type == PMCS_INT_MSI) { 2187 itypes = 0; 2188 } 2189 } 2190 2191 if (itypes & DDI_INTR_TYPE_FIXED) { 2192 pmcs_setup_intr_impl(pwp, DDI_INTR_TYPE_FIXED, 1); 2193 if (pwp->int_type == PMCS_INT_FIXED) { 2194 itypes = 0; 2195 } 2196 } 2197 2198 if (pwp->intr_cnt == 0) { 2199 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, 2200 "No interrupts available"); 2201 return (EAGAIN); 2202 } 2203 2204 iv_table_size = sizeof (ddi_intr_handler_t *) * pwp->intr_cnt; 2205 iv_table = kmem_alloc(iv_table_size, KM_SLEEP); 2206 2207 /* 2208 * Get iblock cookie and add handlers. 2209 */ 2210 switch (pwp->intr_cnt) { 2211 case 1: 2212 iv_table[0] = pmcs_all_intr; 2213 break; 2214 case 2: 2215 iv_table[0] = pmcs_iodone_ix; 2216 iv_table[1] = pmcs_nonio_ix; 2217 break; 2218 case 4: 2219 iv_table[PMCS_MSIX_GENERAL] = pmcs_general_ix; 2220 iv_table[PMCS_MSIX_IODONE] = pmcs_iodone_ix; 2221 iv_table[PMCS_MSIX_EVENTS] = pmcs_event_ix; 2222 iv_table[PMCS_MSIX_FATAL] = pmcs_fatal_ix; 2223 break; 2224 default: 2225 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2226 "%s: intr_cnt = %d - unexpected", __func__, pwp->intr_cnt); 2227 kmem_free(iv_table, iv_table_size); 2228 return (EAGAIN); 2229 } 2230 2231 for (i = 0; i < pwp->intr_cnt; i++) { 2232 r = ddi_intr_add_handler(pwp->ih_table[i], iv_table[i], 2233 (caddr_t)pwp, NULL); 2234 if (r != DDI_SUCCESS) { 2235 kmem_free(iv_table, iv_table_size); 2236 if (pmcs_remove_ihandlers(pwp, i)) { 2237 return (EIO); 2238 } 2239 if (pmcs_free_intrs(pwp, i)) { 2240 return (EIO); 2241 } 2242 pwp->intr_cnt = 0; 2243 return (EAGAIN); 2244 } 2245 } 2246 2247 kmem_free(iv_table, iv_table_size); 2248 2249 if (ddi_intr_get_cap(pwp->ih_table[0], &pwp->intr_cap) != DDI_SUCCESS) { 2250 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2251 "unable to get int capabilities"); 2252 if (pmcs_remove_ihandlers(pwp, pwp->intr_cnt)) { 2253 return (EIO); 2254 } 2255 if (pmcs_free_intrs(pwp, pwp->intr_cnt)) { 2256 return (EIO); 2257 } 2258 pwp->intr_cnt = 0; 2259 return (EAGAIN); 2260 } 2261 2262 if (pwp->intr_cap & DDI_INTR_FLAG_BLOCK) { 2263 r = ddi_intr_block_enable(&pwp->ih_table[0], pwp->intr_cnt); 2264 if (r != DDI_SUCCESS) { 2265 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2266 "intr blk enable failed"); 2267 if (pmcs_remove_ihandlers(pwp, pwp->intr_cnt)) { 2268 return (EIO); 2269 } 2270 if (pmcs_free_intrs(pwp, pwp->intr_cnt)) { 2271 return (EIO); 2272 } 2273 pwp->intr_cnt = 0; 2274 return (EFAULT); 2275 } 2276 } else { 2277 for (i = 0; i < pwp->intr_cnt; i++) { 2278 r = ddi_intr_enable(pwp->ih_table[i]); 2279 if (r == DDI_SUCCESS) { 2280 continue; 2281 } 2282 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2283 "unable to enable interrupt %d", i); 2284 if (pmcs_disable_intrs(pwp, i)) { 2285 return (EIO); 2286 } 2287 if (pmcs_remove_ihandlers(pwp, pwp->intr_cnt)) { 2288 return (EIO); 2289 } 2290 if (pmcs_free_intrs(pwp, pwp->intr_cnt)) { 2291 return (EIO); 2292 } 2293 pwp->intr_cnt = 0; 2294 return (EAGAIN); 2295 } 2296 } 2297 2298 /* 2299 * Set up locks. 2300 */ 2301 if (ddi_intr_get_pri(pwp->ih_table[0], &pri) != DDI_SUCCESS) { 2302 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2303 "unable to get interrupt priority"); 2304 if (pmcs_disable_intrs(pwp, pwp->intr_cnt)) { 2305 return (EIO); 2306 } 2307 if (pmcs_remove_ihandlers(pwp, pwp->intr_cnt)) { 2308 return (EIO); 2309 } 2310 if (pmcs_free_intrs(pwp, pwp->intr_cnt)) { 2311 return (EIO); 2312 } 2313 pwp->intr_cnt = 0; 2314 return (EAGAIN); 2315 } 2316 2317 pwp->locks_initted = 1; 2318 pwp->intr_pri = pri; 2319 mutex_init(&pwp->lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); 2320 mutex_init(&pwp->dma_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); 2321 mutex_init(&pwp->axil_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); 2322 mutex_init(&pwp->cq_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); 2323 mutex_init(&pwp->ict_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); 2324 mutex_init(&pwp->config_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); 2325 mutex_init(&pwp->wfree_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); 2326 mutex_init(&pwp->pfree_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); 2327 mutex_init(&pwp->dead_phylist_lock, NULL, MUTEX_DRIVER, 2328 DDI_INTR_PRI(pri)); 2329 #ifdef DEBUG 2330 mutex_init(&pwp->dbglock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri)); 2331 #endif 2332 cv_init(&pwp->ict_cv, NULL, CV_DRIVER, NULL); 2333 cv_init(&pwp->drain_cv, NULL, CV_DRIVER, NULL); 2334 for (i = 0; i < PMCS_NIQ; i++) { 2335 mutex_init(&pwp->iqp_lock[i], NULL, 2336 MUTEX_DRIVER, DDI_INTR_PRI(pwp->intr_pri)); 2337 } 2338 for (i = 0; i < pwp->cq_info.cq_threads; i++) { 2339 mutex_init(&pwp->cq_info.cq_thr_info[i].cq_thr_lock, NULL, 2340 MUTEX_DRIVER, DDI_INTR_PRI(pwp->intr_pri)); 2341 cv_init(&pwp->cq_info.cq_thr_info[i].cq_cv, NULL, 2342 CV_DRIVER, NULL); 2343 } 2344 2345 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "%d %s interrup%s configured", 2346 pwp->intr_cnt, (pwp->int_type == PMCS_INT_MSIX)? "MSI-X" : 2347 ((pwp->int_type == PMCS_INT_MSI)? "MSI" : "INT-X"), 2348 pwp->intr_cnt == 1? "t" : "ts"); 2349 2350 2351 /* 2352 * Enable Interrupts 2353 */ 2354 if (pwp->intr_cnt > PMCS_NOQ) { 2355 oqv_count = pwp->intr_cnt; 2356 } else { 2357 oqv_count = PMCS_NOQ; 2358 } 2359 for (pri = 0xffffffff, i = 0; i < oqv_count; i++) { 2360 pri ^= (1 << i); 2361 } 2362 2363 mutex_enter(&pwp->lock); 2364 pwp->intr_mask = pri; 2365 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_MASK, pwp->intr_mask); 2366 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 0xffffffff); 2367 mutex_exit(&pwp->lock); 2368 2369 return (0); 2370 } 2371 2372 static int 2373 pmcs_teardown_intr(pmcs_hw_t *pwp) 2374 { 2375 if (pwp->intr_cnt) { 2376 if (pmcs_disable_intrs(pwp, pwp->intr_cnt)) { 2377 return (EIO); 2378 } 2379 if (pmcs_remove_ihandlers(pwp, pwp->intr_cnt)) { 2380 return (EIO); 2381 } 2382 if (pmcs_free_intrs(pwp, pwp->intr_cnt)) { 2383 return (EIO); 2384 } 2385 pwp->intr_cnt = 0; 2386 } 2387 return (0); 2388 } 2389 2390 static uint_t 2391 pmcs_general_ix(caddr_t arg1, caddr_t arg2) 2392 { 2393 pmcs_hw_t *pwp = (pmcs_hw_t *)((void *)arg1); 2394 _NOTE(ARGUNUSED(arg2)); 2395 pmcs_general_intr(pwp); 2396 return (DDI_INTR_CLAIMED); 2397 } 2398 2399 static uint_t 2400 pmcs_event_ix(caddr_t arg1, caddr_t arg2) 2401 { 2402 pmcs_hw_t *pwp = (pmcs_hw_t *)((void *)arg1); 2403 _NOTE(ARGUNUSED(arg2)); 2404 pmcs_event_intr(pwp); 2405 return (DDI_INTR_CLAIMED); 2406 } 2407 2408 static uint_t 2409 pmcs_iodone_ix(caddr_t arg1, caddr_t arg2) 2410 { 2411 _NOTE(ARGUNUSED(arg2)); 2412 pmcs_hw_t *pwp = (pmcs_hw_t *)((void *)arg1); 2413 2414 /* 2415 * It's possible that if we just turned interrupt coalescing off 2416 * (and thus, re-enabled auto clear for interrupts on the I/O outbound 2417 * queue) that there was an interrupt already pending. We use 2418 * io_intr_coal.int_cleared to ensure that we still drop in here and 2419 * clear the appropriate interrupt bit one last time. 2420 */ 2421 mutex_enter(&pwp->ict_lock); 2422 if (pwp->io_intr_coal.timer_on || 2423 (pwp->io_intr_coal.int_cleared == B_FALSE)) { 2424 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 2425 (1 << PMCS_OQ_IODONE)); 2426 pwp->io_intr_coal.int_cleared = B_TRUE; 2427 } 2428 mutex_exit(&pwp->ict_lock); 2429 2430 pmcs_iodone_intr(pwp); 2431 2432 return (DDI_INTR_CLAIMED); 2433 } 2434 2435 static uint_t 2436 pmcs_fatal_ix(caddr_t arg1, caddr_t arg2) 2437 { 2438 pmcs_hw_t *pwp = (pmcs_hw_t *)((void *)arg1); 2439 _NOTE(ARGUNUSED(arg2)); 2440 pmcs_fatal_handler(pwp); 2441 return (DDI_INTR_CLAIMED); 2442 } 2443 2444 static uint_t 2445 pmcs_nonio_ix(caddr_t arg1, caddr_t arg2) 2446 { 2447 _NOTE(ARGUNUSED(arg2)); 2448 pmcs_hw_t *pwp = (void *)arg1; 2449 uint32_t obdb = pmcs_rd_msgunit(pwp, PMCS_MSGU_OBDB); 2450 2451 /* 2452 * Check for Fatal Interrupts 2453 */ 2454 if (obdb & (1 << PMCS_FATAL_INTERRUPT)) { 2455 pmcs_fatal_handler(pwp); 2456 return (DDI_INTR_CLAIMED); 2457 } 2458 2459 if (obdb & (1 << PMCS_OQ_GENERAL)) { 2460 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 2461 (1 << PMCS_OQ_GENERAL)); 2462 pmcs_general_intr(pwp); 2463 pmcs_event_intr(pwp); 2464 } 2465 2466 return (DDI_INTR_CLAIMED); 2467 } 2468 2469 static uint_t 2470 pmcs_all_intr(caddr_t arg1, caddr_t arg2) 2471 { 2472 _NOTE(ARGUNUSED(arg2)); 2473 pmcs_hw_t *pwp = (void *) arg1; 2474 uint32_t obdb; 2475 int handled = 0; 2476 2477 obdb = pmcs_rd_msgunit(pwp, PMCS_MSGU_OBDB); 2478 2479 /* 2480 * Check for Fatal Interrupts 2481 */ 2482 if (obdb & (1 << PMCS_FATAL_INTERRUPT)) { 2483 pmcs_fatal_handler(pwp); 2484 return (DDI_INTR_CLAIMED); 2485 } 2486 2487 /* 2488 * Check for Outbound Queue service needed 2489 */ 2490 if (obdb & (1 << PMCS_OQ_IODONE)) { 2491 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 2492 (1 << PMCS_OQ_IODONE)); 2493 obdb ^= (1 << PMCS_OQ_IODONE); 2494 handled++; 2495 pmcs_iodone_intr(pwp); 2496 } 2497 if (obdb & (1 << PMCS_OQ_GENERAL)) { 2498 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 2499 (1 << PMCS_OQ_GENERAL)); 2500 obdb ^= (1 << PMCS_OQ_GENERAL); 2501 handled++; 2502 pmcs_general_intr(pwp); 2503 } 2504 if (obdb & (1 << PMCS_OQ_EVENTS)) { 2505 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 2506 (1 << PMCS_OQ_EVENTS)); 2507 obdb ^= (1 << PMCS_OQ_EVENTS); 2508 handled++; 2509 pmcs_event_intr(pwp); 2510 } 2511 if (obdb) { 2512 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 2513 "interrupt bits not handled (0x%x)", obdb); 2514 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, obdb); 2515 handled++; 2516 } 2517 if (pwp->int_type == PMCS_INT_MSI) { 2518 handled++; 2519 } 2520 return (handled? DDI_INTR_CLAIMED : DDI_INTR_UNCLAIMED); 2521 } 2522 2523 void 2524 pmcs_fatal_handler(pmcs_hw_t *pwp) 2525 { 2526 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, "Fatal Interrupt caught"); 2527 mutex_enter(&pwp->lock); 2528 pwp->state = STATE_DEAD; 2529 pmcs_register_dump_int(pwp); 2530 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_MASK, 0xffffffff); 2531 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 0xffffffff); 2532 mutex_exit(&pwp->lock); 2533 pmcs_fm_ereport(pwp, DDI_FM_DEVICE_NO_RESPONSE); 2534 ddi_fm_service_impact(pwp->dip, DDI_SERVICE_LOST); 2535 2536 #ifdef DEBUG 2537 cmn_err(CE_PANIC, "PMCS Fatal Firmware Error"); 2538 #endif 2539 } 2540 2541 /* 2542 * Called with PHY lock and target statlock held and scratch acquired. 2543 */ 2544 boolean_t 2545 pmcs_assign_device(pmcs_hw_t *pwp, pmcs_xscsi_t *tgt) 2546 { 2547 pmcs_phy_t *pptr = tgt->phy; 2548 2549 switch (pptr->dtype) { 2550 case SAS: 2551 case EXPANDER: 2552 break; 2553 case SATA: 2554 tgt->ca = 1; 2555 break; 2556 default: 2557 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, tgt, 2558 "%s: Target %p has PHY %p with invalid dtype", 2559 __func__, (void *)tgt, (void *)pptr); 2560 return (B_FALSE); 2561 } 2562 2563 tgt->new = 1; 2564 tgt->dev_gone = 0; 2565 tgt->recover_wait = 0; 2566 2567 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, tgt, 2568 "%s: config %s vtgt %u for " SAS_ADDR_FMT, __func__, 2569 pptr->path, tgt->target_num, SAS_ADDR_PRT(pptr->sas_address)); 2570 2571 if (pmcs_add_new_device(pwp, tgt) != B_TRUE) { 2572 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, tgt, 2573 "%s: Failed for vtgt %u / WWN " SAS_ADDR_FMT, __func__, 2574 tgt->target_num, SAS_ADDR_PRT(pptr->sas_address)); 2575 mutex_destroy(&tgt->statlock); 2576 mutex_destroy(&tgt->wqlock); 2577 mutex_destroy(&tgt->aqlock); 2578 return (B_FALSE); 2579 } 2580 2581 return (B_TRUE); 2582 } 2583 2584 /* 2585 * Called with softstate lock held 2586 */ 2587 void 2588 pmcs_remove_device(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 2589 { 2590 pmcs_xscsi_t *xp; 2591 unsigned int vtgt; 2592 2593 ASSERT(mutex_owned(&pwp->lock)); 2594 2595 for (vtgt = 0; vtgt < pwp->max_dev; vtgt++) { 2596 xp = pwp->targets[vtgt]; 2597 if (xp == NULL) { 2598 continue; 2599 } 2600 2601 mutex_enter(&xp->statlock); 2602 if (xp->phy == pptr) { 2603 if (xp->new) { 2604 xp->new = 0; 2605 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, xp, 2606 "cancel config of vtgt %u", vtgt); 2607 } else { 2608 pmcs_clear_xp(pwp, xp); 2609 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, xp, 2610 "Removed tgt 0x%p vtgt %u", 2611 (void *)xp, vtgt); 2612 } 2613 mutex_exit(&xp->statlock); 2614 break; 2615 } 2616 mutex_exit(&xp->statlock); 2617 } 2618 } 2619 2620 void 2621 pmcs_prt_impl(pmcs_hw_t *pwp, pmcs_prt_level_t level, 2622 pmcs_phy_t *phyp, pmcs_xscsi_t *target, const char *fmt, ...) 2623 { 2624 va_list ap; 2625 int written = 0; 2626 char *ptr; 2627 uint32_t elem_size = PMCS_TBUF_ELEM_SIZE - 1; 2628 boolean_t system_log; 2629 int system_log_level; 2630 2631 switch (level) { 2632 case PMCS_PRT_DEBUG_DEVEL: 2633 case PMCS_PRT_DEBUG_DEV_STATE: 2634 case PMCS_PRT_DEBUG_PHY_LOCKING: 2635 case PMCS_PRT_DEBUG_SCSI_STATUS: 2636 case PMCS_PRT_DEBUG_UNDERFLOW: 2637 case PMCS_PRT_DEBUG_CONFIG: 2638 case PMCS_PRT_DEBUG_IPORT: 2639 case PMCS_PRT_DEBUG_MAP: 2640 case PMCS_PRT_DEBUG3: 2641 case PMCS_PRT_DEBUG2: 2642 case PMCS_PRT_DEBUG1: 2643 case PMCS_PRT_DEBUG: 2644 system_log = B_FALSE; 2645 break; 2646 case PMCS_PRT_INFO: 2647 system_log = B_TRUE; 2648 system_log_level = CE_CONT; 2649 break; 2650 case PMCS_PRT_WARN: 2651 system_log = B_TRUE; 2652 system_log_level = CE_NOTE; 2653 break; 2654 case PMCS_PRT_ERR: 2655 system_log = B_TRUE; 2656 system_log_level = CE_WARN; 2657 break; 2658 default: 2659 return; 2660 } 2661 2662 mutex_enter(&pmcs_trace_lock); 2663 gethrestime(&pmcs_tbuf_ptr->timestamp); 2664 ptr = pmcs_tbuf_ptr->buf; 2665 2666 /* 2667 * Store the pertinent PHY and target information if there is any 2668 */ 2669 if (target == NULL) { 2670 pmcs_tbuf_ptr->target_num = PMCS_INVALID_TARGET_NUM; 2671 pmcs_tbuf_ptr->target_ua[0] = '\0'; 2672 } else { 2673 pmcs_tbuf_ptr->target_num = target->target_num; 2674 (void) strncpy(pmcs_tbuf_ptr->target_ua, target->ua, 2675 PMCS_TBUF_UA_MAX_SIZE); 2676 } 2677 2678 if (phyp == NULL) { 2679 (void) memset(pmcs_tbuf_ptr->phy_sas_address, 0, 8); 2680 pmcs_tbuf_ptr->phy_path[0] = '\0'; 2681 pmcs_tbuf_ptr->phy_dtype = NOTHING; 2682 } else { 2683 (void) memcpy(pmcs_tbuf_ptr->phy_sas_address, 2684 phyp->sas_address, 8); 2685 (void) strncpy(pmcs_tbuf_ptr->phy_path, phyp->path, 32); 2686 pmcs_tbuf_ptr->phy_dtype = phyp->dtype; 2687 } 2688 2689 written += snprintf(ptr, elem_size, "pmcs%d:%d: ", 2690 ddi_get_instance(pwp->dip), level); 2691 ptr += strlen(ptr); 2692 va_start(ap, fmt); 2693 written += vsnprintf(ptr, elem_size - written, fmt, ap); 2694 va_end(ap); 2695 if (written > elem_size - 1) { 2696 /* Indicate truncation */ 2697 pmcs_tbuf_ptr->buf[elem_size - 1] = '+'; 2698 } 2699 if (++pmcs_tbuf_idx == pmcs_tbuf_num_elems) { 2700 pmcs_tbuf_ptr = pmcs_tbuf; 2701 pmcs_tbuf_wrap = B_TRUE; 2702 pmcs_tbuf_idx = 0; 2703 } else { 2704 ++pmcs_tbuf_ptr; 2705 } 2706 mutex_exit(&pmcs_trace_lock); 2707 2708 /* 2709 * When pmcs_force_syslog in non-zero, everything goes also 2710 * to syslog, at CE_CONT level. 2711 */ 2712 if (pmcs_force_syslog) { 2713 system_log = B_TRUE; 2714 system_log_level = CE_CONT; 2715 } 2716 2717 /* 2718 * Anything that comes in with PMCS_PRT_INFO, WARN, or ERR also 2719 * goes to syslog. 2720 */ 2721 if (system_log) { 2722 char local[196]; 2723 2724 switch (system_log_level) { 2725 case CE_CONT: 2726 (void) snprintf(local, sizeof (local), "%sINFO: ", 2727 pmcs_console ? "" : "?"); 2728 break; 2729 case CE_NOTE: 2730 case CE_WARN: 2731 local[0] = 0; 2732 break; 2733 default: 2734 return; 2735 } 2736 2737 ptr = local; 2738 ptr += strlen(local); 2739 (void) snprintf(ptr, (sizeof (local)) - 2740 ((size_t)ptr - (size_t)local), "pmcs%d: ", 2741 ddi_get_instance(pwp->dip)); 2742 ptr += strlen(ptr); 2743 va_start(ap, fmt); 2744 (void) vsnprintf(ptr, 2745 (sizeof (local)) - ((size_t)ptr - (size_t)local), fmt, ap); 2746 va_end(ap); 2747 if (level == CE_CONT) { 2748 (void) strlcat(local, "\n", sizeof (local)); 2749 } 2750 cmn_err(system_log_level, local); 2751 } 2752 2753 } 2754 2755 /* 2756 * pmcs_acquire_scratch 2757 * 2758 * If "wait" is true, the caller will wait until it can acquire the scratch. 2759 * This implies the caller needs to be in a context where spinning for an 2760 * indeterminate amount of time is acceptable. 2761 */ 2762 int 2763 pmcs_acquire_scratch(pmcs_hw_t *pwp, boolean_t wait) 2764 { 2765 int rval; 2766 2767 if (!wait) { 2768 return (atomic_swap_8(&pwp->scratch_locked, 1)); 2769 } 2770 2771 /* 2772 * Caller will wait for scratch. 2773 */ 2774 while ((rval = atomic_swap_8(&pwp->scratch_locked, 1)) != 0) { 2775 drv_usecwait(100); 2776 } 2777 2778 return (rval); 2779 } 2780 2781 void 2782 pmcs_release_scratch(pmcs_hw_t *pwp) 2783 { 2784 pwp->scratch_locked = 0; 2785 } 2786 2787 static void 2788 pmcs_create_phy_stats(pmcs_iport_t *iport) 2789 { 2790 sas_phy_stats_t *ps; 2791 pmcs_hw_t *pwp; 2792 pmcs_phy_t *phyp; 2793 int ndata; 2794 char ks_name[KSTAT_STRLEN]; 2795 2796 ASSERT(iport != NULL); 2797 pwp = iport->pwp; 2798 ASSERT(pwp != NULL); 2799 2800 mutex_enter(&iport->lock); 2801 2802 for (phyp = list_head(&iport->phys); 2803 phyp != NULL; 2804 phyp = list_next(&iport->phys, phyp)) { 2805 2806 pmcs_lock_phy(phyp); 2807 2808 if (phyp->phy_stats != NULL) { 2809 pmcs_unlock_phy(phyp); 2810 /* We've already created this kstat instance */ 2811 continue; 2812 } 2813 2814 ndata = (sizeof (sas_phy_stats_t)/sizeof (kstat_named_t)); 2815 2816 (void) snprintf(ks_name, sizeof (ks_name), 2817 "%s.%llx.%d.%d", ddi_driver_name(iport->dip), 2818 (longlong_t)pwp->sas_wwns[0], 2819 ddi_get_instance(iport->dip), phyp->phynum); 2820 2821 phyp->phy_stats = kstat_create("pmcs", 2822 ddi_get_instance(iport->dip), ks_name, KSTAT_SAS_PHY_CLASS, 2823 KSTAT_TYPE_NAMED, ndata, 0); 2824 2825 if (phyp->phy_stats == NULL) { 2826 pmcs_unlock_phy(phyp); 2827 pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL, 2828 "%s: Failed to create %s kstats", __func__, 2829 ks_name); 2830 continue; 2831 } 2832 2833 ps = (sas_phy_stats_t *)phyp->phy_stats->ks_data; 2834 2835 kstat_named_init(&ps->seconds_since_last_reset, 2836 "SecondsSinceLastReset", KSTAT_DATA_ULONGLONG); 2837 kstat_named_init(&ps->tx_frames, 2838 "TxFrames", KSTAT_DATA_ULONGLONG); 2839 kstat_named_init(&ps->rx_frames, 2840 "RxFrames", KSTAT_DATA_ULONGLONG); 2841 kstat_named_init(&ps->tx_words, 2842 "TxWords", KSTAT_DATA_ULONGLONG); 2843 kstat_named_init(&ps->rx_words, 2844 "RxWords", KSTAT_DATA_ULONGLONG); 2845 kstat_named_init(&ps->invalid_dword_count, 2846 "InvalidDwordCount", KSTAT_DATA_ULONGLONG); 2847 kstat_named_init(&ps->running_disparity_error_count, 2848 "RunningDisparityErrorCount", KSTAT_DATA_ULONGLONG); 2849 kstat_named_init(&ps->loss_of_dword_sync_count, 2850 "LossofDwordSyncCount", KSTAT_DATA_ULONGLONG); 2851 kstat_named_init(&ps->phy_reset_problem_count, 2852 "PhyResetProblemCount", KSTAT_DATA_ULONGLONG); 2853 2854 phyp->phy_stats->ks_private = phyp; 2855 phyp->phy_stats->ks_update = pmcs_update_phy_stats; 2856 kstat_install(phyp->phy_stats); 2857 pmcs_unlock_phy(phyp); 2858 } 2859 2860 mutex_exit(&iport->lock); 2861 } 2862 2863 int 2864 pmcs_update_phy_stats(kstat_t *ks, int rw) 2865 { 2866 int val, ret = DDI_FAILURE; 2867 pmcs_phy_t *pptr = (pmcs_phy_t *)ks->ks_private; 2868 pmcs_hw_t *pwp = pptr->pwp; 2869 sas_phy_stats_t *ps = ks->ks_data; 2870 2871 _NOTE(ARGUNUSED(rw)); 2872 ASSERT((pptr != NULL) && (pwp != NULL)); 2873 2874 /* 2875 * We just want to lock against other invocations of kstat; 2876 * we don't need to pmcs_lock_phy() for this. 2877 */ 2878 mutex_enter(&pptr->phy_lock); 2879 2880 /* Get Stats from Chip */ 2881 val = pmcs_get_diag_report(pwp, PMCS_INVALID_DWORD_CNT, pptr->phynum); 2882 if (val == DDI_FAILURE) 2883 goto fail; 2884 ps->invalid_dword_count.value.ull = (unsigned long long)val; 2885 2886 val = pmcs_get_diag_report(pwp, PMCS_DISPARITY_ERR_CNT, pptr->phynum); 2887 if (val == DDI_FAILURE) 2888 goto fail; 2889 ps->running_disparity_error_count.value.ull = (unsigned long long)val; 2890 2891 val = pmcs_get_diag_report(pwp, PMCS_LOST_DWORD_SYNC_CNT, pptr->phynum); 2892 if (val == DDI_FAILURE) 2893 goto fail; 2894 ps->loss_of_dword_sync_count.value.ull = (unsigned long long)val; 2895 2896 val = pmcs_get_diag_report(pwp, PMCS_RESET_FAILED_CNT, pptr->phynum); 2897 if (val == DDI_FAILURE) 2898 goto fail; 2899 ps->phy_reset_problem_count.value.ull = (unsigned long long)val; 2900 2901 ret = DDI_SUCCESS; 2902 fail: 2903 mutex_exit(&pptr->phy_lock); 2904 return (ret); 2905 } 2906 2907 static void 2908 pmcs_destroy_phy_stats(pmcs_iport_t *iport) 2909 { 2910 pmcs_phy_t *phyp; 2911 2912 ASSERT(iport != NULL); 2913 mutex_enter(&iport->lock); 2914 phyp = iport->pptr; 2915 if (phyp == NULL) { 2916 mutex_exit(&iport->lock); 2917 return; 2918 } 2919 2920 pmcs_lock_phy(phyp); 2921 if (phyp->phy_stats != NULL) { 2922 kstat_delete(phyp->phy_stats); 2923 phyp->phy_stats = NULL; 2924 } 2925 pmcs_unlock_phy(phyp); 2926 2927 mutex_exit(&iport->lock); 2928 } 2929 2930 /*ARGSUSED*/ 2931 static int 2932 pmcs_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) 2933 { 2934 /* 2935 * as the driver can always deal with an error in any dma or 2936 * access handle, we can just return the fme_status value. 2937 */ 2938 pci_ereport_post(dip, err, NULL); 2939 return (err->fme_status); 2940 } 2941 2942 static void 2943 pmcs_fm_init(pmcs_hw_t *pwp) 2944 { 2945 ddi_iblock_cookie_t fm_ibc; 2946 2947 /* Only register with IO Fault Services if we have some capability */ 2948 if (pwp->fm_capabilities) { 2949 /* Adjust access and dma attributes for FMA */ 2950 pwp->reg_acc_attr.devacc_attr_access |= DDI_FLAGERR_ACC; 2951 pwp->dev_acc_attr.devacc_attr_access |= DDI_FLAGERR_ACC; 2952 pwp->iqp_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 2953 pwp->oqp_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 2954 pwp->cip_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 2955 pwp->fwlog_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 2956 2957 /* 2958 * Register capabilities with IO Fault Services. 2959 */ 2960 ddi_fm_init(pwp->dip, &pwp->fm_capabilities, &fm_ibc); 2961 2962 /* 2963 * Initialize pci ereport capabilities if ereport 2964 * capable (should always be.) 2965 */ 2966 if (DDI_FM_EREPORT_CAP(pwp->fm_capabilities) || 2967 DDI_FM_ERRCB_CAP(pwp->fm_capabilities)) { 2968 pci_ereport_setup(pwp->dip); 2969 } 2970 2971 /* 2972 * Register error callback if error callback capable. 2973 */ 2974 if (DDI_FM_ERRCB_CAP(pwp->fm_capabilities)) { 2975 ddi_fm_handler_register(pwp->dip, 2976 pmcs_fm_error_cb, (void *) pwp); 2977 } 2978 } 2979 } 2980 2981 static void 2982 pmcs_fm_fini(pmcs_hw_t *pwp) 2983 { 2984 /* Only unregister FMA capabilities if registered */ 2985 if (pwp->fm_capabilities) { 2986 /* 2987 * Un-register error callback if error callback capable. 2988 */ 2989 if (DDI_FM_ERRCB_CAP(pwp->fm_capabilities)) { 2990 ddi_fm_handler_unregister(pwp->dip); 2991 } 2992 2993 /* 2994 * Release any resources allocated by pci_ereport_setup() 2995 */ 2996 if (DDI_FM_EREPORT_CAP(pwp->fm_capabilities) || 2997 DDI_FM_ERRCB_CAP(pwp->fm_capabilities)) { 2998 pci_ereport_teardown(pwp->dip); 2999 } 3000 3001 /* Unregister from IO Fault Services */ 3002 ddi_fm_fini(pwp->dip); 3003 3004 /* Adjust access and dma attributes for FMA */ 3005 pwp->reg_acc_attr.devacc_attr_access &= ~DDI_FLAGERR_ACC; 3006 pwp->dev_acc_attr.devacc_attr_access &= ~DDI_FLAGERR_ACC; 3007 pwp->iqp_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 3008 pwp->oqp_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 3009 pwp->cip_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 3010 pwp->fwlog_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 3011 } 3012 } 3013 3014 static boolean_t 3015 pmcs_fabricate_wwid(pmcs_hw_t *pwp) 3016 { 3017 char *cp, c; 3018 uint64_t adr; 3019 int i; 3020 3021 cp = &c; 3022 (void) ddi_strtoul(hw_serial, &cp, 10, (unsigned long *)&adr); 3023 if (adr == 0) { 3024 static const char foo[] = __DATE__ __TIME__; 3025 /* Oh, dear, we're toast */ 3026 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 3027 "%s: No serial number available to fabricate WWN", 3028 __func__); 3029 for (i = 0; foo[i]; i++) { 3030 adr += foo[i]; 3031 } 3032 } 3033 adr <<= 8; 3034 adr |= ((uint64_t)ddi_get_instance(pwp->dip) << 52); 3035 adr |= (5ULL << 60); 3036 for (i = 0; i < PMCS_MAX_PORTS; i++) { 3037 pwp->sas_wwns[i] = adr + i; 3038 } 3039 3040 return (B_TRUE); 3041 } 3042