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