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