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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 /* 26 * This file contains various support routines. 27 */ 28 29 #include <sys/scsi/adapters/pmcs/pmcs.h> 30 31 /* 32 * Local static data 33 */ 34 static int tgtmap_stable_usec = MICROSEC; /* 1 second */ 35 static int tgtmap_csync_usec = 10 * MICROSEC; /* 10 seconds */ 36 37 /* 38 * SAS Topology Configuration 39 */ 40 static void pmcs_new_tport(pmcs_hw_t *, pmcs_phy_t *); 41 static void pmcs_configure_expander(pmcs_hw_t *, pmcs_phy_t *, pmcs_iport_t *); 42 43 static void pmcs_check_expanders(pmcs_hw_t *, pmcs_phy_t *); 44 static void pmcs_check_expander(pmcs_hw_t *, pmcs_phy_t *); 45 static void pmcs_clear_expander(pmcs_hw_t *, pmcs_phy_t *, int); 46 47 static int pmcs_expander_get_nphy(pmcs_hw_t *, pmcs_phy_t *); 48 static int pmcs_expander_content_discover(pmcs_hw_t *, pmcs_phy_t *, 49 pmcs_phy_t *); 50 51 static int pmcs_smp_function_result(pmcs_hw_t *, smp_response_frame_t *); 52 static void pmcs_flush_nonio_cmds(pmcs_hw_t *pwp, pmcs_xscsi_t *tgt); 53 static boolean_t pmcs_validate_devid(pmcs_phy_t *, pmcs_phy_t *, uint32_t); 54 static void pmcs_clear_phys(pmcs_hw_t *, pmcs_phy_t *); 55 static int pmcs_configure_new_devices(pmcs_hw_t *, pmcs_phy_t *); 56 static void pmcs_begin_observations(pmcs_hw_t *); 57 static void pmcs_flush_observations(pmcs_hw_t *); 58 static boolean_t pmcs_report_observations(pmcs_hw_t *); 59 static boolean_t pmcs_report_iport_observations(pmcs_hw_t *, pmcs_iport_t *, 60 pmcs_phy_t *); 61 static pmcs_phy_t *pmcs_find_phy_needing_work(pmcs_hw_t *, pmcs_phy_t *); 62 static int pmcs_kill_devices(pmcs_hw_t *, pmcs_phy_t *); 63 static void pmcs_lock_phy_impl(pmcs_phy_t *, int); 64 static void pmcs_unlock_phy_impl(pmcs_phy_t *, int); 65 static pmcs_phy_t *pmcs_clone_phy(pmcs_phy_t *); 66 static boolean_t pmcs_configure_phy(pmcs_hw_t *, pmcs_phy_t *); 67 static void pmcs_reap_dead_phy(pmcs_phy_t *); 68 static pmcs_iport_t *pmcs_get_iport_by_ua(pmcs_hw_t *, char *); 69 static boolean_t pmcs_phy_target_match(pmcs_phy_t *); 70 static void pmcs_iport_active(pmcs_iport_t *); 71 static void pmcs_tgtmap_activate_cb(void *, char *, scsi_tgtmap_tgt_type_t, 72 void **); 73 static boolean_t pmcs_tgtmap_deactivate_cb(void *, char *, 74 scsi_tgtmap_tgt_type_t, void *, scsi_tgtmap_deact_rsn_t); 75 static void pmcs_add_dead_phys(pmcs_hw_t *, pmcs_phy_t *); 76 static void pmcs_get_fw_version(pmcs_hw_t *); 77 static int pmcs_get_time_stamp(pmcs_hw_t *, uint64_t *, hrtime_t *); 78 79 /* 80 * Often used strings 81 */ 82 const char pmcs_nowrk[] = "%s: unable to get work structure"; 83 const char pmcs_nomsg[] = "%s: unable to get Inbound Message entry"; 84 const char pmcs_timeo[] = "%s: command timed out"; 85 86 extern const ddi_dma_attr_t pmcs_dattr; 87 extern kmutex_t pmcs_trace_lock; 88 89 /* 90 * Some Initial setup steps. 91 */ 92 93 int 94 pmcs_setup(pmcs_hw_t *pwp) 95 { 96 uint32_t barval = pwp->mpibar; 97 uint32_t i, scratch, regbar, regoff, barbar, baroff; 98 uint32_t new_ioq_depth, ferr = 0; 99 100 /* 101 * Check current state. If we're not at READY state, 102 * we can't go further. 103 */ 104 scratch = pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH1); 105 if ((scratch & PMCS_MSGU_AAP_STATE_MASK) == PMCS_MSGU_AAP_STATE_ERROR) { 106 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 107 "%s: AAP Error State (0x%x)", 108 __func__, pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH1) & 109 PMCS_MSGU_AAP_ERROR_MASK); 110 pmcs_fm_ereport(pwp, DDI_FM_DEVICE_INVAL_STATE); 111 ddi_fm_service_impact(pwp->dip, DDI_SERVICE_LOST); 112 return (-1); 113 } 114 if ((scratch & PMCS_MSGU_AAP_STATE_MASK) != PMCS_MSGU_AAP_STATE_READY) { 115 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 116 "%s: AAP unit not ready (state 0x%x)", 117 __func__, scratch & PMCS_MSGU_AAP_STATE_MASK); 118 pmcs_fm_ereport(pwp, DDI_FM_DEVICE_INVAL_STATE); 119 ddi_fm_service_impact(pwp->dip, DDI_SERVICE_LOST); 120 return (-1); 121 } 122 123 /* 124 * Read the offset from the Message Unit scratchpad 0 register. 125 * This allows us to read the MPI Configuration table. 126 * 127 * Check its signature for validity. 128 */ 129 baroff = barval; 130 barbar = barval >> PMCS_MSGU_MPI_BAR_SHIFT; 131 baroff &= PMCS_MSGU_MPI_OFFSET_MASK; 132 133 regoff = pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH0); 134 regbar = regoff >> PMCS_MSGU_MPI_BAR_SHIFT; 135 regoff &= PMCS_MSGU_MPI_OFFSET_MASK; 136 137 if (regoff > baroff) { 138 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 139 "%s: bad MPI Table Length (register offset=0x%08x, " 140 "passed offset=0x%08x)", __func__, regoff, baroff); 141 return (-1); 142 } 143 if (regbar != barbar) { 144 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 145 "%s: bad MPI BAR (register BAROFF=0x%08x, " 146 "passed BAROFF=0x%08x)", __func__, regbar, barbar); 147 return (-1); 148 } 149 pwp->mpi_offset = regoff; 150 if (pmcs_rd_mpi_tbl(pwp, PMCS_MPI_AS) != PMCS_SIGNATURE) { 151 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 152 "%s: Bad MPI Configuration Table Signature 0x%x", __func__, 153 pmcs_rd_mpi_tbl(pwp, PMCS_MPI_AS)); 154 return (-1); 155 } 156 157 if (pmcs_rd_mpi_tbl(pwp, PMCS_MPI_IR) != PMCS_MPI_REVISION1) { 158 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 159 "%s: Bad MPI Configuration Revision 0x%x", __func__, 160 pmcs_rd_mpi_tbl(pwp, PMCS_MPI_IR)); 161 return (-1); 162 } 163 164 /* 165 * Generate offsets for the General System, Inbound Queue Configuration 166 * and Outbound Queue configuration tables. This way the macros to 167 * access those tables will work correctly. 168 */ 169 pwp->mpi_gst_offset = 170 pwp->mpi_offset + pmcs_rd_mpi_tbl(pwp, PMCS_MPI_GSTO); 171 pwp->mpi_iqc_offset = 172 pwp->mpi_offset + pmcs_rd_mpi_tbl(pwp, PMCS_MPI_IQCTO); 173 pwp->mpi_oqc_offset = 174 pwp->mpi_offset + pmcs_rd_mpi_tbl(pwp, PMCS_MPI_OQCTO); 175 176 pmcs_get_fw_version(pwp); 177 178 pwp->max_cmd = pmcs_rd_mpi_tbl(pwp, PMCS_MPI_MOIO); 179 pwp->max_dev = pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO0) >> 16; 180 181 pwp->max_iq = PMCS_MNIQ(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO1)); 182 pwp->max_oq = PMCS_MNOQ(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO1)); 183 pwp->nphy = PMCS_NPHY(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO1)); 184 if (pwp->max_iq <= PMCS_NIQ) { 185 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 186 "%s: not enough Inbound Queues supported " 187 "(need %d, max_oq=%d)", __func__, pwp->max_iq, PMCS_NIQ); 188 return (-1); 189 } 190 if (pwp->max_oq <= PMCS_NOQ) { 191 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 192 "%s: not enough Outbound Queues supported " 193 "(need %d, max_oq=%d)", __func__, pwp->max_oq, PMCS_NOQ); 194 return (-1); 195 } 196 if (pwp->nphy == 0) { 197 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 198 "%s: zero phys reported", __func__); 199 return (-1); 200 } 201 if (PMCS_HPIQ(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO1))) { 202 pwp->hipri_queue = (1 << PMCS_IQ_OTHER); 203 } 204 205 206 for (i = 0; i < pwp->nphy; i++) { 207 PMCS_MPI_EVQSET(pwp, PMCS_OQ_EVENTS, i); 208 PMCS_MPI_NCQSET(pwp, PMCS_OQ_EVENTS, i); 209 } 210 211 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_INFO2, 212 (PMCS_OQ_EVENTS << GENERAL_EVENT_OQ_SHIFT) | 213 (PMCS_OQ_EVENTS << DEVICE_HANDLE_REMOVED_SHIFT)); 214 215 /* 216 * Verify that ioq_depth is valid (> 0 and not so high that it 217 * would cause us to overrun the chip with commands). 218 */ 219 if (pwp->ioq_depth == 0) { 220 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 221 "%s: I/O queue depth set to 0. Setting to %d", 222 __func__, PMCS_NQENTRY); 223 pwp->ioq_depth = PMCS_NQENTRY; 224 } 225 226 if (pwp->ioq_depth < PMCS_MIN_NQENTRY) { 227 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 228 "%s: I/O queue depth set too low (%d). Setting to %d", 229 __func__, pwp->ioq_depth, PMCS_MIN_NQENTRY); 230 pwp->ioq_depth = PMCS_MIN_NQENTRY; 231 } 232 233 if (pwp->ioq_depth > (pwp->max_cmd / (PMCS_IO_IQ_MASK + 1))) { 234 new_ioq_depth = pwp->max_cmd / (PMCS_IO_IQ_MASK + 1); 235 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 236 "%s: I/O queue depth set too high (%d). Setting to %d", 237 __func__, pwp->ioq_depth, new_ioq_depth); 238 pwp->ioq_depth = new_ioq_depth; 239 } 240 241 /* 242 * Allocate consistent memory for OQs and IQs. 243 */ 244 pwp->iqp_dma_attr = pwp->oqp_dma_attr = pmcs_dattr; 245 pwp->iqp_dma_attr.dma_attr_align = 246 pwp->oqp_dma_attr.dma_attr_align = PMCS_QENTRY_SIZE; 247 248 /* 249 * The Rev C chip has the ability to do PIO to or from consistent 250 * memory anywhere in a 64 bit address space, but the firmware is 251 * not presently set up to do so. 252 */ 253 pwp->iqp_dma_attr.dma_attr_addr_hi = 254 pwp->oqp_dma_attr.dma_attr_addr_hi = 0x000000FFFFFFFFFFull; 255 256 for (i = 0; i < PMCS_NIQ; i++) { 257 if (pmcs_dma_setup(pwp, &pwp->iqp_dma_attr, 258 &pwp->iqp_acchdls[i], 259 &pwp->iqp_handles[i], PMCS_QENTRY_SIZE * pwp->ioq_depth, 260 (caddr_t *)&pwp->iqp[i], &pwp->iqaddr[i]) == B_FALSE) { 261 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 262 "Failed to setup DMA for iqp[%d]", i); 263 return (-1); 264 } 265 bzero(pwp->iqp[i], PMCS_QENTRY_SIZE * pwp->ioq_depth); 266 } 267 268 for (i = 0; i < PMCS_NOQ; i++) { 269 if (pmcs_dma_setup(pwp, &pwp->oqp_dma_attr, 270 &pwp->oqp_acchdls[i], 271 &pwp->oqp_handles[i], PMCS_QENTRY_SIZE * pwp->ioq_depth, 272 (caddr_t *)&pwp->oqp[i], &pwp->oqaddr[i]) == B_FALSE) { 273 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 274 "Failed to setup DMA for oqp[%d]", i); 275 return (-1); 276 } 277 bzero(pwp->oqp[i], PMCS_QENTRY_SIZE * pwp->ioq_depth); 278 } 279 280 /* 281 * Install the IQ and OQ addresses (and null out the rest). 282 */ 283 for (i = 0; i < pwp->max_iq; i++) { 284 pwp->iqpi_offset[i] = pmcs_rd_iqc_tbl(pwp, PMCS_IQPIOFFX(i)); 285 if (i < PMCS_NIQ) { 286 if (i != PMCS_IQ_OTHER) { 287 pmcs_wr_iqc_tbl(pwp, PMCS_IQC_PARMX(i), 288 pwp->ioq_depth | (PMCS_QENTRY_SIZE << 16)); 289 } else { 290 pmcs_wr_iqc_tbl(pwp, PMCS_IQC_PARMX(i), 291 (1 << 30) | pwp->ioq_depth | 292 (PMCS_QENTRY_SIZE << 16)); 293 } 294 pmcs_wr_iqc_tbl(pwp, PMCS_IQBAHX(i), 295 DWORD1(pwp->iqaddr[i])); 296 pmcs_wr_iqc_tbl(pwp, PMCS_IQBALX(i), 297 DWORD0(pwp->iqaddr[i])); 298 pmcs_wr_iqc_tbl(pwp, PMCS_IQCIBAHX(i), 299 DWORD1(pwp->ciaddr+IQ_OFFSET(i))); 300 pmcs_wr_iqc_tbl(pwp, PMCS_IQCIBALX(i), 301 DWORD0(pwp->ciaddr+IQ_OFFSET(i))); 302 } else { 303 pmcs_wr_iqc_tbl(pwp, PMCS_IQC_PARMX(i), 0); 304 pmcs_wr_iqc_tbl(pwp, PMCS_IQBAHX(i), 0); 305 pmcs_wr_iqc_tbl(pwp, PMCS_IQBALX(i), 0); 306 pmcs_wr_iqc_tbl(pwp, PMCS_IQCIBAHX(i), 0); 307 pmcs_wr_iqc_tbl(pwp, PMCS_IQCIBALX(i), 0); 308 } 309 } 310 311 for (i = 0; i < pwp->max_oq; i++) { 312 pwp->oqci_offset[i] = pmcs_rd_oqc_tbl(pwp, PMCS_OQCIOFFX(i)); 313 if (i < PMCS_NOQ) { 314 pmcs_wr_oqc_tbl(pwp, PMCS_OQC_PARMX(i), pwp->ioq_depth | 315 (PMCS_QENTRY_SIZE << 16) | OQIEX); 316 pmcs_wr_oqc_tbl(pwp, PMCS_OQBAHX(i), 317 DWORD1(pwp->oqaddr[i])); 318 pmcs_wr_oqc_tbl(pwp, PMCS_OQBALX(i), 319 DWORD0(pwp->oqaddr[i])); 320 pmcs_wr_oqc_tbl(pwp, PMCS_OQPIBAHX(i), 321 DWORD1(pwp->ciaddr+OQ_OFFSET(i))); 322 pmcs_wr_oqc_tbl(pwp, PMCS_OQPIBALX(i), 323 DWORD0(pwp->ciaddr+OQ_OFFSET(i))); 324 pmcs_wr_oqc_tbl(pwp, PMCS_OQIPARM(i), 325 pwp->oqvec[i] << 24); 326 pmcs_wr_oqc_tbl(pwp, PMCS_OQDICX(i), 0); 327 } else { 328 pmcs_wr_oqc_tbl(pwp, PMCS_OQC_PARMX(i), 0); 329 pmcs_wr_oqc_tbl(pwp, PMCS_OQBAHX(i), 0); 330 pmcs_wr_oqc_tbl(pwp, PMCS_OQBALX(i), 0); 331 pmcs_wr_oqc_tbl(pwp, PMCS_OQPIBAHX(i), 0); 332 pmcs_wr_oqc_tbl(pwp, PMCS_OQPIBALX(i), 0); 333 pmcs_wr_oqc_tbl(pwp, PMCS_OQIPARM(i), 0); 334 pmcs_wr_oqc_tbl(pwp, PMCS_OQDICX(i), 0); 335 } 336 } 337 338 /* 339 * Set up logging, if defined. 340 */ 341 if (pwp->fwlog) { 342 uint64_t logdma = pwp->fwaddr; 343 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_MELBAH, DWORD1(logdma)); 344 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_MELBAL, DWORD0(logdma)); 345 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_MELBS, PMCS_FWLOG_SIZE >> 1); 346 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_MELSEV, pwp->fwlog); 347 logdma += (PMCS_FWLOG_SIZE >> 1); 348 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_IELBAH, DWORD1(logdma)); 349 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_IELBAL, DWORD0(logdma)); 350 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_IELBS, PMCS_FWLOG_SIZE >> 1); 351 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_IELSEV, pwp->fwlog); 352 } 353 354 /* 355 * Interrupt vectors, outbound queues, and odb_auto_clear 356 * 357 * MSI/MSI-X: 358 * If we got 4 interrupt vectors, we'll assign one to each outbound 359 * queue as well as the fatal interrupt, and auto clear can be set 360 * for each. 361 * 362 * If we only got 2 vectors, one will be used for I/O completions 363 * and the other for the other two vectors. In this case, auto_ 364 * clear can only be set for I/Os, which is fine. The fatal 365 * interrupt will be mapped to the PMCS_FATAL_INTERRUPT bit, which 366 * is not an interrupt vector. 367 * 368 * MSI/MSI-X/INT-X: 369 * If we only got 1 interrupt vector, auto_clear must be set to 0, 370 * and again the fatal interrupt will be mapped to the 371 * PMCS_FATAL_INTERRUPT bit (again, not an interrupt vector). 372 */ 373 374 switch (pwp->int_type) { 375 case PMCS_INT_MSIX: 376 case PMCS_INT_MSI: 377 switch (pwp->intr_cnt) { 378 case 1: 379 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_FERR, PMCS_FERRIE | 380 (PMCS_FATAL_INTERRUPT << PMCS_FERIV_SHIFT)); 381 pwp->odb_auto_clear = 0; 382 break; 383 case 2: 384 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_FERR, PMCS_FERRIE | 385 (PMCS_FATAL_INTERRUPT << PMCS_FERIV_SHIFT)); 386 pwp->odb_auto_clear = (1 << PMCS_FATAL_INTERRUPT) | 387 (1 << PMCS_MSIX_IODONE); 388 break; 389 case 4: 390 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_FERR, PMCS_FERRIE | 391 (PMCS_MSIX_FATAL << PMCS_FERIV_SHIFT)); 392 pwp->odb_auto_clear = (1 << PMCS_MSIX_FATAL) | 393 (1 << PMCS_MSIX_GENERAL) | (1 << PMCS_MSIX_IODONE) | 394 (1 << PMCS_MSIX_EVENTS); 395 break; 396 } 397 break; 398 399 case PMCS_INT_FIXED: 400 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_FERR, 401 PMCS_FERRIE | (PMCS_FATAL_INTERRUPT << PMCS_FERIV_SHIFT)); 402 pwp->odb_auto_clear = 0; 403 break; 404 } 405 406 /* 407 * If the open retry interval is non-zero, set it. 408 */ 409 if (pwp->open_retry_interval != 0) { 410 int phynum; 411 412 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 413 "%s: Setting open retry interval to %d usecs", __func__, 414 pwp->open_retry_interval); 415 for (phynum = 0; phynum < pwp->nphy; phynum ++) { 416 pmcs_wr_gsm_reg(pwp, OPEN_RETRY_INTERVAL(phynum), 417 pwp->open_retry_interval); 418 } 419 } 420 421 /* 422 * Enable Interrupt Reassertion 423 * Default Delay 1000us 424 */ 425 ferr = pmcs_rd_mpi_tbl(pwp, PMCS_MPI_FERR); 426 if ((ferr & PMCS_MPI_IRAE) == 0) { 427 ferr &= ~(PMCS_MPI_IRAU | PMCS_MPI_IRAD_MASK); 428 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_FERR, ferr | PMCS_MPI_IRAE); 429 } 430 431 pmcs_wr_topunit(pwp, PMCS_OBDB_AUTO_CLR, pwp->odb_auto_clear); 432 pwp->mpi_table_setup = 1; 433 return (0); 434 } 435 436 /* 437 * Start the Message Passing protocol with the PMC chip. 438 */ 439 int 440 pmcs_start_mpi(pmcs_hw_t *pwp) 441 { 442 int i; 443 444 pmcs_wr_msgunit(pwp, PMCS_MSGU_IBDB, PMCS_MSGU_IBDB_MPIINI); 445 for (i = 0; i < 1000; i++) { 446 if ((pmcs_rd_msgunit(pwp, PMCS_MSGU_IBDB) & 447 PMCS_MSGU_IBDB_MPIINI) == 0) { 448 break; 449 } 450 drv_usecwait(1000); 451 } 452 if (pmcs_rd_msgunit(pwp, PMCS_MSGU_IBDB) & PMCS_MSGU_IBDB_MPIINI) { 453 return (-1); 454 } 455 drv_usecwait(500000); 456 457 /* 458 * Check to make sure we got to INIT state. 459 */ 460 if (PMCS_MPI_S(pmcs_rd_gst_tbl(pwp, PMCS_GST_BASE)) != 461 PMCS_MPI_STATE_INIT) { 462 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 463 "%s: MPI launch failed (GST 0x%x DBCLR 0x%x)", __func__, 464 pmcs_rd_gst_tbl(pwp, PMCS_GST_BASE), 465 pmcs_rd_msgunit(pwp, PMCS_MSGU_IBDB_CLEAR)); 466 return (-1); 467 } 468 return (0); 469 } 470 471 /* 472 * Stop the Message Passing protocol with the PMC chip. 473 */ 474 int 475 pmcs_stop_mpi(pmcs_hw_t *pwp) 476 { 477 int i; 478 479 for (i = 0; i < pwp->max_iq; i++) { 480 pmcs_wr_iqc_tbl(pwp, PMCS_IQC_PARMX(i), 0); 481 pmcs_wr_iqc_tbl(pwp, PMCS_IQBAHX(i), 0); 482 pmcs_wr_iqc_tbl(pwp, PMCS_IQBALX(i), 0); 483 pmcs_wr_iqc_tbl(pwp, PMCS_IQCIBAHX(i), 0); 484 pmcs_wr_iqc_tbl(pwp, PMCS_IQCIBALX(i), 0); 485 } 486 for (i = 0; i < pwp->max_oq; i++) { 487 pmcs_wr_oqc_tbl(pwp, PMCS_OQC_PARMX(i), 0); 488 pmcs_wr_oqc_tbl(pwp, PMCS_OQBAHX(i), 0); 489 pmcs_wr_oqc_tbl(pwp, PMCS_OQBALX(i), 0); 490 pmcs_wr_oqc_tbl(pwp, PMCS_OQPIBAHX(i), 0); 491 pmcs_wr_oqc_tbl(pwp, PMCS_OQPIBALX(i), 0); 492 pmcs_wr_oqc_tbl(pwp, PMCS_OQIPARM(i), 0); 493 pmcs_wr_oqc_tbl(pwp, PMCS_OQDICX(i), 0); 494 } 495 pmcs_wr_mpi_tbl(pwp, PMCS_MPI_FERR, 0); 496 pmcs_wr_msgunit(pwp, PMCS_MSGU_IBDB, PMCS_MSGU_IBDB_MPICTU); 497 for (i = 0; i < 2000; i++) { 498 if ((pmcs_rd_msgunit(pwp, PMCS_MSGU_IBDB) & 499 PMCS_MSGU_IBDB_MPICTU) == 0) { 500 break; 501 } 502 drv_usecwait(1000); 503 } 504 if (pmcs_rd_msgunit(pwp, PMCS_MSGU_IBDB) & PMCS_MSGU_IBDB_MPICTU) { 505 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 506 "%s: MPI stop failed", __func__); 507 return (-1); 508 } 509 return (0); 510 } 511 512 /* 513 * Do a sequence of ECHO messages to test for MPI functionality, 514 * all inbound and outbound queue functionality and interrupts. 515 */ 516 int 517 pmcs_echo_test(pmcs_hw_t *pwp) 518 { 519 echo_test_t fred; 520 struct pmcwork *pwrk; 521 uint32_t *msg, count; 522 int iqe = 0, iqo = 0, result, rval = 0; 523 int iterations; 524 hrtime_t echo_start, echo_end, echo_total; 525 526 ASSERT(pwp->max_cmd > 0); 527 528 /* 529 * We want iterations to be max_cmd * 3 to ensure that we run the 530 * echo test enough times to iterate through every inbound queue 531 * at least twice. 532 */ 533 iterations = pwp->max_cmd * 3; 534 535 echo_total = 0; 536 count = 0; 537 538 while (count < iterations) { 539 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, NULL); 540 if (pwrk == NULL) { 541 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, 542 pmcs_nowrk, __func__); 543 rval = -1; 544 break; 545 } 546 547 mutex_enter(&pwp->iqp_lock[iqe]); 548 msg = GET_IQ_ENTRY(pwp, iqe); 549 if (msg == NULL) { 550 mutex_exit(&pwp->iqp_lock[iqe]); 551 pmcs_pwork(pwp, pwrk); 552 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, 553 pmcs_nomsg, __func__); 554 rval = -1; 555 break; 556 } 557 558 bzero(msg, PMCS_QENTRY_SIZE); 559 560 if (iqe == PMCS_IQ_OTHER) { 561 /* This is on the high priority queue */ 562 msg[0] = LE_32(PMCS_HIPRI(pwp, iqo, PMCIN_ECHO)); 563 } else { 564 msg[0] = LE_32(PMCS_IOMB_IN_SAS(iqo, PMCIN_ECHO)); 565 } 566 msg[1] = LE_32(pwrk->htag); 567 fred.signature = 0xdeadbeef; 568 fred.count = count; 569 fred.ptr = &count; 570 (void) memcpy(&msg[2], &fred, sizeof (fred)); 571 pwrk->state = PMCS_WORK_STATE_ONCHIP; 572 573 INC_IQ_ENTRY(pwp, iqe); 574 575 echo_start = gethrtime(); 576 DTRACE_PROBE2(pmcs__echo__test__wait__start, 577 hrtime_t, echo_start, uint32_t, pwrk->htag); 578 579 if (++iqe == PMCS_NIQ) { 580 iqe = 0; 581 } 582 if (++iqo == PMCS_NOQ) { 583 iqo = 0; 584 } 585 586 WAIT_FOR(pwrk, 250, result); 587 pmcs_pwork(pwp, pwrk); 588 589 echo_end = gethrtime(); 590 DTRACE_PROBE2(pmcs__echo__test__wait__end, 591 hrtime_t, echo_end, int, result); 592 echo_total += (echo_end - echo_start); 593 594 if (result) { 595 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 596 "%s: command timed out on echo test #%d", 597 __func__, count); 598 rval = -1; 599 break; 600 } 601 } 602 603 /* 604 * The intr_threshold is adjusted by PMCS_INTR_THRESHOLD in order to 605 * remove the overhead of things like the delay in getting signaled 606 * for completion. 607 */ 608 if (echo_total != 0) { 609 pwp->io_intr_coal.intr_latency = 610 (echo_total / iterations) / 2; 611 pwp->io_intr_coal.intr_threshold = 612 PMCS_INTR_THRESHOLD(PMCS_QUANTUM_TIME_USECS * 1000 / 613 pwp->io_intr_coal.intr_latency); 614 } 615 616 return (rval); 617 } 618 619 /* 620 * Start the (real) phys 621 */ 622 int 623 pmcs_start_phy(pmcs_hw_t *pwp, int phynum, int linkmode, int speed) 624 { 625 int result; 626 uint32_t *msg; 627 struct pmcwork *pwrk; 628 pmcs_phy_t *pptr; 629 sas_identify_af_t sap; 630 631 mutex_enter(&pwp->lock); 632 pptr = pwp->root_phys + phynum; 633 if (pptr == NULL) { 634 mutex_exit(&pwp->lock); 635 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 636 "%s: cannot find port %d", __func__, phynum); 637 return (0); 638 } 639 640 pmcs_lock_phy(pptr); 641 mutex_exit(&pwp->lock); 642 643 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr); 644 if (pwrk == NULL) { 645 pmcs_unlock_phy(pptr); 646 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nowrk, __func__); 647 return (-1); 648 } 649 650 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 651 msg = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 652 653 if (msg == NULL) { 654 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 655 pmcs_unlock_phy(pptr); 656 pmcs_pwork(pwp, pwrk); 657 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nomsg, __func__); 658 return (-1); 659 } 660 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_EVENTS, PMCIN_PHY_START)); 661 msg[1] = LE_32(pwrk->htag); 662 msg[2] = LE_32(linkmode | speed | phynum); 663 bzero(&sap, sizeof (sap)); 664 sap.device_type = SAS_IF_DTYPE_ENDPOINT; 665 sap.ssp_ini_port = 1; 666 667 if (pwp->separate_ports) { 668 pmcs_wwn2barray(pwp->sas_wwns[phynum], sap.sas_address); 669 } else { 670 pmcs_wwn2barray(pwp->sas_wwns[0], sap.sas_address); 671 } 672 673 ASSERT(phynum < SAS2_PHYNUM_MAX); 674 sap.phy_identifier = phynum & SAS2_PHYNUM_MASK; 675 (void) memcpy(&msg[3], &sap, sizeof (sas_identify_af_t)); 676 pwrk->state = PMCS_WORK_STATE_ONCHIP; 677 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 678 679 pptr->state.prog_min_rate = (lowbit((ulong_t)speed) - 1); 680 pptr->state.prog_max_rate = (highbit((ulong_t)speed) - 1); 681 pptr->state.hw_min_rate = PMCS_HW_MIN_LINK_RATE; 682 pptr->state.hw_max_rate = PMCS_HW_MAX_LINK_RATE; 683 684 pmcs_unlock_phy(pptr); 685 WAIT_FOR(pwrk, 1000, result); 686 pmcs_pwork(pwp, pwrk); 687 688 if (result) { 689 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, pmcs_timeo, __func__); 690 } else { 691 mutex_enter(&pwp->lock); 692 pwp->phys_started |= (1 << phynum); 693 mutex_exit(&pwp->lock); 694 } 695 696 return (0); 697 } 698 699 int 700 pmcs_start_phys(pmcs_hw_t *pwp) 701 { 702 int i, rval; 703 704 for (i = 0; i < pwp->nphy; i++) { 705 if ((pwp->phyid_block_mask & (1 << i)) == 0) { 706 if (pmcs_start_phy(pwp, i, 707 (pwp->phymode << PHY_MODE_SHIFT), 708 pwp->physpeed << PHY_LINK_SHIFT)) { 709 return (-1); 710 } 711 if (pmcs_clear_diag_counters(pwp, i)) { 712 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 713 "%s: failed to reset counters on PHY (%d)", 714 __func__, i); 715 } 716 } 717 } 718 719 rval = pmcs_get_time_stamp(pwp, &pwp->fw_timestamp, &pwp->hrtimestamp); 720 if (rval) { 721 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 722 "%s: Failed to obtain firmware timestamp", __func__); 723 } else { 724 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 725 "Firmware timestamp: 0x%" PRIx64, pwp->fw_timestamp); 726 } 727 728 return (0); 729 } 730 731 /* 732 * Called with PHY locked 733 */ 734 int 735 pmcs_reset_phy(pmcs_hw_t *pwp, pmcs_phy_t *pptr, uint8_t type) 736 { 737 uint32_t *msg; 738 uint32_t iomb[(PMCS_QENTRY_SIZE << 1) >> 2]; 739 const char *mbar; 740 uint32_t amt; 741 uint32_t pdevid; 742 uint32_t stsoff; 743 uint32_t status; 744 int result, level, phynum; 745 struct pmcwork *pwrk; 746 pmcs_iport_t *iport; 747 uint32_t htag; 748 749 ASSERT(mutex_owned(&pptr->phy_lock)); 750 751 bzero(iomb, PMCS_QENTRY_SIZE); 752 phynum = pptr->phynum; 753 level = pptr->level; 754 if (level > 0) { 755 pdevid = pptr->parent->device_id; 756 } else if ((level == 0) && (pptr->dtype == EXPANDER)) { 757 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, pptr->target, 758 "%s: Not resetting HBA PHY @ %s", __func__, pptr->path); 759 return (0); 760 } 761 762 if (!pptr->iport || !pptr->valid_device_id) { 763 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, pptr->target, 764 "%s: Can't reach PHY %s", __func__, pptr->path); 765 return (0); 766 } 767 768 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr); 769 770 if (pwrk == NULL) { 771 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nowrk, __func__); 772 return (ENOMEM); 773 } 774 775 pwrk->arg = iomb; 776 777 /* 778 * If level > 0, we need to issue an SMP_REQUEST with a PHY_CONTROL 779 * function to do either a link reset or hard reset. If level == 0, 780 * then we do a LOCAL_PHY_CONTROL IOMB to do link/hard reset to the 781 * root (local) PHY 782 */ 783 if (level) { 784 stsoff = 2; 785 iomb[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 786 PMCIN_SMP_REQUEST)); 787 iomb[1] = LE_32(pwrk->htag); 788 iomb[2] = LE_32(pdevid); 789 iomb[3] = LE_32(40 << SMP_REQUEST_LENGTH_SHIFT); 790 /* 791 * Send SMP PHY CONTROL/HARD or LINK RESET 792 */ 793 iomb[4] = BE_32(0x40910000); 794 iomb[5] = 0; 795 796 if (type == PMCS_PHYOP_HARD_RESET) { 797 mbar = "SMP PHY CONTROL/HARD RESET"; 798 iomb[6] = BE_32((phynum << 16) | 799 (PMCS_PHYOP_HARD_RESET << 8)); 800 } else { 801 mbar = "SMP PHY CONTROL/LINK RESET"; 802 iomb[6] = BE_32((phynum << 16) | 803 (PMCS_PHYOP_LINK_RESET << 8)); 804 } 805 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 806 "%s: sending %s to %s for phy 0x%x", 807 __func__, mbar, pptr->parent->path, pptr->phynum); 808 amt = 7; 809 } else { 810 /* 811 * Unlike most other Outbound messages, status for 812 * a local phy operation is in DWORD 3. 813 */ 814 stsoff = 3; 815 iomb[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 816 PMCIN_LOCAL_PHY_CONTROL)); 817 iomb[1] = LE_32(pwrk->htag); 818 if (type == PMCS_PHYOP_LINK_RESET) { 819 mbar = "LOCAL PHY LINK RESET"; 820 iomb[2] = LE_32((PMCS_PHYOP_LINK_RESET << 8) | phynum); 821 } else { 822 mbar = "LOCAL PHY HARD RESET"; 823 iomb[2] = LE_32((PMCS_PHYOP_HARD_RESET << 8) | phynum); 824 } 825 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 826 "%s: sending %s to %s", __func__, mbar, pptr->path); 827 amt = 3; 828 } 829 830 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 831 msg = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 832 if (msg == NULL) { 833 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 834 pmcs_pwork(pwp, pwrk); 835 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nomsg, __func__); 836 return (ENOMEM); 837 } 838 COPY_MESSAGE(msg, iomb, amt); 839 htag = pwrk->htag; 840 841 pmcs_hold_iport(pptr->iport); 842 iport = pptr->iport; 843 pmcs_smp_acquire(iport); 844 pwrk->state = PMCS_WORK_STATE_ONCHIP; 845 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 846 pmcs_unlock_phy(pptr); 847 WAIT_FOR(pwrk, 1000, result); 848 pmcs_pwork(pwp, pwrk); 849 pmcs_smp_release(iport); 850 pmcs_rele_iport(iport); 851 pmcs_lock_phy(pptr); 852 853 if (result) { 854 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, pmcs_timeo, __func__); 855 856 if (pmcs_abort(pwp, pptr, htag, 0, 0)) { 857 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 858 "%s: Unable to issue SMP abort for htag 0x%08x", 859 __func__, htag); 860 } else { 861 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 862 "%s: Issuing SMP ABORT for htag 0x%08x", 863 __func__, htag); 864 } 865 return (EIO); 866 } 867 status = LE_32(iomb[stsoff]); 868 869 if (status != PMCOUT_STATUS_OK) { 870 char buf[32]; 871 const char *es = pmcs_status_str(status); 872 if (es == NULL) { 873 (void) snprintf(buf, sizeof (buf), "Status 0x%x", 874 status); 875 es = buf; 876 } 877 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 878 "%s: %s action returned %s for %s", __func__, mbar, es, 879 pptr->path); 880 return (status); 881 } 882 883 return (0); 884 } 885 886 /* 887 * Stop the (real) phys. No PHY or softstate locks are required as this only 888 * happens during detach. 889 */ 890 void 891 pmcs_stop_phy(pmcs_hw_t *pwp, int phynum) 892 { 893 int result; 894 pmcs_phy_t *pptr; 895 uint32_t *msg; 896 struct pmcwork *pwrk; 897 898 pptr = pwp->root_phys + phynum; 899 if (pptr == NULL) { 900 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 901 "%s: unable to find port %d", __func__, phynum); 902 return; 903 } 904 905 if (pwp->phys_started & (1 << phynum)) { 906 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr); 907 908 if (pwrk == NULL) { 909 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, 910 pmcs_nowrk, __func__); 911 return; 912 } 913 914 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 915 msg = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 916 917 if (msg == NULL) { 918 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 919 pmcs_pwork(pwp, pwrk); 920 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, 921 pmcs_nomsg, __func__); 922 return; 923 } 924 925 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_EVENTS, PMCIN_PHY_STOP)); 926 msg[1] = LE_32(pwrk->htag); 927 msg[2] = LE_32(phynum); 928 pwrk->state = PMCS_WORK_STATE_ONCHIP; 929 /* 930 * Make this unconfigured now. 931 */ 932 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 933 WAIT_FOR(pwrk, 1000, result); 934 pmcs_pwork(pwp, pwrk); 935 if (result) { 936 pmcs_prt(pwp, PMCS_PRT_DEBUG, 937 pptr, NULL, pmcs_timeo, __func__); 938 } 939 940 pwp->phys_started &= ~(1 << phynum); 941 } 942 943 pptr->configured = 0; 944 } 945 946 /* 947 * No locks should be required as this is only called during detach 948 */ 949 void 950 pmcs_stop_phys(pmcs_hw_t *pwp) 951 { 952 int i; 953 for (i = 0; i < pwp->nphy; i++) { 954 if ((pwp->phyid_block_mask & (1 << i)) == 0) { 955 pmcs_stop_phy(pwp, i); 956 } 957 } 958 } 959 960 /* 961 * Run SAS_DIAG_EXECUTE with cmd and cmd_desc passed. 962 * ERR_CNT_RESET: return status of cmd 963 * DIAG_REPORT_GET: return value of the counter 964 */ 965 int 966 pmcs_sas_diag_execute(pmcs_hw_t *pwp, uint32_t cmd, uint32_t cmd_desc, 967 uint8_t phynum) 968 { 969 uint32_t htag, *ptr, status, msg[PMCS_MSG_SIZE << 1]; 970 int result; 971 struct pmcwork *pwrk; 972 973 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, NULL); 974 if (pwrk == NULL) { 975 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, pmcs_nowrk, __func__); 976 return (DDI_FAILURE); 977 } 978 pwrk->arg = msg; 979 htag = pwrk->htag; 980 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_EVENTS, PMCIN_SAS_DIAG_EXECUTE)); 981 msg[1] = LE_32(htag); 982 msg[2] = LE_32((cmd << PMCS_DIAG_CMD_SHIFT) | 983 (cmd_desc << PMCS_DIAG_CMD_DESC_SHIFT) | phynum); 984 985 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 986 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 987 if (ptr == NULL) { 988 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 989 pmcs_pwork(pwp, pwrk); 990 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, pmcs_nomsg, __func__); 991 return (DDI_FAILURE); 992 } 993 COPY_MESSAGE(ptr, msg, 3); 994 pwrk->state = PMCS_WORK_STATE_ONCHIP; 995 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 996 997 WAIT_FOR(pwrk, 1000, result); 998 pmcs_pwork(pwp, pwrk); 999 if (result) { 1000 pmcs_timed_out(pwp, htag, __func__); 1001 return (DDI_FAILURE); 1002 } 1003 1004 status = LE_32(msg[3]); 1005 1006 /* Return for counter reset */ 1007 if (cmd == PMCS_ERR_CNT_RESET) 1008 return (status); 1009 1010 /* Return for counter value */ 1011 if (status) { 1012 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1013 "%s: failed, status (0x%x)", __func__, status); 1014 return (DDI_FAILURE); 1015 } 1016 return (LE_32(msg[4])); 1017 } 1018 1019 /* Get the current value of the counter for desc on phynum and return it. */ 1020 int 1021 pmcs_get_diag_report(pmcs_hw_t *pwp, uint32_t desc, uint8_t phynum) 1022 { 1023 return (pmcs_sas_diag_execute(pwp, PMCS_DIAG_REPORT_GET, desc, phynum)); 1024 } 1025 1026 /* Clear all of the counters for phynum. Returns the status of the command. */ 1027 int 1028 pmcs_clear_diag_counters(pmcs_hw_t *pwp, uint8_t phynum) 1029 { 1030 uint32_t cmd = PMCS_ERR_CNT_RESET; 1031 uint32_t cmd_desc; 1032 1033 cmd_desc = PMCS_INVALID_DWORD_CNT; 1034 if (pmcs_sas_diag_execute(pwp, cmd, cmd_desc, phynum)) 1035 return (DDI_FAILURE); 1036 1037 cmd_desc = PMCS_DISPARITY_ERR_CNT; 1038 if (pmcs_sas_diag_execute(pwp, cmd, cmd_desc, phynum)) 1039 return (DDI_FAILURE); 1040 1041 cmd_desc = PMCS_LOST_DWORD_SYNC_CNT; 1042 if (pmcs_sas_diag_execute(pwp, cmd, cmd_desc, phynum)) 1043 return (DDI_FAILURE); 1044 1045 cmd_desc = PMCS_RESET_FAILED_CNT; 1046 if (pmcs_sas_diag_execute(pwp, cmd, cmd_desc, phynum)) 1047 return (DDI_FAILURE); 1048 1049 return (DDI_SUCCESS); 1050 } 1051 1052 /* 1053 * Get firmware timestamp 1054 */ 1055 static int 1056 pmcs_get_time_stamp(pmcs_hw_t *pwp, uint64_t *fw_ts, hrtime_t *sys_hr_ts) 1057 { 1058 uint32_t htag, *ptr, msg[PMCS_MSG_SIZE << 1]; 1059 int result; 1060 struct pmcwork *pwrk; 1061 1062 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, NULL); 1063 if (pwrk == NULL) { 1064 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, pmcs_nowrk, __func__); 1065 return (-1); 1066 } 1067 pwrk->arg = msg; 1068 htag = pwrk->htag; 1069 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_EVENTS, PMCIN_GET_TIME_STAMP)); 1070 msg[1] = LE_32(pwrk->htag); 1071 1072 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 1073 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 1074 if (ptr == NULL) { 1075 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 1076 pmcs_pwork(pwp, pwrk); 1077 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, pmcs_nomsg, __func__); 1078 return (-1); 1079 } 1080 COPY_MESSAGE(ptr, msg, 2); 1081 pwrk->state = PMCS_WORK_STATE_ONCHIP; 1082 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 1083 1084 WAIT_FOR(pwrk, 1000, result); 1085 pmcs_pwork(pwp, pwrk); 1086 if (result) { 1087 pmcs_timed_out(pwp, htag, __func__); 1088 return (-1); 1089 } 1090 1091 mutex_enter(&pmcs_trace_lock); 1092 *sys_hr_ts = gethrtime(); 1093 gethrestime(&pwp->sys_timestamp); 1094 *fw_ts = LE_32(msg[2]) | (((uint64_t)LE_32(msg[3])) << 32); 1095 mutex_exit(&pmcs_trace_lock); 1096 return (0); 1097 } 1098 1099 /* 1100 * Dump all pertinent registers 1101 */ 1102 1103 void 1104 pmcs_register_dump(pmcs_hw_t *pwp) 1105 { 1106 int i; 1107 uint32_t val; 1108 1109 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "pmcs%d: Register dump start", 1110 ddi_get_instance(pwp->dip)); 1111 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 1112 "OBDB (intr): 0x%08x (mask): 0x%08x (clear): 0x%08x", 1113 pmcs_rd_msgunit(pwp, PMCS_MSGU_OBDB), 1114 pmcs_rd_msgunit(pwp, PMCS_MSGU_OBDB_MASK), 1115 pmcs_rd_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR)); 1116 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "SCRATCH0: 0x%08x", 1117 pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH0)); 1118 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "SCRATCH1: 0x%08x", 1119 pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH1)); 1120 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "SCRATCH2: 0x%08x", 1121 pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH2)); 1122 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "SCRATCH3: 0x%08x", 1123 pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH3)); 1124 for (i = 0; i < PMCS_NIQ; i++) { 1125 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "IQ %d: CI %u PI %u", 1126 i, pmcs_rd_iqci(pwp, i), pmcs_rd_iqpi(pwp, i)); 1127 } 1128 for (i = 0; i < PMCS_NOQ; i++) { 1129 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "OQ %d: CI %u PI %u", 1130 i, pmcs_rd_oqci(pwp, i), pmcs_rd_oqpi(pwp, i)); 1131 } 1132 val = pmcs_rd_gst_tbl(pwp, PMCS_GST_BASE); 1133 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 1134 "GST TABLE BASE: 0x%08x (STATE=0x%x QF=%d GSTLEN=%d HMI_ERR=0x%x)", 1135 val, PMCS_MPI_S(val), PMCS_QF(val), PMCS_GSTLEN(val) * 4, 1136 PMCS_HMI_ERR(val)); 1137 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "GST TABLE IQFRZ0: 0x%08x", 1138 pmcs_rd_gst_tbl(pwp, PMCS_GST_IQFRZ0)); 1139 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "GST TABLE IQFRZ1: 0x%08x", 1140 pmcs_rd_gst_tbl(pwp, PMCS_GST_IQFRZ1)); 1141 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "GST TABLE MSGU TICK: 0x%08x", 1142 pmcs_rd_gst_tbl(pwp, PMCS_GST_MSGU_TICK)); 1143 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "GST TABLE IOP TICK: 0x%08x", 1144 pmcs_rd_gst_tbl(pwp, PMCS_GST_IOP_TICK)); 1145 for (i = 0; i < pwp->nphy; i++) { 1146 uint32_t rerrf, pinfo, started = 0, link = 0; 1147 pinfo = pmcs_rd_gst_tbl(pwp, PMCS_GST_PHY_INFO(i)); 1148 if (pinfo & 1) { 1149 started = 1; 1150 link = pinfo & 2; 1151 } 1152 rerrf = pmcs_rd_gst_tbl(pwp, PMCS_GST_RERR_INFO(i)); 1153 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 1154 "GST TABLE PHY%d STARTED=%d LINK=%d RERR=0x%08x", 1155 i, started, link, rerrf); 1156 } 1157 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "pmcs%d: Register dump end", 1158 ddi_get_instance(pwp->dip)); 1159 } 1160 1161 /* 1162 * Handle SATA Abort and other error processing 1163 */ 1164 int 1165 pmcs_abort_handler(pmcs_hw_t *pwp) 1166 { 1167 pmcs_phy_t *pptr, *pnext, *pnext_uplevel[PMCS_MAX_XPND]; 1168 pmcs_xscsi_t *tgt; 1169 int r, level = 0; 1170 1171 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s", __func__); 1172 1173 mutex_enter(&pwp->lock); 1174 pptr = pwp->root_phys; 1175 mutex_exit(&pwp->lock); 1176 1177 while (pptr) { 1178 /* 1179 * XXX: Need to make sure this doesn't happen 1180 * XXX: when non-NCQ commands are running. 1181 */ 1182 pmcs_lock_phy(pptr); 1183 if (pptr->need_rl_ext) { 1184 ASSERT(pptr->dtype == SATA); 1185 if (pmcs_acquire_scratch(pwp, B_FALSE)) { 1186 goto next_phy; 1187 } 1188 r = pmcs_sata_abort_ncq(pwp, pptr); 1189 pmcs_release_scratch(pwp); 1190 if (r == ENOMEM) { 1191 goto next_phy; 1192 } 1193 if (r) { 1194 r = pmcs_reset_phy(pwp, pptr, 1195 PMCS_PHYOP_LINK_RESET); 1196 if (r == ENOMEM) { 1197 goto next_phy; 1198 } 1199 /* what if other failures happened? */ 1200 pptr->abort_pending = 1; 1201 pptr->abort_sent = 0; 1202 } 1203 } 1204 if (pptr->abort_pending == 0 || pptr->abort_sent) { 1205 goto next_phy; 1206 } 1207 pptr->abort_pending = 0; 1208 if (pmcs_abort(pwp, pptr, pptr->device_id, 1, 1) == ENOMEM) { 1209 pptr->abort_pending = 1; 1210 goto next_phy; 1211 } 1212 pptr->abort_sent = 1; 1213 1214 /* 1215 * If the iport is no longer active, flush the queues 1216 */ 1217 if ((pptr->iport == NULL) || 1218 (pptr->iport->ua_state != UA_ACTIVE)) { 1219 tgt = pptr->target; 1220 if (tgt != NULL) { 1221 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, tgt, 1222 "%s: Clearing target 0x%p, inactive iport", 1223 __func__, (void *) tgt); 1224 mutex_enter(&tgt->statlock); 1225 pmcs_clear_xp(pwp, tgt); 1226 mutex_exit(&tgt->statlock); 1227 } 1228 } 1229 1230 next_phy: 1231 if (pptr->children) { 1232 pnext = pptr->children; 1233 pnext_uplevel[level++] = pptr->sibling; 1234 } else { 1235 pnext = pptr->sibling; 1236 while ((pnext == NULL) && (level > 0)) { 1237 pnext = pnext_uplevel[--level]; 1238 } 1239 } 1240 1241 pmcs_unlock_phy(pptr); 1242 pptr = pnext; 1243 } 1244 1245 return (0); 1246 } 1247 1248 /* 1249 * Register a device (get a device handle for it). 1250 * Called with PHY lock held. 1251 */ 1252 int 1253 pmcs_register_device(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 1254 { 1255 struct pmcwork *pwrk; 1256 int result = 0; 1257 uint32_t *msg; 1258 uint32_t tmp, status; 1259 uint32_t iomb[(PMCS_QENTRY_SIZE << 1) >> 2]; 1260 1261 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 1262 msg = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 1263 1264 if (msg == NULL || 1265 (pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr)) == NULL) { 1266 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 1267 result = ENOMEM; 1268 goto out; 1269 } 1270 1271 pwrk->arg = iomb; 1272 pwrk->dtype = pptr->dtype; 1273 1274 msg[1] = LE_32(pwrk->htag); 1275 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, PMCIN_REGISTER_DEVICE)); 1276 tmp = PMCS_DEVREG_TLR | 1277 (pptr->link_rate << PMCS_DEVREG_LINK_RATE_SHIFT); 1278 if (IS_ROOT_PHY(pptr)) { 1279 msg[2] = LE_32(pptr->portid | 1280 (pptr->phynum << PMCS_PHYID_SHIFT)); 1281 } else { 1282 msg[2] = LE_32(pptr->portid); 1283 } 1284 if (pptr->dtype == SATA) { 1285 if (IS_ROOT_PHY(pptr)) { 1286 tmp |= PMCS_DEVREG_TYPE_SATA_DIRECT; 1287 } else { 1288 tmp |= PMCS_DEVREG_TYPE_SATA; 1289 } 1290 } else { 1291 tmp |= PMCS_DEVREG_TYPE_SAS; 1292 } 1293 msg[3] = LE_32(tmp); 1294 msg[4] = LE_32(PMCS_DEVREG_IT_NEXUS_TIMEOUT); 1295 (void) memcpy(&msg[5], pptr->sas_address, 8); 1296 1297 CLEAN_MESSAGE(msg, 7); 1298 pwrk->state = PMCS_WORK_STATE_ONCHIP; 1299 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 1300 1301 pmcs_unlock_phy(pptr); 1302 WAIT_FOR(pwrk, 250, result); 1303 pmcs_pwork(pwp, pwrk); 1304 pmcs_lock_phy(pptr); 1305 1306 if (result) { 1307 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, pmcs_timeo, __func__); 1308 result = ETIMEDOUT; 1309 goto out; 1310 } 1311 status = LE_32(iomb[2]); 1312 tmp = LE_32(iomb[3]); 1313 switch (status) { 1314 case PMCS_DEVREG_OK: 1315 case PMCS_DEVREG_DEVICE_ALREADY_REGISTERED: 1316 case PMCS_DEVREG_PHY_ALREADY_REGISTERED: 1317 if (pmcs_validate_devid(pwp->root_phys, pptr, tmp) == B_FALSE) { 1318 result = EEXIST; 1319 goto out; 1320 } else if (status != PMCS_DEVREG_OK) { 1321 if (tmp == 0xffffffff) { /* F/W bug */ 1322 pmcs_prt(pwp, PMCS_PRT_INFO, pptr, NULL, 1323 "%s: phy %s already has bogus devid 0x%x", 1324 __func__, pptr->path, tmp); 1325 result = EIO; 1326 goto out; 1327 } else { 1328 pmcs_prt(pwp, PMCS_PRT_INFO, pptr, NULL, 1329 "%s: phy %s already has a device id 0x%x", 1330 __func__, pptr->path, tmp); 1331 } 1332 } 1333 break; 1334 default: 1335 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 1336 "%s: status 0x%x when trying to register device %s", 1337 __func__, status, pptr->path); 1338 result = EIO; 1339 goto out; 1340 } 1341 pptr->device_id = tmp; 1342 pptr->valid_device_id = 1; 1343 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, "Phy %s/" SAS_ADDR_FMT 1344 " registered with device_id 0x%x (portid %d)", pptr->path, 1345 SAS_ADDR_PRT(pptr->sas_address), tmp, pptr->portid); 1346 out: 1347 return (result); 1348 } 1349 1350 /* 1351 * Deregister a device (remove a device handle). 1352 * Called with PHY locked. 1353 */ 1354 void 1355 pmcs_deregister_device(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 1356 { 1357 struct pmcwork *pwrk; 1358 uint32_t msg[PMCS_MSG_SIZE], *ptr, status; 1359 uint32_t iomb[(PMCS_QENTRY_SIZE << 1) >> 2]; 1360 int result; 1361 1362 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr); 1363 if (pwrk == NULL) { 1364 return; 1365 } 1366 1367 pwrk->arg = iomb; 1368 pwrk->dtype = pptr->dtype; 1369 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 1370 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 1371 if (ptr == NULL) { 1372 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 1373 pmcs_pwork(pwp, pwrk); 1374 return; 1375 } 1376 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 1377 PMCIN_DEREGISTER_DEVICE_HANDLE)); 1378 msg[1] = LE_32(pwrk->htag); 1379 msg[2] = LE_32(pptr->device_id); 1380 pwrk->state = PMCS_WORK_STATE_ONCHIP; 1381 COPY_MESSAGE(ptr, msg, 3); 1382 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 1383 1384 pmcs_unlock_phy(pptr); 1385 WAIT_FOR(pwrk, 250, result); 1386 pmcs_pwork(pwp, pwrk); 1387 pmcs_lock_phy(pptr); 1388 1389 if (result) { 1390 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, pmcs_timeo, __func__); 1391 return; 1392 } 1393 status = LE_32(iomb[2]); 1394 if (status != PMCOUT_STATUS_OK) { 1395 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 1396 "%s: status 0x%x when trying to deregister device %s", 1397 __func__, status, pptr->path); 1398 } else { 1399 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 1400 "%s: device %s deregistered", __func__, pptr->path); 1401 } 1402 1403 pptr->device_id = PMCS_INVALID_DEVICE_ID; 1404 pptr->configured = 0; 1405 pptr->deregister_wait = 0; 1406 pptr->valid_device_id = 0; 1407 } 1408 1409 /* 1410 * Deregister all registered devices. 1411 */ 1412 void 1413 pmcs_deregister_devices(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 1414 { 1415 /* 1416 * Start at the maximum level and walk back to level 0. This only 1417 * gets done during detach after all threads and timers have been 1418 * destroyed. 1419 */ 1420 while (phyp) { 1421 if (phyp->children) { 1422 pmcs_deregister_devices(pwp, phyp->children); 1423 } 1424 pmcs_lock_phy(phyp); 1425 if (phyp->valid_device_id) { 1426 pmcs_deregister_device(pwp, phyp); 1427 } 1428 pmcs_unlock_phy(phyp); 1429 phyp = phyp->sibling; 1430 } 1431 } 1432 1433 /* 1434 * Perform a 'soft' reset on the PMC chip 1435 */ 1436 int 1437 pmcs_soft_reset(pmcs_hw_t *pwp, boolean_t no_restart) 1438 { 1439 uint32_t s2, sfrbits, gsm, rapchk, wapchk, wdpchk, spc, tsmode; 1440 pmcs_phy_t *pptr; 1441 char *msg = NULL; 1442 int i; 1443 1444 /* 1445 * Disable interrupts 1446 */ 1447 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_MASK, 0xffffffff); 1448 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 0xffffffff); 1449 1450 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "%s", __func__); 1451 1452 if (pwp->locks_initted) { 1453 mutex_enter(&pwp->lock); 1454 } 1455 pwp->blocked = 1; 1456 1457 /* 1458 * Clear our softstate copies of the MSGU and IOP heartbeats. 1459 */ 1460 pwp->last_msgu_tick = pwp->last_iop_tick = 0; 1461 1462 /* 1463 * Step 1 1464 */ 1465 s2 = pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH2); 1466 if ((s2 & PMCS_MSGU_HOST_SOFT_RESET_READY) == 0) { 1467 pmcs_wr_gsm_reg(pwp, RB6_ACCESS, RB6_NMI_SIGNATURE); 1468 pmcs_wr_gsm_reg(pwp, RB6_ACCESS, RB6_NMI_SIGNATURE); 1469 for (i = 0; i < 100; i++) { 1470 s2 = pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH2) & 1471 PMCS_MSGU_HOST_SOFT_RESET_READY; 1472 if (s2) { 1473 break; 1474 } 1475 drv_usecwait(10000); 1476 } 1477 s2 = pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH2) & 1478 PMCS_MSGU_HOST_SOFT_RESET_READY; 1479 if (s2 == 0) { 1480 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1481 "%s: PMCS_MSGU_HOST_SOFT_RESET_READY never came " 1482 "ready", __func__); 1483 pmcs_register_dump(pwp); 1484 if ((pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH1) & 1485 PMCS_MSGU_CPU_SOFT_RESET_READY) == 0 || 1486 (pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH2) & 1487 PMCS_MSGU_CPU_SOFT_RESET_READY) == 0) { 1488 pwp->state = STATE_DEAD; 1489 pwp->blocked = 0; 1490 if (pwp->locks_initted) { 1491 mutex_exit(&pwp->lock); 1492 } 1493 return (-1); 1494 } 1495 } 1496 } 1497 1498 /* 1499 * Step 2 1500 */ 1501 pmcs_wr_gsm_reg(pwp, NMI_EN_VPE0_IOP, 0); 1502 drv_usecwait(10); 1503 pmcs_wr_gsm_reg(pwp, NMI_EN_VPE0_AAP1, 0); 1504 drv_usecwait(10); 1505 pmcs_wr_topunit(pwp, PMCS_EVENT_INT_ENABLE, 0); 1506 drv_usecwait(10); 1507 pmcs_wr_topunit(pwp, PMCS_EVENT_INT_STAT, 1508 pmcs_rd_topunit(pwp, PMCS_EVENT_INT_STAT)); 1509 drv_usecwait(10); 1510 pmcs_wr_topunit(pwp, PMCS_ERROR_INT_ENABLE, 0); 1511 drv_usecwait(10); 1512 pmcs_wr_topunit(pwp, PMCS_ERROR_INT_STAT, 1513 pmcs_rd_topunit(pwp, PMCS_ERROR_INT_STAT)); 1514 drv_usecwait(10); 1515 1516 sfrbits = pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH1) & 1517 PMCS_MSGU_AAP_SFR_PROGRESS; 1518 sfrbits ^= PMCS_MSGU_AAP_SFR_PROGRESS; 1519 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "PMCS_MSGU_HOST_SCRATCH0 " 1520 "%08x -> %08x", pmcs_rd_msgunit(pwp, PMCS_MSGU_HOST_SCRATCH0), 1521 HST_SFT_RESET_SIG); 1522 pmcs_wr_msgunit(pwp, PMCS_MSGU_HOST_SCRATCH0, HST_SFT_RESET_SIG); 1523 1524 /* 1525 * Step 3 1526 */ 1527 gsm = pmcs_rd_gsm_reg(pwp, 0, GSM_CFG_AND_RESET); 1528 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "GSM %08x -> %08x", gsm, 1529 gsm & ~PMCS_SOFT_RESET_BITS); 1530 pmcs_wr_gsm_reg(pwp, GSM_CFG_AND_RESET, gsm & ~PMCS_SOFT_RESET_BITS); 1531 1532 /* 1533 * Step 4 1534 */ 1535 rapchk = pmcs_rd_gsm_reg(pwp, 0, READ_ADR_PARITY_CHK_EN); 1536 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "READ_ADR_PARITY_CHK_EN " 1537 "%08x -> %08x", rapchk, 0); 1538 pmcs_wr_gsm_reg(pwp, READ_ADR_PARITY_CHK_EN, 0); 1539 wapchk = pmcs_rd_gsm_reg(pwp, 0, WRITE_ADR_PARITY_CHK_EN); 1540 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "WRITE_ADR_PARITY_CHK_EN " 1541 "%08x -> %08x", wapchk, 0); 1542 pmcs_wr_gsm_reg(pwp, WRITE_ADR_PARITY_CHK_EN, 0); 1543 wdpchk = pmcs_rd_gsm_reg(pwp, 0, WRITE_DATA_PARITY_CHK_EN); 1544 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "WRITE_DATA_PARITY_CHK_EN " 1545 "%08x -> %08x", wdpchk, 0); 1546 pmcs_wr_gsm_reg(pwp, WRITE_DATA_PARITY_CHK_EN, 0); 1547 1548 /* 1549 * Step 5 1550 */ 1551 drv_usecwait(100); 1552 1553 /* 1554 * Step 5.5 (Temporary workaround for 1.07.xx Beta) 1555 */ 1556 tsmode = pmcs_rd_gsm_reg(pwp, 0, PMCS_GPIO_TRISTATE_MODE_ADDR); 1557 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "GPIO TSMODE %08x -> %08x", 1558 tsmode, tsmode & ~(PMCS_GPIO_TSMODE_BIT0|PMCS_GPIO_TSMODE_BIT1)); 1559 pmcs_wr_gsm_reg(pwp, PMCS_GPIO_TRISTATE_MODE_ADDR, 1560 tsmode & ~(PMCS_GPIO_TSMODE_BIT0|PMCS_GPIO_TSMODE_BIT1)); 1561 drv_usecwait(10); 1562 1563 /* 1564 * Step 6 1565 */ 1566 spc = pmcs_rd_topunit(pwp, PMCS_SPC_RESET); 1567 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "SPC_RESET %08x -> %08x", 1568 spc, spc & ~(PCS_IOP_SS_RSTB|PCS_AAP1_SS_RSTB)); 1569 pmcs_wr_topunit(pwp, PMCS_SPC_RESET, 1570 spc & ~(PCS_IOP_SS_RSTB|PCS_AAP1_SS_RSTB)); 1571 drv_usecwait(10); 1572 1573 /* 1574 * Step 7 1575 */ 1576 spc = pmcs_rd_topunit(pwp, PMCS_SPC_RESET); 1577 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "SPC_RESET %08x -> %08x", 1578 spc, spc & ~(BDMA_CORE_RSTB|OSSP_RSTB)); 1579 pmcs_wr_topunit(pwp, PMCS_SPC_RESET, spc & ~(BDMA_CORE_RSTB|OSSP_RSTB)); 1580 1581 /* 1582 * Step 8 1583 */ 1584 drv_usecwait(100); 1585 1586 /* 1587 * Step 9 1588 */ 1589 spc = pmcs_rd_topunit(pwp, PMCS_SPC_RESET); 1590 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "SPC_RESET %08x -> %08x", 1591 spc, spc | (BDMA_CORE_RSTB|OSSP_RSTB)); 1592 pmcs_wr_topunit(pwp, PMCS_SPC_RESET, spc | (BDMA_CORE_RSTB|OSSP_RSTB)); 1593 1594 /* 1595 * Step 10 1596 */ 1597 drv_usecwait(100); 1598 1599 /* 1600 * Step 11 1601 */ 1602 gsm = pmcs_rd_gsm_reg(pwp, 0, GSM_CFG_AND_RESET); 1603 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "GSM %08x -> %08x", gsm, 1604 gsm | PMCS_SOFT_RESET_BITS); 1605 pmcs_wr_gsm_reg(pwp, GSM_CFG_AND_RESET, gsm | PMCS_SOFT_RESET_BITS); 1606 drv_usecwait(10); 1607 1608 /* 1609 * Step 12 1610 */ 1611 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "READ_ADR_PARITY_CHK_EN " 1612 "%08x -> %08x", pmcs_rd_gsm_reg(pwp, 0, READ_ADR_PARITY_CHK_EN), 1613 rapchk); 1614 pmcs_wr_gsm_reg(pwp, READ_ADR_PARITY_CHK_EN, rapchk); 1615 drv_usecwait(10); 1616 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "WRITE_ADR_PARITY_CHK_EN " 1617 "%08x -> %08x", pmcs_rd_gsm_reg(pwp, 0, WRITE_ADR_PARITY_CHK_EN), 1618 wapchk); 1619 pmcs_wr_gsm_reg(pwp, WRITE_ADR_PARITY_CHK_EN, wapchk); 1620 drv_usecwait(10); 1621 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "WRITE_DATA_PARITY_CHK_EN " 1622 "%08x -> %08x", pmcs_rd_gsm_reg(pwp, 0, WRITE_DATA_PARITY_CHK_EN), 1623 wapchk); 1624 pmcs_wr_gsm_reg(pwp, WRITE_DATA_PARITY_CHK_EN, wdpchk); 1625 drv_usecwait(10); 1626 1627 /* 1628 * Step 13 1629 */ 1630 spc = pmcs_rd_topunit(pwp, PMCS_SPC_RESET); 1631 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "SPC_RESET %08x -> %08x", 1632 spc, spc | (PCS_IOP_SS_RSTB|PCS_AAP1_SS_RSTB)); 1633 pmcs_wr_topunit(pwp, PMCS_SPC_RESET, 1634 spc | (PCS_IOP_SS_RSTB|PCS_AAP1_SS_RSTB)); 1635 1636 /* 1637 * Step 14 1638 */ 1639 drv_usecwait(100); 1640 1641 /* 1642 * Step 15 1643 */ 1644 for (spc = 0, i = 0; i < 1000; i++) { 1645 drv_usecwait(1000); 1646 spc = pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH1); 1647 if ((spc & PMCS_MSGU_AAP_SFR_PROGRESS) == sfrbits) { 1648 break; 1649 } 1650 } 1651 1652 if ((spc & PMCS_MSGU_AAP_SFR_PROGRESS) != sfrbits) { 1653 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1654 "SFR didn't toggle (sfr 0x%x)", spc); 1655 pwp->state = STATE_DEAD; 1656 pwp->blocked = 0; 1657 if (pwp->locks_initted) { 1658 mutex_exit(&pwp->lock); 1659 } 1660 return (-1); 1661 } 1662 1663 /* 1664 * Step 16 1665 */ 1666 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_MASK, 0xffffffff); 1667 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 0xffffffff); 1668 1669 /* 1670 * Wait for up to 5 seconds for AAP state to come either ready or error. 1671 */ 1672 for (i = 0; i < 50; i++) { 1673 spc = pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH1) & 1674 PMCS_MSGU_AAP_STATE_MASK; 1675 if (spc == PMCS_MSGU_AAP_STATE_ERROR || 1676 spc == PMCS_MSGU_AAP_STATE_READY) { 1677 break; 1678 } 1679 drv_usecwait(100000); 1680 } 1681 spc = pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH1); 1682 if ((spc & PMCS_MSGU_AAP_STATE_MASK) != PMCS_MSGU_AAP_STATE_READY) { 1683 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1684 "soft reset failed (state 0x%x)", spc); 1685 pwp->state = STATE_DEAD; 1686 pwp->blocked = 0; 1687 if (pwp->locks_initted) { 1688 mutex_exit(&pwp->lock); 1689 } 1690 return (-1); 1691 } 1692 1693 /* Clear the firmware log */ 1694 if (pwp->fwlogp) { 1695 bzero(pwp->fwlogp, PMCS_FWLOG_SIZE); 1696 } 1697 1698 /* Reset our queue indices and entries */ 1699 bzero(pwp->shadow_iqpi, sizeof (pwp->shadow_iqpi)); 1700 bzero(pwp->last_iqci, sizeof (pwp->last_iqci)); 1701 bzero(pwp->last_htag, sizeof (pwp->last_htag)); 1702 for (i = 0; i < PMCS_NIQ; i++) { 1703 if (pwp->iqp[i]) { 1704 bzero(pwp->iqp[i], PMCS_QENTRY_SIZE * pwp->ioq_depth); 1705 pmcs_wr_iqpi(pwp, i, 0); 1706 pmcs_wr_iqci(pwp, i, 0); 1707 } 1708 } 1709 for (i = 0; i < PMCS_NOQ; i++) { 1710 if (pwp->oqp[i]) { 1711 bzero(pwp->oqp[i], PMCS_QENTRY_SIZE * pwp->ioq_depth); 1712 pmcs_wr_oqpi(pwp, i, 0); 1713 pmcs_wr_oqci(pwp, i, 0); 1714 } 1715 1716 } 1717 1718 if (pwp->state == STATE_DEAD || pwp->state == STATE_UNPROBING || 1719 pwp->state == STATE_PROBING || pwp->locks_initted == 0) { 1720 pwp->blocked = 0; 1721 if (pwp->locks_initted) { 1722 mutex_exit(&pwp->lock); 1723 } 1724 return (0); 1725 } 1726 1727 /* 1728 * Return at this point if we dont need to startup. 1729 */ 1730 if (no_restart) { 1731 return (0); 1732 } 1733 1734 ASSERT(pwp->locks_initted != 0); 1735 1736 /* 1737 * Flush the target queues and clear each target's PHY 1738 */ 1739 if (pwp->targets) { 1740 for (i = 0; i < pwp->max_dev; i++) { 1741 pmcs_xscsi_t *xp = pwp->targets[i]; 1742 1743 if (xp == NULL) { 1744 continue; 1745 } 1746 1747 mutex_enter(&xp->statlock); 1748 pmcs_flush_target_queues(pwp, xp, PMCS_TGT_ALL_QUEUES); 1749 xp->phy = NULL; 1750 mutex_exit(&xp->statlock); 1751 } 1752 } 1753 1754 /* 1755 * Zero out the ports list, free non root phys, clear root phys 1756 */ 1757 bzero(pwp->ports, sizeof (pwp->ports)); 1758 pmcs_free_all_phys(pwp, pwp->root_phys); 1759 for (pptr = pwp->root_phys; pptr; pptr = pptr->sibling) { 1760 pmcs_lock_phy(pptr); 1761 pmcs_clear_phy(pwp, pptr); 1762 pptr->target = NULL; 1763 pmcs_unlock_phy(pptr); 1764 } 1765 1766 /* 1767 * Restore Interrupt Mask 1768 */ 1769 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_MASK, pwp->intr_mask); 1770 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 0xffffffff); 1771 1772 pwp->mpi_table_setup = 0; 1773 mutex_exit(&pwp->lock); 1774 1775 /* 1776 * Set up MPI again. 1777 */ 1778 if (pmcs_setup(pwp)) { 1779 msg = "unable to setup MPI tables again"; 1780 goto fail_restart; 1781 } 1782 pmcs_report_fwversion(pwp); 1783 1784 /* 1785 * Restart MPI 1786 */ 1787 if (pmcs_start_mpi(pwp)) { 1788 msg = "unable to restart MPI again"; 1789 goto fail_restart; 1790 } 1791 1792 mutex_enter(&pwp->lock); 1793 SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES); 1794 mutex_exit(&pwp->lock); 1795 1796 /* 1797 * Run any completions 1798 */ 1799 PMCS_CQ_RUN(pwp); 1800 1801 /* 1802 * Delay 1803 */ 1804 drv_usecwait(1000000); 1805 return (0); 1806 1807 fail_restart: 1808 mutex_enter(&pwp->lock); 1809 pwp->state = STATE_DEAD; 1810 mutex_exit(&pwp->lock); 1811 pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, 1812 "%s: Failed: %s", __func__, msg); 1813 return (-1); 1814 } 1815 1816 1817 /* 1818 * Perform a 'hot' reset, which will soft reset the chip and 1819 * restore the state back to pre-reset context. Called with pwp 1820 * lock held. 1821 */ 1822 int 1823 pmcs_hot_reset(pmcs_hw_t *pwp) 1824 { 1825 pmcs_iport_t *iport; 1826 1827 ASSERT(mutex_owned(&pwp->lock)); 1828 pwp->state = STATE_IN_RESET; 1829 1830 /* 1831 * For any iports on this HBA, report empty target sets and 1832 * then tear them down. 1833 */ 1834 rw_enter(&pwp->iports_lock, RW_READER); 1835 for (iport = list_head(&pwp->iports); iport != NULL; 1836 iport = list_next(&pwp->iports, iport)) { 1837 mutex_enter(&iport->lock); 1838 (void) scsi_hba_tgtmap_set_begin(iport->iss_tgtmap); 1839 (void) scsi_hba_tgtmap_set_end(iport->iss_tgtmap, 0); 1840 pmcs_iport_teardown_phys(iport); 1841 mutex_exit(&iport->lock); 1842 } 1843 rw_exit(&pwp->iports_lock); 1844 1845 /* Grab a register dump, in the event that reset fails */ 1846 pmcs_register_dump_int(pwp); 1847 mutex_exit(&pwp->lock); 1848 1849 /* Ensure discovery is not running before we proceed */ 1850 mutex_enter(&pwp->config_lock); 1851 while (pwp->configuring) { 1852 cv_wait(&pwp->config_cv, &pwp->config_lock); 1853 } 1854 mutex_exit(&pwp->config_lock); 1855 1856 /* Issue soft reset and clean up related softstate */ 1857 if (pmcs_soft_reset(pwp, B_FALSE)) { 1858 /* 1859 * Disable interrupts, in case we got far enough along to 1860 * enable them, then fire off ereport and service impact. 1861 */ 1862 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1863 "%s: failed soft reset", __func__); 1864 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_MASK, 0xffffffff); 1865 pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 0xffffffff); 1866 pmcs_fm_ereport(pwp, DDI_FM_DEVICE_NO_RESPONSE); 1867 ddi_fm_service_impact(pwp->dip, DDI_SERVICE_LOST); 1868 mutex_enter(&pwp->lock); 1869 pwp->state = STATE_DEAD; 1870 return (DDI_FAILURE); 1871 } 1872 1873 mutex_enter(&pwp->lock); 1874 pwp->state = STATE_RUNNING; 1875 mutex_exit(&pwp->lock); 1876 1877 /* 1878 * Finally, restart the phys, which will bring the iports back 1879 * up and eventually result in discovery running. 1880 */ 1881 if (pmcs_start_phys(pwp)) { 1882 /* We should be up and running now, so retry */ 1883 if (pmcs_start_phys(pwp)) { 1884 /* Apparently unable to restart PHYs, fail */ 1885 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1886 "%s: failed to restart PHYs after soft reset", 1887 __func__); 1888 mutex_enter(&pwp->lock); 1889 return (DDI_FAILURE); 1890 } 1891 } 1892 1893 mutex_enter(&pwp->lock); 1894 return (DDI_SUCCESS); 1895 } 1896 1897 /* 1898 * Reset a device or a logical unit. 1899 */ 1900 int 1901 pmcs_reset_dev(pmcs_hw_t *pwp, pmcs_phy_t *pptr, uint64_t lun) 1902 { 1903 int rval = 0; 1904 1905 if (pptr == NULL) { 1906 return (ENXIO); 1907 } 1908 1909 pmcs_lock_phy(pptr); 1910 if (pptr->dtype == SAS) { 1911 /* 1912 * Some devices do not support SAS_I_T_NEXUS_RESET as 1913 * it is not a mandatory (in SAM4) task management 1914 * function, while LOGIC_UNIT_RESET is mandatory. 1915 * 1916 * The problem here is that we need to iterate over 1917 * all known LUNs to emulate the semantics of 1918 * "RESET_TARGET". 1919 * 1920 * XXX: FIX ME 1921 */ 1922 if (lun == (uint64_t)-1) { 1923 lun = 0; 1924 } 1925 rval = pmcs_ssp_tmf(pwp, pptr, SAS_LOGICAL_UNIT_RESET, 0, lun, 1926 NULL); 1927 } else if (pptr->dtype == SATA) { 1928 if (lun != 0ull) { 1929 pmcs_unlock_phy(pptr); 1930 return (EINVAL); 1931 } 1932 rval = pmcs_reset_phy(pwp, pptr, PMCS_PHYOP_LINK_RESET); 1933 } else { 1934 pmcs_unlock_phy(pptr); 1935 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 1936 "%s: cannot reset a SMP device yet (%s)", 1937 __func__, pptr->path); 1938 return (EINVAL); 1939 } 1940 1941 /* 1942 * Now harvest any commands killed by this action 1943 * by issuing an ABORT for all commands on this device. 1944 * 1945 * We do this even if the the tmf or reset fails (in case there 1946 * are any dead commands around to be harvested *anyway*). 1947 * We don't have to await for the abort to complete. 1948 */ 1949 if (pmcs_abort(pwp, pptr, 0, 1, 0)) { 1950 pptr->abort_pending = 1; 1951 SCHEDULE_WORK(pwp, PMCS_WORK_ABORT_HANDLE); 1952 } 1953 1954 pmcs_unlock_phy(pptr); 1955 return (rval); 1956 } 1957 1958 /* 1959 * Called with PHY locked. 1960 */ 1961 static int 1962 pmcs_get_device_handle(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 1963 { 1964 if (pptr->valid_device_id == 0) { 1965 int result = pmcs_register_device(pwp, pptr); 1966 1967 /* 1968 * If we changed while registering, punt 1969 */ 1970 if (pptr->changed) { 1971 RESTART_DISCOVERY(pwp); 1972 return (-1); 1973 } 1974 1975 /* 1976 * If we had a failure to register, check against errors. 1977 * An ENOMEM error means we just retry (temp resource shortage). 1978 */ 1979 if (result == ENOMEM) { 1980 PHY_CHANGED(pwp, pptr); 1981 RESTART_DISCOVERY(pwp); 1982 return (-1); 1983 } 1984 1985 /* 1986 * An ETIMEDOUT error means we retry (if our counter isn't 1987 * exhausted) 1988 */ 1989 if (result == ETIMEDOUT) { 1990 if (ddi_get_lbolt() < pptr->config_stop) { 1991 PHY_CHANGED(pwp, pptr); 1992 RESTART_DISCOVERY(pwp); 1993 } else { 1994 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 1995 "%s: Retries exhausted for %s, killing", 1996 __func__, pptr->path); 1997 pptr->config_stop = 0; 1998 pmcs_kill_changed(pwp, pptr, 0); 1999 } 2000 return (-1); 2001 } 2002 /* 2003 * Other errors or no valid device id is fatal, but don't 2004 * preclude a future action. 2005 */ 2006 if (result || pptr->valid_device_id == 0) { 2007 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 2008 "%s: %s could not be registered", __func__, 2009 pptr->path); 2010 return (-1); 2011 } 2012 } 2013 return (0); 2014 } 2015 2016 int 2017 pmcs_iport_tgtmap_create(pmcs_iport_t *iport) 2018 { 2019 ASSERT(iport); 2020 if (iport == NULL) 2021 return (B_FALSE); 2022 2023 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, "%s", __func__); 2024 2025 /* create target map */ 2026 if (scsi_hba_tgtmap_create(iport->dip, SCSI_TM_FULLSET, 2027 tgtmap_csync_usec, tgtmap_stable_usec, (void *)iport, 2028 pmcs_tgtmap_activate_cb, pmcs_tgtmap_deactivate_cb, 2029 &iport->iss_tgtmap) != DDI_SUCCESS) { 2030 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG, NULL, NULL, 2031 "%s: failed to create tgtmap", __func__); 2032 return (B_FALSE); 2033 } 2034 return (B_TRUE); 2035 } 2036 2037 int 2038 pmcs_iport_tgtmap_destroy(pmcs_iport_t *iport) 2039 { 2040 ASSERT(iport && iport->iss_tgtmap); 2041 if ((iport == NULL) || (iport->iss_tgtmap == NULL)) 2042 return (B_FALSE); 2043 2044 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, "%s", __func__); 2045 2046 /* destroy target map */ 2047 scsi_hba_tgtmap_destroy(iport->iss_tgtmap); 2048 return (B_TRUE); 2049 } 2050 2051 /* 2052 * Remove all phys from an iport's phymap and empty it's phylist. 2053 * Called when a port has been reset by the host (see pmcs_intr.c) 2054 * or prior to issuing a soft reset if we detect a stall on the chip 2055 * (see pmcs_attach.c). 2056 */ 2057 void 2058 pmcs_iport_teardown_phys(pmcs_iport_t *iport) 2059 { 2060 pmcs_hw_t *pwp; 2061 sas_phymap_phys_t *phys; 2062 int phynum; 2063 2064 ASSERT(iport); 2065 ASSERT(mutex_owned(&iport->lock)); 2066 pwp = iport->pwp; 2067 ASSERT(pwp); 2068 2069 /* 2070 * Remove all phys from the iport handle's phy list, unset its 2071 * primary phy and update its state. 2072 */ 2073 pmcs_remove_phy_from_iport(iport, NULL); 2074 iport->pptr = NULL; 2075 iport->ua_state = UA_PEND_DEACTIVATE; 2076 2077 /* Remove all phys from the phymap */ 2078 phys = sas_phymap_ua2phys(pwp->hss_phymap, iport->ua); 2079 if (phys) { 2080 while ((phynum = sas_phymap_phys_next(phys)) != -1) { 2081 (void) sas_phymap_phy_rem(pwp->hss_phymap, phynum); 2082 } 2083 sas_phymap_phys_free(phys); 2084 } 2085 } 2086 2087 /* 2088 * Query the phymap and populate the iport handle passed in. 2089 * Called with iport lock held. 2090 */ 2091 int 2092 pmcs_iport_configure_phys(pmcs_iport_t *iport) 2093 { 2094 pmcs_hw_t *pwp; 2095 pmcs_phy_t *pptr; 2096 sas_phymap_phys_t *phys; 2097 int phynum; 2098 int inst; 2099 2100 ASSERT(iport); 2101 ASSERT(mutex_owned(&iport->lock)); 2102 pwp = iport->pwp; 2103 ASSERT(pwp); 2104 inst = ddi_get_instance(iport->dip); 2105 2106 mutex_enter(&pwp->lock); 2107 ASSERT(pwp->root_phys != NULL); 2108 2109 /* 2110 * Query the phymap regarding the phys in this iport and populate 2111 * the iport's phys list. Hereafter this list is maintained via 2112 * port up and down events in pmcs_intr.c 2113 */ 2114 ASSERT(list_is_empty(&iport->phys)); 2115 phys = sas_phymap_ua2phys(pwp->hss_phymap, iport->ua); 2116 ASSERT(phys != NULL); 2117 while ((phynum = sas_phymap_phys_next(phys)) != -1) { 2118 /* Grab the phy pointer from root_phys */ 2119 pptr = pwp->root_phys + phynum; 2120 ASSERT(pptr); 2121 pmcs_lock_phy(pptr); 2122 ASSERT(pptr->phynum == phynum); 2123 2124 /* 2125 * Set a back pointer in the phy to this iport. 2126 */ 2127 pptr->iport = iport; 2128 2129 /* 2130 * If this phy is the primary, set a pointer to it on our 2131 * iport handle, and set our portid from it. 2132 */ 2133 if (!pptr->subsidiary) { 2134 iport->pptr = pptr; 2135 iport->portid = pptr->portid; 2136 } 2137 2138 /* 2139 * Finally, insert the phy into our list 2140 */ 2141 pmcs_unlock_phy(pptr); 2142 pmcs_add_phy_to_iport(iport, pptr); 2143 2144 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, "%s: found " 2145 "phy %d [0x%p] on iport%d, refcnt(%d)", __func__, phynum, 2146 (void *)pptr, inst, iport->refcnt); 2147 } 2148 mutex_exit(&pwp->lock); 2149 sas_phymap_phys_free(phys); 2150 RESTART_DISCOVERY(pwp); 2151 return (DDI_SUCCESS); 2152 } 2153 2154 /* 2155 * Return the iport that ua is associated with, or NULL. If an iport is 2156 * returned, it will be held and the caller must release the hold. 2157 */ 2158 static pmcs_iport_t * 2159 pmcs_get_iport_by_ua(pmcs_hw_t *pwp, char *ua) 2160 { 2161 pmcs_iport_t *iport = NULL; 2162 2163 rw_enter(&pwp->iports_lock, RW_READER); 2164 for (iport = list_head(&pwp->iports); 2165 iport != NULL; 2166 iport = list_next(&pwp->iports, iport)) { 2167 mutex_enter(&iport->lock); 2168 if (strcmp(iport->ua, ua) == 0) { 2169 mutex_exit(&iport->lock); 2170 pmcs_hold_iport(iport); 2171 break; 2172 } 2173 mutex_exit(&iport->lock); 2174 } 2175 rw_exit(&pwp->iports_lock); 2176 2177 return (iport); 2178 } 2179 2180 /* 2181 * Return the iport that pptr is associated with, or NULL. 2182 * If an iport is returned, there is a hold that the caller must release. 2183 */ 2184 pmcs_iport_t * 2185 pmcs_get_iport_by_wwn(pmcs_hw_t *pwp, uint64_t wwn) 2186 { 2187 pmcs_iport_t *iport = NULL; 2188 char *ua; 2189 2190 ua = sas_phymap_lookup_ua(pwp->hss_phymap, pwp->sas_wwns[0], wwn); 2191 if (ua) { 2192 iport = pmcs_get_iport_by_ua(pwp, ua); 2193 if (iport) { 2194 mutex_enter(&iport->lock); 2195 pmcs_iport_active(iport); 2196 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, "%s: " 2197 "found iport [0x%p] on ua (%s), refcnt (%d)", 2198 __func__, (void *)iport, ua, iport->refcnt); 2199 mutex_exit(&iport->lock); 2200 } 2201 } 2202 2203 return (iport); 2204 } 2205 2206 /* 2207 * Promote the next phy on this port to primary, and return it. 2208 * Called when the primary PHY on a port is going down, but the port 2209 * remains up (see pmcs_intr.c). 2210 */ 2211 pmcs_phy_t * 2212 pmcs_promote_next_phy(pmcs_phy_t *prev_primary) 2213 { 2214 pmcs_hw_t *pwp; 2215 pmcs_iport_t *iport; 2216 pmcs_phy_t *pptr, *child; 2217 int portid; 2218 2219 pmcs_lock_phy(prev_primary); 2220 portid = prev_primary->portid; 2221 iport = prev_primary->iport; 2222 pwp = prev_primary->pwp; 2223 2224 /* Use the first available phy in this port */ 2225 for (pptr = pwp->root_phys; pptr; pptr = pptr->sibling) { 2226 if ((pptr->portid == portid) && (pptr != prev_primary)) { 2227 mutex_enter(&pptr->phy_lock); 2228 break; 2229 } 2230 } 2231 2232 if (pptr == NULL) { 2233 pmcs_unlock_phy(prev_primary); 2234 return (NULL); 2235 } 2236 2237 if (iport) { 2238 mutex_enter(&iport->lock); 2239 iport->pptr = pptr; 2240 mutex_exit(&iport->lock); 2241 } 2242 2243 /* Update the phy handle with the data from the previous primary */ 2244 pptr->children = prev_primary->children; 2245 child = pptr->children; 2246 while (child) { 2247 child->parent = pptr; 2248 child = child->sibling; 2249 } 2250 pptr->ncphy = prev_primary->ncphy; 2251 pptr->width = prev_primary->width; 2252 pptr->dtype = prev_primary->dtype; 2253 pptr->pend_dtype = prev_primary->pend_dtype; 2254 pptr->tolerates_sas2 = prev_primary->tolerates_sas2; 2255 pptr->atdt = prev_primary->atdt; 2256 pptr->portid = prev_primary->portid; 2257 pptr->link_rate = prev_primary->link_rate; 2258 pptr->configured = prev_primary->configured; 2259 pptr->iport = prev_primary->iport; 2260 pptr->target = prev_primary->target; 2261 if (pptr->target) { 2262 pptr->target->phy = pptr; 2263 } 2264 2265 /* Update the phy mask properties for the affected PHYs */ 2266 /* Clear the current values... */ 2267 pmcs_update_phy_pm_props(pptr, pptr->att_port_pm_tmp, 2268 pptr->tgt_port_pm_tmp, B_FALSE); 2269 /* ...replace with the values from prev_primary... */ 2270 pmcs_update_phy_pm_props(pptr, prev_primary->att_port_pm_tmp, 2271 prev_primary->tgt_port_pm_tmp, B_TRUE); 2272 /* ...then clear prev_primary's PHY values from the new primary */ 2273 pmcs_update_phy_pm_props(pptr, prev_primary->att_port_pm, 2274 prev_primary->tgt_port_pm, B_FALSE); 2275 /* Clear the prev_primary's values */ 2276 pmcs_update_phy_pm_props(prev_primary, prev_primary->att_port_pm_tmp, 2277 prev_primary->tgt_port_pm_tmp, B_FALSE); 2278 2279 pptr->subsidiary = 0; 2280 2281 prev_primary->subsidiary = 1; 2282 prev_primary->children = NULL; 2283 prev_primary->target = NULL; 2284 pptr->device_id = prev_primary->device_id; 2285 pptr->valid_device_id = prev_primary->valid_device_id; 2286 pmcs_unlock_phy(prev_primary); 2287 2288 /* 2289 * We call pmcs_unlock_phy() on pptr because it now contains the 2290 * list of children. 2291 */ 2292 pmcs_unlock_phy(pptr); 2293 2294 return (pptr); 2295 } 2296 2297 void 2298 pmcs_hold_iport(pmcs_iport_t *iport) 2299 { 2300 /* 2301 * Grab a reference to this iport. 2302 */ 2303 ASSERT(iport); 2304 mutex_enter(&iport->refcnt_lock); 2305 iport->refcnt++; 2306 mutex_exit(&iport->refcnt_lock); 2307 2308 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG2, NULL, NULL, "%s: iport " 2309 "[0x%p] refcnt (%d)", __func__, (void *)iport, iport->refcnt); 2310 } 2311 2312 void 2313 pmcs_rele_iport(pmcs_iport_t *iport) 2314 { 2315 /* 2316 * Release a refcnt on this iport. If this is the last reference, 2317 * signal the potential waiter in pmcs_iport_unattach(). 2318 */ 2319 ASSERT(iport->refcnt > 0); 2320 mutex_enter(&iport->refcnt_lock); 2321 iport->refcnt--; 2322 mutex_exit(&iport->refcnt_lock); 2323 if (iport->refcnt == 0) { 2324 cv_signal(&iport->refcnt_cv); 2325 } 2326 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG2, NULL, NULL, "%s: iport " 2327 "[0x%p] refcnt (%d)", __func__, (void *)iport, iport->refcnt); 2328 } 2329 2330 void 2331 pmcs_phymap_activate(void *arg, char *ua, void **privp) 2332 { 2333 _NOTE(ARGUNUSED(privp)); 2334 pmcs_hw_t *pwp = arg; 2335 pmcs_iport_t *iport = NULL; 2336 2337 mutex_enter(&pwp->lock); 2338 if ((pwp->state == STATE_UNPROBING) || (pwp->state == STATE_DEAD) || 2339 (pwp->state == STATE_IN_RESET)) { 2340 mutex_exit(&pwp->lock); 2341 return; 2342 } 2343 pwp->phymap_active++; 2344 mutex_exit(&pwp->lock); 2345 2346 if (scsi_hba_iportmap_iport_add(pwp->hss_iportmap, ua, NULL) != 2347 DDI_SUCCESS) { 2348 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, "%s: failed to " 2349 "add iport handle on unit address [%s]", __func__, ua); 2350 } else { 2351 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, "%s: " 2352 "phymap_active count (%d), added iport handle on unit " 2353 "address [%s]", __func__, pwp->phymap_active, ua); 2354 } 2355 2356 /* Set the HBA softstate as our private data for this unit address */ 2357 *privp = (void *)pwp; 2358 2359 /* 2360 * We are waiting on attach for this iport node, unless it is still 2361 * attached. This can happen if a consumer has an outstanding open 2362 * on our iport node, but the port is down. If this is the case, we 2363 * need to configure our iport here for reuse. 2364 */ 2365 iport = pmcs_get_iport_by_ua(pwp, ua); 2366 if (iport) { 2367 mutex_enter(&iport->lock); 2368 if (pmcs_iport_configure_phys(iport) != DDI_SUCCESS) { 2369 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, "%s: " 2370 "failed to configure phys on iport [0x%p] at " 2371 "unit address (%s)", __func__, (void *)iport, ua); 2372 } 2373 pmcs_iport_active(iport); 2374 pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, PMCS_NUM_PHYS, 2375 &iport->nphy); 2376 mutex_exit(&iport->lock); 2377 pmcs_rele_iport(iport); 2378 } 2379 2380 } 2381 2382 void 2383 pmcs_phymap_deactivate(void *arg, char *ua, void *privp) 2384 { 2385 _NOTE(ARGUNUSED(privp)); 2386 pmcs_hw_t *pwp = arg; 2387 pmcs_iport_t *iport; 2388 2389 mutex_enter(&pwp->lock); 2390 pwp->phymap_active--; 2391 mutex_exit(&pwp->lock); 2392 2393 if (scsi_hba_iportmap_iport_remove(pwp->hss_iportmap, ua) != 2394 DDI_SUCCESS) { 2395 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, "%s: failed to " 2396 "remove iport handle on unit address [%s]", __func__, ua); 2397 } else { 2398 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, "%s: " 2399 "phymap_active count (%d), removed iport handle on unit " 2400 "address [%s]", __func__, pwp->phymap_active, ua); 2401 } 2402 2403 iport = pmcs_get_iport_by_ua(pwp, ua); 2404 2405 if (iport == NULL) { 2406 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, "%s: failed " 2407 "lookup of iport handle on unit addr (%s)", __func__, ua); 2408 return; 2409 } 2410 2411 mutex_enter(&iport->lock); 2412 iport->ua_state = UA_INACTIVE; 2413 iport->portid = PMCS_IPORT_INVALID_PORT_ID; 2414 pmcs_remove_phy_from_iport(iport, NULL); 2415 mutex_exit(&iport->lock); 2416 pmcs_rele_iport(iport); 2417 } 2418 2419 /* 2420 * Top-level discovery function 2421 */ 2422 void 2423 pmcs_discover(pmcs_hw_t *pwp) 2424 { 2425 pmcs_phy_t *pptr; 2426 pmcs_phy_t *root_phy; 2427 2428 DTRACE_PROBE2(pmcs__discover__entry, ulong_t, pwp->work_flags, 2429 boolean_t, pwp->config_changed); 2430 2431 mutex_enter(&pwp->lock); 2432 2433 if (pwp->state != STATE_RUNNING) { 2434 mutex_exit(&pwp->lock); 2435 return; 2436 } 2437 2438 /* Ensure we have at least one phymap active */ 2439 if (pwp->phymap_active == 0) { 2440 mutex_exit(&pwp->lock); 2441 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2442 "%s: phymap inactive, exiting", __func__); 2443 return; 2444 } 2445 2446 mutex_exit(&pwp->lock); 2447 2448 /* 2449 * If no iports have attached, but we have PHYs that are up, we 2450 * are waiting for iport attach to complete. Restart discovery. 2451 */ 2452 rw_enter(&pwp->iports_lock, RW_READER); 2453 if (!pwp->iports_attached) { 2454 rw_exit(&pwp->iports_lock); 2455 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2456 "%s: no iports attached, retry discovery", __func__); 2457 SCHEDULE_WORK(pwp, PMCS_WORK_DISCOVER); 2458 return; 2459 } 2460 rw_exit(&pwp->iports_lock); 2461 2462 mutex_enter(&pwp->config_lock); 2463 if (pwp->configuring) { 2464 mutex_exit(&pwp->config_lock); 2465 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2466 "%s: configuration already in progress", __func__); 2467 return; 2468 } 2469 2470 if (pmcs_acquire_scratch(pwp, B_FALSE)) { 2471 mutex_exit(&pwp->config_lock); 2472 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2473 "%s: cannot allocate scratch", __func__); 2474 SCHEDULE_WORK(pwp, PMCS_WORK_DISCOVER); 2475 return; 2476 } 2477 2478 pwp->configuring = 1; 2479 pwp->config_changed = B_FALSE; 2480 mutex_exit(&pwp->config_lock); 2481 2482 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, "Discovery begin"); 2483 2484 /* 2485 * First, tell SCSA that we're beginning set operations. 2486 */ 2487 pmcs_begin_observations(pwp); 2488 2489 /* 2490 * The order of the following traversals is important. 2491 * 2492 * The first one checks for changed expanders. 2493 * 2494 * The second one aborts commands for dead devices and deregisters them. 2495 * 2496 * The third one clears the contents of dead expanders from the tree 2497 * 2498 * The fourth one clears now dead devices in expanders that remain. 2499 */ 2500 2501 /* 2502 * 1. Check expanders marked changed (but not dead) to see if they still 2503 * have the same number of phys and the same SAS address. Mark them, 2504 * their subsidiary phys (if wide) and their descendents dead if 2505 * anything has changed. Check the devices they contain to see if 2506 * *they* have changed. If they've changed from type NOTHING we leave 2507 * them marked changed to be configured later (picking up a new SAS 2508 * address and link rate if possible). Otherwise, any change in type, 2509 * SAS address or removal of target role will cause us to mark them 2510 * (and their descendents) as dead (and cause any pending commands 2511 * and associated devices to be removed). 2512 * 2513 * NOTE: We don't want to bail on discovery if the config has 2514 * changed until *after* we run pmcs_kill_devices. 2515 */ 2516 root_phy = pwp->root_phys; 2517 pmcs_check_expanders(pwp, root_phy); 2518 2519 /* 2520 * 2. Descend the tree looking for dead devices and kill them 2521 * by aborting all active commands and then deregistering them. 2522 */ 2523 if (pmcs_kill_devices(pwp, root_phy)) { 2524 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2525 "%s: pmcs_kill_devices failed!", __func__); 2526 } 2527 2528 /* 2529 * 3. Check for dead expanders and remove their children from the tree. 2530 * By the time we get here, the devices and commands for them have 2531 * already been terminated and removed. 2532 * 2533 * We do this independent of the configuration count changing so we can 2534 * free any dead device PHYs that were discovered while checking 2535 * expanders. We ignore any subsidiary phys as pmcs_clear_expander 2536 * will take care of those. 2537 * 2538 * NOTE: pmcs_clear_expander requires softstate lock 2539 */ 2540 mutex_enter(&pwp->lock); 2541 for (pptr = pwp->root_phys; pptr; pptr = pptr->sibling) { 2542 /* 2543 * Call pmcs_clear_expander for every root PHY. It will 2544 * recurse and determine which (if any) expanders actually 2545 * need to be cleared. 2546 */ 2547 pmcs_lock_phy(pptr); 2548 pmcs_clear_expander(pwp, pptr, 0); 2549 pmcs_unlock_phy(pptr); 2550 } 2551 mutex_exit(&pwp->lock); 2552 2553 /* 2554 * 4. Check for dead devices and nullify them. By the time we get here, 2555 * the devices and commands for them have already been terminated 2556 * and removed. This is different from step 2 in that this just nulls 2557 * phys that are part of expanders that are still here but used to 2558 * be something but are no longer something (e.g., after a pulled 2559 * disk drive). Note that dead expanders had their contained phys 2560 * removed from the tree- here, the expanders themselves are 2561 * nullified (unless they were removed by being contained in another 2562 * expander phy). 2563 */ 2564 pmcs_clear_phys(pwp, root_phy); 2565 2566 /* 2567 * 5. Now check for and configure new devices. 2568 */ 2569 if (pmcs_configure_new_devices(pwp, root_phy)) { 2570 goto restart; 2571 } 2572 2573 out: 2574 DTRACE_PROBE2(pmcs__discover__exit, ulong_t, pwp->work_flags, 2575 boolean_t, pwp->config_changed); 2576 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, "Discovery end"); 2577 2578 mutex_enter(&pwp->config_lock); 2579 2580 if (pwp->config_changed == B_FALSE) { 2581 /* 2582 * Observation is stable, report what we currently see to 2583 * the tgtmaps for delta processing. Start by setting 2584 * BEGIN on all tgtmaps. 2585 */ 2586 mutex_exit(&pwp->config_lock); 2587 if (pmcs_report_observations(pwp) == B_FALSE) { 2588 goto restart; 2589 } 2590 mutex_enter(&pwp->config_lock); 2591 } else { 2592 /* 2593 * If config_changed is TRUE, we need to reschedule 2594 * discovery now. 2595 */ 2596 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2597 "%s: Config has changed, will re-run discovery", __func__); 2598 SCHEDULE_WORK(pwp, PMCS_WORK_DISCOVER); 2599 } 2600 2601 pmcs_release_scratch(pwp); 2602 if (!pwp->quiesced) { 2603 pwp->blocked = 0; 2604 } 2605 pwp->configuring = 0; 2606 cv_signal(&pwp->config_cv); 2607 mutex_exit(&pwp->config_lock); 2608 2609 #ifdef DEBUG 2610 pptr = pmcs_find_phy_needing_work(pwp, pwp->root_phys); 2611 if (pptr != NULL) { 2612 if (!WORK_IS_SCHEDULED(pwp, PMCS_WORK_DISCOVER)) { 2613 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 2614 "PHY %s dead=%d changed=%d configured=%d " 2615 "but no work scheduled", pptr->path, pptr->dead, 2616 pptr->changed, pptr->configured); 2617 } 2618 pmcs_unlock_phy(pptr); 2619 } 2620 #endif 2621 2622 return; 2623 2624 restart: 2625 /* Clean up and restart discovery */ 2626 pmcs_release_scratch(pwp); 2627 pmcs_flush_observations(pwp); 2628 mutex_enter(&pwp->config_lock); 2629 pwp->configuring = 0; 2630 cv_signal(&pwp->config_cv); 2631 RESTART_DISCOVERY_LOCKED(pwp); 2632 mutex_exit(&pwp->config_lock); 2633 } 2634 2635 /* 2636 * Return any PHY that needs to have scheduled work done. The PHY is returned 2637 * locked. 2638 */ 2639 static pmcs_phy_t * 2640 pmcs_find_phy_needing_work(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 2641 { 2642 pmcs_phy_t *cphyp, *pnext; 2643 2644 while (pptr) { 2645 pmcs_lock_phy(pptr); 2646 2647 if (pptr->changed || (pptr->dead && pptr->valid_device_id)) { 2648 return (pptr); 2649 } 2650 2651 pnext = pptr->sibling; 2652 2653 if (pptr->children) { 2654 cphyp = pptr->children; 2655 pmcs_unlock_phy(pptr); 2656 cphyp = pmcs_find_phy_needing_work(pwp, cphyp); 2657 if (cphyp) { 2658 return (cphyp); 2659 } 2660 } else { 2661 pmcs_unlock_phy(pptr); 2662 } 2663 2664 pptr = pnext; 2665 } 2666 2667 return (NULL); 2668 } 2669 2670 /* 2671 * We may (or may not) report observations to SCSA. This is prefaced by 2672 * issuing a set_begin for each iport target map. 2673 */ 2674 static void 2675 pmcs_begin_observations(pmcs_hw_t *pwp) 2676 { 2677 pmcs_iport_t *iport; 2678 scsi_hba_tgtmap_t *tgtmap; 2679 2680 rw_enter(&pwp->iports_lock, RW_READER); 2681 for (iport = list_head(&pwp->iports); iport != NULL; 2682 iport = list_next(&pwp->iports, iport)) { 2683 /* 2684 * Unless we have at least one phy up, skip this iport. 2685 * Note we don't need to lock the iport for report_skip 2686 * since it is only used here. We are doing the skip so that 2687 * the phymap and iportmap stabilization times are honored - 2688 * giving us the ability to recover port operation within the 2689 * stabilization time without unconfiguring targets using the 2690 * port. 2691 */ 2692 if (!sas_phymap_uahasphys(pwp->hss_phymap, iport->ua)) { 2693 iport->report_skip = 1; 2694 continue; /* skip set_begin */ 2695 } 2696 iport->report_skip = 0; 2697 2698 tgtmap = iport->iss_tgtmap; 2699 ASSERT(tgtmap); 2700 if (scsi_hba_tgtmap_set_begin(tgtmap) != DDI_SUCCESS) { 2701 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, 2702 "%s: cannot set_begin tgtmap ", __func__); 2703 rw_exit(&pwp->iports_lock); 2704 return; 2705 } 2706 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, 2707 "%s: set begin on tgtmap [0x%p]", __func__, (void *)tgtmap); 2708 } 2709 rw_exit(&pwp->iports_lock); 2710 } 2711 2712 /* 2713 * Tell SCSA to flush the observations we've already sent (if any), as they 2714 * are no longer valid. 2715 */ 2716 static void 2717 pmcs_flush_observations(pmcs_hw_t *pwp) 2718 { 2719 pmcs_iport_t *iport; 2720 scsi_hba_tgtmap_t *tgtmap; 2721 2722 rw_enter(&pwp->iports_lock, RW_READER); 2723 for (iport = list_head(&pwp->iports); iport != NULL; 2724 iport = list_next(&pwp->iports, iport)) { 2725 /* 2726 * Skip this iport if it has no PHYs up. 2727 */ 2728 if (!sas_phymap_uahasphys(pwp->hss_phymap, iport->ua)) { 2729 continue; 2730 } 2731 2732 tgtmap = iport->iss_tgtmap; 2733 ASSERT(tgtmap); 2734 if (scsi_hba_tgtmap_set_flush(tgtmap) != DDI_SUCCESS) { 2735 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, 2736 "%s: Failed set_flush on tgtmap 0x%p", __func__, 2737 (void *)tgtmap); 2738 } else { 2739 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, 2740 "%s: set flush on tgtmap 0x%p", __func__, 2741 (void *)tgtmap); 2742 } 2743 } 2744 rw_exit(&pwp->iports_lock); 2745 } 2746 2747 /* 2748 * Report current observations to SCSA. 2749 */ 2750 static boolean_t 2751 pmcs_report_observations(pmcs_hw_t *pwp) 2752 { 2753 pmcs_iport_t *iport; 2754 scsi_hba_tgtmap_t *tgtmap; 2755 char *ap; 2756 pmcs_phy_t *pptr; 2757 uint64_t wwn; 2758 2759 /* 2760 * Observation is stable, report what we currently see to the tgtmaps 2761 * for delta processing. 2762 */ 2763 pptr = pwp->root_phys; 2764 2765 while (pptr) { 2766 pmcs_lock_phy(pptr); 2767 2768 /* 2769 * Skip PHYs that have nothing attached or are dead. 2770 */ 2771 if ((pptr->dtype == NOTHING) || pptr->dead) { 2772 pmcs_unlock_phy(pptr); 2773 pptr = pptr->sibling; 2774 continue; 2775 } 2776 2777 if (pptr->changed) { 2778 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 2779 "%s: oops, PHY %s changed; restart discovery", 2780 __func__, pptr->path); 2781 pmcs_unlock_phy(pptr); 2782 return (B_FALSE); 2783 } 2784 2785 /* 2786 * Get the iport for this root PHY, then call the helper 2787 * to report observations for this iport's targets 2788 */ 2789 wwn = pmcs_barray2wwn(pptr->sas_address); 2790 pmcs_unlock_phy(pptr); 2791 iport = pmcs_get_iport_by_wwn(pwp, wwn); 2792 if (iport == NULL) { 2793 /* No iport for this tgt */ 2794 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 2795 "%s: no iport for this target", __func__); 2796 pptr = pptr->sibling; 2797 continue; 2798 } 2799 2800 pmcs_lock_phy(pptr); 2801 if (!iport->report_skip) { 2802 if (pmcs_report_iport_observations( 2803 pwp, iport, pptr) == B_FALSE) { 2804 pmcs_rele_iport(iport); 2805 pmcs_unlock_phy(pptr); 2806 return (B_FALSE); 2807 } 2808 } 2809 pmcs_rele_iport(iport); 2810 pmcs_unlock_phy(pptr); 2811 pptr = pptr->sibling; 2812 } 2813 2814 /* 2815 * The observation is complete, end sets. Note we will skip any 2816 * iports that are active, but have no PHYs in them (i.e. awaiting 2817 * unconfigure). Set to restart discovery if we find this. 2818 */ 2819 rw_enter(&pwp->iports_lock, RW_READER); 2820 for (iport = list_head(&pwp->iports); 2821 iport != NULL; 2822 iport = list_next(&pwp->iports, iport)) { 2823 2824 if (iport->report_skip) 2825 continue; /* skip set_end */ 2826 2827 tgtmap = iport->iss_tgtmap; 2828 ASSERT(tgtmap); 2829 if (scsi_hba_tgtmap_set_end(tgtmap, 0) != DDI_SUCCESS) { 2830 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, 2831 "%s: cannot set_end tgtmap ", __func__); 2832 rw_exit(&pwp->iports_lock); 2833 return (B_FALSE); 2834 } 2835 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, 2836 "%s: set end on tgtmap [0x%p]", __func__, (void *)tgtmap); 2837 } 2838 2839 /* 2840 * Now that discovery is complete, set up the necessary 2841 * DDI properties on each iport node. 2842 */ 2843 for (iport = list_head(&pwp->iports); iport != NULL; 2844 iport = list_next(&pwp->iports, iport)) { 2845 /* Set up the 'attached-port' property on the iport */ 2846 ap = kmem_zalloc(PMCS_MAX_UA_SIZE, KM_SLEEP); 2847 mutex_enter(&iport->lock); 2848 pptr = iport->pptr; 2849 mutex_exit(&iport->lock); 2850 if (pptr == NULL) { 2851 /* 2852 * This iport is down, but has not been 2853 * removed from our list (unconfigured). 2854 * Set our value to '0'. 2855 */ 2856 (void) snprintf(ap, 1, "%s", "0"); 2857 } else { 2858 /* Otherwise, set it to remote phy's wwn */ 2859 pmcs_lock_phy(pptr); 2860 wwn = pmcs_barray2wwn(pptr->sas_address); 2861 (void) scsi_wwn_to_wwnstr(wwn, 1, ap); 2862 pmcs_unlock_phy(pptr); 2863 } 2864 if (ndi_prop_update_string(DDI_DEV_T_NONE, iport->dip, 2865 SCSI_ADDR_PROP_ATTACHED_PORT, ap) != DDI_SUCCESS) { 2866 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s: Failed " 2867 "to set prop ("SCSI_ADDR_PROP_ATTACHED_PORT")", 2868 __func__); 2869 } 2870 kmem_free(ap, PMCS_MAX_UA_SIZE); 2871 } 2872 rw_exit(&pwp->iports_lock); 2873 2874 return (B_TRUE); 2875 } 2876 2877 /* 2878 * Report observations into a particular iport's target map 2879 * 2880 * Called with phyp (and all descendents) locked 2881 */ 2882 static boolean_t 2883 pmcs_report_iport_observations(pmcs_hw_t *pwp, pmcs_iport_t *iport, 2884 pmcs_phy_t *phyp) 2885 { 2886 pmcs_phy_t *lphyp; 2887 scsi_hba_tgtmap_t *tgtmap; 2888 scsi_tgtmap_tgt_type_t tgt_type; 2889 char *ua; 2890 uint64_t wwn; 2891 2892 tgtmap = iport->iss_tgtmap; 2893 ASSERT(tgtmap); 2894 2895 lphyp = phyp; 2896 while (lphyp) { 2897 switch (lphyp->dtype) { 2898 default: /* Skip unknown PHYs. */ 2899 /* for non-root phys, skip to sibling */ 2900 goto next_phy; 2901 2902 case SATA: 2903 case SAS: 2904 tgt_type = SCSI_TGT_SCSI_DEVICE; 2905 break; 2906 2907 case EXPANDER: 2908 tgt_type = SCSI_TGT_SMP_DEVICE; 2909 break; 2910 } 2911 2912 if (lphyp->dead || !lphyp->configured) { 2913 goto next_phy; 2914 } 2915 2916 /* 2917 * Validate the PHY's SAS address 2918 */ 2919 if (((lphyp->sas_address[0] & 0xf0) >> 4) != NAA_IEEE_REG) { 2920 pmcs_prt(pwp, PMCS_PRT_ERR, lphyp, NULL, 2921 "PHY 0x%p (%s) has invalid SAS address; " 2922 "will not enumerate", (void *)lphyp, lphyp->path); 2923 goto next_phy; 2924 } 2925 2926 wwn = pmcs_barray2wwn(lphyp->sas_address); 2927 ua = scsi_wwn_to_wwnstr(wwn, 1, NULL); 2928 2929 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, lphyp, NULL, 2930 "iport_observation: adding %s on tgtmap [0x%p] phy [0x%p]", 2931 ua, (void *)tgtmap, (void*)lphyp); 2932 2933 if (scsi_hba_tgtmap_set_add(tgtmap, tgt_type, ua, NULL) != 2934 DDI_SUCCESS) { 2935 pmcs_prt(pwp, PMCS_PRT_DEBUG_MAP, NULL, NULL, 2936 "%s: failed to add address %s", __func__, ua); 2937 scsi_free_wwnstr(ua); 2938 return (B_FALSE); 2939 } 2940 scsi_free_wwnstr(ua); 2941 2942 if (lphyp->children) { 2943 if (pmcs_report_iport_observations(pwp, iport, 2944 lphyp->children) == B_FALSE) { 2945 return (B_FALSE); 2946 } 2947 } 2948 2949 /* for non-root phys, report siblings too */ 2950 next_phy: 2951 if (IS_ROOT_PHY(lphyp)) { 2952 lphyp = NULL; 2953 } else { 2954 lphyp = lphyp->sibling; 2955 } 2956 } 2957 2958 return (B_TRUE); 2959 } 2960 2961 /* 2962 * Check for and configure new devices. 2963 * 2964 * If the changed device is a SATA device, add a SATA device. 2965 * 2966 * If the changed device is a SAS device, add a SAS device. 2967 * 2968 * If the changed device is an EXPANDER device, do a REPORT 2969 * GENERAL SMP command to find out the number of contained phys. 2970 * 2971 * For each number of contained phys, allocate a phy, do a 2972 * DISCOVERY SMP command to find out what kind of device it 2973 * is and add it to the linked list of phys on the *next* level. 2974 * 2975 * NOTE: pptr passed in by the caller will be a root PHY 2976 */ 2977 static int 2978 pmcs_configure_new_devices(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 2979 { 2980 int rval = 0; 2981 pmcs_iport_t *iport; 2982 pmcs_phy_t *pnext, *orig_pptr = pptr, *root_phy, *pchild; 2983 uint64_t wwn; 2984 2985 /* 2986 * First, walk through each PHY at this level 2987 */ 2988 while (pptr) { 2989 pmcs_lock_phy(pptr); 2990 pnext = pptr->sibling; 2991 2992 /* 2993 * Set the new dtype if it has changed 2994 */ 2995 if ((pptr->pend_dtype != NEW) && 2996 (pptr->pend_dtype != pptr->dtype)) { 2997 pptr->dtype = pptr->pend_dtype; 2998 } 2999 3000 if (pptr->changed == 0 || pptr->dead || pptr->configured) { 3001 goto next_phy; 3002 } 3003 3004 /* Confirm that this iport is configured */ 3005 root_phy = pmcs_get_root_phy(pptr); 3006 wwn = pmcs_barray2wwn(root_phy->sas_address); 3007 pmcs_unlock_phy(pptr); 3008 iport = pmcs_get_iport_by_wwn(pwp, wwn); 3009 if (iport == NULL) { 3010 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL, 3011 "%s: iport not yet configured, " 3012 "retry discovery", __func__); 3013 pnext = NULL; 3014 rval = -1; 3015 pmcs_lock_phy(pptr); 3016 goto next_phy; 3017 } 3018 3019 pmcs_lock_phy(pptr); 3020 switch (pptr->dtype) { 3021 case NOTHING: 3022 pptr->changed = 0; 3023 break; 3024 case SATA: 3025 case SAS: 3026 pptr->iport = iport; 3027 pmcs_new_tport(pwp, pptr); 3028 break; 3029 case EXPANDER: 3030 pmcs_configure_expander(pwp, pptr, iport); 3031 break; 3032 } 3033 pmcs_rele_iport(iport); 3034 3035 mutex_enter(&pwp->config_lock); 3036 if (pwp->config_changed) { 3037 mutex_exit(&pwp->config_lock); 3038 pnext = NULL; 3039 goto next_phy; 3040 } 3041 mutex_exit(&pwp->config_lock); 3042 3043 next_phy: 3044 pmcs_unlock_phy(pptr); 3045 pptr = pnext; 3046 } 3047 3048 if (rval != 0) { 3049 return (rval); 3050 } 3051 3052 /* 3053 * Now walk through each PHY again, recalling ourselves if they 3054 * have children 3055 */ 3056 pptr = orig_pptr; 3057 while (pptr) { 3058 pmcs_lock_phy(pptr); 3059 pnext = pptr->sibling; 3060 pchild = pptr->children; 3061 pmcs_unlock_phy(pptr); 3062 3063 if (pchild) { 3064 rval = pmcs_configure_new_devices(pwp, pchild); 3065 if (rval != 0) { 3066 break; 3067 } 3068 } 3069 3070 pptr = pnext; 3071 } 3072 3073 return (rval); 3074 } 3075 3076 /* 3077 * Set all phys and descendent phys as changed if changed == B_TRUE, otherwise 3078 * mark them all as not changed. 3079 * 3080 * Called with parent PHY locked. 3081 */ 3082 void 3083 pmcs_set_changed(pmcs_hw_t *pwp, pmcs_phy_t *parent, boolean_t changed, 3084 int level) 3085 { 3086 pmcs_phy_t *pptr; 3087 3088 if (level == 0) { 3089 if (changed) { 3090 PHY_CHANGED(pwp, parent); 3091 } else { 3092 parent->changed = 0; 3093 } 3094 if (parent->dtype == EXPANDER && parent->level) { 3095 parent->width = 1; 3096 } 3097 if (parent->children) { 3098 pmcs_set_changed(pwp, parent->children, changed, 3099 level + 1); 3100 } 3101 } else { 3102 pptr = parent; 3103 while (pptr) { 3104 if (changed) { 3105 PHY_CHANGED(pwp, pptr); 3106 } else { 3107 pptr->changed = 0; 3108 } 3109 if (pptr->dtype == EXPANDER && pptr->level) { 3110 pptr->width = 1; 3111 } 3112 if (pptr->children) { 3113 pmcs_set_changed(pwp, pptr->children, changed, 3114 level + 1); 3115 } 3116 pptr = pptr->sibling; 3117 } 3118 } 3119 } 3120 3121 /* 3122 * Take the passed phy mark it and its descendants as dead. 3123 * Fire up reconfiguration to abort commands and bury it. 3124 * 3125 * Called with the parent PHY locked. 3126 */ 3127 void 3128 pmcs_kill_changed(pmcs_hw_t *pwp, pmcs_phy_t *parent, int level) 3129 { 3130 pmcs_phy_t *pptr = parent; 3131 3132 while (pptr) { 3133 pptr->link_rate = 0; 3134 pptr->abort_sent = 0; 3135 pptr->abort_pending = 1; 3136 SCHEDULE_WORK(pwp, PMCS_WORK_ABORT_HANDLE); 3137 pptr->need_rl_ext = 0; 3138 3139 if (pptr->dead == 0) { 3140 PHY_CHANGED(pwp, pptr); 3141 RESTART_DISCOVERY(pwp); 3142 } 3143 3144 pptr->dead = 1; 3145 3146 if (pptr->children) { 3147 pmcs_kill_changed(pwp, pptr->children, level + 1); 3148 } 3149 3150 /* 3151 * Only kill siblings at level > 0 3152 */ 3153 if (level == 0) { 3154 return; 3155 } 3156 3157 pptr = pptr->sibling; 3158 } 3159 } 3160 3161 /* 3162 * Go through every PHY and clear any that are dead (unless they're expanders) 3163 */ 3164 static void 3165 pmcs_clear_phys(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 3166 { 3167 pmcs_phy_t *pnext, *phyp; 3168 3169 phyp = pptr; 3170 while (phyp) { 3171 if (IS_ROOT_PHY(phyp)) { 3172 pmcs_lock_phy(phyp); 3173 } 3174 3175 if ((phyp->dtype != EXPANDER) && phyp->dead) { 3176 pmcs_clear_phy(pwp, phyp); 3177 } 3178 3179 if (phyp->children) { 3180 pmcs_clear_phys(pwp, phyp->children); 3181 } 3182 3183 pnext = phyp->sibling; 3184 3185 if (IS_ROOT_PHY(phyp)) { 3186 pmcs_unlock_phy(phyp); 3187 } 3188 3189 phyp = pnext; 3190 } 3191 } 3192 3193 /* 3194 * Clear volatile parts of a phy. Called with PHY locked. 3195 */ 3196 void 3197 pmcs_clear_phy(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 3198 { 3199 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, "%s: %s", 3200 __func__, pptr->path); 3201 ASSERT(mutex_owned(&pptr->phy_lock)); 3202 /* keep sibling */ 3203 /* keep children */ 3204 /* keep parent */ 3205 pptr->device_id = PMCS_INVALID_DEVICE_ID; 3206 /* keep hw_event_ack */ 3207 pptr->ncphy = 0; 3208 /* keep phynum */ 3209 pptr->width = 0; 3210 pptr->ds_recovery_retries = 0; 3211 pptr->ds_prev_good_recoveries = 0; 3212 pptr->last_good_recovery = 0; 3213 pptr->prev_recovery = 0; 3214 3215 /* keep dtype */ 3216 pptr->config_stop = 0; 3217 pptr->spinup_hold = 0; 3218 pptr->atdt = 0; 3219 /* keep portid */ 3220 pptr->link_rate = 0; 3221 pptr->valid_device_id = 0; 3222 pptr->abort_sent = 0; 3223 pptr->abort_pending = 0; 3224 pptr->need_rl_ext = 0; 3225 pptr->subsidiary = 0; 3226 pptr->configured = 0; 3227 pptr->deregister_wait = 0; 3228 pptr->reenumerate = 0; 3229 /* Only mark dead if it's not a root PHY and its dtype isn't NOTHING */ 3230 /* XXX: What about directly attached disks? */ 3231 if (!IS_ROOT_PHY(pptr) && (pptr->dtype != NOTHING)) 3232 pptr->dead = 1; 3233 pptr->changed = 0; 3234 /* keep SAS address */ 3235 /* keep path */ 3236 /* keep ref_count */ 3237 /* Don't clear iport on root PHYs - they are handled in pmcs_intr.c */ 3238 if (!IS_ROOT_PHY(pptr)) { 3239 pptr->last_iport = pptr->iport; 3240 pptr->iport = NULL; 3241 } 3242 /* keep target */ 3243 } 3244 3245 /* 3246 * Allocate softstate for this target if there isn't already one. If there 3247 * is, just redo our internal configuration. If it is actually "new", we'll 3248 * soon get a tran_tgt_init for it. 3249 * 3250 * Called with PHY locked. 3251 */ 3252 static void 3253 pmcs_new_tport(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 3254 { 3255 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, "%s: phy 0x%p @ %s", 3256 __func__, (void *)pptr, pptr->path); 3257 3258 if (pmcs_configure_phy(pwp, pptr) == B_FALSE) { 3259 /* 3260 * If the config failed, mark the PHY as changed. 3261 */ 3262 PHY_CHANGED(pwp, pptr); 3263 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3264 "%s: pmcs_configure_phy failed for phy 0x%p", __func__, 3265 (void *)pptr); 3266 return; 3267 } 3268 3269 /* Mark PHY as no longer changed */ 3270 pptr->changed = 0; 3271 3272 /* 3273 * If the PHY has no target pointer: 3274 * 3275 * If it's a root PHY, see if another PHY in the iport holds the 3276 * target pointer (primary PHY changed). If so, move it over. 3277 * 3278 * If it's not a root PHY, see if there's a PHY on the dead_phys 3279 * list that matches. 3280 */ 3281 if (pptr->target == NULL) { 3282 if (IS_ROOT_PHY(pptr)) { 3283 pmcs_phy_t *rphy = pwp->root_phys; 3284 3285 while (rphy) { 3286 if (rphy == pptr) { 3287 rphy = rphy->sibling; 3288 continue; 3289 } 3290 3291 mutex_enter(&rphy->phy_lock); 3292 if ((rphy->iport == pptr->iport) && 3293 (rphy->target != NULL)) { 3294 mutex_enter(&rphy->target->statlock); 3295 pptr->target = rphy->target; 3296 rphy->target = NULL; 3297 pptr->target->phy = pptr; 3298 /* The target is now on pptr */ 3299 mutex_exit(&pptr->target->statlock); 3300 mutex_exit(&rphy->phy_lock); 3301 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, 3302 pptr, pptr->target, 3303 "%s: Moved target from %s to %s", 3304 __func__, rphy->path, pptr->path); 3305 break; 3306 } 3307 mutex_exit(&rphy->phy_lock); 3308 3309 rphy = rphy->sibling; 3310 } 3311 } else { 3312 pmcs_reap_dead_phy(pptr); 3313 } 3314 } 3315 3316 /* 3317 * Only assign the device if there is a target for this PHY with a 3318 * matching SAS address. If an iport is disconnected from one piece 3319 * of storage and connected to another within the iport stabilization 3320 * time, we can get the PHY/target mismatch situation. 3321 * 3322 * Otherwise, it'll get done in tran_tgt_init. 3323 */ 3324 if (pptr->target) { 3325 mutex_enter(&pptr->target->statlock); 3326 if (pmcs_phy_target_match(pptr) == B_FALSE) { 3327 mutex_exit(&pptr->target->statlock); 3328 if (!IS_ROOT_PHY(pptr)) { 3329 pmcs_dec_phy_ref_count(pptr); 3330 } 3331 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 3332 "%s: Not assigning existing tgt %p for PHY %p " 3333 "(WWN mismatch)", __func__, (void *)pptr->target, 3334 (void *)pptr); 3335 pptr->target = NULL; 3336 return; 3337 } 3338 3339 if (!pmcs_assign_device(pwp, pptr->target)) { 3340 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, pptr->target, 3341 "%s: pmcs_assign_device failed for target 0x%p", 3342 __func__, (void *)pptr->target); 3343 } 3344 mutex_exit(&pptr->target->statlock); 3345 } 3346 } 3347 3348 /* 3349 * Called with PHY lock held. 3350 */ 3351 static boolean_t 3352 pmcs_configure_phy(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 3353 { 3354 char *dtype; 3355 3356 ASSERT(mutex_owned(&pptr->phy_lock)); 3357 3358 /* 3359 * Mark this device as no longer changed. 3360 */ 3361 pptr->changed = 0; 3362 3363 /* 3364 * If we don't have a device handle, get one. 3365 */ 3366 if (pmcs_get_device_handle(pwp, pptr)) { 3367 return (B_FALSE); 3368 } 3369 3370 pptr->configured = 1; 3371 3372 switch (pptr->dtype) { 3373 case SAS: 3374 dtype = "SAS"; 3375 break; 3376 case SATA: 3377 dtype = "SATA"; 3378 break; 3379 case EXPANDER: 3380 dtype = "SMP"; 3381 break; 3382 default: 3383 dtype = "???"; 3384 } 3385 3386 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, "config_dev: %s " 3387 "dev %s " SAS_ADDR_FMT " dev id 0x%x lr 0x%x", dtype, pptr->path, 3388 SAS_ADDR_PRT(pptr->sas_address), pptr->device_id, pptr->link_rate); 3389 3390 return (B_TRUE); 3391 } 3392 3393 /* 3394 * Called with PHY locked 3395 */ 3396 static void 3397 pmcs_configure_expander(pmcs_hw_t *pwp, pmcs_phy_t *pptr, pmcs_iport_t *iport) 3398 { 3399 pmcs_phy_t *ctmp, *clist = NULL, *cnext; 3400 int result, i, nphy = 0; 3401 boolean_t root_phy = B_FALSE; 3402 3403 ASSERT(iport); 3404 3405 /* 3406 * Step 1- clear our "changed" bit. If we need to retry/restart due 3407 * to resource shortages, we'll set it again. While we're doing 3408 * configuration, other events may set it again as well. If the PHY 3409 * is a root PHY and is currently marked as having changed, reset the 3410 * config_stop timer as well. 3411 */ 3412 if (IS_ROOT_PHY(pptr) && pptr->changed) { 3413 pptr->config_stop = ddi_get_lbolt() + 3414 drv_usectohz(PMCS_MAX_CONFIG_TIME); 3415 } 3416 pptr->changed = 0; 3417 3418 /* 3419 * Step 2- make sure we don't overflow 3420 */ 3421 if (pptr->level == PMCS_MAX_XPND-1) { 3422 pmcs_prt(pwp, PMCS_PRT_WARN, pptr, NULL, 3423 "%s: SAS expansion tree too deep", __func__); 3424 return; 3425 } 3426 3427 /* 3428 * Step 3- Check if this expander is part of a wide phy that has 3429 * already been configured. 3430 * 3431 * This is known by checking this level for another EXPANDER device 3432 * with the same SAS address and isn't already marked as a subsidiary 3433 * phy and a parent whose SAS address is the same as our SAS address 3434 * (if there are parents). 3435 */ 3436 if (!IS_ROOT_PHY(pptr)) { 3437 /* 3438 * No need to lock the parent here because we're in discovery 3439 * and the only time a PHY's children pointer can change is 3440 * in discovery; either in pmcs_clear_expander (which has 3441 * already been called) or here, down below. Plus, trying to 3442 * grab the parent's lock here can cause deadlock. 3443 */ 3444 ctmp = pptr->parent->children; 3445 } else { 3446 ctmp = pwp->root_phys; 3447 root_phy = B_TRUE; 3448 } 3449 3450 while (ctmp) { 3451 /* 3452 * If we've checked all PHYs up to pptr, we stop. Otherwise, 3453 * we'll be checking for a primary PHY with a higher PHY 3454 * number than pptr, which will never happen. The primary 3455 * PHY on non-root expanders will ALWAYS be the lowest 3456 * numbered PHY. 3457 */ 3458 if (ctmp == pptr) { 3459 break; 3460 } 3461 3462 /* 3463 * If pptr and ctmp are root PHYs, just grab the mutex on 3464 * ctmp. No need to lock the entire tree. If they are not 3465 * root PHYs, there is no need to lock since a non-root PHY's 3466 * SAS address and other characteristics can only change in 3467 * discovery anyway. 3468 */ 3469 if (root_phy) { 3470 mutex_enter(&ctmp->phy_lock); 3471 } 3472 3473 if (ctmp->dtype == EXPANDER && ctmp->width && 3474 memcmp(ctmp->sas_address, pptr->sas_address, 8) == 0) { 3475 int widephy = 0; 3476 /* 3477 * If these phys are not root PHYs, compare their SAS 3478 * addresses too. 3479 */ 3480 if (!root_phy) { 3481 if (memcmp(ctmp->parent->sas_address, 3482 pptr->parent->sas_address, 8) == 0) { 3483 widephy = 1; 3484 } 3485 } else { 3486 widephy = 1; 3487 } 3488 if (widephy) { 3489 ctmp->width++; 3490 pptr->subsidiary = 1; 3491 3492 /* 3493 * Update the primary PHY's attached-port-pm 3494 * and target-port-pm information with the info 3495 * from this subsidiary 3496 */ 3497 pmcs_update_phy_pm_props(ctmp, 3498 pptr->att_port_pm_tmp, 3499 pptr->tgt_port_pm_tmp, B_TRUE); 3500 3501 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3502 "%s: PHY %s part of wide PHY %s " 3503 "(now %d wide)", __func__, pptr->path, 3504 ctmp->path, ctmp->width); 3505 if (root_phy) { 3506 mutex_exit(&ctmp->phy_lock); 3507 } 3508 return; 3509 } 3510 } 3511 3512 cnext = ctmp->sibling; 3513 if (root_phy) { 3514 mutex_exit(&ctmp->phy_lock); 3515 } 3516 ctmp = cnext; 3517 } 3518 3519 /* 3520 * Step 4- If we don't have a device handle, get one. Since this 3521 * is the primary PHY, make sure subsidiary is cleared. 3522 */ 3523 pptr->subsidiary = 0; 3524 pptr->iport = iport; 3525 if (pmcs_get_device_handle(pwp, pptr)) { 3526 goto out; 3527 } 3528 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, "Config expander %s " 3529 SAS_ADDR_FMT " dev id 0x%x lr 0x%x", pptr->path, 3530 SAS_ADDR_PRT(pptr->sas_address), pptr->device_id, pptr->link_rate); 3531 3532 /* 3533 * Step 5- figure out how many phys are in this expander. 3534 */ 3535 nphy = pmcs_expander_get_nphy(pwp, pptr); 3536 if (nphy <= 0) { 3537 if (nphy == 0 && ddi_get_lbolt() < pptr->config_stop) { 3538 PHY_CHANGED(pwp, pptr); 3539 RESTART_DISCOVERY(pwp); 3540 } else { 3541 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3542 "%s: Retries exhausted for %s, killing", __func__, 3543 pptr->path); 3544 pptr->config_stop = 0; 3545 pmcs_kill_changed(pwp, pptr, 0); 3546 } 3547 goto out; 3548 } 3549 3550 /* 3551 * Step 6- Allocate a list of phys for this expander and figure out 3552 * what each one is. 3553 */ 3554 for (i = 0; i < nphy; i++) { 3555 ctmp = kmem_cache_alloc(pwp->phy_cache, KM_SLEEP); 3556 bzero(ctmp, sizeof (pmcs_phy_t)); 3557 ctmp->device_id = PMCS_INVALID_DEVICE_ID; 3558 ctmp->sibling = clist; 3559 ctmp->pend_dtype = NEW; /* Init pending dtype */ 3560 ctmp->config_stop = ddi_get_lbolt() + 3561 drv_usectohz(PMCS_MAX_CONFIG_TIME); 3562 clist = ctmp; 3563 } 3564 3565 mutex_enter(&pwp->config_lock); 3566 if (pwp->config_changed) { 3567 RESTART_DISCOVERY_LOCKED(pwp); 3568 mutex_exit(&pwp->config_lock); 3569 /* 3570 * Clean up the newly allocated PHYs and return 3571 */ 3572 while (clist) { 3573 ctmp = clist->sibling; 3574 kmem_cache_free(pwp->phy_cache, clist); 3575 clist = ctmp; 3576 } 3577 return; 3578 } 3579 mutex_exit(&pwp->config_lock); 3580 3581 /* 3582 * Step 7- Now fill in the rest of the static portions of the phy. 3583 */ 3584 for (i = 0, ctmp = clist; ctmp; ctmp = ctmp->sibling, i++) { 3585 ctmp->parent = pptr; 3586 ctmp->pwp = pwp; 3587 ctmp->level = pptr->level+1; 3588 ctmp->portid = pptr->portid; 3589 if (ctmp->tolerates_sas2) { 3590 ASSERT(i < SAS2_PHYNUM_MAX); 3591 ctmp->phynum = i & SAS2_PHYNUM_MASK; 3592 } else { 3593 ASSERT(i < SAS_PHYNUM_MAX); 3594 ctmp->phynum = i & SAS_PHYNUM_MASK; 3595 } 3596 pmcs_phy_name(pwp, ctmp, ctmp->path, sizeof (ctmp->path)); 3597 pmcs_lock_phy(ctmp); 3598 } 3599 3600 /* 3601 * Step 8- Discover things about each phy in the expander. 3602 */ 3603 for (i = 0, ctmp = clist; ctmp; ctmp = ctmp->sibling, i++) { 3604 result = pmcs_expander_content_discover(pwp, pptr, ctmp); 3605 if (result <= 0) { 3606 if (ddi_get_lbolt() < pptr->config_stop) { 3607 PHY_CHANGED(pwp, pptr); 3608 RESTART_DISCOVERY(pwp); 3609 } else { 3610 pptr->config_stop = 0; 3611 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3612 "%s: Retries exhausted for %s, killing", 3613 __func__, pptr->path); 3614 pmcs_kill_changed(pwp, pptr, 0); 3615 } 3616 goto out; 3617 } 3618 3619 /* Set pend_dtype to dtype for 1st time initialization */ 3620 ctmp->pend_dtype = ctmp->dtype; 3621 } 3622 3623 /* 3624 * Step 9: Install the new list on the next level. There should 3625 * typically be no children pointer on this PHY. There is one known 3626 * case where this can happen, though. If a root PHY goes down and 3627 * comes back up before discovery can run, we will fail to remove the 3628 * children from that PHY since it will no longer be marked dead. 3629 * However, in this case, all children should also be marked dead. If 3630 * we see that, take those children and put them on the dead_phys list. 3631 */ 3632 if (pptr->children != NULL) { 3633 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 3634 "%s: Expander @ %s still has children: Clean up", 3635 __func__, pptr->path); 3636 pmcs_add_dead_phys(pwp, pptr->children); 3637 } 3638 3639 /* 3640 * Set the new children pointer for this expander 3641 */ 3642 pptr->children = clist; 3643 clist = NULL; 3644 pptr->ncphy = nphy; 3645 pptr->configured = 1; 3646 3647 /* 3648 * We only set width if we're greater than level 0. 3649 */ 3650 if (pptr->level) { 3651 pptr->width = 1; 3652 } 3653 3654 /* 3655 * Now tell the rest of the world about us, as an SMP node. 3656 */ 3657 pptr->iport = iport; 3658 pmcs_new_tport(pwp, pptr); 3659 3660 out: 3661 while (clist) { 3662 ctmp = clist->sibling; 3663 pmcs_unlock_phy(clist); 3664 kmem_cache_free(pwp->phy_cache, clist); 3665 clist = ctmp; 3666 } 3667 } 3668 3669 /* 3670 * 2. Check expanders marked changed (but not dead) to see if they still have 3671 * the same number of phys and the same SAS address. Mark them, their subsidiary 3672 * phys (if wide) and their descendents dead if anything has changed. Check the 3673 * the devices they contain to see if *they* have changed. If they've changed 3674 * from type NOTHING we leave them marked changed to be configured later 3675 * (picking up a new SAS address and link rate if possible). Otherwise, any 3676 * change in type, SAS address or removal of target role will cause us to 3677 * mark them (and their descendents) as dead and cause any pending commands 3678 * and associated devices to be removed. 3679 * 3680 * Called with PHY (pptr) locked. 3681 */ 3682 3683 static void 3684 pmcs_check_expander(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 3685 { 3686 int nphy, result; 3687 pmcs_phy_t *ctmp, *local, *local_list = NULL, *local_tail = NULL; 3688 boolean_t kill_changed, changed; 3689 3690 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3691 "%s: check %s", __func__, pptr->path); 3692 3693 /* 3694 * Step 1: Mark phy as not changed. We will mark it changed if we need 3695 * to retry. 3696 */ 3697 pptr->changed = 0; 3698 3699 /* 3700 * Reset the config_stop time. Although we're not actually configuring 3701 * anything here, we do want some indication of when to give up trying 3702 * if we can't communicate with the expander. 3703 */ 3704 pptr->config_stop = ddi_get_lbolt() + 3705 drv_usectohz(PMCS_MAX_CONFIG_TIME); 3706 3707 /* 3708 * Step 2: Figure out how many phys are in this expander. If 3709 * pmcs_expander_get_nphy returns 0 we ran out of resources, 3710 * so reschedule and try later. If it returns another error, 3711 * just return. 3712 */ 3713 nphy = pmcs_expander_get_nphy(pwp, pptr); 3714 if (nphy <= 0) { 3715 if ((nphy == 0) && (ddi_get_lbolt() < pptr->config_stop)) { 3716 PHY_CHANGED(pwp, pptr); 3717 RESTART_DISCOVERY(pwp); 3718 } else { 3719 pptr->config_stop = 0; 3720 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3721 "%s: Retries exhausted for %s, killing", __func__, 3722 pptr->path); 3723 pmcs_kill_changed(pwp, pptr, 0); 3724 } 3725 return; 3726 } 3727 3728 /* 3729 * Step 3: If the number of phys don't agree, kill the old sub-tree. 3730 */ 3731 if (nphy != pptr->ncphy) { 3732 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3733 "%s: number of contained phys for %s changed from %d to %d", 3734 __func__, pptr->path, pptr->ncphy, nphy); 3735 /* 3736 * Force a rescan of this expander after dead contents 3737 * are cleared and removed. 3738 */ 3739 pmcs_kill_changed(pwp, pptr, 0); 3740 return; 3741 } 3742 3743 /* 3744 * Step 4: if we're at the bottom of the stack, we're done 3745 * (we can't have any levels below us) 3746 */ 3747 if (pptr->level == PMCS_MAX_XPND-1) { 3748 return; 3749 } 3750 3751 /* 3752 * Step 5: Discover things about each phy in this expander. We do 3753 * this by walking the current list of contained phys and doing a 3754 * content discovery for it to a local phy. 3755 */ 3756 ctmp = pptr->children; 3757 ASSERT(ctmp); 3758 if (ctmp == NULL) { 3759 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3760 "%s: No children attached to expander @ %s?", __func__, 3761 pptr->path); 3762 return; 3763 } 3764 3765 while (ctmp) { 3766 /* 3767 * Allocate a local PHY to contain the proposed new contents 3768 * and link it to the rest of the local PHYs so that they 3769 * can all be freed later. 3770 */ 3771 local = pmcs_clone_phy(ctmp); 3772 3773 if (local_list == NULL) { 3774 local_list = local; 3775 local_tail = local; 3776 } else { 3777 local_tail->sibling = local; 3778 local_tail = local; 3779 } 3780 3781 /* 3782 * Need to lock the local PHY since pmcs_expander_content_ 3783 * discovery may call pmcs_clear_phy on it, which expects 3784 * the PHY to be locked. 3785 */ 3786 pmcs_lock_phy(local); 3787 result = pmcs_expander_content_discover(pwp, pptr, local); 3788 pmcs_unlock_phy(local); 3789 if (result <= 0) { 3790 if (ddi_get_lbolt() < pptr->config_stop) { 3791 PHY_CHANGED(pwp, pptr); 3792 RESTART_DISCOVERY(pwp); 3793 } else { 3794 pptr->config_stop = 0; 3795 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3796 "%s: Retries exhausted for %s, killing", 3797 __func__, pptr->path); 3798 pmcs_kill_changed(pwp, pptr, 0); 3799 } 3800 3801 /* 3802 * Release all the local PHYs that we allocated. 3803 */ 3804 pmcs_free_phys(pwp, local_list); 3805 return; 3806 } 3807 3808 ctmp = ctmp->sibling; 3809 } 3810 3811 /* 3812 * Step 6: Compare the local PHY's contents to our current PHY. If 3813 * there are changes, take the appropriate action. 3814 * This is done in two steps (step 5 above, and 6 here) so that if we 3815 * have to bail during this process (e.g. pmcs_expander_content_discover 3816 * fails), we haven't actually changed the state of any of the real 3817 * PHYs. Next time we come through here, we'll be starting over from 3818 * scratch. This keeps us from marking a changed PHY as no longer 3819 * changed, but then having to bail only to come back next time and 3820 * think that the PHY hadn't changed. If this were to happen, we 3821 * would fail to properly configure the device behind this PHY. 3822 */ 3823 local = local_list; 3824 ctmp = pptr->children; 3825 3826 while (ctmp) { 3827 changed = B_FALSE; 3828 kill_changed = B_FALSE; 3829 3830 /* 3831 * We set local to local_list prior to this loop so that we 3832 * can simply walk the local_list while we walk this list. The 3833 * two lists should be completely in sync. 3834 * 3835 * Clear the changed flag here. 3836 */ 3837 ctmp->changed = 0; 3838 3839 if (ctmp->dtype != local->dtype) { 3840 if (ctmp->dtype != NOTHING) { 3841 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 3842 "%s: %s type changed from %s to %s " 3843 "(killing)", __func__, ctmp->path, 3844 PHY_TYPE(ctmp), PHY_TYPE(local)); 3845 /* 3846 * Force a rescan of this expander after dead 3847 * contents are cleared and removed. 3848 */ 3849 changed = B_TRUE; 3850 kill_changed = B_TRUE; 3851 } else { 3852 changed = B_TRUE; 3853 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 3854 "%s: %s type changed from NOTHING to %s", 3855 __func__, ctmp->path, PHY_TYPE(local)); 3856 /* 3857 * Since this PHY was nothing and is now 3858 * something, reset the config_stop timer. 3859 */ 3860 ctmp->config_stop = ddi_get_lbolt() + 3861 drv_usectohz(PMCS_MAX_CONFIG_TIME); 3862 } 3863 3864 } else if (ctmp->atdt != local->atdt) { 3865 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, "%s: " 3866 "%s attached device type changed from %d to %d " 3867 "(killing)", __func__, ctmp->path, ctmp->atdt, 3868 local->atdt); 3869 /* 3870 * Force a rescan of this expander after dead 3871 * contents are cleared and removed. 3872 */ 3873 changed = B_TRUE; 3874 3875 if (local->atdt == 0) { 3876 kill_changed = B_TRUE; 3877 } 3878 } else if (ctmp->link_rate != local->link_rate) { 3879 pmcs_prt(pwp, PMCS_PRT_INFO, ctmp, NULL, "%s: %s " 3880 "changed speed from %s to %s", __func__, ctmp->path, 3881 pmcs_get_rate(ctmp->link_rate), 3882 pmcs_get_rate(local->link_rate)); 3883 /* If the speed changed from invalid, force rescan */ 3884 if (!PMCS_VALID_LINK_RATE(ctmp->link_rate)) { 3885 changed = B_TRUE; 3886 RESTART_DISCOVERY(pwp); 3887 } else { 3888 /* Just update to the new link rate */ 3889 ctmp->link_rate = local->link_rate; 3890 } 3891 3892 if (!PMCS_VALID_LINK_RATE(local->link_rate)) { 3893 kill_changed = B_TRUE; 3894 } 3895 } else if (memcmp(ctmp->sas_address, local->sas_address, 3896 sizeof (ctmp->sas_address)) != 0) { 3897 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 3898 "%s: SAS Addr for %s changed from " SAS_ADDR_FMT 3899 "to " SAS_ADDR_FMT " (kill old tree)", __func__, 3900 ctmp->path, SAS_ADDR_PRT(ctmp->sas_address), 3901 SAS_ADDR_PRT(local->sas_address)); 3902 /* 3903 * Force a rescan of this expander after dead 3904 * contents are cleared and removed. 3905 */ 3906 changed = B_TRUE; 3907 } else { 3908 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 3909 "%s: %s looks the same (type %s)", 3910 __func__, ctmp->path, PHY_TYPE(ctmp)); 3911 /* 3912 * If EXPANDER, still mark it changed so we 3913 * re-evaluate its contents. If it's not an expander, 3914 * but it hasn't been configured, also mark it as 3915 * changed so that it will undergo configuration. 3916 */ 3917 if (ctmp->dtype == EXPANDER) { 3918 changed = B_TRUE; 3919 } else if ((ctmp->dtype != NOTHING) && 3920 !ctmp->configured) { 3921 ctmp->changed = 1; 3922 } else { 3923 /* It simply hasn't changed */ 3924 ctmp->changed = 0; 3925 } 3926 } 3927 3928 /* 3929 * If the PHY changed, call pmcs_kill_changed if indicated, 3930 * update its contents to reflect its current state and mark it 3931 * as changed. 3932 */ 3933 if (changed) { 3934 /* 3935 * pmcs_kill_changed will mark the PHY as changed, so 3936 * only do PHY_CHANGED if we did not do kill_changed. 3937 */ 3938 if (kill_changed) { 3939 pmcs_kill_changed(pwp, ctmp, 0); 3940 } else { 3941 /* 3942 * If we're not killing the device, it's not 3943 * dead. Mark the PHY as changed. 3944 */ 3945 PHY_CHANGED(pwp, ctmp); 3946 3947 if (ctmp->dead) { 3948 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, 3949 ctmp, NULL, "%s: Unmarking PHY %s " 3950 "dead, restarting discovery", 3951 __func__, ctmp->path); 3952 ctmp->dead = 0; 3953 RESTART_DISCOVERY(pwp); 3954 } 3955 } 3956 3957 /* 3958 * If the dtype of this PHY is now NOTHING, mark it as 3959 * unconfigured. Set pend_dtype to what the new dtype 3960 * is. It'll get updated at the end of the discovery 3961 * process. 3962 */ 3963 if (local->dtype == NOTHING) { 3964 bzero(ctmp->sas_address, 3965 sizeof (local->sas_address)); 3966 ctmp->atdt = 0; 3967 ctmp->link_rate = 0; 3968 ctmp->pend_dtype = NOTHING; 3969 ctmp->configured = 0; 3970 } else { 3971 (void) memcpy(ctmp->sas_address, 3972 local->sas_address, 3973 sizeof (local->sas_address)); 3974 ctmp->atdt = local->atdt; 3975 ctmp->link_rate = local->link_rate; 3976 ctmp->pend_dtype = local->dtype; 3977 } 3978 } 3979 3980 local = local->sibling; 3981 ctmp = ctmp->sibling; 3982 } 3983 3984 /* 3985 * If we got to here, that means we were able to see all the PHYs 3986 * and we can now update all of the real PHYs with the information 3987 * we got on the local PHYs. Once that's done, free all the local 3988 * PHYs. 3989 */ 3990 3991 pmcs_free_phys(pwp, local_list); 3992 } 3993 3994 /* 3995 * Top level routine to check expanders. We call pmcs_check_expander for 3996 * each expander. Since we're not doing any configuration right now, it 3997 * doesn't matter if this is breadth-first. 3998 */ 3999 static void 4000 pmcs_check_expanders(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 4001 { 4002 pmcs_phy_t *phyp, *pnext, *pchild; 4003 4004 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4005 "%s: %s", __func__, pptr->path); 4006 4007 /* 4008 * Check each expander at this level 4009 */ 4010 phyp = pptr; 4011 while (phyp) { 4012 pmcs_lock_phy(phyp); 4013 4014 if ((phyp->dtype == EXPANDER) && phyp->changed && 4015 !phyp->dead && !phyp->subsidiary && 4016 phyp->configured) { 4017 pmcs_check_expander(pwp, phyp); 4018 } 4019 4020 pnext = phyp->sibling; 4021 pmcs_unlock_phy(phyp); 4022 phyp = pnext; 4023 } 4024 4025 /* 4026 * Now check the children 4027 */ 4028 phyp = pptr; 4029 while (phyp) { 4030 pmcs_lock_phy(phyp); 4031 pnext = phyp->sibling; 4032 pchild = phyp->children; 4033 pmcs_unlock_phy(phyp); 4034 4035 if (pchild) { 4036 pmcs_check_expanders(pwp, pchild); 4037 } 4038 4039 phyp = pnext; 4040 } 4041 } 4042 4043 /* 4044 * Called with softstate and PHY locked 4045 */ 4046 static void 4047 pmcs_clear_expander(pmcs_hw_t *pwp, pmcs_phy_t *pptr, int level) 4048 { 4049 pmcs_phy_t *ctmp; 4050 4051 ASSERT(mutex_owned(&pwp->lock)); 4052 ASSERT(mutex_owned(&pptr->phy_lock)); 4053 ASSERT(pptr->level < PMCS_MAX_XPND - 1); 4054 4055 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4056 "%s: checking %s", __func__, pptr->path); 4057 4058 ctmp = pptr->children; 4059 while (ctmp) { 4060 /* 4061 * If the expander is dead, mark its children dead 4062 */ 4063 if (pptr->dead) { 4064 ctmp->dead = 1; 4065 } 4066 if (ctmp->dtype == EXPANDER) { 4067 pmcs_clear_expander(pwp, ctmp, level + 1); 4068 } 4069 ctmp = ctmp->sibling; 4070 } 4071 4072 /* 4073 * If this expander is not dead, we're done here. 4074 */ 4075 if (!pptr->dead) { 4076 return; 4077 } 4078 4079 /* 4080 * Now snip out the list of children below us and release them 4081 */ 4082 if (pptr->children) { 4083 pmcs_add_dead_phys(pwp, pptr->children); 4084 } 4085 4086 pptr->children = NULL; 4087 4088 /* 4089 * Clear subsidiary phys as well. Getting the parent's PHY lock 4090 * is only necessary if level == 0 since otherwise the parent is 4091 * already locked. 4092 */ 4093 if (!IS_ROOT_PHY(pptr)) { 4094 if (level == 0) { 4095 mutex_enter(&pptr->parent->phy_lock); 4096 } 4097 ctmp = pptr->parent->children; 4098 if (level == 0) { 4099 mutex_exit(&pptr->parent->phy_lock); 4100 } 4101 } else { 4102 ctmp = pwp->root_phys; 4103 } 4104 4105 while (ctmp) { 4106 if (ctmp == pptr) { 4107 ctmp = ctmp->sibling; 4108 continue; 4109 } 4110 /* 4111 * We only need to lock subsidiary PHYs on the level 0 4112 * expander. Any children of that expander, subsidiaries or 4113 * not, will already be locked. 4114 */ 4115 if (level == 0) { 4116 pmcs_lock_phy(ctmp); 4117 } 4118 if (ctmp->dtype != EXPANDER || ctmp->subsidiary == 0 || 4119 memcmp(ctmp->sas_address, pptr->sas_address, 4120 sizeof (ctmp->sas_address)) != 0) { 4121 if (level == 0) { 4122 pmcs_unlock_phy(ctmp); 4123 } 4124 ctmp = ctmp->sibling; 4125 continue; 4126 } 4127 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 4128 "%s: subsidiary %s", __func__, ctmp->path); 4129 pmcs_clear_phy(pwp, ctmp); 4130 if (level == 0) { 4131 pmcs_unlock_phy(ctmp); 4132 } 4133 ctmp = ctmp->sibling; 4134 } 4135 4136 pmcs_clear_phy(pwp, pptr); 4137 } 4138 4139 /* 4140 * Called with PHY locked and with scratch acquired. We return 0 if 4141 * we fail to allocate resources or notice that the configuration 4142 * count changed while we were running the command. We return 4143 * less than zero if we had an I/O error or received an unsupported 4144 * configuration. Otherwise we return the number of phys in the 4145 * expander. 4146 */ 4147 #define DFM(m, y) if (m == NULL) m = y 4148 static int 4149 pmcs_expander_get_nphy(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 4150 { 4151 struct pmcwork *pwrk; 4152 pmcs_iport_t *iport; 4153 char buf[64]; 4154 const uint_t rdoff = 0x100; /* returned data offset */ 4155 smp_response_frame_t *srf; 4156 smp_report_general_resp_t *srgr; 4157 uint32_t msg[PMCS_MSG_SIZE], *ptr, htag, status, ival; 4158 int result = 0; 4159 4160 ival = 0x40001100; 4161 4162 again: 4163 if (!pptr->iport || !pptr->valid_device_id) { 4164 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, pptr->target, 4165 "%s: Can't reach PHY %s", __func__, pptr->path); 4166 goto out; 4167 } 4168 4169 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr); 4170 if (pwrk == NULL) { 4171 goto out; 4172 } 4173 (void) memset(pwp->scratch, 0x77, PMCS_SCRATCH_SIZE); 4174 pwrk->arg = pwp->scratch; 4175 pwrk->dtype = pptr->dtype; 4176 pwrk->xp = pptr->target; 4177 pwrk->htag |= PMCS_TAG_NONIO_CMD; 4178 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4179 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4180 if (ptr == NULL) { 4181 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4182 pmcs_prt(pwp, PMCS_PRT_DEBUG2, pptr, NULL, 4183 "%s: GET_IQ_ENTRY failed", __func__); 4184 pmcs_pwork(pwp, pwrk); 4185 goto out; 4186 } 4187 4188 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, PMCIN_SMP_REQUEST)); 4189 msg[1] = LE_32(pwrk->htag); 4190 msg[2] = LE_32(pptr->device_id); 4191 msg[3] = LE_32((4 << SMP_REQUEST_LENGTH_SHIFT) | SMP_INDIRECT_RESPONSE); 4192 /* 4193 * Send SMP REPORT GENERAL (of either SAS1.1 or SAS2 flavors). 4194 */ 4195 msg[4] = BE_32(ival); 4196 msg[5] = 0; 4197 msg[6] = 0; 4198 msg[7] = 0; 4199 msg[8] = 0; 4200 msg[9] = 0; 4201 msg[10] = 0; 4202 msg[11] = 0; 4203 msg[12] = LE_32(DWORD0(pwp->scratch_dma+rdoff)); 4204 msg[13] = LE_32(DWORD1(pwp->scratch_dma+rdoff)); 4205 msg[14] = LE_32(PMCS_SCRATCH_SIZE - rdoff); 4206 msg[15] = 0; 4207 4208 COPY_MESSAGE(ptr, msg, PMCS_MSG_SIZE); 4209 4210 pmcs_hold_iport(pptr->iport); 4211 iport = pptr->iport; 4212 pmcs_smp_acquire(iport); 4213 pwrk->state = PMCS_WORK_STATE_ONCHIP; 4214 htag = pwrk->htag; 4215 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4216 pmcs_unlock_phy(pptr); 4217 WAIT_FOR(pwrk, 1000, result); 4218 pmcs_pwork(pwp, pwrk); 4219 pmcs_smp_release(iport); 4220 pmcs_rele_iport(iport); 4221 pmcs_lock_phy(pptr); 4222 4223 4224 mutex_enter(&pwp->config_lock); 4225 if (pwp->config_changed) { 4226 RESTART_DISCOVERY_LOCKED(pwp); 4227 mutex_exit(&pwp->config_lock); 4228 result = 0; 4229 goto out; 4230 } 4231 mutex_exit(&pwp->config_lock); 4232 4233 if (result) { 4234 pmcs_timed_out(pwp, htag, __func__); 4235 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4236 "%s: Issuing SMP ABORT for htag 0x%08x", __func__, htag); 4237 if (pmcs_abort(pwp, pptr, htag, 0, 0)) { 4238 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4239 "%s: Unable to issue SMP ABORT for htag 0x%08x", 4240 __func__, htag); 4241 } else { 4242 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4243 "%s: Issuing SMP ABORT for htag 0x%08x", 4244 __func__, htag); 4245 } 4246 result = 0; 4247 goto out; 4248 } 4249 ptr = (void *)pwp->scratch; 4250 status = LE_32(ptr[2]); 4251 if (status == PMCOUT_STATUS_UNDERFLOW || 4252 status == PMCOUT_STATUS_OVERFLOW) { 4253 pmcs_prt(pwp, PMCS_PRT_DEBUG_UNDERFLOW, pptr, NULL, 4254 "%s: over/underflow", __func__); 4255 status = PMCOUT_STATUS_OK; 4256 } 4257 srf = (smp_response_frame_t *)&((uint32_t *)pwp->scratch)[rdoff >> 2]; 4258 srgr = (smp_report_general_resp_t *) 4259 &((uint32_t *)pwp->scratch)[(rdoff >> 2)+1]; 4260 4261 if (status != PMCOUT_STATUS_OK) { 4262 char *nag = NULL; 4263 (void) snprintf(buf, sizeof (buf), 4264 "%s: SMP op failed (0x%x)", __func__, status); 4265 switch (status) { 4266 case PMCOUT_STATUS_IO_PORT_IN_RESET: 4267 DFM(nag, "I/O Port In Reset"); 4268 /* FALLTHROUGH */ 4269 case PMCOUT_STATUS_ERROR_HW_TIMEOUT: 4270 DFM(nag, "Hardware Timeout"); 4271 /* FALLTHROUGH */ 4272 case PMCOUT_STATUS_ERROR_INTERNAL_SMP_RESOURCE: 4273 DFM(nag, "Internal SMP Resource Failure"); 4274 /* FALLTHROUGH */ 4275 case PMCOUT_STATUS_XFER_ERR_PHY_NOT_READY: 4276 DFM(nag, "PHY Not Ready"); 4277 /* FALLTHROUGH */ 4278 case PMCOUT_STATUS_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: 4279 DFM(nag, "Connection Rate Not Supported"); 4280 /* FALLTHROUGH */ 4281 case PMCOUT_STATUS_IO_XFER_OPEN_RETRY_TIMEOUT: 4282 DFM(nag, "Open Retry Timeout"); 4283 /* FALLTHROUGH */ 4284 case PMCOUT_STATUS_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: 4285 DFM(nag, "HW Resource Busy"); 4286 /* FALLTHROUGH */ 4287 case PMCOUT_STATUS_SMP_RESP_CONNECTION_ERROR: 4288 DFM(nag, "Response Connection Error"); 4289 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4290 "%s: expander %s SMP operation failed (%s)", 4291 __func__, pptr->path, nag); 4292 break; 4293 4294 /* 4295 * For the IO_DS_NON_OPERATIONAL case, we need to kick off 4296 * device state recovery and return 0 so that the caller 4297 * doesn't assume this expander is dead for good. 4298 */ 4299 case PMCOUT_STATUS_IO_DS_NON_OPERATIONAL: { 4300 pmcs_xscsi_t *xp = pptr->target; 4301 4302 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, xp, 4303 "%s: expander %s device state non-operational", 4304 __func__, pptr->path); 4305 4306 if (xp == NULL) { 4307 /* 4308 * Kick off recovery right now. 4309 */ 4310 SCHEDULE_WORK(pwp, PMCS_WORK_DS_ERR_RECOVERY); 4311 (void) ddi_taskq_dispatch(pwp->tq, pmcs_worker, 4312 pwp, DDI_NOSLEEP); 4313 } else { 4314 mutex_enter(&xp->statlock); 4315 pmcs_start_dev_state_recovery(xp, pptr); 4316 mutex_exit(&xp->statlock); 4317 } 4318 4319 break; 4320 } 4321 4322 default: 4323 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, buf, ptr); 4324 result = -EIO; 4325 break; 4326 } 4327 } else if (srf->srf_frame_type != SMP_FRAME_TYPE_RESPONSE) { 4328 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4329 "%s: bad response frame type 0x%x", 4330 __func__, srf->srf_frame_type); 4331 result = -EINVAL; 4332 } else if (srf->srf_function != SMP_FUNC_REPORT_GENERAL) { 4333 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4334 "%s: bad response function 0x%x", 4335 __func__, srf->srf_function); 4336 result = -EINVAL; 4337 } else if (srf->srf_result != 0) { 4338 /* 4339 * Check to see if we have a value of 3 for failure and 4340 * whether we were using a SAS2.0 allocation length value 4341 * and retry without it. 4342 */ 4343 if (srf->srf_result == 3 && (ival & 0xff00)) { 4344 ival &= ~0xff00; 4345 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4346 "%s: err 0x%x with SAS2 request- retry with SAS1", 4347 __func__, srf->srf_result); 4348 goto again; 4349 } 4350 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4351 "%s: bad response 0x%x", __func__, srf->srf_result); 4352 result = -EINVAL; 4353 } else if (srgr->srgr_configuring) { 4354 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4355 "%s: expander at phy %s is still configuring", 4356 __func__, pptr->path); 4357 result = 0; 4358 } else { 4359 result = srgr->srgr_number_of_phys; 4360 if (ival & 0xff00) { 4361 pptr->tolerates_sas2 = 1; 4362 } 4363 /* 4364 * Save off the REPORT_GENERAL response 4365 */ 4366 bcopy(srgr, &pptr->rg_resp, sizeof (smp_report_general_resp_t)); 4367 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4368 "%s has %d phys and %s SAS2", pptr->path, result, 4369 pptr->tolerates_sas2? "tolerates" : "does not tolerate"); 4370 } 4371 out: 4372 return (result); 4373 } 4374 4375 /* 4376 * Called with expander locked (and thus, pptr) as well as all PHYs up to 4377 * the root, and scratch acquired. Return 0 if we fail to allocate resources 4378 * or notice that the configuration changed while we were running the command. 4379 * 4380 * We return less than zero if we had an I/O error or received an 4381 * unsupported configuration. 4382 */ 4383 static int 4384 pmcs_expander_content_discover(pmcs_hw_t *pwp, pmcs_phy_t *expander, 4385 pmcs_phy_t *pptr) 4386 { 4387 struct pmcwork *pwrk; 4388 pmcs_iport_t *iport; 4389 char buf[64]; 4390 uint8_t sas_address[8]; 4391 uint8_t att_sas_address[8]; 4392 smp_response_frame_t *srf; 4393 smp_discover_resp_t *sdr; 4394 const uint_t rdoff = 0x100; /* returned data offset */ 4395 uint8_t *roff; 4396 uint32_t status, *ptr, msg[PMCS_MSG_SIZE], htag; 4397 int result = 0; 4398 uint8_t ini_support; 4399 uint8_t tgt_support; 4400 4401 if (!expander->iport || !expander->valid_device_id) { 4402 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, expander, expander->target, 4403 "%s: Can't reach PHY %s", __func__, expander->path); 4404 goto out; 4405 } 4406 4407 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, expander); 4408 if (pwrk == NULL) { 4409 goto out; 4410 } 4411 (void) memset(pwp->scratch, 0x77, PMCS_SCRATCH_SIZE); 4412 pwrk->arg = pwp->scratch; 4413 pwrk->dtype = expander->dtype; 4414 pwrk->xp = expander->target; 4415 pwrk->htag |= PMCS_TAG_NONIO_CMD; 4416 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, PMCIN_SMP_REQUEST)); 4417 msg[1] = LE_32(pwrk->htag); 4418 msg[2] = LE_32(expander->device_id); 4419 msg[3] = LE_32((12 << SMP_REQUEST_LENGTH_SHIFT) | 4420 SMP_INDIRECT_RESPONSE); 4421 /* 4422 * Send SMP DISCOVER (of either SAS1.1 or SAS2 flavors). 4423 */ 4424 if (expander->tolerates_sas2) { 4425 msg[4] = BE_32(0x40101B00); 4426 } else { 4427 msg[4] = BE_32(0x40100000); 4428 } 4429 msg[5] = 0; 4430 msg[6] = BE_32((pptr->phynum << 16)); 4431 msg[7] = 0; 4432 msg[8] = 0; 4433 msg[9] = 0; 4434 msg[10] = 0; 4435 msg[11] = 0; 4436 msg[12] = LE_32(DWORD0(pwp->scratch_dma+rdoff)); 4437 msg[13] = LE_32(DWORD1(pwp->scratch_dma+rdoff)); 4438 msg[14] = LE_32(PMCS_SCRATCH_SIZE - rdoff); 4439 msg[15] = 0; 4440 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4441 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4442 if (ptr == NULL) { 4443 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4444 goto out; 4445 } 4446 4447 COPY_MESSAGE(ptr, msg, PMCS_MSG_SIZE); 4448 4449 pmcs_hold_iport(expander->iport); 4450 iport = expander->iport; 4451 pmcs_smp_acquire(iport); 4452 pwrk->state = PMCS_WORK_STATE_ONCHIP; 4453 htag = pwrk->htag; 4454 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4455 pmcs_unlock_phy(expander); 4456 WAIT_FOR(pwrk, 1000, result); 4457 pmcs_pwork(pwp, pwrk); 4458 pmcs_smp_release(iport); 4459 pmcs_rele_iport(iport); 4460 pmcs_lock_phy(expander); 4461 4462 mutex_enter(&pwp->config_lock); 4463 if (pwp->config_changed) { 4464 RESTART_DISCOVERY_LOCKED(pwp); 4465 mutex_exit(&pwp->config_lock); 4466 result = 0; 4467 goto out; 4468 } 4469 mutex_exit(&pwp->config_lock); 4470 4471 if (result) { 4472 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, pmcs_timeo, __func__); 4473 if (pmcs_abort(pwp, expander, htag, 0, 0)) { 4474 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4475 "%s: Unable to issue SMP ABORT for htag 0x%08x", 4476 __func__, htag); 4477 } else { 4478 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4479 "%s: Issuing SMP ABORT for htag 0x%08x", 4480 __func__, htag); 4481 } 4482 result = -ETIMEDOUT; 4483 goto out; 4484 } 4485 ptr = (void *)pwp->scratch; 4486 /* 4487 * Point roff to the DMA offset for returned data 4488 */ 4489 roff = pwp->scratch; 4490 roff += rdoff; 4491 srf = (smp_response_frame_t *)roff; 4492 sdr = (smp_discover_resp_t *)(roff+4); 4493 status = LE_32(ptr[2]); 4494 if (status == PMCOUT_STATUS_UNDERFLOW || 4495 status == PMCOUT_STATUS_OVERFLOW) { 4496 pmcs_prt(pwp, PMCS_PRT_DEBUG_UNDERFLOW, pptr, NULL, 4497 "%s: over/underflow", __func__); 4498 status = PMCOUT_STATUS_OK; 4499 } 4500 if (status != PMCOUT_STATUS_OK) { 4501 char *nag = NULL; 4502 (void) snprintf(buf, sizeof (buf), 4503 "%s: SMP op failed (0x%x)", __func__, status); 4504 switch (status) { 4505 case PMCOUT_STATUS_ERROR_HW_TIMEOUT: 4506 DFM(nag, "Hardware Timeout"); 4507 /* FALLTHROUGH */ 4508 case PMCOUT_STATUS_ERROR_INTERNAL_SMP_RESOURCE: 4509 DFM(nag, "Internal SMP Resource Failure"); 4510 /* FALLTHROUGH */ 4511 case PMCOUT_STATUS_XFER_ERR_PHY_NOT_READY: 4512 DFM(nag, "PHY Not Ready"); 4513 /* FALLTHROUGH */ 4514 case PMCOUT_STATUS_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: 4515 DFM(nag, "Connection Rate Not Supported"); 4516 /* FALLTHROUGH */ 4517 case PMCOUT_STATUS_IO_XFER_OPEN_RETRY_TIMEOUT: 4518 DFM(nag, "Open Retry Timeout"); 4519 /* FALLTHROUGH */ 4520 case PMCOUT_STATUS_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: 4521 DFM(nag, "HW Resource Busy"); 4522 /* FALLTHROUGH */ 4523 case PMCOUT_STATUS_SMP_RESP_CONNECTION_ERROR: 4524 DFM(nag, "Response Connection Error"); 4525 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4526 "%s: expander %s SMP operation failed (%s)", 4527 __func__, pptr->path, nag); 4528 break; 4529 default: 4530 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, buf, ptr); 4531 result = -EIO; 4532 break; 4533 } 4534 goto out; 4535 } else if (srf->srf_frame_type != SMP_FRAME_TYPE_RESPONSE) { 4536 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4537 "%s: bad response frame type 0x%x", 4538 __func__, srf->srf_frame_type); 4539 result = -EINVAL; 4540 goto out; 4541 } else if (srf->srf_function != SMP_FUNC_DISCOVER) { 4542 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4543 "%s: bad response function 0x%x", 4544 __func__, srf->srf_function); 4545 result = -EINVAL; 4546 goto out; 4547 } else if (srf->srf_result != SMP_RES_FUNCTION_ACCEPTED) { 4548 result = pmcs_smp_function_result(pwp, srf); 4549 /* Need not fail if PHY is Vacant */ 4550 if (result != SMP_RES_PHY_VACANT) { 4551 result = -EINVAL; 4552 goto out; 4553 } 4554 } 4555 4556 /* 4557 * Save off the DISCOVER response 4558 */ 4559 bcopy(sdr, &pptr->disc_resp, sizeof (smp_discover_resp_t)); 4560 4561 ini_support = (sdr->sdr_attached_sata_host | 4562 (sdr->sdr_attached_smp_initiator << 1) | 4563 (sdr->sdr_attached_stp_initiator << 2) | 4564 (sdr->sdr_attached_ssp_initiator << 3)); 4565 4566 tgt_support = (sdr->sdr_attached_sata_device | 4567 (sdr->sdr_attached_smp_target << 1) | 4568 (sdr->sdr_attached_stp_target << 2) | 4569 (sdr->sdr_attached_ssp_target << 3)); 4570 4571 pmcs_wwn2barray(BE_64(sdr->sdr_sas_addr), sas_address); 4572 pmcs_wwn2barray(BE_64(sdr->sdr_attached_sas_addr), att_sas_address); 4573 4574 pptr->virtual = sdr->sdr_virtual_phy; 4575 4576 /* 4577 * Set the routing attribute regardless of the PHY type. 4578 */ 4579 pptr->routing_attr = sdr->sdr_routing_attr; 4580 4581 switch (sdr->sdr_attached_device_type) { 4582 case SAS_IF_DTYPE_ENDPOINT: 4583 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4584 "exp_content: %s atdt=0x%x lr=%x is=%x ts=%x SAS=" 4585 SAS_ADDR_FMT " attSAS=" SAS_ADDR_FMT " atPHY=%x", 4586 pptr->path, 4587 sdr->sdr_attached_device_type, 4588 sdr->sdr_negotiated_logical_link_rate, 4589 ini_support, 4590 tgt_support, 4591 SAS_ADDR_PRT(sas_address), 4592 SAS_ADDR_PRT(att_sas_address), 4593 sdr->sdr_attached_phy_identifier); 4594 4595 if (sdr->sdr_attached_sata_device || 4596 sdr->sdr_attached_stp_target) { 4597 pptr->dtype = SATA; 4598 } else if (sdr->sdr_attached_ssp_target) { 4599 pptr->dtype = SAS; 4600 } else if (tgt_support || ini_support) { 4601 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4602 "%s: %s has tgt support=%x init support=(%x)", 4603 __func__, pptr->path, tgt_support, ini_support); 4604 } 4605 4606 switch (pptr->routing_attr) { 4607 case SMP_ROUTING_SUBTRACTIVE: 4608 case SMP_ROUTING_TABLE: 4609 case SMP_ROUTING_DIRECT: 4610 pptr->routing_method = SMP_ROUTING_DIRECT; 4611 break; 4612 default: 4613 pptr->routing_method = 0xff; /* Invalid method */ 4614 break; 4615 } 4616 pmcs_update_phy_pm_props(pptr, (1ULL << pptr->phynum), 4617 (1ULL << sdr->sdr_attached_phy_identifier), B_TRUE); 4618 break; 4619 case SAS_IF_DTYPE_EDGE: 4620 case SAS_IF_DTYPE_FANOUT: 4621 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4622 "exp_content: %s atdt=0x%x lr=%x is=%x ts=%x SAS=" 4623 SAS_ADDR_FMT " attSAS=" SAS_ADDR_FMT " atPHY=%x", 4624 pptr->path, 4625 sdr->sdr_attached_device_type, 4626 sdr->sdr_negotiated_logical_link_rate, 4627 ini_support, 4628 tgt_support, 4629 SAS_ADDR_PRT(sas_address), 4630 SAS_ADDR_PRT(att_sas_address), 4631 sdr->sdr_attached_phy_identifier); 4632 if (sdr->sdr_attached_smp_target) { 4633 /* 4634 * Avoid configuring phys that just point back 4635 * at a parent phy 4636 */ 4637 if (expander->parent && 4638 memcmp(expander->parent->sas_address, 4639 att_sas_address, 4640 sizeof (expander->parent->sas_address)) == 0) { 4641 pmcs_prt(pwp, PMCS_PRT_DEBUG3, pptr, NULL, 4642 "%s: skipping port back to parent " 4643 "expander (%s)", __func__, pptr->path); 4644 pptr->dtype = NOTHING; 4645 break; 4646 } 4647 pptr->dtype = EXPANDER; 4648 4649 } else if (tgt_support || ini_support) { 4650 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4651 "%s has tgt support=%x init support=(%x)", 4652 pptr->path, tgt_support, ini_support); 4653 pptr->dtype = EXPANDER; 4654 } 4655 if (pptr->routing_attr == SMP_ROUTING_DIRECT) { 4656 pptr->routing_method = 0xff; /* Invalid method */ 4657 } else { 4658 pptr->routing_method = pptr->routing_attr; 4659 } 4660 pmcs_update_phy_pm_props(pptr, (1ULL << pptr->phynum), 4661 (1ULL << sdr->sdr_attached_phy_identifier), B_TRUE); 4662 break; 4663 default: 4664 pptr->dtype = NOTHING; 4665 break; 4666 } 4667 if (pptr->dtype != NOTHING) { 4668 pmcs_phy_t *ctmp; 4669 4670 /* 4671 * If the attached device is a SATA device and the expander 4672 * is (possibly) a SAS2 compliant expander, check for whether 4673 * there is a NAA=5 WWN field starting at this offset and 4674 * use that for the SAS Address for this device. 4675 */ 4676 if (expander->tolerates_sas2 && pptr->dtype == SATA && 4677 (roff[SAS_ATTACHED_NAME_OFFSET] >> 8) == NAA_IEEE_REG) { 4678 (void) memcpy(pptr->sas_address, 4679 &roff[SAS_ATTACHED_NAME_OFFSET], 8); 4680 } else { 4681 (void) memcpy(pptr->sas_address, att_sas_address, 8); 4682 } 4683 pptr->atdt = (sdr->sdr_attached_device_type); 4684 /* 4685 * Now run up from the expander's parent up to the top to 4686 * make sure we only use the least common link_rate. 4687 */ 4688 for (ctmp = expander->parent; ctmp; ctmp = ctmp->parent) { 4689 if (ctmp->link_rate < 4690 sdr->sdr_negotiated_logical_link_rate) { 4691 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4692 "%s: derating link rate from %x to %x due " 4693 "to %s being slower", pptr->path, 4694 sdr->sdr_negotiated_logical_link_rate, 4695 ctmp->link_rate, 4696 ctmp->path); 4697 sdr->sdr_negotiated_logical_link_rate = 4698 ctmp->link_rate; 4699 } 4700 } 4701 pptr->link_rate = sdr->sdr_negotiated_logical_link_rate; 4702 pptr->state.prog_min_rate = sdr->sdr_prog_min_phys_link_rate; 4703 pptr->state.hw_min_rate = sdr->sdr_hw_min_phys_link_rate; 4704 pptr->state.prog_max_rate = sdr->sdr_prog_max_phys_link_rate; 4705 pptr->state.hw_max_rate = sdr->sdr_hw_max_phys_link_rate; 4706 PHY_CHANGED(pwp, pptr); 4707 } else { 4708 pmcs_clear_phy(pwp, pptr); 4709 } 4710 result = 1; 4711 out: 4712 return (result); 4713 } 4714 4715 /* 4716 * Get a work structure and assign it a tag with type and serial number 4717 * If a structure is returned, it is returned locked. 4718 */ 4719 pmcwork_t * 4720 pmcs_gwork(pmcs_hw_t *pwp, uint32_t tag_type, pmcs_phy_t *phyp) 4721 { 4722 pmcwork_t *p; 4723 uint16_t snum; 4724 uint32_t off; 4725 4726 mutex_enter(&pwp->wfree_lock); 4727 p = STAILQ_FIRST(&pwp->wf); 4728 if (p == NULL) { 4729 /* 4730 * If we couldn't get a work structure, it's time to bite 4731 * the bullet, grab the pfree_lock and copy over all the 4732 * work structures from the pending free list to the actual 4733 * free list (assuming it's not also empty). 4734 */ 4735 mutex_enter(&pwp->pfree_lock); 4736 if (STAILQ_FIRST(&pwp->pf) == NULL) { 4737 mutex_exit(&pwp->pfree_lock); 4738 mutex_exit(&pwp->wfree_lock); 4739 return (NULL); 4740 } 4741 pwp->wf.stqh_first = pwp->pf.stqh_first; 4742 pwp->wf.stqh_last = pwp->pf.stqh_last; 4743 STAILQ_INIT(&pwp->pf); 4744 mutex_exit(&pwp->pfree_lock); 4745 4746 p = STAILQ_FIRST(&pwp->wf); 4747 ASSERT(p != NULL); 4748 } 4749 STAILQ_REMOVE(&pwp->wf, p, pmcwork, next); 4750 snum = pwp->wserno++; 4751 mutex_exit(&pwp->wfree_lock); 4752 4753 off = p - pwp->work; 4754 4755 mutex_enter(&p->lock); 4756 ASSERT(p->state == PMCS_WORK_STATE_NIL); 4757 ASSERT(p->htag == PMCS_TAG_FREE); 4758 p->htag = (tag_type << PMCS_TAG_TYPE_SHIFT) & PMCS_TAG_TYPE_MASK; 4759 p->htag |= ((snum << PMCS_TAG_SERNO_SHIFT) & PMCS_TAG_SERNO_MASK); 4760 p->htag |= ((off << PMCS_TAG_INDEX_SHIFT) & PMCS_TAG_INDEX_MASK); 4761 p->start = gethrtime(); 4762 p->state = PMCS_WORK_STATE_READY; 4763 p->ssp_event = 0; 4764 p->dead = 0; 4765 4766 if (phyp) { 4767 p->phy = phyp; 4768 pmcs_inc_phy_ref_count(phyp); 4769 } 4770 4771 return (p); 4772 } 4773 4774 /* 4775 * Called with pwrk lock held. Returned with lock released. 4776 */ 4777 void 4778 pmcs_pwork(pmcs_hw_t *pwp, pmcwork_t *p) 4779 { 4780 ASSERT(p != NULL); 4781 ASSERT(mutex_owned(&p->lock)); 4782 4783 p->last_ptr = p->ptr; 4784 p->last_arg = p->arg; 4785 p->last_phy = p->phy; 4786 p->last_xp = p->xp; 4787 p->last_htag = p->htag; 4788 p->last_state = p->state; 4789 p->finish = gethrtime(); 4790 4791 if (p->phy) { 4792 pmcs_dec_phy_ref_count(p->phy); 4793 } 4794 4795 p->state = PMCS_WORK_STATE_NIL; 4796 p->htag = PMCS_TAG_FREE; 4797 p->xp = NULL; 4798 p->ptr = NULL; 4799 p->arg = NULL; 4800 p->phy = NULL; 4801 p->abt_htag = 0; 4802 p->timer = 0; 4803 mutex_exit(&p->lock); 4804 4805 if (mutex_tryenter(&pwp->wfree_lock) == 0) { 4806 mutex_enter(&pwp->pfree_lock); 4807 STAILQ_INSERT_TAIL(&pwp->pf, p, next); 4808 mutex_exit(&pwp->pfree_lock); 4809 } else { 4810 STAILQ_INSERT_TAIL(&pwp->wf, p, next); 4811 mutex_exit(&pwp->wfree_lock); 4812 } 4813 } 4814 4815 /* 4816 * Find a work structure based upon a tag and make sure that the tag 4817 * serial number matches the work structure we've found. 4818 * If a structure is found, its lock is held upon return. 4819 * If lock_phy is B_TRUE, then lock the phy also when returning the work struct 4820 */ 4821 pmcwork_t * 4822 pmcs_tag2wp(pmcs_hw_t *pwp, uint32_t htag, boolean_t lock_phy) 4823 { 4824 pmcwork_t *p; 4825 uint32_t idx = PMCS_TAG_INDEX(htag); 4826 4827 p = &pwp->work[idx]; 4828 4829 mutex_enter(&p->lock); 4830 if (p->htag == htag) { 4831 if (lock_phy) { 4832 mutex_exit(&p->lock); 4833 mutex_enter(&p->phy->phy_lock); 4834 mutex_enter(&p->lock); 4835 } 4836 return (p); 4837 } 4838 mutex_exit(&p->lock); 4839 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, 4840 "INDEX 0x%x HTAG 0x%x got p->htag 0x%x", idx, htag, p->htag); 4841 return (NULL); 4842 } 4843 4844 /* 4845 * Issue an abort for a command or for all commands. 4846 * 4847 * Since this can be called from interrupt context, 4848 * we don't wait for completion if wait is not set. 4849 * 4850 * Called with PHY lock held. 4851 */ 4852 int 4853 pmcs_abort(pmcs_hw_t *pwp, pmcs_phy_t *pptr, uint32_t tag, int all_cmds, 4854 int wait) 4855 { 4856 pmcwork_t *pwrk; 4857 pmcs_xscsi_t *tgt; 4858 uint32_t msg[PMCS_MSG_SIZE], *ptr; 4859 int result, abt_type; 4860 uint32_t abt_htag, status; 4861 4862 if (pptr->abort_all_start) { 4863 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, "%s: ABORT_ALL for " 4864 "(%s) already in progress.", __func__, pptr->path); 4865 return (EBUSY); 4866 } 4867 4868 switch (pptr->dtype) { 4869 case SAS: 4870 abt_type = PMCIN_SSP_ABORT; 4871 break; 4872 case SATA: 4873 abt_type = PMCIN_SATA_ABORT; 4874 break; 4875 case EXPANDER: 4876 abt_type = PMCIN_SMP_ABORT; 4877 break; 4878 default: 4879 return (0); 4880 } 4881 4882 pwrk = pmcs_gwork(pwp, wait ? PMCS_TAG_TYPE_WAIT : PMCS_TAG_TYPE_NONE, 4883 pptr); 4884 4885 if (pwrk == NULL) { 4886 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nowrk, __func__); 4887 return (ENOMEM); 4888 } 4889 4890 pwrk->dtype = pptr->dtype; 4891 pwrk->xp = pptr->target; 4892 pwrk->htag |= PMCS_TAG_NONIO_CMD; 4893 if (wait) { 4894 pwrk->arg = msg; 4895 } 4896 if (pptr->valid_device_id == 0) { 4897 pmcs_pwork(pwp, pwrk); 4898 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4899 "%s: Invalid DeviceID", __func__); 4900 return (ENODEV); 4901 } 4902 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, abt_type)); 4903 msg[1] = LE_32(pwrk->htag); 4904 msg[2] = LE_32(pptr->device_id); 4905 if (all_cmds) { 4906 msg[3] = 0; 4907 msg[4] = LE_32(1); 4908 pwrk->ptr = NULL; 4909 pwrk->abt_htag = PMCS_ABT_HTAG_ALL; 4910 pptr->abort_all_start = gethrtime(); 4911 } else { 4912 msg[3] = LE_32(tag); 4913 msg[4] = 0; 4914 pwrk->abt_htag = tag; 4915 } 4916 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4917 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4918 if (ptr == NULL) { 4919 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4920 pmcs_pwork(pwp, pwrk); 4921 pptr->abort_all_start = 0; 4922 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nomsg, __func__); 4923 return (ENOMEM); 4924 } 4925 4926 COPY_MESSAGE(ptr, msg, 5); 4927 if (all_cmds) { 4928 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4929 "%s: aborting all commands for %s device %s. (htag=0x%x)", 4930 __func__, pmcs_get_typename(pptr->dtype), pptr->path, 4931 msg[1]); 4932 } else { 4933 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4934 "%s: aborting tag 0x%x for %s device %s. (htag=0x%x)", 4935 __func__, tag, pmcs_get_typename(pptr->dtype), pptr->path, 4936 msg[1]); 4937 } 4938 pwrk->state = PMCS_WORK_STATE_ONCHIP; 4939 4940 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4941 if (!wait) { 4942 mutex_exit(&pwrk->lock); 4943 return (0); 4944 } 4945 4946 abt_htag = pwrk->htag; 4947 pmcs_unlock_phy(pptr); 4948 WAIT_FOR(pwrk, 1000, result); 4949 pmcs_pwork(pwp, pwrk); 4950 pmcs_lock_phy(pptr); 4951 tgt = pptr->target; 4952 4953 if (all_cmds) { 4954 pptr->abort_all_start = 0; 4955 cv_signal(&pptr->abort_all_cv); 4956 } 4957 4958 if (result) { 4959 if (all_cmds) { 4960 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4961 "%s: Abort all request timed out", __func__); 4962 } else { 4963 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4964 "%s: Abort (htag 0x%08x) request timed out", 4965 __func__, abt_htag); 4966 } 4967 if (tgt != NULL) { 4968 mutex_enter(&tgt->statlock); 4969 if ((tgt->dev_state != PMCS_DEVICE_STATE_IN_RECOVERY) && 4970 (tgt->dev_state != 4971 PMCS_DEVICE_STATE_NON_OPERATIONAL)) { 4972 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4973 "%s: Trying DS error recovery for tgt 0x%p", 4974 __func__, (void *)tgt); 4975 (void) pmcs_send_err_recovery_cmd(pwp, 4976 PMCS_DEVICE_STATE_IN_RECOVERY, pptr, tgt); 4977 } 4978 mutex_exit(&tgt->statlock); 4979 } 4980 return (ETIMEDOUT); 4981 } 4982 4983 status = LE_32(msg[2]); 4984 if (status != PMCOUT_STATUS_OK) { 4985 /* 4986 * The only non-success status are IO_NOT_VALID & 4987 * IO_ABORT_IN_PROGRESS. 4988 * In case of IO_ABORT_IN_PROGRESS, the other ABORT cmd's 4989 * status is of concern and this duplicate cmd status can 4990 * be ignored. 4991 * If IO_NOT_VALID, that's not an error per-se. 4992 * For abort of single I/O complete the command anyway. 4993 * If, however, we were aborting all, that is a problem 4994 * as IO_NOT_VALID really means that the IO or device is 4995 * not there. So, discovery process will take of the cleanup. 4996 */ 4997 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4998 "%s: abort result 0x%x", __func__, LE_32(msg[2])); 4999 if (all_cmds) { 5000 PHY_CHANGED(pwp, pptr); 5001 RESTART_DISCOVERY(pwp); 5002 } else { 5003 return (EINVAL); 5004 } 5005 5006 return (0); 5007 } 5008 5009 if (tgt != NULL) { 5010 mutex_enter(&tgt->statlock); 5011 if (tgt->dev_state == PMCS_DEVICE_STATE_IN_RECOVERY) { 5012 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 5013 "%s: Restoring OPERATIONAL dev_state for tgt 0x%p", 5014 __func__, (void *)tgt); 5015 (void) pmcs_send_err_recovery_cmd(pwp, 5016 PMCS_DEVICE_STATE_OPERATIONAL, pptr, tgt); 5017 } 5018 mutex_exit(&tgt->statlock); 5019 } 5020 5021 return (0); 5022 } 5023 5024 /* 5025 * Issue a task management function to an SSP device. 5026 * 5027 * Called with PHY lock held. 5028 * statlock CANNOT be held upon entry. 5029 */ 5030 int 5031 pmcs_ssp_tmf(pmcs_hw_t *pwp, pmcs_phy_t *pptr, uint8_t tmf, uint32_t tag, 5032 uint64_t lun, uint32_t *response) 5033 { 5034 int result, ds; 5035 uint8_t local[PMCS_QENTRY_SIZE << 1], *xd; 5036 sas_ssp_rsp_iu_t *rptr = (void *)local; 5037 static const uint8_t ssp_rsp_evec[] = { 5038 0x58, 0x61, 0x56, 0x72, 0x00 5039 }; 5040 uint32_t msg[PMCS_MSG_SIZE], *ptr, status; 5041 struct pmcwork *pwrk; 5042 pmcs_xscsi_t *xp; 5043 5044 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr); 5045 if (pwrk == NULL) { 5046 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nowrk, __func__); 5047 return (ENOMEM); 5048 } 5049 /* 5050 * NB: We use the PMCS_OQ_GENERAL outbound queue 5051 * NB: so as to not get entangled in normal I/O 5052 * NB: processing. 5053 */ 5054 pwrk->htag |= PMCS_TAG_NONIO_CMD; 5055 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 5056 PMCIN_SSP_INI_TM_START)); 5057 msg[1] = LE_32(pwrk->htag); 5058 msg[2] = LE_32(pptr->device_id); 5059 if (tmf == SAS_ABORT_TASK || tmf == SAS_QUERY_TASK) { 5060 msg[3] = LE_32(tag); 5061 } else { 5062 msg[3] = 0; 5063 } 5064 msg[4] = LE_32(tmf); 5065 msg[5] = BE_32((uint32_t)lun); 5066 msg[6] = BE_32((uint32_t)(lun >> 32)); 5067 msg[7] = LE_32(PMCIN_MESSAGE_REPORT); 5068 5069 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5070 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5071 if (ptr == NULL) { 5072 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5073 pmcs_pwork(pwp, pwrk); 5074 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nomsg, __func__); 5075 return (ENOMEM); 5076 } 5077 COPY_MESSAGE(ptr, msg, 7); 5078 pwrk->arg = msg; 5079 pwrk->dtype = pptr->dtype; 5080 xp = pptr->target; 5081 pwrk->xp = xp; 5082 5083 if (xp != NULL) { 5084 mutex_enter(&xp->statlock); 5085 if (xp->dev_state == PMCS_DEVICE_STATE_NON_OPERATIONAL) { 5086 mutex_exit(&xp->statlock); 5087 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5088 pmcs_pwork(pwp, pwrk); 5089 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, "%s: Not " 5090 "sending '%s' because DS is '%s'", __func__, 5091 pmcs_tmf2str(tmf), pmcs_status_str 5092 (PMCOUT_STATUS_IO_DS_NON_OPERATIONAL)); 5093 return (EIO); 5094 } 5095 mutex_exit(&xp->statlock); 5096 } 5097 5098 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5099 "%s: sending '%s' to %s (lun %llu) tag 0x%x", __func__, 5100 pmcs_tmf2str(tmf), pptr->path, (unsigned long long) lun, tag); 5101 pwrk->state = PMCS_WORK_STATE_ONCHIP; 5102 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5103 5104 pmcs_unlock_phy(pptr); 5105 /* 5106 * This is a command sent to the target device, so it can take 5107 * significant amount of time to complete when path & device is busy. 5108 * Set a timeout to 20 seconds 5109 */ 5110 WAIT_FOR(pwrk, 20000, result); 5111 pmcs_pwork(pwp, pwrk); 5112 pmcs_lock_phy(pptr); 5113 xp = pptr->target; 5114 5115 if (result) { 5116 if (xp == NULL) { 5117 return (ETIMEDOUT); 5118 } 5119 5120 mutex_enter(&xp->statlock); 5121 pmcs_start_dev_state_recovery(xp, pptr); 5122 mutex_exit(&xp->statlock); 5123 return (ETIMEDOUT); 5124 } 5125 5126 status = LE_32(msg[2]); 5127 if (status != PMCOUT_STATUS_OK) { 5128 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5129 "%s: status %s for TMF %s action to %s, lun %llu", 5130 __func__, pmcs_status_str(status), pmcs_tmf2str(tmf), 5131 pptr->path, (unsigned long long) lun); 5132 if ((status == PMCOUT_STATUS_IO_DS_NON_OPERATIONAL) || 5133 (status == PMCOUT_STATUS_OPEN_CNX_ERROR_BREAK) || 5134 (status == PMCOUT_STATUS_OPEN_CNX_ERROR_IT_NEXUS_LOSS)) { 5135 ds = PMCS_DEVICE_STATE_NON_OPERATIONAL; 5136 } else if (status == PMCOUT_STATUS_IO_DS_IN_RECOVERY) { 5137 /* 5138 * If the status is IN_RECOVERY, it's an indication 5139 * that it's now time for us to request to have the 5140 * device state set to OPERATIONAL since we're the ones 5141 * that requested recovery to begin with. 5142 */ 5143 ds = PMCS_DEVICE_STATE_OPERATIONAL; 5144 } else { 5145 ds = PMCS_DEVICE_STATE_IN_RECOVERY; 5146 } 5147 if (xp != NULL) { 5148 mutex_enter(&xp->statlock); 5149 if (xp->dev_state != ds) { 5150 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5151 "%s: Sending err recovery cmd" 5152 " for tgt 0x%p (status = %s)", 5153 __func__, (void *)xp, 5154 pmcs_status_str(status)); 5155 (void) pmcs_send_err_recovery_cmd(pwp, ds, 5156 pptr, xp); 5157 } 5158 mutex_exit(&xp->statlock); 5159 } 5160 return (EIO); 5161 } else { 5162 ds = PMCS_DEVICE_STATE_OPERATIONAL; 5163 if (xp != NULL) { 5164 mutex_enter(&xp->statlock); 5165 if (xp->dev_state != ds) { 5166 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5167 "%s: Sending err recovery cmd" 5168 " for tgt 0x%p (status = %s)", 5169 __func__, (void *)xp, 5170 pmcs_status_str(status)); 5171 (void) pmcs_send_err_recovery_cmd(pwp, ds, 5172 pptr, xp); 5173 } 5174 mutex_exit(&xp->statlock); 5175 } 5176 } 5177 if (LE_32(msg[3]) == 0) { 5178 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5179 "TMF completed with no response"); 5180 return (EIO); 5181 } 5182 pmcs_endian_transform(pwp, local, &msg[5], ssp_rsp_evec); 5183 xd = (uint8_t *)(&msg[5]); 5184 xd += SAS_RSP_HDR_SIZE; 5185 if (rptr->datapres != SAS_RSP_DATAPRES_RESPONSE_DATA) { 5186 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5187 "%s: TMF response not RESPONSE DATA (0x%x)", 5188 __func__, rptr->datapres); 5189 return (EIO); 5190 } 5191 if (rptr->response_data_length != 4) { 5192 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, 5193 "Bad SAS RESPONSE DATA LENGTH", msg); 5194 return (EIO); 5195 } 5196 (void) memcpy(&status, xd, sizeof (uint32_t)); 5197 status = BE_32(status); 5198 if (response != NULL) 5199 *response = status; 5200 /* 5201 * The status is actually in the low-order byte. The upper three 5202 * bytes contain additional information for the TMFs that support them. 5203 * However, at this time we do not issue any of those. In the other 5204 * cases, the upper three bytes are supposed to be 0, but it appears 5205 * they aren't always. Just mask them off. 5206 */ 5207 switch (status & 0xff) { 5208 case SAS_RSP_TMF_COMPLETE: 5209 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5210 "%s: TMF complete", __func__); 5211 result = 0; 5212 break; 5213 case SAS_RSP_TMF_SUCCEEDED: 5214 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5215 "%s: TMF succeeded", __func__); 5216 result = 0; 5217 break; 5218 case SAS_RSP_INVALID_FRAME: 5219 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5220 "%s: TMF returned INVALID FRAME", __func__); 5221 result = EIO; 5222 break; 5223 case SAS_RSP_TMF_NOT_SUPPORTED: 5224 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5225 "%s: TMF returned TMF NOT SUPPORTED", __func__); 5226 result = EIO; 5227 break; 5228 case SAS_RSP_TMF_FAILED: 5229 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5230 "%s: TMF returned TMF FAILED", __func__); 5231 result = EIO; 5232 break; 5233 case SAS_RSP_TMF_INCORRECT_LUN: 5234 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5235 "%s: TMF returned INCORRECT LUN", __func__); 5236 result = EIO; 5237 break; 5238 case SAS_RSP_OVERLAPPED_OIPTTA: 5239 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5240 "%s: TMF returned OVERLAPPED INITIATOR PORT TRANSFER TAG " 5241 "ATTEMPTED", __func__); 5242 result = EIO; 5243 break; 5244 default: 5245 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 5246 "%s: TMF returned unknown code 0x%x", __func__, status); 5247 result = EIO; 5248 break; 5249 } 5250 return (result); 5251 } 5252 5253 /* 5254 * Called with PHY lock held and scratch acquired 5255 */ 5256 int 5257 pmcs_sata_abort_ncq(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 5258 { 5259 const char *utag_fail_fmt = "%s: untagged NCQ command failure"; 5260 const char *tag_fail_fmt = "%s: NCQ command failure (tag 0x%x)"; 5261 uint32_t msg[PMCS_QENTRY_SIZE], *ptr, result, status; 5262 uint8_t *fp = pwp->scratch, ds; 5263 fis_t fis; 5264 pmcwork_t *pwrk; 5265 pmcs_xscsi_t *tgt; 5266 5267 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr); 5268 if (pwrk == NULL) { 5269 return (ENOMEM); 5270 } 5271 pwrk->htag |= PMCS_TAG_NONIO_CMD; 5272 msg[0] = LE_32(PMCS_IOMB_IN_SAS(PMCS_OQ_IODONE, 5273 PMCIN_SATA_HOST_IO_START)); 5274 msg[1] = LE_32(pwrk->htag); 5275 msg[2] = LE_32(pptr->device_id); 5276 msg[3] = LE_32(512); 5277 msg[4] = LE_32(SATA_PROTOCOL_PIO | PMCIN_DATADIR_2_INI); 5278 msg[5] = LE_32((READ_LOG_EXT << 16) | (C_BIT << 8) | FIS_REG_H2DEV); 5279 msg[6] = LE_32(0x10); 5280 msg[8] = LE_32(1); 5281 msg[9] = 0; 5282 msg[10] = 0; 5283 msg[11] = 0; 5284 msg[12] = LE_32(DWORD0(pwp->scratch_dma)); 5285 msg[13] = LE_32(DWORD1(pwp->scratch_dma)); 5286 msg[14] = LE_32(512); 5287 msg[15] = 0; 5288 5289 pwrk->arg = msg; 5290 pwrk->dtype = pptr->dtype; 5291 pwrk->xp = pptr->target; 5292 5293 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5294 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5295 if (ptr == NULL) { 5296 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5297 pmcs_pwork(pwp, pwrk); 5298 return (ENOMEM); 5299 } 5300 COPY_MESSAGE(ptr, msg, PMCS_QENTRY_SIZE); 5301 pwrk->state = PMCS_WORK_STATE_ONCHIP; 5302 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5303 5304 pmcs_unlock_phy(pptr); 5305 WAIT_FOR(pwrk, 250, result); 5306 pmcs_pwork(pwp, pwrk); 5307 pmcs_lock_phy(pptr); 5308 5309 tgt = pptr->target; 5310 if (result) { 5311 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, pmcs_timeo, __func__); 5312 return (EIO); 5313 } 5314 status = LE_32(msg[2]); 5315 if (status != PMCOUT_STATUS_OK || LE_32(msg[3])) { 5316 if (tgt == NULL) { 5317 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 5318 "%s: cannot find target for phy 0x%p for " 5319 "dev state recovery", __func__, (void *)pptr); 5320 return (EIO); 5321 } 5322 5323 mutex_enter(&tgt->statlock); 5324 5325 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, "READ LOG EXT", msg); 5326 if ((status == PMCOUT_STATUS_IO_DS_NON_OPERATIONAL) || 5327 (status == PMCOUT_STATUS_OPEN_CNX_ERROR_BREAK) || 5328 (status == PMCOUT_STATUS_OPEN_CNX_ERROR_IT_NEXUS_LOSS)) { 5329 ds = PMCS_DEVICE_STATE_NON_OPERATIONAL; 5330 } else { 5331 ds = PMCS_DEVICE_STATE_IN_RECOVERY; 5332 } 5333 if (tgt->dev_state != ds) { 5334 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, "%s: Trying " 5335 "SATA DS Recovery for tgt(0x%p) for status(%s)", 5336 __func__, (void *)tgt, pmcs_status_str(status)); 5337 (void) pmcs_send_err_recovery_cmd(pwp, ds, pptr, tgt); 5338 } 5339 5340 mutex_exit(&tgt->statlock); 5341 return (EIO); 5342 } 5343 fis[0] = (fp[4] << 24) | (fp[3] << 16) | (fp[2] << 8) | FIS_REG_D2H; 5344 fis[1] = (fp[8] << 24) | (fp[7] << 16) | (fp[6] << 8) | fp[5]; 5345 fis[2] = (fp[12] << 24) | (fp[11] << 16) | (fp[10] << 8) | fp[9]; 5346 fis[3] = (fp[16] << 24) | (fp[15] << 16) | (fp[14] << 8) | fp[13]; 5347 fis[4] = 0; 5348 if (fp[0] & 0x80) { 5349 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 5350 utag_fail_fmt, __func__); 5351 } else { 5352 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 5353 tag_fail_fmt, __func__, fp[0] & 0x1f); 5354 } 5355 pmcs_fis_dump(pwp, fis); 5356 pptr->need_rl_ext = 0; 5357 return (0); 5358 } 5359 5360 /* 5361 * Transform a structure from CPU to Device endian format, or 5362 * vice versa, based upon a transformation vector. 5363 * 5364 * A transformation vector is an array of bytes, each byte 5365 * of which is defined thusly: 5366 * 5367 * bit 7: from CPU to desired endian, otherwise from desired endian 5368 * to CPU format 5369 * bit 6: Big Endian, else Little Endian 5370 * bits 5-4: 5371 * 00 Undefined 5372 * 01 One Byte quantities 5373 * 02 Two Byte quantities 5374 * 03 Four Byte quantities 5375 * 5376 * bits 3-0: 5377 * 00 Undefined 5378 * Number of quantities to transform 5379 * 5380 * The vector is terminated by a 0 value. 5381 */ 5382 5383 void 5384 pmcs_endian_transform(pmcs_hw_t *pwp, void *orig_out, void *orig_in, 5385 const uint8_t *xfvec) 5386 { 5387 uint8_t c, *out = orig_out, *in = orig_in; 5388 5389 if (xfvec == NULL) { 5390 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 5391 "%s: null xfvec", __func__); 5392 return; 5393 } 5394 if (out == NULL) { 5395 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 5396 "%s: null out", __func__); 5397 return; 5398 } 5399 if (in == NULL) { 5400 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 5401 "%s: null in", __func__); 5402 return; 5403 } 5404 while ((c = *xfvec++) != 0) { 5405 int nbyt = (c & 0xf); 5406 int size = (c >> 4) & 0x3; 5407 int bige = (c >> 4) & 0x4; 5408 5409 switch (size) { 5410 case 1: 5411 { 5412 while (nbyt-- > 0) { 5413 *out++ = *in++; 5414 } 5415 break; 5416 } 5417 case 2: 5418 { 5419 uint16_t tmp; 5420 while (nbyt-- > 0) { 5421 (void) memcpy(&tmp, in, sizeof (uint16_t)); 5422 if (bige) { 5423 tmp = BE_16(tmp); 5424 } else { 5425 tmp = LE_16(tmp); 5426 } 5427 (void) memcpy(out, &tmp, sizeof (uint16_t)); 5428 out += sizeof (uint16_t); 5429 in += sizeof (uint16_t); 5430 } 5431 break; 5432 } 5433 case 3: 5434 { 5435 uint32_t tmp; 5436 while (nbyt-- > 0) { 5437 (void) memcpy(&tmp, in, sizeof (uint32_t)); 5438 if (bige) { 5439 tmp = BE_32(tmp); 5440 } else { 5441 tmp = LE_32(tmp); 5442 } 5443 (void) memcpy(out, &tmp, sizeof (uint32_t)); 5444 out += sizeof (uint32_t); 5445 in += sizeof (uint32_t); 5446 } 5447 break; 5448 } 5449 default: 5450 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 5451 "%s: bad size", __func__); 5452 return; 5453 } 5454 } 5455 } 5456 5457 const char * 5458 pmcs_get_rate(unsigned int linkrt) 5459 { 5460 const char *rate; 5461 switch (linkrt) { 5462 case SAS_LINK_RATE_1_5GBIT: 5463 rate = "1.5"; 5464 break; 5465 case SAS_LINK_RATE_3GBIT: 5466 rate = "3.0"; 5467 break; 5468 case SAS_LINK_RATE_6GBIT: 5469 rate = "6.0"; 5470 break; 5471 default: 5472 rate = "???"; 5473 break; 5474 } 5475 return (rate); 5476 } 5477 5478 const char * 5479 pmcs_get_typename(pmcs_dtype_t type) 5480 { 5481 switch (type) { 5482 case NOTHING: 5483 return ("NIL"); 5484 case SATA: 5485 return ("SATA"); 5486 case SAS: 5487 return ("SSP"); 5488 case EXPANDER: 5489 return ("EXPANDER"); 5490 } 5491 return ("????"); 5492 } 5493 5494 const char * 5495 pmcs_tmf2str(int tmf) 5496 { 5497 switch (tmf) { 5498 case SAS_ABORT_TASK: 5499 return ("Abort Task"); 5500 case SAS_ABORT_TASK_SET: 5501 return ("Abort Task Set"); 5502 case SAS_CLEAR_TASK_SET: 5503 return ("Clear Task Set"); 5504 case SAS_LOGICAL_UNIT_RESET: 5505 return ("Logical Unit Reset"); 5506 case SAS_I_T_NEXUS_RESET: 5507 return ("I_T Nexus Reset"); 5508 case SAS_CLEAR_ACA: 5509 return ("Clear ACA"); 5510 case SAS_QUERY_TASK: 5511 return ("Query Task"); 5512 case SAS_QUERY_TASK_SET: 5513 return ("Query Task Set"); 5514 case SAS_QUERY_UNIT_ATTENTION: 5515 return ("Query Unit Attention"); 5516 default: 5517 return ("Unknown"); 5518 } 5519 } 5520 5521 const char * 5522 pmcs_status_str(uint32_t status) 5523 { 5524 switch (status) { 5525 case PMCOUT_STATUS_OK: 5526 return ("OK"); 5527 case PMCOUT_STATUS_ABORTED: 5528 return ("ABORTED"); 5529 case PMCOUT_STATUS_OVERFLOW: 5530 return ("OVERFLOW"); 5531 case PMCOUT_STATUS_UNDERFLOW: 5532 return ("UNDERFLOW"); 5533 case PMCOUT_STATUS_FAILED: 5534 return ("FAILED"); 5535 case PMCOUT_STATUS_ABORT_RESET: 5536 return ("ABORT_RESET"); 5537 case PMCOUT_STATUS_IO_NOT_VALID: 5538 return ("IO_NOT_VALID"); 5539 case PMCOUT_STATUS_NO_DEVICE: 5540 return ("NO_DEVICE"); 5541 case PMCOUT_STATUS_ILLEGAL_PARAMETER: 5542 return ("ILLEGAL_PARAMETER"); 5543 case PMCOUT_STATUS_LINK_FAILURE: 5544 return ("LINK_FAILURE"); 5545 case PMCOUT_STATUS_PROG_ERROR: 5546 return ("PROG_ERROR"); 5547 case PMCOUT_STATUS_EDC_IN_ERROR: 5548 return ("EDC_IN_ERROR"); 5549 case PMCOUT_STATUS_EDC_OUT_ERROR: 5550 return ("EDC_OUT_ERROR"); 5551 case PMCOUT_STATUS_ERROR_HW_TIMEOUT: 5552 return ("ERROR_HW_TIMEOUT"); 5553 case PMCOUT_STATUS_XFER_ERR_BREAK: 5554 return ("XFER_ERR_BREAK"); 5555 case PMCOUT_STATUS_XFER_ERR_PHY_NOT_READY: 5556 return ("XFER_ERR_PHY_NOT_READY"); 5557 case PMCOUT_STATUS_OPEN_CNX_PROTOCOL_NOT_SUPPORTED: 5558 return ("OPEN_CNX_PROTOCOL_NOT_SUPPORTED"); 5559 case PMCOUT_STATUS_OPEN_CNX_ERROR_ZONE_VIOLATION: 5560 return ("OPEN_CNX_ERROR_ZONE_VIOLATION"); 5561 case PMCOUT_STATUS_OPEN_CNX_ERROR_BREAK: 5562 return ("OPEN_CNX_ERROR_BREAK"); 5563 case PMCOUT_STATUS_OPEN_CNX_ERROR_IT_NEXUS_LOSS: 5564 return ("OPEN_CNX_ERROR_IT_NEXUS_LOSS"); 5565 case PMCOUT_STATUS_OPENCNX_ERROR_BAD_DESTINATION: 5566 return ("OPENCNX_ERROR_BAD_DESTINATION"); 5567 case PMCOUT_STATUS_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: 5568 return ("OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED"); 5569 case PMCOUT_STATUS_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: 5570 return ("OPEN_CNX_ERROR_STP_RESOURCES_BUSY"); 5571 case PMCOUT_STATUS_OPEN_CNX_ERROR_WRONG_DESTINATION: 5572 return ("OPEN_CNX_ERROR_WRONG_DESTINATION"); 5573 case PMCOUT_STATUS_OPEN_CNX_ERROR_UNKNOWN_ERROR: 5574 return ("OPEN_CNX_ERROR_UNKNOWN_ERROR"); 5575 case PMCOUT_STATUS_IO_XFER_ERROR_NAK_RECEIVED: 5576 return ("IO_XFER_ERROR_NAK_RECEIVED"); 5577 case PMCOUT_STATUS_XFER_ERROR_ACK_NAK_TIMEOUT: 5578 return ("XFER_ERROR_ACK_NAK_TIMEOUT"); 5579 case PMCOUT_STATUS_XFER_ERROR_PEER_ABORTED: 5580 return ("XFER_ERROR_PEER_ABORTED"); 5581 case PMCOUT_STATUS_XFER_ERROR_RX_FRAME: 5582 return ("XFER_ERROR_RX_FRAME"); 5583 case PMCOUT_STATUS_IO_XFER_ERROR_DMA: 5584 return ("IO_XFER_ERROR_DMA"); 5585 case PMCOUT_STATUS_XFER_ERROR_CREDIT_TIMEOUT: 5586 return ("XFER_ERROR_CREDIT_TIMEOUT"); 5587 case PMCOUT_STATUS_XFER_ERROR_SATA_LINK_TIMEOUT: 5588 return ("XFER_ERROR_SATA_LINK_TIMEOUT"); 5589 case PMCOUT_STATUS_XFER_ERROR_SATA: 5590 return ("XFER_ERROR_SATA"); 5591 case PMCOUT_STATUS_XFER_ERROR_REJECTED_NCQ_MODE: 5592 return ("XFER_ERROR_REJECTED_NCQ_MODE"); 5593 case PMCOUT_STATUS_XFER_ERROR_ABORTED_DUE_TO_SRST: 5594 return ("XFER_ERROR_ABORTED_DUE_TO_SRST"); 5595 case PMCOUT_STATUS_XFER_ERROR_ABORTED_NCQ_MODE: 5596 return ("XFER_ERROR_ABORTED_NCQ_MODE"); 5597 case PMCOUT_STATUS_IO_XFER_OPEN_RETRY_TIMEOUT: 5598 return ("IO_XFER_OPEN_RETRY_TIMEOUT"); 5599 case PMCOUT_STATUS_SMP_RESP_CONNECTION_ERROR: 5600 return ("SMP_RESP_CONNECTION_ERROR"); 5601 case PMCOUT_STATUS_XFER_ERROR_UNEXPECTED_PHASE: 5602 return ("XFER_ERROR_UNEXPECTED_PHASE"); 5603 case PMCOUT_STATUS_XFER_ERROR_RDY_OVERRUN: 5604 return ("XFER_ERROR_RDY_OVERRUN"); 5605 case PMCOUT_STATUS_XFER_ERROR_RDY_NOT_EXPECTED: 5606 return ("XFER_ERROR_RDY_NOT_EXPECTED"); 5607 case PMCOUT_STATUS_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT: 5608 return ("XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT"); 5609 case PMCOUT_STATUS_XFER_ERROR_CMD_ISSUE_BREAK_BEFORE_ACK_NACK: 5610 return ("XFER_ERROR_CMD_ISSUE_BREAK_BEFORE_ACK_NACK"); 5611 case PMCOUT_STATUS_XFER_ERROR_CMD_ISSUE_PHY_DOWN_BEFORE_ACK_NAK: 5612 return ("XFER_ERROR_CMD_ISSUE_PHY_DOWN_BEFORE_ACK_NAK"); 5613 case PMCOUT_STATUS_XFER_ERROR_OFFSET_MISMATCH: 5614 return ("XFER_ERROR_OFFSET_MISMATCH"); 5615 case PMCOUT_STATUS_XFER_ERROR_ZERO_DATA_LEN: 5616 return ("XFER_ERROR_ZERO_DATA_LEN"); 5617 case PMCOUT_STATUS_XFER_CMD_FRAME_ISSUED: 5618 return ("XFER_CMD_FRAME_ISSUED"); 5619 case PMCOUT_STATUS_ERROR_INTERNAL_SMP_RESOURCE: 5620 return ("ERROR_INTERNAL_SMP_RESOURCE"); 5621 case PMCOUT_STATUS_IO_PORT_IN_RESET: 5622 return ("IO_PORT_IN_RESET"); 5623 case PMCOUT_STATUS_IO_DS_NON_OPERATIONAL: 5624 return ("DEVICE STATE NON-OPERATIONAL"); 5625 case PMCOUT_STATUS_IO_DS_IN_RECOVERY: 5626 return ("DEVICE STATE IN RECOVERY"); 5627 case PMCOUT_STATUS_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: 5628 return ("OPEN CNX ERR HW RESOURCE BUSY"); 5629 default: 5630 return (NULL); 5631 } 5632 } 5633 5634 uint64_t 5635 pmcs_barray2wwn(uint8_t ba[8]) 5636 { 5637 uint64_t result = 0; 5638 int i; 5639 5640 for (i = 0; i < 8; i++) { 5641 result <<= 8; 5642 result |= ba[i]; 5643 } 5644 return (result); 5645 } 5646 5647 void 5648 pmcs_wwn2barray(uint64_t wwn, uint8_t ba[8]) 5649 { 5650 int i; 5651 for (i = 0; i < 8; i++) { 5652 ba[7 - i] = wwn & 0xff; 5653 wwn >>= 8; 5654 } 5655 } 5656 5657 void 5658 pmcs_report_fwversion(pmcs_hw_t *pwp) 5659 { 5660 const char *fwsupport; 5661 switch (PMCS_FW_TYPE(pwp)) { 5662 case PMCS_FW_TYPE_RELEASED: 5663 fwsupport = "Released"; 5664 break; 5665 case PMCS_FW_TYPE_DEVELOPMENT: 5666 fwsupport = "Development"; 5667 break; 5668 case PMCS_FW_TYPE_ALPHA: 5669 fwsupport = "Alpha"; 5670 break; 5671 case PMCS_FW_TYPE_BETA: 5672 fwsupport = "Beta"; 5673 break; 5674 default: 5675 fwsupport = "Special"; 5676 break; 5677 } 5678 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 5679 "Chip Revision: %c; F/W Revision %x.%x.%x %s (ILA rev %08x)", 5680 'A' + pwp->chiprev, PMCS_FW_MAJOR(pwp), PMCS_FW_MINOR(pwp), 5681 PMCS_FW_MICRO(pwp), fwsupport, pwp->ila_ver); 5682 } 5683 5684 void 5685 pmcs_phy_name(pmcs_hw_t *pwp, pmcs_phy_t *pptr, char *obuf, size_t olen) 5686 { 5687 if (pptr->parent) { 5688 pmcs_phy_name(pwp, pptr->parent, obuf, olen); 5689 (void) snprintf(obuf, olen, "%s.%02x", obuf, pptr->phynum); 5690 } else { 5691 (void) snprintf(obuf, olen, "pp%02x", pptr->phynum); 5692 } 5693 } 5694 5695 /* 5696 * This function is called as a sanity check to ensure that a newly registered 5697 * PHY doesn't have a device_id that exists with another registered PHY. 5698 */ 5699 static boolean_t 5700 pmcs_validate_devid(pmcs_phy_t *parent, pmcs_phy_t *phyp, uint32_t device_id) 5701 { 5702 pmcs_phy_t *pptr, *pchild; 5703 boolean_t rval; 5704 5705 pptr = parent; 5706 5707 while (pptr) { 5708 if (pptr->valid_device_id && (pptr != phyp) && 5709 (pptr->device_id == device_id)) { 5710 /* 5711 * This can still be OK if both of these PHYs actually 5712 * represent the same device (e.g. expander). It could 5713 * be a case of a new "primary" PHY. If the SAS address 5714 * is the same and they have the same parent, we'll 5715 * accept this if the PHY to be registered is the 5716 * primary. 5717 */ 5718 if ((phyp->parent == pptr->parent) && 5719 (memcmp(phyp->sas_address, 5720 pptr->sas_address, 8) == 0) && (phyp->width > 1)) { 5721 /* 5722 * Move children over to the new primary and 5723 * update both PHYs 5724 */ 5725 pmcs_lock_phy(pptr); 5726 phyp->children = pptr->children; 5727 pchild = phyp->children; 5728 while (pchild) { 5729 pchild->parent = phyp; 5730 pchild = pchild->sibling; 5731 } 5732 phyp->subsidiary = 0; 5733 phyp->ncphy = pptr->ncphy; 5734 /* 5735 * device_id, valid_device_id, and configured 5736 * will be set by the caller 5737 */ 5738 pptr->children = NULL; 5739 pptr->subsidiary = 1; 5740 pptr->ncphy = 0; 5741 pmcs_unlock_phy(pptr); 5742 pmcs_prt(pptr->pwp, PMCS_PRT_DEBUG, pptr, NULL, 5743 "%s: Moving device_id %d from PHY %s to %s", 5744 __func__, device_id, pptr->path, 5745 phyp->path); 5746 return (B_TRUE); 5747 } 5748 pmcs_prt(pptr->pwp, PMCS_PRT_DEBUG, pptr, NULL, 5749 "%s: phy %s already exists as %s with " 5750 "device id 0x%x", __func__, phyp->path, 5751 pptr->path, device_id); 5752 return (B_FALSE); 5753 } 5754 5755 if (pptr->children) { 5756 rval = pmcs_validate_devid(pptr->children, phyp, 5757 device_id); 5758 if (rval == B_FALSE) { 5759 return (rval); 5760 } 5761 } 5762 5763 pptr = pptr->sibling; 5764 } 5765 5766 /* This PHY and device_id are valid */ 5767 return (B_TRUE); 5768 } 5769 5770 /* 5771 * If the PHY is found, it is returned locked 5772 */ 5773 static pmcs_phy_t * 5774 pmcs_find_phy_by_wwn_impl(pmcs_phy_t *phyp, uint8_t *wwn) 5775 { 5776 pmcs_phy_t *matched_phy, *cphyp, *nphyp; 5777 5778 ASSERT(!mutex_owned(&phyp->phy_lock)); 5779 5780 while (phyp) { 5781 pmcs_lock_phy(phyp); 5782 5783 if (phyp->valid_device_id) { 5784 if (memcmp(phyp->sas_address, wwn, 8) == 0) { 5785 return (phyp); 5786 } 5787 } 5788 5789 if (phyp->children) { 5790 cphyp = phyp->children; 5791 pmcs_unlock_phy(phyp); 5792 matched_phy = pmcs_find_phy_by_wwn_impl(cphyp, wwn); 5793 if (matched_phy) { 5794 ASSERT(mutex_owned(&matched_phy->phy_lock)); 5795 return (matched_phy); 5796 } 5797 pmcs_lock_phy(phyp); 5798 } 5799 5800 /* 5801 * Only iterate through non-root PHYs 5802 */ 5803 if (IS_ROOT_PHY(phyp)) { 5804 pmcs_unlock_phy(phyp); 5805 phyp = NULL; 5806 } else { 5807 nphyp = phyp->sibling; 5808 pmcs_unlock_phy(phyp); 5809 phyp = nphyp; 5810 } 5811 } 5812 5813 return (NULL); 5814 } 5815 5816 pmcs_phy_t * 5817 pmcs_find_phy_by_wwn(pmcs_hw_t *pwp, uint64_t wwn) 5818 { 5819 uint8_t ebstr[8]; 5820 pmcs_phy_t *pptr, *matched_phy; 5821 5822 pmcs_wwn2barray(wwn, ebstr); 5823 5824 pptr = pwp->root_phys; 5825 while (pptr) { 5826 matched_phy = pmcs_find_phy_by_wwn_impl(pptr, ebstr); 5827 if (matched_phy) { 5828 ASSERT(mutex_owned(&matched_phy->phy_lock)); 5829 return (matched_phy); 5830 } 5831 5832 pptr = pptr->sibling; 5833 } 5834 5835 return (NULL); 5836 } 5837 5838 5839 /* 5840 * pmcs_find_phy_by_sas_address 5841 * 5842 * Find a PHY that both matches "sas_addr" and is on "iport". 5843 * If a matching PHY is found, it is returned locked. 5844 */ 5845 pmcs_phy_t * 5846 pmcs_find_phy_by_sas_address(pmcs_hw_t *pwp, pmcs_iport_t *iport, 5847 pmcs_phy_t *root, char *sas_addr) 5848 { 5849 int ua_form = 1; 5850 uint64_t wwn; 5851 char addr[PMCS_MAX_UA_SIZE]; 5852 pmcs_phy_t *pptr, *pnext, *pchild; 5853 5854 if (root == NULL) { 5855 pptr = pwp->root_phys; 5856 } else { 5857 pptr = root; 5858 } 5859 5860 while (pptr) { 5861 pmcs_lock_phy(pptr); 5862 /* 5863 * If the PHY is dead or does not have a valid device ID, 5864 * skip it. 5865 */ 5866 if ((pptr->dead) || (!pptr->valid_device_id)) { 5867 goto next_phy; 5868 } 5869 5870 if (pptr->iport != iport) { 5871 goto next_phy; 5872 } 5873 5874 wwn = pmcs_barray2wwn(pptr->sas_address); 5875 (void *) scsi_wwn_to_wwnstr(wwn, ua_form, addr); 5876 if (strncmp(addr, sas_addr, strlen(addr)) == 0) { 5877 return (pptr); 5878 } 5879 5880 if (pptr->children) { 5881 pchild = pptr->children; 5882 pmcs_unlock_phy(pptr); 5883 pnext = pmcs_find_phy_by_sas_address(pwp, iport, pchild, 5884 sas_addr); 5885 if (pnext) { 5886 return (pnext); 5887 } 5888 pmcs_lock_phy(pptr); 5889 } 5890 5891 next_phy: 5892 pnext = pptr->sibling; 5893 pmcs_unlock_phy(pptr); 5894 pptr = pnext; 5895 } 5896 5897 return (NULL); 5898 } 5899 5900 void 5901 pmcs_fis_dump(pmcs_hw_t *pwp, fis_t fis) 5902 { 5903 switch (fis[0] & 0xff) { 5904 case FIS_REG_H2DEV: 5905 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 5906 "FIS REGISTER HOST TO DEVICE: " 5907 "OP=0x%02x Feature=0x%04x Count=0x%04x Device=0x%02x " 5908 "LBA=%llu", BYTE2(fis[0]), BYTE3(fis[2]) << 8 | 5909 BYTE3(fis[0]), WORD0(fis[3]), BYTE3(fis[1]), 5910 (unsigned long long) 5911 (((uint64_t)fis[2] & 0x00ffffff) << 24 | 5912 ((uint64_t)fis[1] & 0x00ffffff))); 5913 break; 5914 case FIS_REG_D2H: 5915 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 5916 "FIS REGISTER DEVICE TO HOST: Status=0x%02x " 5917 "Error=0x%02x Dev=0x%02x Count=0x%04x LBA=%llu", 5918 BYTE2(fis[0]), BYTE3(fis[0]), BYTE3(fis[1]), WORD0(fis[3]), 5919 (unsigned long long)(((uint64_t)fis[2] & 0x00ffffff) << 24 | 5920 ((uint64_t)fis[1] & 0x00ffffff))); 5921 break; 5922 default: 5923 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 5924 "FIS: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", 5925 fis[0], fis[1], fis[2], fis[3], fis[4]); 5926 break; 5927 } 5928 } 5929 5930 void 5931 pmcs_print_entry(pmcs_hw_t *pwp, int level, char *msg, void *arg) 5932 { 5933 uint32_t *mb = arg; 5934 size_t i; 5935 5936 pmcs_prt(pwp, level, NULL, NULL, msg); 5937 for (i = 0; i < (PMCS_QENTRY_SIZE / sizeof (uint32_t)); i += 4) { 5938 pmcs_prt(pwp, level, NULL, NULL, 5939 "Offset %2lu: 0x%08x 0x%08x 0x%08x 0x%08x", 5940 i * sizeof (uint32_t), LE_32(mb[i]), 5941 LE_32(mb[i+1]), LE_32(mb[i+2]), LE_32(mb[i+3])); 5942 } 5943 } 5944 5945 /* 5946 * If phyp == NULL we're being called from the worker thread, in which 5947 * case we need to check all the PHYs. In this case, the softstate lock 5948 * will be held. 5949 * If phyp is non-NULL, just issue the spinup release for the specified PHY 5950 * (which will already be locked). 5951 */ 5952 void 5953 pmcs_spinup_release(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 5954 { 5955 uint32_t *msg; 5956 struct pmcwork *pwrk; 5957 pmcs_phy_t *tphyp; 5958 5959 if (phyp != NULL) { 5960 ASSERT(mutex_owned(&phyp->phy_lock)); 5961 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, NULL, 5962 "%s: Issuing spinup release only for PHY %s", __func__, 5963 phyp->path); 5964 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5965 msg = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5966 if (msg == NULL || (pwrk = 5967 pmcs_gwork(pwp, PMCS_TAG_TYPE_NONE, NULL)) == NULL) { 5968 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5969 SCHEDULE_WORK(pwp, PMCS_WORK_SPINUP_RELEASE); 5970 return; 5971 } 5972 5973 phyp->spinup_hold = 0; 5974 bzero(msg, PMCS_QENTRY_SIZE); 5975 pwrk->htag |= PMCS_TAG_NONIO_CMD; 5976 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 5977 PMCIN_LOCAL_PHY_CONTROL)); 5978 msg[1] = LE_32(pwrk->htag); 5979 msg[2] = LE_32((0x10 << 8) | phyp->phynum); 5980 5981 pwrk->dtype = phyp->dtype; 5982 pwrk->state = PMCS_WORK_STATE_ONCHIP; 5983 pwrk->xp = phyp->target; 5984 mutex_exit(&pwrk->lock); 5985 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5986 return; 5987 } 5988 5989 ASSERT(mutex_owned(&pwp->lock)); 5990 5991 tphyp = pwp->root_phys; 5992 while (tphyp) { 5993 pmcs_lock_phy(tphyp); 5994 if (tphyp->spinup_hold == 0) { 5995 pmcs_unlock_phy(tphyp); 5996 tphyp = tphyp->sibling; 5997 continue; 5998 } 5999 6000 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, tphyp, NULL, 6001 "%s: Issuing spinup release for PHY %s", __func__, 6002 tphyp->path); 6003 6004 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 6005 msg = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 6006 if (msg == NULL || (pwrk = 6007 pmcs_gwork(pwp, PMCS_TAG_TYPE_NONE, NULL)) == NULL) { 6008 pmcs_unlock_phy(tphyp); 6009 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 6010 SCHEDULE_WORK(pwp, PMCS_WORK_SPINUP_RELEASE); 6011 break; 6012 } 6013 6014 tphyp->spinup_hold = 0; 6015 bzero(msg, PMCS_QENTRY_SIZE); 6016 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 6017 PMCIN_LOCAL_PHY_CONTROL)); 6018 msg[1] = LE_32(pwrk->htag); 6019 msg[2] = LE_32((0x10 << 8) | tphyp->phynum); 6020 6021 pwrk->dtype = tphyp->dtype; 6022 pwrk->state = PMCS_WORK_STATE_ONCHIP; 6023 pwrk->xp = tphyp->target; 6024 mutex_exit(&pwrk->lock); 6025 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 6026 pmcs_unlock_phy(tphyp); 6027 6028 tphyp = tphyp->sibling; 6029 } 6030 } 6031 6032 /* 6033 * Abort commands on dead PHYs and deregister them as well as removing 6034 * the associated targets. 6035 */ 6036 static int 6037 pmcs_kill_devices(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 6038 { 6039 pmcs_phy_t *pnext, *pchild; 6040 boolean_t remove_device; 6041 int rval = 0; 6042 6043 while (phyp) { 6044 pmcs_lock_phy(phyp); 6045 pchild = phyp->children; 6046 pnext = phyp->sibling; 6047 pmcs_unlock_phy(phyp); 6048 6049 if (pchild) { 6050 rval = pmcs_kill_devices(pwp, pchild); 6051 if (rval) { 6052 return (rval); 6053 } 6054 } 6055 6056 mutex_enter(&pwp->lock); 6057 pmcs_lock_phy(phyp); 6058 if (phyp->dead && phyp->valid_device_id) { 6059 remove_device = B_TRUE; 6060 } else { 6061 remove_device = B_FALSE; 6062 } 6063 6064 if (remove_device) { 6065 pmcs_remove_device(pwp, phyp); 6066 mutex_exit(&pwp->lock); 6067 6068 rval = pmcs_kill_device(pwp, phyp); 6069 if (rval) { 6070 pmcs_unlock_phy(phyp); 6071 return (rval); 6072 } 6073 } else { 6074 mutex_exit(&pwp->lock); 6075 } 6076 6077 pmcs_unlock_phy(phyp); 6078 phyp = pnext; 6079 } 6080 6081 return (rval); 6082 } 6083 6084 /* 6085 * Called with PHY locked 6086 */ 6087 int 6088 pmcs_kill_device(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 6089 { 6090 int rval; 6091 6092 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, "kill %s device @ %s", 6093 pmcs_get_typename(pptr->dtype), pptr->path); 6094 6095 /* 6096 * There may be an outstanding ABORT_ALL running, which we wouldn't 6097 * know just by checking abort_pending. We can, however, check 6098 * abort_all_start. If it's non-zero, there is one, and we'll just 6099 * sit here and wait for it to complete. If we don't, we'll remove 6100 * the device while there are still commands pending. 6101 */ 6102 if (pptr->abort_all_start) { 6103 while (pptr->abort_all_start) { 6104 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 6105 "%s: Waiting for outstanding ABORT_ALL on PHY 0x%p", 6106 __func__, (void *)pptr); 6107 cv_wait(&pptr->abort_all_cv, &pptr->phy_lock); 6108 } 6109 } else if (pptr->abort_pending) { 6110 rval = pmcs_abort(pwp, pptr, pptr->device_id, 1, 1); 6111 if (rval) { 6112 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 6113 "%s: ABORT_ALL returned non-zero status (%d) for " 6114 "PHY 0x%p", __func__, rval, (void *)pptr); 6115 return (rval); 6116 } 6117 pptr->abort_pending = 0; 6118 } 6119 6120 if (pptr->valid_device_id) { 6121 pmcs_deregister_device(pwp, pptr); 6122 } 6123 6124 PHY_CHANGED(pwp, pptr); 6125 RESTART_DISCOVERY(pwp); 6126 pptr->valid_device_id = 0; 6127 return (0); 6128 } 6129 6130 /* 6131 * Acknowledge the SAS h/w events that need acknowledgement. 6132 * This is only needed for first level PHYs. 6133 */ 6134 void 6135 pmcs_ack_events(pmcs_hw_t *pwp) 6136 { 6137 uint32_t msg[PMCS_MSG_SIZE], *ptr; 6138 struct pmcwork *pwrk; 6139 pmcs_phy_t *pptr; 6140 6141 for (pptr = pwp->root_phys; pptr; pptr = pptr->sibling) { 6142 pmcs_lock_phy(pptr); 6143 if (pptr->hw_event_ack == 0) { 6144 pmcs_unlock_phy(pptr); 6145 continue; 6146 } 6147 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 6148 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 6149 6150 if ((ptr == NULL) || (pwrk = 6151 pmcs_gwork(pwp, PMCS_TAG_TYPE_NONE, NULL)) == NULL) { 6152 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 6153 pmcs_unlock_phy(pptr); 6154 SCHEDULE_WORK(pwp, PMCS_WORK_SAS_HW_ACK); 6155 break; 6156 } 6157 6158 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 6159 PMCIN_SAS_HW_EVENT_ACK)); 6160 msg[1] = LE_32(pwrk->htag); 6161 msg[2] = LE_32(pptr->hw_event_ack); 6162 6163 mutex_exit(&pwrk->lock); 6164 pwrk->dtype = pptr->dtype; 6165 pptr->hw_event_ack = 0; 6166 COPY_MESSAGE(ptr, msg, 3); 6167 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 6168 pmcs_unlock_phy(pptr); 6169 } 6170 } 6171 6172 /* 6173 * Load DMA 6174 */ 6175 int 6176 pmcs_dma_load(pmcs_hw_t *pwp, pmcs_cmd_t *sp, uint32_t *msg) 6177 { 6178 ddi_dma_cookie_t *sg; 6179 pmcs_dmachunk_t *tc; 6180 pmcs_dmasgl_t *sgl, *prior; 6181 int seg, tsc; 6182 uint64_t sgl_addr; 6183 6184 /* 6185 * If we have no data segments, we're done. 6186 */ 6187 if (CMD2PKT(sp)->pkt_numcookies == 0) { 6188 return (0); 6189 } 6190 6191 /* 6192 * Get the S/G list pointer. 6193 */ 6194 sg = CMD2PKT(sp)->pkt_cookies; 6195 6196 /* 6197 * If we only have one dma segment, we can directly address that 6198 * data within the Inbound message itself. 6199 */ 6200 if (CMD2PKT(sp)->pkt_numcookies == 1) { 6201 msg[12] = LE_32(DWORD0(sg->dmac_laddress)); 6202 msg[13] = LE_32(DWORD1(sg->dmac_laddress)); 6203 msg[14] = LE_32(sg->dmac_size); 6204 msg[15] = 0; 6205 return (0); 6206 } 6207 6208 /* 6209 * Otherwise, we'll need one or more external S/G list chunks. 6210 * Get the first one and its dma address into the Inbound message. 6211 */ 6212 mutex_enter(&pwp->dma_lock); 6213 tc = pwp->dma_freelist; 6214 if (tc == NULL) { 6215 SCHEDULE_WORK(pwp, PMCS_WORK_ADD_DMA_CHUNKS); 6216 mutex_exit(&pwp->dma_lock); 6217 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, 6218 "%s: out of SG lists", __func__); 6219 return (-1); 6220 } 6221 pwp->dma_freelist = tc->nxt; 6222 mutex_exit(&pwp->dma_lock); 6223 6224 tc->nxt = NULL; 6225 sp->cmd_clist = tc; 6226 sgl = tc->chunks; 6227 (void) memset(tc->chunks, 0, PMCS_SGL_CHUNKSZ); 6228 sgl_addr = tc->addr; 6229 msg[12] = LE_32(DWORD0(sgl_addr)); 6230 msg[13] = LE_32(DWORD1(sgl_addr)); 6231 msg[14] = 0; 6232 msg[15] = LE_32(PMCS_DMASGL_EXTENSION); 6233 6234 prior = sgl; 6235 tsc = 0; 6236 6237 for (seg = 0; seg < CMD2PKT(sp)->pkt_numcookies; seg++) { 6238 /* 6239 * If the current segment count for this chunk is one less than 6240 * the number s/g lists per chunk and we have more than one seg 6241 * to go, we need another chunk. Get it, and make sure that the 6242 * tail end of the the previous chunk points the new chunk 6243 * (if remembering an offset can be called 'pointing to'). 6244 * 6245 * Note that we can store the offset into our command area that 6246 * represents the new chunk in the length field of the part 6247 * that points the PMC chip at the next chunk- the PMC chip 6248 * ignores this field when the EXTENSION bit is set. 6249 * 6250 * This is required for dma unloads later. 6251 */ 6252 if (tsc == (PMCS_SGL_NCHUNKS - 1) && 6253 seg < (CMD2PKT(sp)->pkt_numcookies - 1)) { 6254 mutex_enter(&pwp->dma_lock); 6255 tc = pwp->dma_freelist; 6256 if (tc == NULL) { 6257 SCHEDULE_WORK(pwp, PMCS_WORK_ADD_DMA_CHUNKS); 6258 mutex_exit(&pwp->dma_lock); 6259 pmcs_dma_unload(pwp, sp); 6260 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, 6261 "%s: out of SG lists", __func__); 6262 return (-1); 6263 } 6264 pwp->dma_freelist = tc->nxt; 6265 tc->nxt = sp->cmd_clist; 6266 mutex_exit(&pwp->dma_lock); 6267 6268 sp->cmd_clist = tc; 6269 (void) memset(tc->chunks, 0, PMCS_SGL_CHUNKSZ); 6270 sgl = tc->chunks; 6271 sgl_addr = tc->addr; 6272 prior[PMCS_SGL_NCHUNKS-1].sglal = 6273 LE_32(DWORD0(sgl_addr)); 6274 prior[PMCS_SGL_NCHUNKS-1].sglah = 6275 LE_32(DWORD1(sgl_addr)); 6276 prior[PMCS_SGL_NCHUNKS-1].sglen = 0; 6277 prior[PMCS_SGL_NCHUNKS-1].flags = 6278 LE_32(PMCS_DMASGL_EXTENSION); 6279 prior = sgl; 6280 tsc = 0; 6281 } 6282 sgl[tsc].sglal = LE_32(DWORD0(sg->dmac_laddress)); 6283 sgl[tsc].sglah = LE_32(DWORD1(sg->dmac_laddress)); 6284 sgl[tsc].sglen = LE_32(sg->dmac_size); 6285 sgl[tsc++].flags = 0; 6286 sg++; 6287 } 6288 return (0); 6289 } 6290 6291 /* 6292 * Unload DMA 6293 */ 6294 void 6295 pmcs_dma_unload(pmcs_hw_t *pwp, pmcs_cmd_t *sp) 6296 { 6297 pmcs_dmachunk_t *cp; 6298 6299 mutex_enter(&pwp->dma_lock); 6300 while ((cp = sp->cmd_clist) != NULL) { 6301 sp->cmd_clist = cp->nxt; 6302 cp->nxt = pwp->dma_freelist; 6303 pwp->dma_freelist = cp; 6304 } 6305 mutex_exit(&pwp->dma_lock); 6306 } 6307 6308 /* 6309 * Take a chunk of consistent memory that has just been allocated and inserted 6310 * into the cip indices and prepare it for DMA chunk usage and add it to the 6311 * freelist. 6312 * 6313 * Called with dma_lock locked (except during attach when it's unnecessary) 6314 */ 6315 void 6316 pmcs_idma_chunks(pmcs_hw_t *pwp, pmcs_dmachunk_t *dcp, 6317 pmcs_chunk_t *pchunk, unsigned long lim) 6318 { 6319 unsigned long off, n; 6320 pmcs_dmachunk_t *np = dcp; 6321 pmcs_chunk_t *tmp_chunk; 6322 6323 if (pwp->dma_chunklist == NULL) { 6324 pwp->dma_chunklist = pchunk; 6325 } else { 6326 tmp_chunk = pwp->dma_chunklist; 6327 while (tmp_chunk->next) { 6328 tmp_chunk = tmp_chunk->next; 6329 } 6330 tmp_chunk->next = pchunk; 6331 } 6332 6333 /* 6334 * Install offsets into chunk lists. 6335 */ 6336 for (n = 0, off = 0; off < lim; off += PMCS_SGL_CHUNKSZ, n++) { 6337 np->chunks = (void *)&pchunk->addrp[off]; 6338 np->addr = pchunk->dma_addr + off; 6339 np->acc_handle = pchunk->acc_handle; 6340 np->dma_handle = pchunk->dma_handle; 6341 if ((off + PMCS_SGL_CHUNKSZ) < lim) { 6342 np = np->nxt; 6343 } 6344 } 6345 np->nxt = pwp->dma_freelist; 6346 pwp->dma_freelist = dcp; 6347 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, 6348 "added %lu DMA chunks ", n); 6349 } 6350 6351 /* 6352 * Change the value of the interrupt coalescing timer. This is done currently 6353 * only for I/O completions. If we're using the "auto clear" feature, it can 6354 * be turned back on when interrupt coalescing is turned off and must be 6355 * turned off when the coalescing timer is on. 6356 * NOTE: PMCS_MSIX_GENERAL and PMCS_OQ_IODONE are the same value. As long 6357 * as that's true, we don't need to distinguish between them. 6358 */ 6359 6360 void 6361 pmcs_set_intr_coal_timer(pmcs_hw_t *pwp, pmcs_coal_timer_adj_t adj) 6362 { 6363 if (adj == DECREASE_TIMER) { 6364 /* If the timer is already off, nothing to do. */ 6365 if (pwp->io_intr_coal.timer_on == B_FALSE) { 6366 return; 6367 } 6368 6369 pwp->io_intr_coal.intr_coal_timer -= PMCS_COAL_TIMER_GRAN; 6370 6371 if (pwp->io_intr_coal.intr_coal_timer == 0) { 6372 /* Disable the timer */ 6373 pmcs_wr_topunit(pwp, PMCS_INT_COALESCING_CONTROL, 0); 6374 6375 if (pwp->odb_auto_clear & (1 << PMCS_MSIX_IODONE)) { 6376 pmcs_wr_topunit(pwp, PMCS_OBDB_AUTO_CLR, 6377 pwp->odb_auto_clear); 6378 } 6379 6380 pwp->io_intr_coal.timer_on = B_FALSE; 6381 pwp->io_intr_coal.max_io_completions = B_FALSE; 6382 pwp->io_intr_coal.num_intrs = 0; 6383 pwp->io_intr_coal.int_cleared = B_FALSE; 6384 pwp->io_intr_coal.num_io_completions = 0; 6385 6386 DTRACE_PROBE1(pmcs__intr__coalesce__timer__off, 6387 pmcs_io_intr_coal_t *, &pwp->io_intr_coal); 6388 } else { 6389 pmcs_wr_topunit(pwp, PMCS_INT_COALESCING_TIMER, 6390 pwp->io_intr_coal.intr_coal_timer); 6391 } 6392 } else { 6393 /* 6394 * If the timer isn't on yet, do the setup for it now. 6395 */ 6396 if (pwp->io_intr_coal.timer_on == B_FALSE) { 6397 /* If auto clear is being used, turn it off. */ 6398 if (pwp->odb_auto_clear & (1 << PMCS_MSIX_IODONE)) { 6399 pmcs_wr_topunit(pwp, PMCS_OBDB_AUTO_CLR, 6400 (pwp->odb_auto_clear & 6401 ~(1 << PMCS_MSIX_IODONE))); 6402 } 6403 6404 pmcs_wr_topunit(pwp, PMCS_INT_COALESCING_CONTROL, 6405 (1 << PMCS_MSIX_IODONE)); 6406 pwp->io_intr_coal.timer_on = B_TRUE; 6407 pwp->io_intr_coal.intr_coal_timer = 6408 PMCS_COAL_TIMER_GRAN; 6409 6410 DTRACE_PROBE1(pmcs__intr__coalesce__timer__on, 6411 pmcs_io_intr_coal_t *, &pwp->io_intr_coal); 6412 } else { 6413 pwp->io_intr_coal.intr_coal_timer += 6414 PMCS_COAL_TIMER_GRAN; 6415 } 6416 6417 if (pwp->io_intr_coal.intr_coal_timer > PMCS_MAX_COAL_TIMER) { 6418 pwp->io_intr_coal.intr_coal_timer = PMCS_MAX_COAL_TIMER; 6419 } 6420 6421 pmcs_wr_topunit(pwp, PMCS_INT_COALESCING_TIMER, 6422 pwp->io_intr_coal.intr_coal_timer); 6423 } 6424 6425 /* 6426 * Adjust the interrupt threshold based on the current timer value 6427 */ 6428 pwp->io_intr_coal.intr_threshold = 6429 PMCS_INTR_THRESHOLD(PMCS_QUANTUM_TIME_USECS * 1000 / 6430 (pwp->io_intr_coal.intr_latency + 6431 (pwp->io_intr_coal.intr_coal_timer * 1000))); 6432 } 6433 6434 /* 6435 * Register Access functions 6436 */ 6437 uint32_t 6438 pmcs_rd_iqci(pmcs_hw_t *pwp, uint32_t qnum) 6439 { 6440 uint32_t iqci; 6441 6442 if (ddi_dma_sync(pwp->cip_handles, 0, 0, DDI_DMA_SYNC_FORKERNEL) != 6443 DDI_SUCCESS) { 6444 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6445 "%s: ddi_dma_sync failed?", __func__); 6446 } 6447 6448 iqci = LE_32( 6449 ((uint32_t *)((void *)pwp->cip))[IQ_OFFSET(qnum) >> 2]); 6450 6451 return (iqci); 6452 } 6453 6454 uint32_t 6455 pmcs_rd_oqpi(pmcs_hw_t *pwp, uint32_t qnum) 6456 { 6457 uint32_t oqpi; 6458 6459 if (ddi_dma_sync(pwp->cip_handles, 0, 0, DDI_DMA_SYNC_FORKERNEL) != 6460 DDI_SUCCESS) { 6461 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6462 "%s: ddi_dma_sync failed?", __func__); 6463 } 6464 6465 oqpi = LE_32( 6466 ((uint32_t *)((void *)pwp->cip))[OQ_OFFSET(qnum) >> 2]); 6467 6468 return (oqpi); 6469 } 6470 6471 uint32_t 6472 pmcs_rd_gsm_reg(pmcs_hw_t *pwp, uint8_t hi, uint32_t off) 6473 { 6474 uint32_t rv, newaxil, oldaxil, oldaxih; 6475 6476 newaxil = off & ~GSM_BASE_MASK; 6477 off &= GSM_BASE_MASK; 6478 mutex_enter(&pwp->axil_lock); 6479 oldaxil = ddi_get32(pwp->top_acc_handle, 6480 &pwp->top_regs[PMCS_AXI_TRANS >> 2]); 6481 ddi_put32(pwp->top_acc_handle, 6482 &pwp->top_regs[PMCS_AXI_TRANS >> 2], newaxil); 6483 drv_usecwait(10); 6484 if (ddi_get32(pwp->top_acc_handle, 6485 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != newaxil) { 6486 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6487 "AXIL register update failed"); 6488 } 6489 if (hi) { 6490 oldaxih = ddi_get32(pwp->top_acc_handle, 6491 &pwp->top_regs[PMCS_AXI_TRANS_UPPER >> 2]); 6492 ddi_put32(pwp->top_acc_handle, 6493 &pwp->top_regs[PMCS_AXI_TRANS_UPPER >> 2], hi); 6494 drv_usecwait(10); 6495 if (ddi_get32(pwp->top_acc_handle, 6496 &pwp->top_regs[PMCS_AXI_TRANS_UPPER >> 2]) != hi) { 6497 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6498 "AXIH register update failed"); 6499 } 6500 } 6501 rv = ddi_get32(pwp->gsm_acc_handle, &pwp->gsm_regs[off >> 2]); 6502 if (hi) { 6503 ddi_put32(pwp->top_acc_handle, 6504 &pwp->top_regs[PMCS_AXI_TRANS_UPPER >> 2], oldaxih); 6505 drv_usecwait(10); 6506 if (ddi_get32(pwp->top_acc_handle, 6507 &pwp->top_regs[PMCS_AXI_TRANS_UPPER >> 2]) != oldaxih) { 6508 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6509 "AXIH register restore failed"); 6510 } 6511 } 6512 ddi_put32(pwp->top_acc_handle, 6513 &pwp->top_regs[PMCS_AXI_TRANS >> 2], oldaxil); 6514 drv_usecwait(10); 6515 if (ddi_get32(pwp->top_acc_handle, 6516 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != oldaxil) { 6517 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6518 "AXIL register restore failed"); 6519 } 6520 mutex_exit(&pwp->axil_lock); 6521 return (rv); 6522 } 6523 6524 void 6525 pmcs_wr_gsm_reg(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6526 { 6527 uint32_t newaxil, oldaxil; 6528 6529 newaxil = off & ~GSM_BASE_MASK; 6530 off &= GSM_BASE_MASK; 6531 mutex_enter(&pwp->axil_lock); 6532 oldaxil = ddi_get32(pwp->top_acc_handle, 6533 &pwp->top_regs[PMCS_AXI_TRANS >> 2]); 6534 ddi_put32(pwp->top_acc_handle, 6535 &pwp->top_regs[PMCS_AXI_TRANS >> 2], newaxil); 6536 drv_usecwait(10); 6537 if (ddi_get32(pwp->top_acc_handle, 6538 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != newaxil) { 6539 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6540 "AXIL register update failed"); 6541 } 6542 ddi_put32(pwp->gsm_acc_handle, &pwp->gsm_regs[off >> 2], val); 6543 ddi_put32(pwp->top_acc_handle, 6544 &pwp->top_regs[PMCS_AXI_TRANS >> 2], oldaxil); 6545 drv_usecwait(10); 6546 if (ddi_get32(pwp->top_acc_handle, 6547 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != oldaxil) { 6548 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6549 "AXIL register restore failed"); 6550 } 6551 mutex_exit(&pwp->axil_lock); 6552 } 6553 6554 uint32_t 6555 pmcs_rd_topunit(pmcs_hw_t *pwp, uint32_t off) 6556 { 6557 switch (off) { 6558 case PMCS_SPC_RESET: 6559 case PMCS_SPC_BOOT_STRAP: 6560 case PMCS_SPC_DEVICE_ID: 6561 case PMCS_DEVICE_REVISION: 6562 off = pmcs_rd_gsm_reg(pwp, 0, off); 6563 break; 6564 default: 6565 off = ddi_get32(pwp->top_acc_handle, 6566 &pwp->top_regs[off >> 2]); 6567 break; 6568 } 6569 return (off); 6570 } 6571 6572 void 6573 pmcs_wr_topunit(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6574 { 6575 switch (off) { 6576 case PMCS_SPC_RESET: 6577 case PMCS_DEVICE_REVISION: 6578 pmcs_wr_gsm_reg(pwp, off, val); 6579 break; 6580 default: 6581 ddi_put32(pwp->top_acc_handle, &pwp->top_regs[off >> 2], val); 6582 break; 6583 } 6584 } 6585 6586 uint32_t 6587 pmcs_rd_msgunit(pmcs_hw_t *pwp, uint32_t off) 6588 { 6589 return (ddi_get32(pwp->msg_acc_handle, &pwp->msg_regs[off >> 2])); 6590 } 6591 6592 uint32_t 6593 pmcs_rd_mpi_tbl(pmcs_hw_t *pwp, uint32_t off) 6594 { 6595 return (ddi_get32(pwp->mpi_acc_handle, 6596 &pwp->mpi_regs[(pwp->mpi_offset + off) >> 2])); 6597 } 6598 6599 uint32_t 6600 pmcs_rd_gst_tbl(pmcs_hw_t *pwp, uint32_t off) 6601 { 6602 return (ddi_get32(pwp->mpi_acc_handle, 6603 &pwp->mpi_regs[(pwp->mpi_gst_offset + off) >> 2])); 6604 } 6605 6606 uint32_t 6607 pmcs_rd_iqc_tbl(pmcs_hw_t *pwp, uint32_t off) 6608 { 6609 return (ddi_get32(pwp->mpi_acc_handle, 6610 &pwp->mpi_regs[(pwp->mpi_iqc_offset + off) >> 2])); 6611 } 6612 6613 uint32_t 6614 pmcs_rd_oqc_tbl(pmcs_hw_t *pwp, uint32_t off) 6615 { 6616 return (ddi_get32(pwp->mpi_acc_handle, 6617 &pwp->mpi_regs[(pwp->mpi_oqc_offset + off) >> 2])); 6618 } 6619 6620 uint32_t 6621 pmcs_rd_iqpi(pmcs_hw_t *pwp, uint32_t qnum) 6622 { 6623 return (ddi_get32(pwp->mpi_acc_handle, 6624 &pwp->mpi_regs[pwp->iqpi_offset[qnum] >> 2])); 6625 } 6626 6627 uint32_t 6628 pmcs_rd_oqci(pmcs_hw_t *pwp, uint32_t qnum) 6629 { 6630 return (ddi_get32(pwp->mpi_acc_handle, 6631 &pwp->mpi_regs[pwp->oqci_offset[qnum] >> 2])); 6632 } 6633 6634 void 6635 pmcs_wr_msgunit(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6636 { 6637 ddi_put32(pwp->msg_acc_handle, &pwp->msg_regs[off >> 2], val); 6638 } 6639 6640 void 6641 pmcs_wr_mpi_tbl(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6642 { 6643 ddi_put32(pwp->mpi_acc_handle, 6644 &pwp->mpi_regs[(pwp->mpi_offset + off) >> 2], (val)); 6645 } 6646 6647 void 6648 pmcs_wr_gst_tbl(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6649 { 6650 ddi_put32(pwp->mpi_acc_handle, 6651 &pwp->mpi_regs[(pwp->mpi_gst_offset + off) >> 2], val); 6652 } 6653 6654 void 6655 pmcs_wr_iqc_tbl(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6656 { 6657 ddi_put32(pwp->mpi_acc_handle, 6658 &pwp->mpi_regs[(pwp->mpi_iqc_offset + off) >> 2], val); 6659 } 6660 6661 void 6662 pmcs_wr_oqc_tbl(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6663 { 6664 ddi_put32(pwp->mpi_acc_handle, 6665 &pwp->mpi_regs[(pwp->mpi_oqc_offset + off) >> 2], val); 6666 } 6667 6668 void 6669 pmcs_wr_iqci(pmcs_hw_t *pwp, uint32_t qnum, uint32_t val) 6670 { 6671 ((uint32_t *)((void *)pwp->cip))[IQ_OFFSET(qnum) >> 2] = val; 6672 if (ddi_dma_sync(pwp->cip_handles, 0, 0, DDI_DMA_SYNC_FORDEV) != 6673 DDI_SUCCESS) { 6674 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6675 "%s: ddi_dma_sync failed?", __func__); 6676 } 6677 } 6678 6679 void 6680 pmcs_wr_iqpi(pmcs_hw_t *pwp, uint32_t qnum, uint32_t val) 6681 { 6682 ddi_put32(pwp->mpi_acc_handle, 6683 &pwp->mpi_regs[pwp->iqpi_offset[qnum] >> 2], val); 6684 } 6685 6686 void 6687 pmcs_wr_oqci(pmcs_hw_t *pwp, uint32_t qnum, uint32_t val) 6688 { 6689 ddi_put32(pwp->mpi_acc_handle, 6690 &pwp->mpi_regs[pwp->oqci_offset[qnum] >> 2], val); 6691 } 6692 6693 void 6694 pmcs_wr_oqpi(pmcs_hw_t *pwp, uint32_t qnum, uint32_t val) 6695 { 6696 ((uint32_t *)((void *)pwp->cip))[OQ_OFFSET(qnum) >> 2] = val; 6697 if (ddi_dma_sync(pwp->cip_handles, 0, 0, DDI_DMA_SYNC_FORDEV) != 6698 DDI_SUCCESS) { 6699 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6700 "%s: ddi_dma_sync failed?", __func__); 6701 } 6702 } 6703 6704 /* 6705 * Check the status value of an outbound IOMB and report anything bad 6706 */ 6707 6708 void 6709 pmcs_check_iomb_status(pmcs_hw_t *pwp, uint32_t *iomb) 6710 { 6711 uint16_t opcode; 6712 int offset; 6713 6714 if (iomb == NULL) { 6715 return; 6716 } 6717 6718 opcode = LE_32(iomb[0]) & 0xfff; 6719 6720 switch (opcode) { 6721 /* 6722 * The following have no status field, so ignore them 6723 */ 6724 case PMCOUT_ECHO: 6725 case PMCOUT_SAS_HW_EVENT: 6726 case PMCOUT_GET_DEVICE_HANDLE: 6727 case PMCOUT_SATA_EVENT: 6728 case PMCOUT_SSP_EVENT: 6729 case PMCOUT_DEVICE_HANDLE_ARRIVED: 6730 case PMCOUT_SMP_REQUEST_RECEIVED: 6731 case PMCOUT_GPIO: 6732 case PMCOUT_GPIO_EVENT: 6733 case PMCOUT_GET_TIME_STAMP: 6734 case PMCOUT_SKIP_ENTRIES: 6735 case PMCOUT_GET_NVMD_DATA: /* Actually lower 16 bits of word 3 */ 6736 case PMCOUT_SET_NVMD_DATA: /* but ignore - we don't use these */ 6737 case PMCOUT_DEVICE_HANDLE_REMOVED: 6738 case PMCOUT_SSP_REQUEST_RECEIVED: 6739 return; 6740 6741 case PMCOUT_GENERAL_EVENT: 6742 offset = 1; 6743 break; 6744 6745 case PMCOUT_SSP_COMPLETION: 6746 case PMCOUT_SMP_COMPLETION: 6747 case PMCOUT_DEVICE_REGISTRATION: 6748 case PMCOUT_DEREGISTER_DEVICE_HANDLE: 6749 case PMCOUT_SATA_COMPLETION: 6750 case PMCOUT_DEVICE_INFO: 6751 case PMCOUT_FW_FLASH_UPDATE: 6752 case PMCOUT_SSP_ABORT: 6753 case PMCOUT_SATA_ABORT: 6754 case PMCOUT_SAS_DIAG_MODE_START_END: 6755 case PMCOUT_SAS_HW_EVENT_ACK_ACK: 6756 case PMCOUT_SMP_ABORT: 6757 case PMCOUT_SET_DEVICE_STATE: 6758 case PMCOUT_GET_DEVICE_STATE: 6759 case PMCOUT_SET_DEVICE_INFO: 6760 offset = 2; 6761 break; 6762 6763 case PMCOUT_LOCAL_PHY_CONTROL: 6764 case PMCOUT_SAS_DIAG_EXECUTE: 6765 case PMCOUT_PORT_CONTROL: 6766 offset = 3; 6767 break; 6768 6769 case PMCOUT_GET_INFO: 6770 case PMCOUT_GET_VPD: 6771 case PMCOUT_SAS_ASSISTED_DISCOVERY_EVENT: 6772 case PMCOUT_SATA_ASSISTED_DISCOVERY_EVENT: 6773 case PMCOUT_SET_VPD: 6774 case PMCOUT_TWI: 6775 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, 6776 "Got response for deprecated opcode", iomb); 6777 return; 6778 6779 default: 6780 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, 6781 "Got response for unknown opcode", iomb); 6782 return; 6783 } 6784 6785 if (LE_32(iomb[offset]) != PMCOUT_STATUS_OK) { 6786 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, 6787 "bad status on TAG_TYPE_NONE command", iomb); 6788 } 6789 } 6790 6791 /* 6792 * Called with statlock held 6793 */ 6794 void 6795 pmcs_clear_xp(pmcs_hw_t *pwp, pmcs_xscsi_t *xp) 6796 { 6797 _NOTE(ARGUNUSED(pwp)); 6798 6799 ASSERT(mutex_owned(&xp->statlock)); 6800 6801 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp, "%s: Device 0x%p is gone.", 6802 __func__, (void *)xp); 6803 6804 /* 6805 * Clear the dip now. This keeps pmcs_remove_device from attempting 6806 * to call us on the same device while we're still flushing queues. 6807 * The only side effect is we can no longer update SM-HBA properties, 6808 * but this device is going away anyway, so no matter. 6809 */ 6810 xp->dip = NULL; 6811 xp->smpd = NULL; 6812 xp->special_running = 0; 6813 xp->recovering = 0; 6814 xp->recover_wait = 0; 6815 xp->draining = 0; 6816 xp->new = 0; 6817 xp->assigned = 0; 6818 xp->dev_state = 0; 6819 xp->tagmap = 0; 6820 xp->dev_gone = 1; 6821 xp->event_recovery = 0; 6822 xp->dtype = NOTHING; 6823 xp->wq_recovery_tail = NULL; 6824 /* Don't clear xp->phy */ 6825 /* Don't clear xp->actv_cnt */ 6826 /* Don't clear xp->actv_pkts */ 6827 6828 /* 6829 * Flush all target queues 6830 */ 6831 pmcs_flush_target_queues(pwp, xp, PMCS_TGT_ALL_QUEUES); 6832 } 6833 6834 static int 6835 pmcs_smp_function_result(pmcs_hw_t *pwp, smp_response_frame_t *srf) 6836 { 6837 int result = srf->srf_result; 6838 6839 switch (result) { 6840 case SMP_RES_UNKNOWN_FUNCTION: 6841 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6842 "%s: SMP DISCOVER Response " 6843 "Function Result: Unknown SMP Function(0x%x)", 6844 __func__, result); 6845 break; 6846 case SMP_RES_FUNCTION_FAILED: 6847 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6848 "%s: SMP DISCOVER Response " 6849 "Function Result: SMP Function Failed(0x%x)", 6850 __func__, result); 6851 break; 6852 case SMP_RES_INVALID_REQUEST_FRAME_LENGTH: 6853 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6854 "%s: SMP DISCOVER Response " 6855 "Function Result: Invalid Request Frame Length(0x%x)", 6856 __func__, result); 6857 break; 6858 case SMP_RES_INCOMPLETE_DESCRIPTOR_LIST: 6859 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6860 "%s: SMP DISCOVER Response " 6861 "Function Result: Incomplete Descriptor List(0x%x)", 6862 __func__, result); 6863 break; 6864 case SMP_RES_PHY_DOES_NOT_EXIST: 6865 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6866 "%s: SMP DISCOVER Response " 6867 "Function Result: PHY does not exist(0x%x)", 6868 __func__, result); 6869 break; 6870 case SMP_RES_PHY_VACANT: 6871 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6872 "%s: SMP DISCOVER Response " 6873 "Function Result: PHY Vacant(0x%x)", 6874 __func__, result); 6875 break; 6876 default: 6877 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6878 "%s: SMP DISCOVER Response " 6879 "Function Result: (0x%x)", 6880 __func__, result); 6881 break; 6882 } 6883 6884 return (result); 6885 } 6886 6887 /* 6888 * Do all the repetitive stuff necessary to setup for DMA 6889 * 6890 * pwp: Used for dip 6891 * dma_attr: ddi_dma_attr_t to use for the mapping 6892 * acch: ddi_acc_handle_t to use for the mapping 6893 * dmah: ddi_dma_handle_t to use 6894 * length: Amount of memory for mapping 6895 * kvap: Pointer filled in with kernel virtual address on successful return 6896 * dma_addr: Pointer filled in with DMA address on successful return 6897 */ 6898 boolean_t 6899 pmcs_dma_setup(pmcs_hw_t *pwp, ddi_dma_attr_t *dma_attr, ddi_acc_handle_t *acch, 6900 ddi_dma_handle_t *dmah, size_t length, caddr_t *kvap, uint64_t *dma_addr) 6901 { 6902 dev_info_t *dip = pwp->dip; 6903 ddi_dma_cookie_t cookie; 6904 size_t real_length; 6905 uint_t ddma_flag = DDI_DMA_CONSISTENT; 6906 uint_t ddabh_flag = DDI_DMA_CONSISTENT | DDI_DMA_RDWR; 6907 uint_t cookie_cnt; 6908 ddi_device_acc_attr_t mattr = { 6909 DDI_DEVICE_ATTR_V0, 6910 DDI_NEVERSWAP_ACC, 6911 DDI_STRICTORDER_ACC, 6912 DDI_DEFAULT_ACC 6913 }; 6914 6915 *acch = NULL; 6916 *dmah = NULL; 6917 6918 if (ddi_dma_alloc_handle(dip, dma_attr, DDI_DMA_SLEEP, NULL, dmah) != 6919 DDI_SUCCESS) { 6920 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6921 "Failed to allocate DMA handle"); 6922 return (B_FALSE); 6923 } 6924 6925 if (ddi_dma_mem_alloc(*dmah, length, &mattr, ddma_flag, DDI_DMA_SLEEP, 6926 NULL, kvap, &real_length, acch) != DDI_SUCCESS) { 6927 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6928 "Failed to allocate DMA mem"); 6929 ddi_dma_free_handle(dmah); 6930 *dmah = NULL; 6931 return (B_FALSE); 6932 } 6933 6934 if (ddi_dma_addr_bind_handle(*dmah, NULL, *kvap, real_length, 6935 ddabh_flag, DDI_DMA_SLEEP, NULL, &cookie, &cookie_cnt) 6936 != DDI_DMA_MAPPED) { 6937 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "Failed to bind DMA"); 6938 ddi_dma_free_handle(dmah); 6939 ddi_dma_mem_free(acch); 6940 *dmah = NULL; 6941 *acch = NULL; 6942 return (B_FALSE); 6943 } 6944 6945 if (cookie_cnt != 1) { 6946 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "Multiple cookies"); 6947 if (ddi_dma_unbind_handle(*dmah) != DDI_SUCCESS) { 6948 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "Condition " 6949 "failed at %s():%d", __func__, __LINE__); 6950 } 6951 ddi_dma_free_handle(dmah); 6952 ddi_dma_mem_free(acch); 6953 *dmah = NULL; 6954 *acch = NULL; 6955 return (B_FALSE); 6956 } 6957 6958 *dma_addr = cookie.dmac_laddress; 6959 6960 return (B_TRUE); 6961 } 6962 6963 /* 6964 * Flush requested queues for a particular target. Called with statlock held 6965 */ 6966 void 6967 pmcs_flush_target_queues(pmcs_hw_t *pwp, pmcs_xscsi_t *tgt, uint8_t queues) 6968 { 6969 pmcs_cmd_t *sp, *sp_next; 6970 pmcwork_t *pwrk; 6971 6972 ASSERT(pwp != NULL); 6973 ASSERT(tgt != NULL); 6974 6975 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, tgt, 6976 "%s: Flushing queues (%d) for target 0x%p", __func__, 6977 queues, (void *)tgt); 6978 6979 /* 6980 * Commands on the wait queue (or the special queue below) don't have 6981 * work structures associated with them. 6982 */ 6983 if (queues & PMCS_TGT_WAIT_QUEUE) { 6984 mutex_enter(&tgt->wqlock); 6985 while ((sp = STAILQ_FIRST(&tgt->wq)) != NULL) { 6986 STAILQ_REMOVE(&tgt->wq, sp, pmcs_cmd, cmd_next); 6987 pmcs_prt(pwp, PMCS_PRT_DEBUG1, NULL, tgt, 6988 "%s: Removing cmd 0x%p from wq for target 0x%p", 6989 __func__, (void *)sp, (void *)tgt); 6990 CMD2PKT(sp)->pkt_reason = CMD_DEV_GONE; 6991 CMD2PKT(sp)->pkt_state = STATE_GOT_BUS; 6992 mutex_exit(&tgt->wqlock); 6993 pmcs_dma_unload(pwp, sp); 6994 mutex_enter(&pwp->cq_lock); 6995 STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next); 6996 PMCS_CQ_RUN_LOCKED(pwp); 6997 mutex_exit(&pwp->cq_lock); 6998 mutex_enter(&tgt->wqlock); 6999 } 7000 mutex_exit(&tgt->wqlock); 7001 } 7002 7003 /* 7004 * Commands on the active queue will have work structures associated 7005 * with them. 7006 */ 7007 if (queues & PMCS_TGT_ACTIVE_QUEUE) { 7008 mutex_exit(&tgt->statlock); 7009 mutex_enter(&tgt->aqlock); 7010 sp = STAILQ_FIRST(&tgt->aq); 7011 while (sp) { 7012 sp_next = STAILQ_NEXT(sp, cmd_next); 7013 pwrk = pmcs_tag2wp(pwp, sp->cmd_tag, B_FALSE); 7014 7015 /* 7016 * If we don't find a work structure, it's because 7017 * the command is already complete. If so, move on 7018 * to the next one. 7019 */ 7020 if (pwrk == NULL) { 7021 pmcs_prt(pwp, PMCS_PRT_DEBUG1, tgt->phy, tgt, 7022 "%s: Not removing cmd 0x%p (htag 0x%x) " 7023 "from aq", __func__, (void *)sp, 7024 sp->cmd_tag); 7025 sp = sp_next; 7026 continue; 7027 } 7028 7029 STAILQ_REMOVE(&tgt->aq, sp, pmcs_cmd, cmd_next); 7030 pmcs_prt(pwp, PMCS_PRT_DEBUG1, tgt->phy, tgt, 7031 "%s: Removing cmd 0x%p (htag 0x%x) from aq for " 7032 "target 0x%p", __func__, (void *)sp, sp->cmd_tag, 7033 (void *)tgt); 7034 mutex_exit(&tgt->aqlock); 7035 7036 /* 7037 * Mark the work structure as dead and complete it 7038 */ 7039 pwrk->dead = 1; 7040 CMD2PKT(sp)->pkt_reason = CMD_DEV_GONE; 7041 CMD2PKT(sp)->pkt_state = STATE_GOT_BUS; 7042 pmcs_complete_work_impl(pwp, pwrk, NULL, 0); 7043 pmcs_dma_unload(pwp, sp); 7044 mutex_enter(&pwp->cq_lock); 7045 STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next); 7046 mutex_exit(&pwp->cq_lock); 7047 mutex_enter(&tgt->aqlock); 7048 sp = sp_next; 7049 } 7050 mutex_exit(&tgt->aqlock); 7051 mutex_enter(&tgt->statlock); 7052 } 7053 7054 if (queues & PMCS_TGT_SPECIAL_QUEUE) { 7055 while ((sp = STAILQ_FIRST(&tgt->sq)) != NULL) { 7056 STAILQ_REMOVE(&tgt->sq, sp, pmcs_cmd, cmd_next); 7057 pmcs_prt(pwp, PMCS_PRT_DEBUG1, tgt->phy, tgt, 7058 "%s: Removing cmd 0x%p from sq for target 0x%p", 7059 __func__, (void *)sp, (void *)tgt); 7060 CMD2PKT(sp)->pkt_reason = CMD_DEV_GONE; 7061 CMD2PKT(sp)->pkt_state = STATE_GOT_BUS; 7062 pmcs_dma_unload(pwp, sp); 7063 mutex_enter(&pwp->cq_lock); 7064 STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next); 7065 mutex_exit(&pwp->cq_lock); 7066 } 7067 } 7068 7069 if (queues == PMCS_TGT_ALL_QUEUES) { 7070 mutex_exit(&tgt->statlock); 7071 pmcs_flush_nonio_cmds(pwp, tgt); 7072 mutex_enter(&tgt->statlock); 7073 } 7074 } 7075 7076 /* 7077 * Flush non-IO commands for this target. This cleans up the off-queue 7078 * work with no pmcs_cmd_t associated. 7079 */ 7080 static void 7081 pmcs_flush_nonio_cmds(pmcs_hw_t *pwp, pmcs_xscsi_t *tgt) 7082 { 7083 int i; 7084 pmcwork_t *p; 7085 7086 for (i = 0; i < pwp->max_cmd; i++) { 7087 p = &pwp->work[i]; 7088 mutex_enter(&p->lock); 7089 if (p->xp != tgt) { 7090 mutex_exit(&p->lock); 7091 continue; 7092 } 7093 if (p->htag & PMCS_TAG_NONIO_CMD) { 7094 if (!PMCS_COMMAND_ACTIVE(p) || PMCS_COMMAND_DONE(p)) { 7095 mutex_exit(&p->lock); 7096 continue; 7097 } 7098 pmcs_prt(pwp, PMCS_PRT_DEBUG, p->phy, p->xp, 7099 "%s: Completing non-io cmd with HTAG 0x%x", 7100 __func__, p->htag); 7101 pmcs_complete_work_impl(pwp, p, NULL, 0); 7102 } else { 7103 mutex_exit(&p->lock); 7104 } 7105 } 7106 } 7107 7108 void 7109 pmcs_complete_work_impl(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *iomb, 7110 size_t amt) 7111 { 7112 pmcs_phy_t *pptr = NULL; 7113 7114 switch (PMCS_TAG_TYPE(pwrk->htag)) { 7115 case PMCS_TAG_TYPE_CBACK: 7116 { 7117 pmcs_cb_t callback = (pmcs_cb_t)pwrk->ptr; 7118 (*callback)(pwp, pwrk, iomb); 7119 break; 7120 } 7121 case PMCS_TAG_TYPE_WAIT: 7122 if (pwrk->arg && iomb && amt) { 7123 (void) memcpy(pwrk->arg, iomb, amt); 7124 } 7125 cv_signal(&pwrk->sleep_cv); 7126 mutex_exit(&pwrk->lock); 7127 break; 7128 case PMCS_TAG_TYPE_NONE: 7129 #ifdef DEBUG 7130 pmcs_check_iomb_status(pwp, iomb); 7131 #endif 7132 pptr = pwrk->phy; 7133 pmcs_pwork(pwp, pwrk); 7134 7135 /* If this was an abort all, clean up if needed */ 7136 if ((pwrk->abt_htag == PMCS_ABT_HTAG_ALL) && (pptr != NULL)) { 7137 mutex_enter(&pptr->phy_lock); 7138 if (pptr->abort_all_start) { 7139 pptr->abort_all_start = 0; 7140 cv_signal(&pptr->abort_all_cv); 7141 } 7142 mutex_exit(&pptr->phy_lock); 7143 } 7144 break; 7145 default: 7146 /* 7147 * We will leak a structure here if we don't know 7148 * what happened 7149 */ 7150 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 7151 "%s: Unknown PMCS_TAG_TYPE (%x)", 7152 __func__, PMCS_TAG_TYPE(pwrk->htag)); 7153 break; 7154 } 7155 } 7156 7157 /* 7158 * Determine if iport still has targets. During detach(9E), if SCSA is 7159 * successfull in its guarantee of tran_tgt_free(9E) before detach(9E), 7160 * this should always return B_FALSE. 7161 */ 7162 boolean_t 7163 pmcs_iport_has_targets(pmcs_hw_t *pwp, pmcs_iport_t *iport) 7164 { 7165 pmcs_xscsi_t *xp; 7166 int i; 7167 7168 mutex_enter(&pwp->lock); 7169 7170 if (!pwp->targets || !pwp->max_dev) { 7171 mutex_exit(&pwp->lock); 7172 return (B_FALSE); 7173 } 7174 7175 for (i = 0; i < pwp->max_dev; i++) { 7176 xp = pwp->targets[i]; 7177 if ((xp == NULL) || (xp->phy == NULL) || 7178 (xp->phy->iport != iport)) { 7179 continue; 7180 } 7181 7182 mutex_exit(&pwp->lock); 7183 return (B_TRUE); 7184 } 7185 7186 mutex_exit(&pwp->lock); 7187 return (B_FALSE); 7188 } 7189 7190 /* 7191 * Called with softstate lock held 7192 */ 7193 void 7194 pmcs_destroy_target(pmcs_xscsi_t *target) 7195 { 7196 pmcs_hw_t *pwp = target->pwp; 7197 pmcs_iport_t *iport; 7198 7199 ASSERT(pwp); 7200 ASSERT(mutex_owned(&pwp->lock)); 7201 7202 if (!target->ua) { 7203 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, target, 7204 "%s: target %p iport address is null", 7205 __func__, (void *)target); 7206 } 7207 7208 iport = pmcs_get_iport_by_ua(pwp, target->ua); 7209 if (iport == NULL) { 7210 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, target, 7211 "%s: no iport associated with tgt(0x%p)", 7212 __func__, (void *)target); 7213 return; 7214 } 7215 7216 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, target, 7217 "%s: free target %p", __func__, (void *)target); 7218 if (target->ua) { 7219 strfree(target->ua); 7220 } 7221 7222 mutex_destroy(&target->wqlock); 7223 mutex_destroy(&target->aqlock); 7224 mutex_destroy(&target->statlock); 7225 cv_destroy(&target->reset_cv); 7226 cv_destroy(&target->abort_cv); 7227 ddi_soft_state_bystr_fini(&target->lun_sstate); 7228 ddi_soft_state_bystr_free(iport->tgt_sstate, target->unit_address); 7229 pmcs_rele_iport(iport); 7230 } 7231 7232 /* 7233 * pmcs_lock_phy_impl 7234 * 7235 * This function is what does the actual work for pmcs_lock_phy. It will 7236 * lock all PHYs from phyp down in a top-down fashion. 7237 * 7238 * Locking notes: 7239 * 1. level starts from 0 for the PHY ("parent") that's passed in. It is 7240 * not a reflection of the actual level of the PHY in the SAS topology. 7241 * 2. If parent is an expander, then parent is locked along with all its 7242 * descendents. 7243 * 3. Expander subsidiary PHYs at level 0 are not locked. It is the 7244 * responsibility of the caller to individually lock expander subsidiary PHYs 7245 * at level 0 if necessary. 7246 * 4. Siblings at level 0 are not traversed due to the possibility that we're 7247 * locking a PHY on the dead list. The siblings could be pointing to invalid 7248 * PHYs. We don't lock siblings at level 0 anyway. 7249 */ 7250 static void 7251 pmcs_lock_phy_impl(pmcs_phy_t *phyp, int level) 7252 { 7253 pmcs_phy_t *tphyp; 7254 7255 ASSERT((phyp->dtype == SAS) || (phyp->dtype == SATA) || 7256 (phyp->dtype == EXPANDER) || (phyp->dtype == NOTHING)); 7257 7258 /* 7259 * Start walking the PHYs. 7260 */ 7261 tphyp = phyp; 7262 while (tphyp) { 7263 /* 7264 * If we're at the top level, only lock ourselves. For anything 7265 * at level > 0, traverse children while locking everything. 7266 */ 7267 if ((level > 0) || (tphyp == phyp)) { 7268 pmcs_prt(tphyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, tphyp, 7269 NULL, "%s: PHY 0x%p parent 0x%p path %s lvl %d", 7270 __func__, (void *)tphyp, (void *)tphyp->parent, 7271 tphyp->path, level); 7272 mutex_enter(&tphyp->phy_lock); 7273 7274 if (tphyp->children) { 7275 pmcs_lock_phy_impl(tphyp->children, level + 1); 7276 } 7277 } 7278 7279 if (level == 0) { 7280 return; 7281 } 7282 7283 tphyp = tphyp->sibling; 7284 } 7285 } 7286 7287 /* 7288 * pmcs_lock_phy 7289 * 7290 * This function is responsible for locking a PHY and all its descendents 7291 */ 7292 void 7293 pmcs_lock_phy(pmcs_phy_t *phyp) 7294 { 7295 #ifdef DEBUG 7296 char *callername = NULL; 7297 ulong_t off; 7298 7299 ASSERT(phyp != NULL); 7300 7301 callername = modgetsymname((uintptr_t)caller(), &off); 7302 7303 if (callername == NULL) { 7304 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7305 "%s: PHY 0x%p path %s caller: unknown", __func__, 7306 (void *)phyp, phyp->path); 7307 } else { 7308 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7309 "%s: PHY 0x%p path %s caller: %s+%lx", __func__, 7310 (void *)phyp, phyp->path, callername, off); 7311 } 7312 #else 7313 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7314 "%s: PHY 0x%p path %s", __func__, (void *)phyp, phyp->path); 7315 #endif 7316 pmcs_lock_phy_impl(phyp, 0); 7317 } 7318 7319 /* 7320 * pmcs_unlock_phy_impl 7321 * 7322 * Unlock all PHYs from phyp down in a bottom-up fashion. 7323 */ 7324 static void 7325 pmcs_unlock_phy_impl(pmcs_phy_t *phyp, int level) 7326 { 7327 pmcs_phy_t *phy_next; 7328 7329 ASSERT((phyp->dtype == SAS) || (phyp->dtype == SATA) || 7330 (phyp->dtype == EXPANDER) || (phyp->dtype == NOTHING)); 7331 7332 /* 7333 * Recurse down to the bottom PHYs 7334 */ 7335 if (level == 0) { 7336 if (phyp->children) { 7337 pmcs_unlock_phy_impl(phyp->children, level + 1); 7338 } 7339 } else { 7340 phy_next = phyp; 7341 while (phy_next) { 7342 if (phy_next->children) { 7343 pmcs_unlock_phy_impl(phy_next->children, 7344 level + 1); 7345 } 7346 phy_next = phy_next->sibling; 7347 } 7348 } 7349 7350 /* 7351 * Iterate through PHYs unlocking all at level > 0 as well the top PHY 7352 */ 7353 phy_next = phyp; 7354 while (phy_next) { 7355 if ((level > 0) || (phy_next == phyp)) { 7356 pmcs_prt(phy_next->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, 7357 phy_next, NULL, 7358 "%s: PHY 0x%p parent 0x%p path %s lvl %d", 7359 __func__, (void *)phy_next, 7360 (void *)phy_next->parent, phy_next->path, level); 7361 mutex_exit(&phy_next->phy_lock); 7362 } 7363 7364 if (level == 0) { 7365 return; 7366 } 7367 7368 phy_next = phy_next->sibling; 7369 } 7370 } 7371 7372 /* 7373 * pmcs_unlock_phy 7374 * 7375 * Unlock a PHY and all its descendents 7376 */ 7377 void 7378 pmcs_unlock_phy(pmcs_phy_t *phyp) 7379 { 7380 #ifdef DEBUG 7381 char *callername = NULL; 7382 ulong_t off; 7383 7384 ASSERT(phyp != NULL); 7385 7386 callername = modgetsymname((uintptr_t)caller(), &off); 7387 7388 if (callername == NULL) { 7389 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7390 "%s: PHY 0x%p path %s caller: unknown", __func__, 7391 (void *)phyp, phyp->path); 7392 } else { 7393 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7394 "%s: PHY 0x%p path %s caller: %s+%lx", __func__, 7395 (void *)phyp, phyp->path, callername, off); 7396 } 7397 #else 7398 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7399 "%s: PHY 0x%p path %s", __func__, (void *)phyp, phyp->path); 7400 #endif 7401 pmcs_unlock_phy_impl(phyp, 0); 7402 } 7403 7404 /* 7405 * pmcs_get_root_phy 7406 * 7407 * For a given phy pointer return its root phy. 7408 * This function must only be called during discovery in order to ensure that 7409 * the chain of PHYs from phyp up to the root PHY doesn't change. 7410 */ 7411 pmcs_phy_t * 7412 pmcs_get_root_phy(pmcs_phy_t *phyp) 7413 { 7414 ASSERT(phyp); 7415 7416 while (phyp) { 7417 if (IS_ROOT_PHY(phyp)) { 7418 break; 7419 } 7420 phyp = phyp->parent; 7421 } 7422 7423 return (phyp); 7424 } 7425 7426 /* 7427 * pmcs_free_dma_chunklist 7428 * 7429 * Free DMA S/G chunk list 7430 */ 7431 void 7432 pmcs_free_dma_chunklist(pmcs_hw_t *pwp) 7433 { 7434 pmcs_chunk_t *pchunk; 7435 7436 while (pwp->dma_chunklist) { 7437 pchunk = pwp->dma_chunklist; 7438 pwp->dma_chunklist = pwp->dma_chunklist->next; 7439 if (pchunk->dma_handle) { 7440 if (ddi_dma_unbind_handle(pchunk->dma_handle) != 7441 DDI_SUCCESS) { 7442 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 7443 "Condition failed at %s():%d", 7444 __func__, __LINE__); 7445 } 7446 ddi_dma_free_handle(&pchunk->dma_handle); 7447 ddi_dma_mem_free(&pchunk->acc_handle); 7448 } 7449 kmem_free(pchunk, sizeof (pmcs_chunk_t)); 7450 } 7451 } 7452 7453 /*ARGSUSED2*/ 7454 int 7455 pmcs_phy_constructor(void *buf, void *arg, int kmflags) 7456 { 7457 pmcs_hw_t *pwp = (pmcs_hw_t *)arg; 7458 pmcs_phy_t *phyp = (pmcs_phy_t *)buf; 7459 7460 mutex_init(&phyp->phy_lock, NULL, MUTEX_DRIVER, 7461 DDI_INTR_PRI(pwp->intr_pri)); 7462 cv_init(&phyp->abort_all_cv, NULL, CV_DRIVER, NULL); 7463 return (0); 7464 } 7465 7466 /*ARGSUSED1*/ 7467 void 7468 pmcs_phy_destructor(void *buf, void *arg) 7469 { 7470 pmcs_phy_t *phyp = (pmcs_phy_t *)buf; 7471 7472 cv_destroy(&phyp->abort_all_cv); 7473 mutex_destroy(&phyp->phy_lock); 7474 } 7475 7476 /* 7477 * Free all PHYs from the kmem_cache starting at phyp as well as everything 7478 * on the dead_phys list. 7479 * 7480 * NOTE: This function does not free root PHYs as they are not allocated 7481 * from the kmem_cache. 7482 * 7483 * No PHY locks are acquired as this should only be called during DDI_DETACH 7484 * or soft reset (while pmcs interrupts are disabled). 7485 */ 7486 void 7487 pmcs_free_all_phys(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 7488 { 7489 pmcs_phy_t *tphyp, *nphyp, *cphyp; 7490 7491 if (phyp == NULL) { 7492 return; 7493 } 7494 7495 for (tphyp = phyp; tphyp; tphyp = nphyp) { 7496 nphyp = tphyp->sibling; 7497 cphyp = tphyp->children; 7498 7499 if (cphyp) { 7500 tphyp->children = NULL; 7501 pmcs_free_all_phys(pwp, cphyp); 7502 } 7503 7504 if (!IS_ROOT_PHY(tphyp)) { 7505 kmem_cache_free(pwp->phy_cache, tphyp); 7506 } 7507 } 7508 7509 mutex_enter(&pwp->dead_phylist_lock); 7510 for (tphyp = pwp->dead_phys; tphyp; tphyp = nphyp) { 7511 nphyp = tphyp->dead_next; 7512 kmem_cache_free(pwp->phy_cache, tphyp); 7513 } 7514 pwp->dead_phys = NULL; 7515 mutex_exit(&pwp->dead_phylist_lock); 7516 } 7517 7518 /* 7519 * Free a list of PHYs linked together by the sibling pointer back to the 7520 * kmem cache from whence they came. This function does not recurse, so the 7521 * caller must ensure there are no children. 7522 */ 7523 void 7524 pmcs_free_phys(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 7525 { 7526 pmcs_phy_t *next_phy; 7527 7528 while (phyp) { 7529 next_phy = phyp->sibling; 7530 ASSERT(!mutex_owned(&phyp->phy_lock)); 7531 kmem_cache_free(pwp->phy_cache, phyp); 7532 phyp = next_phy; 7533 } 7534 } 7535 7536 /* 7537 * Make a copy of an existing PHY structure. This is used primarily in 7538 * discovery to compare the contents of an existing PHY with what gets 7539 * reported back by an expander. 7540 * 7541 * This function must not be called from any context where sleeping is 7542 * not possible. 7543 * 7544 * The new PHY is returned unlocked. 7545 */ 7546 static pmcs_phy_t * 7547 pmcs_clone_phy(pmcs_phy_t *orig_phy) 7548 { 7549 pmcs_phy_t *local; 7550 7551 local = kmem_cache_alloc(orig_phy->pwp->phy_cache, KM_SLEEP); 7552 7553 /* 7554 * Go ahead and just copy everything... 7555 */ 7556 *local = *orig_phy; 7557 7558 /* 7559 * But the following must be set appropriately for this copy 7560 */ 7561 local->sibling = NULL; 7562 local->children = NULL; 7563 mutex_init(&local->phy_lock, NULL, MUTEX_DRIVER, 7564 DDI_INTR_PRI(orig_phy->pwp->intr_pri)); 7565 7566 return (local); 7567 } 7568 7569 int 7570 pmcs_check_acc_handle(ddi_acc_handle_t handle) 7571 { 7572 ddi_fm_error_t de; 7573 7574 if (handle == NULL) { 7575 return (DDI_FAILURE); 7576 } 7577 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0); 7578 return (de.fme_status); 7579 } 7580 7581 int 7582 pmcs_check_dma_handle(ddi_dma_handle_t handle) 7583 { 7584 ddi_fm_error_t de; 7585 7586 if (handle == NULL) { 7587 return (DDI_FAILURE); 7588 } 7589 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0); 7590 return (de.fme_status); 7591 } 7592 7593 7594 void 7595 pmcs_fm_ereport(pmcs_hw_t *pwp, char *detail) 7596 { 7597 uint64_t ena; 7598 char buf[FM_MAX_CLASS]; 7599 7600 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); 7601 ena = fm_ena_generate(0, FM_ENA_FMT1); 7602 if (DDI_FM_EREPORT_CAP(pwp->fm_capabilities)) { 7603 ddi_fm_ereport_post(pwp->dip, buf, ena, DDI_NOSLEEP, 7604 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL); 7605 } 7606 } 7607 7608 int 7609 pmcs_check_acc_dma_handle(pmcs_hw_t *pwp) 7610 { 7611 pmcs_chunk_t *pchunk; 7612 int i; 7613 7614 /* check all acc & dma handles allocated in attach */ 7615 if ((pmcs_check_acc_handle(pwp->pci_acc_handle) != DDI_SUCCESS) || 7616 (pmcs_check_acc_handle(pwp->msg_acc_handle) != DDI_SUCCESS) || 7617 (pmcs_check_acc_handle(pwp->top_acc_handle) != DDI_SUCCESS) || 7618 (pmcs_check_acc_handle(pwp->mpi_acc_handle) != DDI_SUCCESS) || 7619 (pmcs_check_acc_handle(pwp->gsm_acc_handle) != DDI_SUCCESS)) { 7620 goto check_failed; 7621 } 7622 7623 for (i = 0; i < PMCS_NIQ; i++) { 7624 if ((pmcs_check_dma_handle( 7625 pwp->iqp_handles[i]) != DDI_SUCCESS) || 7626 (pmcs_check_acc_handle( 7627 pwp->iqp_acchdls[i]) != DDI_SUCCESS)) { 7628 goto check_failed; 7629 } 7630 } 7631 7632 for (i = 0; i < PMCS_NOQ; i++) { 7633 if ((pmcs_check_dma_handle( 7634 pwp->oqp_handles[i]) != DDI_SUCCESS) || 7635 (pmcs_check_acc_handle( 7636 pwp->oqp_acchdls[i]) != DDI_SUCCESS)) { 7637 goto check_failed; 7638 } 7639 } 7640 7641 if ((pmcs_check_dma_handle(pwp->cip_handles) != DDI_SUCCESS) || 7642 (pmcs_check_acc_handle(pwp->cip_acchdls) != DDI_SUCCESS)) { 7643 goto check_failed; 7644 } 7645 7646 if (pwp->fwlog && 7647 ((pmcs_check_dma_handle(pwp->fwlog_hndl) != DDI_SUCCESS) || 7648 (pmcs_check_acc_handle(pwp->fwlog_acchdl) != DDI_SUCCESS))) { 7649 goto check_failed; 7650 } 7651 7652 if (pwp->regdump_hndl && pwp->regdump_acchdl && 7653 ((pmcs_check_dma_handle(pwp->regdump_hndl) != DDI_SUCCESS) || 7654 (pmcs_check_acc_handle(pwp->regdump_acchdl) 7655 != DDI_SUCCESS))) { 7656 goto check_failed; 7657 } 7658 7659 7660 pchunk = pwp->dma_chunklist; 7661 while (pchunk) { 7662 if ((pmcs_check_acc_handle(pchunk->acc_handle) 7663 != DDI_SUCCESS) || 7664 (pmcs_check_dma_handle(pchunk->dma_handle) 7665 != DDI_SUCCESS)) { 7666 goto check_failed; 7667 } 7668 pchunk = pchunk->next; 7669 } 7670 7671 return (0); 7672 7673 check_failed: 7674 7675 return (1); 7676 } 7677 7678 /* 7679 * pmcs_handle_dead_phys 7680 * 7681 * If the PHY has no outstanding work associated with it, remove it from 7682 * the dead PHY list and free it. 7683 * 7684 * If pwp->ds_err_recovering or pwp->configuring is set, don't run. 7685 * This keeps routines that need to submit work to the chip from having to 7686 * hold PHY locks to ensure that PHYs don't disappear while they do their work. 7687 */ 7688 void 7689 pmcs_handle_dead_phys(pmcs_hw_t *pwp) 7690 { 7691 pmcs_phy_t *phyp, *nphyp, *pphyp; 7692 7693 mutex_enter(&pwp->lock); 7694 mutex_enter(&pwp->config_lock); 7695 7696 if (pwp->configuring | pwp->ds_err_recovering) { 7697 mutex_exit(&pwp->config_lock); 7698 mutex_exit(&pwp->lock); 7699 return; 7700 } 7701 7702 /* 7703 * Check every PHY in the dead PHY list 7704 */ 7705 mutex_enter(&pwp->dead_phylist_lock); 7706 phyp = pwp->dead_phys; 7707 pphyp = NULL; /* Set previous PHY to NULL */ 7708 7709 while (phyp != NULL) { 7710 pmcs_lock_phy(phyp); 7711 ASSERT(phyp->dead); 7712 7713 nphyp = phyp->dead_next; 7714 7715 /* 7716 * Check for outstanding work 7717 */ 7718 if (phyp->ref_count > 0) { 7719 pmcs_unlock_phy(phyp); 7720 pphyp = phyp; /* This PHY becomes "previous" */ 7721 } else if (phyp->target) { 7722 pmcs_unlock_phy(phyp); 7723 pmcs_prt(pwp, PMCS_PRT_DEBUG1, phyp, phyp->target, 7724 "%s: Not freeing PHY 0x%p: target 0x%p is not free", 7725 __func__, (void *)phyp, (void *)phyp->target); 7726 pphyp = phyp; 7727 } else { 7728 /* 7729 * No outstanding work or target references. Remove it 7730 * from the list and free it 7731 */ 7732 pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, phyp->target, 7733 "%s: Freeing inactive dead PHY 0x%p @ %s " 7734 "target = 0x%p", __func__, (void *)phyp, 7735 phyp->path, (void *)phyp->target); 7736 /* 7737 * If pphyp is NULL, then phyp was the head of the list, 7738 * so just reset the head to nphyp. Otherwise, the 7739 * previous PHY will now point to nphyp (the next PHY) 7740 */ 7741 if (pphyp == NULL) { 7742 pwp->dead_phys = nphyp; 7743 } else { 7744 pphyp->dead_next = nphyp; 7745 } 7746 /* 7747 * If the target still points to this PHY, remove 7748 * that linkage now. 7749 */ 7750 if (phyp->target) { 7751 mutex_enter(&phyp->target->statlock); 7752 if (phyp->target->phy == phyp) { 7753 phyp->target->phy = NULL; 7754 } 7755 mutex_exit(&phyp->target->statlock); 7756 } 7757 pmcs_unlock_phy(phyp); 7758 kmem_cache_free(pwp->phy_cache, phyp); 7759 } 7760 7761 phyp = nphyp; 7762 } 7763 7764 mutex_exit(&pwp->dead_phylist_lock); 7765 mutex_exit(&pwp->config_lock); 7766 mutex_exit(&pwp->lock); 7767 } 7768 7769 void 7770 pmcs_inc_phy_ref_count(pmcs_phy_t *phyp) 7771 { 7772 atomic_inc_32(&phyp->ref_count); 7773 } 7774 7775 void 7776 pmcs_dec_phy_ref_count(pmcs_phy_t *phyp) 7777 { 7778 ASSERT(phyp->ref_count != 0); 7779 atomic_dec_32(&phyp->ref_count); 7780 } 7781 7782 /* 7783 * pmcs_reap_dead_phy 7784 * 7785 * This function is called from pmcs_new_tport when we have a PHY 7786 * without a target pointer. It's possible in that case that this PHY 7787 * may have a "brother" on the dead_phys list. That is, it may be the same as 7788 * this one but with a different root PHY number (e.g. pp05 vs. pp04). If 7789 * that's the case, update the dead PHY and this new PHY. If that's not the 7790 * case, we should get a tran_tgt_init on this after it's reported to SCSA. 7791 * 7792 * Called with PHY locked. 7793 */ 7794 static void 7795 pmcs_reap_dead_phy(pmcs_phy_t *phyp) 7796 { 7797 pmcs_hw_t *pwp = phyp->pwp; 7798 pmcs_phy_t *ctmp; 7799 pmcs_iport_t *iport_cmp; 7800 7801 ASSERT(mutex_owned(&phyp->phy_lock)); 7802 7803 /* 7804 * Check the dead PHYs list 7805 */ 7806 mutex_enter(&pwp->dead_phylist_lock); 7807 ctmp = pwp->dead_phys; 7808 while (ctmp) { 7809 /* 7810 * If the iport is NULL, compare against last_iport. 7811 */ 7812 if (ctmp->iport) { 7813 iport_cmp = ctmp->iport; 7814 } else { 7815 iport_cmp = ctmp->last_iport; 7816 } 7817 7818 if ((iport_cmp != phyp->iport) || 7819 (memcmp((void *)&ctmp->sas_address[0], 7820 (void *)&phyp->sas_address[0], 8))) { 7821 ctmp = ctmp->dead_next; 7822 continue; 7823 } 7824 7825 /* 7826 * Same SAS address on same iport. Now check to see if 7827 * the PHY path is the same with the possible exception 7828 * of the root PHY number. 7829 * The "5" is the string length of "pp00." 7830 */ 7831 if ((strnlen(phyp->path, 5) >= 5) && 7832 (strnlen(ctmp->path, 5) >= 5)) { 7833 if (memcmp((void *)&phyp->path[5], 7834 (void *)&ctmp->path[5], 7835 strnlen(phyp->path, 32) - 5) == 0) { 7836 break; 7837 } 7838 } 7839 7840 ctmp = ctmp->dead_next; 7841 } 7842 mutex_exit(&pwp->dead_phylist_lock); 7843 7844 /* 7845 * Found a match. Remove the target linkage and drop the 7846 * ref count on the old PHY. Then, increment the ref count 7847 * on the new PHY to compensate. 7848 */ 7849 if (ctmp) { 7850 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 7851 "%s: Found match in dead PHY list (0x%p) for new PHY %s", 7852 __func__, (void *)ctmp, phyp->path); 7853 /* 7854 * If there is a pointer to the target in the dead PHY, move 7855 * all reference counts to the new PHY. 7856 */ 7857 if (ctmp->target) { 7858 mutex_enter(&ctmp->target->statlock); 7859 phyp->target = ctmp->target; 7860 7861 while (ctmp->ref_count != 0) { 7862 pmcs_inc_phy_ref_count(phyp); 7863 pmcs_dec_phy_ref_count(ctmp); 7864 } 7865 /* 7866 * Update the target's linkage as well 7867 */ 7868 phyp->target->phy = phyp; 7869 phyp->target->dtype = phyp->dtype; 7870 ctmp->target = NULL; 7871 mutex_exit(&phyp->target->statlock); 7872 } 7873 } 7874 } 7875 7876 /* 7877 * Called with iport lock held 7878 */ 7879 void 7880 pmcs_add_phy_to_iport(pmcs_iport_t *iport, pmcs_phy_t *phyp) 7881 { 7882 ASSERT(mutex_owned(&iport->lock)); 7883 ASSERT(phyp); 7884 ASSERT(!list_link_active(&phyp->list_node)); 7885 7886 iport->nphy++; 7887 list_insert_tail(&iport->phys, phyp); 7888 pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, PMCS_NUM_PHYS, 7889 &iport->nphy); 7890 mutex_enter(&phyp->phy_lock); 7891 pmcs_create_one_phy_stats(iport, phyp); 7892 mutex_exit(&phyp->phy_lock); 7893 pmcs_hold_iport(iport); 7894 } 7895 7896 /* 7897 * Called with the iport lock held 7898 */ 7899 void 7900 pmcs_remove_phy_from_iport(pmcs_iport_t *iport, pmcs_phy_t *phyp) 7901 { 7902 pmcs_phy_t *pptr, *next_pptr; 7903 7904 ASSERT(mutex_owned(&iport->lock)); 7905 7906 /* 7907 * If phyp is NULL, remove all PHYs from the iport 7908 */ 7909 if (phyp == NULL) { 7910 for (pptr = list_head(&iport->phys); pptr != NULL; 7911 pptr = next_pptr) { 7912 next_pptr = list_next(&iport->phys, pptr); 7913 mutex_enter(&pptr->phy_lock); 7914 if (pptr->phy_stats != NULL) { 7915 kstat_delete(pptr->phy_stats); 7916 pptr->phy_stats = NULL; 7917 } 7918 pptr->iport = NULL; 7919 pmcs_update_phy_pm_props(pptr, pptr->att_port_pm_tmp, 7920 pptr->tgt_port_pm_tmp, B_FALSE); 7921 mutex_exit(&pptr->phy_lock); 7922 pmcs_rele_iport(iport); 7923 list_remove(&iport->phys, pptr); 7924 pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, 7925 PMCS_NUM_PHYS, &iport->nphy); 7926 } 7927 iport->nphy = 0; 7928 return; 7929 } 7930 7931 ASSERT(phyp); 7932 ASSERT(iport->nphy > 0); 7933 ASSERT(list_link_active(&phyp->list_node)); 7934 iport->nphy--; 7935 list_remove(&iport->phys, phyp); 7936 pmcs_update_phy_pm_props(phyp, phyp->att_port_pm_tmp, 7937 phyp->tgt_port_pm_tmp, B_FALSE); 7938 pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, PMCS_NUM_PHYS, 7939 &iport->nphy); 7940 pmcs_rele_iport(iport); 7941 } 7942 7943 /* 7944 * This function checks to see if the target pointed to by phyp is still 7945 * correct. This is done by comparing the target's unit address with the 7946 * SAS address in phyp. 7947 * 7948 * Called with PHY locked and target statlock held 7949 */ 7950 static boolean_t 7951 pmcs_phy_target_match(pmcs_phy_t *phyp) 7952 { 7953 uint64_t wwn; 7954 char unit_address[PMCS_MAX_UA_SIZE]; 7955 boolean_t rval = B_FALSE; 7956 7957 ASSERT(phyp); 7958 ASSERT(phyp->target); 7959 ASSERT(mutex_owned(&phyp->phy_lock)); 7960 ASSERT(mutex_owned(&phyp->target->statlock)); 7961 7962 wwn = pmcs_barray2wwn(phyp->sas_address); 7963 (void) scsi_wwn_to_wwnstr(wwn, 1, unit_address); 7964 7965 if (memcmp((void *)unit_address, (void *)phyp->target->unit_address, 7966 strnlen(phyp->target->unit_address, PMCS_MAX_UA_SIZE)) == 0) { 7967 rval = B_TRUE; 7968 } 7969 7970 return (rval); 7971 } 7972 /* 7973 * Commands used to serialize SMP requests. 7974 * 7975 * The SPC only allows 2 SMP commands per SMP target: 1 cmd pending and 1 cmd 7976 * queued for the same SMP target. If a third SMP cmd is sent to the SPC for an 7977 * SMP target that already has a SMP cmd pending and one queued, then the 7978 * SPC responds with the ERROR_INTERNAL_SMP_RESOURCE response. 7979 * 7980 * Additionally, the SPC has an 8 entry deep cmd queue and the number of SMP 7981 * cmds that can be queued is controlled by the PORT_CONTROL IOMB. The 7982 * SPC default is 1 SMP command/port (iport). These 2 queued SMP cmds would 7983 * have to be for different SMP targets. The INTERNAL_SMP_RESOURCE error will 7984 * also be returned if a 2nd SMP cmd is sent to the controller when there is 7985 * already 1 SMP cmd queued for that port or if a 3rd SMP cmd is sent to the 7986 * queue if there are already 2 queued SMP cmds. 7987 */ 7988 void 7989 pmcs_smp_acquire(pmcs_iport_t *iport) 7990 { 7991 if (iport == NULL) { 7992 return; 7993 } 7994 7995 mutex_enter(&iport->smp_lock); 7996 while (iport->smp_active) { 7997 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG_IPORT, NULL, NULL, 7998 "%s: SMP is active on thread 0x%p, waiting", __func__, 7999 (void *)iport->smp_active_thread); 8000 cv_wait(&iport->smp_cv, &iport->smp_lock); 8001 } 8002 iport->smp_active = B_TRUE; 8003 iport->smp_active_thread = curthread; 8004 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG3, NULL, NULL, 8005 "%s: SMP acquired by thread 0x%p", __func__, 8006 (void *)iport->smp_active_thread); 8007 mutex_exit(&iport->smp_lock); 8008 } 8009 8010 void 8011 pmcs_smp_release(pmcs_iport_t *iport) 8012 { 8013 if (iport == NULL) { 8014 return; 8015 } 8016 8017 mutex_enter(&iport->smp_lock); 8018 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG3, NULL, NULL, 8019 "%s: SMP released by thread 0x%p", __func__, (void *)curthread); 8020 iport->smp_active = B_FALSE; 8021 iport->smp_active_thread = NULL; 8022 cv_signal(&iport->smp_cv); 8023 mutex_exit(&iport->smp_lock); 8024 } 8025 8026 /* 8027 * Update a PHY's attached-port-pm and target-port-pm properties 8028 * 8029 * phyp: PHY whose properties are to be updated 8030 * 8031 * att_bv: Bit value of the attached-port-pm property to be updated in the 8032 * 64-bit holding area for the PHY. 8033 * 8034 * tgt_bv: Bit value of the target-port-pm property to update in the 64-bit 8035 * holding area for the PHY. 8036 * 8037 * prop_add_val: If TRUE, we're adding bits into the property value. 8038 * Otherwise, we're taking them out. Either way, the properties for this 8039 * PHY will be updated. 8040 */ 8041 void 8042 pmcs_update_phy_pm_props(pmcs_phy_t *phyp, uint64_t att_bv, uint64_t tgt_bv, 8043 boolean_t prop_add_val) 8044 { 8045 if (prop_add_val) { 8046 /* 8047 * If the values are currently 0, then we're setting the 8048 * phymask for just this PHY as well. 8049 */ 8050 if (phyp->att_port_pm_tmp == 0) { 8051 phyp->att_port_pm = att_bv; 8052 phyp->tgt_port_pm = tgt_bv; 8053 } 8054 phyp->att_port_pm_tmp |= att_bv; 8055 phyp->tgt_port_pm_tmp |= tgt_bv; 8056 (void) snprintf(phyp->att_port_pm_str, PMCS_PM_MAX_NAMELEN, 8057 "%"PRIx64, phyp->att_port_pm_tmp); 8058 (void) snprintf(phyp->tgt_port_pm_str, PMCS_PM_MAX_NAMELEN, 8059 "%"PRIx64, phyp->tgt_port_pm_tmp); 8060 } else { 8061 phyp->att_port_pm_tmp &= ~att_bv; 8062 phyp->tgt_port_pm_tmp &= ~tgt_bv; 8063 if (phyp->att_port_pm_tmp) { 8064 (void) snprintf(phyp->att_port_pm_str, 8065 PMCS_PM_MAX_NAMELEN, "%"PRIx64, 8066 phyp->att_port_pm_tmp); 8067 } else { 8068 phyp->att_port_pm_str[0] = '\0'; 8069 phyp->att_port_pm = 0; 8070 } 8071 if (phyp->tgt_port_pm_tmp) { 8072 (void) snprintf(phyp->tgt_port_pm_str, 8073 PMCS_PM_MAX_NAMELEN, "%"PRIx64, 8074 phyp->tgt_port_pm_tmp); 8075 } else { 8076 phyp->tgt_port_pm_str[0] = '\0'; 8077 phyp->tgt_port_pm = 0; 8078 } 8079 } 8080 8081 if (phyp->target == NULL) { 8082 return; 8083 } 8084 8085 mutex_enter(&phyp->target->statlock); 8086 if (!list_is_empty(&phyp->target->lun_list)) { 8087 pmcs_lun_t *lunp; 8088 8089 lunp = list_head(&phyp->target->lun_list); 8090 while (lunp) { 8091 (void) scsi_device_prop_update_string(lunp->sd, 8092 SCSI_DEVICE_PROP_PATH, 8093 SCSI_ADDR_PROP_ATTACHED_PORT_PM, 8094 phyp->att_port_pm_str); 8095 (void) scsi_device_prop_update_string(lunp->sd, 8096 SCSI_DEVICE_PROP_PATH, 8097 SCSI_ADDR_PROP_TARGET_PORT_PM, 8098 phyp->tgt_port_pm_str); 8099 lunp = list_next(&phyp->target->lun_list, lunp); 8100 } 8101 } else if (phyp->target->smpd) { 8102 (void) smp_device_prop_update_string(phyp->target->smpd, 8103 SCSI_ADDR_PROP_ATTACHED_PORT_PM, 8104 phyp->att_port_pm_str); 8105 (void) smp_device_prop_update_string(phyp->target->smpd, 8106 SCSI_ADDR_PROP_TARGET_PORT_PM, 8107 phyp->tgt_port_pm_str); 8108 } 8109 mutex_exit(&phyp->target->statlock); 8110 } 8111 8112 /* ARGSUSED */ 8113 void 8114 pmcs_deregister_device_work(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 8115 { 8116 pmcs_phy_t *pptr; 8117 8118 for (pptr = pwp->root_phys; pptr; pptr = pptr->sibling) { 8119 pmcs_lock_phy(pptr); 8120 if (pptr->deregister_wait) { 8121 pmcs_deregister_device(pwp, pptr); 8122 } 8123 pmcs_unlock_phy(pptr); 8124 } 8125 } 8126 8127 /* 8128 * pmcs_iport_active 8129 * 8130 * Mark this iport as active. Called with the iport lock held. 8131 */ 8132 static void 8133 pmcs_iport_active(pmcs_iport_t *iport) 8134 { 8135 ASSERT(mutex_owned(&iport->lock)); 8136 8137 iport->ua_state = UA_ACTIVE; 8138 iport->smp_active = B_FALSE; 8139 iport->smp_active_thread = NULL; 8140 } 8141 8142 /* ARGSUSED */ 8143 static void 8144 pmcs_tgtmap_activate_cb(void *tgtmap_priv, char *tgt_addr, 8145 scsi_tgtmap_tgt_type_t tgt_type, void **tgt_privp) 8146 { 8147 pmcs_iport_t *iport = (pmcs_iport_t *)tgtmap_priv; 8148 pmcs_hw_t *pwp = iport->pwp; 8149 pmcs_xscsi_t *target; 8150 8151 /* 8152 * Look up the target. If there is one, and it doesn't have a PHY 8153 * pointer, re-establish that linkage here. 8154 */ 8155 mutex_enter(&pwp->lock); 8156 target = pmcs_get_target(iport, tgt_addr, B_FALSE); 8157 mutex_exit(&pwp->lock); 8158 8159 /* 8160 * If we got a target, it will now have a PHY pointer and the PHY 8161 * will point to the target. The PHY will be locked, so we'll need 8162 * to unlock it. 8163 */ 8164 if (target != NULL) { 8165 pmcs_unlock_phy(target->phy); 8166 } 8167 8168 /* 8169 * Update config_restart_time so we don't try to restart discovery 8170 * while enumeration is still in progress. 8171 */ 8172 mutex_enter(&pwp->config_lock); 8173 pwp->config_restart_time = ddi_get_lbolt() + 8174 drv_usectohz(PMCS_REDISCOVERY_DELAY); 8175 mutex_exit(&pwp->config_lock); 8176 } 8177 8178 /* ARGSUSED */ 8179 static boolean_t 8180 pmcs_tgtmap_deactivate_cb(void *tgtmap_priv, char *tgt_addr, 8181 scsi_tgtmap_tgt_type_t tgt_type, void *tgt_priv, 8182 scsi_tgtmap_deact_rsn_t tgt_deact_rsn) 8183 { 8184 pmcs_iport_t *iport = (pmcs_iport_t *)tgtmap_priv; 8185 pmcs_phy_t *phyp; 8186 boolean_t rediscover = B_FALSE; 8187 8188 ASSERT(iport); 8189 8190 phyp = pmcs_find_phy_by_sas_address(iport->pwp, iport, NULL, tgt_addr); 8191 if (phyp == NULL) { 8192 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG_IPORT, NULL, NULL, 8193 "%s: Couldn't find PHY at %s", __func__, tgt_addr); 8194 return (rediscover); 8195 } 8196 /* phyp is locked */ 8197 8198 if (!phyp->reenumerate && phyp->configured) { 8199 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG_CONFIG, phyp, phyp->target, 8200 "%s: PHY @ %s is configured... re-enumerate", __func__, 8201 tgt_addr); 8202 phyp->reenumerate = 1; 8203 } 8204 8205 /* 8206 * Check to see if reenumerate is set, and if so, if we've reached our 8207 * maximum number of retries. 8208 */ 8209 if (phyp->reenumerate) { 8210 if (phyp->enum_attempts == PMCS_MAX_REENUMERATE) { 8211 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG_CONFIG, phyp, 8212 phyp->target, 8213 "%s: No more enumeration attempts for %s", __func__, 8214 tgt_addr); 8215 } else { 8216 pmcs_prt(iport->pwp, PMCS_PRT_DEBUG_CONFIG, phyp, 8217 phyp->target, "%s: Re-attempt enumeration for %s", 8218 __func__, tgt_addr); 8219 ++phyp->enum_attempts; 8220 rediscover = B_TRUE; 8221 } 8222 8223 phyp->reenumerate = 0; 8224 } 8225 8226 pmcs_unlock_phy(phyp); 8227 8228 mutex_enter(&iport->pwp->config_lock); 8229 iport->pwp->config_restart_time = ddi_get_lbolt() + 8230 drv_usectohz(PMCS_REDISCOVERY_DELAY); 8231 if (rediscover) { 8232 iport->pwp->config_restart = B_TRUE; 8233 } else if (iport->pwp->config_restart == B_TRUE) { 8234 /* 8235 * If we aren't asking for rediscovery because of this PHY, 8236 * check to see if we're already asking for it on behalf of 8237 * some other PHY. If so, we'll want to return TRUE, so reset 8238 * "rediscover" here. 8239 */ 8240 rediscover = B_TRUE; 8241 } 8242 8243 mutex_exit(&iport->pwp->config_lock); 8244 8245 return (rediscover); 8246 } 8247 8248 void 8249 pmcs_status_disposition(pmcs_phy_t *phyp, uint32_t status) 8250 { 8251 ASSERT(phyp); 8252 ASSERT(!mutex_owned(&phyp->phy_lock)); 8253 8254 if (phyp == NULL) { 8255 return; 8256 } 8257 8258 pmcs_lock_phy(phyp); 8259 8260 /* 8261 * XXX: Do we need to call this function from an SSP_EVENT? 8262 */ 8263 8264 switch (status) { 8265 case PMCOUT_STATUS_NO_DEVICE: 8266 case PMCOUT_STATUS_ERROR_HW_TIMEOUT: 8267 case PMCOUT_STATUS_XFER_ERR_BREAK: 8268 case PMCOUT_STATUS_XFER_ERR_PHY_NOT_READY: 8269 case PMCOUT_STATUS_OPEN_CNX_PROTOCOL_NOT_SUPPORTED: 8270 case PMCOUT_STATUS_OPEN_CNX_ERROR_ZONE_VIOLATION: 8271 case PMCOUT_STATUS_OPEN_CNX_ERROR_BREAK: 8272 case PMCOUT_STATUS_OPENCNX_ERROR_BAD_DESTINATION: 8273 case PMCOUT_STATUS_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: 8274 case PMCOUT_STATUS_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: 8275 case PMCOUT_STATUS_OPEN_CNX_ERROR_WRONG_DESTINATION: 8276 case PMCOUT_STATUS_OPEN_CNX_ERROR_UNKNOWN_ERROR: 8277 case PMCOUT_STATUS_IO_XFER_ERROR_NAK_RECEIVED: 8278 case PMCOUT_STATUS_XFER_ERROR_RX_FRAME: 8279 case PMCOUT_STATUS_IO_XFER_OPEN_RETRY_TIMEOUT: 8280 case PMCOUT_STATUS_ERROR_INTERNAL_SMP_RESOURCE: 8281 case PMCOUT_STATUS_IO_PORT_IN_RESET: 8282 case PMCOUT_STATUS_IO_DS_NON_OPERATIONAL: 8283 case PMCOUT_STATUS_IO_DS_IN_RECOVERY: 8284 case PMCOUT_STATUS_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: 8285 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG, phyp, phyp->target, 8286 "%s: status = 0x%x for " SAS_ADDR_FMT ", reenumerate", 8287 __func__, status, SAS_ADDR_PRT(phyp->sas_address)); 8288 phyp->reenumerate = 1; 8289 break; 8290 8291 default: 8292 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG, phyp, phyp->target, 8293 "%s: status = 0x%x for " SAS_ADDR_FMT ", no reenumeration", 8294 __func__, status, SAS_ADDR_PRT(phyp->sas_address)); 8295 break; 8296 } 8297 8298 pmcs_unlock_phy(phyp); 8299 } 8300 8301 /* 8302 * Add the list of PHYs pointed to by phyp to the dead_phys_list 8303 * 8304 * Called with all PHYs in the list locked 8305 */ 8306 static void 8307 pmcs_add_dead_phys(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 8308 { 8309 mutex_enter(&pwp->dead_phylist_lock); 8310 while (phyp) { 8311 pmcs_phy_t *nxt = phyp->sibling; 8312 ASSERT(phyp->dead); 8313 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, NULL, 8314 "%s: dead PHY 0x%p (%s) (ref_count %d)", __func__, 8315 (void *)phyp, phyp->path, phyp->ref_count); 8316 /* 8317 * Put this PHY on the dead PHY list for the watchdog to 8318 * clean up after any outstanding work has completed. 8319 */ 8320 phyp->dead_next = pwp->dead_phys; 8321 pwp->dead_phys = phyp; 8322 pmcs_unlock_phy(phyp); 8323 phyp = nxt; 8324 } 8325 mutex_exit(&pwp->dead_phylist_lock); 8326 } 8327 8328 static void 8329 pmcs_get_fw_version(pmcs_hw_t *pwp) 8330 { 8331 uint32_t ila_len, ver_hi, ver_lo; 8332 uint8_t ila_ver_string[9], img_flag; 8333 char uc, *ucp = &uc; 8334 unsigned long ila_ver; 8335 uint64_t ver_hilo; 8336 8337 /* Firmware version is easy. */ 8338 pwp->fw = pmcs_rd_mpi_tbl(pwp, PMCS_MPI_FW); 8339 8340 /* 8341 * Get the image size (2nd to last dword) 8342 * NOTE: The GSM registers are mapped little-endian, but the data 8343 * on the flash is actually big-endian, so we need to swap these values 8344 * regardless of which platform we're on. 8345 */ 8346 ila_len = BSWAP_32(pmcs_rd_gsm_reg(pwp, GSM_FLASH_BASE_UPPER, 8347 GSM_FLASH_BASE + GSM_SM_BLKSZ - (2 << 2))); 8348 if (ila_len > 65535) { 8349 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 8350 "%s: Invalid ILA image size (0x%x)?", __func__, ila_len); 8351 return; 8352 } 8353 8354 /* 8355 * The numeric version is at ila_len - PMCS_ILA_VER_OFFSET 8356 */ 8357 ver_hi = BSWAP_32(pmcs_rd_gsm_reg(pwp, GSM_FLASH_BASE_UPPER, 8358 GSM_FLASH_BASE + ila_len - PMCS_ILA_VER_OFFSET)); 8359 ver_lo = BSWAP_32(pmcs_rd_gsm_reg(pwp, GSM_FLASH_BASE_UPPER, 8360 GSM_FLASH_BASE + ila_len - PMCS_ILA_VER_OFFSET + 4)); 8361 ver_hilo = BE_64(((uint64_t)ver_hi << 32) | ver_lo); 8362 bcopy((const void *)&ver_hilo, &ila_ver_string[0], 8); 8363 ila_ver_string[8] = '\0'; 8364 8365 (void) ddi_strtoul((const char *)ila_ver_string, &ucp, 16, &ila_ver); 8366 pwp->ila_ver = (int)(ila_ver & 0xffffffff); 8367 8368 img_flag = (BSWAP_32(pmcs_rd_gsm_reg(pwp, GSM_FLASH_BASE_UPPER, 8369 GSM_FLASH_IMG_FLAGS)) & 0xff000000) >> 24; 8370 if (img_flag & PMCS_IMG_FLAG_A) { 8371 pwp->fw_active_img = 1; 8372 } else { 8373 pwp->fw_active_img = 0; 8374 } 8375 } 8376