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