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