1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * This file contains firmware log routines. 28 */ 29 30 #include <sys/scsi/adapters/pmcs/pmcs.h> 31 #include <sys/scsi/adapters/pmcs/pmcs_fwlog.h> 32 33 static int pmcs_dump_ioqs(pmcs_hw_t *, caddr_t, uint32_t); 34 static int pmcs_dump_spc_ver(pmcs_hw_t *, caddr_t, uint32_t); 35 static int pmcs_dump_mpi_table(pmcs_hw_t *, caddr_t, uint32_t); 36 static int pmcs_dump_gsm_conf(pmcs_hw_t *, caddr_t, uint32_t); 37 static int pmcs_dump_pcie_conf(pmcs_hw_t *, caddr_t, uint32_t); 38 static uint32_t pmcs_get_axil(pmcs_hw_t *); 39 static boolean_t pmcs_shift_axil(pmcs_hw_t *, uint32_t); 40 static void pmcs_restore_axil(pmcs_hw_t *, uint32_t); 41 static int pmcs_dump_gsm(pmcs_hw_t *, caddr_t, uint32_t); 42 static int pmcs_dump_gsm_addiregs(pmcs_hw_t *, caddr_t, uint32_t); 43 static int pmcs_dump_hsst_sregs(pmcs_hw_t *, caddr_t, uint32_t); 44 static int pmcs_dump_sspa_sregs(pmcs_hw_t *, caddr_t, uint32_t); 45 static int pmcs_dump_fwlog(pmcs_hw_t *, caddr_t, uint32_t); 46 static void pmcs_write_fwlog(pmcs_hw_t *, pmcs_fw_event_hdr_t *); 47 48 /* 49 * Dump internal registers. Used after a firmware crash. 50 * Here dump various registers for firmware forensics, 51 * including MPI, GSM configuration, firmware log, IO Queues etc. 52 */ 53 void 54 pmcs_register_dump_int(pmcs_hw_t *pwp) 55 { 56 int n = 0; 57 uint32_t size_left = 0; 58 uint8_t slice = 0; 59 caddr_t buf = NULL; 60 61 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 62 "pmcs%d: Internal register dump", ddi_get_instance(pwp->dip)); 63 ASSERT(mutex_owned(&pwp->lock)); 64 65 if (pwp->regdumpp == NULL) { 66 pwp->regdumpp = 67 kmem_zalloc(PMCS_REG_DUMP_SIZE, KM_NOSLEEP); 68 if (pwp->regdumpp == NULL) { 69 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 70 "%s: register dump memory not allocated", __func__); 71 return; 72 } 73 } 74 buf = pwp->regdumpp; 75 size_left = PMCS_REG_DUMP_SIZE - 1; 76 77 n = pmcs_dump_spc_ver(pwp, buf, size_left); 78 ASSERT(size_left >= n); 79 buf += n; size_left -= n; 80 n = pmcs_dump_gsm_conf(pwp, buf, size_left); 81 ASSERT(size_left >= n); 82 buf += n; size_left -= n; 83 n = pmcs_dump_pcie_conf(pwp, buf, size_left); 84 ASSERT(size_left >= n); 85 buf += n; size_left -= n; 86 n = pmcs_dump_mpi_table(pwp, buf, size_left); 87 ASSERT(size_left >= n); 88 buf += n; size_left -= n; 89 n = pmcs_dump_ioqs(pwp, buf, size_left); 90 ASSERT(size_left >= n); 91 buf += n; size_left -= n; 92 93 if (pwp->state == STATE_DEAD) { 94 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 95 "%s: HBA dead, skipping AAP1/IOP registers and event logs", 96 __func__); 97 goto skip_logs; 98 } 99 100 mutex_exit(&pwp->lock); 101 slice = (PMCS_REGISTER_DUMP_FLASH_SIZE / PMCS_FLASH_CHUNK_SIZE); 102 n = snprintf(buf, size_left, "\nDump AAP1 register: \n" 103 "-----------------\n"); 104 ASSERT(size_left >= n); 105 buf += n; size_left -= n; 106 for (uint8_t j = 0; j < slice; j++) { 107 n = pmcs_get_nvmd(pwp, PMCS_NVMD_REG_DUMP, 108 PMCIN_NVMD_AAP1, (j * PMCS_FLASH_CHUNK_SIZE), 109 buf, size_left); 110 if (n == PMCS_FLASH_CHUNK_SIZE) { 111 ASSERT(size_left >= n); 112 buf += n; size_left -= n; 113 } else if ((n < PMCS_FLASH_CHUNK_SIZE) && (n > 0)) { 114 ASSERT(size_left >= n); 115 buf += n; size_left -= n; 116 break; 117 } else if (n == 0) { 118 n = snprintf(buf, size_left, "AAP1: Content of " 119 "register dump on flash is NULL\n"); 120 ASSERT(size_left >= n); 121 buf += n; size_left -= n; 122 break; 123 } else { 124 n = snprintf(buf, size_left, 125 "AAP1: Unable to obtain internal register dump\n"); 126 ASSERT(size_left >= n); 127 buf += n; size_left -= n; 128 break; 129 } 130 131 } 132 133 n = snprintf(buf, size_left, "\nDump IOP register: \n" 134 "-----------------\n"); 135 ASSERT(size_left >= n); 136 buf += n; size_left -= n; 137 for (uint8_t j = 0; j < slice; j++) { 138 n = pmcs_get_nvmd(pwp, PMCS_NVMD_REG_DUMP, 139 PMCIN_NVMD_IOP, (j * PMCS_FLASH_CHUNK_SIZE), 140 buf, size_left); 141 if (n == PMCS_FLASH_CHUNK_SIZE) { 142 ASSERT(size_left >= n); 143 buf += n; size_left -= n; 144 } else if ((n < PMCS_FLASH_CHUNK_SIZE) && (n > 0)) { 145 ASSERT(size_left >= n); 146 buf += n; size_left -= n; 147 break; 148 } else if (n == 0) { 149 n = snprintf(buf, size_left, 150 "IOP: Content of internal register dump is NULL\n"); 151 ASSERT(size_left >= n); 152 buf += n; size_left -= n; 153 break; 154 } else { 155 n = snprintf(buf, size_left, 156 "IOP: Unable to obtain internal register dump\n"); 157 ASSERT(size_left >= n); 158 buf += n; size_left -= n; 159 break; 160 } 161 162 } 163 164 n = snprintf(buf, size_left, "\nDump AAP1 event log: \n" 165 "-----------------\n"); 166 ASSERT(size_left >= n); 167 buf += n; size_left -= n; 168 for (uint8_t j = 0; j < slice; j++) { 169 n = pmcs_get_nvmd(pwp, PMCS_NVMD_EVENT_LOG, 170 PMCIN_NVMD_AAP1, (j * PMCS_FLASH_CHUNK_SIZE), 171 buf, size_left); 172 if (n > 0) { 173 ASSERT(size_left >= n); 174 buf += n; size_left -= n; 175 } else { 176 n = snprintf(buf, size_left, 177 "AAP1: Unable to obtain event log on flash\n"); 178 ASSERT(size_left >= n); 179 buf += n; size_left -= n; 180 break; 181 } 182 } 183 184 n = snprintf(buf, size_left, "\nDump IOP event log: \n" 185 "-----------------\n"); 186 ASSERT(size_left >= n); 187 buf += n; size_left -= n; 188 for (uint8_t j = 0; j < slice; j++) { 189 n = pmcs_get_nvmd(pwp, PMCS_NVMD_EVENT_LOG, 190 PMCIN_NVMD_IOP, (j * PMCS_FLASH_CHUNK_SIZE), 191 buf, size_left); 192 if (n > 0) { 193 ASSERT(size_left >= n); 194 buf += n; size_left -= n; 195 } else { 196 n = snprintf(buf, size_left, 197 "IOP: Unable to obtain event log dump\n"); 198 ASSERT(size_left >= n); 199 buf += n; size_left -= n; 200 break; 201 } 202 } 203 mutex_enter(&pwp->lock); 204 205 skip_logs: 206 n = pmcs_dump_gsm_addiregs(pwp, buf, size_left); 207 ASSERT(size_left >= n); 208 buf += n; size_left -= n; 209 210 n = pmcs_dump_hsst_sregs(pwp, buf, size_left); 211 ASSERT(size_left >= n); 212 buf += n; size_left -= n; 213 214 n = pmcs_dump_sspa_sregs(pwp, buf, size_left); 215 ASSERT(size_left >= n); 216 buf += n; size_left -= n; 217 n = snprintf(buf, size_left, "\nDump firmware log: \n" 218 "-----------------\n"); 219 ASSERT(size_left >= n); 220 buf += n; size_left -= n; 221 222 n = pmcs_dump_fwlog(pwp, buf, size_left); 223 ASSERT(size_left >= n); 224 buf += n; size_left -= n; 225 226 n = pmcs_dump_gsm(pwp, buf, size_left); 227 ASSERT(size_left >= n); 228 buf += n; size_left -= n; 229 230 n = snprintf(buf, size_left, "-----------------\n" 231 "\n------------ Dump internal registers end -------------\n"); 232 ASSERT(size_left >= n); 233 buf += n; size_left -= n; 234 } 235 236 static int 237 pmcs_dump_fwlog(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 238 { 239 pmcs_fw_event_hdr_t *evl_hdr; 240 int n = 0, retries = 0; 241 uint32_t evlog_latest_idx; 242 boolean_t log_is_current = B_FALSE; 243 244 if (pwp->fwlogp == NULL) { 245 n = snprintf(buf, size_left, "\nFirmware logging " 246 "not enabled\n"); 247 return (n); 248 } 249 250 /* 251 * First, check to make sure all entries have been DMAed to the 252 * log buffer. 253 * 254 * We'll wait the required 50ms, but if the latest entry keeps 255 * changing, we'll only retry twice 256 */ 257 evl_hdr = (pmcs_fw_event_hdr_t *)pwp->fwlogp; 258 evlog_latest_idx = evl_hdr->fw_el_latest_idx; 259 260 while ((log_is_current == B_FALSE) && (retries < 3)) { 261 drv_usecwait(50 * 1000); 262 if (evl_hdr->fw_el_latest_idx == evlog_latest_idx) { 263 log_is_current = B_TRUE; 264 } else { 265 ++retries; 266 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 267 "%s: event log is still being updated... waiting", 268 __func__); 269 evlog_latest_idx = evl_hdr->fw_el_latest_idx; 270 } 271 } 272 273 n = pmcs_dump_binary(pwp, pwp->fwlogp, 0, (PMCS_FWLOG_SIZE >> 2), 274 buf, size_left); 275 276 return (n); 277 } 278 279 /* 280 * Dump Inbound and Outbound Queues. 281 */ 282 static int 283 pmcs_dump_ioqs(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 284 { 285 uint8_t i = 0, k = 0; 286 uint32_t j = 0, depth = 0; 287 int n = 0; 288 uint32_t *ptr = NULL; 289 290 n += snprintf(&buf[n], (size_left - n), "\nDump I/O queues: \n" 291 "-----------------\n"); 292 for (i = 0; i < PMCS_NIQ; i++) { 293 depth = PMCS_IQDX(pmcs_rd_iqc_tbl(pwp, PMCS_IQC_PARMX(i))); 294 n += snprintf(&buf[n], (size_left - n), 295 "IQ[%d] Details:\n-----------------\n", i); 296 n += snprintf(&buf[n], (size_left - n), 297 " depth = 0x%04x\n", depth); 298 n += snprintf(&buf[n], (size_left - n), 299 " latest ci = 0x%02x\n", pmcs_rd_iqci(pwp, i)); 300 n += snprintf(&buf[n], (size_left - n), 301 " latest pi = 0x%02x\n", pmcs_rd_iqpi(pwp, i)); 302 for (j = 0; j < depth; j++) { 303 n += snprintf(&buf[n], (size_left - n), 304 "IOMB[%d]:\n", j); 305 ptr = &pwp->iqp[i][(j * PMCS_QENTRY_SIZE) >> 2]; 306 for (k = 0; k < (PMCS_QENTRY_SIZE / sizeof (uint32_t)); 307 k += 8) { 308 n += snprintf(&buf[n], (size_left - n), 309 "0x%08x 0x%08x 0x%08x 0x%08x " 310 "0x%08x 0x%08x 0x%08x 0x%08x\n", 311 LE_32(ptr[k]), LE_32(ptr[k+1]), 312 LE_32(ptr[k+2]), LE_32(ptr[k+3]), 313 LE_32(ptr[k+4]), LE_32(ptr[k+5]), 314 LE_32(ptr[k+6]), LE_32(ptr[k+7])); 315 } 316 } 317 } 318 for (i = 0; i < PMCS_NOQ; i++) { 319 depth = PMCS_OQDX(pmcs_rd_oqc_tbl(pwp, PMCS_OQC_PARMX(i))); 320 n += snprintf(&buf[n], (size_left - n), 321 "OQ[%d] Details:\n", i); 322 n += snprintf(&buf[n], (size_left - n), 323 " depth = 0x%04x\n", depth); 324 n += snprintf(&buf[n], (size_left - n), 325 " latest ci = 0x%02x\n", pmcs_rd_oqci(pwp, i)); 326 n += snprintf(&buf[n], (size_left - n), 327 " latest pi = 0x%02x\n", pmcs_rd_oqpi(pwp, i)); 328 for (j = 0; j < depth; j++) { 329 n += snprintf(&buf[n], (size_left - n), 330 "IOMB[%d]:\n", j); 331 ptr = &pwp->oqp[i][(j * PMCS_QENTRY_SIZE) >> 2]; 332 for (k = 0; k < (PMCS_QENTRY_SIZE / sizeof (uint32_t)); 333 k += 8) { 334 n += snprintf(&buf[n], (size_left - n), 335 "0x%08x 0x%08x 0x%08x 0x%08x " 336 "0x%08x 0x%08x 0x%08x 0x%08x\n", 337 LE_32(ptr[k]), LE_32(ptr[k+1]), 338 LE_32(ptr[k+2]), LE_32(ptr[k+3]), 339 LE_32(ptr[k+4]), LE_32(ptr[k+5]), 340 LE_32(ptr[k+6]), LE_32(ptr[k+7])); 341 } 342 } 343 344 } 345 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 346 "Dump I/O queues end \n"); 347 return (n); 348 } 349 350 /* 351 * Dump SPC Version. 352 */ 353 static int 354 pmcs_dump_spc_ver(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 355 { 356 int n = 0; 357 358 n += snprintf(&buf[n], (size_left - n), "\nDump SPC version: \n" 359 "-----------------\n"); 360 n += snprintf(&buf[n], (size_left - n), "Firmware Release Type = " 361 "0x%02x\n", PMCS_FW_TYPE(pwp)); 362 n += snprintf(&buf[n], (size_left - n), " Sub-Minor Release " 363 "Number = 0x%02x\n", PMCS_FW_MICRO(pwp)); 364 n += snprintf(&buf[n], (size_left - n), " Minor Release " 365 "Number = 0x%02x\n", PMCS_FW_MINOR(pwp)); 366 n += snprintf(&buf[n], (size_left - n), " Major Release " 367 "Number = 0x%02x\n", PMCS_FW_MAJOR(pwp)); 368 n += snprintf(&buf[n], (size_left - n), "SPC DeviceID = 0x%04x\n", 369 pmcs_rd_topunit(pwp, PMCS_SPC_DEVICE_ID)); 370 n += snprintf(&buf[n], (size_left - n), "SPC Device Revision = " 371 "0x%08x\n", pmcs_rd_topunit(pwp, PMCS_DEVICE_REVISION)); 372 n += snprintf(&buf[n], (size_left - n), "SPC BootStrap Register = " 373 "0x%08x\n", pmcs_rd_topunit(pwp, PMCS_SPC_BOOT_STRAP)); 374 n += snprintf(&buf[n], (size_left - n), "SPC Reset Register = 0x%08x\n", 375 pmcs_rd_topunit(pwp, PMCS_SPC_RESET)); 376 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 377 "Dump SPC version end \n"); 378 return (n); 379 } 380 381 /* 382 * Dump MPI Table. 383 */ 384 static int 385 pmcs_dump_mpi_table(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 386 { 387 int n = 0; 388 389 n += snprintf(&buf[n], (size_left - n), "\nDump MSGU registers: \n" 390 "-----------------\n"); 391 n += snprintf(&buf[n], (size_left - n), "inb_doorbell = 0x%08x\n", 392 pmcs_rd_msgunit(pwp, PMCS_MSGU_IBDB)); 393 n += snprintf(&buf[n], (size_left - n), "inb_doorbell_clear = 0x%08x" 394 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_IBDB_CLEAR)); 395 n += snprintf(&buf[n], (size_left - n), "outb_doorbell = 0x%08x" 396 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_OBDB)); 397 n += snprintf(&buf[n], (size_left - n), "outb_doorbell_clear = 0x%08x" 398 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR)); 399 n += snprintf(&buf[n], (size_left - n), "scratch_pad0 = 0x%08x" 400 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH0)); 401 n += snprintf(&buf[n], (size_left - n), "scratch_pad1 = 0x%08x" 402 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH1)); 403 n += snprintf(&buf[n], (size_left - n), "scratch_pad2 = 0x%08x" 404 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH2)); 405 n += snprintf(&buf[n], (size_left - n), "scratch_pad3 = 0x%08x" 406 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_SCRATCH3)); 407 n += snprintf(&buf[n], (size_left - n), "host_scratch_pad0 = 0x%08x" 408 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_HOST_SCRATCH0)); 409 n += snprintf(&buf[n], (size_left - n), "host_scratch_pad1 = 0x%08x" 410 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_HOST_SCRATCH1)); 411 n += snprintf(&buf[n], (size_left - n), "host_scratch_pad2 = 0x%08x" 412 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_HOST_SCRATCH2)); 413 n += snprintf(&buf[n], (size_left - n), "host_scratch_pad3 = 0x%08x" 414 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_HOST_SCRATCH3)); 415 n += snprintf(&buf[n], (size_left - n), "host_scratch_pad4 = 0x%08x" 416 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_HOST_SCRATCH4)); 417 n += snprintf(&buf[n], (size_left - n), "host_scratch_pad5 = 0x%08x" 418 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_HOST_SCRATCH5)); 419 n += snprintf(&buf[n], (size_left - n), "host_scratch_pad6 = 0x%08x" 420 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_HOST_SCRATCH6)); 421 n += snprintf(&buf[n], (size_left - n), "host_scratch_pad7 = 0x%08x" 422 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_HOST_SCRATCH7)); 423 n += snprintf(&buf[n], (size_left - n), "outb_doorbell_mask = 0x%08x" 424 "\n", pmcs_rd_msgunit(pwp, PMCS_MSGU_OBDB_MASK)); 425 426 n += snprintf(&buf[n], (size_left - n), "MPI Configuration Table: \n" 427 "-----------------\n"); 428 n += snprintf(&buf[n], (size_left - n), "ASCII Signature = 0x%08x\n", 429 pmcs_rd_mpi_tbl(pwp, PMCS_MPI_AS)); 430 n += snprintf(&buf[n], (size_left - n), "Firmware Release Type = " 431 "0x%08x\n", PMCS_FW_TYPE(pwp)); 432 n += snprintf(&buf[n], (size_left - n), "Firmware Release Variant = " 433 "0x%08x\n", PMCS_FW_VARIANT(pwp)); 434 n += snprintf(&buf[n], (size_left - n), "Firmware Sub-Minor Release " 435 "Number = 0x%08x\n", PMCS_FW_MICRO(pwp)); 436 n += snprintf(&buf[n], (size_left - n), "Firmware Minor Release " 437 "Number = 0x%08x\n", PMCS_FW_MINOR(pwp)); 438 n += snprintf(&buf[n], (size_left - n), "Firmware Major Release " 439 "Number = 0x%08x\n", PMCS_FW_MAJOR(pwp)); 440 n += snprintf(&buf[n], (size_left - n), "Maximum Outstanding I/Os " 441 "supported = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_MOIO)); 442 n += snprintf(&buf[n], (size_left - n), "Maximum Scatter-Gather List " 443 "Elements = 0x%08x\n", 444 PMCS_MSGL(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO0))); 445 n += snprintf(&buf[n], (size_left - n), "Maximum number of devices " 446 "connected to the SPC = 0x%08x\n", 447 PMCS_MD(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO0))); 448 n += snprintf(&buf[n], (size_left - n), "Maximum Number of IQs " 449 "supported = 0x%08x\n", 450 PMCS_MNIQ(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO1))); 451 n += snprintf(&buf[n], (size_left - n), "Maximum Number of OQs " 452 "supported = 0x%08x\n", 453 PMCS_MNOQ(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO1))); 454 n += snprintf(&buf[n], (size_left - n), "High Priority Queue supported" 455 " = 0x%08x\n", PMCS_HPIQ(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO1))); 456 n += snprintf(&buf[n], (size_left - n), "Interrupt Coalescing supported" 457 " = 0x%08x\n", PMCS_ICS(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO1))); 458 n += snprintf(&buf[n], (size_left - n), "Number of Phys = " 459 "0x%08x\n", PMCS_NPHY(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO1))); 460 n += snprintf(&buf[n], (size_left - n), "SAS Revision Specification = " 461 "0x%08x\n", PMCS_SASREV(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO1))); 462 n += snprintf(&buf[n], (size_left - n), "General Status Table Offset = " 463 "0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_GSTO)); 464 n += snprintf(&buf[n], (size_left - n), "Inbound Queue Configuration " 465 "Table Offset = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_IQCTO)); 466 n += snprintf(&buf[n], (size_left - n), "Outbound Queue Configuration " 467 "Table Offset = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_OQCTO)); 468 n += snprintf(&buf[n], (size_left - n), "Inbound Queue Normal/High " 469 "Priority Processing Depth = 0x%02x 0x%02x\n", 470 (pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO2) & IQ_NORMAL_PRI_DEPTH_MASK), 471 ((pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO2) & 472 IQ_HIPRI_PRI_DEPTH_MASK) >> IQ_HIPRI_PRI_DEPTH_SHIFT)); 473 n += snprintf(&buf[n], (size_left - n), "General Event Notification " 474 "Queue = 0x%02x\n", (pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO2) & 475 GENERAL_EVENT_OQ_MASK) >> GENERAL_EVENT_OQ_SHIFT); 476 n += snprintf(&buf[n], (size_left - n), "Device Handle Removed " 477 "Notification Queue = 0x%02x\n", 478 (uint32_t)(pmcs_rd_mpi_tbl(pwp, PMCS_MPI_INFO2) & 479 DEVICE_HANDLE_REMOVED_MASK) >> DEVICE_HANDLE_REMOVED_SHIFT); 480 for (uint8_t i = 0; i < pwp->nphy; i++) { 481 uint32_t woff = i / 4; 482 uint32_t shf = (i % 4) * 8; 483 n += snprintf(&buf[n], (size_left - n), "SAS HW Event " 484 "Notification Queue - PHY ID %d = 0x%02x\n", i, 485 (pmcs_rd_mpi_tbl(pwp, PMCS_MPI_EVQS + (woff << 2)) >> shf) 486 & 0xff); 487 } 488 for (uint8_t i = 0; i < pwp->nphy; i++) { 489 uint32_t woff = i / 4; 490 uint32_t shf = (i % 4) * 8; 491 n += snprintf(&buf[n], (size_left - n), "SATA NCQ Error " 492 "Event Notification Queue - PHY ID %d = 0x%02x\n", i, 493 (pmcs_rd_mpi_tbl(pwp, PMCS_MPI_SNCQ + (woff << 2)) >> shf) 494 & 0xff); 495 } 496 for (uint8_t i = 0; i < pwp->nphy; i++) { 497 uint32_t woff = i / 4; 498 uint32_t shf = (i % 4) * 8; 499 n += snprintf(&buf[n], (size_left - n), "I_T Nexus Target " 500 "Event Notification Queue - PHY ID %d = 0x%02x\n", i, 501 (pmcs_rd_mpi_tbl(pwp, PMCS_MPI_IT_NTENQ + 502 (woff << 2)) >> shf) & 0xff); 503 } 504 for (uint8_t i = 0; i < pwp->nphy; i++) { 505 uint32_t woff = i / 4; 506 uint32_t shf = (i % 4) * 8; 507 n += snprintf(&buf[n], (size_left - n), "SSP Target " 508 "Event Notification Queue - PHY ID %d = 0x%02x\n", i, 509 (pmcs_rd_mpi_tbl(pwp, PMCS_MPI_SSP_TENQ + 510 (woff << 2)) >> shf) & 0xff); 511 } 512 513 n += snprintf(&buf[n], (size_left - n), "I/O Abort Delay = 0x%04x\n", 514 pmcs_rd_mpi_tbl(pwp, PMCS_MPI_IOABTDLY) & 0xffff); 515 n += snprintf(&buf[n], (size_left - n), 516 "Customization Setting = 0x%08x\n", 517 pmcs_rd_mpi_tbl(pwp, PMCS_MPI_CUSTSET)); 518 n += snprintf(&buf[n], (size_left - n), "MSGU Event Log Buffer Address " 519 "Higher = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_MELBAH)); 520 n += snprintf(&buf[n], (size_left - n), "MSGU Event Log Buffer Address " 521 "Lower = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_MELBAL)); 522 n += snprintf(&buf[n], (size_left - n), "MSGU Event Log Buffer Size " 523 "= 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_MELBS)); 524 n += snprintf(&buf[n], (size_left - n), "MSGU Event Log Severity " 525 "= 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_MELSEV)); 526 n += snprintf(&buf[n], (size_left - n), "IOP Event Log Buffer Address " 527 "Higher = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_IELBAH)); 528 n += snprintf(&buf[n], (size_left - n), "IOP Event Log Buffer Address " 529 "Lower = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_IELBAL)); 530 n += snprintf(&buf[n], (size_left - n), "IOP Event Log Buffer Size " 531 "= 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_IELBS)); 532 n += snprintf(&buf[n], (size_left - n), "IOP Event Log Severity " 533 "= 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_IELSEV)); 534 n += snprintf(&buf[n], (size_left - n), "Fatal Error Interrupt " 535 "= 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_MPI_FERR)); 536 n += snprintf(&buf[n], (size_left - n), 537 "Fatal Error Register Dump Offset " 538 "For MSGU = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_FERDOMSGU)); 539 n += snprintf(&buf[n], (size_left - n), 540 "Fatal Error Register Dump Length " 541 "For MSGU = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_FERDLMSGU)); 542 n += snprintf(&buf[n], (size_left - n), 543 "Fatal Error Register Dump Offset " 544 "For IOP = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_FERDOIOP)); 545 n += snprintf(&buf[n], (size_left - n), 546 "Fatal Error Register Dump Length " 547 "For IOP = 0x%08x\n", pmcs_rd_mpi_tbl(pwp, PMCS_FERDLIOP)); 548 549 n += snprintf(&buf[n], (size_left - n), "Dump GS Table: \n" 550 "-----------------\n"); 551 n += snprintf(&buf[n], (size_left - n), "GST MPI State: 0x%08x\n", 552 pmcs_rd_gst_tbl(pwp, PMCS_GST_BASE)); 553 n += snprintf(&buf[n], (size_left - n), "Inbound Queue Freeze State 0 " 554 "= 0x%08x\n", pmcs_rd_gst_tbl(pwp, PMCS_GST_IQFRZ0)); 555 n += snprintf(&buf[n], (size_left - n), "Inbound Queue Freeze State 1 " 556 "= 0x%08x\n", pmcs_rd_gst_tbl(pwp, PMCS_GST_IQFRZ1)); 557 n += snprintf(&buf[n], (size_left - n), "MSGU Tick Count = 0x%08x \n", 558 pmcs_rd_gst_tbl(pwp, PMCS_GST_MSGU_TICK)); 559 n += snprintf(&buf[n], (size_left - n), "IOP Tick Count = 0x%08x\n", 560 pmcs_rd_gst_tbl(pwp, PMCS_GST_IOP_TICK)); 561 for (uint8_t i = 0; i < pwp->nphy; i++) { 562 n += snprintf(&buf[n], (size_left - n), " Phy %d state = " 563 "0x%08x\n", i, pmcs_rd_gst_tbl(pwp, PMCS_GST_PHY_INFO(i))); 564 } 565 for (uint8_t i = 0; i < pwp->nphy; i++) { 566 n += snprintf(&buf[n], (size_left - n), " Recoverable Error " 567 "Information %d = 0x%08x\n", i, 568 pmcs_rd_gst_tbl(pwp, PMCS_GST_RERR_INFO(i))); 569 } 570 571 n += snprintf(&buf[n], (size_left - n), "Dump IQCT Table\n" 572 "-----------------\n"); 573 for (uint8_t i = 0; i < PMCS_NIQ; i++) { 574 n += snprintf(&buf[n], (size_left - n), "Inbound Queue " 575 "Configuration Table - [%d]:\n", i); 576 n += snprintf(&buf[n], (size_left - n), " Inbound Queue " 577 "Depth = 0x%08x\n", 578 PMCS_IQDX(pmcs_rd_iqc_tbl(pwp, PMCS_IQC_PARMX(i)))); 579 n += snprintf(&buf[n], (size_left - n), " Inbound Queue " 580 "Element Size and Priority = 0x%08x 0x%08x\n", 581 PMCS_IQESX(pmcs_rd_iqc_tbl(pwp, PMCS_IQC_PARMX(i))), 582 PMCS_IQPX(pmcs_rd_iqc_tbl(pwp, PMCS_IQC_PARMX(i)))); 583 n += snprintf(&buf[n], (size_left - n), " Inbound Queue " 584 "Base Address High = 0x%08x\n", 585 pmcs_rd_iqc_tbl(pwp, PMCS_IQBAHX(i))); 586 n += snprintf(&buf[n], (size_left - n), " Inbound Queue " 587 "Base Address Low = 0x%08x\n", 588 pmcs_rd_iqc_tbl(pwp, PMCS_IQBALX(i))); 589 n += snprintf(&buf[n], (size_left - n), " Inbound Queue " 590 "Consumer Index Base Address High = 0x%08x\n", 591 pmcs_rd_iqc_tbl(pwp, PMCS_IQCIBAHX(i))); 592 n += snprintf(&buf[n], (size_left - n), " Inbound Queue " 593 "Consumer Index Base Address Low = 0x%08x\n", 594 pmcs_rd_iqc_tbl(pwp, PMCS_IQCIBALX(i))); 595 n += snprintf(&buf[n], (size_left - n), " Inbound Queue " 596 "Producer Index PCI BAR = 0x%08x\n", 597 pmcs_rd_iqc_tbl(pwp, PMCS_IQPIBARX(i))); 598 n += snprintf(&buf[n], (size_left - n), " Inbound Queue " 599 "Producer Index PCI BAR offset = 0x%08x\n", 600 pmcs_rd_iqc_tbl(pwp, PMCS_IQPIOFFX(i))); 601 } 602 603 n += snprintf(&buf[n], (size_left - n), "Dump OQCT Table: \n" 604 "-----------------\n"); 605 for (uint8_t i = 0; i < PMCS_NOQ; i++) { 606 n += snprintf(&buf[n], (size_left - n), "Outbound Queue " 607 "Configuration Table - [%d]:\n", i); 608 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 609 "Depth = 0x%08x\n", 610 PMCS_OQDX(pmcs_rd_oqc_tbl(pwp, PMCS_OQC_PARMX(i)))); 611 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 612 "Element Size = 0x%08x\n", 613 PMCS_OQESX(pmcs_rd_oqc_tbl(pwp, PMCS_OQC_PARMX(i)))); 614 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 615 "Base Address High = 0x%08x\n", 616 pmcs_rd_oqc_tbl(pwp, PMCS_OQBAHX(i))); 617 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 618 "Base Address Low = 0x%08x\n", 619 pmcs_rd_oqc_tbl(pwp, PMCS_OQBALX(i))); 620 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 621 "Producer Index Base Address High = 0x%08x\n", 622 pmcs_rd_oqc_tbl(pwp, PMCS_OQPIBAHX(i))); 623 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 624 "Producer Index Base Address Low = 0x%08x\n", 625 pmcs_rd_oqc_tbl(pwp, PMCS_OQPIBALX(i))); 626 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 627 "Consumer Index PCI BAR = 0x%08x\n", 628 pmcs_rd_oqc_tbl(pwp, PMCS_OQCIBARX(i))); 629 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 630 "Consumer Index PCI BAR offset = 0x%08x\n", 631 pmcs_rd_oqc_tbl(pwp, PMCS_OQCIOFFX(i))); 632 633 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 634 "Interrupt Coalescing Timeout = 0x%08x\n", 635 PMCS_OQICT(pmcs_rd_oqc_tbl(pwp, PMCS_OQIPARM(i)))); 636 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 637 "Interrupt Coalescing Count = 0x%08x\n", 638 PMCS_OQICC(pmcs_rd_oqc_tbl(pwp, PMCS_OQIPARM(i)))); 639 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 640 "Interrupt Vector = 0x%08x\n", 641 PMCS_OQIV(pmcs_rd_oqc_tbl(pwp, PMCS_OQIPARM(i)))); 642 n += snprintf(&buf[n], (size_left - n), " Outbound Queue " 643 "Dynamic Interrupt Coalescing Timeout = 0x%08x\n", 644 pmcs_rd_oqc_tbl(pwp, PMCS_OQDICX(i))); 645 646 } 647 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 648 "Dump MPI Table end\n"); 649 return (n); 650 } 651 652 /*ARGSUSED*/ 653 int 654 pmcs_dump_binary(pmcs_hw_t *pwp, uint32_t *addr, uint32_t off, 655 uint32_t words_to_read, caddr_t buf, uint32_t size_left) 656 { 657 uint32_t i; 658 int n = 0; 659 char c = ' '; 660 661 for (i = 0, n = 0; i < words_to_read; i++) { 662 if ((i & 7) == 0) { 663 n += snprintf(&buf[n], (size_left - n), 664 "%08x: ", (i << 2) + off); 665 } 666 if ((i + 1) & 7) { 667 c = ' '; 668 } else { 669 c = '\n'; 670 } 671 n += snprintf(&buf[n], (size_left - n), "%08x%c", addr[i], c); 672 } 673 return (n); 674 } 675 676 /* 677 * Dump Global Shared Memory Configuration Registers 678 */ 679 static int 680 pmcs_dump_gsm_conf(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 681 { 682 int n = 0; 683 684 n += snprintf(&buf[n], (size_left - n), "\nDump GSM configuration " 685 "registers: \n -----------------\n"); 686 n += snprintf(&buf[n], (size_left - n), "RB6 Access Register = " 687 "0x%08x\n", pmcs_rd_gsm_reg(pwp, RB6_ACCESS)); 688 n += snprintf(&buf[n], (size_left - n), "CFG and RST = 0x%08x\n", 689 pmcs_rd_gsm_reg(pwp, GSM_CFG_AND_RESET)); 690 n += snprintf(&buf[n], (size_left - n), "RAM ECC ERR INDICATOR= " 691 "0x%08x\n", pmcs_rd_gsm_reg(pwp, RAM_ECC_DOUBLE_ERROR_INDICATOR)); 692 n += snprintf(&buf[n], (size_left - n), "READ ADR PARITY CHK EN = " 693 "0x%08x\n", pmcs_rd_gsm_reg(pwp, READ_ADR_PARITY_CHK_EN)); 694 n += snprintf(&buf[n], (size_left - n), "WRITE ADR PARITY CHK EN = " 695 "0x%08x\n", pmcs_rd_gsm_reg(pwp, WRITE_ADR_PARITY_CHK_EN)); 696 n += snprintf(&buf[n], (size_left - n), "WRITE DATA PARITY CHK EN= " 697 "0x%08x\n", pmcs_rd_gsm_reg(pwp, WRITE_DATA_PARITY_CHK_EN)); 698 n += snprintf(&buf[n], (size_left - n), 699 "READ ADR PARITY ERROR INDICATOR = 0x%08x\n", 700 pmcs_rd_gsm_reg(pwp, READ_ADR_PARITY_ERROR_INDICATOR)); 701 n += snprintf(&buf[n], (size_left - n), 702 "WRITE ADR PARITY ERROR INDICATOR = 0x%08x\n", 703 pmcs_rd_gsm_reg(pwp, WRITE_ADR_PARITY_ERROR_INDICATOR)); 704 n += snprintf(&buf[n], (size_left - n), 705 "WRITE DATA PARITY ERROR INDICATOR = 0x%08x\n", 706 pmcs_rd_gsm_reg(pwp, WRITE_DATA_PARITY_ERROR_INDICATOR)); 707 n += snprintf(&buf[n], (size_left - n), "NMI Enable VPE0 IOP Register" 708 " = 0x%08x\n", pmcs_rd_gsm_reg(pwp, NMI_EN_VPE0_IOP)); 709 n += snprintf(&buf[n], (size_left - n), "NMI Enable VPE0 AAP1 Register" 710 " = 0x%08x\n", pmcs_rd_gsm_reg(pwp, NMI_EN_VPE0_AAP1)); 711 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 712 "Dump GSM configuration registers end \n"); 713 return (n); 714 } 715 716 /* 717 * Dump PCIe Configuration Registers. 718 */ 719 static int 720 pmcs_dump_pcie_conf(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 721 { 722 int n = 0; 723 uint32_t i = 0; 724 725 n += snprintf(&buf[n], (size_left - n), "\nDump PCIe configuration " 726 "registers: \n -----------------\n"); 727 n += snprintf(&buf[n], (size_left - n), "VENID = 0x%04x\n", 728 pci_config_get16(pwp->pci_acc_handle, PCI_CONF_VENID)); 729 n += snprintf(&buf[n], (size_left - n), "DEVICE_ID = 0x%04x\n", 730 pci_config_get16(pwp->pci_acc_handle, PCI_CONF_DEVID)); 731 n += snprintf(&buf[n], (size_left - n), "CFGCMD = 0x%04x\n", 732 pci_config_get16(pwp->pci_acc_handle, PCI_CONF_COMM)); 733 n += snprintf(&buf[n], (size_left - n), "CFGSTAT = 0x%04x\n", 734 pci_config_get16(pwp->pci_acc_handle, PCI_CONF_STAT)); 735 n += snprintf(&buf[n], (size_left - n), "CLSCODE and REVID = 0x%08x\n", 736 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_REVID)); 737 n += snprintf(&buf[n], (size_left - n), "BIST HDRTYPE LATTIM CLSIZE = " 738 "0x%08x\n", 739 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_CACHE_LINESZ)); 740 n += snprintf(&buf[n], (size_left - n), "MEMBASE-I LOWER = 0x%08x\n", 741 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE0)); 742 n += snprintf(&buf[n], (size_left - n), "MEMBASE-I UPPER = 0x%08x\n", 743 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE1)); 744 n += snprintf(&buf[n], (size_left - n), "MEMBASE-II LOWER = 0x%08x\n", 745 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE2)); 746 n += snprintf(&buf[n], (size_left - n), "MEMBASE-II UPPER = 0x%08x\n", 747 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE3)); 748 n += snprintf(&buf[n], (size_left - n), "MEMBASE-III = 0x%08x\n", 749 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE4)); 750 n += snprintf(&buf[n], (size_left - n), "MEMBASE-IV = 0x%08x\n", 751 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE5)); 752 n += snprintf(&buf[n], (size_left - n), "SVID = 0x%08x\n", 753 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_SUBVENID)); 754 n += snprintf(&buf[n], (size_left - n), "ROMBASE = 0x%08x\n", 755 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_ROM)); 756 n += snprintf(&buf[n], (size_left - n), "CAP_PTR = 0x%02x\n", 757 pci_config_get8(pwp->pci_acc_handle, PCI_CONF_CAP_PTR)); 758 n += snprintf(&buf[n], (size_left - n), "MAXLAT MINGNT INTPIN " 759 "INTLINE = 0x%08x\n", 760 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_ILINE)); 761 n += snprintf(&buf[n], (size_left - n), "PMC PM_NEXT_CAP PM_CAP_ID = " 762 "0x%08x\n", pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_PMC)); 763 n += snprintf(&buf[n], (size_left - n), "PMCSR = 0x%08x\n", 764 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_PMCSR)); 765 n += snprintf(&buf[n], (size_left - n), 766 "MC MSI_NEXT_CAP MSI_CAP_ID = 0x%08x\n", 767 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_MSI)); 768 n += snprintf(&buf[n], (size_left - n), "MAL = 0x%08x\n", 769 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_MAL)); 770 n += snprintf(&buf[n], (size_left - n), "MAU = 0x%08x\n", 771 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_MAU)); 772 n += snprintf(&buf[n], (size_left - n), "MD = 0x%04x\n", 773 pci_config_get16(pwp->pci_acc_handle, PMCS_PCI_MD)); 774 n += snprintf(&buf[n], (size_left - n), 775 "PCIE_CAP PCIE_NEXT_CAP PCIE_CAP_ID = 0x%08x\n", 776 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_PCIE)); 777 n += snprintf(&buf[n], (size_left - n), "DEVICE_CAP = 0x%08x\n", 778 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_DEV_CAP)); 779 n += snprintf(&buf[n], (size_left - n), 780 "DEVICE_STAT DEVICE_CTRL = 0x%08x\n", 781 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_DEV_CTRL)); 782 n += snprintf(&buf[n], (size_left - n), "LINK_CAP = 0x%08x\n", 783 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_LINK_CAP)); 784 n += snprintf(&buf[n], (size_left - n), 785 "LINK_STAT LINK_CTRL = 0x%08x\n", 786 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_LINK_CTRL)); 787 n += snprintf(&buf[n], (size_left - n), "MSIX_CAP = 0x%08x\n", 788 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_MSIX_CAP)); 789 n += snprintf(&buf[n], (size_left - n), "TBL_OFFSET = 0x%08x\n", 790 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_TBL_OFFSET)); 791 n += snprintf(&buf[n], (size_left - n), "PBA_OFFSET = 0x%08x\n", 792 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_PBA_OFFSET)); 793 n += snprintf(&buf[n], (size_left - n), "PCIE_CAP_HD = 0x%08x\n", 794 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_PCIE_CAP_HD)); 795 n += snprintf(&buf[n], (size_left - n), "UE_STAT = 0x%08x\n", 796 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_UE_STAT)); 797 n += snprintf(&buf[n], (size_left - n), "UE_MASK = 0x%08x\n", 798 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_UE_MASK)); 799 n += snprintf(&buf[n], (size_left - n), "UE_SEV = 0x%08x\n", 800 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_UE_SEV)); 801 n += snprintf(&buf[n], (size_left - n), "CE_STAT = 0x%08x\n", 802 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_CE_STAT)); 803 n += snprintf(&buf[n], (size_left - n), "CE_MASK = 0x%08x\n", 804 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_CE_MASK)); 805 n += snprintf(&buf[n], (size_left - n), "ADV_ERR_CTRL = 0x%08x\n", 806 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_ADV_ERR_CTRL)); 807 for (i = 0; i < 4; i++) { 808 n += snprintf(&buf[n], (size_left - n), "HD_LOG_DW%d = " 809 "0x%08x\n", i, pci_config_get32(pwp->pci_acc_handle, 810 (PMCS_PCI_HD_LOG_DW + i * 4))); 811 } 812 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 813 "Dump PCIe configuration registers end \n"); 814 return (n); 815 } 816 /* 817 * Called with axil_lock held 818 */ 819 static boolean_t 820 pmcs_shift_axil(pmcs_hw_t *pwp, uint32_t offset) 821 { 822 uint32_t newaxil = offset & ~GSM_BASE_MASK; 823 824 ASSERT(mutex_owned(&pwp->axil_lock)); 825 ddi_put32(pwp->top_acc_handle, 826 &pwp->top_regs[PMCS_AXI_TRANS >> 2], newaxil); 827 drv_usecwait(10); 828 829 if (ddi_get32(pwp->top_acc_handle, 830 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != newaxil) { 831 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 832 "AXIL register update failed"); 833 return (B_FALSE); 834 } 835 return (B_TRUE); 836 } 837 838 static uint32_t 839 pmcs_get_axil(pmcs_hw_t *pwp) 840 { 841 uint32_t regval = 0; 842 mutex_enter(&pwp->axil_lock); 843 regval = ddi_get32(pwp->top_acc_handle, 844 &pwp->top_regs[PMCS_AXI_TRANS >> 2]); 845 mutex_exit(&pwp->axil_lock); 846 return (regval); 847 } 848 849 static void 850 pmcs_restore_axil(pmcs_hw_t *pwp, uint32_t oldaxil) 851 { 852 mutex_enter(&pwp->axil_lock); 853 ddi_put32(pwp->top_acc_handle, 854 &pwp->top_regs[PMCS_AXI_TRANS >> 2], oldaxil); 855 drv_usecwait(10); 856 857 if (ddi_get32(pwp->top_acc_handle, 858 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != oldaxil) { 859 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 860 "AXIL register restore failed"); 861 } 862 mutex_exit(&pwp->axil_lock); 863 } 864 865 /* 866 * Dump Additional GSM Registers. 867 */ 868 static int 869 pmcs_dump_gsm_addiregs(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 870 { 871 uint32_t i = 0; 872 int n = 0, j = 0, nums = 0; 873 uint32_t gsm_addr = 0, addr = 0; 874 875 n += snprintf(&buf[n], (size_left - n), "\nDump GSM Sparse Registers:" 876 "\n-----------------\n"); 877 for (i = 0; i < sizeof (gsm_spregs) / sizeof (pmcs_sparse_regs_t); 878 i++) { 879 gsm_addr = 880 gsm_spregs[i].shift_addr + gsm_spregs[i].offset_start; 881 nums = gsm_spregs[i].offset_end - gsm_spregs[i].offset_start; 882 if (gsm_spregs[i].flag & PMCS_SPREGS_BLOCK_START) { 883 n += snprintf(&buf[n], (size_left - n), "\n%s - 0x%08X" 884 "[MEMBASE-III SHIFT = 0x%08X]\nOffset:\n", 885 gsm_spregs[i].desc ? gsm_spregs[i].desc : "NULL", 886 gsm_spregs[i].base_addr, gsm_spregs[i].shift_addr); 887 } 888 889 if (nums == 0) { 890 n += snprintf(&buf[n], (size_left - n), 891 "[%04X]: %08X\n", gsm_spregs[i].offset_start, 892 pmcs_rd_gsm_reg(pwp, gsm_addr)); 893 } else if (nums > 0) { 894 n += snprintf(&buf[n], (size_left - n), 895 "\n[%04X] - [%04X]: \n", gsm_spregs[i].offset_start, 896 gsm_spregs[i].offset_end); 897 898 j = 0; 899 while (nums > 0) { 900 addr = gsm_addr + j * 4; 901 n += snprintf(&buf[n], (size_left - n), 902 "[%04X]: %08X\n", addr & GSM_BASE_MASK, 903 pmcs_rd_gsm_reg(pwp, addr)); 904 j++; 905 nums -= 4; 906 } 907 } 908 909 } 910 911 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 912 "------------ Dump GSM Sparse Registers end ------------\n"); 913 return (n); 914 915 } 916 917 /* 918 * Dump GSM Memory Regions. 919 */ 920 static int 921 pmcs_dump_gsm(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 922 { 923 int n = 0; 924 uint32_t i = 0; 925 uint32_t oldaxil = 0; 926 uint32_t gsm_addr = 0; 927 uint32_t *local_buf = NULL; 928 929 local_buf = kmem_zalloc(GSM_SM_BLKSZ, KM_NOSLEEP); 930 if (local_buf == NULL) { 931 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 932 "%s: local_buf memory not allocated", __func__); 933 return (0); 934 } 935 936 oldaxil = pmcs_get_axil(pwp); 937 mutex_enter(&pwp->axil_lock); 938 n += snprintf(&buf[n], (size_left - n), "\nDump GSM IO Status Table: \n" 939 " -----------------\n"); 940 for (i = 0; i < 4; i++) { 941 gsm_addr = IO_STATUS_TABLE_BASE + GSM_SM_BLKSZ * i; 942 if (pmcs_shift_axil(pwp, gsm_addr) == B_TRUE) { 943 gsm_addr &= GSM_BASE_MASK; 944 ddi_rep_get32(pwp->gsm_acc_handle, local_buf, 945 &pwp->gsm_regs[gsm_addr >> 2], GSM_SM_BLKSZ >> 2, 946 DDI_DEV_AUTOINCR); 947 n += pmcs_dump_binary(pwp, local_buf, i * GSM_SM_BLKSZ, 948 GSM_SM_BLKSZ >> 2, &buf[n], size_left - n); 949 } 950 } 951 n += snprintf(&buf[n], (size_left - n), "\n-----------------\n" 952 "Dump GSM IO Status Table end \n"); 953 n += snprintf(&buf[n], (size_left - n), "\nDump Ring Buffer Storage: \n" 954 " -----------------\n"); 955 for (i = 0; i < 2; i++) { 956 gsm_addr = RING_BUF_STORAGE_0 + GSM_SM_BLKSZ * i; 957 if (pmcs_shift_axil(pwp, gsm_addr) == B_TRUE) { 958 gsm_addr &= GSM_BASE_MASK; 959 ddi_rep_get32(pwp->gsm_acc_handle, local_buf, 960 &pwp->gsm_regs[gsm_addr >> 2], GSM_SM_BLKSZ >> 2, 961 DDI_DEV_AUTOINCR); 962 n += pmcs_dump_binary(pwp, local_buf, i * GSM_SM_BLKSZ, 963 GSM_SM_BLKSZ >> 2, &buf[n], size_left - n); 964 } 965 } 966 n += snprintf(&buf[n], (size_left - n), "\n-----------------\n" 967 "Dump Ring Buffer Storage end \n"); 968 969 n += snprintf(&buf[n], (size_left - n), "\nDump Ring Buffer Pointers:\n" 970 " -----------------\n"); 971 gsm_addr = RING_BUF_PTR_ACC_BASE + RING_BUF_PTR_OFF; 972 if (pmcs_shift_axil(pwp, gsm_addr) == B_TRUE) { 973 gsm_addr &= GSM_BASE_MASK; 974 ddi_rep_get32(pwp->gsm_acc_handle, local_buf, 975 &pwp->gsm_regs[gsm_addr >> 2], 976 RING_BUF_PTR_SIZE >> 2, DDI_DEV_AUTOINCR); 977 n += pmcs_dump_binary(pwp, local_buf, 0, 978 RING_BUF_PTR_SIZE >> 2, &buf[n], size_left - n); 979 } 980 n += snprintf(&buf[n], (size_left - n), "\n-----------------\n" 981 "Dump Ring Buffer Pointers end \n"); 982 983 n += snprintf(&buf[n], (size_left - n), "\nDump Ring Buffer Access: \n" 984 " -----------------\n"); 985 gsm_addr = RING_BUF_PTR_ACC_BASE + RING_BUF_ACC_OFF; 986 if (pmcs_shift_axil(pwp, gsm_addr) == B_TRUE) { 987 gsm_addr &= GSM_BASE_MASK; 988 ddi_rep_get32(pwp->gsm_acc_handle, local_buf, 989 &pwp->gsm_regs[gsm_addr >> 2], 990 RING_BUF_ACC_SIZE >> 2, DDI_DEV_AUTOINCR); 991 n += pmcs_dump_binary(pwp, local_buf, 0, 992 RING_BUF_ACC_SIZE >> 2, &buf[n], size_left - n); 993 } 994 n += snprintf(&buf[n], (size_left - n), "\n-----------------\n" 995 "Dump Ring Buffer Access end \n"); 996 997 n += snprintf(&buf[n], (size_left - n), "\nDump GSM SM: \n" 998 " -----------------\n"); 999 for (i = 0; i < 16; i++) { 1000 gsm_addr = GSM_SM_BASE + GSM_SM_BLKSZ * i; 1001 if (pmcs_shift_axil(pwp, gsm_addr) == B_TRUE) { 1002 gsm_addr &= GSM_BASE_MASK; 1003 ddi_rep_get32(pwp->gsm_acc_handle, local_buf, 1004 &pwp->gsm_regs[gsm_addr >> 2], 1005 GSM_SM_BLKSZ >> 2, DDI_DEV_AUTOINCR); 1006 n += pmcs_dump_binary(pwp, local_buf, i * GSM_SM_BLKSZ, 1007 GSM_SM_BLKSZ >> 2, &buf[n], size_left - n); 1008 } 1009 } 1010 mutex_exit(&pwp->axil_lock); 1011 pmcs_restore_axil(pwp, oldaxil); 1012 1013 n += snprintf(&buf[n], (size_left - n), "\n-----------------\n" 1014 "Dump GSM SM end \n"); 1015 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 1016 "\n------------ Dump GSM Memory Regions end -------------\n"); 1017 if (local_buf) { 1018 kmem_free(local_buf, GSM_SM_BLKSZ); 1019 } 1020 return (n); 1021 } 1022 1023 /* 1024 * Trace current Inbound Message host sent to SPC. 1025 */ 1026 void 1027 pmcs_iqp_trace(pmcs_hw_t *pwp, uint32_t qnum) 1028 { 1029 uint32_t k = 0; 1030 int n = 0; 1031 uint32_t *ptr = NULL; 1032 char *tbuf = pwp->iqpt->curpos; 1033 uint32_t size_left = pwp->iqpt->size_left; 1034 1035 if (tbuf == NULL) { 1036 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1037 "%s: trace buffer is not ready," 1038 " Inbound Message from host to SPC is not traced", 1039 __func__); 1040 return; 1041 } else if (size_left < PMCS_QENTRY_SIZE * PMCS_QENTRY_SIZE) { 1042 tbuf = pwp->iqpt->curpos = pwp->iqpt->head; 1043 size_left = pwp->iqpt->size_left = PMCS_IQP_TRACE_BUFFER_SIZE; 1044 } 1045 1046 ptr = &pwp->iqp[qnum][pwp->shadow_iqpi[qnum] * 1047 (PMCS_QENTRY_SIZE >> 2)]; 1048 for (k = 0; k < (PMCS_QENTRY_SIZE / sizeof (uint32_t)); 1049 k += 8) { 1050 n += snprintf(&tbuf[n], (size_left - n), 1051 "0x%08x 0x%08x 0x%08x 0x%08x " 1052 "0x%08x 0x%08x 0x%08x 0x%08x\n", 1053 LE_32(ptr[k]), LE_32(ptr[k+1]), 1054 LE_32(ptr[k+2]), LE_32(ptr[k+3]), 1055 LE_32(ptr[k+4]), LE_32(ptr[k+5]), 1056 LE_32(ptr[k+6]), LE_32(ptr[k+7])); 1057 } 1058 pwp->iqpt->size_left -= n; 1059 if (pwp->iqpt->size_left > 0) { 1060 pwp->iqpt->curpos += n; 1061 } else { 1062 pwp->iqpt->curpos = 1063 pwp->iqpt->head + PMCS_IQP_TRACE_BUFFER_SIZE - 1; 1064 } 1065 } 1066 1067 /* 1068 * Capture HSST State Registers. 1069 */ 1070 static int 1071 pmcs_dump_hsst_sregs(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 1072 { 1073 uint32_t i = 0, j = 0, addr = 0; 1074 int n = 0; 1075 1076 n += snprintf(&buf[n], (size_left - n), "\nHSST State Capture : \n" 1077 "-----------------\n"); 1078 n += snprintf(&buf[n], (size_left - n), "%s \t %s \n", 1079 hsst_state[8].desc ? hsst_state[8].desc : "NULL", 1080 hsst_state[16].desc ? hsst_state[16].desc : "NULL"); 1081 1082 for (i = 0; i < 8; i++) { 1083 addr = hsst_state[i].offset_start + 1084 hsst_state[i].shift_addr; 1085 n += snprintf(&buf[n], (size_left - n), "Phy[%1d]\n", i); 1086 for (j = 0; j < 6; j++) { 1087 pmcs_wr_gsm_reg(pwp, addr, j); 1088 pmcs_wr_gsm_reg(pwp, addr, (0x0100 + j)); 1089 addr = hsst_state[i+8].offset_start + 1090 hsst_state[i+8].shift_addr; 1091 n += snprintf(&buf[n], (size_left - n), 1092 "[%08X]: %08X\t", addr, pmcs_rd_gsm_reg(pwp, addr)); 1093 addr = hsst_state[i+16].offset_start + 1094 hsst_state[i+16].shift_addr; 1095 n += snprintf(&buf[n], (size_left - n), 1096 "[%08X]: %08X\n", addr, pmcs_rd_gsm_reg(pwp, addr)); 1097 } 1098 1099 } 1100 return (n); 1101 1102 } 1103 1104 /* 1105 * Capture SSPA State Registers. 1106 */ 1107 static int 1108 pmcs_dump_sspa_sregs(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 1109 { 1110 uint32_t i = 0, rv = 0, addr = 0; 1111 int n = 0; 1112 1113 n += snprintf(&buf[n], (size_left - n), "\nSSPA State Capture : \n" 1114 "-----------------\n"); 1115 for (i = 0; i < 8; i++) { 1116 if (sspa_state[i].flag & PMCS_SPREGS_BLOCK_START) { 1117 n += snprintf(&buf[n], (size_left - n), "%s \n", 1118 sspa_state[i].desc ? sspa_state[i].desc : "NULL"); 1119 } 1120 addr = sspa_state[i].offset_start + sspa_state[i].shift_addr; 1121 rv = pmcs_rd_gsm_reg(pwp, addr); 1122 rv |= PMCS_SSPA_CONTROL_REGISTER_BIT27; 1123 pmcs_wr_gsm_reg(pwp, addr, rv); 1124 n += snprintf(&buf[n], (size_left - n), "[%08X]: %08X \n", 1125 addr, pmcs_rd_gsm_reg(pwp, addr)); 1126 1127 } 1128 return (n); 1129 } 1130 1131 /* 1132 * Dump fatal error register content from GSM. 1133 */ 1134 int 1135 pmcs_dump_feregs(pmcs_hw_t *pwp, uint32_t *addr, uint8_t nvmd, 1136 caddr_t buf, uint32_t size_left) 1137 { 1138 uint32_t offset = 0, length = 0; 1139 int i = 0; 1140 uint8_t *ptr = (uint8_t *)addr; 1141 1142 if ((addr == NULL) || (buf == NULL)) { 1143 return (0); 1144 } 1145 switch (nvmd) { 1146 case PMCIN_NVMD_AAP1: 1147 offset = pmcs_rd_mpi_tbl(pwp, PMCS_FERDOMSGU); 1148 length = pmcs_rd_mpi_tbl(pwp, PMCS_FERDLMSGU); 1149 break; 1150 case PMCIN_NVMD_IOP: 1151 offset = pmcs_rd_mpi_tbl(pwp, PMCS_FERDOIOP); 1152 length = pmcs_rd_mpi_tbl(pwp, PMCS_FERDLIOP); 1153 break; 1154 default: 1155 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1156 "UNKNOWN NVMD DEVICE %s():%d", __func__, __LINE__); 1157 return (0); 1158 } 1159 1160 while ((i < length) && (ptr[i + offset] != 0xff) && 1161 (ptr[i + offset] != '\0')) { 1162 i += snprintf(&buf[i], (size_left - i), 1163 "%c", ptr[i + offset]); 1164 } 1165 return (i); 1166 } 1167 1168 /* 1169 * Write out either the AAP1 or IOP event log 1170 */ 1171 static void 1172 pmcs_write_fwlog(pmcs_hw_t *pwp, pmcs_fw_event_hdr_t *fwlogp) 1173 { 1174 struct vnode *vnp; 1175 caddr_t fwlogfile, bufp; 1176 rlim64_t rlimit; 1177 ssize_t resid; 1178 offset_t offset = 0; 1179 int error; 1180 uint32_t data_len; 1181 1182 if (fwlogp == pwp->fwlogp_aap1) { 1183 fwlogfile = pwp->fwlogfile_aap1; 1184 } else { 1185 fwlogfile = pwp->fwlogfile_iop; 1186 } 1187 1188 if ((error = vn_open(fwlogfile, UIO_SYSSPACE, FCREAT|FWRITE, 0644, 1189 &vnp, CRCREAT, 0)) != 0) { 1190 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1191 "%s: Could not create '%s', error %d", __func__, 1192 fwlogfile, error); 1193 return; 1194 } 1195 1196 bufp = (caddr_t)fwlogp; 1197 data_len = PMCS_FWLOG_SIZE / 2; 1198 rlimit = data_len + 1; 1199 for (;;) { 1200 error = vn_rdwr(UIO_WRITE, vnp, bufp, data_len, offset, 1201 UIO_SYSSPACE, FSYNC, rlimit, CRED(), &resid); 1202 if (error) { 1203 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1204 "%s: could not write %s, error %d", __func__, 1205 fwlogfile, error); 1206 break; 1207 } 1208 if (resid == data_len) { 1209 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1210 "%s: Out of space in %s, error %d", __func__, 1211 fwlogfile, error); 1212 error = ENOSPC; 1213 break; 1214 } 1215 if (resid == 0) 1216 break; 1217 offset += (data_len - resid); 1218 data_len = (ssize_t)resid; 1219 } 1220 1221 if (error = VOP_CLOSE(vnp, FWRITE, 1, (offset_t)0, kcred, NULL)) { 1222 if (!error) { 1223 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1224 "%s: Error on close %s, error %d", __func__, 1225 fwlogfile, error); 1226 } 1227 } 1228 1229 VN_RELE(vnp); 1230 } 1231 1232 /* 1233 * Check the in-memory event log. If it's filled up to or beyond the 1234 * threshold, write it out to the configured filename. 1235 */ 1236 void 1237 pmcs_gather_fwlog(pmcs_hw_t *pwp) 1238 { 1239 uint32_t num_entries_aap1, num_entries_iop, fname_suffix; 1240 1241 ASSERT(!mutex_owned(&pwp->lock)); 1242 1243 /* 1244 * Get our copies of the latest indices 1245 */ 1246 pwp->fwlog_latest_idx_aap1 = pwp->fwlogp_aap1->fw_el_latest_idx; 1247 pwp->fwlog_latest_idx_iop = pwp->fwlogp_iop->fw_el_latest_idx; 1248 1249 /* 1250 * We need entries in the log before we can know how big they are 1251 */ 1252 if ((pwp->fwlog_max_entries_aap1 == 0) && 1253 (pwp->fwlogp_aap1->fw_el_latest_idx != 0)) { 1254 pwp->fwlog_max_entries_aap1 = 1255 (PMCS_FWLOG_SIZE / 2) / pwp->fwlogp_aap1->fw_el_entry_size; 1256 pwp->fwlog_threshold_aap1 = 1257 (pwp->fwlog_max_entries_aap1 * PMCS_FWLOG_THRESH) / 100; 1258 } 1259 1260 if ((pwp->fwlog_max_entries_iop == 0) && 1261 (pwp->fwlogp_iop->fw_el_latest_idx != 0)) { 1262 pwp->fwlog_max_entries_iop = 1263 (PMCS_FWLOG_SIZE / 2) / pwp->fwlogp_iop->fw_el_entry_size; 1264 pwp->fwlog_threshold_iop = 1265 (pwp->fwlog_max_entries_iop * PMCS_FWLOG_THRESH) / 100; 1266 } 1267 1268 /* 1269 * Check if we've reached the threshold in the AAP1 log. We do this 1270 * by comparing the latest index with our copy of the oldest index 1271 * (not the chip's). 1272 */ 1273 if (pwp->fwlog_latest_idx_aap1 >= pwp->fwlog_oldest_idx_aap1) { 1274 /* Log has not wrapped */ 1275 num_entries_aap1 = 1276 pwp->fwlog_latest_idx_aap1 - pwp->fwlog_oldest_idx_aap1; 1277 } else { 1278 /* Log has wrapped */ 1279 num_entries_aap1 = pwp->fwlog_max_entries_aap1 - 1280 (pwp->fwlog_oldest_idx_aap1 - pwp->fwlog_latest_idx_aap1); 1281 } 1282 1283 /* 1284 * Now check the IOP log 1285 */ 1286 if (pwp->fwlog_latest_idx_iop >= pwp->fwlog_oldest_idx_iop) { 1287 /* Log has not wrapped */ 1288 num_entries_iop = pwp->fwlog_latest_idx_iop - 1289 pwp->fwlog_oldest_idx_iop; 1290 } else { 1291 /* Log has wrapped */ 1292 num_entries_iop = pwp->fwlog_max_entries_iop - 1293 (pwp->fwlog_oldest_idx_iop - pwp->fwlog_latest_idx_iop); 1294 } 1295 1296 if ((num_entries_aap1 < pwp->fwlog_threshold_aap1) && 1297 (num_entries_iop < pwp->fwlog_threshold_iop)) { 1298 return; 1299 } 1300 1301 /* 1302 * Write out the necessary log file(s), update the "oldest" pointers 1303 * and the suffix to the written filenames. 1304 */ 1305 if (num_entries_aap1 >= pwp->fwlog_threshold_aap1) { 1306 pmcs_write_fwlog(pwp, pwp->fwlogp_aap1); 1307 pwp->fwlog_oldest_idx_aap1 = pwp->fwlog_latest_idx_aap1; 1308 1309 fname_suffix = strlen(pwp->fwlogfile_aap1) - 1; 1310 if (pwp->fwlogfile_aap1[fname_suffix] == '4') { 1311 pwp->fwlogfile_aap1[fname_suffix] = '0'; 1312 } else { 1313 ++pwp->fwlogfile_aap1[fname_suffix]; 1314 } 1315 } 1316 1317 if (num_entries_iop >= pwp->fwlog_threshold_iop) { 1318 pmcs_write_fwlog(pwp, pwp->fwlogp_iop); 1319 pwp->fwlog_oldest_idx_iop = pwp->fwlog_latest_idx_iop; 1320 1321 fname_suffix = strlen(pwp->fwlogfile_iop) - 1; 1322 if (pwp->fwlogfile_iop[fname_suffix] == '4') { 1323 pwp->fwlogfile_iop[fname_suffix] = '0'; 1324 } else { 1325 ++pwp->fwlogfile_iop[fname_suffix]; 1326 } 1327 } 1328 } 1329