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