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