emlxs_dump.c revision a9800beb32c1006bb21c8da39e0180ea440b7bad
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Emulex. All rights reserved.
* Use is subject to license terms.
*/
#include <emlxs.h>
#ifdef DUMP_SUPPORT
/* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
/* ************************************************************************* */
/* Utility functions */
/* ************************************************************************* */
static uint32_t
{
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_set_cmd_t);
rsp_size = 4;
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_set_mode: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_set_mode: Menlo command error. code=%d.\n",
}
done:
if (cmd_buf) {
}
if (rsp_buf) {
}
return (rval);
} /* emlxs_menlo_set_mode() */
static uint32_t
{
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_reset_cmd_t);
rsp_size = 4;
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_reset: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_reset: Menlo command error. code=%d.\n",
}
done:
if (cmd_buf) {
}
if (rsp_buf) {
}
return (rval);
} /* emlxs_menlo_reset() */
static uint32_t
{
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_get_cmd_t);
rsp_size = sizeof (menlo_get_config_rsp_t);
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_get_cfg: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_get_cfg: Menlo command error. code=%d.\n",
}
done:
if (cmd_buf) {
}
return (rval);
} /* emlxs_menlo_get_cfg() */
static uint32_t
{
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_get_cmd_t);
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_get_logcfg: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_get_logcfg: Menlo command error. code=%d.\n",
}
done:
if (cmd_buf) {
}
return (rval);
} /* emlxs_menlo_get_logcfg() */
static uint32_t
{
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_get_cmd_t);
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_get_log: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_get_log: Menlo command error. code=%d.\n",
}
done:
if (cmd_buf) {
}
return (rval);
} /* emlxs_menlo_get_log() */
static uint32_t
{
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_get_cmd_t);
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_get_paniclog: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
"emlxs_menlo_get_paniclog: Menlo command error. code=%d.\n",
}
done:
if (cmd_buf) {
}
return (rval);
} /* emlxs_menlo_get_paniclog() */
extern void
{
}
return;
} /* emlxs_fflush() */
extern uint32_t
{
return (offset);
} /* emlxs_ftell() */
static void
{
}
return;
} /* emlxs_fputc() */
static uint32_t
{
if (length) {
offset =
}
if (length) {
}
}
return (length);
} /* emlxs_fwrite() */
static uint32_t
const char *fmt, ...)
{
char va_str[1024];
return (length);
} /* emlxs_fprintf() */
extern emlxs_file_t *
{
switch (file_type) {
case EMLXS_TXT_FILE:
break;
case EMLXS_DMP_FILE:
break;
case EMLXS_CEE_FILE:
break;
default:
return (NULL);
}
/* Make sure it is word aligned */
} else {
}
return (fp);
} /* emlxs_fopen() */
extern uint32_t
{
return (0);
}
switch (offset) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
}
return (0);
} /* emlxs_fclose() */
static void
{
return;
}
}
return;
} /* emlxs_fdelete() */
/* This builds a single core buffer for the IOCTL interface */
extern uint32_t
{
int32_t i;
if (!buflen) {
"emlxs_get_dump: Buffer length = 0");
return (1);
}
size = 0;
count = 0;
if (size_txt) {
count++;
}
if (size_dmp) {
count++;
}
if (size_cee) {
count++;
}
if (size) {
size += 4;
}
if (!buffer) {
goto done;
}
"emlxs_get_dump: Buffer length too small. %d < %d",
*buflen = 0;
return (1);
}
i = 1;
if (size_txt) {
wptr[i++] = EMLXS_TXT_FILE_ID;
}
if (size_dmp) {
wptr[i++] = EMLXS_DMP_FILE_ID;
}
if (size_cee) {
wptr[i++] = EMLXS_FAT_FILE_ID;
} else {
wptr[i++] = EMLXS_CEE_FILE_ID;
}
}
if (size_txt) {
}
if (size_dmp) {
}
if (size_cee) {
}
done:
/* printf("Done. buflen=%d \n", *buflen); */
return (0);
} /* emlxs_get_dump() */
static uint32_t
{
mbq =
Offset = 0; /* start at offset 0 */
*pRetByteCount = 0; /* init returned byte count */
CopyCount = 0;
ByteCountRem -= CopyCount) {
/* Clear the local dump_region */
MBX_SUCCESS) {
"Unable to read config region. id=%x "\
"offset=%x status=%x",
return (1);
}
/* if no more data returned */
if (CopyCount == 0) {
break;
}
if (CopyCount > ByteCountReq) {
"emlxs_read_cfg_region: " \
"Byte count too big. %d > %d\n",
}
} else {
MBX_SUCCESS) {
"Unable to read config region. id=%x "\
"offset=%x status=%x",
return (1);
}
/* Note: for Type 2/3 Dumps, varDmp.word_cnt is */
/* actually a byte count. */
/* if no more data returned */
if (CopyCount == 0) {
break;
}
if (CopyCount > ByteCountReq) {
"emlxs_read_cfg_region: " \
"Byte count too big. %d > %d\n",
}
}
*pRetByteCount += CopyCount;
}
return (0);
} /* emlxs_read_cfg_region() */
/* ************************************************************************* */
/* ************************************************************************* */
/* Dump Generators, Low-Level */
/* ************************************************************************* */
/* ************************************************************************* */
static uint32_t
char *pString,
char *pSidLegend,
char *pLidLegend,
{
if (!fpTxtFile) {
return (1);
}
if (pSidLegend && pLidLegend) {
if (pure == 0) {
}
if (pure == 0) {
}
} else {
if (pure == 0) {
}
}
return (0);
} /* emlxs_dump_string_txtfile() */
static uint32_t
char *pSidLegend,
char *pLidLegend)
{
char buf1[256];
char buf2[256];
uint32_t j;
if (!fpTxtFile) {
return (1);
}
/* Write Legend String to the TXT File */
/* Write the buffer to the TXT File */
for (j = 0; j < WordCount; j++) {
buf1[0] = 0;
buf2[0] = 0;
if ((j & 0x03) == 0) {
}
}
return (0);
} /* emlxs_dump_word_txtfile() */
static uint32_t
char *pString,
char *pSidLegend,
char *pLidLegend)
{
if (!fpDmpFile) {
return (1);
}
/* Write Legend SID to the DMP File */
/* Write Argument SID to the DMP File */
/* Write Legend String to the DMP File, including a Null Byte */
emlxs_fputc(0, fpDmpFile);
/* Write Argument SID to the DMP File */
/* Write Buffer Length to the DMP File */
#ifdef EMLXS_LITTLE_ENDIAN
#endif /* EMLXS_LITTLE_ENDIAN */
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
/* Write Argument String to the DMP File, including a Null Byte */
emlxs_fputc(0, fpDmpFile);
/* check file size.. pad as necessary */
switch (pos & 0x03) {
case 0:
break;
case 1:
emlxs_fputc(0, fpDmpFile);
emlxs_fputc(0, fpDmpFile);
emlxs_fputc(0, fpDmpFile);
break;
case 2:
emlxs_fputc(0, fpDmpFile);
emlxs_fputc(0, fpDmpFile);
break;
case 3:
emlxs_fputc(0, fpDmpFile);
break;
}
#endif
return (0);
} /* emlxs_dump_string_dmpfile() */
/* ************************************************************************** */
/* emlxs_dump_word_dmpfile */
/* If little endian, just write the buffer normally. */
/* However, if Big Endian... Consider the following: */
/* Automatic Dump, initiated by driver, Port Offline (FW WarmStart Mode), */
/* Mailbox in SLIM. */
/* On-Demand Dump, initiated by utility, Port Online (FW Normal Mode), */
/* Mailbox in Host Memory. */
/* We use the same IOCTL to get the DUMP Data, for both cases. */
/* However, it normalizes the data before delivering it to us. */
/* In the Dump File, we must always write the data in native mode. */
/* So, if Big Endian, On-demand Dump, we must swap the words. */
/* ************************************************************************* */
/*ARGSUSED*/
extern uint32_t
int fSwap)
{
uint32_t i;
if (!fpDmpFile) {
return (1);
}
if (fSwap) {
}
}
return (0);
} /* emlxs_dump_word_dmpfile() */
static uint32_t
int fSwap)
{
uint32_t w;
uint8_t b;
if (!fpDmpFile) {
return (1);
}
/* Write Argument SID to the DMP File */
emlxs_fputc(b, fpDmpFile);
#ifdef EMLXS_LITTLE_ENDIAN
/* Write Buffer Length to the DMP File */
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
/* Write address to the DMP File */
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
#endif /* EMLXS_LITTLE_ENDIAN */
#ifdef EMLXS_BIG_ENDIAN
/* Write Buffer Length to the DMP File */
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
/* Write address to the DMP File */
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
#endif /* EMLXS_BIG_ENDIAN */
status =
return (status);
} /* emlxs_dump_port_block() */
static uint32_t
int fSwap)
{
uint32_t w;
uint8_t b;
if (!fpDmpFile) {
return (1);
}
/* Write Argument SID to the DMP File */
emlxs_fputc(b, fpDmpFile);
/* Write Element Length to the DMP File */
emlxs_fputc(b, fpDmpFile);
#ifdef EMLXS_LITTLE_ENDIAN
/* Write Element Count to the DMP File */
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
/* Write Address to the DMP File */
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
#endif /* EMLXS_LITTLE_ENDIAN */
#ifdef EMLXS_BIG_ENDIAN
/* Write Element Count to the DMP File */
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
/* Write Address to the DMP File */
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
#endif /* EMLXS_BIG_ENDIAN */
status =
return (status);
} /* emlxs_dump_port_struct() */
static uint32_t
char *pSidLegend,
char *pLidLegend,
int fSwap)
{
if (!fpDmpFile) {
return (1);
}
/* Write Legend SID to the DMP File */
/* Write Argument SID to the DMP File */
/* Write Legend String to the DMP File, including a Null Byte */
emlxs_fputc(0, fpDmpFile);
/* Write Argument SID to the DMP File */
/* Write Buffer Length to the DMP File */
#ifdef EMLXS_LITTLE_ENDIAN
#endif /* EMLXS_LITTLE_ENDIAN */
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
status =
return (status);
} /* emlxs_dump_host_block() */
static uint32_t
char *pSidLegend,
char *pLidLegend,
int fSwap)
{
uint32_t w;
uint8_t b;
if (!fpDmpFile) {
return (1);
}
/* Write Legend SID to the DMP File */
/* Write Argument SID to the DMP File */
/* Write Legend String to the DMP File, including a Null Byte */
emlxs_fputc(0, fpDmpFile);
/* Write Argument SID to the DMP File */
/* Write Element Length to the DMP File */
b = (uint8_t)elementLength;
emlxs_fputc(b, fpDmpFile);
/* Write Element Count to the DMP File */
w = elementCount;
#ifdef EMLXS_LITTLE_ENDIAN
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
emlxs_fputc(b, fpDmpFile);
#endif /* EMLXS_LITTLE_ENDIAN */
#ifdef EMLXS_BIG_ENDIAN
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
#endif /* EMLXS_BIG_ENDIAN */
status =
return (status);
} /* emlxs_dump_host_struct() */
/* ************************************************************************* */
/* ************************************************************************* */
/* Dump Generators, Mid-Level */
/* ************************************************************************* */
/* ************************************************************************* */
static uint32_t
{
uint32_t i;
/* vars used to build the Dump String */
char *buf1;
char *buf2;
/* Driver Parameters Heading */
"IDX string Low "\
"High Def Cur Exp Dyn");
/* Build the buffer containing all the Driver Params */
for (i = 0; i < NUM_CFG_PARAM; i++) {
"\n %02x: %25s %8x %8x %8x %8x %4x %4x", i,
}
status =
LEGEND_NULL, 0);
status =
return (status);
} /* emlxs_dump_parm_table() */
static uint32_t
{
/* vars used to build the Dump String */
char buf1[512];
char buf2[512];
/* Write the Model into the buffer */
/* Write the Model Description into the buffer */
status =
LEGEND_HBA_MODEL, 0);
status =
return (status);
} /* emlxs_dump_model() */
static uint32_t
{
/* vars used to build the Dump String */
char buf1[512];
char buf2[512];
int i;
uint8_t *p;
/* Write the WWPN into the buffer */
for (i = 0; i < 7; i++) {
}
/* Write the WWNN into the buffer */
for (i = 0; i < 7; i++) {
}
status =
LEGEND_HBA_WWN, 0);
status =
return (status);
} /* emlxs_dump_wwn() */
static uint32_t
{
/* vars used to build the Dump String */
char buf1[512];
char buf2[512];
/* Write the Serial Number into the buffer */
status =
LEGEND_HBA_SN, 0);
status =
return (status);
} /* emlxs_dump_serial_number() */
static uint32_t
{
char *buf1;
char *buf2;
buf1_size = 1024;
buf2_size = 1024;
/* Write the Firmware Version into the buffer */
/* Write the Operational FW Version into the buffer */
/* Write the SLI-1 FW Version into the buffer */
/* Write the SLI-2 FW Version into the buffer */
/* Write the SLI-3 FW Version into the buffer */
/* Write the Kernel FW Version into the buffer */
status =
status =
return (status);
} /* emlxs_dump_fw_version() */
static uint32_t
{
char *buf1;
char *buf2;
buf1_size = 1024;
buf2_size = 1024;
#ifdef EMLXS_SPARC
#else
#endif /* EMLXS_SPARC */
{
} else {
}
/* Write the Boot Bios State into the buffer */
/* Write the Boot Bios Version into the buffer */
if (state == 2) {
} else {
#ifdef EMLXS_SPARC
#else
#endif /* EMLXS_SPARC */
}
status =
status =
return (status);
} /* emlxs_dump_boot_version() */
/* ARGSUSED */
static uint32_t
char *pLidLegend,
{
char *buf1; /* text buffer */
char *buf2; /* text buffer */
buf1_size = 1024;
buf2_size = 1024;
/* Write the Initial ID into the buffer */
/* Write the Flags Word into the buffer */
/* Write the Boot Bios ID into the buffer */
/* Write the SLI1 ID into the buffer */
/* Write the SLI2 ID into the buffer */
/* Write the SLI3 ID into the buffer */
/* Write the SLI4 ID into the buffer */
/* Write the Erom ID into the buffer */
status =
return (status);
} /* emlxs_dump_cfg_region4_decoded() */
/* ARGSUSED */
char *pLidLegend,
char *pBuffer,
{
char *buf1; /* text buffer */
char *buf2; /* text buffer */
int i;
char mnemonic[4];
#ifdef EMLXS_BIG_ENDIAN
#endif
buf1_size = 1024;
buf2_size = 1024;
/* If Big Endian, swap the data in place, */
/* because it's PCI Data (Little Endian) */
#ifdef EMLXS_BIG_ENDIAN
}
#endif /* EMLXS_BIG_ENDIAN */
/* Decode the VPD Data and write it into the buffer */
/* CR 26941 */
/* NOTE: The following code is correct, */
/* should work, and used to work. */
/* pBuffer points to char, and the symbol VPD_TAG_82 is 0x82. */
/* The test is an equality test, not a relational test. */
/* The compiler should generate an 8 bit test, and */
/* sign extension does not apply. */
/* I don't know when or why it stopped working, */
/* and don't have time to dig. */
/* The cast fixes it. */
if (((unsigned char)pBuffer[0]) != VPD_TAG_82) {
} else { /* begin good data */
i = 0;
while (!fDone) {
switch (tag) {
case VPD_TAG_82:
1) : length] = 0;
i += length;
break;
case VPD_TAG_90:
for (;;) {
mnemonic[2] = 0;
break;
}
if (mnemonic[0] == 0) {
break;
}
mnemonic);
length2 >
1) : length2] = 0;
i += length2;
}
break;
default:
break;
} /* end switch */
} /* end while */
} /* good data */
status =
return (status);
} /* emlxs_dump_cfg_region14_decoded() */
static uint32_t
char *pLidLegend,
int fSwap)
{
char *buf1; /* string ops buffer */
char *buf2; /* string ops buffer */
int i;
#ifdef EMLXS_LITTLE_ENDIAN
#endif /* EMLXS_LITTLE_ENDIAN */
buf1_size = 4096;
buf2_size = 1024;
buffer =
status =
if (status != 0) {
return (status);
}
/* Write the Data into the buffer */
for (i = 0; i < (int)RetByteCount / 4; i++) {
if ((i % 8 == 0) && (i != 0)) {
}
}
status =
pLidLegend, 0);
if (Region == 4) {
status =
}
if (Region == 14) {
status =
}
return (status);
} /* emlxs_dump_cfg_region() */
static uint32_t
{
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
status =
return (status);
} /* emlxs_dump_cfg_regions() */
/*ARGSUSED*/
static uint32_t
{
char *buf1;
char *buf2;
buf1_size = 1024;
buf2_size = 1024;
/* First, write the OS Name string into the buffer */
/* Second, write the Version Info into the buffer */
status =
status =
return (status);
} /* emlxs_dump_os_version() */
/*ARGSUSED*/
static uint32_t
{
char *buf1;
char *buf2;
buf1_size = 1024;
buf2_size = 1024;
/* Write the Driver Type into the buffer */
/* Write the Driver Name into the buffer */
/* Write the Driver Version into the buffer */
status =
status =
return (status);
} /* emlxs_dump_drv_version() */
static uint32_t
{
if (fpTxtFile) {
/* Create the Dump Files */
return (1);
}
}
if (fpCeeFile) {
if ((*fpCeeFile =
return (1);
}
}
}
if (fpDmpFile) {
return (1);
}
/* Initialize the DMP File */
/* Write the single-byte Dump Identification */
/* SID to the DMP File */
#ifdef EMLXS_LITTLE_ENDIAN
#endif /* EMLXS_LITTLE_ENDIAN */
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
}
return (0);
} /* emlxs_dump_file_create() */
static uint32_t
{
if (fpTxtFile) {
/* Write a suitable string to the Dump TXT File */
}
if (fpCeeFile) {
}
}
/* Write the single-byte Dump Termination SID to the DMP File */
if (fpDmpFile) {
}
return (0);
} /* emlxs_dump_file_terminate() */
static uint32_t
{
if (fpTxtFile) {
(void) emlxs_fclose(fpTxtFile);
}
if (fpCeeFile) {
(void) emlxs_fclose(fpCeeFile);
}
if (fpDmpFile) {
(void) emlxs_fclose(fpDmpFile);
}
return (0);
} /* emlxs_dump_file_close() */
/* ************************************************************************* */
/* ************************************************************************* */
/* Dump Generators, High Level */
/* ************************************************************************* */
/* ************************************************************************* */
static uint32_t
{
return (0);
} /* emlxs_dump_rev_info() */
/* ARGSUSED */
static uint32_t
{
return (0);
} /* emlxs_dump_hba_info() */
/* ************************************************************************* */
/* emlxs_dump_table_check */
/* Examine Dump Table, and determine its size. */
/* Count and include ID SIDs, and the TERM SID, */
/* but not the Pointer at Addr 654. */
/* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */
/* ************************************************************************* */
static uint32_t
{
*pSize = 0;
/* Read 1 word from low memory at address 654; */
/* save the returned Dump Table Base Address */
mbq =
/* Read the dump table address */
"Unable to read dump table address. "\
"offset=0x654 status=%x",
return (1);
}
if (DumpTableAddr == 0) {
return (1);
}
/* Now loop reading Dump Table Entries.. */
/* break out when we see a Terminator SID */
while (!fDone) {
MBX_SUCCESS) {
"Unable to read dump table entry. "\
"offset=%x status=%x",
return (1);
}
/* New Dump Table */
case SID_ID01:
tableSize++;
DumpTableAddr += 4;
break;
#ifdef CC_DUMP_USE_ALL_TABLES
/* New Dump Table */
case SID_ID02:
case SID_ID03:
tableSize++;
DumpTableAddr += 4;
break;
#else
/* New Dump Table */
case SID_ID02:
case SID_ID03:
tableSize++;
break;
#endif /* CC_DUMP_USE_ALL_TABLES */
/* Dump Table(s) Termination - all done */
case SID_TERM:
tableSize++;
break;
/* Dump Table Entry */
default:
tableSize += 2;
DumpTableAddr += 8;
break;
}
} /* end while */
return (0);
} /* emlxs_dump_table_check() */
/* ************************************************************************ */
/* emlxs_dump_table_read */
/* Read the Dump Table and store it, for use */
/* subsequently in emlxs_dump_hba_memory. */
/* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */
/* ************************************************************************ */
static uint32_t
{
char buf2[256];
char *buf1;
/* First, check the dump table and if valid, get its size */
if (status != 0) {
return (status);
}
/* Allocate a buffer to hold the Dump Table */
/* Read 1 word from low memory at address 654; */
/* save the returned Dump Table Base Address */
mbq =
/* Read the dump table address */
"Unable to read dump table address. "\
"offset=0x654 status=%x",
*pDumpTableSize = 0;
*ppDumpTable = NULL;
return (1);
}
if (DumpTableAddr == 0) {
*pDumpTableSize = 0;
*ppDumpTable = NULL;
return (1);
}
/* Now loop reading Dump Table Entries.. */
/* break out when we see a Terminator SID */
while (!fDone) {
MBX_SUCCESS) {
"Unable to read dump table entry. "\
"offset=%x status=%x",
*pDumpTableSize = 0;
*ppDumpTable = NULL;
return (1);
}
/* New Dump Table */
case SID_ID01:
DumpTableAddr += 4;
break;
#ifdef CC_DUMP_USE_ALL_TABLES
/* New Dump Table */
case SID_ID02:
case SID_ID03:
DumpTableAddr += 4;
break;
#else
/* New Dump Table */
case SID_ID02:
case SID_ID03:
break;
#endif /* CC_DUMP_USE_ALL_TABLES */
/* Dump Table(s) Termination - all done */
case SID_TERM:
break;
/* Dump Table Entry */
default:
DumpTableAddr += 8;
break;
}
} /* end while */
status =
if (status != 0) {
*pDumpTableSize = 0;
*ppDumpTable = NULL;
return (status);
}
return (0);
} /* emlxs_dump_table_read() */
/* ************************************************************************* */
/* emlxs_dump_hba_memory */
/* Guided by the Dump Table previously read in, */
/* generate the Port Memory Dump. */
/* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */
/* ************************************************************************* */
static uint32_t
{
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
if (!fpDmpFile) {
return (1);
}
mbq =
/* loop reading Dump Table Entries.. break out when */
/* we see a Terminator SID */
while (!fDone) {
/* New Dump Table */
case SID_ID01:
break;
#ifdef CC_DUMP_USE_ALL_TABLES
/* New Dump Table */
case SID_ID02:
case SID_ID03:
break;
#else
/* New Dump Table */
case SID_ID02:
case SID_ID03:
break;
#endif /* CC_DUMP_USE_ALL_TABLES */
/* Dump Table(s) Termination - all done */
case SID_TERM:
break;
default:
/* Dump Table Entry */
#ifdef CC_DUMP_FW_BUG_1
break;
}
#endif /* CC_DUMP_FW_BUG_1 */
/* Check if indirect address, and */
/* obtain the new address if so */
offset =
addr & 0x01FFFFFF);
0) != MBX_SUCCESS) {
"Unable to read dump table entry. "\
"offset=%x status=%x",
return (1);
}
/* replace the indirect address in the */
/* Dump Table */
}
/* determine byte count to dump */
256 *
} else {
}
}
"Dump: addr=%x count=%d total=%d", offset,
/* allocate a buffer to receive the dump data */
/* loop issuing MBX commands, 18x measly words at */
/* a time */
/* init vars */
for (;;) {
if (byteCountRem == 0) {
break;
}
wcount =
(byteCountRem / 4 >=
0) != MBX_SUCCESS) {
"Unable to read dump table entry."\
" offset=%x wc=%d status=%x",
break;
}
} /* end for */
if (status == 0) {
sid & SID_MULT_ELEM) {
status =
} else {
status =
}
}
if (pBuf) {
}
break;
} /* end switch */
} /* end while */
return (status);
} /* emlxs_dump_hba_memory() */
static uint32_t
{
uint32_t *pDumpTable = 0;
uint32_t DumpTableSize = 0;
return (1);
}
/* HBA should be in WARM state here */
status =
if (status) {
return (status);
}
if (pDumpTable != 0) {
}
return (status);
} /* emlxs_dump_hba() */
/* ************************************************************************* */
/* emlxs_dump_drv_region */
/* Common subroutine for all the Dump_Sli"Structures" Routines */
/* NOTE: This routine does not free pBuf. This is by design. */
/* The caller does it. */
/* ************************************************************************* */
static uint32_t
{ /* ptr to length of buffer */
*pBufLen = 0;
size = 0;
if (status != 0) {
return (1);
}
/* Now that we know the required length, request the actual data */
if (status != 0) {
return (1);
}
return (status);
} /* emlxs_dump_drv_region() */
static uint32_t
{
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
if (!fpDmpFile) {
return (1);
}
if (status != 0) {
return (status);
}
status =
return (status);
} /* emlxs_dump_sli_regs() */
static uint32_t
{
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
if (status != 0) {
return (status);
}
/* The SLIM Dump is only useful if it's a */
/* Driver-Initiated dump, say, after a HW Error */
if (dump_type == DUMP_TYPE_DRIVER) {
status =
}
status =
return (status);
} /* emlxs_dump_slim() */
static uint32_t
{
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
if (!fpDmpFile) {
return (1);
}
if (status != 0) {
return (status);
}
status =
return (status);
} /* emlxs_dump_pcb() */
static uint32_t
{
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
if (!fpDmpFile) {
return (1);
}
if (status != 0) {
return (status);
}
status =
return (status);
} /* emlxs_dump_mbox() */
static uint32_t
{
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
if (!fpDmpFile) {
return (1);
}
if (status != 0) {
return (status);
}
status =
return (status);
} /* emlxs_dump_host_pointers() */
static uint32_t
{
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
if (!fpDmpFile) {
return (1);
}
if (status != 0) {
return (status);
}
status =
return (status);
} /* emlxs_dump_port_pointers() */
static uint32_t
{
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
if (!fpDmpFile) {
return (1);
}
if (status != 0) {
return (status);
}
status =
return (status);
} /* emlxs_dump_rings() */
static uint32_t
{
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
if (!fpDmpFile) {
return (1);
}
if (status != 0) {
return (status);
}
status =
return (status);
} /* emlxs_dump_drv_internals() */
static uint32_t
{
/* HBA should be in OFFLINE state here */
}
return (0);
} /* emlxs_dump_sli_interface() */
static uint32_t
{
int i, j;
char buf1[2048] = { 0 };
char buf2[2048] = { 0 };
/* Get Config Command vars */
/* Get Log Config Command vars */
/* Get Log Data Command vars */
char *pLogString;
/* Get Panic Log Command vars */
return (DFC_INVALID_ADAPTER);
}
/* First, issue a GetConfig command, which gives us */
/* the Log Config and Panic Log sizes */
RmStatus =
if (RmStatus != 0) {
goto done;
}
if (RmStatus != 0) {
goto done;
}
buf1[0] = 0;
RmStatus =
buf1[0] = 0;
for (i = 0; i < (int)NumLogs; i++) {
buf1[0] = 0;
pLcEntry[i].num_entries,
RmStatus =
}
/* Now issue a series of GetLogData commands, */
/* which gives us the actual Logs */
for (i = 0; i < (int)NumLogs; i++) {
if (RmStatus != 0) {
goto done;
}
/* print a caption for the current log */
buf1[0] = 0;
for (j = 0; j < 75; j++) {
}
RmStatus =
/* check the head entry to determine whether */
/* the log has wrapped or not */
if (strlen(pLogString) != 0) {
}
/* if log is wrapped, get entries from the */
/* Head through the End */
if (isWrapped) {
(char *)&(pLogEntry[j *
pLcEntry[i].entry_size]);
buf1[0] = 0;
RmStatus =
0, 0, 1);
}
}
/* if wrapped or not, get entries from the Top */
/* through the Head */
for (j = 0; j < Head; j++) {
buf1[0] = 0;
RmStatus =
1);
}
} /* end for i */
/* Now issue a GetPanicLog command, which gives us the Panic Log */
/* print a caption for the current log */
buf2[0] = 0;
for (j = 0; j < 75; j++) {
}
if (RmStatus == 0) {
buf1[0] = 0;
RmStatus =
buf1[0] = 0;
for (i = 0; i < MENLO_NUM_GP_REGS; i++) {
}
RmStatus =
buf1[0] = 0;
RmStatus =
/* print a caption for the current log */
buf2[0] = 0;
for (j = 0; j < 75; j++) {
}
RmStatus =
/* check the head entry to determine whether the */
/* log has wrapped or not */
if (strlen(pLogString) != 0) {
}
/* if log is wrapped, get entries from the */
/* Head through the End */
if (isWrapped) {
for (j = Head; j < (int)PanicLogEntryCount; j++) {
(char *)&(pLogEntry[j *
buf1[0] = 0;
RmStatus =
0, 0, 1);
}
}
/* if wrapped or not, get entries from the Top */
/* through the Head */
for (j = 0; j < Head; j++) {
(char *)&(pLogEntry[j * PanicLogEntrySize]);
buf1[0] = 0;
RmStatus =
1);
}
}
done:
if (pLdBuf != 0) {
}
if (pLcBuf != 0) {
}
if (pPlBuf != 0) {
}
return (RmStatus);
} /* emlxs_dump_menlo_log() */
static uint32_t
{
uint32_t i;
#ifdef EMLXS_BIG_ENDIAN
#endif /* EMLXS_BIG_ENDIAN */
return (1);
}
mbq =
/* Step 1: Call MBX_READ_EVENT_LOG_STATUS to get the log size. */
for (i = 0; i < 10; i++) {
MBX_SUCCESS) {
break;
}
"Unable to read event log status. status=%x",
(void) emlxs_dump_string_txtfile(fpTxtFile,
return (1);
}
/* The call to get the log size simply fails. */
/* Retry up to 10 times. */
/* Mailbox fails for some unknown reason. */
/* Put something in the txt to indicate this case. */
(void) emlxs_dump_string_txtfile(fpTxtFile,
return (1);
}
}
if (i >= 10) {
(void) emlxs_dump_string_txtfile(fpTxtFile,
return (1);
}
/* Step 2: Use the log size from step 1 to call MBX_READ_EVENT_LOG */
"Unable to allocate receive buffer. "
"size=%d",
logSize);
return (1);
}
} else {
block_size = 1024;
}
MBX_SUCCESS) {
"Unable to read event log. status=%x",
return (1);
}
}
/* Step 3: Dump the log to the DMP file as raw data. */
/* Write a string to text file to direct the user to the DMP */
/* file for the actual log. */
status =
/* Write the real log to the DMP file. */
status =
fSwap);
#ifdef FMA_SUPPORT
!= DDI_FM_OK) {
"emlxs_dump_saturn_log: hdl=%p",
mp->dma_handle);
status = 1;
}
#endif /* FMA_SUPPORT */
return (status);
} /* emlxs_dump_saturn_log() */
static uint32_t
{
return (1);
}
"Querying FAT...");
KM_SLEEP);
"Unable to allocate FAT buffer.");
rval = 1;
goto done;
}
/* Query FAT */
MBX_SUCCESS) {
"FAT Query failed. status=%x",
rval = 1;
goto done;
}
"FAT: log_size=%d", log_size);
if (buffer_size == 0) {
goto done;
}
"Unable to allocate log buffer.");
rval = 1;
goto done;
}
/* Upload Log */
offset = 0;
"Uploading log... (%d bytes)", log_size);
while (log_size) {
sizeof (IOCTL_COMMON_MANAGE_FAT) + xfer_size;
MBX_SUCCESS) {
"Failed to upload log. status=%x",
(void) emlxs_dump_string_txtfile(fpTxtFile,
rval = 1;
goto done;
}
}
"Log upload complete.");
/* Write a string to text file to direct the user to the CEE */
/* file for the actual log. */
rval =
/* Write the log to the CEE file. */
/* First word is the log size */
log_size, 0);
done:
if (mbq) {
}
if (mp) {
}
if (buffer) {
}
if (rval == 0) {
"Dump complete.");
}
return (rval);
} /* emlxs_dump_tigershark_log() */
extern uint32_t
{
"User Event: Firmware core dump initiated...");
status =
if (status != 0) {
return (1);
}
}
}
}
}
if (status == 0) {
(void) emlxs_menlo_set_mode(hba,
}
return (0);
} /* emlxs_dump_user_event() */
extern uint32_t
{
/* misc vars */
"Temperature Event: type=%d temp=%d. "\
"Invalid SLI4 event.",
return (1);
}
"Temperature Event: type=%d temp=%d. "\
"Firmware core dump initiated...",
if (status != 0) {
return (1);
}
/* Now generate the Dump */
/* Note: ignore return (status); if one part fails, */
/* keep trying to dump more stuff. */
/* Write a warning at the top of the file */
switch (tempType) {
case TEMP_TYPE_CRITICAL:
tempType);
break;
case TEMP_TYPE_THRESHOLD:
tempType);
break;
case TEMP_TYPE_NORMAL:
tempType);
break;
default:
break;
}
return (0);
} /* emlxs_dump_temp_event() */
extern uint32_t
{
"Dump Event: Firmware core dump initiated...");
status =
if (status != 0) {
return (1);
}
}
}
}
}
if (status == 0) {
}
/* Now generate the rest of the Dump */
/* The last step of the Menlo Dump. */
return (0);
} /* emlxs_dump_drv_event() */
/* ARGSUSED */
extern void
{
(void) emlxs_dump_drv_event(hba);
/* Clear the Dump flag */
return;
} /* emlxs_dump_drv_thread() */
/* ARGSUSED */
extern void
{
(void) emlxs_dump_user_event(hba);
/* Clear the Dump flag */
return;
} /* emlxs_dump_user_thread() */
/* ARGSUSED */
extern void
{
temp_event->temp);
/* Free the temp event object */
/* Clear the Dump flag */
return;
} /* emlxs_dump_temp_thread() */
/* Schedules a dump thread */
/* temp_type and temp are only valid for type=EMLXS_TEMP_DUMP */
extern void
{
/* Check if it is safe to dump */
"emlxs_dump: Dump disabled.");
return;
}
/* Check if a dump is already in progess */
"emlxs_dump: Dump already in progress.");
return;
}
/* Prepare to schedule dump */
switch (type) {
case EMLXS_DRV_DUMP:
case EMLXS_USER_DUMP:
break;
case EMLXS_TEMP_DUMP:
sizeof (dump_temp_event_t), KM_NOSLEEP);
if (temp_event == NULL) {
"emlxs_dump: Unable to allocate temp object.");
return;
}
break;
default:
"emlxs_dump: Error: Unknown dump type. (%x)",
type);
return;
}
/* Set the Dump-in-progess flag */
/* Create a separate thread to run the dump event */
switch (type) {
case EMLXS_DRV_DUMP:
break;
case EMLXS_TEMP_DUMP:
(void *)temp_event, NULL);
break;
case EMLXS_USER_DUMP:
break;
}
return;
} /* emlxs_dump() */
extern void
{
/* Wait for the Dump flag to clear */
DELAYMS(1000);
}
} /* emlxs_dump_wait() */
#endif /* DUMP_SUPPORT */