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 /* keep dtype */ 2879 pptr->config_stop = 0; 2880 pptr->spinup_hold = 0; 2881 pptr->atdt = 0; 2882 /* keep portid */ 2883 pptr->link_rate = 0; 2884 pptr->valid_device_id = 0; 2885 pptr->abort_sent = 0; 2886 pptr->abort_pending = 0; 2887 pptr->need_rl_ext = 0; 2888 pptr->subsidiary = 0; 2889 pptr->configured = 0; 2890 /* Only mark dead if it's not a root PHY and its dtype isn't NOTHING */ 2891 /* XXX: What about directly attached disks? */ 2892 if (!IS_ROOT_PHY(pptr) && (pptr->dtype != NOTHING)) 2893 pptr->dead = 1; 2894 pptr->changed = 0; 2895 /* keep SAS address */ 2896 /* keep path */ 2897 /* keep ref_count */ 2898 /* Don't clear iport on root PHYs - they are handled in pmcs_intr.c */ 2899 if (!IS_ROOT_PHY(pptr)) { 2900 pptr->iport = NULL; 2901 } 2902 /* keep target */ 2903 } 2904 2905 /* 2906 * Allocate softstate for this target if there isn't already one. If there 2907 * is, just redo our internal configuration. If it is actually "new", we'll 2908 * soon get a tran_tgt_init for it. 2909 * 2910 * Called with PHY locked. 2911 */ 2912 static void 2913 pmcs_new_tport(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 2914 { 2915 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, "%s: phy 0x%p @ %s", 2916 __func__, (void *)pptr, pptr->path); 2917 2918 if (pmcs_configure_phy(pwp, pptr) == B_FALSE) { 2919 /* 2920 * If the config failed, mark the PHY as changed. 2921 */ 2922 PHY_CHANGED(pwp, pptr); 2923 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 2924 "%s: pmcs_configure_phy failed for phy 0x%p", __func__, 2925 (void *)pptr); 2926 return; 2927 } 2928 2929 /* Mark PHY as no longer changed */ 2930 pptr->changed = 0; 2931 2932 /* 2933 * If the PHY has no target pointer, see if there's a dead PHY that 2934 * matches. 2935 */ 2936 if (pptr->target == NULL) { 2937 pmcs_reap_dead_phy(pptr); 2938 } 2939 2940 /* 2941 * Only assign the device if there is a target for this PHY with a 2942 * matching SAS address. If an iport is disconnected from one piece 2943 * of storage and connected to another within the iport stabilization 2944 * time, we can get the PHY/target mismatch situation. 2945 * 2946 * Otherwise, it'll get done in tran_tgt_init. 2947 */ 2948 if (pptr->target) { 2949 mutex_enter(&pptr->target->statlock); 2950 if (pmcs_phy_target_match(pptr) == B_FALSE) { 2951 mutex_exit(&pptr->target->statlock); 2952 if (!IS_ROOT_PHY(pptr)) { 2953 pmcs_dec_phy_ref_count(pptr); 2954 } 2955 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 2956 "%s: Not assigning existing tgt %p for PHY %p " 2957 "(WWN mismatch)", __func__, (void *)pptr->target, 2958 (void *)pptr); 2959 pptr->target = NULL; 2960 return; 2961 } 2962 2963 if (!pmcs_assign_device(pwp, pptr->target)) { 2964 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, pptr->target, 2965 "%s: pmcs_assign_device failed for target 0x%p", 2966 __func__, (void *)pptr->target); 2967 } 2968 mutex_exit(&pptr->target->statlock); 2969 } 2970 } 2971 2972 /* 2973 * Called with PHY lock held. 2974 */ 2975 static boolean_t 2976 pmcs_configure_phy(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 2977 { 2978 char *dtype; 2979 2980 ASSERT(mutex_owned(&pptr->phy_lock)); 2981 2982 /* 2983 * Mark this device as no longer changed. 2984 */ 2985 pptr->changed = 0; 2986 2987 /* 2988 * If we don't have a device handle, get one. 2989 */ 2990 if (pmcs_get_device_handle(pwp, pptr)) { 2991 return (B_FALSE); 2992 } 2993 2994 pptr->configured = 1; 2995 2996 switch (pptr->dtype) { 2997 case SAS: 2998 dtype = "SAS"; 2999 break; 3000 case SATA: 3001 dtype = "SATA"; 3002 break; 3003 case EXPANDER: 3004 dtype = "SMP"; 3005 break; 3006 default: 3007 dtype = "???"; 3008 } 3009 3010 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, "config_dev: %s " 3011 "dev %s " SAS_ADDR_FMT " dev id 0x%x lr 0x%x", dtype, pptr->path, 3012 SAS_ADDR_PRT(pptr->sas_address), pptr->device_id, pptr->link_rate); 3013 3014 return (B_TRUE); 3015 } 3016 3017 /* 3018 * Called with PHY locked 3019 */ 3020 static void 3021 pmcs_configure_expander(pmcs_hw_t *pwp, pmcs_phy_t *pptr, pmcs_iport_t *iport) 3022 { 3023 pmcs_phy_t *ctmp, *clist = NULL, *cnext; 3024 int result, i, nphy = 0; 3025 boolean_t root_phy = B_FALSE; 3026 3027 ASSERT(iport); 3028 3029 /* 3030 * Step 1- clear our "changed" bit. If we need to retry/restart due 3031 * to resource shortages, we'll set it again. While we're doing 3032 * configuration, other events may set it again as well. If the PHY 3033 * is a root PHY and is currently marked as having changed, reset the 3034 * config_stop timer as well. 3035 */ 3036 if (IS_ROOT_PHY(pptr) && pptr->changed) { 3037 pptr->config_stop = ddi_get_lbolt() + 3038 drv_usectohz(PMCS_MAX_CONFIG_TIME); 3039 } 3040 pptr->changed = 0; 3041 3042 /* 3043 * Step 2- make sure we don't overflow 3044 */ 3045 if (pptr->level == PMCS_MAX_XPND-1) { 3046 pmcs_prt(pwp, PMCS_PRT_WARN, pptr, NULL, 3047 "%s: SAS expansion tree too deep", __func__); 3048 return; 3049 } 3050 3051 /* 3052 * Step 3- Check if this expander is part of a wide phy that has 3053 * already been configured. 3054 * 3055 * This is known by checking this level for another EXPANDER device 3056 * with the same SAS address and isn't already marked as a subsidiary 3057 * phy and a parent whose SAS address is the same as our SAS address 3058 * (if there are parents). 3059 */ 3060 if (!IS_ROOT_PHY(pptr)) { 3061 /* 3062 * No need to lock the parent here because we're in discovery 3063 * and the only time a PHY's children pointer can change is 3064 * in discovery; either in pmcs_clear_expander (which has 3065 * already been called) or here, down below. Plus, trying to 3066 * grab the parent's lock here can cause deadlock. 3067 */ 3068 ctmp = pptr->parent->children; 3069 } else { 3070 ctmp = pwp->root_phys; 3071 root_phy = B_TRUE; 3072 } 3073 3074 while (ctmp) { 3075 /* 3076 * If we've checked all PHYs up to pptr, we stop. Otherwise, 3077 * we'll be checking for a primary PHY with a higher PHY 3078 * number than pptr, which will never happen. The primary 3079 * PHY on non-root expanders will ALWAYS be the lowest 3080 * numbered PHY. 3081 */ 3082 if (ctmp == pptr) { 3083 break; 3084 } 3085 3086 /* 3087 * If pptr and ctmp are root PHYs, just grab the mutex on 3088 * ctmp. No need to lock the entire tree. If they are not 3089 * root PHYs, there is no need to lock since a non-root PHY's 3090 * SAS address and other characteristics can only change in 3091 * discovery anyway. 3092 */ 3093 if (root_phy) { 3094 mutex_enter(&ctmp->phy_lock); 3095 } 3096 3097 if (ctmp->dtype == EXPANDER && ctmp->width && 3098 memcmp(ctmp->sas_address, pptr->sas_address, 8) == 0) { 3099 int widephy = 0; 3100 /* 3101 * If these phys are not root PHYs, compare their SAS 3102 * addresses too. 3103 */ 3104 if (!root_phy) { 3105 if (memcmp(ctmp->parent->sas_address, 3106 pptr->parent->sas_address, 8) == 0) { 3107 widephy = 1; 3108 } 3109 } else { 3110 widephy = 1; 3111 } 3112 if (widephy) { 3113 ctmp->width++; 3114 pptr->subsidiary = 1; 3115 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3116 "%s: PHY %s part of wide PHY %s " 3117 "(now %d wide)", __func__, pptr->path, 3118 ctmp->path, ctmp->width); 3119 if (root_phy) { 3120 mutex_exit(&ctmp->phy_lock); 3121 } 3122 return; 3123 } 3124 } 3125 3126 cnext = ctmp->sibling; 3127 if (root_phy) { 3128 mutex_exit(&ctmp->phy_lock); 3129 } 3130 ctmp = cnext; 3131 } 3132 3133 /* 3134 * Step 4- If we don't have a device handle, get one. Since this 3135 * is the primary PHY, make sure subsidiary is cleared. 3136 */ 3137 pptr->subsidiary = 0; 3138 if (pmcs_get_device_handle(pwp, pptr)) { 3139 goto out; 3140 } 3141 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, "Config expander %s " 3142 SAS_ADDR_FMT " dev id 0x%x lr 0x%x", pptr->path, 3143 SAS_ADDR_PRT(pptr->sas_address), pptr->device_id, pptr->link_rate); 3144 3145 /* 3146 * Step 5- figure out how many phys are in this expander. 3147 */ 3148 nphy = pmcs_expander_get_nphy(pwp, pptr); 3149 if (nphy <= 0) { 3150 if (nphy == 0 && ddi_get_lbolt() < pptr->config_stop) { 3151 PHY_CHANGED(pwp, pptr); 3152 RESTART_DISCOVERY(pwp); 3153 } else { 3154 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3155 "%s: Retries exhausted for %s, killing", __func__, 3156 pptr->path); 3157 pptr->config_stop = 0; 3158 pmcs_kill_changed(pwp, pptr, 0); 3159 } 3160 goto out; 3161 } 3162 3163 /* 3164 * Step 6- Allocate a list of phys for this expander and figure out 3165 * what each one is. 3166 */ 3167 for (i = 0; i < nphy; i++) { 3168 ctmp = kmem_cache_alloc(pwp->phy_cache, KM_SLEEP); 3169 bzero(ctmp, sizeof (pmcs_phy_t)); 3170 ctmp->device_id = PMCS_INVALID_DEVICE_ID; 3171 ctmp->sibling = clist; 3172 ctmp->pend_dtype = NEW; /* Init pending dtype */ 3173 ctmp->config_stop = ddi_get_lbolt() + 3174 drv_usectohz(PMCS_MAX_CONFIG_TIME); 3175 clist = ctmp; 3176 } 3177 3178 mutex_enter(&pwp->config_lock); 3179 if (pwp->config_changed) { 3180 RESTART_DISCOVERY_LOCKED(pwp); 3181 mutex_exit(&pwp->config_lock); 3182 /* 3183 * Clean up the newly allocated PHYs and return 3184 */ 3185 while (clist) { 3186 ctmp = clist->sibling; 3187 kmem_cache_free(pwp->phy_cache, clist); 3188 clist = ctmp; 3189 } 3190 return; 3191 } 3192 mutex_exit(&pwp->config_lock); 3193 3194 /* 3195 * Step 7- Now fill in the rest of the static portions of the phy. 3196 */ 3197 for (i = 0, ctmp = clist; ctmp; ctmp = ctmp->sibling, i++) { 3198 ctmp->parent = pptr; 3199 ctmp->pwp = pwp; 3200 ctmp->level = pptr->level+1; 3201 ctmp->portid = pptr->portid; 3202 if (ctmp->tolerates_sas2) { 3203 ASSERT(i < SAS2_PHYNUM_MAX); 3204 ctmp->phynum = i & SAS2_PHYNUM_MASK; 3205 } else { 3206 ASSERT(i < SAS_PHYNUM_MAX); 3207 ctmp->phynum = i & SAS_PHYNUM_MASK; 3208 } 3209 pmcs_phy_name(pwp, ctmp, ctmp->path, sizeof (ctmp->path)); 3210 pmcs_lock_phy(ctmp); 3211 } 3212 3213 /* 3214 * Step 8- Discover things about each phy in the expander. 3215 */ 3216 for (i = 0, ctmp = clist; ctmp; ctmp = ctmp->sibling, i++) { 3217 result = pmcs_expander_content_discover(pwp, pptr, ctmp); 3218 if (result <= 0) { 3219 if (ddi_get_lbolt() < pptr->config_stop) { 3220 PHY_CHANGED(pwp, pptr); 3221 RESTART_DISCOVERY(pwp); 3222 } else { 3223 pptr->config_stop = 0; 3224 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3225 "%s: Retries exhausted for %s, killing", 3226 __func__, pptr->path); 3227 pmcs_kill_changed(pwp, pptr, 0); 3228 } 3229 goto out; 3230 } 3231 3232 /* Set pend_dtype to dtype for 1st time initialization */ 3233 ctmp->pend_dtype = ctmp->dtype; 3234 } 3235 3236 /* 3237 * Step 9- Install the new list on the next level. There should be 3238 * no children pointer on this PHY. If there is, we'd need to know 3239 * how it happened (The expander suddenly got more PHYs?). 3240 */ 3241 ASSERT(pptr->children == NULL); 3242 if (pptr->children != NULL) { 3243 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, "%s: Already child " 3244 "PHYs attached to PHY %s: This should never happen", 3245 __func__, pptr->path); 3246 goto out; 3247 } else { 3248 pptr->children = clist; 3249 } 3250 3251 clist = NULL; 3252 pptr->ncphy = nphy; 3253 pptr->configured = 1; 3254 3255 /* 3256 * We only set width if we're greater than level 0. 3257 */ 3258 if (pptr->level) { 3259 pptr->width = 1; 3260 } 3261 3262 /* 3263 * Now tell the rest of the world about us, as an SMP node. 3264 */ 3265 pptr->iport = iport; 3266 pmcs_new_tport(pwp, pptr); 3267 3268 out: 3269 while (clist) { 3270 ctmp = clist->sibling; 3271 pmcs_unlock_phy(clist); 3272 kmem_cache_free(pwp->phy_cache, clist); 3273 clist = ctmp; 3274 } 3275 } 3276 3277 /* 3278 * 2. Check expanders marked changed (but not dead) to see if they still have 3279 * the same number of phys and the same SAS address. Mark them, their subsidiary 3280 * phys (if wide) and their descendents dead if anything has changed. Check the 3281 * the devices they contain to see if *they* have changed. If they've changed 3282 * from type NOTHING we leave them marked changed to be configured later 3283 * (picking up a new SAS address and link rate if possible). Otherwise, any 3284 * change in type, SAS address or removal of target role will cause us to 3285 * mark them (and their descendents) as dead and cause any pending commands 3286 * and associated devices to be removed. 3287 * 3288 * Called with PHY (pptr) locked. 3289 */ 3290 3291 static void 3292 pmcs_check_expander(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 3293 { 3294 int nphy, result; 3295 pmcs_phy_t *ctmp, *local, *local_list = NULL, *local_tail = NULL; 3296 boolean_t kill_changed, changed; 3297 3298 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3299 "%s: check %s", __func__, pptr->path); 3300 3301 /* 3302 * Step 1: Mark phy as not changed. We will mark it changed if we need 3303 * to retry. 3304 */ 3305 pptr->changed = 0; 3306 3307 /* 3308 * Reset the config_stop time. Although we're not actually configuring 3309 * anything here, we do want some indication of when to give up trying 3310 * if we can't communicate with the expander. 3311 */ 3312 pptr->config_stop = ddi_get_lbolt() + 3313 drv_usectohz(PMCS_MAX_CONFIG_TIME); 3314 3315 /* 3316 * Step 2: Figure out how many phys are in this expander. If 3317 * pmcs_expander_get_nphy returns 0 we ran out of resources, 3318 * so reschedule and try later. If it returns another error, 3319 * just return. 3320 */ 3321 nphy = pmcs_expander_get_nphy(pwp, pptr); 3322 if (nphy <= 0) { 3323 if ((nphy == 0) && (ddi_get_lbolt() < pptr->config_stop)) { 3324 PHY_CHANGED(pwp, pptr); 3325 RESTART_DISCOVERY(pwp); 3326 } else { 3327 pptr->config_stop = 0; 3328 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3329 "%s: Retries exhausted for %s, killing", __func__, 3330 pptr->path); 3331 pmcs_kill_changed(pwp, pptr, 0); 3332 } 3333 return; 3334 } 3335 3336 /* 3337 * Step 3: If the number of phys don't agree, kill the old sub-tree. 3338 */ 3339 if (nphy != pptr->ncphy) { 3340 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3341 "%s: number of contained phys for %s changed from %d to %d", 3342 __func__, pptr->path, pptr->ncphy, nphy); 3343 /* 3344 * Force a rescan of this expander after dead contents 3345 * are cleared and removed. 3346 */ 3347 pmcs_kill_changed(pwp, pptr, 0); 3348 return; 3349 } 3350 3351 /* 3352 * Step 4: if we're at the bottom of the stack, we're done 3353 * (we can't have any levels below us) 3354 */ 3355 if (pptr->level == PMCS_MAX_XPND-1) { 3356 return; 3357 } 3358 3359 /* 3360 * Step 5: Discover things about each phy in this expander. We do 3361 * this by walking the current list of contained phys and doing a 3362 * content discovery for it to a local phy. 3363 */ 3364 ctmp = pptr->children; 3365 ASSERT(ctmp); 3366 if (ctmp == NULL) { 3367 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3368 "%s: No children attached to expander @ %s?", __func__, 3369 pptr->path); 3370 return; 3371 } 3372 3373 while (ctmp) { 3374 /* 3375 * Allocate a local PHY to contain the proposed new contents 3376 * and link it to the rest of the local PHYs so that they 3377 * can all be freed later. 3378 */ 3379 local = pmcs_clone_phy(ctmp); 3380 3381 if (local_list == NULL) { 3382 local_list = local; 3383 local_tail = local; 3384 } else { 3385 local_tail->sibling = local; 3386 local_tail = local; 3387 } 3388 3389 /* 3390 * Need to lock the local PHY since pmcs_expander_content_ 3391 * discovery may call pmcs_clear_phy on it, which expects 3392 * the PHY to be locked. 3393 */ 3394 pmcs_lock_phy(local); 3395 result = pmcs_expander_content_discover(pwp, pptr, local); 3396 pmcs_unlock_phy(local); 3397 if (result <= 0) { 3398 if (ddi_get_lbolt() < pptr->config_stop) { 3399 PHY_CHANGED(pwp, pptr); 3400 RESTART_DISCOVERY(pwp); 3401 } else { 3402 pptr->config_stop = 0; 3403 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3404 "%s: Retries exhausted for %s, killing", 3405 __func__, pptr->path); 3406 pmcs_kill_changed(pwp, pptr, 0); 3407 } 3408 3409 /* 3410 * Release all the local PHYs that we allocated. 3411 */ 3412 pmcs_free_phys(pwp, local_list); 3413 return; 3414 } 3415 3416 ctmp = ctmp->sibling; 3417 } 3418 3419 /* 3420 * Step 6: Compare the local PHY's contents to our current PHY. If 3421 * there are changes, take the appropriate action. 3422 * This is done in two steps (step 5 above, and 6 here) so that if we 3423 * have to bail during this process (e.g. pmcs_expander_content_discover 3424 * fails), we haven't actually changed the state of any of the real 3425 * PHYs. Next time we come through here, we'll be starting over from 3426 * scratch. This keeps us from marking a changed PHY as no longer 3427 * changed, but then having to bail only to come back next time and 3428 * think that the PHY hadn't changed. If this were to happen, we 3429 * would fail to properly configure the device behind this PHY. 3430 */ 3431 local = local_list; 3432 ctmp = pptr->children; 3433 3434 while (ctmp) { 3435 changed = B_FALSE; 3436 kill_changed = B_FALSE; 3437 3438 /* 3439 * We set local to local_list prior to this loop so that we 3440 * can simply walk the local_list while we walk this list. The 3441 * two lists should be completely in sync. 3442 * 3443 * Clear the changed flag here. 3444 */ 3445 ctmp->changed = 0; 3446 3447 if (ctmp->dtype != local->dtype) { 3448 if (ctmp->dtype != NOTHING) { 3449 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 3450 "%s: %s type changed from %s to %s " 3451 "(killing)", __func__, ctmp->path, 3452 PHY_TYPE(ctmp), PHY_TYPE(local)); 3453 /* 3454 * Force a rescan of this expander after dead 3455 * contents are cleared and removed. 3456 */ 3457 changed = B_TRUE; 3458 kill_changed = B_TRUE; 3459 } else { 3460 changed = B_TRUE; 3461 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 3462 "%s: %s type changed from NOTHING to %s", 3463 __func__, ctmp->path, PHY_TYPE(local)); 3464 } 3465 3466 } else if (ctmp->atdt != local->atdt) { 3467 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, "%s: " 3468 "%s attached device type changed from %d to %d " 3469 "(killing)", __func__, ctmp->path, ctmp->atdt, 3470 local->atdt); 3471 /* 3472 * Force a rescan of this expander after dead 3473 * contents are cleared and removed. 3474 */ 3475 changed = B_TRUE; 3476 3477 if (local->atdt == 0) { 3478 kill_changed = B_TRUE; 3479 } 3480 } else if (ctmp->link_rate != local->link_rate) { 3481 pmcs_prt(pwp, PMCS_PRT_INFO, ctmp, NULL, "%s: %s " 3482 "changed speed from %s to %s", __func__, ctmp->path, 3483 pmcs_get_rate(ctmp->link_rate), 3484 pmcs_get_rate(local->link_rate)); 3485 /* If the speed changed from invalid, force rescan */ 3486 if (!PMCS_VALID_LINK_RATE(ctmp->link_rate)) { 3487 changed = B_TRUE; 3488 RESTART_DISCOVERY(pwp); 3489 } else { 3490 /* Just update to the new link rate */ 3491 ctmp->link_rate = local->link_rate; 3492 } 3493 3494 if (!PMCS_VALID_LINK_RATE(local->link_rate)) { 3495 kill_changed = B_TRUE; 3496 } 3497 } else if (memcmp(ctmp->sas_address, local->sas_address, 3498 sizeof (ctmp->sas_address)) != 0) { 3499 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 3500 "%s: SAS Addr for %s changed from " SAS_ADDR_FMT 3501 "to " SAS_ADDR_FMT " (kill old tree)", __func__, 3502 ctmp->path, SAS_ADDR_PRT(ctmp->sas_address), 3503 SAS_ADDR_PRT(local->sas_address)); 3504 /* 3505 * Force a rescan of this expander after dead 3506 * contents are cleared and removed. 3507 */ 3508 changed = B_TRUE; 3509 } else { 3510 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 3511 "%s: %s looks the same (type %s)", 3512 __func__, ctmp->path, PHY_TYPE(ctmp)); 3513 /* 3514 * If EXPANDER, still mark it changed so we 3515 * re-evaluate its contents. If it's not an expander, 3516 * but it hasn't been configured, also mark it as 3517 * changed so that it will undergo configuration. 3518 */ 3519 if (ctmp->dtype == EXPANDER) { 3520 changed = B_TRUE; 3521 } else if ((ctmp->dtype != NOTHING) && 3522 !ctmp->configured) { 3523 ctmp->changed = 1; 3524 } else { 3525 /* It simply hasn't changed */ 3526 ctmp->changed = 0; 3527 } 3528 } 3529 3530 /* 3531 * If the PHY changed, call pmcs_kill_changed if indicated, 3532 * update its contents to reflect its current state and mark it 3533 * as changed. 3534 */ 3535 if (changed) { 3536 /* 3537 * pmcs_kill_changed will mark the PHY as changed, so 3538 * only do PHY_CHANGED if we did not do kill_changed. 3539 */ 3540 if (kill_changed) { 3541 pmcs_kill_changed(pwp, ctmp, 0); 3542 } else { 3543 /* 3544 * If we're not killing the device, it's not 3545 * dead. Mark the PHY as changed. 3546 */ 3547 PHY_CHANGED(pwp, ctmp); 3548 3549 if (ctmp->dead) { 3550 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, 3551 ctmp, NULL, "%s: Unmarking PHY %s " 3552 "dead, restarting discovery", 3553 __func__, ctmp->path); 3554 ctmp->dead = 0; 3555 RESTART_DISCOVERY(pwp); 3556 } 3557 } 3558 3559 /* 3560 * If the dtype of this PHY is now NOTHING, mark it as 3561 * unconfigured. Set pend_dtype to what the new dtype 3562 * is. It'll get updated at the end of the discovery 3563 * process. 3564 */ 3565 if (local->dtype == NOTHING) { 3566 bzero(ctmp->sas_address, 3567 sizeof (local->sas_address)); 3568 ctmp->atdt = 0; 3569 ctmp->link_rate = 0; 3570 ctmp->pend_dtype = NOTHING; 3571 ctmp->configured = 0; 3572 } else { 3573 (void) memcpy(ctmp->sas_address, 3574 local->sas_address, 3575 sizeof (local->sas_address)); 3576 ctmp->atdt = local->atdt; 3577 ctmp->link_rate = local->link_rate; 3578 ctmp->pend_dtype = local->dtype; 3579 } 3580 } 3581 3582 local = local->sibling; 3583 ctmp = ctmp->sibling; 3584 } 3585 3586 /* 3587 * If we got to here, that means we were able to see all the PHYs 3588 * and we can now update all of the real PHYs with the information 3589 * we got on the local PHYs. Once that's done, free all the local 3590 * PHYs. 3591 */ 3592 3593 pmcs_free_phys(pwp, local_list); 3594 } 3595 3596 /* 3597 * Top level routine to check expanders. We call pmcs_check_expander for 3598 * each expander. Since we're not doing any configuration right now, it 3599 * doesn't matter if this is breadth-first. 3600 */ 3601 static boolean_t 3602 pmcs_check_expanders(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 3603 { 3604 pmcs_phy_t *phyp, *pnext, *pchild; 3605 boolean_t config_changed = B_FALSE; 3606 3607 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3608 "%s: %s", __func__, pptr->path); 3609 3610 /* 3611 * Check each expander at this level 3612 */ 3613 phyp = pptr; 3614 while (phyp && !config_changed) { 3615 pmcs_lock_phy(phyp); 3616 3617 if ((phyp->dtype == EXPANDER) && phyp->changed && 3618 !phyp->dead && !phyp->subsidiary && 3619 phyp->configured) { 3620 pmcs_check_expander(pwp, phyp); 3621 } 3622 3623 pnext = phyp->sibling; 3624 pmcs_unlock_phy(phyp); 3625 3626 mutex_enter(&pwp->config_lock); 3627 config_changed = pwp->config_changed; 3628 mutex_exit(&pwp->config_lock); 3629 3630 phyp = pnext; 3631 } 3632 3633 if (config_changed) { 3634 return (config_changed); 3635 } 3636 3637 /* 3638 * Now check the children 3639 */ 3640 phyp = pptr; 3641 while (phyp && !config_changed) { 3642 pmcs_lock_phy(phyp); 3643 pnext = phyp->sibling; 3644 pchild = phyp->children; 3645 pmcs_unlock_phy(phyp); 3646 3647 if (pchild) { 3648 (void) pmcs_check_expanders(pwp, pchild); 3649 } 3650 3651 mutex_enter(&pwp->config_lock); 3652 config_changed = pwp->config_changed; 3653 mutex_exit(&pwp->config_lock); 3654 3655 phyp = pnext; 3656 } 3657 3658 /* 3659 * We're done 3660 */ 3661 return (config_changed); 3662 } 3663 3664 /* 3665 * Called with softstate and PHY locked 3666 */ 3667 static void 3668 pmcs_clear_expander(pmcs_hw_t *pwp, pmcs_phy_t *pptr, int level) 3669 { 3670 pmcs_phy_t *ctmp; 3671 3672 ASSERT(mutex_owned(&pwp->lock)); 3673 ASSERT(mutex_owned(&pptr->phy_lock)); 3674 ASSERT(pptr->level < PMCS_MAX_XPND - 1); 3675 3676 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3677 "%s: checking %s", __func__, pptr->path); 3678 3679 ctmp = pptr->children; 3680 while (ctmp) { 3681 /* 3682 * If the expander is dead, mark its children dead 3683 */ 3684 if (pptr->dead) { 3685 ctmp->dead = 1; 3686 } 3687 if (ctmp->dtype == EXPANDER) { 3688 pmcs_clear_expander(pwp, ctmp, level + 1); 3689 } 3690 ctmp = ctmp->sibling; 3691 } 3692 3693 /* 3694 * If this expander is not dead, we're done here. 3695 */ 3696 if (!pptr->dead) { 3697 return; 3698 } 3699 3700 /* 3701 * Now snip out the list of children below us and release them 3702 */ 3703 ctmp = pptr->children; 3704 while (ctmp) { 3705 pmcs_phy_t *nxt = ctmp->sibling; 3706 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 3707 "%s: dead PHY 0x%p (%s) (ref_count %d)", __func__, 3708 (void *)ctmp, ctmp->path, ctmp->ref_count); 3709 /* 3710 * Put this PHY on the dead PHY list for the watchdog to 3711 * clean up after any outstanding work has completed. 3712 */ 3713 mutex_enter(&pwp->dead_phylist_lock); 3714 ctmp->dead_next = pwp->dead_phys; 3715 pwp->dead_phys = ctmp; 3716 mutex_exit(&pwp->dead_phylist_lock); 3717 pmcs_unlock_phy(ctmp); 3718 ctmp = nxt; 3719 } 3720 3721 pptr->children = NULL; 3722 3723 /* 3724 * Clear subsidiary phys as well. Getting the parent's PHY lock 3725 * is only necessary if level == 0 since otherwise the parent is 3726 * already locked. 3727 */ 3728 if (!IS_ROOT_PHY(pptr)) { 3729 if (level == 0) { 3730 mutex_enter(&pptr->parent->phy_lock); 3731 } 3732 ctmp = pptr->parent->children; 3733 if (level == 0) { 3734 mutex_exit(&pptr->parent->phy_lock); 3735 } 3736 } else { 3737 ctmp = pwp->root_phys; 3738 } 3739 3740 while (ctmp) { 3741 if (ctmp == pptr) { 3742 ctmp = ctmp->sibling; 3743 continue; 3744 } 3745 /* 3746 * We only need to lock subsidiary PHYs on the level 0 3747 * expander. Any children of that expander, subsidiaries or 3748 * not, will already be locked. 3749 */ 3750 if (level == 0) { 3751 pmcs_lock_phy(ctmp); 3752 } 3753 if (ctmp->dtype != EXPANDER || ctmp->subsidiary == 0 || 3754 memcmp(ctmp->sas_address, pptr->sas_address, 3755 sizeof (ctmp->sas_address)) != 0) { 3756 if (level == 0) { 3757 pmcs_unlock_phy(ctmp); 3758 } 3759 ctmp = ctmp->sibling; 3760 continue; 3761 } 3762 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 3763 "%s: subsidiary %s", __func__, ctmp->path); 3764 pmcs_clear_phy(pwp, ctmp); 3765 if (level == 0) { 3766 pmcs_unlock_phy(ctmp); 3767 } 3768 ctmp = ctmp->sibling; 3769 } 3770 3771 pmcs_clear_phy(pwp, pptr); 3772 } 3773 3774 /* 3775 * Called with PHY locked and with scratch acquired. We return 0 if 3776 * we fail to allocate resources or notice that the configuration 3777 * count changed while we were running the command. We return 3778 * less than zero if we had an I/O error or received an unsupported 3779 * configuration. Otherwise we return the number of phys in the 3780 * expander. 3781 */ 3782 #define DFM(m, y) if (m == NULL) m = y 3783 static int 3784 pmcs_expander_get_nphy(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 3785 { 3786 struct pmcwork *pwrk; 3787 char buf[64]; 3788 const uint_t rdoff = 0x100; /* returned data offset */ 3789 smp_response_frame_t *srf; 3790 smp_report_general_resp_t *srgr; 3791 uint32_t msg[PMCS_MSG_SIZE], *ptr, htag, status, ival; 3792 int result; 3793 3794 ival = 0x40001100; 3795 again: 3796 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr); 3797 if (pwrk == NULL) { 3798 result = 0; 3799 goto out; 3800 } 3801 (void) memset(pwp->scratch, 0x77, PMCS_SCRATCH_SIZE); 3802 pwrk->arg = pwp->scratch; 3803 pwrk->dtype = pptr->dtype; 3804 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 3805 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 3806 if (ptr == NULL) { 3807 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 3808 pmcs_prt(pwp, PMCS_PRT_DEBUG2, pptr, NULL, 3809 "%s: GET_IQ_ENTRY failed", __func__); 3810 pmcs_pwork(pwp, pwrk); 3811 result = 0; 3812 goto out; 3813 } 3814 3815 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, PMCIN_SMP_REQUEST)); 3816 msg[1] = LE_32(pwrk->htag); 3817 msg[2] = LE_32(pptr->device_id); 3818 msg[3] = LE_32((4 << SMP_REQUEST_LENGTH_SHIFT) | SMP_INDIRECT_RESPONSE); 3819 /* 3820 * Send SMP REPORT GENERAL (of either SAS1.1 or SAS2 flavors). 3821 */ 3822 msg[4] = BE_32(ival); 3823 msg[5] = 0; 3824 msg[6] = 0; 3825 msg[7] = 0; 3826 msg[8] = 0; 3827 msg[9] = 0; 3828 msg[10] = 0; 3829 msg[11] = 0; 3830 msg[12] = LE_32(DWORD0(pwp->scratch_dma+rdoff)); 3831 msg[13] = LE_32(DWORD1(pwp->scratch_dma+rdoff)); 3832 msg[14] = LE_32(PMCS_SCRATCH_SIZE - rdoff); 3833 msg[15] = 0; 3834 3835 COPY_MESSAGE(ptr, msg, PMCS_MSG_SIZE); 3836 pwrk->state = PMCS_WORK_STATE_ONCHIP; 3837 htag = pwrk->htag; 3838 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 3839 3840 pmcs_unlock_phy(pptr); 3841 WAIT_FOR(pwrk, 1000, result); 3842 pmcs_lock_phy(pptr); 3843 pmcs_pwork(pwp, pwrk); 3844 3845 mutex_enter(&pwp->config_lock); 3846 if (pwp->config_changed) { 3847 RESTART_DISCOVERY_LOCKED(pwp); 3848 mutex_exit(&pwp->config_lock); 3849 result = 0; 3850 goto out; 3851 } 3852 mutex_exit(&pwp->config_lock); 3853 3854 if (result) { 3855 pmcs_timed_out(pwp, htag, __func__); 3856 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3857 "%s: Issuing SMP ABORT for htag 0x%08x", __func__, htag); 3858 if (pmcs_abort(pwp, pptr, htag, 0, 0)) { 3859 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3860 "%s: Unable to issue SMP ABORT for htag 0x%08x", 3861 __func__, htag); 3862 } else { 3863 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3864 "%s: Issuing SMP ABORT for htag 0x%08x", 3865 __func__, htag); 3866 } 3867 result = 0; 3868 goto out; 3869 } 3870 ptr = (void *)pwp->scratch; 3871 status = LE_32(ptr[2]); 3872 if (status == PMCOUT_STATUS_UNDERFLOW || 3873 status == PMCOUT_STATUS_OVERFLOW) { 3874 pmcs_prt(pwp, PMCS_PRT_DEBUG_UNDERFLOW, pptr, NULL, 3875 "%s: over/underflow", __func__); 3876 status = PMCOUT_STATUS_OK; 3877 } 3878 srf = (smp_response_frame_t *)&((uint32_t *)pwp->scratch)[rdoff >> 2]; 3879 srgr = (smp_report_general_resp_t *) 3880 &((uint32_t *)pwp->scratch)[(rdoff >> 2)+1]; 3881 3882 if (status != PMCOUT_STATUS_OK) { 3883 char *nag = NULL; 3884 (void) snprintf(buf, sizeof (buf), 3885 "%s: SMP op failed (0x%x)", __func__, status); 3886 switch (status) { 3887 case PMCOUT_STATUS_IO_PORT_IN_RESET: 3888 DFM(nag, "I/O Port In Reset"); 3889 /* FALLTHROUGH */ 3890 case PMCOUT_STATUS_ERROR_HW_TIMEOUT: 3891 DFM(nag, "Hardware Timeout"); 3892 /* FALLTHROUGH */ 3893 case PMCOUT_STATUS_ERROR_INTERNAL_SMP_RESOURCE: 3894 DFM(nag, "Internal SMP Resource Failure"); 3895 /* FALLTHROUGH */ 3896 case PMCOUT_STATUS_XFER_ERR_PHY_NOT_READY: 3897 DFM(nag, "PHY Not Ready"); 3898 /* FALLTHROUGH */ 3899 case PMCOUT_STATUS_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: 3900 DFM(nag, "Connection Rate Not Supported"); 3901 /* FALLTHROUGH */ 3902 case PMCOUT_STATUS_IO_XFER_OPEN_RETRY_TIMEOUT: 3903 DFM(nag, "Open Retry Timeout"); 3904 /* FALLTHROUGH */ 3905 case PMCOUT_STATUS_SMP_RESP_CONNECTION_ERROR: 3906 DFM(nag, "Response Connection Error"); 3907 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 3908 "%s: expander %s SMP operation failed (%s)", 3909 __func__, pptr->path, nag); 3910 break; 3911 3912 /* 3913 * For the IO_DS_NON_OPERATIONAL case, we need to kick off 3914 * device state recovery and return 0 so that the caller 3915 * doesn't assume this expander is dead for good. 3916 */ 3917 case PMCOUT_STATUS_IO_DS_NON_OPERATIONAL: { 3918 pmcs_xscsi_t *xp = pptr->target; 3919 3920 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, xp, 3921 "%s: expander %s device state non-operational", 3922 __func__, pptr->path); 3923 3924 if (xp == NULL) { 3925 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, 3926 xp, "%s: No target to do DS recovery for " 3927 "PHY %p (%s), attempting PHY hard reset", 3928 __func__, (void *)pptr, pptr->path); 3929 (void) pmcs_reset_phy(pwp, pptr, 3930 PMCS_PHYOP_HARD_RESET); 3931 break; 3932 } 3933 3934 mutex_enter(&xp->statlock); 3935 pmcs_start_dev_state_recovery(xp, pptr); 3936 mutex_exit(&xp->statlock); 3937 break; 3938 } 3939 3940 default: 3941 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, buf, ptr); 3942 result = -EIO; 3943 break; 3944 } 3945 } else if (srf->srf_frame_type != SMP_FRAME_TYPE_RESPONSE) { 3946 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 3947 "%s: bad response frame type 0x%x", 3948 __func__, srf->srf_frame_type); 3949 result = -EINVAL; 3950 } else if (srf->srf_function != SMP_FUNC_REPORT_GENERAL) { 3951 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 3952 "%s: bad response function 0x%x", 3953 __func__, srf->srf_function); 3954 result = -EINVAL; 3955 } else if (srf->srf_result != 0) { 3956 /* 3957 * Check to see if we have a value of 3 for failure and 3958 * whether we were using a SAS2.0 allocation length value 3959 * and retry without it. 3960 */ 3961 if (srf->srf_result == 3 && (ival & 0xff00)) { 3962 ival &= ~0xff00; 3963 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 3964 "%s: err 0x%x with SAS2 request- retry with SAS1", 3965 __func__, srf->srf_result); 3966 goto again; 3967 } 3968 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 3969 "%s: bad response 0x%x", __func__, srf->srf_result); 3970 result = -EINVAL; 3971 } else if (srgr->srgr_configuring) { 3972 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 3973 "%s: expander at phy %s is still configuring", 3974 __func__, pptr->path); 3975 result = 0; 3976 } else { 3977 result = srgr->srgr_number_of_phys; 3978 if (ival & 0xff00) { 3979 pptr->tolerates_sas2 = 1; 3980 } 3981 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 3982 "%s has %d phys and %s SAS2", pptr->path, result, 3983 pptr->tolerates_sas2? "tolerates" : "does not tolerate"); 3984 } 3985 out: 3986 return (result); 3987 } 3988 3989 /* 3990 * Called with expander locked (and thus, pptr) as well as all PHYs up to 3991 * the root, and scratch acquired. Return 0 if we fail to allocate resources 3992 * or notice that the configuration changed while we were running the command. 3993 * 3994 * We return less than zero if we had an I/O error or received an 3995 * unsupported configuration. 3996 */ 3997 static int 3998 pmcs_expander_content_discover(pmcs_hw_t *pwp, pmcs_phy_t *expander, 3999 pmcs_phy_t *pptr) 4000 { 4001 struct pmcwork *pwrk; 4002 char buf[64]; 4003 uint8_t sas_address[8]; 4004 uint8_t att_sas_address[8]; 4005 smp_response_frame_t *srf; 4006 smp_discover_resp_t *sdr; 4007 const uint_t rdoff = 0x100; /* returned data offset */ 4008 uint8_t *roff; 4009 uint32_t status, *ptr, msg[PMCS_MSG_SIZE], htag; 4010 int result; 4011 uint8_t ini_support; 4012 uint8_t tgt_support; 4013 4014 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, expander); 4015 if (pwrk == NULL) { 4016 result = 0; 4017 goto out; 4018 } 4019 (void) memset(pwp->scratch, 0x77, PMCS_SCRATCH_SIZE); 4020 pwrk->arg = pwp->scratch; 4021 pwrk->dtype = expander->dtype; 4022 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, PMCIN_SMP_REQUEST)); 4023 msg[1] = LE_32(pwrk->htag); 4024 msg[2] = LE_32(expander->device_id); 4025 msg[3] = LE_32((12 << SMP_REQUEST_LENGTH_SHIFT) | 4026 SMP_INDIRECT_RESPONSE); 4027 /* 4028 * Send SMP DISCOVER (of either SAS1.1 or SAS2 flavors). 4029 */ 4030 if (expander->tolerates_sas2) { 4031 msg[4] = BE_32(0x40101B00); 4032 } else { 4033 msg[4] = BE_32(0x40100000); 4034 } 4035 msg[5] = 0; 4036 msg[6] = BE_32((pptr->phynum << 16)); 4037 msg[7] = 0; 4038 msg[8] = 0; 4039 msg[9] = 0; 4040 msg[10] = 0; 4041 msg[11] = 0; 4042 msg[12] = LE_32(DWORD0(pwp->scratch_dma+rdoff)); 4043 msg[13] = LE_32(DWORD1(pwp->scratch_dma+rdoff)); 4044 msg[14] = LE_32(PMCS_SCRATCH_SIZE - rdoff); 4045 msg[15] = 0; 4046 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4047 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4048 if (ptr == NULL) { 4049 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4050 result = 0; 4051 goto out; 4052 } 4053 4054 COPY_MESSAGE(ptr, msg, PMCS_MSG_SIZE); 4055 pwrk->state = PMCS_WORK_STATE_ONCHIP; 4056 htag = pwrk->htag; 4057 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4058 4059 /* 4060 * Drop PHY lock while waiting so other completions aren't potentially 4061 * blocked. 4062 */ 4063 pmcs_unlock_phy(expander); 4064 WAIT_FOR(pwrk, 1000, result); 4065 pmcs_lock_phy(expander); 4066 pmcs_pwork(pwp, pwrk); 4067 4068 mutex_enter(&pwp->config_lock); 4069 if (pwp->config_changed) { 4070 RESTART_DISCOVERY_LOCKED(pwp); 4071 mutex_exit(&pwp->config_lock); 4072 result = 0; 4073 goto out; 4074 } 4075 mutex_exit(&pwp->config_lock); 4076 4077 if (result) { 4078 pmcs_prt(pwp, PMCS_PRT_WARN, pptr, NULL, pmcs_timeo, __func__); 4079 if (pmcs_abort(pwp, expander, htag, 0, 0)) { 4080 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4081 "%s: Unable to issue SMP ABORT for htag 0x%08x", 4082 __func__, htag); 4083 } else { 4084 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4085 "%s: Issuing SMP ABORT for htag 0x%08x", 4086 __func__, htag); 4087 } 4088 result = -ETIMEDOUT; 4089 goto out; 4090 } 4091 ptr = (void *)pwp->scratch; 4092 /* 4093 * Point roff to the DMA offset for returned data 4094 */ 4095 roff = pwp->scratch; 4096 roff += rdoff; 4097 srf = (smp_response_frame_t *)roff; 4098 sdr = (smp_discover_resp_t *)(roff+4); 4099 status = LE_32(ptr[2]); 4100 if (status == PMCOUT_STATUS_UNDERFLOW || 4101 status == PMCOUT_STATUS_OVERFLOW) { 4102 pmcs_prt(pwp, PMCS_PRT_DEBUG_UNDERFLOW, pptr, NULL, 4103 "%s: over/underflow", __func__); 4104 status = PMCOUT_STATUS_OK; 4105 } 4106 if (status != PMCOUT_STATUS_OK) { 4107 char *nag = NULL; 4108 (void) snprintf(buf, sizeof (buf), 4109 "%s: SMP op failed (0x%x)", __func__, status); 4110 switch (status) { 4111 case PMCOUT_STATUS_ERROR_HW_TIMEOUT: 4112 DFM(nag, "Hardware Timeout"); 4113 /* FALLTHROUGH */ 4114 case PMCOUT_STATUS_ERROR_INTERNAL_SMP_RESOURCE: 4115 DFM(nag, "Internal SMP Resource Failure"); 4116 /* FALLTHROUGH */ 4117 case PMCOUT_STATUS_XFER_ERR_PHY_NOT_READY: 4118 DFM(nag, "PHY Not Ready"); 4119 /* FALLTHROUGH */ 4120 case PMCOUT_STATUS_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: 4121 DFM(nag, "Connection Rate Not Supported"); 4122 /* FALLTHROUGH */ 4123 case PMCOUT_STATUS_IO_XFER_OPEN_RETRY_TIMEOUT: 4124 DFM(nag, "Open Retry Timeout"); 4125 /* FALLTHROUGH */ 4126 case PMCOUT_STATUS_SMP_RESP_CONNECTION_ERROR: 4127 DFM(nag, "Response Connection Error"); 4128 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4129 "%s: expander %s SMP operation failed (%s)", 4130 __func__, pptr->path, nag); 4131 break; 4132 default: 4133 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, buf, ptr); 4134 result = -EIO; 4135 break; 4136 } 4137 goto out; 4138 } else if (srf->srf_frame_type != SMP_FRAME_TYPE_RESPONSE) { 4139 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4140 "%s: bad response frame type 0x%x", 4141 __func__, srf->srf_frame_type); 4142 result = -EINVAL; 4143 goto out; 4144 } else if (srf->srf_function != SMP_FUNC_DISCOVER) { 4145 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4146 "%s: bad response function 0x%x", 4147 __func__, srf->srf_function); 4148 result = -EINVAL; 4149 goto out; 4150 } else if (srf->srf_result != SMP_RES_FUNCTION_ACCEPTED) { 4151 result = pmcs_smp_function_result(pwp, srf); 4152 /* Need not fail if PHY is Vacant */ 4153 if (result != SMP_RES_PHY_VACANT) { 4154 result = -EINVAL; 4155 goto out; 4156 } 4157 } 4158 4159 ini_support = (sdr->sdr_attached_sata_host | 4160 (sdr->sdr_attached_smp_initiator << 1) | 4161 (sdr->sdr_attached_stp_initiator << 2) | 4162 (sdr->sdr_attached_ssp_initiator << 3)); 4163 4164 tgt_support = (sdr->sdr_attached_sata_device | 4165 (sdr->sdr_attached_smp_target << 1) | 4166 (sdr->sdr_attached_stp_target << 2) | 4167 (sdr->sdr_attached_ssp_target << 3)); 4168 4169 pmcs_wwn2barray(BE_64(sdr->sdr_sas_addr), sas_address); 4170 pmcs_wwn2barray(BE_64(sdr->sdr_attached_sas_addr), att_sas_address); 4171 4172 switch (sdr->sdr_attached_device_type) { 4173 case SAS_IF_DTYPE_ENDPOINT: 4174 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4175 "exp_content: %s atdt=0x%x lr=%x is=%x ts=%x SAS=" 4176 SAS_ADDR_FMT " attSAS=" SAS_ADDR_FMT " atPHY=%x", 4177 pptr->path, 4178 sdr->sdr_attached_device_type, 4179 sdr->sdr_negotiated_logical_link_rate, 4180 ini_support, 4181 tgt_support, 4182 SAS_ADDR_PRT(sas_address), 4183 SAS_ADDR_PRT(att_sas_address), 4184 sdr->sdr_attached_phy_identifier); 4185 4186 if (sdr->sdr_attached_sata_device || 4187 sdr->sdr_attached_stp_target) { 4188 pptr->dtype = SATA; 4189 } else if (sdr->sdr_attached_ssp_target) { 4190 pptr->dtype = SAS; 4191 } else if (tgt_support || ini_support) { 4192 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4193 "%s: %s has tgt support=%x init support=(%x)", 4194 __func__, pptr->path, tgt_support, ini_support); 4195 } 4196 break; 4197 case SAS_IF_DTYPE_EDGE: 4198 case SAS_IF_DTYPE_FANOUT: 4199 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4200 "exp_content: %s atdt=0x%x lr=%x is=%x ts=%x SAS=" 4201 SAS_ADDR_FMT " attSAS=" SAS_ADDR_FMT " atPHY=%x", 4202 pptr->path, 4203 sdr->sdr_attached_device_type, 4204 sdr->sdr_negotiated_logical_link_rate, 4205 ini_support, 4206 tgt_support, 4207 SAS_ADDR_PRT(sas_address), 4208 SAS_ADDR_PRT(att_sas_address), 4209 sdr->sdr_attached_phy_identifier); 4210 if (sdr->sdr_attached_smp_target) { 4211 /* 4212 * Avoid configuring phys that just point back 4213 * at a parent phy 4214 */ 4215 if (expander->parent && 4216 memcmp(expander->parent->sas_address, 4217 att_sas_address, 4218 sizeof (expander->parent->sas_address)) == 0) { 4219 pmcs_prt(pwp, PMCS_PRT_DEBUG3, pptr, NULL, 4220 "%s: skipping port back to parent " 4221 "expander (%s)", __func__, pptr->path); 4222 pptr->dtype = NOTHING; 4223 break; 4224 } 4225 pptr->dtype = EXPANDER; 4226 4227 } else if (tgt_support || ini_support) { 4228 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4229 "%s has tgt support=%x init support=(%x)", 4230 pptr->path, tgt_support, ini_support); 4231 pptr->dtype = EXPANDER; 4232 } 4233 break; 4234 default: 4235 pptr->dtype = NOTHING; 4236 break; 4237 } 4238 if (pptr->dtype != NOTHING) { 4239 pmcs_phy_t *ctmp; 4240 4241 /* 4242 * If the attached device is a SATA device and the expander 4243 * is (possibly) a SAS2 compliant expander, check for whether 4244 * there is a NAA=5 WWN field starting at this offset and 4245 * use that for the SAS Address for this device. 4246 */ 4247 if (expander->tolerates_sas2 && pptr->dtype == SATA && 4248 (roff[SAS_ATTACHED_NAME_OFFSET] >> 8) == 0x5) { 4249 (void) memcpy(pptr->sas_address, 4250 &roff[SAS_ATTACHED_NAME_OFFSET], 8); 4251 } else { 4252 (void) memcpy(pptr->sas_address, att_sas_address, 8); 4253 } 4254 pptr->atdt = (sdr->sdr_attached_device_type); 4255 /* 4256 * Now run up from the expander's parent up to the top to 4257 * make sure we only use the least common link_rate. 4258 */ 4259 for (ctmp = expander->parent; ctmp; ctmp = ctmp->parent) { 4260 if (ctmp->link_rate < 4261 sdr->sdr_negotiated_logical_link_rate) { 4262 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, NULL, 4263 "%s: derating link rate from %x to %x due " 4264 "to %s being slower", pptr->path, 4265 sdr->sdr_negotiated_logical_link_rate, 4266 ctmp->link_rate, 4267 ctmp->path); 4268 sdr->sdr_negotiated_logical_link_rate = 4269 ctmp->link_rate; 4270 } 4271 } 4272 pptr->link_rate = sdr->sdr_negotiated_logical_link_rate; 4273 pptr->state.prog_min_rate = sdr->sdr_prog_min_phys_link_rate; 4274 pptr->state.hw_min_rate = sdr->sdr_hw_min_phys_link_rate; 4275 pptr->state.prog_max_rate = sdr->sdr_prog_max_phys_link_rate; 4276 pptr->state.hw_max_rate = sdr->sdr_hw_max_phys_link_rate; 4277 PHY_CHANGED(pwp, pptr); 4278 } else { 4279 pmcs_clear_phy(pwp, pptr); 4280 } 4281 result = 1; 4282 out: 4283 return (result); 4284 } 4285 4286 /* 4287 * Get a work structure and assign it a tag with type and serial number 4288 * If a structure is returned, it is returned locked. 4289 */ 4290 pmcwork_t * 4291 pmcs_gwork(pmcs_hw_t *pwp, uint32_t tag_type, pmcs_phy_t *phyp) 4292 { 4293 pmcwork_t *p; 4294 uint16_t snum; 4295 uint32_t off; 4296 4297 mutex_enter(&pwp->wfree_lock); 4298 p = STAILQ_FIRST(&pwp->wf); 4299 if (p == NULL) { 4300 /* 4301 * If we couldn't get a work structure, it's time to bite 4302 * the bullet, grab the pfree_lock and copy over all the 4303 * work structures from the pending free list to the actual 4304 * free list. This shouldn't happen all that often. 4305 */ 4306 mutex_enter(&pwp->pfree_lock); 4307 pwp->wf.stqh_first = pwp->pf.stqh_first; 4308 pwp->wf.stqh_last = pwp->pf.stqh_last; 4309 STAILQ_INIT(&pwp->pf); 4310 mutex_exit(&pwp->pfree_lock); 4311 4312 p = STAILQ_FIRST(&pwp->wf); 4313 if (p == NULL) { 4314 mutex_exit(&pwp->wfree_lock); 4315 return (NULL); 4316 } 4317 } 4318 STAILQ_REMOVE(&pwp->wf, p, pmcwork, next); 4319 snum = pwp->wserno++; 4320 mutex_exit(&pwp->wfree_lock); 4321 4322 off = p - pwp->work; 4323 4324 mutex_enter(&p->lock); 4325 ASSERT(p->state == PMCS_WORK_STATE_NIL); 4326 ASSERT(p->htag == PMCS_TAG_FREE); 4327 p->htag = (tag_type << PMCS_TAG_TYPE_SHIFT) & PMCS_TAG_TYPE_MASK; 4328 p->htag |= ((snum << PMCS_TAG_SERNO_SHIFT) & PMCS_TAG_SERNO_MASK); 4329 p->htag |= ((off << PMCS_TAG_INDEX_SHIFT) & PMCS_TAG_INDEX_MASK); 4330 p->start = gethrtime(); 4331 p->state = PMCS_WORK_STATE_READY; 4332 p->ssp_event = 0; 4333 p->dead = 0; 4334 4335 if (phyp) { 4336 p->phy = phyp; 4337 pmcs_inc_phy_ref_count(phyp); 4338 } 4339 4340 return (p); 4341 } 4342 4343 /* 4344 * Called with pwrk lock held. Returned with lock released. 4345 */ 4346 void 4347 pmcs_pwork(pmcs_hw_t *pwp, pmcwork_t *p) 4348 { 4349 ASSERT(p != NULL); 4350 ASSERT(mutex_owned(&p->lock)); 4351 4352 p->last_ptr = p->ptr; 4353 p->last_arg = p->arg; 4354 p->last_phy = p->phy; 4355 p->last_xp = p->xp; 4356 p->last_htag = p->htag; 4357 p->last_state = p->state; 4358 p->finish = gethrtime(); 4359 4360 if (p->phy) { 4361 pmcs_dec_phy_ref_count(p->phy); 4362 } 4363 4364 p->state = PMCS_WORK_STATE_NIL; 4365 p->htag = PMCS_TAG_FREE; 4366 p->xp = NULL; 4367 p->ptr = NULL; 4368 p->arg = NULL; 4369 p->phy = NULL; 4370 p->abt_htag = 0; 4371 p->timer = 0; 4372 mutex_exit(&p->lock); 4373 4374 if (mutex_tryenter(&pwp->wfree_lock) == 0) { 4375 mutex_enter(&pwp->pfree_lock); 4376 STAILQ_INSERT_TAIL(&pwp->pf, p, next); 4377 mutex_exit(&pwp->pfree_lock); 4378 } else { 4379 STAILQ_INSERT_TAIL(&pwp->wf, p, next); 4380 mutex_exit(&pwp->wfree_lock); 4381 } 4382 } 4383 4384 /* 4385 * Find a work structure based upon a tag and make sure that the tag 4386 * serial number matches the work structure we've found. 4387 * If a structure is found, its lock is held upon return. 4388 */ 4389 pmcwork_t * 4390 pmcs_tag2wp(pmcs_hw_t *pwp, uint32_t htag) 4391 { 4392 pmcwork_t *p; 4393 uint32_t idx = PMCS_TAG_INDEX(htag); 4394 4395 p = &pwp->work[idx]; 4396 4397 mutex_enter(&p->lock); 4398 if (p->htag == htag) { 4399 return (p); 4400 } 4401 mutex_exit(&p->lock); 4402 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, 4403 "INDEX 0x%x HTAG 0x%x got p->htag 0x%x", idx, htag, p->htag); 4404 return (NULL); 4405 } 4406 4407 /* 4408 * Issue an abort for a command or for all commands. 4409 * 4410 * Since this can be called from interrupt context, 4411 * we don't wait for completion if wait is not set. 4412 * 4413 * Called with PHY lock held. 4414 */ 4415 int 4416 pmcs_abort(pmcs_hw_t *pwp, pmcs_phy_t *pptr, uint32_t tag, int all_cmds, 4417 int wait) 4418 { 4419 pmcwork_t *pwrk; 4420 pmcs_xscsi_t *tgt; 4421 uint32_t msg[PMCS_MSG_SIZE], *ptr; 4422 int result, abt_type; 4423 uint32_t abt_htag, status; 4424 4425 if (pptr->abort_all_start) { 4426 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, "%s: ABORT_ALL for " 4427 "(%s) already in progress.", __func__, pptr->path); 4428 return (EBUSY); 4429 } 4430 4431 switch (pptr->dtype) { 4432 case SAS: 4433 abt_type = PMCIN_SSP_ABORT; 4434 break; 4435 case SATA: 4436 abt_type = PMCIN_SATA_ABORT; 4437 break; 4438 case EXPANDER: 4439 abt_type = PMCIN_SMP_ABORT; 4440 break; 4441 default: 4442 return (0); 4443 } 4444 4445 pwrk = pmcs_gwork(pwp, wait ? PMCS_TAG_TYPE_WAIT : PMCS_TAG_TYPE_NONE, 4446 pptr); 4447 4448 if (pwrk == NULL) { 4449 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nowrk, __func__); 4450 return (ENOMEM); 4451 } 4452 4453 pwrk->dtype = pptr->dtype; 4454 if (wait) { 4455 pwrk->arg = msg; 4456 } 4457 if (pptr->valid_device_id == 0) { 4458 pmcs_pwork(pwp, pwrk); 4459 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4460 "%s: Invalid DeviceID", __func__); 4461 return (ENODEV); 4462 } 4463 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, abt_type)); 4464 msg[1] = LE_32(pwrk->htag); 4465 msg[2] = LE_32(pptr->device_id); 4466 if (all_cmds) { 4467 msg[3] = 0; 4468 msg[4] = LE_32(1); 4469 pwrk->ptr = NULL; 4470 pptr->abort_all_start = gethrtime(); 4471 } else { 4472 msg[3] = LE_32(tag); 4473 msg[4] = 0; 4474 pwrk->abt_htag = tag; 4475 } 4476 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4477 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4478 if (ptr == NULL) { 4479 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4480 pmcs_pwork(pwp, pwrk); 4481 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nomsg, __func__); 4482 return (ENOMEM); 4483 } 4484 4485 COPY_MESSAGE(ptr, msg, 5); 4486 if (all_cmds) { 4487 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4488 "%s: aborting all commands for %s device %s. (htag=0x%x)", 4489 __func__, pmcs_get_typename(pptr->dtype), pptr->path, 4490 msg[1]); 4491 } else { 4492 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 4493 "%s: aborting tag 0x%x for %s device %s. (htag=0x%x)", 4494 __func__, tag, pmcs_get_typename(pptr->dtype), pptr->path, 4495 msg[1]); 4496 } 4497 pwrk->state = PMCS_WORK_STATE_ONCHIP; 4498 4499 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4500 if (!wait) { 4501 mutex_exit(&pwrk->lock); 4502 return (0); 4503 } 4504 4505 abt_htag = pwrk->htag; 4506 pmcs_unlock_phy(pwrk->phy); 4507 WAIT_FOR(pwrk, 1000, result); 4508 pmcs_lock_phy(pwrk->phy); 4509 4510 tgt = pwrk->xp; 4511 pmcs_pwork(pwp, pwrk); 4512 4513 if (tgt != NULL) { 4514 mutex_enter(&tgt->aqlock); 4515 if (!STAILQ_EMPTY(&tgt->aq)) { 4516 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4517 "%s: Abort complete (result=0x%x), but " 4518 "aq not empty (tgt 0x%p), waiting", 4519 __func__, result, (void *)tgt); 4520 cv_wait(&tgt->abort_cv, &tgt->aqlock); 4521 } 4522 mutex_exit(&tgt->aqlock); 4523 } 4524 4525 if (all_cmds) { 4526 pptr->abort_all_start = 0; 4527 cv_signal(&pptr->abort_all_cv); 4528 } 4529 4530 if (result) { 4531 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4532 "%s: Abort (htag 0x%08x) request timed out", 4533 __func__, abt_htag); 4534 if (tgt != NULL) { 4535 mutex_enter(&tgt->statlock); 4536 if ((tgt->dev_state != PMCS_DEVICE_STATE_IN_RECOVERY) && 4537 (tgt->dev_state != 4538 PMCS_DEVICE_STATE_NON_OPERATIONAL)) { 4539 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4540 "%s: Trying DS error recovery for tgt 0x%p", 4541 __func__, (void *)tgt); 4542 (void) pmcs_send_err_recovery_cmd(pwp, 4543 PMCS_DEVICE_STATE_IN_RECOVERY, tgt); 4544 } 4545 mutex_exit(&tgt->statlock); 4546 } 4547 return (ETIMEDOUT); 4548 } 4549 4550 status = LE_32(msg[2]); 4551 if (status != PMCOUT_STATUS_OK) { 4552 /* 4553 * The only non-success status are IO_NOT_VALID & 4554 * IO_ABORT_IN_PROGRESS. 4555 * In case of IO_ABORT_IN_PROGRESS, the other ABORT cmd's 4556 * status is of concern and this duplicate cmd status can 4557 * be ignored. 4558 * If IO_NOT_VALID, that's not an error per-se. 4559 * For abort of single I/O complete the command anyway. 4560 * If, however, we were aborting all, that is a problem 4561 * as IO_NOT_VALID really means that the IO or device is 4562 * not there. So, discovery process will take of the cleanup. 4563 */ 4564 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4565 "%s: abort result 0x%x", __func__, LE_32(msg[2])); 4566 if (all_cmds) { 4567 PHY_CHANGED(pwp, pptr); 4568 RESTART_DISCOVERY(pwp); 4569 } else { 4570 return (EINVAL); 4571 } 4572 4573 return (0); 4574 } 4575 4576 if (tgt != NULL) { 4577 mutex_enter(&tgt->statlock); 4578 if (tgt->dev_state == PMCS_DEVICE_STATE_IN_RECOVERY) { 4579 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4580 "%s: Restoring OPERATIONAL dev_state for tgt 0x%p", 4581 __func__, (void *)tgt); 4582 (void) pmcs_send_err_recovery_cmd(pwp, 4583 PMCS_DEVICE_STATE_OPERATIONAL, tgt); 4584 } 4585 mutex_exit(&tgt->statlock); 4586 } 4587 4588 return (0); 4589 } 4590 4591 /* 4592 * Issue a task management function to an SSP device. 4593 * 4594 * Called with PHY lock held. 4595 * statlock CANNOT be held upon entry. 4596 */ 4597 int 4598 pmcs_ssp_tmf(pmcs_hw_t *pwp, pmcs_phy_t *pptr, uint8_t tmf, uint32_t tag, 4599 uint64_t lun, uint32_t *response) 4600 { 4601 int result, ds; 4602 uint8_t local[PMCS_QENTRY_SIZE << 1], *xd; 4603 sas_ssp_rsp_iu_t *rptr = (void *)local; 4604 static const uint8_t ssp_rsp_evec[] = { 4605 0x58, 0x61, 0x56, 0x72, 0x00 4606 }; 4607 uint32_t msg[PMCS_MSG_SIZE], *ptr, status; 4608 struct pmcwork *pwrk; 4609 pmcs_xscsi_t *xp; 4610 4611 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr); 4612 if (pwrk == NULL) { 4613 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nowrk, __func__); 4614 return (ENOMEM); 4615 } 4616 /* 4617 * NB: We use the PMCS_OQ_GENERAL outbound queue 4618 * NB: so as to not get entangled in normal I/O 4619 * NB: processing. 4620 */ 4621 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 4622 PMCIN_SSP_INI_TM_START)); 4623 msg[1] = LE_32(pwrk->htag); 4624 msg[2] = LE_32(pptr->device_id); 4625 if (tmf == SAS_ABORT_TASK || tmf == SAS_QUERY_TASK) { 4626 msg[3] = LE_32(tag); 4627 } else { 4628 msg[3] = 0; 4629 } 4630 msg[4] = LE_32(tmf); 4631 msg[5] = BE_32((uint32_t)lun); 4632 msg[6] = BE_32((uint32_t)(lun >> 32)); 4633 msg[7] = LE_32(PMCIN_MESSAGE_REPORT); 4634 4635 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4636 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4637 if (ptr == NULL) { 4638 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4639 pmcs_pwork(pwp, pwrk); 4640 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nomsg, __func__); 4641 return (ENOMEM); 4642 } 4643 COPY_MESSAGE(ptr, msg, 7); 4644 pwrk->arg = msg; 4645 pwrk->dtype = pptr->dtype; 4646 4647 xp = pptr->target; 4648 if (xp != NULL) { 4649 mutex_enter(&xp->statlock); 4650 if (xp->dev_state == PMCS_DEVICE_STATE_NON_OPERATIONAL) { 4651 mutex_exit(&xp->statlock); 4652 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4653 pmcs_pwork(pwp, pwrk); 4654 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, "%s: Not " 4655 "sending '%s' because DS is '%s'", __func__, 4656 pmcs_tmf2str(tmf), pmcs_status_str 4657 (PMCOUT_STATUS_IO_DS_NON_OPERATIONAL)); 4658 return (EIO); 4659 } 4660 mutex_exit(&xp->statlock); 4661 } 4662 4663 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4664 "%s: sending '%s' to %s (lun %llu) tag 0x%x", __func__, 4665 pmcs_tmf2str(tmf), pptr->path, (unsigned long long) lun, tag); 4666 pwrk->state = PMCS_WORK_STATE_ONCHIP; 4667 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4668 4669 pmcs_unlock_phy(pptr); 4670 /* 4671 * This is a command sent to the target device, so it can take 4672 * significant amount of time to complete when path & device is busy. 4673 * Set a timeout to 20 seconds 4674 */ 4675 WAIT_FOR(pwrk, 20000, result); 4676 pmcs_lock_phy(pptr); 4677 pmcs_pwork(pwp, pwrk); 4678 4679 if (result) { 4680 if (xp == NULL) { 4681 return (ETIMEDOUT); 4682 } 4683 4684 mutex_enter(&xp->statlock); 4685 pmcs_start_dev_state_recovery(xp, pptr); 4686 mutex_exit(&xp->statlock); 4687 return (ETIMEDOUT); 4688 } 4689 4690 status = LE_32(msg[2]); 4691 if (status != PMCOUT_STATUS_OK) { 4692 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4693 "%s: status %s for TMF %s action to %s, lun %llu", 4694 __func__, pmcs_status_str(status), pmcs_tmf2str(tmf), 4695 pptr->path, (unsigned long long) lun); 4696 if ((status == PMCOUT_STATUS_IO_DS_NON_OPERATIONAL) || 4697 (status == PMCOUT_STATUS_OPEN_CNX_ERROR_BREAK) || 4698 (status == PMCOUT_STATUS_OPEN_CNX_ERROR_IT_NEXUS_LOSS)) { 4699 ds = PMCS_DEVICE_STATE_NON_OPERATIONAL; 4700 } else if (status == PMCOUT_STATUS_IO_DS_IN_RECOVERY) { 4701 /* 4702 * If the status is IN_RECOVERY, it's an indication 4703 * that it's now time for us to request to have the 4704 * device state set to OPERATIONAL since we're the ones 4705 * that requested recovery to begin with. 4706 */ 4707 ds = PMCS_DEVICE_STATE_OPERATIONAL; 4708 } else { 4709 ds = PMCS_DEVICE_STATE_IN_RECOVERY; 4710 } 4711 if (xp != NULL) { 4712 mutex_enter(&xp->statlock); 4713 if (xp->dev_state != ds) { 4714 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4715 "%s: Sending err recovery cmd" 4716 " for tgt 0x%p (status = %s)", 4717 __func__, (void *)xp, 4718 pmcs_status_str(status)); 4719 (void) pmcs_send_err_recovery_cmd(pwp, ds, xp); 4720 } 4721 mutex_exit(&xp->statlock); 4722 } 4723 return (EIO); 4724 } else { 4725 ds = PMCS_DEVICE_STATE_OPERATIONAL; 4726 if (xp != NULL) { 4727 mutex_enter(&xp->statlock); 4728 if (xp->dev_state != ds) { 4729 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4730 "%s: Sending err recovery cmd" 4731 " for tgt 0x%p (status = %s)", 4732 __func__, (void *)xp, 4733 pmcs_status_str(status)); 4734 (void) pmcs_send_err_recovery_cmd(pwp, ds, xp); 4735 } 4736 mutex_exit(&xp->statlock); 4737 } 4738 } 4739 if (LE_32(msg[3]) == 0) { 4740 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4741 "TMF completed with no response"); 4742 return (EIO); 4743 } 4744 pmcs_endian_transform(pwp, local, &msg[5], ssp_rsp_evec); 4745 xd = (uint8_t *)(&msg[5]); 4746 xd += SAS_RSP_HDR_SIZE; 4747 if (rptr->datapres != SAS_RSP_DATAPRES_RESPONSE_DATA) { 4748 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4749 "%s: TMF response not RESPONSE DATA (0x%x)", 4750 __func__, rptr->datapres); 4751 return (EIO); 4752 } 4753 if (rptr->response_data_length != 4) { 4754 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, 4755 "Bad SAS RESPONSE DATA LENGTH", msg); 4756 return (EIO); 4757 } 4758 (void) memcpy(&status, xd, sizeof (uint32_t)); 4759 status = BE_32(status); 4760 if (response != NULL) 4761 *response = status; 4762 /* 4763 * The status is actually in the low-order byte. The upper three 4764 * bytes contain additional information for the TMFs that support them. 4765 * However, at this time we do not issue any of those. In the other 4766 * cases, the upper three bytes are supposed to be 0, but it appears 4767 * they aren't always. Just mask them off. 4768 */ 4769 switch (status & 0xff) { 4770 case SAS_RSP_TMF_COMPLETE: 4771 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4772 "%s: TMF complete", __func__); 4773 result = 0; 4774 break; 4775 case SAS_RSP_TMF_SUCCEEDED: 4776 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4777 "%s: TMF succeeded", __func__); 4778 result = 0; 4779 break; 4780 case SAS_RSP_INVALID_FRAME: 4781 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4782 "%s: TMF returned INVALID FRAME", __func__); 4783 result = EIO; 4784 break; 4785 case SAS_RSP_TMF_NOT_SUPPORTED: 4786 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4787 "%s: TMF returned TMF NOT SUPPORTED", __func__); 4788 result = EIO; 4789 break; 4790 case SAS_RSP_TMF_FAILED: 4791 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4792 "%s: TMF returned TMF FAILED", __func__); 4793 result = EIO; 4794 break; 4795 case SAS_RSP_TMF_INCORRECT_LUN: 4796 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4797 "%s: TMF returned INCORRECT LUN", __func__); 4798 result = EIO; 4799 break; 4800 case SAS_RSP_OVERLAPPED_OIPTTA: 4801 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4802 "%s: TMF returned OVERLAPPED INITIATOR PORT TRANSFER TAG " 4803 "ATTEMPTED", __func__); 4804 result = EIO; 4805 break; 4806 default: 4807 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, 4808 "%s: TMF returned unknown code 0x%x", __func__, status); 4809 result = EIO; 4810 break; 4811 } 4812 return (result); 4813 } 4814 4815 /* 4816 * Called with PHY lock held and scratch acquired 4817 */ 4818 int 4819 pmcs_sata_abort_ncq(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 4820 { 4821 const char *utag_fail_fmt = "%s: untagged NCQ command failure"; 4822 const char *tag_fail_fmt = "%s: NCQ command failure (tag 0x%x)"; 4823 uint32_t msg[PMCS_QENTRY_SIZE], *ptr, result, status; 4824 uint8_t *fp = pwp->scratch, ds; 4825 fis_t fis; 4826 pmcwork_t *pwrk; 4827 pmcs_xscsi_t *tgt; 4828 4829 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr); 4830 if (pwrk == NULL) { 4831 return (ENOMEM); 4832 } 4833 msg[0] = LE_32(PMCS_IOMB_IN_SAS(PMCS_OQ_IODONE, 4834 PMCIN_SATA_HOST_IO_START)); 4835 msg[1] = LE_32(pwrk->htag); 4836 msg[2] = LE_32(pptr->device_id); 4837 msg[3] = LE_32(512); 4838 msg[4] = LE_32(SATA_PROTOCOL_PIO | PMCIN_DATADIR_2_INI); 4839 msg[5] = LE_32((READ_LOG_EXT << 16) | (C_BIT << 8) | FIS_REG_H2DEV); 4840 msg[6] = LE_32(0x10); 4841 msg[8] = LE_32(1); 4842 msg[9] = 0; 4843 msg[10] = 0; 4844 msg[11] = 0; 4845 msg[12] = LE_32(DWORD0(pwp->scratch_dma)); 4846 msg[13] = LE_32(DWORD1(pwp->scratch_dma)); 4847 msg[14] = LE_32(512); 4848 msg[15] = 0; 4849 4850 pwrk->arg = msg; 4851 pwrk->dtype = pptr->dtype; 4852 4853 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4854 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4855 if (ptr == NULL) { 4856 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 4857 pmcs_pwork(pwp, pwrk); 4858 return (ENOMEM); 4859 } 4860 COPY_MESSAGE(ptr, msg, PMCS_QENTRY_SIZE); 4861 pwrk->state = PMCS_WORK_STATE_ONCHIP; 4862 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 4863 4864 pmcs_unlock_phy(pptr); 4865 WAIT_FOR(pwrk, 250, result); 4866 pmcs_lock_phy(pptr); 4867 pmcs_pwork(pwp, pwrk); 4868 4869 tgt = pptr->target; 4870 if (result) { 4871 pmcs_prt(pwp, PMCS_PRT_INFO, pptr, tgt, pmcs_timeo, __func__); 4872 return (EIO); 4873 } 4874 status = LE_32(msg[2]); 4875 if (status != PMCOUT_STATUS_OK || LE_32(msg[3])) { 4876 if (tgt == NULL) { 4877 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4878 "%s: cannot find target for phy 0x%p for " 4879 "dev state recovery", __func__, (void *)pptr); 4880 return (EIO); 4881 } 4882 4883 mutex_enter(&tgt->statlock); 4884 4885 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, "READ LOG EXT", msg); 4886 if ((status == PMCOUT_STATUS_IO_DS_NON_OPERATIONAL) || 4887 (status == PMCOUT_STATUS_OPEN_CNX_ERROR_BREAK) || 4888 (status == PMCOUT_STATUS_OPEN_CNX_ERROR_IT_NEXUS_LOSS)) { 4889 ds = PMCS_DEVICE_STATE_NON_OPERATIONAL; 4890 } else { 4891 ds = PMCS_DEVICE_STATE_IN_RECOVERY; 4892 } 4893 if (tgt->dev_state != ds) { 4894 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, "%s: Trying " 4895 "SATA DS Recovery for tgt(0x%p) for status(%s)", 4896 __func__, (void *)tgt, pmcs_status_str(status)); 4897 (void) pmcs_send_err_recovery_cmd(pwp, ds, tgt); 4898 } 4899 4900 mutex_exit(&tgt->statlock); 4901 return (EIO); 4902 } 4903 fis[0] = (fp[4] << 24) | (fp[3] << 16) | (fp[2] << 8) | FIS_REG_D2H; 4904 fis[1] = (fp[8] << 24) | (fp[7] << 16) | (fp[6] << 8) | fp[5]; 4905 fis[2] = (fp[12] << 24) | (fp[11] << 16) | (fp[10] << 8) | fp[9]; 4906 fis[3] = (fp[16] << 24) | (fp[15] << 16) | (fp[14] << 8) | fp[13]; 4907 fis[4] = 0; 4908 if (fp[0] & 0x80) { 4909 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4910 utag_fail_fmt, __func__); 4911 } else { 4912 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 4913 tag_fail_fmt, __func__, fp[0] & 0x1f); 4914 } 4915 pmcs_fis_dump(pwp, fis); 4916 pptr->need_rl_ext = 0; 4917 return (0); 4918 } 4919 4920 /* 4921 * Transform a structure from CPU to Device endian format, or 4922 * vice versa, based upon a transformation vector. 4923 * 4924 * A transformation vector is an array of bytes, each byte 4925 * of which is defined thusly: 4926 * 4927 * bit 7: from CPU to desired endian, otherwise from desired endian 4928 * to CPU format 4929 * bit 6: Big Endian, else Little Endian 4930 * bits 5-4: 4931 * 00 Undefined 4932 * 01 One Byte quantities 4933 * 02 Two Byte quantities 4934 * 03 Four Byte quantities 4935 * 4936 * bits 3-0: 4937 * 00 Undefined 4938 * Number of quantities to transform 4939 * 4940 * The vector is terminated by a 0 value. 4941 */ 4942 4943 void 4944 pmcs_endian_transform(pmcs_hw_t *pwp, void *orig_out, void *orig_in, 4945 const uint8_t *xfvec) 4946 { 4947 uint8_t c, *out = orig_out, *in = orig_in; 4948 4949 if (xfvec == NULL) { 4950 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 4951 "%s: null xfvec", __func__); 4952 return; 4953 } 4954 if (out == NULL) { 4955 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 4956 "%s: null out", __func__); 4957 return; 4958 } 4959 if (in == NULL) { 4960 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 4961 "%s: null in", __func__); 4962 return; 4963 } 4964 while ((c = *xfvec++) != 0) { 4965 int nbyt = (c & 0xf); 4966 int size = (c >> 4) & 0x3; 4967 int bige = (c >> 4) & 0x4; 4968 4969 switch (size) { 4970 case 1: 4971 { 4972 while (nbyt-- > 0) { 4973 *out++ = *in++; 4974 } 4975 break; 4976 } 4977 case 2: 4978 { 4979 uint16_t tmp; 4980 while (nbyt-- > 0) { 4981 (void) memcpy(&tmp, in, sizeof (uint16_t)); 4982 if (bige) { 4983 tmp = BE_16(tmp); 4984 } else { 4985 tmp = LE_16(tmp); 4986 } 4987 (void) memcpy(out, &tmp, sizeof (uint16_t)); 4988 out += sizeof (uint16_t); 4989 in += sizeof (uint16_t); 4990 } 4991 break; 4992 } 4993 case 3: 4994 { 4995 uint32_t tmp; 4996 while (nbyt-- > 0) { 4997 (void) memcpy(&tmp, in, sizeof (uint32_t)); 4998 if (bige) { 4999 tmp = BE_32(tmp); 5000 } else { 5001 tmp = LE_32(tmp); 5002 } 5003 (void) memcpy(out, &tmp, sizeof (uint32_t)); 5004 out += sizeof (uint32_t); 5005 in += sizeof (uint32_t); 5006 } 5007 break; 5008 } 5009 default: 5010 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 5011 "%s: bad size", __func__); 5012 return; 5013 } 5014 } 5015 } 5016 5017 const char * 5018 pmcs_get_rate(unsigned int linkrt) 5019 { 5020 const char *rate; 5021 switch (linkrt) { 5022 case SAS_LINK_RATE_1_5GBIT: 5023 rate = "1.5"; 5024 break; 5025 case SAS_LINK_RATE_3GBIT: 5026 rate = "3.0"; 5027 break; 5028 case SAS_LINK_RATE_6GBIT: 5029 rate = "6.0"; 5030 break; 5031 default: 5032 rate = "???"; 5033 break; 5034 } 5035 return (rate); 5036 } 5037 5038 const char * 5039 pmcs_get_typename(pmcs_dtype_t type) 5040 { 5041 switch (type) { 5042 case NOTHING: 5043 return ("NIL"); 5044 case SATA: 5045 return ("SATA"); 5046 case SAS: 5047 return ("SSP"); 5048 case EXPANDER: 5049 return ("EXPANDER"); 5050 } 5051 return ("????"); 5052 } 5053 5054 const char * 5055 pmcs_tmf2str(int tmf) 5056 { 5057 switch (tmf) { 5058 case SAS_ABORT_TASK: 5059 return ("Abort Task"); 5060 case SAS_ABORT_TASK_SET: 5061 return ("Abort Task Set"); 5062 case SAS_CLEAR_TASK_SET: 5063 return ("Clear Task Set"); 5064 case SAS_LOGICAL_UNIT_RESET: 5065 return ("Logical Unit Reset"); 5066 case SAS_I_T_NEXUS_RESET: 5067 return ("I_T Nexus Reset"); 5068 case SAS_CLEAR_ACA: 5069 return ("Clear ACA"); 5070 case SAS_QUERY_TASK: 5071 return ("Query Task"); 5072 case SAS_QUERY_TASK_SET: 5073 return ("Query Task Set"); 5074 case SAS_QUERY_UNIT_ATTENTION: 5075 return ("Query Unit Attention"); 5076 default: 5077 return ("Unknown"); 5078 } 5079 } 5080 5081 const char * 5082 pmcs_status_str(uint32_t status) 5083 { 5084 switch (status) { 5085 case PMCOUT_STATUS_OK: 5086 return ("OK"); 5087 case PMCOUT_STATUS_ABORTED: 5088 return ("ABORTED"); 5089 case PMCOUT_STATUS_OVERFLOW: 5090 return ("OVERFLOW"); 5091 case PMCOUT_STATUS_UNDERFLOW: 5092 return ("UNDERFLOW"); 5093 case PMCOUT_STATUS_FAILED: 5094 return ("FAILED"); 5095 case PMCOUT_STATUS_ABORT_RESET: 5096 return ("ABORT_RESET"); 5097 case PMCOUT_STATUS_IO_NOT_VALID: 5098 return ("IO_NOT_VALID"); 5099 case PMCOUT_STATUS_NO_DEVICE: 5100 return ("NO_DEVICE"); 5101 case PMCOUT_STATUS_ILLEGAL_PARAMETER: 5102 return ("ILLEGAL_PARAMETER"); 5103 case PMCOUT_STATUS_LINK_FAILURE: 5104 return ("LINK_FAILURE"); 5105 case PMCOUT_STATUS_PROG_ERROR: 5106 return ("PROG_ERROR"); 5107 case PMCOUT_STATUS_EDC_IN_ERROR: 5108 return ("EDC_IN_ERROR"); 5109 case PMCOUT_STATUS_EDC_OUT_ERROR: 5110 return ("EDC_OUT_ERROR"); 5111 case PMCOUT_STATUS_ERROR_HW_TIMEOUT: 5112 return ("ERROR_HW_TIMEOUT"); 5113 case PMCOUT_STATUS_XFER_ERR_BREAK: 5114 return ("XFER_ERR_BREAK"); 5115 case PMCOUT_STATUS_XFER_ERR_PHY_NOT_READY: 5116 return ("XFER_ERR_PHY_NOT_READY"); 5117 case PMCOUT_STATUS_OPEN_CNX_PROTOCOL_NOT_SUPPORTED: 5118 return ("OPEN_CNX_PROTOCOL_NOT_SUPPORTED"); 5119 case PMCOUT_STATUS_OPEN_CNX_ERROR_ZONE_VIOLATION: 5120 return ("OPEN_CNX_ERROR_ZONE_VIOLATION"); 5121 case PMCOUT_STATUS_OPEN_CNX_ERROR_BREAK: 5122 return ("OPEN_CNX_ERROR_BREAK"); 5123 case PMCOUT_STATUS_OPEN_CNX_ERROR_IT_NEXUS_LOSS: 5124 return ("OPEN_CNX_ERROR_IT_NEXUS_LOSS"); 5125 case PMCOUT_STATUS_OPENCNX_ERROR_BAD_DESTINATION: 5126 return ("OPENCNX_ERROR_BAD_DESTINATION"); 5127 case PMCOUT_STATUS_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: 5128 return ("OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED"); 5129 case PMCOUT_STATUS_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: 5130 return ("OPEN_CNX_ERROR_STP_RESOURCES_BUSY"); 5131 case PMCOUT_STATUS_OPEN_CNX_ERROR_WRONG_DESTINATION: 5132 return ("OPEN_CNX_ERROR_WRONG_DESTINATION"); 5133 case PMCOUT_STATUS_OPEN_CNX_ERROR_UNKNOWN_EROOR: 5134 return ("OPEN_CNX_ERROR_UNKNOWN_EROOR"); 5135 case PMCOUT_STATUS_IO_XFER_ERROR_NAK_RECEIVED: 5136 return ("IO_XFER_ERROR_NAK_RECEIVED"); 5137 case PMCOUT_STATUS_XFER_ERROR_ACK_NAK_TIMEOUT: 5138 return ("XFER_ERROR_ACK_NAK_TIMEOUT"); 5139 case PMCOUT_STATUS_XFER_ERROR_PEER_ABORTED: 5140 return ("XFER_ERROR_PEER_ABORTED"); 5141 case PMCOUT_STATUS_XFER_ERROR_RX_FRAME: 5142 return ("XFER_ERROR_RX_FRAME"); 5143 case PMCOUT_STATUS_IO_XFER_ERROR_DMA: 5144 return ("IO_XFER_ERROR_DMA"); 5145 case PMCOUT_STATUS_XFER_ERROR_CREDIT_TIMEOUT: 5146 return ("XFER_ERROR_CREDIT_TIMEOUT"); 5147 case PMCOUT_STATUS_XFER_ERROR_SATA_LINK_TIMEOUT: 5148 return ("XFER_ERROR_SATA_LINK_TIMEOUT"); 5149 case PMCOUT_STATUS_XFER_ERROR_SATA: 5150 return ("XFER_ERROR_SATA"); 5151 case PMCOUT_STATUS_XFER_ERROR_REJECTED_NCQ_MODE: 5152 return ("XFER_ERROR_REJECTED_NCQ_MODE"); 5153 case PMCOUT_STATUS_XFER_ERROR_ABORTED_DUE_TO_SRST: 5154 return ("XFER_ERROR_ABORTED_DUE_TO_SRST"); 5155 case PMCOUT_STATUS_XFER_ERROR_ABORTED_NCQ_MODE: 5156 return ("XFER_ERROR_ABORTED_NCQ_MODE"); 5157 case PMCOUT_STATUS_IO_XFER_OPEN_RETRY_TIMEOUT: 5158 return ("IO_XFER_OPEN_RETRY_TIMEOUT"); 5159 case PMCOUT_STATUS_SMP_RESP_CONNECTION_ERROR: 5160 return ("SMP_RESP_CONNECTION_ERROR"); 5161 case PMCOUT_STATUS_XFER_ERROR_UNEXPECTED_PHASE: 5162 return ("XFER_ERROR_UNEXPECTED_PHASE"); 5163 case PMCOUT_STATUS_XFER_ERROR_RDY_OVERRUN: 5164 return ("XFER_ERROR_RDY_OVERRUN"); 5165 case PMCOUT_STATUS_XFER_ERROR_RDY_NOT_EXPECTED: 5166 return ("XFER_ERROR_RDY_NOT_EXPECTED"); 5167 case PMCOUT_STATUS_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT: 5168 return ("XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT"); 5169 case PMCOUT_STATUS_XFER_ERROR_CMD_ISSUE_BREAK_BEFORE_ACK_NACK: 5170 return ("XFER_ERROR_CMD_ISSUE_BREAK_BEFORE_ACK_NACK"); 5171 case PMCOUT_STATUS_XFER_ERROR_CMD_ISSUE_PHY_DOWN_BEFORE_ACK_NAK: 5172 return ("XFER_ERROR_CMD_ISSUE_PHY_DOWN_BEFORE_ACK_NAK"); 5173 case PMCOUT_STATUS_XFER_ERROR_OFFSET_MISMATCH: 5174 return ("XFER_ERROR_OFFSET_MISMATCH"); 5175 case PMCOUT_STATUS_XFER_ERROR_ZERO_DATA_LEN: 5176 return ("XFER_ERROR_ZERO_DATA_LEN"); 5177 case PMCOUT_STATUS_XFER_CMD_FRAME_ISSUED: 5178 return ("XFER_CMD_FRAME_ISSUED"); 5179 case PMCOUT_STATUS_ERROR_INTERNAL_SMP_RESOURCE: 5180 return ("ERROR_INTERNAL_SMP_RESOURCE"); 5181 case PMCOUT_STATUS_IO_PORT_IN_RESET: 5182 return ("IO_PORT_IN_RESET"); 5183 case PMCOUT_STATUS_IO_DS_NON_OPERATIONAL: 5184 return ("DEVICE STATE NON-OPERATIONAL"); 5185 case PMCOUT_STATUS_IO_DS_IN_RECOVERY: 5186 return ("DEVICE STATE IN RECOVERY"); 5187 default: 5188 return (NULL); 5189 } 5190 } 5191 5192 uint64_t 5193 pmcs_barray2wwn(uint8_t ba[8]) 5194 { 5195 uint64_t result = 0; 5196 int i; 5197 5198 for (i = 0; i < 8; i++) { 5199 result <<= 8; 5200 result |= ba[i]; 5201 } 5202 return (result); 5203 } 5204 5205 void 5206 pmcs_wwn2barray(uint64_t wwn, uint8_t ba[8]) 5207 { 5208 int i; 5209 for (i = 0; i < 8; i++) { 5210 ba[7 - i] = wwn & 0xff; 5211 wwn >>= 8; 5212 } 5213 } 5214 5215 void 5216 pmcs_report_fwversion(pmcs_hw_t *pwp) 5217 { 5218 const char *fwsupport; 5219 switch (PMCS_FW_TYPE(pwp)) { 5220 case PMCS_FW_TYPE_RELEASED: 5221 fwsupport = "Released"; 5222 break; 5223 case PMCS_FW_TYPE_DEVELOPMENT: 5224 fwsupport = "Development"; 5225 break; 5226 case PMCS_FW_TYPE_ALPHA: 5227 fwsupport = "Alpha"; 5228 break; 5229 case PMCS_FW_TYPE_BETA: 5230 fwsupport = "Beta"; 5231 break; 5232 default: 5233 fwsupport = "Special"; 5234 break; 5235 } 5236 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 5237 "Chip Revision: %c; F/W Revision %x.%x.%x %s", 'A' + pwp->chiprev, 5238 PMCS_FW_MAJOR(pwp), PMCS_FW_MINOR(pwp), PMCS_FW_MICRO(pwp), 5239 fwsupport); 5240 } 5241 5242 void 5243 pmcs_phy_name(pmcs_hw_t *pwp, pmcs_phy_t *pptr, char *obuf, size_t olen) 5244 { 5245 if (pptr->parent) { 5246 pmcs_phy_name(pwp, pptr->parent, obuf, olen); 5247 (void) snprintf(obuf, olen, "%s.%02x", obuf, pptr->phynum); 5248 } else { 5249 (void) snprintf(obuf, olen, "pp%02x", pptr->phynum); 5250 } 5251 } 5252 5253 /* 5254 * Implementation for pmcs_find_phy_by_devid. 5255 * If the PHY is found, it is returned locked. 5256 */ 5257 static pmcs_phy_t * 5258 pmcs_find_phy_by_devid_impl(pmcs_phy_t *phyp, uint32_t device_id) 5259 { 5260 pmcs_phy_t *match, *cphyp, *nphyp; 5261 5262 ASSERT(!mutex_owned(&phyp->phy_lock)); 5263 5264 while (phyp) { 5265 pmcs_lock_phy(phyp); 5266 5267 if ((phyp->valid_device_id) && (phyp->device_id == device_id)) { 5268 return (phyp); 5269 } 5270 if (phyp->children) { 5271 cphyp = phyp->children; 5272 pmcs_unlock_phy(phyp); 5273 match = pmcs_find_phy_by_devid_impl(cphyp, device_id); 5274 if (match) { 5275 ASSERT(mutex_owned(&match->phy_lock)); 5276 return (match); 5277 } 5278 pmcs_lock_phy(phyp); 5279 } 5280 5281 if (IS_ROOT_PHY(phyp)) { 5282 pmcs_unlock_phy(phyp); 5283 phyp = NULL; 5284 } else { 5285 nphyp = phyp->sibling; 5286 pmcs_unlock_phy(phyp); 5287 phyp = nphyp; 5288 } 5289 } 5290 5291 return (NULL); 5292 } 5293 5294 /* 5295 * If the PHY is found, it is returned locked 5296 */ 5297 pmcs_phy_t * 5298 pmcs_find_phy_by_devid(pmcs_hw_t *pwp, uint32_t device_id) 5299 { 5300 pmcs_phy_t *phyp, *match = NULL; 5301 5302 phyp = pwp->root_phys; 5303 5304 while (phyp) { 5305 match = pmcs_find_phy_by_devid_impl(phyp, device_id); 5306 if (match) { 5307 ASSERT(mutex_owned(&match->phy_lock)); 5308 return (match); 5309 } 5310 phyp = phyp->sibling; 5311 } 5312 5313 return (NULL); 5314 } 5315 5316 /* 5317 * This function is called as a sanity check to ensure that a newly registered 5318 * PHY doesn't have a device_id that exists with another registered PHY. 5319 */ 5320 static boolean_t 5321 pmcs_validate_devid(pmcs_phy_t *parent, pmcs_phy_t *phyp, uint32_t device_id) 5322 { 5323 pmcs_phy_t *pptr; 5324 boolean_t rval; 5325 5326 pptr = parent; 5327 5328 while (pptr) { 5329 if (pptr->valid_device_id && (pptr != phyp) && 5330 (pptr->device_id == device_id)) { 5331 pmcs_prt(pptr->pwp, PMCS_PRT_DEBUG, pptr, NULL, 5332 "%s: phy %s already exists as %s with " 5333 "device id 0x%x", __func__, phyp->path, 5334 pptr->path, device_id); 5335 return (B_FALSE); 5336 } 5337 5338 if (pptr->children) { 5339 rval = pmcs_validate_devid(pptr->children, phyp, 5340 device_id); 5341 if (rval == B_FALSE) { 5342 return (rval); 5343 } 5344 } 5345 5346 pptr = pptr->sibling; 5347 } 5348 5349 /* This PHY and device_id are valid */ 5350 return (B_TRUE); 5351 } 5352 5353 /* 5354 * If the PHY is found, it is returned locked 5355 */ 5356 static pmcs_phy_t * 5357 pmcs_find_phy_by_wwn_impl(pmcs_phy_t *phyp, uint8_t *wwn) 5358 { 5359 pmcs_phy_t *matched_phy, *cphyp, *nphyp; 5360 5361 ASSERT(!mutex_owned(&phyp->phy_lock)); 5362 5363 while (phyp) { 5364 pmcs_lock_phy(phyp); 5365 5366 if (phyp->valid_device_id) { 5367 if (memcmp(phyp->sas_address, wwn, 8) == 0) { 5368 return (phyp); 5369 } 5370 } 5371 5372 if (phyp->children) { 5373 cphyp = phyp->children; 5374 pmcs_unlock_phy(phyp); 5375 matched_phy = pmcs_find_phy_by_wwn_impl(cphyp, wwn); 5376 if (matched_phy) { 5377 ASSERT(mutex_owned(&matched_phy->phy_lock)); 5378 return (matched_phy); 5379 } 5380 pmcs_lock_phy(phyp); 5381 } 5382 5383 /* 5384 * Only iterate through non-root PHYs 5385 */ 5386 if (IS_ROOT_PHY(phyp)) { 5387 pmcs_unlock_phy(phyp); 5388 phyp = NULL; 5389 } else { 5390 nphyp = phyp->sibling; 5391 pmcs_unlock_phy(phyp); 5392 phyp = nphyp; 5393 } 5394 } 5395 5396 return (NULL); 5397 } 5398 5399 pmcs_phy_t * 5400 pmcs_find_phy_by_wwn(pmcs_hw_t *pwp, uint64_t wwn) 5401 { 5402 uint8_t ebstr[8]; 5403 pmcs_phy_t *pptr, *matched_phy; 5404 5405 pmcs_wwn2barray(wwn, ebstr); 5406 5407 pptr = pwp->root_phys; 5408 while (pptr) { 5409 matched_phy = pmcs_find_phy_by_wwn_impl(pptr, ebstr); 5410 if (matched_phy) { 5411 ASSERT(mutex_owned(&matched_phy->phy_lock)); 5412 return (matched_phy); 5413 } 5414 5415 pptr = pptr->sibling; 5416 } 5417 5418 return (NULL); 5419 } 5420 5421 5422 /* 5423 * pmcs_find_phy_by_sas_address 5424 * 5425 * Find a PHY that both matches "sas_addr" and is on "iport". 5426 * If a matching PHY is found, it is returned locked. 5427 */ 5428 pmcs_phy_t * 5429 pmcs_find_phy_by_sas_address(pmcs_hw_t *pwp, pmcs_iport_t *iport, 5430 pmcs_phy_t *root, char *sas_addr) 5431 { 5432 int ua_form = 1; 5433 uint64_t wwn; 5434 char addr[PMCS_MAX_UA_SIZE]; 5435 pmcs_phy_t *pptr, *pnext, *pchild; 5436 5437 if (root == NULL) { 5438 pptr = pwp->root_phys; 5439 } else { 5440 pptr = root; 5441 } 5442 5443 while (pptr) { 5444 pmcs_lock_phy(pptr); 5445 /* 5446 * If the PHY is dead or does not have a valid device ID, 5447 * skip it. 5448 */ 5449 if ((pptr->dead) || (!pptr->valid_device_id)) { 5450 goto next_phy; 5451 } 5452 5453 if (pptr->iport != iport) { 5454 goto next_phy; 5455 } 5456 5457 wwn = pmcs_barray2wwn(pptr->sas_address); 5458 (void *) scsi_wwn_to_wwnstr(wwn, ua_form, addr); 5459 if (strncmp(addr, sas_addr, strlen(addr)) == 0) { 5460 return (pptr); 5461 } 5462 5463 if (pptr->children) { 5464 pchild = pptr->children; 5465 pmcs_unlock_phy(pptr); 5466 pnext = pmcs_find_phy_by_sas_address(pwp, iport, pchild, 5467 sas_addr); 5468 if (pnext) { 5469 return (pnext); 5470 } 5471 pmcs_lock_phy(pptr); 5472 } 5473 5474 next_phy: 5475 pnext = pptr->sibling; 5476 pmcs_unlock_phy(pptr); 5477 pptr = pnext; 5478 } 5479 5480 return (NULL); 5481 } 5482 5483 void 5484 pmcs_fis_dump(pmcs_hw_t *pwp, fis_t fis) 5485 { 5486 switch (fis[0] & 0xff) { 5487 case FIS_REG_H2DEV: 5488 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 5489 "FIS REGISTER HOST TO DEVICE: " 5490 "OP=0x%02x Feature=0x%04x Count=0x%04x Device=0x%02x " 5491 "LBA=%llu", BYTE2(fis[0]), BYTE3(fis[2]) << 8 | 5492 BYTE3(fis[0]), WORD0(fis[3]), BYTE3(fis[1]), 5493 (unsigned long long) 5494 (((uint64_t)fis[2] & 0x00ffffff) << 24 | 5495 ((uint64_t)fis[1] & 0x00ffffff))); 5496 break; 5497 case FIS_REG_D2H: 5498 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 5499 "FIS REGISTER DEVICE TO HOST: Status=0x%02x " 5500 "Error=0x%02x Dev=0x%02x Count=0x%04x LBA=%llu", 5501 BYTE2(fis[0]), BYTE3(fis[0]), BYTE3(fis[1]), WORD0(fis[3]), 5502 (unsigned long long)(((uint64_t)fis[2] & 0x00ffffff) << 24 | 5503 ((uint64_t)fis[1] & 0x00ffffff))); 5504 break; 5505 default: 5506 pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, 5507 "FIS: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x", 5508 fis[0], fis[1], fis[2], fis[3], fis[4], fis[5], fis[6]); 5509 break; 5510 } 5511 } 5512 5513 void 5514 pmcs_print_entry(pmcs_hw_t *pwp, int level, char *msg, void *arg) 5515 { 5516 uint32_t *mb = arg; 5517 size_t i; 5518 5519 pmcs_prt(pwp, level, NULL, NULL, msg); 5520 for (i = 0; i < (PMCS_QENTRY_SIZE / sizeof (uint32_t)); i += 4) { 5521 pmcs_prt(pwp, level, NULL, NULL, 5522 "Offset %2lu: 0x%08x 0x%08x 0x%08x 0x%08x", 5523 i * sizeof (uint32_t), LE_32(mb[i]), 5524 LE_32(mb[i+1]), LE_32(mb[i+2]), LE_32(mb[i+3])); 5525 } 5526 } 5527 5528 /* 5529 * If phyp == NULL we're being called from the worker thread, in which 5530 * case we need to check all the PHYs. In this case, the softstate lock 5531 * will be held. 5532 * If phyp is non-NULL, just issue the spinup release for the specified PHY 5533 * (which will already be locked). 5534 */ 5535 void 5536 pmcs_spinup_release(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 5537 { 5538 uint32_t *msg; 5539 struct pmcwork *pwrk; 5540 pmcs_phy_t *tphyp; 5541 5542 if (phyp != NULL) { 5543 ASSERT(mutex_owned(&phyp->phy_lock)); 5544 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, NULL, 5545 "%s: Issuing spinup release only for PHY %s", __func__, 5546 phyp->path); 5547 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5548 msg = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5549 if (msg == NULL || (pwrk = 5550 pmcs_gwork(pwp, PMCS_TAG_TYPE_NONE, NULL)) == NULL) { 5551 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5552 SCHEDULE_WORK(pwp, PMCS_WORK_SPINUP_RELEASE); 5553 return; 5554 } 5555 5556 phyp->spinup_hold = 0; 5557 bzero(msg, PMCS_QENTRY_SIZE); 5558 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 5559 PMCIN_LOCAL_PHY_CONTROL)); 5560 msg[1] = LE_32(pwrk->htag); 5561 msg[2] = LE_32((0x10 << 8) | phyp->phynum); 5562 5563 pwrk->dtype = phyp->dtype; 5564 pwrk->state = PMCS_WORK_STATE_ONCHIP; 5565 mutex_exit(&pwrk->lock); 5566 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5567 return; 5568 } 5569 5570 ASSERT(mutex_owned(&pwp->lock)); 5571 5572 tphyp = pwp->root_phys; 5573 while (tphyp) { 5574 pmcs_lock_phy(tphyp); 5575 if (tphyp->spinup_hold == 0) { 5576 pmcs_unlock_phy(tphyp); 5577 tphyp = tphyp->sibling; 5578 continue; 5579 } 5580 5581 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, NULL, 5582 "%s: Issuing spinup release for PHY %s", __func__, 5583 phyp->path); 5584 5585 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5586 msg = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5587 if (msg == NULL || (pwrk = 5588 pmcs_gwork(pwp, PMCS_TAG_TYPE_NONE, NULL)) == NULL) { 5589 pmcs_unlock_phy(tphyp); 5590 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5591 SCHEDULE_WORK(pwp, PMCS_WORK_SPINUP_RELEASE); 5592 break; 5593 } 5594 5595 tphyp->spinup_hold = 0; 5596 bzero(msg, PMCS_QENTRY_SIZE); 5597 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 5598 PMCIN_LOCAL_PHY_CONTROL)); 5599 msg[1] = LE_32(pwrk->htag); 5600 msg[2] = LE_32((0x10 << 8) | tphyp->phynum); 5601 5602 pwrk->dtype = phyp->dtype; 5603 pwrk->state = PMCS_WORK_STATE_ONCHIP; 5604 mutex_exit(&pwrk->lock); 5605 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5606 pmcs_unlock_phy(tphyp); 5607 5608 tphyp = tphyp->sibling; 5609 } 5610 } 5611 5612 /* 5613 * Abort commands on dead PHYs and deregister them as well as removing 5614 * the associated targets. 5615 */ 5616 static int 5617 pmcs_kill_devices(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 5618 { 5619 pmcs_phy_t *pnext, *pchild; 5620 boolean_t remove_device; 5621 int rval = 0; 5622 5623 while (phyp) { 5624 pmcs_lock_phy(phyp); 5625 pchild = phyp->children; 5626 pnext = phyp->sibling; 5627 pmcs_unlock_phy(phyp); 5628 5629 if (pchild) { 5630 rval = pmcs_kill_devices(pwp, pchild); 5631 if (rval) { 5632 return (rval); 5633 } 5634 } 5635 5636 /* 5637 * pmcs_remove_device requires the softstate lock. 5638 */ 5639 mutex_enter(&pwp->lock); 5640 pmcs_lock_phy(phyp); 5641 if (phyp->dead && phyp->valid_device_id) { 5642 remove_device = B_TRUE; 5643 } else { 5644 remove_device = B_FALSE; 5645 } 5646 5647 if (remove_device) { 5648 pmcs_remove_device(pwp, phyp); 5649 mutex_exit(&pwp->lock); 5650 5651 rval = pmcs_kill_device(pwp, phyp); 5652 5653 if (rval) { 5654 pmcs_unlock_phy(phyp); 5655 return (rval); 5656 } 5657 } else { 5658 mutex_exit(&pwp->lock); 5659 } 5660 5661 pmcs_unlock_phy(phyp); 5662 phyp = pnext; 5663 } 5664 5665 return (rval); 5666 } 5667 5668 /* 5669 * Called with PHY locked 5670 */ 5671 int 5672 pmcs_kill_device(pmcs_hw_t *pwp, pmcs_phy_t *pptr) 5673 { 5674 int r, result; 5675 uint32_t msg[PMCS_MSG_SIZE], *ptr, status; 5676 struct pmcwork *pwrk; 5677 5678 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, "kill %s device @ %s", 5679 pmcs_get_typename(pptr->dtype), pptr->path); 5680 5681 /* 5682 * There may be an outstanding ABORT_ALL running, which we wouldn't 5683 * know just by checking abort_pending. We can, however, check 5684 * abort_all_start. If it's non-zero, there is one, and we'll just 5685 * sit here and wait for it to complete. If we don't, we'll remove 5686 * the device while there are still commands pending. 5687 */ 5688 if (pptr->abort_all_start) { 5689 while (pptr->abort_all_start) { 5690 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 5691 "%s: Waiting for outstanding ABORT_ALL on PHY 0x%p", 5692 __func__, (void *)pptr); 5693 cv_wait(&pptr->abort_all_cv, &pptr->phy_lock); 5694 } 5695 } else if (pptr->abort_pending) { 5696 r = pmcs_abort(pwp, pptr, pptr->device_id, 1, 1); 5697 5698 if (r) { 5699 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 5700 "%s: ABORT_ALL returned non-zero status (%d) for " 5701 "PHY 0x%p", __func__, r, (void *)pptr); 5702 return (r); 5703 } 5704 pptr->abort_pending = 0; 5705 } 5706 5707 if (pptr->valid_device_id == 0) { 5708 return (0); 5709 } 5710 5711 if ((pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr)) == NULL) { 5712 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nowrk, __func__); 5713 return (ENOMEM); 5714 } 5715 pwrk->arg = msg; 5716 pwrk->dtype = pptr->dtype; 5717 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 5718 PMCIN_DEREGISTER_DEVICE_HANDLE)); 5719 msg[1] = LE_32(pwrk->htag); 5720 msg[2] = LE_32(pptr->device_id); 5721 5722 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5723 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5724 if (ptr == NULL) { 5725 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5726 mutex_exit(&pwrk->lock); 5727 pmcs_prt(pwp, PMCS_PRT_ERR, pptr, NULL, pmcs_nomsg, __func__); 5728 return (ENOMEM); 5729 } 5730 5731 COPY_MESSAGE(ptr, msg, 3); 5732 pwrk->state = PMCS_WORK_STATE_ONCHIP; 5733 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5734 5735 pmcs_unlock_phy(pptr); 5736 WAIT_FOR(pwrk, 250, result); 5737 pmcs_lock_phy(pptr); 5738 pmcs_pwork(pwp, pwrk); 5739 5740 if (result) { 5741 return (ETIMEDOUT); 5742 } 5743 status = LE_32(msg[2]); 5744 if (status != PMCOUT_STATUS_OK) { 5745 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL, 5746 "%s: status 0x%x when trying to deregister device %s", 5747 __func__, status, pptr->path); 5748 } 5749 5750 pptr->device_id = PMCS_INVALID_DEVICE_ID; 5751 PHY_CHANGED(pwp, pptr); 5752 RESTART_DISCOVERY(pwp); 5753 pptr->valid_device_id = 0; 5754 return (0); 5755 } 5756 5757 /* 5758 * Acknowledge the SAS h/w events that need acknowledgement. 5759 * This is only needed for first level PHYs. 5760 */ 5761 void 5762 pmcs_ack_events(pmcs_hw_t *pwp) 5763 { 5764 uint32_t msg[PMCS_MSG_SIZE], *ptr; 5765 struct pmcwork *pwrk; 5766 pmcs_phy_t *pptr; 5767 5768 for (pptr = pwp->root_phys; pptr; pptr = pptr->sibling) { 5769 pmcs_lock_phy(pptr); 5770 if (pptr->hw_event_ack == 0) { 5771 pmcs_unlock_phy(pptr); 5772 continue; 5773 } 5774 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5775 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5776 5777 if ((ptr == NULL) || (pwrk = 5778 pmcs_gwork(pwp, PMCS_TAG_TYPE_NONE, NULL)) == NULL) { 5779 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 5780 pmcs_unlock_phy(pptr); 5781 SCHEDULE_WORK(pwp, PMCS_WORK_SAS_HW_ACK); 5782 break; 5783 } 5784 5785 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 5786 PMCIN_SAW_HW_EVENT_ACK)); 5787 msg[1] = LE_32(pwrk->htag); 5788 msg[2] = LE_32(pptr->hw_event_ack); 5789 5790 mutex_exit(&pwrk->lock); 5791 pwrk->dtype = pptr->dtype; 5792 pptr->hw_event_ack = 0; 5793 COPY_MESSAGE(ptr, msg, 3); 5794 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 5795 pmcs_unlock_phy(pptr); 5796 } 5797 } 5798 5799 /* 5800 * Load DMA 5801 */ 5802 int 5803 pmcs_dma_load(pmcs_hw_t *pwp, pmcs_cmd_t *sp, uint32_t *msg) 5804 { 5805 ddi_dma_cookie_t *sg; 5806 pmcs_dmachunk_t *tc; 5807 pmcs_dmasgl_t *sgl, *prior; 5808 int seg, tsc; 5809 uint64_t sgl_addr; 5810 5811 /* 5812 * If we have no data segments, we're done. 5813 */ 5814 if (CMD2PKT(sp)->pkt_numcookies == 0) { 5815 return (0); 5816 } 5817 5818 /* 5819 * Get the S/G list pointer. 5820 */ 5821 sg = CMD2PKT(sp)->pkt_cookies; 5822 5823 /* 5824 * If we only have one dma segment, we can directly address that 5825 * data within the Inbound message itself. 5826 */ 5827 if (CMD2PKT(sp)->pkt_numcookies == 1) { 5828 msg[12] = LE_32(DWORD0(sg->dmac_laddress)); 5829 msg[13] = LE_32(DWORD1(sg->dmac_laddress)); 5830 msg[14] = LE_32(sg->dmac_size); 5831 msg[15] = 0; 5832 return (0); 5833 } 5834 5835 /* 5836 * Otherwise, we'll need one or more external S/G list chunks. 5837 * Get the first one and its dma address into the Inbound message. 5838 */ 5839 mutex_enter(&pwp->dma_lock); 5840 tc = pwp->dma_freelist; 5841 if (tc == NULL) { 5842 SCHEDULE_WORK(pwp, PMCS_WORK_ADD_DMA_CHUNKS); 5843 mutex_exit(&pwp->dma_lock); 5844 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, 5845 "%s: out of SG lists", __func__); 5846 return (-1); 5847 } 5848 pwp->dma_freelist = tc->nxt; 5849 mutex_exit(&pwp->dma_lock); 5850 5851 tc->nxt = NULL; 5852 sp->cmd_clist = tc; 5853 sgl = tc->chunks; 5854 (void) memset(tc->chunks, 0, PMCS_SGL_CHUNKSZ); 5855 sgl_addr = tc->addr; 5856 msg[12] = LE_32(DWORD0(sgl_addr)); 5857 msg[13] = LE_32(DWORD1(sgl_addr)); 5858 msg[14] = 0; 5859 msg[15] = LE_32(PMCS_DMASGL_EXTENSION); 5860 5861 prior = sgl; 5862 tsc = 0; 5863 5864 for (seg = 0; seg < CMD2PKT(sp)->pkt_numcookies; seg++) { 5865 /* 5866 * If the current segment count for this chunk is one less than 5867 * the number s/g lists per chunk and we have more than one seg 5868 * to go, we need another chunk. Get it, and make sure that the 5869 * tail end of the the previous chunk points the new chunk 5870 * (if remembering an offset can be called 'pointing to'). 5871 * 5872 * Note that we can store the offset into our command area that 5873 * represents the new chunk in the length field of the part 5874 * that points the PMC chip at the next chunk- the PMC chip 5875 * ignores this field when the EXTENSION bit is set. 5876 * 5877 * This is required for dma unloads later. 5878 */ 5879 if (tsc == (PMCS_SGL_NCHUNKS - 1) && 5880 seg < (CMD2PKT(sp)->pkt_numcookies - 1)) { 5881 mutex_enter(&pwp->dma_lock); 5882 tc = pwp->dma_freelist; 5883 if (tc == NULL) { 5884 SCHEDULE_WORK(pwp, PMCS_WORK_ADD_DMA_CHUNKS); 5885 mutex_exit(&pwp->dma_lock); 5886 pmcs_dma_unload(pwp, sp); 5887 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, 5888 "%s: out of SG lists", __func__); 5889 return (-1); 5890 } 5891 pwp->dma_freelist = tc->nxt; 5892 tc->nxt = sp->cmd_clist; 5893 mutex_exit(&pwp->dma_lock); 5894 5895 sp->cmd_clist = tc; 5896 (void) memset(tc->chunks, 0, PMCS_SGL_CHUNKSZ); 5897 sgl = tc->chunks; 5898 sgl_addr = tc->addr; 5899 prior[PMCS_SGL_NCHUNKS-1].sglal = 5900 LE_32(DWORD0(sgl_addr)); 5901 prior[PMCS_SGL_NCHUNKS-1].sglah = 5902 LE_32(DWORD1(sgl_addr)); 5903 prior[PMCS_SGL_NCHUNKS-1].sglen = 0; 5904 prior[PMCS_SGL_NCHUNKS-1].flags = 5905 LE_32(PMCS_DMASGL_EXTENSION); 5906 prior = sgl; 5907 tsc = 0; 5908 } 5909 sgl[tsc].sglal = LE_32(DWORD0(sg->dmac_laddress)); 5910 sgl[tsc].sglah = LE_32(DWORD1(sg->dmac_laddress)); 5911 sgl[tsc].sglen = LE_32(sg->dmac_size); 5912 sgl[tsc++].flags = 0; 5913 sg++; 5914 } 5915 return (0); 5916 } 5917 5918 /* 5919 * Unload DMA 5920 */ 5921 void 5922 pmcs_dma_unload(pmcs_hw_t *pwp, pmcs_cmd_t *sp) 5923 { 5924 pmcs_dmachunk_t *cp; 5925 5926 mutex_enter(&pwp->dma_lock); 5927 while ((cp = sp->cmd_clist) != NULL) { 5928 sp->cmd_clist = cp->nxt; 5929 cp->nxt = pwp->dma_freelist; 5930 pwp->dma_freelist = cp; 5931 } 5932 mutex_exit(&pwp->dma_lock); 5933 } 5934 5935 /* 5936 * Take a chunk of consistent memory that has just been allocated and inserted 5937 * into the cip indices and prepare it for DMA chunk usage and add it to the 5938 * freelist. 5939 * 5940 * Called with dma_lock locked (except during attach when it's unnecessary) 5941 */ 5942 void 5943 pmcs_idma_chunks(pmcs_hw_t *pwp, pmcs_dmachunk_t *dcp, 5944 pmcs_chunk_t *pchunk, unsigned long lim) 5945 { 5946 unsigned long off, n; 5947 pmcs_dmachunk_t *np = dcp; 5948 pmcs_chunk_t *tmp_chunk; 5949 5950 if (pwp->dma_chunklist == NULL) { 5951 pwp->dma_chunklist = pchunk; 5952 } else { 5953 tmp_chunk = pwp->dma_chunklist; 5954 while (tmp_chunk->next) { 5955 tmp_chunk = tmp_chunk->next; 5956 } 5957 tmp_chunk->next = pchunk; 5958 } 5959 5960 /* 5961 * Install offsets into chunk lists. 5962 */ 5963 for (n = 0, off = 0; off < lim; off += PMCS_SGL_CHUNKSZ, n++) { 5964 np->chunks = (void *)&pchunk->addrp[off]; 5965 np->addr = pchunk->dma_addr + off; 5966 np->acc_handle = pchunk->acc_handle; 5967 np->dma_handle = pchunk->dma_handle; 5968 if ((off + PMCS_SGL_CHUNKSZ) < lim) { 5969 np = np->nxt; 5970 } 5971 } 5972 np->nxt = pwp->dma_freelist; 5973 pwp->dma_freelist = dcp; 5974 pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, 5975 "added %lu DMA chunks ", n); 5976 } 5977 5978 /* 5979 * Change the value of the interrupt coalescing timer. This is done currently 5980 * only for I/O completions. If we're using the "auto clear" feature, it can 5981 * be turned back on when interrupt coalescing is turned off and must be 5982 * turned off when the coalescing timer is on. 5983 * NOTE: PMCS_MSIX_GENERAL and PMCS_OQ_IODONE are the same value. As long 5984 * as that's true, we don't need to distinguish between them. 5985 */ 5986 5987 void 5988 pmcs_set_intr_coal_timer(pmcs_hw_t *pwp, pmcs_coal_timer_adj_t adj) 5989 { 5990 if (adj == DECREASE_TIMER) { 5991 /* If the timer is already off, nothing to do. */ 5992 if (pwp->io_intr_coal.timer_on == B_FALSE) { 5993 return; 5994 } 5995 5996 pwp->io_intr_coal.intr_coal_timer -= PMCS_COAL_TIMER_GRAN; 5997 5998 if (pwp->io_intr_coal.intr_coal_timer == 0) { 5999 /* Disable the timer */ 6000 pmcs_wr_topunit(pwp, PMCS_INT_COALESCING_CONTROL, 0); 6001 6002 if (pwp->odb_auto_clear & (1 << PMCS_MSIX_IODONE)) { 6003 pmcs_wr_topunit(pwp, PMCS_OBDB_AUTO_CLR, 6004 pwp->odb_auto_clear); 6005 } 6006 6007 pwp->io_intr_coal.timer_on = B_FALSE; 6008 pwp->io_intr_coal.max_io_completions = B_FALSE; 6009 pwp->io_intr_coal.num_intrs = 0; 6010 pwp->io_intr_coal.int_cleared = B_FALSE; 6011 pwp->io_intr_coal.num_io_completions = 0; 6012 6013 DTRACE_PROBE1(pmcs__intr__coalesce__timer__off, 6014 pmcs_io_intr_coal_t *, &pwp->io_intr_coal); 6015 } else { 6016 pmcs_wr_topunit(pwp, PMCS_INT_COALESCING_TIMER, 6017 pwp->io_intr_coal.intr_coal_timer); 6018 } 6019 } else { 6020 /* 6021 * If the timer isn't on yet, do the setup for it now. 6022 */ 6023 if (pwp->io_intr_coal.timer_on == B_FALSE) { 6024 /* If auto clear is being used, turn it off. */ 6025 if (pwp->odb_auto_clear & (1 << PMCS_MSIX_IODONE)) { 6026 pmcs_wr_topunit(pwp, PMCS_OBDB_AUTO_CLR, 6027 (pwp->odb_auto_clear & 6028 ~(1 << PMCS_MSIX_IODONE))); 6029 } 6030 6031 pmcs_wr_topunit(pwp, PMCS_INT_COALESCING_CONTROL, 6032 (1 << PMCS_MSIX_IODONE)); 6033 pwp->io_intr_coal.timer_on = B_TRUE; 6034 pwp->io_intr_coal.intr_coal_timer = 6035 PMCS_COAL_TIMER_GRAN; 6036 6037 DTRACE_PROBE1(pmcs__intr__coalesce__timer__on, 6038 pmcs_io_intr_coal_t *, &pwp->io_intr_coal); 6039 } else { 6040 pwp->io_intr_coal.intr_coal_timer += 6041 PMCS_COAL_TIMER_GRAN; 6042 } 6043 6044 if (pwp->io_intr_coal.intr_coal_timer > PMCS_MAX_COAL_TIMER) { 6045 pwp->io_intr_coal.intr_coal_timer = PMCS_MAX_COAL_TIMER; 6046 } 6047 6048 pmcs_wr_topunit(pwp, PMCS_INT_COALESCING_TIMER, 6049 pwp->io_intr_coal.intr_coal_timer); 6050 } 6051 6052 /* 6053 * Adjust the interrupt threshold based on the current timer value 6054 */ 6055 pwp->io_intr_coal.intr_threshold = 6056 PMCS_INTR_THRESHOLD(PMCS_QUANTUM_TIME_USECS * 1000 / 6057 (pwp->io_intr_coal.intr_latency + 6058 (pwp->io_intr_coal.intr_coal_timer * 1000))); 6059 } 6060 6061 /* 6062 * Register Access functions 6063 */ 6064 uint32_t 6065 pmcs_rd_iqci(pmcs_hw_t *pwp, uint32_t qnum) 6066 { 6067 uint32_t iqci; 6068 6069 if (ddi_dma_sync(pwp->cip_handles, 0, 0, DDI_DMA_SYNC_FORKERNEL) != 6070 DDI_SUCCESS) { 6071 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6072 "%s: ddi_dma_sync failed?", __func__); 6073 } 6074 6075 iqci = LE_32( 6076 ((uint32_t *)((void *)pwp->cip))[IQ_OFFSET(qnum) >> 2]); 6077 6078 return (iqci); 6079 } 6080 6081 uint32_t 6082 pmcs_rd_oqpi(pmcs_hw_t *pwp, uint32_t qnum) 6083 { 6084 uint32_t oqpi; 6085 6086 if (ddi_dma_sync(pwp->cip_handles, 0, 0, DDI_DMA_SYNC_FORKERNEL) != 6087 DDI_SUCCESS) { 6088 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6089 "%s: ddi_dma_sync failed?", __func__); 6090 } 6091 6092 oqpi = LE_32( 6093 ((uint32_t *)((void *)pwp->cip))[OQ_OFFSET(qnum) >> 2]); 6094 6095 return (oqpi); 6096 } 6097 6098 uint32_t 6099 pmcs_rd_gsm_reg(pmcs_hw_t *pwp, uint32_t off) 6100 { 6101 uint32_t rv, newaxil, oldaxil; 6102 6103 newaxil = off & ~GSM_BASE_MASK; 6104 off &= GSM_BASE_MASK; 6105 mutex_enter(&pwp->axil_lock); 6106 oldaxil = ddi_get32(pwp->top_acc_handle, 6107 &pwp->top_regs[PMCS_AXI_TRANS >> 2]); 6108 ddi_put32(pwp->top_acc_handle, 6109 &pwp->top_regs[PMCS_AXI_TRANS >> 2], newaxil); 6110 drv_usecwait(10); 6111 if (ddi_get32(pwp->top_acc_handle, 6112 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != newaxil) { 6113 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6114 "AXIL register update failed"); 6115 } 6116 rv = ddi_get32(pwp->gsm_acc_handle, &pwp->gsm_regs[off >> 2]); 6117 ddi_put32(pwp->top_acc_handle, 6118 &pwp->top_regs[PMCS_AXI_TRANS >> 2], oldaxil); 6119 drv_usecwait(10); 6120 if (ddi_get32(pwp->top_acc_handle, 6121 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != oldaxil) { 6122 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6123 "AXIL register restore failed"); 6124 } 6125 mutex_exit(&pwp->axil_lock); 6126 return (rv); 6127 } 6128 6129 void 6130 pmcs_wr_gsm_reg(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6131 { 6132 uint32_t newaxil, oldaxil; 6133 6134 newaxil = off & ~GSM_BASE_MASK; 6135 off &= GSM_BASE_MASK; 6136 mutex_enter(&pwp->axil_lock); 6137 oldaxil = ddi_get32(pwp->top_acc_handle, 6138 &pwp->top_regs[PMCS_AXI_TRANS >> 2]); 6139 ddi_put32(pwp->top_acc_handle, 6140 &pwp->top_regs[PMCS_AXI_TRANS >> 2], newaxil); 6141 drv_usecwait(10); 6142 if (ddi_get32(pwp->top_acc_handle, 6143 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != newaxil) { 6144 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6145 "AXIL register update failed"); 6146 } 6147 ddi_put32(pwp->gsm_acc_handle, &pwp->gsm_regs[off >> 2], val); 6148 ddi_put32(pwp->top_acc_handle, 6149 &pwp->top_regs[PMCS_AXI_TRANS >> 2], oldaxil); 6150 drv_usecwait(10); 6151 if (ddi_get32(pwp->top_acc_handle, 6152 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != oldaxil) { 6153 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6154 "AXIL register restore failed"); 6155 } 6156 mutex_exit(&pwp->axil_lock); 6157 } 6158 6159 uint32_t 6160 pmcs_rd_topunit(pmcs_hw_t *pwp, uint32_t off) 6161 { 6162 switch (off) { 6163 case PMCS_SPC_RESET: 6164 case PMCS_SPC_BOOT_STRAP: 6165 case PMCS_SPC_DEVICE_ID: 6166 case PMCS_DEVICE_REVISION: 6167 off = pmcs_rd_gsm_reg(pwp, off); 6168 break; 6169 default: 6170 off = ddi_get32(pwp->top_acc_handle, 6171 &pwp->top_regs[off >> 2]); 6172 break; 6173 } 6174 return (off); 6175 } 6176 6177 void 6178 pmcs_wr_topunit(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6179 { 6180 switch (off) { 6181 case PMCS_SPC_RESET: 6182 case PMCS_DEVICE_REVISION: 6183 pmcs_wr_gsm_reg(pwp, off, val); 6184 break; 6185 default: 6186 ddi_put32(pwp->top_acc_handle, &pwp->top_regs[off >> 2], val); 6187 break; 6188 } 6189 } 6190 6191 uint32_t 6192 pmcs_rd_msgunit(pmcs_hw_t *pwp, uint32_t off) 6193 { 6194 return (ddi_get32(pwp->msg_acc_handle, &pwp->msg_regs[off >> 2])); 6195 } 6196 6197 uint32_t 6198 pmcs_rd_mpi_tbl(pmcs_hw_t *pwp, uint32_t off) 6199 { 6200 return (ddi_get32(pwp->mpi_acc_handle, 6201 &pwp->mpi_regs[(pwp->mpi_offset + off) >> 2])); 6202 } 6203 6204 uint32_t 6205 pmcs_rd_gst_tbl(pmcs_hw_t *pwp, uint32_t off) 6206 { 6207 return (ddi_get32(pwp->mpi_acc_handle, 6208 &pwp->mpi_regs[(pwp->mpi_gst_offset + off) >> 2])); 6209 } 6210 6211 uint32_t 6212 pmcs_rd_iqc_tbl(pmcs_hw_t *pwp, uint32_t off) 6213 { 6214 return (ddi_get32(pwp->mpi_acc_handle, 6215 &pwp->mpi_regs[(pwp->mpi_iqc_offset + off) >> 2])); 6216 } 6217 6218 uint32_t 6219 pmcs_rd_oqc_tbl(pmcs_hw_t *pwp, uint32_t off) 6220 { 6221 return (ddi_get32(pwp->mpi_acc_handle, 6222 &pwp->mpi_regs[(pwp->mpi_oqc_offset + off) >> 2])); 6223 } 6224 6225 uint32_t 6226 pmcs_rd_iqpi(pmcs_hw_t *pwp, uint32_t qnum) 6227 { 6228 return (ddi_get32(pwp->mpi_acc_handle, 6229 &pwp->mpi_regs[pwp->iqpi_offset[qnum] >> 2])); 6230 } 6231 6232 uint32_t 6233 pmcs_rd_oqci(pmcs_hw_t *pwp, uint32_t qnum) 6234 { 6235 return (ddi_get32(pwp->mpi_acc_handle, 6236 &pwp->mpi_regs[pwp->oqci_offset[qnum] >> 2])); 6237 } 6238 6239 void 6240 pmcs_wr_msgunit(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6241 { 6242 ddi_put32(pwp->msg_acc_handle, &pwp->msg_regs[off >> 2], val); 6243 } 6244 6245 void 6246 pmcs_wr_mpi_tbl(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6247 { 6248 ddi_put32(pwp->mpi_acc_handle, 6249 &pwp->mpi_regs[(pwp->mpi_offset + off) >> 2], (val)); 6250 } 6251 6252 void 6253 pmcs_wr_gst_tbl(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6254 { 6255 ddi_put32(pwp->mpi_acc_handle, 6256 &pwp->mpi_regs[(pwp->mpi_gst_offset + off) >> 2], val); 6257 } 6258 6259 void 6260 pmcs_wr_iqc_tbl(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6261 { 6262 ddi_put32(pwp->mpi_acc_handle, 6263 &pwp->mpi_regs[(pwp->mpi_iqc_offset + off) >> 2], val); 6264 } 6265 6266 void 6267 pmcs_wr_oqc_tbl(pmcs_hw_t *pwp, uint32_t off, uint32_t val) 6268 { 6269 ddi_put32(pwp->mpi_acc_handle, 6270 &pwp->mpi_regs[(pwp->mpi_oqc_offset + off) >> 2], val); 6271 } 6272 6273 void 6274 pmcs_wr_iqci(pmcs_hw_t *pwp, uint32_t qnum, uint32_t val) 6275 { 6276 ((uint32_t *)((void *)pwp->cip))[IQ_OFFSET(qnum) >> 2] = val; 6277 if (ddi_dma_sync(pwp->cip_handles, 0, 0, DDI_DMA_SYNC_FORDEV) != 6278 DDI_SUCCESS) { 6279 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6280 "%s: ddi_dma_sync failed?", __func__); 6281 } 6282 } 6283 6284 void 6285 pmcs_wr_iqpi(pmcs_hw_t *pwp, uint32_t qnum, uint32_t val) 6286 { 6287 ddi_put32(pwp->mpi_acc_handle, 6288 &pwp->mpi_regs[pwp->iqpi_offset[qnum] >> 2], val); 6289 } 6290 6291 void 6292 pmcs_wr_oqci(pmcs_hw_t *pwp, uint32_t qnum, uint32_t val) 6293 { 6294 ddi_put32(pwp->mpi_acc_handle, 6295 &pwp->mpi_regs[pwp->oqci_offset[qnum] >> 2], val); 6296 } 6297 6298 void 6299 pmcs_wr_oqpi(pmcs_hw_t *pwp, uint32_t qnum, uint32_t val) 6300 { 6301 ((uint32_t *)((void *)pwp->cip))[OQ_OFFSET(qnum) >> 2] = val; 6302 if (ddi_dma_sync(pwp->cip_handles, 0, 0, DDI_DMA_SYNC_FORDEV) != 6303 DDI_SUCCESS) { 6304 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6305 "%s: ddi_dma_sync failed?", __func__); 6306 } 6307 } 6308 6309 /* 6310 * Check the status value of an outbound IOMB and report anything bad 6311 */ 6312 6313 void 6314 pmcs_check_iomb_status(pmcs_hw_t *pwp, uint32_t *iomb) 6315 { 6316 uint16_t opcode; 6317 int offset; 6318 6319 if (iomb == NULL) { 6320 return; 6321 } 6322 6323 opcode = LE_32(iomb[0]) & 0xfff; 6324 6325 switch (opcode) { 6326 /* 6327 * The following have no status field, so ignore them 6328 */ 6329 case PMCOUT_ECHO: 6330 case PMCOUT_SAS_HW_EVENT: 6331 case PMCOUT_GET_DEVICE_HANDLE: 6332 case PMCOUT_SATA_EVENT: 6333 case PMCOUT_SSP_EVENT: 6334 case PMCOUT_DEVICE_HANDLE_ARRIVED: 6335 case PMCOUT_SMP_REQUEST_RECEIVED: 6336 case PMCOUT_GPIO: 6337 case PMCOUT_GPIO_EVENT: 6338 case PMCOUT_GET_TIME_STAMP: 6339 case PMCOUT_SKIP_ENTRIES: 6340 case PMCOUT_GET_NVMD_DATA: /* Actually lower 16 bits of word 3 */ 6341 case PMCOUT_SET_NVMD_DATA: /* but ignore - we don't use these */ 6342 case PMCOUT_DEVICE_HANDLE_REMOVED: 6343 case PMCOUT_SSP_REQUEST_RECEIVED: 6344 return; 6345 6346 case PMCOUT_GENERAL_EVENT: 6347 offset = 1; 6348 break; 6349 6350 case PMCOUT_SSP_COMPLETION: 6351 case PMCOUT_SMP_COMPLETION: 6352 case PMCOUT_DEVICE_REGISTRATION: 6353 case PMCOUT_DEREGISTER_DEVICE_HANDLE: 6354 case PMCOUT_SATA_COMPLETION: 6355 case PMCOUT_DEVICE_INFO: 6356 case PMCOUT_FW_FLASH_UPDATE: 6357 case PMCOUT_SSP_ABORT: 6358 case PMCOUT_SATA_ABORT: 6359 case PMCOUT_SAS_DIAG_MODE_START_END: 6360 case PMCOUT_SAS_HW_EVENT_ACK_ACK: 6361 case PMCOUT_SMP_ABORT: 6362 case PMCOUT_SET_DEVICE_STATE: 6363 case PMCOUT_GET_DEVICE_STATE: 6364 case PMCOUT_SET_DEVICE_INFO: 6365 offset = 2; 6366 break; 6367 6368 case PMCOUT_LOCAL_PHY_CONTROL: 6369 case PMCOUT_SAS_DIAG_EXECUTE: 6370 case PMCOUT_PORT_CONTROL: 6371 offset = 3; 6372 break; 6373 6374 case PMCOUT_GET_INFO: 6375 case PMCOUT_GET_VPD: 6376 case PMCOUT_SAS_ASSISTED_DISCOVERY_EVENT: 6377 case PMCOUT_SATA_ASSISTED_DISCOVERY_EVENT: 6378 case PMCOUT_SET_VPD: 6379 case PMCOUT_TWI: 6380 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, 6381 "Got response for deprecated opcode", iomb); 6382 return; 6383 6384 default: 6385 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, 6386 "Got response for unknown opcode", iomb); 6387 return; 6388 } 6389 6390 if (LE_32(iomb[offset]) != PMCOUT_STATUS_OK) { 6391 pmcs_print_entry(pwp, PMCS_PRT_DEBUG, 6392 "bad status on TAG_TYPE_NONE command", iomb); 6393 } 6394 } 6395 6396 /* 6397 * Called with statlock held 6398 */ 6399 void 6400 pmcs_clear_xp(pmcs_hw_t *pwp, pmcs_xscsi_t *xp) 6401 { 6402 _NOTE(ARGUNUSED(pwp)); 6403 6404 ASSERT(mutex_owned(&xp->statlock)); 6405 6406 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp, "%s: Device 0x%p is gone.", 6407 __func__, (void *)xp); 6408 6409 /* 6410 * Clear the dip now. This keeps pmcs_remove_device from attempting 6411 * to call us on the same device while we're still flushing queues. 6412 * The only side effect is we can no longer update SM-HBA properties, 6413 * but this device is going away anyway, so no matter. 6414 */ 6415 xp->dip = NULL; 6416 6417 xp->special_running = 0; 6418 xp->recovering = 0; 6419 xp->recover_wait = 0; 6420 xp->draining = 0; 6421 xp->new = 0; 6422 xp->assigned = 0; 6423 xp->dev_state = 0; 6424 xp->tagmap = 0; 6425 xp->dev_gone = 1; 6426 xp->event_recovery = 0; 6427 xp->dtype = NOTHING; 6428 xp->wq_recovery_tail = NULL; 6429 /* Don't clear xp->phy */ 6430 /* Don't clear xp->actv_cnt */ 6431 6432 /* 6433 * Flush all target queues 6434 */ 6435 pmcs_flush_target_queues(pwp, xp, PMCS_TGT_ALL_QUEUES); 6436 } 6437 6438 static int 6439 pmcs_smp_function_result(pmcs_hw_t *pwp, smp_response_frame_t *srf) 6440 { 6441 int result = srf->srf_result; 6442 6443 switch (result) { 6444 case SMP_RES_UNKNOWN_FUNCTION: 6445 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6446 "%s: SMP DISCOVER Response " 6447 "Function Result: Unknown SMP Function(0x%x)", 6448 __func__, result); 6449 break; 6450 case SMP_RES_FUNCTION_FAILED: 6451 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6452 "%s: SMP DISCOVER Response " 6453 "Function Result: SMP Function Failed(0x%x)", 6454 __func__, result); 6455 break; 6456 case SMP_RES_INVALID_REQUEST_FRAME_LENGTH: 6457 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6458 "%s: SMP DISCOVER Response " 6459 "Function Result: Invalid Request Frame Length(0x%x)", 6460 __func__, result); 6461 break; 6462 case SMP_RES_INCOMPLETE_DESCRIPTOR_LIST: 6463 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6464 "%s: SMP DISCOVER Response " 6465 "Function Result: Incomplete Descriptor List(0x%x)", 6466 __func__, result); 6467 break; 6468 case SMP_RES_PHY_DOES_NOT_EXIST: 6469 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6470 "%s: SMP DISCOVER Response " 6471 "Function Result: PHY does not exist(0x%x)", 6472 __func__, result); 6473 break; 6474 case SMP_RES_PHY_VACANT: 6475 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6476 "%s: SMP DISCOVER Response " 6477 "Function Result: PHY Vacant(0x%x)", 6478 __func__, result); 6479 break; 6480 default: 6481 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6482 "%s: SMP DISCOVER Response " 6483 "Function Result: (0x%x)", 6484 __func__, result); 6485 break; 6486 } 6487 6488 return (result); 6489 } 6490 6491 /* 6492 * Do all the repetitive stuff necessary to setup for DMA 6493 * 6494 * pwp: Used for dip 6495 * dma_attr: ddi_dma_attr_t to use for the mapping 6496 * acch: ddi_acc_handle_t to use for the mapping 6497 * dmah: ddi_dma_handle_t to use 6498 * length: Amount of memory for mapping 6499 * kvp: Pointer filled in with kernel virtual address on successful return 6500 * dma_addr: Pointer filled in with DMA address on successful return 6501 */ 6502 boolean_t 6503 pmcs_dma_setup(pmcs_hw_t *pwp, ddi_dma_attr_t *dma_attr, ddi_acc_handle_t *acch, 6504 ddi_dma_handle_t *dmah, size_t length, caddr_t *kvp, uint64_t *dma_addr) 6505 { 6506 dev_info_t *dip = pwp->dip; 6507 ddi_dma_cookie_t cookie; 6508 size_t real_length; 6509 uint_t ddma_flag = DDI_DMA_CONSISTENT; 6510 uint_t ddabh_flag = DDI_DMA_CONSISTENT | DDI_DMA_RDWR; 6511 uint_t cookie_cnt; 6512 ddi_device_acc_attr_t mattr = { 6513 DDI_DEVICE_ATTR_V0, 6514 DDI_NEVERSWAP_ACC, 6515 DDI_STRICTORDER_ACC, 6516 DDI_DEFAULT_ACC 6517 }; 6518 6519 *acch = NULL; 6520 *dmah = NULL; 6521 6522 if (ddi_dma_alloc_handle(dip, dma_attr, DDI_DMA_SLEEP, NULL, dmah) != 6523 DDI_SUCCESS) { 6524 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6525 "Failed to allocate DMA handle"); 6526 return (B_FALSE); 6527 } 6528 6529 if (ddi_dma_mem_alloc(*dmah, length, &mattr, ddma_flag, DDI_DMA_SLEEP, 6530 NULL, kvp, &real_length, acch) != DDI_SUCCESS) { 6531 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6532 "Failed to allocate DMA mem"); 6533 ddi_dma_free_handle(dmah); 6534 *dmah = NULL; 6535 return (B_FALSE); 6536 } 6537 6538 if (ddi_dma_addr_bind_handle(*dmah, NULL, *kvp, real_length, 6539 ddabh_flag, DDI_DMA_SLEEP, NULL, &cookie, &cookie_cnt) 6540 != DDI_DMA_MAPPED) { 6541 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "Failed to bind DMA"); 6542 ddi_dma_free_handle(dmah); 6543 ddi_dma_mem_free(acch); 6544 *dmah = NULL; 6545 *acch = NULL; 6546 return (B_FALSE); 6547 } 6548 6549 if (cookie_cnt != 1) { 6550 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "Multiple cookies"); 6551 if (ddi_dma_unbind_handle(*dmah) != DDI_SUCCESS) { 6552 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "Condition " 6553 "failed at %s():%d", __func__, __LINE__); 6554 } 6555 ddi_dma_free_handle(dmah); 6556 ddi_dma_mem_free(acch); 6557 *dmah = NULL; 6558 *acch = NULL; 6559 return (B_FALSE); 6560 } 6561 6562 *dma_addr = cookie.dmac_laddress; 6563 6564 return (B_TRUE); 6565 } 6566 6567 /* 6568 * Flush requested queues for a particular target. Called with statlock held 6569 */ 6570 void 6571 pmcs_flush_target_queues(pmcs_hw_t *pwp, pmcs_xscsi_t *tgt, uint8_t queues) 6572 { 6573 pmcs_cmd_t *sp; 6574 pmcwork_t *pwrk; 6575 6576 ASSERT(pwp != NULL); 6577 ASSERT(tgt != NULL); 6578 6579 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, tgt, 6580 "%s: Flushing queues (%d) for target 0x%p", __func__, 6581 queues, (void *)tgt); 6582 6583 /* 6584 * Commands on the wait queue (or the special queue below) don't have 6585 * work structures associated with them. 6586 */ 6587 if (queues & PMCS_TGT_WAIT_QUEUE) { 6588 mutex_enter(&tgt->wqlock); 6589 while ((sp = STAILQ_FIRST(&tgt->wq)) != NULL) { 6590 STAILQ_REMOVE(&tgt->wq, sp, pmcs_cmd, cmd_next); 6591 pmcs_prt(pwp, PMCS_PRT_DEBUG1, NULL, tgt, 6592 "%s: Removing cmd 0x%p from wq for target 0x%p", 6593 __func__, (void *)sp, (void *)tgt); 6594 CMD2PKT(sp)->pkt_reason = CMD_DEV_GONE; 6595 CMD2PKT(sp)->pkt_state = STATE_GOT_BUS; 6596 mutex_exit(&tgt->wqlock); 6597 pmcs_dma_unload(pwp, sp); 6598 mutex_enter(&pwp->cq_lock); 6599 STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next); 6600 mutex_exit(&pwp->cq_lock); 6601 mutex_enter(&tgt->wqlock); 6602 } 6603 mutex_exit(&tgt->wqlock); 6604 } 6605 6606 /* 6607 * Commands on the active queue will have work structures associated 6608 * with them. 6609 */ 6610 if (queues & PMCS_TGT_ACTIVE_QUEUE) { 6611 mutex_enter(&tgt->aqlock); 6612 while ((sp = STAILQ_FIRST(&tgt->aq)) != NULL) { 6613 STAILQ_REMOVE(&tgt->aq, sp, pmcs_cmd, cmd_next); 6614 pwrk = pmcs_tag2wp(pwp, sp->cmd_tag); 6615 mutex_exit(&tgt->aqlock); 6616 mutex_exit(&tgt->statlock); 6617 /* 6618 * If we found a work structure, mark it as dead 6619 * and complete it 6620 */ 6621 if (pwrk != NULL) { 6622 pwrk->dead = 1; 6623 CMD2PKT(sp)->pkt_reason = CMD_DEV_GONE; 6624 CMD2PKT(sp)->pkt_state = STATE_GOT_BUS; 6625 pmcs_complete_work_impl(pwp, pwrk, NULL, 0); 6626 } 6627 pmcs_prt(pwp, PMCS_PRT_DEBUG1, NULL, tgt, 6628 "%s: Removing cmd 0x%p from aq for target 0x%p", 6629 __func__, (void *)sp, (void *)tgt); 6630 pmcs_dma_unload(pwp, sp); 6631 mutex_enter(&pwp->cq_lock); 6632 STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next); 6633 mutex_exit(&pwp->cq_lock); 6634 mutex_enter(&tgt->aqlock); 6635 mutex_enter(&tgt->statlock); 6636 } 6637 mutex_exit(&tgt->aqlock); 6638 } 6639 6640 if (queues & PMCS_TGT_SPECIAL_QUEUE) { 6641 while ((sp = STAILQ_FIRST(&tgt->sq)) != NULL) { 6642 STAILQ_REMOVE(&tgt->sq, sp, pmcs_cmd, cmd_next); 6643 pmcs_prt(pwp, PMCS_PRT_DEBUG1, NULL, tgt, 6644 "%s: Removing cmd 0x%p from sq for target 0x%p", 6645 __func__, (void *)sp, (void *)tgt); 6646 CMD2PKT(sp)->pkt_reason = CMD_DEV_GONE; 6647 CMD2PKT(sp)->pkt_state = STATE_GOT_BUS; 6648 pmcs_dma_unload(pwp, sp); 6649 mutex_enter(&pwp->cq_lock); 6650 STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next); 6651 mutex_exit(&pwp->cq_lock); 6652 } 6653 } 6654 } 6655 6656 void 6657 pmcs_complete_work_impl(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *iomb, 6658 size_t amt) 6659 { 6660 switch (PMCS_TAG_TYPE(pwrk->htag)) { 6661 case PMCS_TAG_TYPE_CBACK: 6662 { 6663 pmcs_cb_t callback = (pmcs_cb_t)pwrk->ptr; 6664 (*callback)(pwp, pwrk, iomb); 6665 break; 6666 } 6667 case PMCS_TAG_TYPE_WAIT: 6668 if (pwrk->arg && iomb && amt) { 6669 (void) memcpy(pwrk->arg, iomb, amt); 6670 } 6671 cv_signal(&pwrk->sleep_cv); 6672 mutex_exit(&pwrk->lock); 6673 break; 6674 case PMCS_TAG_TYPE_NONE: 6675 #ifdef DEBUG 6676 pmcs_check_iomb_status(pwp, iomb); 6677 #endif 6678 pmcs_pwork(pwp, pwrk); 6679 break; 6680 default: 6681 /* 6682 * We will leak a structure here if we don't know 6683 * what happened 6684 */ 6685 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 6686 "%s: Unknown PMCS_TAG_TYPE (%x)", 6687 __func__, PMCS_TAG_TYPE(pwrk->htag)); 6688 break; 6689 } 6690 } 6691 6692 /* 6693 * Determine if iport still has targets. During detach(9E), if SCSA is 6694 * successfull in its guarantee of tran_tgt_free(9E) before detach(9E), 6695 * this should always return B_FALSE. 6696 */ 6697 boolean_t 6698 pmcs_iport_has_targets(pmcs_hw_t *pwp, pmcs_iport_t *iport) 6699 { 6700 pmcs_xscsi_t *xp; 6701 int i; 6702 6703 mutex_enter(&pwp->lock); 6704 6705 if (!pwp->targets || !pwp->max_dev) { 6706 mutex_exit(&pwp->lock); 6707 return (B_FALSE); 6708 } 6709 6710 for (i = 0; i < pwp->max_dev; i++) { 6711 xp = pwp->targets[i]; 6712 if ((xp == NULL) || (xp->phy == NULL) || 6713 (xp->phy->iport != iport)) { 6714 continue; 6715 } 6716 6717 mutex_exit(&pwp->lock); 6718 return (B_TRUE); 6719 } 6720 6721 mutex_exit(&pwp->lock); 6722 return (B_FALSE); 6723 } 6724 6725 /* 6726 * Called with softstate lock held 6727 */ 6728 void 6729 pmcs_destroy_target(pmcs_xscsi_t *target) 6730 { 6731 pmcs_hw_t *pwp = target->pwp; 6732 pmcs_iport_t *iport; 6733 6734 ASSERT(pwp); 6735 ASSERT(mutex_owned(&pwp->lock)); 6736 6737 if (!target->ua) { 6738 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, target, 6739 "%s: target %p iport address is null", 6740 __func__, (void *)target); 6741 } 6742 6743 iport = pmcs_get_iport_by_ua(pwp, target->ua); 6744 if (iport == NULL) { 6745 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, target, 6746 "%s: no iport associated with tgt(0x%p)", 6747 __func__, (void *)target); 6748 return; 6749 } 6750 6751 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, target, 6752 "%s: free target %p", __func__, (void *)target); 6753 if (target->ua) { 6754 strfree(target->ua); 6755 } 6756 6757 mutex_destroy(&target->wqlock); 6758 mutex_destroy(&target->aqlock); 6759 mutex_destroy(&target->statlock); 6760 cv_destroy(&target->reset_cv); 6761 cv_destroy(&target->abort_cv); 6762 ddi_soft_state_bystr_fini(&target->lun_sstate); 6763 ddi_soft_state_bystr_free(iport->tgt_sstate, target->unit_address); 6764 pmcs_rele_iport(iport); 6765 } 6766 6767 /* 6768 * Get device state. Called with statlock and PHY lock held. 6769 */ 6770 int 6771 pmcs_get_dev_state(pmcs_hw_t *pwp, pmcs_xscsi_t *xp, uint8_t *ds) 6772 { 6773 uint32_t htag, *ptr, msg[PMCS_MSG_SIZE]; 6774 int result; 6775 struct pmcwork *pwrk; 6776 pmcs_phy_t *phyp; 6777 6778 pmcs_prt(pwp, PMCS_PRT_DEBUG3, NULL, xp, "%s: tgt(0x%p)", __func__, 6779 (void *)xp); 6780 if (xp == NULL) { 6781 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp, 6782 "%s: Target is NULL", __func__); 6783 return (-1); 6784 } 6785 6786 ASSERT(mutex_owned(&xp->statlock)); 6787 phyp = xp->phy; 6788 ASSERT(mutex_owned(&phyp->phy_lock)); 6789 6790 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, phyp); 6791 if (pwrk == NULL) { 6792 pmcs_prt(pwp, PMCS_PRT_ERR, phyp, xp, pmcs_nowrk, __func__); 6793 return (-1); 6794 } 6795 pwrk->arg = msg; 6796 pwrk->dtype = phyp->dtype; 6797 6798 if (phyp->valid_device_id == 0) { 6799 pmcs_pwork(pwp, pwrk); 6800 pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, xp, 6801 "%s: Invalid DeviceID", __func__); 6802 return (-1); 6803 } 6804 htag = pwrk->htag; 6805 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 6806 PMCIN_GET_DEVICE_STATE)); 6807 msg[1] = LE_32(pwrk->htag); 6808 msg[2] = LE_32(phyp->device_id); 6809 6810 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 6811 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 6812 if (ptr == NULL) { 6813 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 6814 pmcs_pwork(pwp, pwrk); 6815 pmcs_prt(pwp, PMCS_PRT_ERR, phyp, xp, pmcs_nomsg, __func__); 6816 return (-1); 6817 } 6818 COPY_MESSAGE(ptr, msg, PMCS_MSG_SIZE); 6819 pwrk->state = PMCS_WORK_STATE_ONCHIP; 6820 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 6821 mutex_exit(&xp->statlock); 6822 pmcs_unlock_phy(phyp); 6823 WAIT_FOR(pwrk, 1000, result); 6824 pmcs_lock_phy(phyp); 6825 pmcs_pwork(pwp, pwrk); 6826 mutex_enter(&xp->statlock); 6827 6828 if (result) { 6829 pmcs_timed_out(pwp, htag, __func__); 6830 pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, xp, 6831 "%s: cmd timed out, returning ", __func__); 6832 return (-1); 6833 } 6834 if (LE_32(msg[2]) == 0) { 6835 *ds = (uint8_t)(LE_32(msg[4])); 6836 if (*ds != xp->dev_state) { 6837 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, phyp, xp, 6838 "%s: retrieved_ds=0x%x, target_ds=0x%x", __func__, 6839 *ds, xp->dev_state); 6840 } 6841 return (0); 6842 } else { 6843 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, phyp, xp, 6844 "%s: cmd failed Status(0x%x), returning ", __func__, 6845 LE_32(msg[2])); 6846 return (-1); 6847 } 6848 } 6849 6850 /* 6851 * Set device state. Called with target's statlock and PHY lock held. 6852 */ 6853 int 6854 pmcs_set_dev_state(pmcs_hw_t *pwp, pmcs_xscsi_t *xp, uint8_t ds) 6855 { 6856 uint32_t htag, *ptr, msg[PMCS_MSG_SIZE]; 6857 int result; 6858 uint8_t pds, nds; 6859 struct pmcwork *pwrk; 6860 pmcs_phy_t *phyp; 6861 6862 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, NULL, xp, 6863 "%s: ds(0x%x), tgt(0x%p)", __func__, ds, (void *)xp); 6864 if (xp == NULL) { 6865 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp, 6866 "%s: Target is Null", __func__); 6867 return (-1); 6868 } 6869 6870 phyp = xp->phy; 6871 pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, phyp); 6872 if (pwrk == NULL) { 6873 pmcs_prt(pwp, PMCS_PRT_ERR, phyp, xp, pmcs_nowrk, __func__); 6874 return (-1); 6875 } 6876 if (phyp == NULL) { 6877 pmcs_pwork(pwp, pwrk); 6878 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, phyp, xp, 6879 "%s: PHY is Null", __func__); 6880 return (-1); 6881 } 6882 if (phyp->valid_device_id == 0) { 6883 pmcs_pwork(pwp, pwrk); 6884 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, phyp, xp, 6885 "%s: Invalid DeviceID", __func__); 6886 return (-1); 6887 } 6888 pwrk->arg = msg; 6889 pwrk->dtype = phyp->dtype; 6890 htag = pwrk->htag; 6891 msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, 6892 PMCIN_SET_DEVICE_STATE)); 6893 msg[1] = LE_32(pwrk->htag); 6894 msg[2] = LE_32(phyp->device_id); 6895 msg[3] = LE_32(ds); 6896 6897 mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]); 6898 ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 6899 if (ptr == NULL) { 6900 mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]); 6901 pmcs_pwork(pwp, pwrk); 6902 pmcs_prt(pwp, PMCS_PRT_ERR, phyp, xp, pmcs_nomsg, __func__); 6903 return (-1); 6904 } 6905 COPY_MESSAGE(ptr, msg, PMCS_MSG_SIZE); 6906 pwrk->state = PMCS_WORK_STATE_ONCHIP; 6907 INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER); 6908 6909 mutex_exit(&xp->statlock); 6910 pmcs_unlock_phy(phyp); 6911 WAIT_FOR(pwrk, 1000, result); 6912 pmcs_lock_phy(phyp); 6913 pmcs_pwork(pwp, pwrk); 6914 mutex_enter(&xp->statlock); 6915 6916 if (result) { 6917 pmcs_timed_out(pwp, htag, __func__); 6918 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, phyp, xp, 6919 "%s: cmd timed out, returning", __func__); 6920 return (-1); 6921 } 6922 if (LE_32(msg[2]) == 0) { 6923 pds = (uint8_t)(LE_32(msg[4]) >> 4); 6924 nds = (uint8_t)(LE_32(msg[4]) & 0x0000000f); 6925 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, phyp, xp, 6926 "%s: previous_ds=0x%x, new_ds=0x%x", __func__, pds, nds); 6927 xp->dev_state = nds; 6928 return (0); 6929 } else { 6930 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, phyp, xp, 6931 "%s: cmd failed Status(0x%x), returning ", __func__, 6932 LE_32(msg[2])); 6933 return (-1); 6934 } 6935 } 6936 6937 void 6938 pmcs_dev_state_recovery(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 6939 { 6940 uint8_t ds; 6941 int rc; 6942 pmcs_xscsi_t *tgt; 6943 pmcs_phy_t *pptr, *pnext, *pchild; 6944 6945 /* 6946 * First time, check to see if we're already performing recovery 6947 */ 6948 if (phyp == NULL) { 6949 mutex_enter(&pwp->lock); 6950 if (pwp->ds_err_recovering) { 6951 mutex_exit(&pwp->lock); 6952 SCHEDULE_WORK(pwp, PMCS_WORK_DS_ERR_RECOVERY); 6953 return; 6954 } 6955 6956 pwp->ds_err_recovering = 1; 6957 pptr = pwp->root_phys; 6958 mutex_exit(&pwp->lock); 6959 } else { 6960 pptr = phyp; 6961 } 6962 6963 while (pptr) { 6964 /* 6965 * Since ds_err_recovering is set, we can be assured these 6966 * PHYs won't disappear on us while we do this. 6967 */ 6968 pmcs_lock_phy(pptr); 6969 pchild = pptr->children; 6970 pnext = pptr->sibling; 6971 pmcs_unlock_phy(pptr); 6972 6973 if (pchild) { 6974 pmcs_dev_state_recovery(pwp, pchild); 6975 } 6976 6977 tgt = NULL; 6978 pmcs_lock_phy(pptr); 6979 6980 if (pptr->dead) { 6981 goto next_phy; 6982 } 6983 6984 tgt = pptr->target; 6985 if (tgt == NULL || tgt->dev_gone) { 6986 if (pptr->dtype != NOTHING) { 6987 pmcs_prt(pwp, PMCS_PRT_DEBUG2, pptr, tgt, 6988 "%s: no target for DS error recovery for " 6989 "PHY 0x%p", __func__, (void *)pptr); 6990 } 6991 goto next_phy; 6992 } 6993 6994 mutex_enter(&tgt->statlock); 6995 6996 if (tgt->recover_wait == 0) { 6997 goto next_phy; 6998 } 6999 7000 /* 7001 * Step 1: Put the device into the IN_RECOVERY state 7002 */ 7003 rc = pmcs_get_dev_state(pwp, tgt, &ds); 7004 if (rc != 0) { 7005 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 7006 "%s: pmcs_get_dev_state on PHY %s " 7007 "failed (rc=%d)", 7008 __func__, pptr->path, rc); 7009 7010 pmcs_handle_ds_recovery_error(pptr, tgt, pwp, 7011 __func__, __LINE__, "pmcs_get_dev_state"); 7012 7013 goto next_phy; 7014 } 7015 7016 if ((tgt->dev_state == ds) && 7017 (ds == PMCS_DEVICE_STATE_IN_RECOVERY)) { 7018 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7019 "%s: Target 0x%p already IN_RECOVERY", __func__, 7020 (void *)tgt); 7021 } else { 7022 tgt->dev_state = ds; 7023 ds = PMCS_DEVICE_STATE_IN_RECOVERY; 7024 rc = pmcs_send_err_recovery_cmd(pwp, ds, tgt); 7025 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7026 "%s: pmcs_send_err_recovery_cmd " 7027 "result(%d) tgt(0x%p) ds(0x%x) tgt->ds(0x%x)", 7028 __func__, rc, (void *)tgt, ds, tgt->dev_state); 7029 7030 if (rc) { 7031 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 7032 "%s: pmcs_send_err_recovery_cmd to PHY %s " 7033 "failed (rc=%d)", 7034 __func__, pptr->path, rc); 7035 7036 pmcs_handle_ds_recovery_error(pptr, tgt, pwp, 7037 __func__, __LINE__, 7038 "pmcs_send_err_recovery_cmd"); 7039 7040 goto next_phy; 7041 } 7042 } 7043 7044 /* 7045 * Step 2: Perform a hard reset on the PHY 7046 */ 7047 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7048 "%s: Issue HARD_RESET to PHY %s", __func__, pptr->path); 7049 /* 7050 * Must release statlock here because pmcs_reset_phy will 7051 * drop and reacquire the PHY lock. 7052 */ 7053 mutex_exit(&tgt->statlock); 7054 rc = pmcs_reset_phy(pwp, pptr, PMCS_PHYOP_HARD_RESET); 7055 mutex_enter(&tgt->statlock); 7056 if (rc) { 7057 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 7058 "%s: HARD_RESET to PHY %s failed (rc=%d)", 7059 __func__, pptr->path, rc); 7060 7061 pmcs_handle_ds_recovery_error(pptr, tgt, pwp, 7062 __func__, __LINE__, "HARD_RESET"); 7063 7064 goto next_phy; 7065 } 7066 7067 /* 7068 * Step 3: Abort all I/Os to the device 7069 */ 7070 if (pptr->abort_all_start) { 7071 while (pptr->abort_all_start) { 7072 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 7073 "%s: Waiting for outstanding ABORT_ALL on " 7074 "PHY 0x%p", __func__, (void *)pptr); 7075 cv_wait(&pptr->abort_all_cv, &pptr->phy_lock); 7076 } 7077 } else { 7078 mutex_exit(&tgt->statlock); 7079 rc = pmcs_abort(pwp, pptr, pptr->device_id, 1, 1); 7080 mutex_enter(&tgt->statlock); 7081 if (rc != 0) { 7082 pptr->abort_pending = 1; 7083 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 7084 "%s: pmcs_abort to PHY %s failed (rc=%d)", 7085 __func__, pptr->path, rc); 7086 7087 pmcs_handle_ds_recovery_error(pptr, tgt, 7088 pwp, __func__, __LINE__, "pmcs_abort"); 7089 7090 goto next_phy; 7091 } 7092 } 7093 7094 /* 7095 * Step 4: Set the device back to OPERATIONAL state 7096 */ 7097 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7098 "%s: Set PHY/tgt 0x%p/0x%p to OPERATIONAL state", 7099 __func__, (void *)pptr, (void *)tgt); 7100 rc = pmcs_set_dev_state(pwp, tgt, 7101 PMCS_DEVICE_STATE_OPERATIONAL); 7102 if (rc == 0) { 7103 tgt->recover_wait = 0; 7104 pptr->ds_recovery_retries = 0; 7105 /* 7106 * Don't bother to run the work queues if the PHY 7107 * is dead. 7108 */ 7109 if (tgt->phy && !tgt->phy->dead) { 7110 SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES); 7111 (void) ddi_taskq_dispatch(pwp->tq, pmcs_worker, 7112 pwp, DDI_NOSLEEP); 7113 } 7114 } else { 7115 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7116 "%s: Failed to SET tgt 0x%p to OPERATIONAL state", 7117 __func__, (void *)tgt); 7118 7119 pmcs_handle_ds_recovery_error(pptr, tgt, pwp, 7120 __func__, __LINE__, "SET tgt to OPERATIONAL state"); 7121 7122 goto next_phy; 7123 } 7124 7125 next_phy: 7126 if (tgt) { 7127 mutex_exit(&tgt->statlock); 7128 } 7129 pmcs_unlock_phy(pptr); 7130 pptr = pnext; 7131 } 7132 7133 /* 7134 * Only clear ds_err_recovering if we're exiting for good and not 7135 * just unwinding from recursion 7136 */ 7137 if (phyp == NULL) { 7138 mutex_enter(&pwp->lock); 7139 pwp->ds_err_recovering = 0; 7140 mutex_exit(&pwp->lock); 7141 } 7142 } 7143 7144 /* 7145 * Called with target's statlock and PHY lock held. 7146 */ 7147 int 7148 pmcs_send_err_recovery_cmd(pmcs_hw_t *pwp, uint8_t dev_state, pmcs_xscsi_t *tgt) 7149 { 7150 pmcs_phy_t *pptr; 7151 int rc = -1; 7152 7153 ASSERT(tgt != NULL); 7154 ASSERT(mutex_owned(&tgt->statlock)); 7155 7156 if (tgt->recovering) { 7157 return (0); 7158 } 7159 7160 tgt->recovering = 1; 7161 pptr = tgt->phy; 7162 7163 if (pptr == NULL) { 7164 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7165 "%s: PHY is Null", __func__); 7166 return (-1); 7167 } 7168 7169 ASSERT(mutex_owned(&pptr->phy_lock)); 7170 7171 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7172 "%s: ds: 0x%x, tgt ds(0x%x)", __func__, dev_state, tgt->dev_state); 7173 7174 switch (dev_state) { 7175 case PMCS_DEVICE_STATE_IN_RECOVERY: 7176 if (tgt->dev_state == PMCS_DEVICE_STATE_IN_RECOVERY) { 7177 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7178 "%s: Target 0x%p already IN_RECOVERY", __func__, 7179 (void *)tgt); 7180 rc = 0; /* This is not an error */ 7181 goto no_action; 7182 } 7183 7184 rc = pmcs_set_dev_state(pwp, tgt, 7185 PMCS_DEVICE_STATE_IN_RECOVERY); 7186 if (rc != 0) { 7187 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7188 "%s(1): Failed to SET tgt(0x%p) to _IN_RECOVERY", 7189 __func__, (void *)tgt); 7190 } 7191 7192 break; 7193 7194 case PMCS_DEVICE_STATE_OPERATIONAL: 7195 if (tgt->dev_state != PMCS_DEVICE_STATE_IN_RECOVERY) { 7196 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7197 "%s: Target 0x%p not ready to go OPERATIONAL", 7198 __func__, (void *)tgt); 7199 goto no_action; 7200 } 7201 7202 rc = pmcs_set_dev_state(pwp, tgt, 7203 PMCS_DEVICE_STATE_OPERATIONAL); 7204 tgt->reset_success = 1; 7205 if (rc != 0) { 7206 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7207 "%s(2): Failed to SET tgt(0x%p) to OPERATIONAL", 7208 __func__, (void *)tgt); 7209 tgt->reset_success = 0; 7210 } 7211 7212 break; 7213 7214 case PMCS_DEVICE_STATE_NON_OPERATIONAL: 7215 PHY_CHANGED(pwp, pptr); 7216 RESTART_DISCOVERY(pwp); 7217 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7218 "%s: Device at %s is non-operational", 7219 __func__, pptr->path); 7220 tgt->dev_state = PMCS_DEVICE_STATE_NON_OPERATIONAL; 7221 rc = 0; 7222 7223 break; 7224 7225 default: 7226 pmcs_prt(pwp, PMCS_PRT_DEBUG_DEV_STATE, pptr, tgt, 7227 "%s: Invalid state requested (%d)", __func__, 7228 dev_state); 7229 break; 7230 7231 } 7232 7233 no_action: 7234 tgt->recovering = 0; 7235 return (rc); 7236 } 7237 7238 /* 7239 * pmcs_lock_phy_impl 7240 * 7241 * This function is what does the actual work for pmcs_lock_phy. It will 7242 * lock all PHYs from phyp down in a top-down fashion. 7243 * 7244 * Locking notes: 7245 * 1. level starts from 0 for the PHY ("parent") that's passed in. It is 7246 * not a reflection of the actual level of the PHY in the SAS topology. 7247 * 2. If parent is an expander, then parent is locked along with all its 7248 * descendents. 7249 * 3. Expander subsidiary PHYs at level 0 are not locked. It is the 7250 * responsibility of the caller to individually lock expander subsidiary PHYs 7251 * at level 0 if necessary. 7252 * 4. Siblings at level 0 are not traversed due to the possibility that we're 7253 * locking a PHY on the dead list. The siblings could be pointing to invalid 7254 * PHYs. We don't lock siblings at level 0 anyway. 7255 */ 7256 static void 7257 pmcs_lock_phy_impl(pmcs_phy_t *phyp, int level) 7258 { 7259 pmcs_phy_t *tphyp; 7260 7261 ASSERT((phyp->dtype == SAS) || (phyp->dtype == SATA) || 7262 (phyp->dtype == EXPANDER) || (phyp->dtype == NOTHING)); 7263 7264 /* 7265 * Start walking the PHYs. 7266 */ 7267 tphyp = phyp; 7268 while (tphyp) { 7269 /* 7270 * If we're at the top level, only lock ourselves. For anything 7271 * at level > 0, traverse children while locking everything. 7272 */ 7273 if ((level > 0) || (tphyp == phyp)) { 7274 pmcs_prt(tphyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, tphyp, 7275 NULL, "%s: PHY 0x%p parent 0x%p path %s lvl %d", 7276 __func__, (void *)tphyp, (void *)tphyp->parent, 7277 tphyp->path, level); 7278 mutex_enter(&tphyp->phy_lock); 7279 7280 if (tphyp->children) { 7281 pmcs_lock_phy_impl(tphyp->children, level + 1); 7282 } 7283 } 7284 7285 if (level == 0) { 7286 return; 7287 } 7288 7289 tphyp = tphyp->sibling; 7290 } 7291 } 7292 7293 /* 7294 * pmcs_lock_phy 7295 * 7296 * This function is responsible for locking a PHY and all its descendents 7297 */ 7298 void 7299 pmcs_lock_phy(pmcs_phy_t *phyp) 7300 { 7301 #ifdef DEBUG 7302 char *callername = NULL; 7303 ulong_t off; 7304 7305 ASSERT(phyp != NULL); 7306 7307 callername = modgetsymname((uintptr_t)caller(), &off); 7308 7309 if (callername == NULL) { 7310 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7311 "%s: PHY 0x%p path %s caller: unknown", __func__, 7312 (void *)phyp, phyp->path); 7313 } else { 7314 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7315 "%s: PHY 0x%p path %s caller: %s+%lx", __func__, 7316 (void *)phyp, phyp->path, callername, off); 7317 } 7318 #else 7319 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7320 "%s: PHY 0x%p path %s", __func__, (void *)phyp, phyp->path); 7321 #endif 7322 pmcs_lock_phy_impl(phyp, 0); 7323 } 7324 7325 /* 7326 * pmcs_unlock_phy_impl 7327 * 7328 * Unlock all PHYs from phyp down in a bottom-up fashion. 7329 */ 7330 static void 7331 pmcs_unlock_phy_impl(pmcs_phy_t *phyp, int level) 7332 { 7333 pmcs_phy_t *phy_next; 7334 7335 ASSERT((phyp->dtype == SAS) || (phyp->dtype == SATA) || 7336 (phyp->dtype == EXPANDER) || (phyp->dtype == NOTHING)); 7337 7338 /* 7339 * Recurse down to the bottom PHYs 7340 */ 7341 if (level == 0) { 7342 if (phyp->children) { 7343 pmcs_unlock_phy_impl(phyp->children, level + 1); 7344 } 7345 } else { 7346 phy_next = phyp; 7347 while (phy_next) { 7348 if (phy_next->children) { 7349 pmcs_unlock_phy_impl(phy_next->children, 7350 level + 1); 7351 } 7352 phy_next = phy_next->sibling; 7353 } 7354 } 7355 7356 /* 7357 * Iterate through PHYs unlocking all at level > 0 as well the top PHY 7358 */ 7359 phy_next = phyp; 7360 while (phy_next) { 7361 if ((level > 0) || (phy_next == phyp)) { 7362 pmcs_prt(phy_next->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, 7363 phy_next, NULL, 7364 "%s: PHY 0x%p parent 0x%p path %s lvl %d", 7365 __func__, (void *)phy_next, 7366 (void *)phy_next->parent, phy_next->path, level); 7367 mutex_exit(&phy_next->phy_lock); 7368 } 7369 7370 if (level == 0) { 7371 return; 7372 } 7373 7374 phy_next = phy_next->sibling; 7375 } 7376 } 7377 7378 /* 7379 * pmcs_unlock_phy 7380 * 7381 * Unlock a PHY and all its descendents 7382 */ 7383 void 7384 pmcs_unlock_phy(pmcs_phy_t *phyp) 7385 { 7386 #ifdef DEBUG 7387 char *callername = NULL; 7388 ulong_t off; 7389 7390 ASSERT(phyp != NULL); 7391 7392 callername = modgetsymname((uintptr_t)caller(), &off); 7393 7394 if (callername == NULL) { 7395 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7396 "%s: PHY 0x%p path %s caller: unknown", __func__, 7397 (void *)phyp, phyp->path); 7398 } else { 7399 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7400 "%s: PHY 0x%p path %s caller: %s+%lx", __func__, 7401 (void *)phyp, phyp->path, callername, off); 7402 } 7403 #else 7404 pmcs_prt(phyp->pwp, PMCS_PRT_DEBUG_PHY_LOCKING, phyp, NULL, 7405 "%s: PHY 0x%p path %s", __func__, (void *)phyp, phyp->path); 7406 #endif 7407 pmcs_unlock_phy_impl(phyp, 0); 7408 } 7409 7410 /* 7411 * pmcs_get_root_phy 7412 * 7413 * For a given phy pointer return its root phy. 7414 * The caller must be holding the lock on every PHY from phyp up to the root. 7415 */ 7416 pmcs_phy_t * 7417 pmcs_get_root_phy(pmcs_phy_t *phyp) 7418 { 7419 ASSERT(phyp); 7420 7421 while (phyp) { 7422 if (IS_ROOT_PHY(phyp)) { 7423 break; 7424 } 7425 phyp = phyp->parent; 7426 } 7427 7428 return (phyp); 7429 } 7430 7431 /* 7432 * pmcs_free_dma_chunklist 7433 * 7434 * Free DMA S/G chunk list 7435 */ 7436 void 7437 pmcs_free_dma_chunklist(pmcs_hw_t *pwp) 7438 { 7439 pmcs_chunk_t *pchunk; 7440 7441 while (pwp->dma_chunklist) { 7442 pchunk = pwp->dma_chunklist; 7443 pwp->dma_chunklist = pwp->dma_chunklist->next; 7444 if (pchunk->dma_handle) { 7445 if (ddi_dma_unbind_handle(pchunk->dma_handle) != 7446 DDI_SUCCESS) { 7447 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 7448 "Condition failed at %s():%d", 7449 __func__, __LINE__); 7450 } 7451 ddi_dma_free_handle(&pchunk->dma_handle); 7452 ddi_dma_mem_free(&pchunk->acc_handle); 7453 } 7454 kmem_free(pchunk, sizeof (pmcs_chunk_t)); 7455 } 7456 } 7457 7458 7459 /* 7460 * Start ssp event recovery. We have to schedule recovery operation because 7461 * it involves sending multiple commands to device and we should not do it 7462 * in the interrupt context. 7463 * If it is failure of a recovery command, let the recovery thread deal with it. 7464 * Called with pmcwork lock held. 7465 */ 7466 7467 void 7468 pmcs_start_ssp_event_recovery(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *iomb, 7469 size_t amt) 7470 { 7471 pmcs_xscsi_t *tgt = pwrk->xp; 7472 uint32_t event = LE_32(iomb[2]); 7473 pmcs_phy_t *pptr = pwrk->phy; 7474 uint32_t tag; 7475 7476 if (tgt != NULL) { 7477 mutex_enter(&tgt->statlock); 7478 if (!tgt->assigned) { 7479 if (pptr) { 7480 pmcs_dec_phy_ref_count(pptr); 7481 } 7482 pptr = NULL; 7483 pwrk->phy = NULL; 7484 } 7485 mutex_exit(&tgt->statlock); 7486 } 7487 if (pptr == NULL) { 7488 /* 7489 * No target, need to run RE-DISCOVERY here. 7490 */ 7491 if (pwrk->state != PMCS_WORK_STATE_TIMED_OUT) { 7492 pwrk->state = PMCS_WORK_STATE_INTR; 7493 } 7494 /* 7495 * Although we cannot mark phy to force abort nor mark phy 7496 * as changed, killing of a target would take care of aborting 7497 * commands for the device. 7498 */ 7499 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 7500 "%s: No valid target for event processing found. " 7501 "Scheduling RECONFIGURE", __func__); 7502 pmcs_pwork(pwp, pwrk); 7503 RESTART_DISCOVERY(pwp); 7504 return; 7505 } else { 7506 pmcs_lock_phy(pptr); 7507 mutex_enter(&tgt->statlock); 7508 if (event == PMCOUT_STATUS_OPEN_CNX_ERROR_IT_NEXUS_LOSS) { 7509 if (tgt->dev_state != 7510 PMCS_DEVICE_STATE_NON_OPERATIONAL) { 7511 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 7512 "%s: Device at %s is non-operational", 7513 __func__, pptr->path); 7514 tgt->dev_state = 7515 PMCS_DEVICE_STATE_NON_OPERATIONAL; 7516 } 7517 pptr->abort_pending = 1; 7518 mutex_exit(&tgt->statlock); 7519 pmcs_unlock_phy(pptr); 7520 mutex_exit(&pwrk->lock); 7521 SCHEDULE_WORK(pwp, PMCS_WORK_ABORT_HANDLE); 7522 RESTART_DISCOVERY(pwp); 7523 return; 7524 } 7525 7526 /* 7527 * If this command is run in WAIT mode, it is a failing recovery 7528 * command. If so, just wake up recovery thread waiting for 7529 * command completion. 7530 */ 7531 tag = PMCS_TAG_TYPE(pwrk->htag); 7532 if (tag == PMCS_TAG_TYPE_WAIT) { 7533 pwrk->htag |= PMCS_TAG_DONE; 7534 if (pwrk->arg && amt) { 7535 (void) memcpy(pwrk->arg, iomb, amt); 7536 } 7537 cv_signal(&pwrk->sleep_cv); 7538 mutex_exit(&tgt->statlock); 7539 pmcs_unlock_phy(pptr); 7540 mutex_exit(&pwrk->lock); 7541 return; 7542 } 7543 7544 /* 7545 * To recover from primary failures, 7546 * we need to schedule handling events recovery. 7547 */ 7548 tgt->event_recovery = 1; 7549 mutex_exit(&tgt->statlock); 7550 pmcs_unlock_phy(pptr); 7551 pwrk->ssp_event = event; 7552 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 7553 "%s: Scheduling SSP event recovery for tgt(0x%p) " 7554 "pwrk(%p) tag(0x%x)", __func__, (void *)tgt, (void *)pwrk, 7555 pwrk->htag); 7556 mutex_exit(&pwrk->lock); 7557 SCHEDULE_WORK(pwp, PMCS_WORK_SSP_EVT_RECOVERY); 7558 } 7559 7560 /* Work cannot be completed until event recovery is completed. */ 7561 } 7562 7563 /* 7564 * SSP target event recovery 7565 * Entered with a phy lock held 7566 * Pwrk lock is not needed - pwrk is on the target aq and no other thread 7567 * will do anything with it until this thread starts the chain of recovery. 7568 * Statlock may be acquired and released. 7569 */ 7570 7571 void 7572 pmcs_tgt_event_recovery(pmcs_hw_t *pwp, pmcwork_t *pwrk) 7573 { 7574 pmcs_phy_t *pptr = pwrk->phy; 7575 pmcs_cmd_t *sp = pwrk->arg; 7576 pmcs_lun_t *lun = sp->cmd_lun; 7577 pmcs_xscsi_t *tgt = pwrk->xp; 7578 uint32_t event; 7579 uint32_t htag; 7580 uint32_t status; 7581 uint8_t dstate; 7582 int rv; 7583 7584 ASSERT(pwrk->arg != NULL); 7585 ASSERT(pwrk->xp != NULL); 7586 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, "%s: event recovery for " 7587 "target 0x%p", __func__, (void *)pwrk->xp); 7588 htag = pwrk->htag; 7589 event = pwrk->ssp_event; 7590 pwrk->ssp_event = 0xffffffff; 7591 if (event == PMCOUT_STATUS_XFER_ERR_BREAK || 7592 event == PMCOUT_STATUS_XFER_ERR_PHY_NOT_READY || 7593 event == PMCOUT_STATUS_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT) { 7594 /* Command may be still pending on device */ 7595 rv = pmcs_ssp_tmf(pwp, pptr, SAS_QUERY_TASK, htag, 7596 lun->lun_num, &status); 7597 if (rv != 0) { 7598 goto out; 7599 } 7600 if (status == SAS_RSP_TMF_COMPLETE) { 7601 /* Command NOT pending on a device */ 7602 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 7603 "%s: No pending command for tgt 0x%p", 7604 __func__, (void *)tgt); 7605 /* Nothing more to do, just abort it on chip */ 7606 htag = 0; 7607 } 7608 } 7609 /* 7610 * All other events left the command pending in the host 7611 * Send abort task and abort it on the chip 7612 */ 7613 if (htag != 0) { 7614 if (pmcs_ssp_tmf(pwp, pptr, SAS_ABORT_TASK, htag, 7615 lun->lun_num, &status)) 7616 goto out; 7617 } 7618 (void) pmcs_abort(pwp, pptr, pwrk->htag, 0, 1); 7619 /* 7620 * Abort either took care of work completion, or put device in 7621 * a recovery state 7622 */ 7623 return; 7624 out: 7625 /* Abort failed, do full device recovery */ 7626 mutex_enter(&tgt->statlock); 7627 if (!pmcs_get_dev_state(pwp, tgt, &dstate)) 7628 tgt->dev_state = dstate; 7629 7630 if ((tgt->dev_state != PMCS_DEVICE_STATE_IN_RECOVERY) && 7631 (tgt->dev_state != PMCS_DEVICE_STATE_NON_OPERATIONAL)) { 7632 pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, tgt, 7633 "%s: Setting IN_RECOVERY for tgt 0x%p", 7634 __func__, (void *)tgt); 7635 (void) pmcs_send_err_recovery_cmd(pwp, 7636 PMCS_DEVICE_STATE_IN_RECOVERY, tgt); 7637 } 7638 mutex_exit(&tgt->statlock); 7639 } 7640 7641 /* 7642 * SSP event recovery task. 7643 */ 7644 void 7645 pmcs_ssp_event_recovery(pmcs_hw_t *pwp) 7646 { 7647 int idx; 7648 pmcs_xscsi_t *tgt; 7649 pmcs_cmd_t *cp; 7650 pmcwork_t *pwrk; 7651 pmcs_phy_t *pphy; 7652 int er_flag; 7653 uint32_t idxpwrk; 7654 7655 restart: 7656 for (idx = 0; idx < pwp->max_dev; idx++) { 7657 mutex_enter(&pwp->lock); 7658 tgt = pwp->targets[idx]; 7659 mutex_exit(&pwp->lock); 7660 if (tgt != NULL) { 7661 mutex_enter(&tgt->statlock); 7662 if (!tgt->assigned) { 7663 mutex_exit(&tgt->statlock); 7664 continue; 7665 } 7666 pphy = tgt->phy; 7667 er_flag = tgt->event_recovery; 7668 mutex_exit(&tgt->statlock); 7669 if (pphy != NULL && er_flag != 0) { 7670 pmcs_lock_phy(pphy); 7671 mutex_enter(&tgt->statlock); 7672 pmcs_prt(pwp, PMCS_PRT_DEBUG, pphy, tgt, 7673 "%s: found target(0x%p)", __func__, 7674 (void *) tgt); 7675 7676 /* Check what cmd expects recovery */ 7677 mutex_enter(&tgt->aqlock); 7678 STAILQ_FOREACH(cp, &tgt->aq, cmd_next) { 7679 /* 7680 * Since work structure is on this 7681 * target aq, and only this thread 7682 * is accessing it now, we do not need 7683 * to lock it 7684 */ 7685 idxpwrk = PMCS_TAG_INDEX(cp->cmd_tag); 7686 pwrk = &pwp->work[idxpwrk]; 7687 if (pwrk->htag != cp->cmd_tag) { 7688 /* 7689 * aq may contain TMF commands, 7690 * so we may not find work 7691 * structure with htag 7692 */ 7693 break; 7694 } 7695 if (pwrk->ssp_event != 0 && 7696 pwrk->ssp_event != 7697 PMCS_REC_EVENT) { 7698 pmcs_prt(pwp, 7699 PMCS_PRT_DEBUG, pphy, tgt, 7700 "%s: pwrk(%p) ctag(0x%x)", 7701 __func__, (void *) pwrk, 7702 cp->cmd_tag); 7703 mutex_exit(&tgt->aqlock); 7704 mutex_exit(&tgt->statlock); 7705 pmcs_tgt_event_recovery( 7706 pwp, pwrk); 7707 /* 7708 * We dropped statlock, so 7709 * restart scanning from scratch 7710 */ 7711 pmcs_unlock_phy(pphy); 7712 goto restart; 7713 } 7714 } 7715 mutex_exit(&tgt->aqlock); 7716 tgt->event_recovery = 0; 7717 pmcs_prt(pwp, PMCS_PRT_DEBUG, pphy, tgt, 7718 "%s: end of SSP event recovery for " 7719 "target(0x%p)", __func__, (void *) tgt); 7720 mutex_exit(&tgt->statlock); 7721 pmcs_unlock_phy(pphy); 7722 } 7723 } 7724 } 7725 pmcs_prt(pwp, PMCS_PRT_DEBUG, pphy, tgt, "%s: " 7726 "end of SSP event recovery for pwp(0x%p)", __func__, (void *) pwp); 7727 } 7728 7729 /*ARGSUSED2*/ 7730 int 7731 pmcs_phy_constructor(void *buf, void *arg, int kmflags) 7732 { 7733 pmcs_hw_t *pwp = (pmcs_hw_t *)arg; 7734 pmcs_phy_t *phyp = (pmcs_phy_t *)buf; 7735 7736 mutex_init(&phyp->phy_lock, NULL, MUTEX_DRIVER, 7737 DDI_INTR_PRI(pwp->intr_pri)); 7738 cv_init(&phyp->abort_all_cv, NULL, CV_DRIVER, NULL); 7739 return (0); 7740 } 7741 7742 /*ARGSUSED1*/ 7743 void 7744 pmcs_phy_destructor(void *buf, void *arg) 7745 { 7746 pmcs_phy_t *phyp = (pmcs_phy_t *)buf; 7747 7748 cv_destroy(&phyp->abort_all_cv); 7749 mutex_destroy(&phyp->phy_lock); 7750 } 7751 7752 /* 7753 * Free all PHYs from the kmem_cache starting at phyp as well as everything 7754 * on the dead_phys list. 7755 * 7756 * NOTE: This function does not free root PHYs as they are not allocated 7757 * from the kmem_cache. 7758 * 7759 * No PHY locks are acquired as this should only be called during DDI_DETACH 7760 * or soft reset (while pmcs interrupts are disabled). 7761 */ 7762 void 7763 pmcs_free_all_phys(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 7764 { 7765 pmcs_phy_t *tphyp, *nphyp; 7766 7767 if (phyp == NULL) { 7768 return; 7769 } 7770 7771 tphyp = phyp; 7772 while (tphyp) { 7773 nphyp = tphyp->sibling; 7774 7775 if (tphyp->children) { 7776 pmcs_free_all_phys(pwp, tphyp->children); 7777 tphyp->children = NULL; 7778 } 7779 if (!IS_ROOT_PHY(tphyp)) { 7780 kmem_cache_free(pwp->phy_cache, tphyp); 7781 } 7782 7783 tphyp = nphyp; 7784 } 7785 7786 tphyp = pwp->dead_phys; 7787 while (tphyp) { 7788 nphyp = tphyp->sibling; 7789 kmem_cache_free(pwp->phy_cache, tphyp); 7790 tphyp = nphyp; 7791 } 7792 pwp->dead_phys = NULL; 7793 } 7794 7795 /* 7796 * Free a list of PHYs linked together by the sibling pointer back to the 7797 * kmem cache from whence they came. This function does not recurse, so the 7798 * caller must ensure there are no children. 7799 */ 7800 void 7801 pmcs_free_phys(pmcs_hw_t *pwp, pmcs_phy_t *phyp) 7802 { 7803 pmcs_phy_t *next_phy; 7804 7805 while (phyp) { 7806 next_phy = phyp->sibling; 7807 ASSERT(!mutex_owned(&phyp->phy_lock)); 7808 kmem_cache_free(pwp->phy_cache, phyp); 7809 phyp = next_phy; 7810 } 7811 } 7812 7813 /* 7814 * Make a copy of an existing PHY structure. This is used primarily in 7815 * discovery to compare the contents of an existing PHY with what gets 7816 * reported back by an expander. 7817 * 7818 * This function must not be called from any context where sleeping is 7819 * not possible. 7820 * 7821 * The new PHY is returned unlocked. 7822 */ 7823 static pmcs_phy_t * 7824 pmcs_clone_phy(pmcs_phy_t *orig_phy) 7825 { 7826 pmcs_phy_t *local; 7827 7828 local = kmem_cache_alloc(orig_phy->pwp->phy_cache, KM_SLEEP); 7829 7830 /* 7831 * Go ahead and just copy everything... 7832 */ 7833 *local = *orig_phy; 7834 7835 /* 7836 * But the following must be set appropriately for this copy 7837 */ 7838 local->sibling = NULL; 7839 local->children = NULL; 7840 mutex_init(&local->phy_lock, NULL, MUTEX_DRIVER, 7841 DDI_INTR_PRI(orig_phy->pwp->intr_pri)); 7842 7843 return (local); 7844 } 7845 7846 int 7847 pmcs_check_acc_handle(ddi_acc_handle_t handle) 7848 { 7849 ddi_fm_error_t de; 7850 7851 if (handle == NULL) { 7852 return (DDI_FAILURE); 7853 } 7854 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0); 7855 return (de.fme_status); 7856 } 7857 7858 int 7859 pmcs_check_dma_handle(ddi_dma_handle_t handle) 7860 { 7861 ddi_fm_error_t de; 7862 7863 if (handle == NULL) { 7864 return (DDI_FAILURE); 7865 } 7866 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0); 7867 return (de.fme_status); 7868 } 7869 7870 7871 void 7872 pmcs_fm_ereport(pmcs_hw_t *pwp, char *detail) 7873 { 7874 uint64_t ena; 7875 char buf[FM_MAX_CLASS]; 7876 7877 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); 7878 ena = fm_ena_generate(0, FM_ENA_FMT1); 7879 if (DDI_FM_EREPORT_CAP(pwp->fm_capabilities)) { 7880 ddi_fm_ereport_post(pwp->dip, buf, ena, DDI_NOSLEEP, 7881 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL); 7882 } 7883 } 7884 7885 int 7886 pmcs_check_acc_dma_handle(pmcs_hw_t *pwp) 7887 { 7888 pmcs_chunk_t *pchunk; 7889 int i; 7890 7891 /* check all acc & dma handles allocated in attach */ 7892 if ((pmcs_check_acc_handle(pwp->pci_acc_handle) != DDI_SUCCESS) || 7893 (pmcs_check_acc_handle(pwp->msg_acc_handle) != DDI_SUCCESS) || 7894 (pmcs_check_acc_handle(pwp->top_acc_handle) != DDI_SUCCESS) || 7895 (pmcs_check_acc_handle(pwp->mpi_acc_handle) != DDI_SUCCESS) || 7896 (pmcs_check_acc_handle(pwp->gsm_acc_handle) != DDI_SUCCESS)) { 7897 goto check_failed; 7898 } 7899 7900 for (i = 0; i < PMCS_NIQ; i++) { 7901 if ((pmcs_check_dma_handle( 7902 pwp->iqp_handles[i]) != DDI_SUCCESS) || 7903 (pmcs_check_acc_handle( 7904 pwp->iqp_acchdls[i]) != DDI_SUCCESS)) { 7905 goto check_failed; 7906 } 7907 } 7908 7909 for (i = 0; i < PMCS_NOQ; i++) { 7910 if ((pmcs_check_dma_handle( 7911 pwp->oqp_handles[i]) != DDI_SUCCESS) || 7912 (pmcs_check_acc_handle( 7913 pwp->oqp_acchdls[i]) != DDI_SUCCESS)) { 7914 goto check_failed; 7915 } 7916 } 7917 7918 if ((pmcs_check_dma_handle(pwp->cip_handles) != DDI_SUCCESS) || 7919 (pmcs_check_acc_handle(pwp->cip_acchdls) != DDI_SUCCESS)) { 7920 goto check_failed; 7921 } 7922 7923 if (pwp->fwlog && 7924 ((pmcs_check_dma_handle(pwp->fwlog_hndl) != DDI_SUCCESS) || 7925 (pmcs_check_acc_handle(pwp->fwlog_acchdl) != DDI_SUCCESS))) { 7926 goto check_failed; 7927 } 7928 7929 if (pwp->regdump_hndl && pwp->regdump_acchdl && 7930 ((pmcs_check_dma_handle(pwp->regdump_hndl) != DDI_SUCCESS) || 7931 (pmcs_check_acc_handle(pwp->regdump_acchdl) 7932 != DDI_SUCCESS))) { 7933 goto check_failed; 7934 } 7935 7936 7937 pchunk = pwp->dma_chunklist; 7938 while (pchunk) { 7939 if ((pmcs_check_acc_handle(pchunk->acc_handle) 7940 != DDI_SUCCESS) || 7941 (pmcs_check_dma_handle(pchunk->dma_handle) 7942 != DDI_SUCCESS)) { 7943 goto check_failed; 7944 } 7945 pchunk = pchunk->next; 7946 } 7947 7948 return (0); 7949 7950 check_failed: 7951 7952 return (1); 7953 } 7954 7955 /* 7956 * pmcs_handle_dead_phys 7957 * 7958 * If the PHY has no outstanding work associated with it, remove it from 7959 * the dead PHY list and free it. 7960 * 7961 * If pwp->ds_err_recovering or pwp->configuring is set, don't run. 7962 * This keeps routines that need to submit work to the chip from having to 7963 * hold PHY locks to ensure that PHYs don't disappear while they do their work. 7964 */ 7965 void 7966 pmcs_handle_dead_phys(pmcs_hw_t *pwp) 7967 { 7968 pmcs_phy_t *phyp, *nphyp, *pphyp; 7969 7970 mutex_enter(&pwp->lock); 7971 mutex_enter(&pwp->config_lock); 7972 7973 if (pwp->configuring | pwp->ds_err_recovering) { 7974 mutex_exit(&pwp->config_lock); 7975 mutex_exit(&pwp->lock); 7976 return; 7977 } 7978 7979 /* 7980 * Check every PHY in the dead PHY list 7981 */ 7982 mutex_enter(&pwp->dead_phylist_lock); 7983 phyp = pwp->dead_phys; 7984 pphyp = NULL; /* Set previous PHY to NULL */ 7985 7986 while (phyp != NULL) { 7987 pmcs_lock_phy(phyp); 7988 ASSERT(phyp->dead); 7989 7990 nphyp = phyp->dead_next; 7991 7992 /* 7993 * Check for outstanding work 7994 */ 7995 if (phyp->ref_count > 0) { 7996 pmcs_unlock_phy(phyp); 7997 pphyp = phyp; /* This PHY becomes "previous" */ 7998 } else if (phyp->target) { 7999 pmcs_unlock_phy(phyp); 8000 pmcs_prt(pwp, PMCS_PRT_DEBUG1, phyp, phyp->target, 8001 "%s: Not freeing PHY 0x%p: target 0x%p is not free", 8002 __func__, (void *)phyp, (void *)phyp->target); 8003 pphyp = phyp; 8004 } else { 8005 /* 8006 * No outstanding work or target references. Remove it 8007 * from the list and free it 8008 */ 8009 pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, phyp->target, 8010 "%s: Freeing inactive dead PHY 0x%p @ %s " 8011 "target = 0x%p", __func__, (void *)phyp, 8012 phyp->path, (void *)phyp->target); 8013 /* 8014 * If pphyp is NULL, then phyp was the head of the list, 8015 * so just reset the head to nphyp. Otherwise, the 8016 * previous PHY will now point to nphyp (the next PHY) 8017 */ 8018 if (pphyp == NULL) { 8019 pwp->dead_phys = nphyp; 8020 } else { 8021 pphyp->dead_next = nphyp; 8022 } 8023 /* 8024 * If the target still points to this PHY, remove 8025 * that linkage now. 8026 */ 8027 if (phyp->target) { 8028 mutex_enter(&phyp->target->statlock); 8029 if (phyp->target->phy == phyp) { 8030 phyp->target->phy = NULL; 8031 } 8032 mutex_exit(&phyp->target->statlock); 8033 } 8034 pmcs_unlock_phy(phyp); 8035 kmem_cache_free(pwp->phy_cache, phyp); 8036 } 8037 8038 phyp = nphyp; 8039 } 8040 8041 mutex_exit(&pwp->dead_phylist_lock); 8042 mutex_exit(&pwp->config_lock); 8043 mutex_exit(&pwp->lock); 8044 } 8045 8046 void 8047 pmcs_inc_phy_ref_count(pmcs_phy_t *phyp) 8048 { 8049 atomic_inc_32(&phyp->ref_count); 8050 } 8051 8052 void 8053 pmcs_dec_phy_ref_count(pmcs_phy_t *phyp) 8054 { 8055 ASSERT(phyp->ref_count != 0); 8056 atomic_dec_32(&phyp->ref_count); 8057 } 8058 8059 /* 8060 * pmcs_reap_dead_phy 8061 * 8062 * This function is called from pmcs_new_tport when we have a PHY 8063 * without a target pointer. It's possible in that case that this PHY 8064 * may have a "brother" on the dead_phys list. That is, it may be the same as 8065 * this one but with a different root PHY number (e.g. pp05 vs. pp04). If 8066 * that's the case, update the dead PHY and this new PHY. If that's not the 8067 * case, we should get a tran_tgt_init on this after it's reported to SCSA. 8068 * 8069 * Called with PHY locked. 8070 */ 8071 static void 8072 pmcs_reap_dead_phy(pmcs_phy_t *phyp) 8073 { 8074 pmcs_hw_t *pwp = phyp->pwp; 8075 pmcs_phy_t *ctmp; 8076 8077 ASSERT(mutex_owned(&phyp->phy_lock)); 8078 8079 /* 8080 * Check the dead PHYs list 8081 */ 8082 mutex_enter(&pwp->dead_phylist_lock); 8083 ctmp = pwp->dead_phys; 8084 while (ctmp) { 8085 if ((ctmp->iport != phyp->iport) || 8086 (memcmp((void *)&ctmp->sas_address[0], 8087 (void *)&phyp->sas_address[0], 8))) { 8088 ctmp = ctmp->dead_next; 8089 continue; 8090 } 8091 8092 /* 8093 * Same SAS address on same iport. Now check to see if 8094 * the PHY path is the same with the possible exception 8095 * of the root PHY number. 8096 * The "5" is the string length of "pp00." 8097 */ 8098 if ((strnlen(phyp->path, 5) >= 5) && 8099 (strnlen(ctmp->path, 5) >= 5)) { 8100 if (memcmp((void *)&phyp->path[5], 8101 (void *)&ctmp->path[5], 8102 strnlen(phyp->path, 32) - 5) == 0) { 8103 break; 8104 } 8105 } 8106 8107 ctmp = ctmp->dead_next; 8108 } 8109 mutex_exit(&pwp->dead_phylist_lock); 8110 8111 /* 8112 * Found a match. Remove the target linkage and drop the 8113 * ref count on the old PHY. Then, increment the ref count 8114 * on the new PHY to compensate. 8115 */ 8116 if (ctmp) { 8117 pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, ctmp, NULL, 8118 "%s: Found match in dead PHY list for new PHY %s", 8119 __func__, phyp->path); 8120 if (ctmp->target) { 8121 /* 8122 * If there is a pointer to the target in the dead 8123 * PHY, and that PHY's ref_count drops to 0, we can 8124 * clear the target linkage now. If the PHY's 8125 * ref_count is > 1, then there may be multiple 8126 * LUNs still remaining, so leave the linkage. 8127 */ 8128 pmcs_inc_phy_ref_count(phyp); 8129 pmcs_dec_phy_ref_count(ctmp); 8130 phyp->target = ctmp->target; 8131 /* 8132 * Update the target's linkage as well 8133 */ 8134 mutex_enter(&phyp->target->statlock); 8135 phyp->target->phy = phyp; 8136 phyp->target->dtype = phyp->dtype; 8137 mutex_exit(&phyp->target->statlock); 8138 8139 if (ctmp->ref_count == 0) { 8140 ctmp->target = NULL; 8141 } 8142 } 8143 } 8144 } 8145 8146 /* 8147 * Called with iport lock held 8148 */ 8149 void 8150 pmcs_add_phy_to_iport(pmcs_iport_t *iport, pmcs_phy_t *phyp) 8151 { 8152 ASSERT(mutex_owned(&iport->lock)); 8153 ASSERT(phyp); 8154 ASSERT(!list_link_active(&phyp->list_node)); 8155 iport->nphy++; 8156 pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, PMCS_NUM_PHYS, 8157 &iport->nphy); 8158 list_insert_tail(&iport->phys, phyp); 8159 mutex_enter(&iport->refcnt_lock); 8160 iport->refcnt++; 8161 mutex_exit(&iport->refcnt_lock); 8162 } 8163 8164 /* 8165 * Called with the iport lock held 8166 */ 8167 void 8168 pmcs_remove_phy_from_iport(pmcs_iport_t *iport, pmcs_phy_t *phyp) 8169 { 8170 pmcs_phy_t *pptr, *next_pptr; 8171 8172 ASSERT(mutex_owned(&iport->lock)); 8173 8174 /* 8175 * If phyp is NULL, remove all PHYs from the iport 8176 */ 8177 if (phyp == NULL) { 8178 for (pptr = list_head(&iport->phys); pptr != NULL; 8179 pptr = next_pptr) { 8180 next_pptr = list_next(&iport->phys, pptr); 8181 mutex_enter(&pptr->phy_lock); 8182 pptr->iport = NULL; 8183 mutex_exit(&pptr->phy_lock); 8184 pmcs_rele_iport(iport); 8185 list_remove(&iport->phys, pptr); 8186 } 8187 iport->nphy = 0; 8188 return; 8189 } 8190 8191 ASSERT(phyp); 8192 ASSERT(iport->nphy > 0); 8193 ASSERT(list_link_active(&phyp->list_node)); 8194 iport->nphy--; 8195 pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, PMCS_NUM_PHYS, 8196 &iport->nphy); 8197 list_remove(&iport->phys, phyp); 8198 pmcs_rele_iport(iport); 8199 } 8200 8201 /* 8202 * This function checks to see if the target pointed to by phyp is still 8203 * correct. This is done by comparing the target's unit address with the 8204 * SAS address in phyp. 8205 * 8206 * Called with PHY locked and target statlock held 8207 */ 8208 static boolean_t 8209 pmcs_phy_target_match(pmcs_phy_t *phyp) 8210 { 8211 uint64_t wwn; 8212 char unit_address[PMCS_MAX_UA_SIZE]; 8213 boolean_t rval = B_FALSE; 8214 8215 ASSERT(phyp); 8216 ASSERT(phyp->target); 8217 ASSERT(mutex_owned(&phyp->phy_lock)); 8218 ASSERT(mutex_owned(&phyp->target->statlock)); 8219 8220 wwn = pmcs_barray2wwn(phyp->sas_address); 8221 (void) scsi_wwn_to_wwnstr(wwn, 1, unit_address); 8222 8223 if (memcmp((void *)unit_address, (void *)phyp->target->unit_address, 8224 strnlen(phyp->target->unit_address, PMCS_MAX_UA_SIZE)) == 0) { 8225 rval = B_TRUE; 8226 } 8227 8228 return (rval); 8229 } 8230 8231 void 8232 pmcs_start_dev_state_recovery(pmcs_xscsi_t *xp, pmcs_phy_t *phyp) 8233 { 8234 ASSERT(mutex_owned(&xp->statlock)); 8235 ASSERT(xp->pwp != NULL); 8236 8237 if (xp->recover_wait == 0) { 8238 pmcs_prt(xp->pwp, PMCS_PRT_DEBUG_DEV_STATE, phyp, xp, 8239 "%s: Start ds_recovery for tgt 0x%p/PHY 0x%p (%s)", 8240 __func__, (void *)xp, (void *)phyp, phyp->path); 8241 xp->recover_wait = 1; 8242 8243 /* 8244 * Rather than waiting for the watchdog timer, we'll 8245 * kick it right now. 8246 */ 8247 SCHEDULE_WORK(xp->pwp, PMCS_WORK_DS_ERR_RECOVERY); 8248 (void) ddi_taskq_dispatch(xp->pwp->tq, pmcs_worker, xp->pwp, 8249 DDI_NOSLEEP); 8250 } 8251 } 8252 8253 /* 8254 * Increment the phy ds error retry count. 8255 * If too many retries, mark phy dead and restart discovery; 8256 * otherwise schedule ds recovery. 8257 */ 8258 static void 8259 pmcs_handle_ds_recovery_error(pmcs_phy_t *phyp, pmcs_xscsi_t *tgt, 8260 pmcs_hw_t *pwp, const char *func_name, int line, char *reason_string) 8261 { 8262 ASSERT(mutex_owned(&phyp->phy_lock)); 8263 8264 phyp->ds_recovery_retries++; 8265 8266 if (phyp->ds_recovery_retries > PMCS_MAX_DS_RECOVERY_RETRIES) { 8267 pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, tgt, 8268 "%s: retry limit reached after %s to PHY %s failed", 8269 func_name, reason_string, phyp->path); 8270 tgt->recover_wait = 0; 8271 phyp->dead = 1; 8272 PHY_CHANGED_AT_LOCATION(pwp, phyp, func_name, line); 8273 RESTART_DISCOVERY(pwp); 8274 } else { 8275 SCHEDULE_WORK(pwp, PMCS_WORK_DS_ERR_RECOVERY); 8276 } 8277 } 8278