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