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