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, 0, RB6_ACCESS)); 688 n += snprintf(&buf[n], (size_left - n), "CFG and RST = 0x%08x\n", 689 pmcs_rd_gsm_reg(pwp, 0, 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, 0, 692 RAM_ECC_DOUBLE_ERROR_INDICATOR)); 693 n += snprintf(&buf[n], (size_left - n), "READ ADR PARITY CHK EN = " 694 "0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, READ_ADR_PARITY_CHK_EN)); 695 n += snprintf(&buf[n], (size_left - n), "WRITE ADR PARITY CHK EN = " 696 "0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, WRITE_ADR_PARITY_CHK_EN)); 697 n += snprintf(&buf[n], (size_left - n), "WRITE DATA PARITY CHK EN= " 698 "0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, WRITE_DATA_PARITY_CHK_EN)); 699 n += snprintf(&buf[n], (size_left - n), 700 "READ ADR PARITY ERROR INDICATOR = 0x%08x\n", 701 pmcs_rd_gsm_reg(pwp, 0, READ_ADR_PARITY_ERROR_INDICATOR)); 702 n += snprintf(&buf[n], (size_left - n), 703 "WRITE ADR PARITY ERROR INDICATOR = 0x%08x\n", 704 pmcs_rd_gsm_reg(pwp, 0, WRITE_ADR_PARITY_ERROR_INDICATOR)); 705 n += snprintf(&buf[n], (size_left - n), 706 "WRITE DATA PARITY ERROR INDICATOR = 0x%08x\n", 707 pmcs_rd_gsm_reg(pwp, 0, WRITE_DATA_PARITY_ERROR_INDICATOR)); 708 n += snprintf(&buf[n], (size_left - n), "NMI Enable VPE0 IOP Register" 709 " = 0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, NMI_EN_VPE0_IOP)); 710 n += snprintf(&buf[n], (size_left - n), "NMI Enable VPE0 AAP1 Register" 711 " = 0x%08x\n", pmcs_rd_gsm_reg(pwp, 0, NMI_EN_VPE0_AAP1)); 712 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 713 "Dump GSM configuration registers end \n"); 714 return (n); 715 } 716 717 /* 718 * Dump PCIe Configuration Registers. 719 */ 720 static int 721 pmcs_dump_pcie_conf(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 722 { 723 int n = 0; 724 uint32_t i = 0; 725 726 n += snprintf(&buf[n], (size_left - n), "\nDump PCIe configuration " 727 "registers: \n -----------------\n"); 728 n += snprintf(&buf[n], (size_left - n), "VENID = 0x%04x\n", 729 pci_config_get16(pwp->pci_acc_handle, PCI_CONF_VENID)); 730 n += snprintf(&buf[n], (size_left - n), "DEVICE_ID = 0x%04x\n", 731 pci_config_get16(pwp->pci_acc_handle, PCI_CONF_DEVID)); 732 n += snprintf(&buf[n], (size_left - n), "CFGCMD = 0x%04x\n", 733 pci_config_get16(pwp->pci_acc_handle, PCI_CONF_COMM)); 734 n += snprintf(&buf[n], (size_left - n), "CFGSTAT = 0x%04x\n", 735 pci_config_get16(pwp->pci_acc_handle, PCI_CONF_STAT)); 736 n += snprintf(&buf[n], (size_left - n), "CLSCODE and REVID = 0x%08x\n", 737 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_REVID)); 738 n += snprintf(&buf[n], (size_left - n), "BIST HDRTYPE LATTIM CLSIZE = " 739 "0x%08x\n", 740 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_CACHE_LINESZ)); 741 n += snprintf(&buf[n], (size_left - n), "MEMBASE-I LOWER = 0x%08x\n", 742 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE0)); 743 n += snprintf(&buf[n], (size_left - n), "MEMBASE-I UPPER = 0x%08x\n", 744 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE1)); 745 n += snprintf(&buf[n], (size_left - n), "MEMBASE-II LOWER = 0x%08x\n", 746 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE2)); 747 n += snprintf(&buf[n], (size_left - n), "MEMBASE-II UPPER = 0x%08x\n", 748 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE3)); 749 n += snprintf(&buf[n], (size_left - n), "MEMBASE-III = 0x%08x\n", 750 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE4)); 751 n += snprintf(&buf[n], (size_left - n), "MEMBASE-IV = 0x%08x\n", 752 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_BASE5)); 753 n += snprintf(&buf[n], (size_left - n), "SVID = 0x%08x\n", 754 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_SUBVENID)); 755 n += snprintf(&buf[n], (size_left - n), "ROMBASE = 0x%08x\n", 756 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_ROM)); 757 n += snprintf(&buf[n], (size_left - n), "CAP_PTR = 0x%02x\n", 758 pci_config_get8(pwp->pci_acc_handle, PCI_CONF_CAP_PTR)); 759 n += snprintf(&buf[n], (size_left - n), "MAXLAT MINGNT INTPIN " 760 "INTLINE = 0x%08x\n", 761 pci_config_get32(pwp->pci_acc_handle, PCI_CONF_ILINE)); 762 n += snprintf(&buf[n], (size_left - n), "PMC PM_NEXT_CAP PM_CAP_ID = " 763 "0x%08x\n", pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_PMC)); 764 n += snprintf(&buf[n], (size_left - n), "PMCSR = 0x%08x\n", 765 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_PMCSR)); 766 n += snprintf(&buf[n], (size_left - n), 767 "MC MSI_NEXT_CAP MSI_CAP_ID = 0x%08x\n", 768 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_MSI)); 769 n += snprintf(&buf[n], (size_left - n), "MAL = 0x%08x\n", 770 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_MAL)); 771 n += snprintf(&buf[n], (size_left - n), "MAU = 0x%08x\n", 772 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_MAU)); 773 n += snprintf(&buf[n], (size_left - n), "MD = 0x%04x\n", 774 pci_config_get16(pwp->pci_acc_handle, PMCS_PCI_MD)); 775 n += snprintf(&buf[n], (size_left - n), 776 "PCIE_CAP PCIE_NEXT_CAP PCIE_CAP_ID = 0x%08x\n", 777 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_PCIE)); 778 n += snprintf(&buf[n], (size_left - n), "DEVICE_CAP = 0x%08x\n", 779 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_DEV_CAP)); 780 n += snprintf(&buf[n], (size_left - n), 781 "DEVICE_STAT DEVICE_CTRL = 0x%08x\n", 782 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_DEV_CTRL)); 783 n += snprintf(&buf[n], (size_left - n), "LINK_CAP = 0x%08x\n", 784 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_LINK_CAP)); 785 n += snprintf(&buf[n], (size_left - n), 786 "LINK_STAT LINK_CTRL = 0x%08x\n", 787 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_LINK_CTRL)); 788 n += snprintf(&buf[n], (size_left - n), "MSIX_CAP = 0x%08x\n", 789 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_MSIX_CAP)); 790 n += snprintf(&buf[n], (size_left - n), "TBL_OFFSET = 0x%08x\n", 791 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_TBL_OFFSET)); 792 n += snprintf(&buf[n], (size_left - n), "PBA_OFFSET = 0x%08x\n", 793 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_PBA_OFFSET)); 794 n += snprintf(&buf[n], (size_left - n), "PCIE_CAP_HD = 0x%08x\n", 795 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_PCIE_CAP_HD)); 796 n += snprintf(&buf[n], (size_left - n), "UE_STAT = 0x%08x\n", 797 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_UE_STAT)); 798 n += snprintf(&buf[n], (size_left - n), "UE_MASK = 0x%08x\n", 799 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_UE_MASK)); 800 n += snprintf(&buf[n], (size_left - n), "UE_SEV = 0x%08x\n", 801 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_UE_SEV)); 802 n += snprintf(&buf[n], (size_left - n), "CE_STAT = 0x%08x\n", 803 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_CE_STAT)); 804 n += snprintf(&buf[n], (size_left - n), "CE_MASK = 0x%08x\n", 805 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_CE_MASK)); 806 n += snprintf(&buf[n], (size_left - n), "ADV_ERR_CTRL = 0x%08x\n", 807 pci_config_get32(pwp->pci_acc_handle, PMCS_PCI_ADV_ERR_CTRL)); 808 for (i = 0; i < 4; i++) { 809 n += snprintf(&buf[n], (size_left - n), "HD_LOG_DW%d = " 810 "0x%08x\n", i, pci_config_get32(pwp->pci_acc_handle, 811 (PMCS_PCI_HD_LOG_DW + i * 4))); 812 } 813 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 814 "Dump PCIe configuration registers end \n"); 815 return (n); 816 } 817 /* 818 * Called with axil_lock held 819 */ 820 static boolean_t 821 pmcs_shift_axil(pmcs_hw_t *pwp, uint32_t offset) 822 { 823 uint32_t newaxil = offset & ~GSM_BASE_MASK; 824 825 ASSERT(mutex_owned(&pwp->axil_lock)); 826 ddi_put32(pwp->top_acc_handle, 827 &pwp->top_regs[PMCS_AXI_TRANS >> 2], newaxil); 828 drv_usecwait(10); 829 830 if (ddi_get32(pwp->top_acc_handle, 831 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != newaxil) { 832 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 833 "AXIL register update failed"); 834 return (B_FALSE); 835 } 836 return (B_TRUE); 837 } 838 839 static uint32_t 840 pmcs_get_axil(pmcs_hw_t *pwp) 841 { 842 uint32_t regval = 0; 843 mutex_enter(&pwp->axil_lock); 844 regval = ddi_get32(pwp->top_acc_handle, 845 &pwp->top_regs[PMCS_AXI_TRANS >> 2]); 846 mutex_exit(&pwp->axil_lock); 847 return (regval); 848 } 849 850 static void 851 pmcs_restore_axil(pmcs_hw_t *pwp, uint32_t oldaxil) 852 { 853 mutex_enter(&pwp->axil_lock); 854 ddi_put32(pwp->top_acc_handle, 855 &pwp->top_regs[PMCS_AXI_TRANS >> 2], oldaxil); 856 drv_usecwait(10); 857 858 if (ddi_get32(pwp->top_acc_handle, 859 &pwp->top_regs[PMCS_AXI_TRANS >> 2]) != oldaxil) { 860 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 861 "AXIL register restore failed"); 862 } 863 mutex_exit(&pwp->axil_lock); 864 } 865 866 /* 867 * Dump Additional GSM Registers. 868 */ 869 static int 870 pmcs_dump_gsm_addiregs(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 871 { 872 uint32_t i = 0; 873 int n = 0, j = 0, nums = 0; 874 uint32_t gsm_addr = 0, addr = 0; 875 876 n += snprintf(&buf[n], (size_left - n), "\nDump GSM Sparse Registers:" 877 "\n-----------------\n"); 878 for (i = 0; i < sizeof (gsm_spregs) / sizeof (pmcs_sparse_regs_t); 879 i++) { 880 gsm_addr = 881 gsm_spregs[i].shift_addr + gsm_spregs[i].offset_start; 882 nums = gsm_spregs[i].offset_end - gsm_spregs[i].offset_start; 883 if (gsm_spregs[i].flag & PMCS_SPREGS_BLOCK_START) { 884 n += snprintf(&buf[n], (size_left - n), "\n%s - 0x%08X" 885 "[MEMBASE-III SHIFT = 0x%08X]\nOffset:\n", 886 gsm_spregs[i].desc ? gsm_spregs[i].desc : "NULL", 887 gsm_spregs[i].base_addr, gsm_spregs[i].shift_addr); 888 } 889 890 if (nums == 0) { 891 n += snprintf(&buf[n], (size_left - n), 892 "[%04X]: %08X\n", gsm_spregs[i].offset_start, 893 pmcs_rd_gsm_reg(pwp, 0, gsm_addr)); 894 } else if (nums > 0) { 895 n += snprintf(&buf[n], (size_left - n), 896 "\n[%04X] - [%04X]: \n", gsm_spregs[i].offset_start, 897 gsm_spregs[i].offset_end); 898 899 j = 0; 900 while (nums > 0) { 901 addr = gsm_addr + j * 4; 902 n += snprintf(&buf[n], (size_left - n), 903 "[%04X]: %08X\n", addr & GSM_BASE_MASK, 904 pmcs_rd_gsm_reg(pwp, 0, addr)); 905 j++; 906 nums -= 4; 907 } 908 } 909 910 } 911 912 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 913 "------------ Dump GSM Sparse Registers end ------------\n"); 914 return (n); 915 916 } 917 918 /* 919 * Dump GSM Memory Regions. 920 */ 921 static int 922 pmcs_dump_gsm(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 923 { 924 int n = 0; 925 uint32_t i = 0; 926 uint32_t oldaxil = 0; 927 uint32_t gsm_addr = 0; 928 uint32_t *local_buf = NULL; 929 930 local_buf = kmem_zalloc(GSM_SM_BLKSZ, KM_NOSLEEP); 931 if (local_buf == NULL) { 932 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 933 "%s: local_buf memory not allocated", __func__); 934 return (0); 935 } 936 937 oldaxil = pmcs_get_axil(pwp); 938 mutex_enter(&pwp->axil_lock); 939 n += snprintf(&buf[n], (size_left - n), "\nDump GSM IO Status Table: \n" 940 " -----------------\n"); 941 for (i = 0; i < 4; i++) { 942 gsm_addr = IO_STATUS_TABLE_BASE + GSM_SM_BLKSZ * i; 943 if (pmcs_shift_axil(pwp, gsm_addr) == B_TRUE) { 944 gsm_addr &= GSM_BASE_MASK; 945 ddi_rep_get32(pwp->gsm_acc_handle, local_buf, 946 &pwp->gsm_regs[gsm_addr >> 2], GSM_SM_BLKSZ >> 2, 947 DDI_DEV_AUTOINCR); 948 n += pmcs_dump_binary(pwp, local_buf, i * GSM_SM_BLKSZ, 949 GSM_SM_BLKSZ >> 2, &buf[n], size_left - n); 950 } 951 } 952 n += snprintf(&buf[n], (size_left - n), "\n-----------------\n" 953 "Dump GSM IO Status Table end \n"); 954 n += snprintf(&buf[n], (size_left - n), "\nDump Ring Buffer Storage: \n" 955 " -----------------\n"); 956 for (i = 0; i < 2; i++) { 957 gsm_addr = RING_BUF_STORAGE_0 + GSM_SM_BLKSZ * i; 958 if (pmcs_shift_axil(pwp, gsm_addr) == B_TRUE) { 959 gsm_addr &= GSM_BASE_MASK; 960 ddi_rep_get32(pwp->gsm_acc_handle, local_buf, 961 &pwp->gsm_regs[gsm_addr >> 2], GSM_SM_BLKSZ >> 2, 962 DDI_DEV_AUTOINCR); 963 n += pmcs_dump_binary(pwp, local_buf, i * GSM_SM_BLKSZ, 964 GSM_SM_BLKSZ >> 2, &buf[n], size_left - n); 965 } 966 } 967 n += snprintf(&buf[n], (size_left - n), "\n-----------------\n" 968 "Dump Ring Buffer Storage end \n"); 969 970 n += snprintf(&buf[n], (size_left - n), "\nDump Ring Buffer Pointers:\n" 971 " -----------------\n"); 972 gsm_addr = RING_BUF_PTR_ACC_BASE + RING_BUF_PTR_OFF; 973 if (pmcs_shift_axil(pwp, gsm_addr) == B_TRUE) { 974 gsm_addr &= GSM_BASE_MASK; 975 ddi_rep_get32(pwp->gsm_acc_handle, local_buf, 976 &pwp->gsm_regs[gsm_addr >> 2], 977 RING_BUF_PTR_SIZE >> 2, DDI_DEV_AUTOINCR); 978 n += pmcs_dump_binary(pwp, local_buf, 0, 979 RING_BUF_PTR_SIZE >> 2, &buf[n], size_left - n); 980 } 981 n += snprintf(&buf[n], (size_left - n), "\n-----------------\n" 982 "Dump Ring Buffer Pointers end \n"); 983 984 n += snprintf(&buf[n], (size_left - n), "\nDump Ring Buffer Access: \n" 985 " -----------------\n"); 986 gsm_addr = RING_BUF_PTR_ACC_BASE + RING_BUF_ACC_OFF; 987 if (pmcs_shift_axil(pwp, gsm_addr) == B_TRUE) { 988 gsm_addr &= GSM_BASE_MASK; 989 ddi_rep_get32(pwp->gsm_acc_handle, local_buf, 990 &pwp->gsm_regs[gsm_addr >> 2], 991 RING_BUF_ACC_SIZE >> 2, DDI_DEV_AUTOINCR); 992 n += pmcs_dump_binary(pwp, local_buf, 0, 993 RING_BUF_ACC_SIZE >> 2, &buf[n], size_left - n); 994 } 995 n += snprintf(&buf[n], (size_left - n), "\n-----------------\n" 996 "Dump Ring Buffer Access end \n"); 997 998 n += snprintf(&buf[n], (size_left - n), "\nDump GSM SM: \n" 999 " -----------------\n"); 1000 for (i = 0; i < 16; i++) { 1001 gsm_addr = GSM_SM_BASE + GSM_SM_BLKSZ * i; 1002 if (pmcs_shift_axil(pwp, gsm_addr) == B_TRUE) { 1003 gsm_addr &= GSM_BASE_MASK; 1004 ddi_rep_get32(pwp->gsm_acc_handle, local_buf, 1005 &pwp->gsm_regs[gsm_addr >> 2], 1006 GSM_SM_BLKSZ >> 2, DDI_DEV_AUTOINCR); 1007 n += pmcs_dump_binary(pwp, local_buf, i * GSM_SM_BLKSZ, 1008 GSM_SM_BLKSZ >> 2, &buf[n], size_left - n); 1009 } 1010 } 1011 mutex_exit(&pwp->axil_lock); 1012 pmcs_restore_axil(pwp, oldaxil); 1013 1014 n += snprintf(&buf[n], (size_left - n), "\n-----------------\n" 1015 "Dump GSM SM end \n"); 1016 n += snprintf(&buf[n], (size_left - n), "-----------------\n" 1017 "\n------------ Dump GSM Memory Regions end -------------\n"); 1018 if (local_buf) { 1019 kmem_free(local_buf, GSM_SM_BLKSZ); 1020 } 1021 return (n); 1022 } 1023 1024 /* 1025 * Trace current Inbound Message host sent to SPC. 1026 */ 1027 void 1028 pmcs_iqp_trace(pmcs_hw_t *pwp, uint32_t qnum) 1029 { 1030 uint32_t k = 0; 1031 int n = 0; 1032 uint32_t *ptr = NULL; 1033 char *tbuf = pwp->iqpt->curpos; 1034 uint32_t size_left = pwp->iqpt->size_left; 1035 1036 if (tbuf == NULL) { 1037 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1038 "%s: trace buffer is not ready," 1039 " Inbound Message from host to SPC is not traced", 1040 __func__); 1041 return; 1042 } else if (size_left < PMCS_QENTRY_SIZE * PMCS_QENTRY_SIZE) { 1043 tbuf = pwp->iqpt->curpos = pwp->iqpt->head; 1044 size_left = pwp->iqpt->size_left = PMCS_IQP_TRACE_BUFFER_SIZE; 1045 } 1046 1047 ptr = &pwp->iqp[qnum][pwp->shadow_iqpi[qnum] * 1048 (PMCS_QENTRY_SIZE >> 2)]; 1049 for (k = 0; k < (PMCS_QENTRY_SIZE / sizeof (uint32_t)); 1050 k += 8) { 1051 n += snprintf(&tbuf[n], (size_left - n), 1052 "0x%08x 0x%08x 0x%08x 0x%08x " 1053 "0x%08x 0x%08x 0x%08x 0x%08x\n", 1054 LE_32(ptr[k]), LE_32(ptr[k+1]), 1055 LE_32(ptr[k+2]), LE_32(ptr[k+3]), 1056 LE_32(ptr[k+4]), LE_32(ptr[k+5]), 1057 LE_32(ptr[k+6]), LE_32(ptr[k+7])); 1058 } 1059 pwp->iqpt->size_left -= n; 1060 if (pwp->iqpt->size_left > 0) { 1061 pwp->iqpt->curpos += n; 1062 } else { 1063 pwp->iqpt->curpos = 1064 pwp->iqpt->head + PMCS_IQP_TRACE_BUFFER_SIZE - 1; 1065 } 1066 } 1067 1068 /* 1069 * Capture HSST State Registers. 1070 */ 1071 static int 1072 pmcs_dump_hsst_sregs(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 1073 { 1074 uint32_t i = 0, j = 0, addr = 0; 1075 int n = 0; 1076 1077 n += snprintf(&buf[n], (size_left - n), "\nHSST State Capture : \n" 1078 "-----------------\n"); 1079 n += snprintf(&buf[n], (size_left - n), "%s \t %s \n", 1080 hsst_state[8].desc ? hsst_state[8].desc : "NULL", 1081 hsst_state[16].desc ? hsst_state[16].desc : "NULL"); 1082 1083 for (i = 0; i < 8; i++) { 1084 addr = hsst_state[i].offset_start + 1085 hsst_state[i].shift_addr; 1086 n += snprintf(&buf[n], (size_left - n), "Phy[%1d]\n", i); 1087 for (j = 0; j < 6; j++) { 1088 pmcs_wr_gsm_reg(pwp, addr, j); 1089 pmcs_wr_gsm_reg(pwp, addr, (0x0100 + j)); 1090 addr = hsst_state[i+8].offset_start + 1091 hsst_state[i+8].shift_addr; 1092 n += snprintf(&buf[n], (size_left - n), 1093 "[%08X]: %08X\t", addr, pmcs_rd_gsm_reg(pwp, 0, 1094 addr)); 1095 addr = hsst_state[i+16].offset_start + 1096 hsst_state[i+16].shift_addr; 1097 n += snprintf(&buf[n], (size_left - n), 1098 "[%08X]: %08X\n", addr, pmcs_rd_gsm_reg(pwp, 0, 1099 addr)); 1100 } 1101 1102 } 1103 return (n); 1104 1105 } 1106 1107 /* 1108 * Capture SSPA State Registers. 1109 */ 1110 static int 1111 pmcs_dump_sspa_sregs(pmcs_hw_t *pwp, caddr_t buf, uint32_t size_left) 1112 { 1113 uint32_t i = 0, rv = 0, addr = 0; 1114 int n = 0; 1115 1116 n += snprintf(&buf[n], (size_left - n), "\nSSPA State Capture : \n" 1117 "-----------------\n"); 1118 for (i = 0; i < 8; i++) { 1119 if (sspa_state[i].flag & PMCS_SPREGS_BLOCK_START) { 1120 n += snprintf(&buf[n], (size_left - n), "%s \n", 1121 sspa_state[i].desc ? sspa_state[i].desc : "NULL"); 1122 } 1123 addr = sspa_state[i].offset_start + sspa_state[i].shift_addr; 1124 rv = pmcs_rd_gsm_reg(pwp, 0, addr); 1125 rv |= PMCS_SSPA_CONTROL_REGISTER_BIT27; 1126 pmcs_wr_gsm_reg(pwp, addr, rv); 1127 n += snprintf(&buf[n], (size_left - n), "[%08X]: %08X \n", 1128 addr, pmcs_rd_gsm_reg(pwp, 0, addr)); 1129 1130 } 1131 return (n); 1132 } 1133 1134 /* 1135 * Dump fatal error register content from GSM. 1136 */ 1137 int 1138 pmcs_dump_feregs(pmcs_hw_t *pwp, uint32_t *addr, uint8_t nvmd, 1139 caddr_t buf, uint32_t size_left) 1140 { 1141 uint32_t offset = 0, length = 0; 1142 int i = 0; 1143 uint8_t *ptr = (uint8_t *)addr; 1144 1145 if ((addr == NULL) || (buf == NULL)) { 1146 return (0); 1147 } 1148 switch (nvmd) { 1149 case PMCIN_NVMD_AAP1: 1150 offset = pmcs_rd_mpi_tbl(pwp, PMCS_FERDOMSGU); 1151 length = pmcs_rd_mpi_tbl(pwp, PMCS_FERDLMSGU); 1152 break; 1153 case PMCIN_NVMD_IOP: 1154 offset = pmcs_rd_mpi_tbl(pwp, PMCS_FERDOIOP); 1155 length = pmcs_rd_mpi_tbl(pwp, PMCS_FERDLIOP); 1156 break; 1157 default: 1158 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1159 "UNKNOWN NVMD DEVICE %s():%d", __func__, __LINE__); 1160 return (0); 1161 } 1162 1163 while ((i < length) && (ptr[i + offset] != 0xff) && 1164 (ptr[i + offset] != '\0')) { 1165 i += snprintf(&buf[i], (size_left - i), 1166 "%c", ptr[i + offset]); 1167 } 1168 return (i); 1169 } 1170 1171 /* 1172 * Write out either the AAP1 or IOP event log 1173 */ 1174 static void 1175 pmcs_write_fwlog(pmcs_hw_t *pwp, pmcs_fw_event_hdr_t *fwlogp) 1176 { 1177 struct vnode *vnp; 1178 caddr_t fwlogfile, bufp; 1179 rlim64_t rlimit; 1180 ssize_t resid; 1181 offset_t offset = 0; 1182 int error; 1183 uint32_t data_len; 1184 1185 if (fwlogp == pwp->fwlogp_aap1) { 1186 fwlogfile = pwp->fwlogfile_aap1; 1187 } else { 1188 fwlogfile = pwp->fwlogfile_iop; 1189 } 1190 1191 if ((error = vn_open(fwlogfile, UIO_SYSSPACE, FCREAT|FWRITE, 0644, 1192 &vnp, CRCREAT, 0)) != 0) { 1193 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1194 "%s: Could not create '%s', error %d", __func__, 1195 fwlogfile, error); 1196 return; 1197 } 1198 1199 bufp = (caddr_t)fwlogp; 1200 data_len = PMCS_FWLOG_SIZE / 2; 1201 rlimit = data_len + 1; 1202 for (;;) { 1203 error = vn_rdwr(UIO_WRITE, vnp, bufp, data_len, offset, 1204 UIO_SYSSPACE, FSYNC, rlimit, CRED(), &resid); 1205 if (error) { 1206 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1207 "%s: could not write %s, error %d", __func__, 1208 fwlogfile, error); 1209 break; 1210 } 1211 if (resid == data_len) { 1212 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1213 "%s: Out of space in %s, error %d", __func__, 1214 fwlogfile, error); 1215 error = ENOSPC; 1216 break; 1217 } 1218 if (resid == 0) 1219 break; 1220 offset += (data_len - resid); 1221 data_len = (ssize_t)resid; 1222 } 1223 1224 if (error = VOP_CLOSE(vnp, FWRITE, 1, (offset_t)0, kcred, NULL)) { 1225 if (!error) { 1226 pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, 1227 "%s: Error on close %s, error %d", __func__, 1228 fwlogfile, error); 1229 } 1230 } 1231 1232 VN_RELE(vnp); 1233 } 1234 1235 /* 1236 * Check the in-memory event log. If it's filled up to or beyond the 1237 * threshold, write it out to the configured filename. 1238 */ 1239 void 1240 pmcs_gather_fwlog(pmcs_hw_t *pwp) 1241 { 1242 uint32_t num_entries_aap1, num_entries_iop, fname_suffix; 1243 1244 ASSERT(!mutex_owned(&pwp->lock)); 1245 1246 /* 1247 * Get our copies of the latest indices 1248 */ 1249 pwp->fwlog_latest_idx_aap1 = pwp->fwlogp_aap1->fw_el_latest_idx; 1250 pwp->fwlog_latest_idx_iop = pwp->fwlogp_iop->fw_el_latest_idx; 1251 1252 /* 1253 * We need entries in the log before we can know how big they are 1254 */ 1255 if ((pwp->fwlog_max_entries_aap1 == 0) && 1256 (pwp->fwlogp_aap1->fw_el_latest_idx != 0)) { 1257 pwp->fwlog_max_entries_aap1 = 1258 (PMCS_FWLOG_SIZE / 2) / pwp->fwlogp_aap1->fw_el_entry_size; 1259 pwp->fwlog_threshold_aap1 = 1260 (pwp->fwlog_max_entries_aap1 * PMCS_FWLOG_THRESH) / 100; 1261 } 1262 1263 if ((pwp->fwlog_max_entries_iop == 0) && 1264 (pwp->fwlogp_iop->fw_el_latest_idx != 0)) { 1265 pwp->fwlog_max_entries_iop = 1266 (PMCS_FWLOG_SIZE / 2) / pwp->fwlogp_iop->fw_el_entry_size; 1267 pwp->fwlog_threshold_iop = 1268 (pwp->fwlog_max_entries_iop * PMCS_FWLOG_THRESH) / 100; 1269 } 1270 1271 /* 1272 * Check if we've reached the threshold in the AAP1 log. We do this 1273 * by comparing the latest index with our copy of the oldest index 1274 * (not the chip's). 1275 */ 1276 if (pwp->fwlog_latest_idx_aap1 >= pwp->fwlog_oldest_idx_aap1) { 1277 /* Log has not wrapped */ 1278 num_entries_aap1 = 1279 pwp->fwlog_latest_idx_aap1 - pwp->fwlog_oldest_idx_aap1; 1280 } else { 1281 /* Log has wrapped */ 1282 num_entries_aap1 = pwp->fwlog_max_entries_aap1 - 1283 (pwp->fwlog_oldest_idx_aap1 - pwp->fwlog_latest_idx_aap1); 1284 } 1285 1286 /* 1287 * Now check the IOP log 1288 */ 1289 if (pwp->fwlog_latest_idx_iop >= pwp->fwlog_oldest_idx_iop) { 1290 /* Log has not wrapped */ 1291 num_entries_iop = pwp->fwlog_latest_idx_iop - 1292 pwp->fwlog_oldest_idx_iop; 1293 } else { 1294 /* Log has wrapped */ 1295 num_entries_iop = pwp->fwlog_max_entries_iop - 1296 (pwp->fwlog_oldest_idx_iop - pwp->fwlog_latest_idx_iop); 1297 } 1298 1299 if ((num_entries_aap1 < pwp->fwlog_threshold_aap1) && 1300 (num_entries_iop < pwp->fwlog_threshold_iop)) { 1301 return; 1302 } 1303 1304 /* 1305 * We also can't write the event log out if it's too early in boot 1306 * (i.e. the root fs isn't mounted yet). 1307 */ 1308 if (!modrootloaded) { 1309 return; 1310 } 1311 1312 /* 1313 * Write out the necessary log file(s), update the "oldest" pointers 1314 * and the suffix to the written filenames. 1315 */ 1316 if (num_entries_aap1 >= pwp->fwlog_threshold_aap1) { 1317 pmcs_write_fwlog(pwp, pwp->fwlogp_aap1); 1318 pwp->fwlog_oldest_idx_aap1 = pwp->fwlog_latest_idx_aap1; 1319 1320 fname_suffix = strlen(pwp->fwlogfile_aap1) - 1; 1321 if (pwp->fwlogfile_aap1[fname_suffix] == '4') { 1322 pwp->fwlogfile_aap1[fname_suffix] = '0'; 1323 } else { 1324 ++pwp->fwlogfile_aap1[fname_suffix]; 1325 } 1326 } 1327 1328 if (num_entries_iop >= pwp->fwlog_threshold_iop) { 1329 pmcs_write_fwlog(pwp, pwp->fwlogp_iop); 1330 pwp->fwlog_oldest_idx_iop = pwp->fwlog_latest_idx_iop; 1331 1332 fname_suffix = strlen(pwp->fwlogfile_iop) - 1; 1333 if (pwp->fwlogfile_iop[fname_suffix] == '4') { 1334 pwp->fwlogfile_iop[fname_suffix] = '0'; 1335 } else { 1336 ++pwp->fwlogfile_iop[fname_suffix]; 1337 } 1338 } 1339 } 1340