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