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