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