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