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