#include <emlxs.h>
#ifdef DUMP_SUPPORT
EMLXS_MSG_DEF(EMLXS_DUMP_C);
static uint32_t
emlxs_menlo_set_mode(
emlxs_hba_t *hba,
uint32_t mode)
{
emlxs_port_t *port = &PPORT;
uint32_t cmd_size;
uint32_t rsp_size;
menlo_cmd_t *cmd_buf = NULL;
menlo_rsp_t *rsp_buf = NULL;
uint32_t rval = 0;
if (hba->model_info.vendor_id != PCI_VENDOR_ID_EMULEX ||
hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_set_cmd_t);
cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
rsp_size = 4;
rsp_buf = (menlo_rsp_t *)kmem_zalloc(rsp_size, KM_SLEEP);
cmd_buf->code = MENLO_CMD_SET_MODE;
cmd_buf->set.value1 = mode;
cmd_buf->set.value2 = 0;
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
#endif
if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size,
(uint8_t *)rsp_buf, &rsp_size)) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_set_mode: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
#endif
if (rsp_buf->code != 0) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_set_mode: Menlo command error. code=%d.\n",
rsp_buf->code);
}
rval = rsp_buf->code;
done:
if (cmd_buf) {
kmem_free(cmd_buf, sizeof (menlo_set_cmd_t));
}
if (rsp_buf) {
kmem_free(rsp_buf, 4);
}
return (rval);
}
static uint32_t
emlxs_menlo_reset(
emlxs_hba_t *hba,
uint32_t firmware)
{
emlxs_port_t *port = &PPORT;
uint32_t cmd_size;
uint32_t rsp_size;
menlo_cmd_t *cmd_buf = NULL;
menlo_rsp_t *rsp_buf = NULL;
uint32_t rval = 0;
if (hba->model_info.vendor_id != PCI_VENDOR_ID_EMULEX ||
hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_reset_cmd_t);
cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
rsp_size = 4;
rsp_buf = (menlo_rsp_t *)kmem_zalloc(rsp_size, KM_SLEEP);
cmd_buf->code = MENLO_CMD_RESET;
cmd_buf->reset.firmware = firmware;
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
#endif
if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size,
(uint8_t *)rsp_buf, &rsp_size)) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_reset: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
#endif
if (rsp_buf->code != 0) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_reset: Menlo command error. code=%d.\n",
rsp_buf->code);
}
rval = rsp_buf->code;
done:
if (cmd_buf) {
kmem_free(cmd_buf, sizeof (menlo_reset_cmd_t));
}
if (rsp_buf) {
kmem_free(rsp_buf, 4);
}
return (rval);
}
static uint32_t
emlxs_menlo_get_cfg(
emlxs_hba_t *hba,
menlo_get_config_rsp_t *rsp_buf,
uint32_t rsp_size)
{
emlxs_port_t *port = &PPORT;
uint32_t cmd_size;
menlo_cmd_t *cmd_buf = NULL;
uint32_t rval = 0;
if (hba->model_info.vendor_id != PCI_VENDOR_ID_EMULEX ||
hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_get_cmd_t);
cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
rsp_size = sizeof (menlo_get_config_rsp_t);
cmd_buf->code = MENLO_CMD_GET_CONFIG;
cmd_buf->get.context = 0;
cmd_buf->get.length = rsp_size;
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
#endif
if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size,
(uint8_t *)rsp_buf, &rsp_size)) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_get_cfg: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
#endif
if (rsp_buf->code != 0) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_get_cfg: Menlo command error. code=%d.\n",
rsp_buf->code);
}
rval = rsp_buf->code;
done:
if (cmd_buf) {
kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
}
return (rval);
}
static uint32_t
emlxs_menlo_get_logcfg(
emlxs_hba_t *hba,
menlo_rsp_t *rsp_buf,
uint32_t rsp_size)
{
emlxs_port_t *port = &PPORT;
uint32_t cmd_size;
menlo_cmd_t *cmd_buf = NULL;
uint32_t rval = 0;
if (hba->model_info.vendor_id != PCI_VENDOR_ID_EMULEX ||
hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_get_cmd_t);
cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
cmd_buf->code = MENLO_CMD_GET_LOG_CONFIG;
cmd_buf->get.context = 0;
cmd_buf->get.length = rsp_size;
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
#endif
if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size,
(uint8_t *)rsp_buf, &rsp_size)) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_get_logcfg: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
#endif
if (rsp_buf->code != 0) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_get_logcfg: Menlo command error. code=%d.\n",
rsp_buf->code);
}
rval = rsp_buf->code;
done:
if (cmd_buf) {
kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
}
return (rval);
}
static uint32_t
emlxs_menlo_get_log(
emlxs_hba_t *hba,
uint32_t id,
menlo_rsp_t *rsp_buf,
uint32_t rsp_size)
{
emlxs_port_t *port = &PPORT;
uint32_t cmd_size;
menlo_cmd_t *cmd_buf = NULL;
uint32_t rval = 0;
if (hba->model_info.vendor_id != PCI_VENDOR_ID_EMULEX ||
hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_get_cmd_t);
cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
cmd_buf->code = MENLO_CMD_GET_LOG_DATA;
cmd_buf->get.context = id;
cmd_buf->get.length = rsp_size;
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
#endif
if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size,
(uint8_t *)rsp_buf, &rsp_size)) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_get_log: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
#endif
if (rsp_buf->code != 0) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_get_log: Menlo command error. code=%d.\n",
rsp_buf->code);
}
rval = rsp_buf->code;
done:
if (cmd_buf) {
kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
}
return (rval);
}
static uint32_t
emlxs_menlo_get_paniclog(
emlxs_hba_t *hba,
menlo_rsp_t *rsp_buf,
uint32_t rsp_size)
{
emlxs_port_t *port = &PPORT;
uint32_t cmd_size;
menlo_cmd_t *cmd_buf = NULL;
uint32_t rval = 0;
if (hba->model_info.vendor_id != PCI_VENDOR_ID_EMULEX ||
hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
return (DFC_INVALID_ADAPTER);
}
cmd_size = sizeof (menlo_get_cmd_t);
cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
cmd_buf->code = MENLO_CMD_GET_PANIC_LOG;
cmd_buf->get.context = 0;
cmd_buf->get.length = rsp_size;
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
#endif
if (rval = emlxs_send_menlo_cmd(hba, (uint8_t *)cmd_buf, cmd_size,
(uint8_t *)rsp_buf, &rsp_size)) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_get_paniclog: Unable to send command.");
goto done;
}
#ifdef EMLXS_BIG_ENDIAN
emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
#endif
if (rsp_buf->code != 0) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"menlo_get_paniclog: Menlo command error. code=%d.\n",
rsp_buf->code);
}
rval = rsp_buf->code;
done:
if (cmd_buf) {
kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
}
return (rval);
}
extern void
emlxs_fflush(
emlxs_file_t *fp)
{
uint32_t offset;
offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
if (offset > fp->size) {
fp->ptr = fp->buffer + fp->size;
}
return;
}
extern uint32_t
emlxs_ftell(
emlxs_file_t *fp)
{
uint32_t offset;
offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
return (offset);
}
static void
emlxs_fputc(
uint8_t value,
emlxs_file_t *fp)
{
uint32_t offset;
offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
if ((offset + 1) <= fp->size) {
*fp->ptr++ = value;
}
return;
}
static uint32_t
emlxs_fwrite(
uint8_t *buffer,
uint32_t size,
uint32_t nitems,
emlxs_file_t *fp)
{
uint32_t offset;
uint32_t length;
length = size * nitems;
if (length) {
offset =
(uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
if ((offset + length) > fp->size) {
length = fp->size - offset;
}
if (length) {
bcopy(buffer, fp->ptr, length);
fp->ptr += length;
}
}
return (length);
}
static uint32_t
emlxs_fprintf(
emlxs_file_t *fp,
const char *fmt, ...)
{
va_list valist;
char va_str[1024];
uint32_t length;
va_start(valist, fmt);
(void) vsnprintf(va_str, sizeof (va_str), fmt, valist);
va_end(valist);
length = emlxs_fwrite((uint8_t *)va_str, strlen(va_str), 1, fp);
return (length);
}
extern emlxs_file_t *
emlxs_fopen(
emlxs_hba_t *hba,
uint32_t file_type)
{
emlxs_file_t *fp;
switch (file_type) {
case EMLXS_TXT_FILE:
fp = &hba->dump_txtfile;
fp->size = EMLXS_TXT_FILE_SIZE;
break;
case EMLXS_DMP_FILE:
fp = &hba->dump_dmpfile;
fp->size = EMLXS_DMP_FILE_SIZE;
break;
case EMLXS_CEE_FILE:
fp = &hba->dump_ceefile;
fp->size = EMLXS_CEE_FILE_SIZE;
break;
default:
return (NULL);
}
fp->size &= 0xFFFFFFFC;
if (!fp->buffer) {
fp->buffer =
(uint8_t *)kmem_zalloc(fp->size, KM_SLEEP);
} else {
bzero(fp->buffer, fp->size);
}
fp->ptr = fp->buffer;
return (fp);
}
extern uint32_t
emlxs_fclose(
emlxs_file_t *fp)
{
uint32_t offset;
if (fp == NULL) {
return (0);
}
offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
offset = offset % 4;
switch (offset) {
case 0:
break;
case 1:
*fp->ptr++ = 0;
*fp->ptr++ = 0;
*fp->ptr++ = 0;
break;
case 2:
*fp->ptr++ = 0;
*fp->ptr++ = 0;
break;
case 3:
*fp->ptr++ = 0;
break;
}
return (0);
}
static void
emlxs_fdelete(
emlxs_file_t *fp)
{
if (fp == NULL) {
return;
}
if (fp->buffer && fp->size) {
kmem_free(fp->buffer, fp->size);
}
fp->buffer = NULL;
fp->ptr = NULL;
fp->size = 0;
return;
}
extern uint32_t
emlxs_get_dump(
emlxs_hba_t *hba,
uint8_t *buffer,
uint32_t *buflen)
{
emlxs_port_t *port = &PPORT;
int32_t i;
int32_t size;
int32_t count;
uint32_t size_dmp;
uint32_t size_txt;
uint32_t size_cee;
emlxs_file_t *fp_txt;
emlxs_file_t *fp_dmp;
emlxs_file_t *fp_cee;
uint32_t *wptr;
uint8_t *bptr;
if (!buflen) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"get_dump: Buffer length = 0");
return (1);
}
fp_txt = &hba->dump_txtfile;
fp_dmp = &hba->dump_dmpfile;
fp_cee = &hba->dump_ceefile;
size_txt = emlxs_ftell(fp_txt);
size_dmp = emlxs_ftell(fp_dmp);
size_cee = emlxs_ftell(fp_cee);
size = 0;
count = 0;
if (size_txt) {
count++;
size += size_txt + 8;
}
if (size_dmp) {
count++;
size += size_dmp + 8;
}
if (size_cee) {
count++;
size += size_cee + 8;
}
if (size) {
size += 4;
}
if (!buffer) {
goto done;
}
bzero(buffer, *buflen);
if (*buflen < size) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"get_dump: Buffer length too small. %d < %d",
*buflen, size);
*buflen = 0;
return (1);
}
wptr = (uint32_t *)buffer;
wptr[0] = count;
i = 1;
if (size_txt) {
wptr[i++] = EMLXS_TXT_FILE_ID;
wptr[i++] = size_txt;
}
if (size_dmp) {
wptr[i++] = EMLXS_DMP_FILE_ID;
wptr[i++] = size_dmp;
}
if (size_cee) {
if ((hba->model_info.chip == EMLXS_BE2_CHIP) ||
(hba->model_info.chip == EMLXS_BE3_CHIP)) {
wptr[i++] = EMLXS_FAT_FILE_ID;
} else {
wptr[i++] = EMLXS_CEE_FILE_ID;
}
wptr[i++] = size_cee;
}
bptr = (uint8_t *)&wptr[i];
if (size_txt) {
bcopy(fp_txt->buffer, bptr, size_txt);
bptr += size_txt;
}
if (size_dmp) {
bcopy(fp_dmp->buffer, bptr, size_dmp);
bptr += size_dmp;
}
if (size_cee) {
bcopy(fp_cee->buffer, bptr, size_cee);
bptr += size_cee;
}
done:
*buflen = size;
return (0);
}
static uint32_t
emlxs_read_cfg_region(
emlxs_hba_t *hba,
uint32_t Identifier,
uint32_t ByteCount,
uint32_t *pRetByteCount,
uint8_t *pBuffer)
{
emlxs_port_t *port = &PPORT;
MAILBOXQ *mbq;
uint32_t ByteCountRem;
uint32_t ByteCountReq;
uint32_t CopyCount;
uint32_t Offset;
uint8_t *pLocalBuf;
if (! ByteCount) {
return (0);
}
mbq =
(MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP);
pLocalBuf = pBuffer;
Offset = 0;
*pRetByteCount = 0;
CopyCount = 0;
for (ByteCountRem = ByteCount; ByteCountRem > 0;
ByteCountRem -= CopyCount) {
if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
MAILBOX4 *mb = (MAILBOX4 *)mbq;
ByteCountReq =
(ByteCountRem < hba->sli.sli4.dump_region.size) ?
ByteCountRem : hba->sli.sli4.dump_region.size;
bzero(hba->sli.sli4.dump_region.virt,
hba->sli.sli4.dump_region.size);
bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
mb->mbxCommand = MBX_DUMP_MEMORY;
mb->un.varDmp4.type = DMP_NV_PARAMS;
mb->un.varDmp4.entry_index = Offset;
mb->un.varDmp4.region_id = Identifier;
mb->un.varDmp4.available_cnt = ByteCountReq;
mb->un.varDmp4.addrHigh =
PADDR_HI(hba->sli.sli4.dump_region.phys);
mb->un.varDmp4.addrLow =
PADDR_LO(hba->sli.sli4.dump_region.phys);
mb->un.varDmp4.rsp_cnt = 0;
mb->mbxOwner = OWN_HOST;
mbq->mbox_cmpl = NULL;
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"Unable to read config region. id=%x "\
"offset=%x status=%x",
Identifier, Offset, mb->mbxStatus);
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
CopyCount = mb->un.varDmp4.rsp_cnt;
if (CopyCount == 0) {
break;
}
if (CopyCount > ByteCountReq) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"read_cfg_region: " \
"Byte count too big. %d > %d\n",
CopyCount, ByteCountReq);
CopyCount = ByteCountReq;
}
bcopy((uint8_t *)hba->sli.sli4.dump_region.virt,
pLocalBuf, CopyCount);
} else {
MAILBOX *mb = (MAILBOX *)mbq;
ByteCountReq =
(ByteCountRem < DUMP_BC_MAX) ? ByteCountRem :
DUMP_BC_MAX;
bzero((void *)mb, MAILBOX_CMD_BSIZE);
mb->mbxCommand = MBX_DUMP_MEMORY;
mb->un.varDmp.type = DMP_NV_PARAMS;
mb->un.varDmp.cv = 1;
mb->un.varDmp.region_id = Identifier;
mb->un.varDmp.entry_index = Offset;
mb->un.varDmp.word_cnt = ByteCountReq / 4;
mb->mbxOwner = OWN_HOST;
mbq->mbox_cmpl = NULL;
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"Unable to read config region. id=%x "\
"offset=%x status=%x",
Identifier, Offset, mb->mbxStatus);
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
CopyCount = mb->un.varDmp.word_cnt;
if (CopyCount == 0) {
break;
}
if (CopyCount > ByteCountReq) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"read_cfg_region: " \
"Byte count too big. %d > %d\n",
CopyCount, ByteCountReq);
CopyCount = ByteCountReq;
}
bcopy((uint8_t *)&mb->un.varDmp.resp_offset, pLocalBuf,
CopyCount);
}
pLocalBuf += CopyCount;
Offset += CopyCount;
*pRetByteCount += CopyCount;
}
return (0);
}
static uint32_t
emlxs_dump_string_txtfile(
emlxs_file_t *fpTxtFile,
char *pString,
char *pSidLegend,
char *pLidLegend,
uint32_t pure)
{
if (!fpTxtFile) {
return (1);
}
if (pSidLegend && pLidLegend) {
(void) emlxs_fprintf(fpTxtFile, "%s: %s\n", pSidLegend,
pLidLegend);
if (pure == 0) {
emlxs_fputc(' ', fpTxtFile);
}
(void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1,
fpTxtFile);
if (pure == 0) {
emlxs_fputc('\n', fpTxtFile);
emlxs_fputc('\n', fpTxtFile);
}
} else {
if (pure == 0) {
emlxs_fputc(' ', fpTxtFile);
}
(void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1,
fpTxtFile);
}
emlxs_fflush(fpTxtFile);
return (0);
}
static uint32_t
emlxs_dump_word_txtfile(
emlxs_file_t *fpTxtFile,
uint32_t *pBuffer,
uint32_t WordCount,
char *pSidLegend,
char *pLidLegend)
{
char buf1[256];
char buf2[256];
uint32_t *ptr;
uint32_t j;
if (!fpTxtFile) {
return (1);
}
(void) emlxs_fprintf(fpTxtFile, "%s: %s\n", pSidLegend, pLidLegend);
ptr = pBuffer;
for (j = 0; j < WordCount; j++) {
buf1[0] = 0;
buf2[0] = 0;
if ((j & 0x03) == 0) {
(void) snprintf(buf1, sizeof (buf1), "\n%04x:", j * 4);
(void) strlcat(buf2, buf1, sizeof (buf2));
}
(void) snprintf(buf1, sizeof (buf1), " %08x", ptr[j]);
(void) strlcat(buf2, buf1, sizeof (buf2));
(void) emlxs_fwrite((uint8_t *)buf2, strlen(buf2), 1,
fpTxtFile);
}
emlxs_fputc('\n', fpTxtFile);
emlxs_fputc('\n', fpTxtFile);
emlxs_fflush(fpTxtFile);
return (0);
}
static uint32_t
emlxs_dump_string_dmpfile(
emlxs_file_t *fpDmpFile,
char *pString,
uint8_t sid,
char *pSidLegend,
char *pLidLegend)
{
uint32_t length;
uint8_t byte;
uint32_t pos;
if (!fpDmpFile) {
return (1);
}
emlxs_fputc(SID_LEGEND, fpDmpFile);
emlxs_fputc(sid, fpDmpFile);
(void) emlxs_fprintf(fpDmpFile, "%s: %s", pSidLegend, pLidLegend);
emlxs_fputc(0, fpDmpFile);
emlxs_fputc(sid, fpDmpFile);
length = (uint32_t)(strlen(pString) + 1);
#ifdef EMLXS_LITTLE_ENDIAN
byte = (uint8_t)(length & 0x0000FF);
emlxs_fputc(byte, fpDmpFile);
byte = (uint8_t)((length & 0x00FF00) >> 8);
emlxs_fputc(byte, fpDmpFile);
byte = (uint8_t)((length & 0xFF0000) >> 16);
emlxs_fputc(byte, fpDmpFile);
#endif
#ifdef EMLXS_BIG_ENDIAN
byte = (uint8_t)((length & 0xFF0000) >> 16);
emlxs_fputc(byte, fpDmpFile);
byte = (uint8_t)((length & 0x00FF00) >> 8);
emlxs_fputc(byte, fpDmpFile);
byte = (uint8_t)(length & 0x0000FF);
emlxs_fputc(byte, fpDmpFile);
#endif
(void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1, fpDmpFile);
emlxs_fputc(0, fpDmpFile);
emlxs_fflush(fpDmpFile);
#if CC_DUMP_ENABLE_PAD
pos = emlxs_ftell(fpDmpFile);
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;
}
emlxs_fflush(fpDmpFile);
#endif
return (0);
}
extern uint32_t
emlxs_dump_word_dmpfile(
emlxs_file_t *fpDmpFile,
uint8_t *pBuffer,
uint32_t bufferLen,
int fSwap)
{
uint32_t i;
uint32_t *wptr;
if (!fpDmpFile) {
return (1);
}
wptr = (uint32_t *)pBuffer;
for (i = 0; i < bufferLen / 4; i++, wptr++) {
if (fSwap) {
uint32_t w1;
w1 = *wptr;
*wptr = BE_SWAP32(w1);
}
(void) emlxs_fwrite((uint8_t *)wptr, 4, 1, fpDmpFile);
}
emlxs_fflush(fpDmpFile);
return (0);
}
static uint32_t
emlxs_dump_port_block(
emlxs_file_t *fpDmpFile,
uint8_t *pBuffer,
uint32_t bufferLen,
DUMP_TABLE_ENTRY entry,
int fSwap)
{
uint32_t status;
uint32_t w;
uint8_t b;
if (!fpDmpFile) {
return (1);
}
b = (uint8_t)entry.un.PortBlock.un.s.sid;
emlxs_fputc(b, fpDmpFile);
#ifdef EMLXS_LITTLE_ENDIAN
w = entry.un.PortBlock.un.s.bc;
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x0000FF00) >> 8);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x00FF0000) >> 16);
emlxs_fputc(b, fpDmpFile);
w = entry.un.PortBlock.un.s.addr;
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x0000FF00) >> 8);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x00FF0000) >> 16);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0xFF000000) >> 24);
emlxs_fputc(b, fpDmpFile);
#endif
#ifdef EMLXS_BIG_ENDIAN
w = entry.un.PortBlock.un.s.bc;
b = (uint8_t)((w & 0x00FF0000) >> 16);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x0000FF00) >> 8);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
w = entry.un.PortBlock.un.s.addr;
b = (uint8_t)((w & 0xFF000000) >> 24);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x00FF0000) >> 16);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x0000FF00) >> 8);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
#endif
status =
emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
emlxs_fflush(fpDmpFile);
return (status);
}
static uint32_t
emlxs_dump_port_struct(
emlxs_file_t *fpDmpFile,
uint8_t *pBuffer,
uint32_t bufferLen,
DUMP_TABLE_ENTRY entry,
int fSwap)
{
uint32_t status;
uint32_t w;
uint8_t b;
if (!fpDmpFile) {
return (1);
}
b = (uint8_t)entry.un.PortStruct.un.s.sid;
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)entry.un.PortStruct.un.s.length;
emlxs_fputc(b, fpDmpFile);
#ifdef EMLXS_LITTLE_ENDIAN
w = entry.un.PortStruct.un.s.count;
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x0000FF00) >> 8);
emlxs_fputc(b, fpDmpFile);
w = entry.un.PortStruct.un.s.addr;
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x0000FF00) >> 8);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x00FF0000) >> 16);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0xFF000000) >> 24);
emlxs_fputc(b, fpDmpFile);
#endif
#ifdef EMLXS_BIG_ENDIAN
w = entry.un.PortStruct.un.s.count;
b = (uint8_t)((w & 0x0000FF00) >> 8);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
w = entry.un.PortStruct.un.s.addr;
b = (uint8_t)((w & 0xFF000000) >> 24);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x00FF0000) >> 16);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x0000FF00) >> 8);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
#endif
status =
emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
emlxs_fflush(fpDmpFile);
return (status);
}
static uint32_t
emlxs_dump_host_block(
emlxs_file_t *fpDmpFile,
uint8_t *pBuffer,
uint32_t bufferLen,
uint8_t sid,
char *pSidLegend,
char *pLidLegend,
int fSwap)
{
uint32_t status;
uint32_t length;
uint8_t byte;
if (!fpDmpFile) {
return (1);
}
emlxs_fputc(SID_LEGEND, fpDmpFile);
emlxs_fputc(sid, fpDmpFile);
(void) emlxs_fprintf(fpDmpFile, "%s: %s", pSidLegend, pLidLegend);
emlxs_fputc(0, fpDmpFile);
emlxs_fputc(sid, fpDmpFile);
length = bufferLen;
#ifdef EMLXS_LITTLE_ENDIAN
byte = (uint8_t)(length & 0x0000FF);
emlxs_fputc(byte, fpDmpFile);
byte = (uint8_t)((length & 0x00FF00) >> 8);
emlxs_fputc(byte, fpDmpFile);
byte = (uint8_t)((length & 0xFF0000) >> 16);
emlxs_fputc(byte, fpDmpFile);
#endif
#ifdef EMLXS_BIG_ENDIAN
byte = (uint8_t)((length & 0xFF0000) >> 16);
emlxs_fputc(byte, fpDmpFile);
byte = (uint8_t)((length & 0x00FF00) >> 8);
emlxs_fputc(byte, fpDmpFile);
byte = (uint8_t)(length & 0x0000FF);
emlxs_fputc(byte, fpDmpFile);
#endif
status =
emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
emlxs_fflush(fpDmpFile);
return (status);
}
static uint32_t
emlxs_dump_host_struct(
emlxs_file_t *fpDmpFile,
uint8_t *pBuffer,
uint32_t bufferLen,
uint32_t elementLength,
uint32_t elementCount,
uint8_t sid,
char *pSidLegend,
char *pLidLegend,
int fSwap)
{
uint32_t status;
uint32_t w;
uint8_t b;
if (!fpDmpFile) {
return (1);
}
emlxs_fputc(SID_LEGEND, fpDmpFile);
emlxs_fputc(sid, fpDmpFile);
(void) emlxs_fprintf(fpDmpFile, "%s: %s", pSidLegend, pLidLegend);
emlxs_fputc(0, fpDmpFile);
emlxs_fputc(sid, fpDmpFile);
b = (uint8_t)elementLength;
emlxs_fputc(b, fpDmpFile);
w = elementCount;
#ifdef EMLXS_LITTLE_ENDIAN
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)((w & 0x0000FF00) >> 8);
emlxs_fputc(b, fpDmpFile);
#endif
#ifdef EMLXS_BIG_ENDIAN
b = (uint8_t)((w & 0x0000FF00) >> 8);
emlxs_fputc(b, fpDmpFile);
b = (uint8_t)(w & 0x000000FF);
emlxs_fputc(b, fpDmpFile);
#endif
status =
emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
emlxs_fflush(fpDmpFile);
return (status);
}
static uint32_t
emlxs_dump_parm_table(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
emlxs_config_t *cfg = &CFG;
uint32_t status;
uint32_t i;
char *buf1;
char *buf2;
buf1 = (char *)kmem_zalloc(8192, KM_SLEEP);
buf2 = (char *)kmem_zalloc(8192, KM_SLEEP);
(void) snprintf(buf1, 8192,
"IDX string Low "\
"High Def Cur Exp Dyn");
for (i = 0; i < NUM_CFG_PARAM; i++) {
(void) snprintf(buf2, 8192,
"\n %02x: %25s %8x %8x %8x %8x %4x %4x", i,
cfg[i].string, cfg[i].low, cfg[i].hi, cfg[i].def,
cfg[i].current, (cfg[i].flags & PARM_HIDDEN) ? 0 : 1,
(cfg[i].flags & PARM_DYNAMIC) ? 1 : 0);
(void) strlcat(buf1, buf2, 8192);
}
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_DP_TABLE,
LEGEND_NULL, 0);
status =
emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_DP_TABLE,
LEGEND_DP_TABLE, LEGEND_NULL);
kmem_free(buf1, 8192);
kmem_free(buf2, 8192);
return (status);
}
static uint32_t
emlxs_dump_model(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
emlxs_vpd_t *vpd = &VPD;
uint32_t status;
char buf1[512];
char buf2[512];
(void) snprintf(buf2, sizeof (buf2), "%s", vpd->model);
(void) strlcpy(buf1, "Model: ", sizeof (buf1));
(void) strlcat(buf1, buf2, sizeof (buf1));
(void) snprintf(buf2, sizeof (buf2), "%s", vpd->model_desc);
(void) strlcat(buf1, "\n Description: ", sizeof (buf1));
(void) strlcat(buf1, buf2, sizeof (buf1));
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
LEGEND_HBA_MODEL, 0);
status =
emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
LEGEND_HBA_INFO, LEGEND_HBA_MODEL);
return (status);
}
static uint32_t
emlxs_dump_wwn(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
char buf1[512];
char buf2[512];
int i;
uint8_t *p;
(void) strlcpy(buf1, "Port WWN: ", sizeof (buf1));
p = (uint8_t *)&hba->wwpn;
for (i = 0; i < 7; i++) {
(void) snprintf(buf2, sizeof (buf2), "%02x:", *p++);
(void) strlcat(buf1, buf2, sizeof (buf1));
}
(void) snprintf(buf2, sizeof (buf2), "%02x", *p++);
(void) strlcat(buf1, buf2, sizeof (buf1));
(void) strlcat(buf1, "\n Node WWN: ", sizeof (buf1));
p = (uint8_t *)&hba->wwnn;
for (i = 0; i < 7; i++) {
(void) snprintf(buf2, sizeof (buf2), "%02x:", *p++);
(void) strlcat(buf1, buf2, sizeof (buf1));
}
(void) snprintf(buf2, sizeof (buf2), "%02x", *p++);
(void) strlcat(buf1, buf2, sizeof (buf1));
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
LEGEND_HBA_WWN, 0);
status =
emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
LEGEND_HBA_INFO, LEGEND_HBA_WWN);
return (status);
}
static uint32_t
emlxs_dump_serial_number(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
emlxs_vpd_t *vpd = &VPD;
uint32_t status;
char buf1[512];
char buf2[512];
(void) snprintf(buf2, sizeof (buf2), "%s", vpd->serial_num);
(void) strlcpy(buf1, LEGEND_HBA_SN, sizeof (buf1));
(void) strlcat(buf1, ": ", sizeof (buf1));
(void) strlcat(buf1, buf2, sizeof (buf1));
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
LEGEND_HBA_SN, 0);
status =
emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
LEGEND_HBA_INFO, LEGEND_HBA_SN);
return (status);
}
static uint32_t
emlxs_dump_fw_version(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
emlxs_vpd_t *vpd = &VPD;
uint32_t status;
char *buf1;
char *buf2;
uint32_t buf1_size;
uint32_t buf2_size;
buf1_size = 1024;
buf2_size = 1024;
buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
(void) snprintf(buf2, buf2_size, "%s", vpd->fw_version);
(void) strlcpy(buf1, LEGEND_HBA_FW_VERSION, buf1_size);
(void) strlcat(buf1, ": ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "%s", vpd->opFwName);
(void) strlcat(buf1, "\n ", buf1_size);
(void) strlcat(buf1, LEGEND_HBA_FW_OPVERSION, buf1_size);
(void) strlcat(buf1, ": ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "%s", vpd->sli1FwName);
(void) strlcat(buf1, "\n ", buf1_size);
(void) strlcat(buf1, LEGEND_HBA_FW_SLI1VERSION, buf1_size);
(void) strlcat(buf1, ": ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "%s", vpd->sli2FwName);
(void) strlcat(buf1, "\n ", buf1_size);
(void) strlcat(buf1, LEGEND_HBA_FW_SLI2VERSION, buf1_size);
(void) strlcat(buf1, ": ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "%s", vpd->sli3FwName);
(void) strlcat(buf1, "\n ", buf1_size);
(void) strlcat(buf1, LEGEND_HBA_FW_SLI3VERSION, buf1_size);
(void) strlcat(buf1, ": ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "%s", vpd->postKernName);
(void) strlcat(buf1, "\n ", buf1_size);
(void) strlcat(buf1, LEGEND_HBA_FW_KERNELVERSION, buf1_size);
(void) strlcat(buf1, ": ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
LEGEND_HBA_FW_VERSION, 0);
status =
emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
LEGEND_HBA_INFO, LEGEND_HBA_FW_VERSION);
kmem_free(buf1, buf1_size);
kmem_free(buf2, buf2_size);
return (status);
}
static uint32_t
emlxs_dump_boot_version(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
emlxs_vpd_t *vpd = &VPD;
uint32_t status;
uint32_t state;
char *buf1;
char *buf2;
uint32_t buf1_size;
uint32_t buf2_size;
buf1_size = 1024;
buf2_size = 1024;
buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
#ifdef EMLXS_SPARC
if (strcmp(vpd->fcode_version, "none") == 0)
#else
if (strcmp(vpd->boot_version, "none") == 0)
#endif
{
state = 2;
} else {
state = emlxs_boot_code_state(hba);
}
(void) snprintf(buf2, buf2_size, " %d", state);
(void) strlcpy(buf1, LEGEND_HBA_BB_STATE, buf1_size);
(void) strlcat(buf1, ": ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
if (state == 2) {
(void) snprintf(buf2, buf2_size, "%s", "unknown");
} else {
#ifdef EMLXS_SPARC
(void) snprintf(buf2, buf2_size, "%s (FCode)",
vpd->fcode_version);
#else
(void) snprintf(buf2, buf2_size, "%s", vpd->boot_version);
#endif
}
(void) strlcat(buf1, "\n ", buf1_size);
(void) strlcat(buf1, LEGEND_HBA_BB_VERSION, buf1_size);
(void) strlcat(buf1, ": ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
LEGEND_HBA_BB_VERSION, 0);
status =
emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
LEGEND_HBA_INFO, LEGEND_HBA_BB_VERSION);
kmem_free(buf1, buf1_size);
kmem_free(buf2, buf2_size);
return (status);
}
static uint32_t
emlxs_dump_cfg_region4_decoded(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
char *pLidLegend,
DUMP_WAKE_UP_PARAMS *pBuffer,
uint32_t ByteCount)
{
uint32_t status;
char *buf1;
char *buf2;
uint32_t buf1_size;
uint32_t buf2_size;
buf1_size = 1024;
buf2_size = 1024;
buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
(void) snprintf(buf2, buf2_size, "%s: %08x %08x",
LEGEND_CR4_INITIAL_LOAD,
pBuffer->InitialId[0], pBuffer->InitialId[1]);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "\n %s: %08x", LEGEND_CR4_FLAGS,
pBuffer->Flags);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
LEGEND_CR4_BOOT_BIOS_ID,
pBuffer->BootBiosId[0], pBuffer->BootBiosId[1]);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
LEGEND_CR4_SLI1_ID,
pBuffer->Sli1Id[0], pBuffer->Sli1Id[1]);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
LEGEND_CR4_SLI2_ID,
pBuffer->Sli2Id[0], pBuffer->Sli2Id[1]);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
LEGEND_CR4_SLI3_ID,
pBuffer->Sli3Id[0], pBuffer->Sli3Id[1]);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
LEGEND_CR4_SLI4_ID,
pBuffer->Sli4Id[0], pBuffer->Sli4Id[1]);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
LEGEND_CR4_EROM_ID,
pBuffer->EromId[0], pBuffer->EromId[1]);
(void) strlcat(buf1, buf2, buf1_size);
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_CONFIG_REGION,
LEGEND_CONFIG_REGION_4, 0);
kmem_free(buf1, buf1_size);
kmem_free(buf2, buf2_size);
return (status);
}
uint32_t
emlxs_dump_cfg_region14_decoded(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
char *pLidLegend,
char *pBuffer,
uint32_t ByteCount)
{
uint32_t status;
char *buf1;
char *buf2;
uint32_t buf1_size;
uint32_t buf2_size;
int i;
uint8_t tag;
uint16_t length;
uint16_t length2;
char mnemonic[4];
int fDone = FALSE;
#ifdef EMLXS_BIG_ENDIAN
uint32_t *wptr;
uint32_t w1;
#endif
buf1_size = 1024;
buf2_size = 1024;
buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
#ifdef EMLXS_BIG_ENDIAN
wptr = (uint32_t *)pBuffer;
for (i = 0; i < (int)ByteCount / 4; i++, wptr++) {
w1 = *wptr;
*wptr = BE_SWAP32(w1);
}
#endif
if (((unsigned char)pBuffer[0]) != VPD_TAG_82) {
(void) snprintf(buf1, buf1_size,
"Bad VPD Data: (w0=0x%08x)", *(uint32_t *)pBuffer);
} else {
i = 0;
while (!fDone) {
tag = pBuffer[i++];
length = pBuffer[i++];
length |= (pBuffer[i++] << 8);
switch (tag) {
case VPD_TAG_82:
(void) strncpy(buf2, &pBuffer[i],
length > buf2_size ? buf2_size : length);
buf2[length >
(buf2_size - 1) ? (buf2_size -
1) : length] = 0;
(void) strlcat(buf1, "Name: ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
i += length;
break;
case VPD_TAG_90:
for (;;) {
mnemonic[0] = pBuffer[i++];
mnemonic[1] = pBuffer[i++];
mnemonic[2] = 0;
if (strcmp(mnemonic, "RV") == 0) {
fDone = TRUE;
break;
}
if (mnemonic[0] == 0) {
fDone = TRUE;
break;
}
length2 = pBuffer[i++];
(void) snprintf(buf2, buf2_size,
"\n %s: ", mnemonic);
(void) strlcat(buf1, buf2,
buf1_size);
(void) strncpy(buf2, &pBuffer[i],
length2 >
buf2_size ? buf2_size : length2);
buf2[length2 >
(buf2_size - 1) ? (buf2_size -
1) : length2] = 0;
(void) strlcat(buf1, buf2,
buf1_size);
i += length2;
}
break;
default:
break;
}
}
}
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_CONFIG_REGION,
LEGEND_CONFIG_REGION_14, 0);
kmem_free(buf1, buf1_size);
kmem_free(buf2, buf2_size);
return (status);
}
static uint32_t
emlxs_dump_cfg_region(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile,
uint8_t Region,
char *pLidLegend,
int fSwap)
{
uint32_t status;
uint32_t RetByteCount = 0;
char *buf1;
char *buf2;
uint32_t buf1_size;
uint32_t buf2_size;
uint32_t *buffer;
int i;
#ifdef EMLXS_LITTLE_ENDIAN
fSwap = FALSE;
#endif
buf1_size = 4096;
buf2_size = 1024;
buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
buffer =
(uint32_t *)kmem_zalloc(DUMP_MAX_CONFIG_REGION_LENGTH, KM_SLEEP);
status =
emlxs_read_cfg_region(hba, Region, DUMP_MAX_CONFIG_REGION_LENGTH,
&RetByteCount, (uint8_t *)buffer);
if (status != 0) {
kmem_free(buffer, DUMP_MAX_CONFIG_REGION_LENGTH);
kmem_free(buf1, buf1_size);
kmem_free(buf2, buf2_size);
return (status);
}
for (i = 0; i < (int)RetByteCount / 4; i++) {
if ((i % 8 == 0) && (i != 0)) {
(void) strlcat((char *)buf1, "\n ", buf1_size);
}
(void) snprintf(buf2, buf2_size, "%08x, ", buffer[i]);
(void) strlcat((char *)buf1, buf2, buf1_size);
}
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_CONFIG_REGION,
pLidLegend, 0);
status = emlxs_dump_host_block(fpDmpFile,
(uint8_t *)buffer,
RetByteCount,
SID_CONFIG_REGION, LEGEND_CONFIG_REGION, pLidLegend, fSwap);
if (Region == 4) {
status =
emlxs_dump_cfg_region4_decoded(hba, fpTxtFile, pLidLegend,
(DUMP_WAKE_UP_PARAMS *)buffer, RetByteCount);
}
if (Region == 14) {
status =
emlxs_dump_cfg_region14_decoded(hba, fpTxtFile,
pLidLegend, (char *)buffer, RetByteCount);
}
kmem_free(buffer, DUMP_MAX_CONFIG_REGION_LENGTH);
kmem_free(buf1, buf1_size);
kmem_free(buf2, buf2_size);
return (status);
}
static uint32_t
emlxs_dump_cfg_regions(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 0,
LEGEND_CONFIG_REGION_0, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 1,
LEGEND_CONFIG_REGION_1, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 2,
LEGEND_CONFIG_REGION_2, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 3,
LEGEND_CONFIG_REGION_3, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 4,
LEGEND_CONFIG_REGION_4, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 5,
LEGEND_CONFIG_REGION_5, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 6,
LEGEND_CONFIG_REGION_6, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 7,
LEGEND_CONFIG_REGION_7, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 8,
LEGEND_CONFIG_REGION_8, TRUE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 9,
LEGEND_CONFIG_REGION_9, TRUE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 10,
LEGEND_CONFIG_REGION_10, TRUE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 11,
LEGEND_CONFIG_REGION_11, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 12,
LEGEND_CONFIG_REGION_12, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 13,
LEGEND_CONFIG_REGION_13, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 14,
LEGEND_CONFIG_REGION_14, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 15,
LEGEND_CONFIG_REGION_15, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 16,
LEGEND_CONFIG_REGION_16, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 17,
LEGEND_CONFIG_REGION_17, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 18,
LEGEND_CONFIG_REGION_18, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 19,
LEGEND_CONFIG_REGION_19, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 20,
LEGEND_CONFIG_REGION_20, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 21,
LEGEND_CONFIG_REGION_21, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 22,
LEGEND_CONFIG_REGION_22, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 23,
LEGEND_CONFIG_REGION_23, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 24,
LEGEND_CONFIG_REGION_24, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 25,
LEGEND_CONFIG_REGION_25, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 26,
LEGEND_CONFIG_REGION_26, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 27,
LEGEND_CONFIG_REGION_27, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 28,
LEGEND_CONFIG_REGION_28, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 29,
LEGEND_CONFIG_REGION_29, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 30,
LEGEND_CONFIG_REGION_30, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 31,
LEGEND_CONFIG_REGION_31, FALSE);
status =
emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 32,
LEGEND_CONFIG_REGION_32, FALSE);
return (status);
}
static uint32_t
emlxs_dump_os_version(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
char *buf1;
char *buf2;
uint32_t buf1_size;
uint32_t buf2_size;
buf1_size = 1024;
buf2_size = 1024;
buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
(void) strlcpy(buf1, utsname.sysname, buf1_size);
(void) snprintf(buf2, buf2_size, ", %s", utsname.release);
(void) strlcat(buf1, buf2, buf1_size);
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_REV_INFO,
LEGEND_REV_OS_VERSION, 0);
status =
emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_REV_INFO,
LEGEND_REV_INFO, LEGEND_REV_OS_VERSION);
kmem_free(buf1, buf1_size);
kmem_free(buf2, buf2_size);
return (status);
}
static uint32_t
emlxs_dump_drv_version(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
char *buf1;
char *buf2;
uint32_t buf1_size;
uint32_t buf2_size;
buf1_size = 1024;
buf2_size = 1024;
buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
(void) strlcpy(buf1, "Driver Type: ", buf1_size);
(void) strlcat(buf1, DUMP_DRV_LEADVILLE, buf1_size);
(void) snprintf(buf2, buf2_size, "%s", DRIVER_NAME);
(void) strlcat(buf1, "\n Driver Name: ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
(void) snprintf(buf2, buf2_size, "%s", emlxs_version);
(void) strlcat(buf1, "\n Driver Version: ", buf1_size);
(void) strlcat(buf1, buf2, buf1_size);
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_REV_INFO,
LEGEND_REV_DRV_VERSION, 0);
status =
emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_REV_INFO,
LEGEND_REV_INFO, LEGEND_REV_DRV_VERSION);
kmem_free(buf1, buf1_size);
kmem_free(buf2, buf2_size);
return (status);
}
static uint32_t
emlxs_dump_file_create(
emlxs_hba_t *hba,
emlxs_file_t ** fpTxtFile,
emlxs_file_t ** fpDmpFile,
emlxs_file_t ** fpCeeFile)
{
if (fpTxtFile) {
if ((*fpTxtFile = emlxs_fopen(hba, EMLXS_TXT_FILE)) == NULL) {
return (1);
}
}
if (fpCeeFile) {
*fpCeeFile = NULL;
if ((hba->model_info.vendor_id == PCI_VENDOR_ID_EMULEX &&
hba->model_info.device_id == PCI_DEVICE_ID_HORNET) ||
(hba->model_info.chip == EMLXS_BE2_CHIP) ||
(hba->model_info.chip == EMLXS_BE3_CHIP)) {
if ((*fpCeeFile =
emlxs_fopen(hba, EMLXS_CEE_FILE)) == NULL) {
emlxs_fdelete(*fpTxtFile);
return (1);
}
}
}
if (fpDmpFile) {
if ((*fpDmpFile = emlxs_fopen(hba, EMLXS_DMP_FILE)) == NULL) {
emlxs_fdelete(*fpTxtFile);
emlxs_fdelete(*fpCeeFile);
return (1);
}
#ifdef EMLXS_LITTLE_ENDIAN
emlxs_fputc(SID_DUMP_ID_LE, *fpDmpFile);
#endif
#ifdef EMLXS_BIG_ENDIAN
emlxs_fputc(SID_DUMP_ID_BE, *fpDmpFile);
#endif
emlxs_fputc(SID_NULL, *fpDmpFile);
emlxs_fputc(SID_NULL, *fpDmpFile);
emlxs_fputc(SID_NULL, *fpDmpFile);
emlxs_fflush(*fpDmpFile);
}
return (0);
}
static uint32_t
emlxs_dump_file_terminate(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile,
emlxs_file_t *fpCeeFile)
{
if (fpTxtFile) {
(void) emlxs_fprintf(fpTxtFile, "Dump File End\n");
emlxs_fflush(fpTxtFile);
}
if (fpCeeFile) {
if (hba->model_info.vendor_id == PCI_VENDOR_ID_EMULEX &&
hba->model_info.device_id == PCI_DEVICE_ID_HORNET) {
(void) emlxs_fprintf(fpCeeFile, "Dump File End\n");
}
emlxs_fflush(fpCeeFile);
}
if (fpDmpFile) {
emlxs_fputc(SID_DUMP_TERM, fpDmpFile);
emlxs_fflush(fpDmpFile);
}
return (0);
}
static uint32_t
emlxs_dump_file_close(
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile,
emlxs_file_t *fpCeeFile)
{
if (fpTxtFile) {
(void) emlxs_fclose(fpTxtFile);
}
if (fpCeeFile) {
(void) emlxs_fclose(fpCeeFile);
}
if (fpDmpFile) {
(void) emlxs_fclose(fpDmpFile);
}
return (0);
}
static uint32_t
emlxs_dump_rev_info(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
(void) emlxs_dump_os_version(hba, fpTxtFile, fpDmpFile);
(void) emlxs_dump_drv_version(hba, fpTxtFile, fpDmpFile);
return (0);
}
static uint32_t
emlxs_dump_hba_info(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile,
uint32_t dump_type)
{
(void) emlxs_dump_model(hba, fpTxtFile, fpDmpFile);
(void) emlxs_dump_wwn(hba, fpTxtFile, fpDmpFile);
(void) emlxs_dump_serial_number(hba, fpTxtFile, fpDmpFile);
(void) emlxs_dump_fw_version(hba, fpTxtFile, fpDmpFile);
(void) emlxs_dump_boot_version(hba, fpTxtFile, fpDmpFile);
return (0);
}
static uint32_t
emlxs_dump_table_check(
emlxs_hba_t *hba,
uint32_t *pSize)
{
emlxs_port_t *port = &PPORT;
int fDone = FALSE;
uint32_t tableSize = 0;
MAILBOX *mb;
MAILBOXQ *mbq;
uint32_t DumpTableAddr;
DUMP_TABLE_ENTRY entry;
*pSize = 0;
mbq =
(MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP);
mb = (MAILBOX *) mbq;
emlxs_mb_dump(hba, mbq, 0x654, 1);
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"Unable to read dump table address. "\
"offset=0x654 status=%x",
mb->mbxStatus);
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
DumpTableAddr = mb->un.varDmp.resp_offset;
if (DumpTableAddr == 0) {
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
while (!fDone) {
emlxs_mb_dump(hba, mbq, DumpTableAddr, 2);
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"Unable to read dump table entry. "\
"offset=%x status=%x",
DumpTableAddr, mb->mbxStatus);
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
entry.un.PortBlock.un.w[0] = mb->un.varWords[4];
switch (entry.un.PortBlock.un.s.sid) {
case SID_ID01:
tableSize++;
DumpTableAddr += 4;
break;
#ifdef CC_DUMP_USE_ALL_TABLES
case SID_ID02:
case SID_ID03:
tableSize++;
DumpTableAddr += 4;
break;
#else
case SID_ID02:
case SID_ID03:
tableSize++;
fDone = TRUE;
break;
#endif
case SID_TERM:
tableSize++;
fDone = TRUE;
break;
default:
tableSize += 2;
DumpTableAddr += 8;
break;
}
}
*pSize = (tableSize * 4);
kmem_free(mbq, sizeof (MAILBOXQ));
return (0);
}
static uint32_t
emlxs_dump_table_read(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
uint32_t **ppDumpTable,
uint32_t *pDumpTableSize)
{
emlxs_port_t *port = &PPORT;
uint32_t status = 0;
int fDone = FALSE;
MAILBOXQ *mbq;
MAILBOX *mb;
uint32_t *pDumpTableEntry;
uint32_t DumpTableAddr;
DUMP_TABLE_ENTRY entry;
char buf2[256];
char *buf1;
uint32_t size = (32 * 1024);
status = emlxs_dump_table_check(hba, pDumpTableSize);
if (status != 0) {
return (status);
}
buf1 = (char *)kmem_zalloc(size, KM_SLEEP);
*ppDumpTable = (uint32_t *)kmem_zalloc(*pDumpTableSize, KM_SLEEP);
pDumpTableEntry = *ppDumpTable;
mbq =
(MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP);
mb = (MAILBOX *) mbq;
emlxs_mb_dump(hba, mbq, 0x654, 1);
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"Unable to read dump table address. "\
"offset=0x654 status=%x",
mb->mbxStatus);
kmem_free(buf1, size);
kmem_free(mbq, sizeof (MAILBOXQ));
kmem_free(*ppDumpTable, *pDumpTableSize);
*pDumpTableSize = 0;
*ppDumpTable = NULL;
return (1);
}
DumpTableAddr = mb->un.varDmp.resp_offset;
if (DumpTableAddr == 0) {
kmem_free(buf1, size);
kmem_free(mbq, sizeof (MAILBOXQ));
kmem_free(*ppDumpTable, *pDumpTableSize);
*pDumpTableSize = 0;
*ppDumpTable = NULL;
return (1);
}
while (!fDone) {
emlxs_mb_dump(hba, mbq, DumpTableAddr, 2);
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"Unable to read dump table entry. "\
"offset=%x status=%x",
DumpTableAddr, mb->mbxStatus);
kmem_free(buf1, size);
kmem_free(mbq, sizeof (MAILBOXQ));
kmem_free(*ppDumpTable, *pDumpTableSize);
*pDumpTableSize = 0;
*ppDumpTable = NULL;
return (1);
}
(void) snprintf(buf2, sizeof (buf2), "\n Addr=%08x: ",
mb->un.varDmp.base_adr);
(void) strlcat(buf1, buf2, size);
entry.un.PortBlock.un.w[0] = mb->un.varWords[4];
*pDumpTableEntry++ = mb->un.varWords[4];
switch (entry.un.PortBlock.un.s.sid) {
case SID_ID01:
(void) snprintf(buf2, sizeof (buf2), "w0=%08x",
entry.un.PortBlock.un.w[0]);
(void) strlcat(buf1, buf2, size);
DumpTableAddr += 4;
break;
#ifdef CC_DUMP_USE_ALL_TABLES
case SID_ID02:
case SID_ID03:
(void) snprintf(buf2, sizeof (buf2), "w0=%08x",
entry.un.PortBlock.un.w[0]);
(void) strlcat(buf1, buf2, size);
DumpTableAddr += 4;
break;
#else
case SID_ID02:
case SID_ID03:
(void) snprintf(buf2, sizeof (buf2), "w0=%08x",
entry.un.PortBlock.un.w[0]);
(void) strlcat(buf1, buf2, size);
fDone = TRUE;
break;
#endif
case SID_TERM:
(void) snprintf(buf2, sizeof (buf2), "w0=%08x",
entry.un.PortBlock.un.w[0]);
(void) strlcat(buf1, buf2, size);
fDone = TRUE;
break;
default:
entry.un.PortBlock.un.w[1] = mb->un.varWords[5];
*pDumpTableEntry++ = mb->un.varWords[5];
(void) snprintf(buf2, sizeof (buf2), "w0=%08x, w1=%08x",
entry.un.PortBlock.un.w[0],
entry.un.PortBlock.un.w[1]);
(void) strlcat(buf1, buf2, size);
DumpTableAddr += 8;
break;
}
}
status =
emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_MEM_DUMP,
LEGEND_HBA_MEM_DUMP_TABLE, 0);
kmem_free(buf1, size);
kmem_free(mbq, sizeof (MAILBOXQ));
if (status != 0) {
kmem_free(*ppDumpTable, *pDumpTableSize);
*pDumpTableSize = 0;
*ppDumpTable = NULL;
return (status);
}
return (0);
}
static uint32_t
emlxs_dump_hba_memory(
emlxs_hba_t *hba,
emlxs_file_t *fpDmpFile,
uint32_t *pDumpTable)
{
emlxs_port_t *port = &PPORT;
uint32_t status = 0;
int fDone = FALSE;
DUMP_TABLE_ENTRY entry;
MAILBOXQ *mbq;
MAILBOX *mb;
uint32_t byteCount;
uint32_t byteCountRem;
uint8_t *pBuf;
uint8_t *p1;
uint32_t portAddr;
int fSwap = FALSE;
uint32_t offset = 0;
uint32_t wcount;
uint32_t total = 0;
#ifdef EMLXS_BIG_ENDIAN
fSwap = TRUE;
#endif
if (!fpDmpFile) {
return (1);
}
mbq =
(MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP);
mb = (MAILBOX *) mbq;
while (!fDone) {
entry.un.PortBlock.un.w[0] = *pDumpTable++;
switch (entry.un.PortBlock.un.s.sid) {
case SID_ID01:
break;
#ifdef CC_DUMP_USE_ALL_TABLES
case SID_ID02:
case SID_ID03:
break;
#else
case SID_ID02:
case SID_ID03:
fDone = TRUE;
break;
#endif
case SID_TERM:
fDone = TRUE;
break;
default:
entry.un.PortBlock.un.w[1] = *pDumpTable++;
#ifdef CC_DUMP_FW_BUG_1
if (entry.un.PortBlock.un.w[1] == 0x3E0000) {
break;
}
#endif
if ((entry.un.PortBlock.un.s.addr & 0x80000000) != 0) {
offset =
(entry.un.PortBlock.un.s.
addr & 0x01FFFFFF);
emlxs_mb_dump(hba, mbq, offset, 1);
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT,
0) != MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT,
&emlxs_init_debug_msg,
"Unable to read dump table entry. "\
"offset=%x status=%x",
offset, mb->mbxStatus);
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
entry.un.PortBlock.un.s.addr =
mb->un.varWords[4];
}
byteCount = entry.un.PortBlock.un.s.bc;
if (entry.un.PortBlock.un.s.sid & SID_MULT_ELEM) {
if (entry.un.PortStruct.un.s.count == 0) {
byteCount =
256 *
entry.un.PortStruct.un.s.length;
} else {
byteCount =
entry.un.PortStruct.un.s.count *
entry.un.PortStruct.un.s.length;
}
}
total += byteCount;
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"Dump: addr=%x count=%d total=%d", offset,
byteCount, total);
pBuf = (uint8_t *)kmem_zalloc(byteCount, KM_SLEEP);
byteCountRem = byteCount;
p1 = pBuf;
portAddr = entry.un.PortBlock.un.s.addr;
for (;;) {
if (byteCountRem == 0) {
break;
}
wcount =
(byteCountRem / 4 >=
0x18) ? 0x18 : (byteCountRem / 4);
emlxs_mb_dump(hba, mbq, portAddr, wcount);
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT,
0) != MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT,
&emlxs_init_debug_msg,
"Unable to read dump table entry."\
" offset=%x wc=%d status=%x",
portAddr, wcount, mb->mbxStatus);
break;
}
bcopy((uint8_t *)&mb->un.varWords[4], p1,
(mb->un.varDmp.word_cnt * 4));
byteCountRem -= (mb->un.varDmp.word_cnt * 4);
p1 += (mb->un.varDmp.word_cnt * 4);
portAddr += (mb->un.varDmp.word_cnt * 4);
}
if (status == 0) {
if (entry.un.PortBlock.un.s.
sid & SID_MULT_ELEM) {
status =
emlxs_dump_port_struct(fpDmpFile,
pBuf, byteCount, entry, fSwap);
} else {
status =
emlxs_dump_port_block(fpDmpFile,
pBuf, byteCount, entry, fSwap);
}
}
if (pBuf) {
kmem_free(pBuf, byteCount);
}
break;
}
}
kmem_free(mbq, sizeof (MAILBOXQ));
return (status);
}
static uint32_t
emlxs_dump_hba(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
uint32_t status = 0;
uint32_t *pDumpTable = 0;
uint32_t DumpTableSize = 0;
if (hba->sli_mode >= EMLXS_HBA_SLI4_MODE) {
return (1);
}
status =
emlxs_dump_table_read(hba, fpTxtFile, &pDumpTable,
&DumpTableSize);
if (status) {
return (status);
}
status = emlxs_dump_hba_memory(hba, fpDmpFile, pDumpTable);
if (pDumpTable != 0) {
kmem_free(pDumpTable, DumpTableSize);
}
return (status);
}
static uint32_t
emlxs_dump_drv_region(
emlxs_hba_t *hba,
uint32_t regionId,
uint8_t **pBuf,
uint32_t *pBufLen)
{
uint32_t status;
uint32_t size;
*pBuf = NULL;
*pBufLen = 0;
size = 0;
status = emlxs_get_dump_region(hba, regionId, NULL, &size);
if (status != 0) {
return (1);
}
*pBuf = (uint8_t *)kmem_zalloc(size, KM_SLEEP);
status = emlxs_get_dump_region(hba, regionId, *pBuf, &size);
if (status != 0) {
kmem_free(*pBuf, size);
*pBuf = NULL;
return (1);
}
*pBufLen = size;
return (status);
}
static uint32_t
emlxs_dump_sli_regs(
emlxs_hba_t *hba,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
uint8_t *pBuf;
uint32_t bufLen = 0;
int fSwap = FALSE;
#ifdef EMLXS_BIG_ENDIAN
fSwap = TRUE;
#endif
if (!fpDmpFile) {
return (1);
}
status = emlxs_dump_drv_region(hba, DR_SLI_REGS, &pBuf, &bufLen);
if (status != 0) {
return (status);
}
status =
emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_SLI_REGS,
LEGEND_SLI_STRUCTURES, LEGEND_SLI_REGS, fSwap);
kmem_free(pBuf, bufLen);
return (status);
}
static uint32_t
emlxs_dump_slim(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile,
uint32_t dump_type)
{
uint32_t status;
uint8_t *pBuf;
uint32_t bufLen = 0;
int fSwap = FALSE;
#ifdef EMLXS_BIG_ENDIAN
fSwap = TRUE;
#endif
status = emlxs_dump_drv_region(hba, DR_SLIM, &pBuf, &bufLen);
if (status != 0) {
return (status);
}
if (dump_type == DUMP_TYPE_DRIVER) {
status =
emlxs_dump_word_txtfile(fpTxtFile, (uint32_t *)pBuf,
0x40, LEGEND_SLI_STRUCTURES, LEGEND_SLIM);
}
status =
emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_SLIM,
LEGEND_SLI_STRUCTURES, LEGEND_SLIM, fSwap);
kmem_free(pBuf, bufLen);
return (status);
}
static uint32_t
emlxs_dump_pcb(
emlxs_hba_t *hba,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
uint8_t *pBuf;
uint32_t bufLen = 0;
int fSwap = FALSE;
#ifdef EMLXS_BIG_ENDIAN
fSwap = TRUE;
#endif
if (!fpDmpFile) {
return (1);
}
status = emlxs_dump_drv_region(hba, DR_PCB, &pBuf, &bufLen);
if (status != 0) {
return (status);
}
status =
emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_PCB,
LEGEND_SLI_STRUCTURES, LEGEND_PCB, fSwap);
kmem_free(pBuf, bufLen);
return (status);
}
static uint32_t
emlxs_dump_mbox(
emlxs_hba_t *hba,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
uint8_t *pBuf;
uint32_t bufLen = 0;
int fSwap = FALSE;
#ifdef EMLXS_BIG_ENDIAN
fSwap = TRUE;
#endif
if (!fpDmpFile) {
return (1);
}
status = emlxs_dump_drv_region(hba, DR_MBX, &pBuf, &bufLen);
if (status != 0) {
return (status);
}
status =
emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_MBX,
LEGEND_SLI_STRUCTURES, LEGEND_MBX, fSwap);
kmem_free(pBuf, bufLen);
return (status);
}
static uint32_t
emlxs_dump_host_pointers(
emlxs_hba_t *hba,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
uint8_t *pBuf;
uint32_t bufLen = 0;
int fSwap = FALSE;
#ifdef EMLXS_BIG_ENDIAN
fSwap = TRUE;
#endif
if (!fpDmpFile) {
return (1);
}
status = emlxs_dump_drv_region(hba, DR_HOST_PTRS, &pBuf, &bufLen);
if (status != 0) {
return (status);
}
status =
emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_HOST_PTRS,
LEGEND_SLI_STRUCTURES, LEGEND_HOST_PTRS, fSwap);
kmem_free(pBuf, bufLen);
return (status);
}
static uint32_t
emlxs_dump_port_pointers(
emlxs_hba_t *hba,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
uint8_t *pBuf;
uint32_t bufLen = 0;
int fSwap = FALSE;
#ifdef EMLXS_BIG_ENDIAN
fSwap = TRUE;
#endif
if (!fpDmpFile) {
return (1);
}
status = emlxs_dump_drv_region(hba, DR_PORT_PTRS, &pBuf, &bufLen);
if (status != 0) {
return (status);
}
status =
emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_PORT_PTRS,
LEGEND_SLI_STRUCTURES, LEGEND_PORT_PTRS, fSwap);
kmem_free(pBuf, bufLen);
return (status);
}
static uint32_t
emlxs_dump_rings(
emlxs_hba_t *hba,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
uint8_t *pBuf;
uint32_t bufLen = 0;
int fSwap = FALSE;
#ifdef EMLXS_BIG_ENDIAN
fSwap = TRUE;
#endif
if (!fpDmpFile) {
return (1);
}
status = emlxs_dump_drv_region(hba, DR_RINGS, &pBuf, &bufLen);
if (status != 0) {
return (status);
}
status =
emlxs_dump_host_struct(fpDmpFile, pBuf, bufLen, sizeof (IOCB),
bufLen / sizeof (IOCB), SID_RINGS, LEGEND_SLI_STRUCTURES,
LEGEND_RINGS, fSwap);
kmem_free(pBuf, bufLen);
return (status);
}
static uint32_t
emlxs_dump_drv_internals(
emlxs_hba_t *hba,
emlxs_file_t *fpDmpFile)
{
uint32_t status;
uint8_t *pBuf;
uint32_t bufLen = 0;
int fSwap = FALSE;
#ifdef EMLXS_BIG_ENDIAN
fSwap = TRUE;
#endif
if (!fpDmpFile) {
return (1);
}
status = emlxs_dump_drv_region(hba, DR_INTERNAL, &pBuf, &bufLen);
if (status != 0) {
return (status);
}
status =
emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_INTERNAL_SOL,
LEGEND_SLI_STRUCTURES, LEGEND_DRIVER_SPEC, fSwap);
kmem_free(pBuf, bufLen);
return (status);
}
static uint32_t
emlxs_dump_sli_interface(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile,
uint32_t dump_type)
{
if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
(void) emlxs_dump_sli_regs(hba, fpDmpFile);
(void) emlxs_dump_slim(hba, fpTxtFile, fpDmpFile, dump_type);
(void) emlxs_dump_pcb(hba, fpDmpFile);
(void) emlxs_dump_mbox(hba, fpDmpFile);
(void) emlxs_dump_host_pointers(hba, fpDmpFile);
(void) emlxs_dump_port_pointers(hba, fpDmpFile);
(void) emlxs_dump_rings(hba, fpDmpFile);
}
(void) emlxs_dump_drv_internals(hba, fpDmpFile);
return (0);
}
static uint32_t
emlxs_dump_menlo_log(
emlxs_hba_t *hba,
emlxs_file_t *fpCeeFile)
{
uint32_t RmStatus;
int i, j;
int isWrapped = FALSE;
char buf1[2048] = { 0 };
char buf2[2048] = { 0 };
menlo_get_config_rsp_t GcBuf;
menlo_get_config_rsp_t *pGcBuf = &GcBuf;
uint32_t LcBufSize;
menlo_rsp_t *pLcBuf = NULL;
uint32_t NumLogs;
menlo_log_t *pLcEntry;
uint32_t LdBufSize;
menlo_rsp_t *pLdBuf = NULL;
uint16_t Head;
uint8_t *pLogEntry;
char *pLogString;
uint32_t PlBufSize;
menlo_rsp_t *pPlBuf = NULL;
uint32_t PanicLogEntryCount;
uint32_t PanicLogEntrySize;
if (hba->model_info.vendor_id != PCI_VENDOR_ID_EMULEX ||
hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
return (DFC_INVALID_ADAPTER);
}
RmStatus =
emlxs_menlo_get_cfg(hba, pGcBuf, sizeof (menlo_get_config_rsp_t));
if (RmStatus != 0) {
goto done;
}
LcBufSize = GcBuf.log_cfg_size + 8;
PlBufSize = GcBuf.panic_log_size;
pLcBuf = (menlo_rsp_t *)kmem_zalloc(LcBufSize, KM_SLEEP);
RmStatus = emlxs_menlo_get_logcfg(hba, pLcBuf, LcBufSize);
if (RmStatus != 0) {
goto done;
}
buf1[0] = 0;
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1,
LEGEND_MENLO_LOG_CONFIG, LEGEND_NULL, 0);
NumLogs = pLcBuf->log_cfg.num_logs;
pLcEntry = (menlo_log_t *)&pLcBuf->log_cfg.data;
buf1[0] = 0;
(void) snprintf(buf2, sizeof (buf2), "LogId Entries Size Name");
(void) strlcat(buf1, buf2, sizeof (buf1));
(void) snprintf(buf2, sizeof (buf2), "\n----- ------- ---- ----");
(void) strlcat(buf1, buf2, sizeof (buf1));
RmStatus = emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
for (i = 0; i < (int)NumLogs; i++) {
buf1[0] = 0;
(void) snprintf(buf2, sizeof (buf2),
"\n %2d %4d %4d %s",
pLcEntry[i].id,
pLcEntry[i].num_entries,
pLcEntry[i].entry_size, pLcEntry[i].name);
(void) strlcat(buf1, buf2, sizeof (buf1));
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
}
for (i = 0; i < (int)NumLogs; i++) {
LdBufSize =
(pLcEntry[i].num_entries *pLcEntry[i].entry_size) + 8;
pLdBuf = (menlo_rsp_t *)kmem_zalloc(LdBufSize, KM_SLEEP);
RmStatus = emlxs_menlo_get_log(hba, i, pLdBuf, LdBufSize);
if (RmStatus != 0) {
goto done;
}
buf1[0] = 0;
(void) snprintf(buf2, sizeof (buf2), "\n\nLog %d:", i);
(void) strlcat(buf1, buf2, sizeof (buf1));
(void) snprintf(buf2, sizeof (buf2), " %s", pLcEntry[i].name);
(void) strlcat(buf1, buf2, sizeof (buf1));
(void) snprintf(buf2, sizeof (buf2), "\n");
for (j = 0; j < 75; j++) {
(void) strlcat(buf2, "-", sizeof (buf2));
}
(void) strlcat(buf1, buf2, sizeof (buf1));
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
Head = pLdBuf->log.head;
pLogEntry = (uint8_t *)&pLdBuf->log.data;
pLogString =
(char *)&(pLogEntry[Head *pLcEntry[i].entry_size]);
isWrapped = FALSE;
if (strlen(pLogString) != 0) {
isWrapped = TRUE;
}
if (isWrapped) {
for (j = Head; j < (int)pLcEntry[i].num_entries; j++) {
pLogString =
(char *)&(pLogEntry[j *
pLcEntry[i].entry_size]);
buf1[0] = 0;
(void) snprintf(buf2, sizeof (buf2),
"\n%3d: %s", j, pLogString);
(void) strlcat(buf1, buf2, sizeof (buf1));
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1,
0, 0, 1);
}
}
for (j = 0; j < Head; j++) {
pLogString =
(char *)&(pLogEntry[j * pLcEntry[i].entry_size]);
buf1[0] = 0;
(void) snprintf(buf2, sizeof (buf2), "\n%3d: %s", j,
pLogString);
(void) strlcat(buf1, buf2, sizeof (buf1));
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0,
1);
}
}
(void) strlcpy(buf1, LEGEND_MENLO_LOG_PANIC_REGS, sizeof (buf1));
buf2[0] = 0;
for (j = 0; j < 75; j++) {
(void) strlcat(buf2, "-", sizeof (buf2));
}
(void) strlcat(buf1, buf2, sizeof (buf1));
RmStatus = emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
pPlBuf = (menlo_rsp_t *)kmem_zalloc(PlBufSize, KM_SLEEP);
RmStatus = emlxs_menlo_get_paniclog(hba, pPlBuf, PlBufSize);
if (RmStatus == 0) {
buf1[0] = 0;
(void) snprintf(buf2, sizeof (buf2), "\nType = %x",
pPlBuf->panic_log.type);
(void) strlcat(buf1, buf2, sizeof (buf1));
(void) snprintf(buf2, sizeof (buf2), "\nRegsEpc = %08x",
pPlBuf->panic_log.regs_epc);
(void) strlcat(buf1, buf2, sizeof (buf1));
(void) snprintf(buf2, sizeof (buf2), "\nRegsCp0Cause = %08x",
pPlBuf->panic_log.regs_cp0_cause);
(void) strlcat(buf1, buf2, sizeof (buf1));
(void) snprintf(buf2, sizeof (buf2), "\nRegsCp0Stat = %08x",
pPlBuf->panic_log.regs_cp0_status);
(void) strlcat(buf1, buf2, sizeof (buf1));
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
buf1[0] = 0;
for (i = 0; i < MENLO_NUM_GP_REGS; i++) {
(void) snprintf(buf2, sizeof (buf2),
"\nRegsGp[%02x] = %08x", i,
pPlBuf->panic_log.regs_gp[i]);
(void) strlcat(buf1, buf2, sizeof (buf1));
}
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
buf1[0] = 0;
(void) snprintf(buf2, sizeof (buf2), "\nLogPresent = %08x",
pPlBuf->panic_log.log_present);
(void) strlcat(buf1, buf2, sizeof (buf1));
PanicLogEntryCount = pPlBuf->panic_log.num_entries;
(void) snprintf(buf2, sizeof (buf2), "\nNumEntries = %08x",
PanicLogEntryCount);
(void) strlcat(buf1, buf2, sizeof (buf1));
PanicLogEntrySize = pPlBuf->panic_log.entry_size;
(void) snprintf(buf2, sizeof (buf2), "\nEntrySize = %d.",
PanicLogEntrySize);
(void) strlcat(buf1, buf2, sizeof (buf1));
(void) snprintf(buf2, sizeof (buf2), "\nHead Entry = %d.",
pPlBuf->panic_log.head);
(void) strlcat(buf1, buf2, sizeof (buf1));
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
(void) strlcpy(buf1, LEGEND_MENLO_LOG_PANIC_LOGS,
sizeof (buf1));
buf2[0] = 0;
for (j = 0; j < 75; j++) {
(void) strlcat(buf2, "-", sizeof (buf2));
}
(void) strlcat(buf1, buf2, sizeof (buf2));
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
Head = pPlBuf->panic_log.head;
pLogEntry = (uint8_t *)&pPlBuf->panic_log.data;
pLogString = (char *)&(pLogEntry[Head * PanicLogEntrySize]);
isWrapped = FALSE;
if (strlen(pLogString) != 0) {
isWrapped = TRUE;
}
if (isWrapped) {
for (j = Head; j < (int)PanicLogEntryCount; j++) {
pLogString =
(char *)&(pLogEntry[j *
PanicLogEntrySize]);
buf1[0] = 0;
(void) snprintf(buf2, sizeof (buf2),
"\n%3d: %s", j, pLogString);
(void) strlcat(buf1, buf2, sizeof (buf2));
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1,
0, 0, 1);
}
}
for (j = 0; j < Head; j++) {
pLogString =
(char *)&(pLogEntry[j * PanicLogEntrySize]);
buf1[0] = 0;
(void) snprintf(buf2, sizeof (buf2), "\n%3d: %s", j,
pLogString);
(void) strlcat(buf1, buf2, sizeof (buf2));
RmStatus =
emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0,
1);
}
}
RmStatus = emlxs_dump_string_txtfile(fpCeeFile, "\n\n", 0, 0, 1);
done:
if (pLdBuf != 0) {
kmem_free(pLdBuf, LdBufSize);
}
if (pLcBuf != 0) {
kmem_free(pLcBuf, LcBufSize);
}
if (pPlBuf != 0) {
kmem_free(pPlBuf, PlBufSize);
}
return (RmStatus);
}
static uint32_t
emlxs_dump_saturn_log(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpDmpFile)
{
emlxs_port_t *port = &PPORT;
MAILBOXQ *mbq;
MAILBOX *mb;
MATCHMAP *mp = NULL;
uint32_t status;
uint32_t logSize = 0;
uintptr_t tempAddress;
int fSwap = FALSE;
uint32_t i;
uint32_t block_size;
uint32_t offset;
#ifdef EMLXS_BIG_ENDIAN
fSwap = TRUE;
#endif
if (hba->model_info.chip != EMLXS_SATURN_CHIP) {
return (1);
}
mbq =
(MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP);
mb = (MAILBOX *) mbq;
for (i = 0; i < 10; i++) {
bzero((void *)mb, MAILBOX_CMD_BSIZE);
mb->mbxCommand = MBX_READ_EVENT_LOG_STATUS;
mbq->mbox_cmpl = NULL;
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) ==
MBX_SUCCESS) {
break;
}
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"Unable to read event log status. status=%x",
mb->mbxStatus);
if ((mb->mbxStatus & 0xFFFF) == MBXERR_NOT_SUPPORTED ||
(mb->mbxStatus & 0xFFFF) == MBX_DRVR_ERROR) {
(void) emlxs_dump_string_txtfile(fpTxtFile,
NV_LOG_NOT_INCLUDED_IN_DMP,
LEGEND_NON_VOLATILE_LOG,
LEGEND_NV_LOG_DRIVER_NOT_SUPPORTED, 0);
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
if ((mb->mbxStatus & 0xFFFF) != MBX_BUSY) {
(void) emlxs_dump_string_txtfile(fpTxtFile,
NV_LOG_NOT_INCLUDED_IN_DMP,
LEGEND_NON_VOLATILE_LOG,
LEGEND_NV_LOG_STATUS_ERROR, 0);
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
}
if (i >= 10) {
(void) emlxs_dump_string_txtfile(fpTxtFile,
NV_LOG_NOT_INCLUDED_IN_DMP, LEGEND_NON_VOLATILE_LOG,
LEGEND_NV_LOG_STATUS_ERROR, 0);
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
logSize = mb->un.varLogStat.size;
if ((mp = emlxs_mem_buf_alloc(hba, logSize)) == 0) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"Unable to allocate receive buffer. "
"size=%d",
logSize);
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
for (offset = 0; offset < logSize; offset = offset + 1024) {
if (logSize - offset < 1024) {
block_size = logSize - offset;
} else {
block_size = 1024;
}
tempAddress = (uintptr_t)(mp->phys + offset);
bzero((void *)mb, MAILBOX_CMD_BSIZE);
mb->mbxCommand = MBX_READ_EVENT_LOG;
mb->un.varRdEvtLog.read_log = 1;
mb->un.varRdEvtLog.mbox_rsp = 0;
mb->un.varRdEvtLog.offset = offset;
mb->un.varRdEvtLog.un.sp64.tus.f.bdeFlags = 0x0;
mb->un.varRdEvtLog.un.sp64.tus.f.bdeSize = block_size;
mb->un.varRdEvtLog.un.sp64.addrLow = PADDR_LO(tempAddress);
mb->un.varRdEvtLog.un.sp64.addrHigh = PADDR_HI(tempAddress);
mbq->mbox_cmpl = NULL;
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
"Unable to read event log. status=%x",
mb->mbxStatus);
emlxs_mem_buf_free(hba, mp);
kmem_free(mbq, sizeof (MAILBOXQ));
return (1);
}
}
status =
emlxs_dump_string_txtfile(fpTxtFile, NV_LOG_INCLUDED_IN_DMP,
LEGEND_NON_VOLATILE_LOG, LEGEND_NULL, 0);
EMLXS_MPDATA_SYNC(mp->dma_handle, 0, logSize, DDI_DMA_SYNC_FORKERNEL);
status =
emlxs_dump_host_block(fpDmpFile, mp->virt, logSize,
SID_NON_VOLATILE_LOG, LEGEND_NON_VOLATILE_LOG, LEGEND_NULL,
fSwap);
#ifdef FMA_SUPPORT
if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
!= DDI_FM_OK) {
EMLXS_MSGF(EMLXS_CONTEXT,
&emlxs_invalid_dma_handle_msg,
"dump_saturn_log: hdl=%p",
mp->dma_handle);
status = 1;
}
#endif
emlxs_mem_buf_free(hba, mp);
kmem_free(mbq, sizeof (MAILBOXQ));
return (status);
}
static uint32_t
emlxs_dump_tigershark_log(
emlxs_hba_t *hba,
emlxs_file_t *fpTxtFile,
emlxs_file_t *fpCeeFile)
{
emlxs_port_t *port = &PPORT;
uint32_t rval = 0;
uint32_t offset;
uint32_t log_size;
uint32_t xfer_size;
uint32_t buffer_size;
uint8_t *buffer = NULL;
uint8_t *bptr;
uint8_t *payload;
MAILBOXQ *mbq = NULL;
MAILBOX4 *mb = NULL;
MATCHMAP *mp = NULL;
IOCTL_COMMON_MANAGE_FAT *fat;
mbox_req_hdr_t *hdr_req;
if ((hba->model_info.chip != EMLXS_BE2_CHIP) &&
(hba->model_info.chip != EMLXS_BE3_CHIP)) {
return (1);
}
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"Querying FAT...");
mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
KM_SLEEP);
mb = (MAILBOX4*)mbq;
if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) +
sizeof (IOCTL_COMMON_MANAGE_FAT) + BE_MAX_XFER_SIZE))) == NULL) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"Unable to allocate FAT buffer.");
rval = 1;
goto done;
}
mb->un.varSLIConfig.be.embedded = 0;
mbq->nonembed = (void *)mp;
mbq->mbox_cmpl = NULL;
mb->mbxCommand = MBX_SLI_CONFIG;
mb->mbxOwner = OWN_HOST;
hdr_req = (mbox_req_hdr_t *)mp->virt;
hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
hdr_req->opcode = COMMON_OPCODE_MANAGE_FAT;
hdr_req->timeout = 0;
hdr_req->req_length = sizeof (IOCTL_COMMON_MANAGE_FAT);
fat = (IOCTL_COMMON_MANAGE_FAT *)(hdr_req + 1);
fat->params.request.fat_operation = QUERY_FAT;
fat->params.request.read_log_offset = 0;
fat->params.request.read_log_length = 0;
fat->params.request.data_buffer_size = BE_MAX_XFER_SIZE;
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"FAT Query failed. status=%x",
mb->mbxStatus);
rval = 1;
goto done;
}
log_size = fat->params.response.log_size;
buffer_size = fat->params.response.log_size;
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"FAT: log_size=%d", log_size);
if (buffer_size == 0) {
goto done;
}
if ((buffer = (uint8_t *)kmem_alloc(
buffer_size, KM_NOSLEEP)) == NULL) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"Unable to allocate log buffer.");
rval = 1;
goto done;
}
bzero(buffer, buffer_size);
bptr = buffer;
offset = 0;
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"Uploading log... (%d bytes)", log_size);
while (log_size) {
bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
bzero((void *) mp->virt, mp->size);
xfer_size = min(BE_MAX_XFER_SIZE, log_size);
mb->un.varSLIConfig.be.embedded = 0;
mbq->nonembed = (void *)mp;
mbq->mbox_cmpl = NULL;
mb->mbxCommand = MBX_SLI_CONFIG;
mb->mbxOwner = OWN_HOST;
hdr_req = (mbox_req_hdr_t *)mp->virt;
hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
hdr_req->opcode = COMMON_OPCODE_MANAGE_FAT;
hdr_req->timeout = 0;
hdr_req->req_length =
sizeof (IOCTL_COMMON_MANAGE_FAT) + xfer_size;
fat = (IOCTL_COMMON_MANAGE_FAT *)(hdr_req + 1);
fat->params.request.fat_operation = RETRIEVE_FAT;
fat->params.request.read_log_offset = offset;
fat->params.request.read_log_length = xfer_size;
fat->params.request.data_buffer_size = BE_MAX_XFER_SIZE;
if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
MBX_SUCCESS) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"Failed to upload log. status=%x",
mb->mbxStatus);
(void) emlxs_dump_string_txtfile(fpTxtFile,
NV_LOG_NOT_INCLUDED_IN_FAT,
LEGEND_NON_VOLATILE_LOG,
LEGEND_NV_LOG_STATUS_ERROR, 0);
rval = 1;
goto done;
}
payload = (uint8_t *)(&fat->params.response.data_buffer);
BE_SWAP32_BCOPY(payload, bptr, xfer_size);
log_size -= xfer_size;
offset += xfer_size;
bptr += xfer_size;
}
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"Log upload complete.");
rval =
emlxs_dump_string_txtfile(fpTxtFile, NV_LOG_INCLUDED_IN_FAT,
LEGEND_NON_VOLATILE_LOG, LEGEND_NULL, 0);
bptr = buffer + sizeof (uint32_t);
log_size = buffer_size - sizeof (uint32_t);
rval = emlxs_dump_word_dmpfile(fpCeeFile, (uint8_t *)bptr,
log_size, 0);
done:
if (mbq) {
emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
}
if (mp) {
emlxs_mem_buf_free(hba, mp);
}
if (buffer) {
kmem_free(buffer, buffer_size);
}
if (rval == 0) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"Dump complete.");
}
return (rval);
}
extern uint32_t
emlxs_dump_user_event(
emlxs_hba_t *hba)
{
emlxs_port_t *port = &PPORT;
uint32_t status;
emlxs_file_t *fpTxtFile;
emlxs_file_t *fpDmpFile;
emlxs_file_t *fpCeeFile;
mutex_enter(&EMLXS_DUMP_LOCK);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"User Event: Firmware core dump initiated...");
status =
emlxs_dump_file_create(hba, &fpTxtFile, &fpDmpFile, &fpCeeFile);
if (status != 0) {
mutex_exit(&EMLXS_DUMP_LOCK);
return (1);
}
(void) emlxs_dump_rev_info(hba, fpTxtFile, fpDmpFile);
(void) emlxs_dump_hba_info(hba, fpTxtFile, fpDmpFile, DUMP_TYPE_USER);
(void) emlxs_dump_parm_table(hba, fpTxtFile, fpDmpFile);
(void) emlxs_dump_cfg_regions(hba, fpTxtFile, fpDmpFile);
if (hba->model_info.chip == EMLXS_SATURN_CHIP) {
(void) emlxs_set_hba_mode(hba, DDI_ONDI);
(void) emlxs_dump_saturn_log(hba, fpTxtFile, fpDmpFile);
}
if ((hba->model_info.chip == EMLXS_BE2_CHIP) ||
(hba->model_info.chip == EMLXS_BE3_CHIP)) {
(void) emlxs_dump_tigershark_log(hba, fpTxtFile, fpCeeFile);
}
if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
(void) emlxs_set_hba_mode(hba, DDI_DIAGDI);
}
(void) emlxs_dump_sli_interface(hba, fpTxtFile, fpDmpFile,
DUMP_TYPE_USER);
if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
(void) emlxs_set_hba_mode(hba, DDI_WARMDI);
}
(void) emlxs_dump_hba(hba, fpTxtFile, fpDmpFile);
(void) emlxs_set_hba_mode(hba, DDI_ONDI);
status = emlxs_menlo_set_mode(hba, MENLO_MAINTENANCE_MODE_ENABLE);
if (status == 0) {
(void) emlxs_dump_menlo_log(hba, fpCeeFile);
(void) emlxs_menlo_set_mode(hba,
MENLO_MAINTENANCE_MODE_DISABLE);
}
(void) emlxs_dump_file_terminate(hba, fpTxtFile, fpDmpFile, fpCeeFile);
(void) emlxs_dump_file_close(fpTxtFile, fpDmpFile, fpCeeFile);
mutex_exit(&EMLXS_DUMP_LOCK);
return (0);
}
extern uint32_t
emlxs_dump_temp_event(
emlxs_hba_t *hba,
uint32_t tempType,
uint32_t temp)
{
emlxs_port_t *port = &PPORT;
uint32_t status;
emlxs_file_t *fpTxtFile;
char sBuf1[512];
char sBuf2[256];
char sBuf3[256];
if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"Temperature Event: type=%d temp=%d. "\
"Invalid SLI4 event.",
tempType, temp);
return (1);
}
mutex_enter(&EMLXS_DUMP_LOCK);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"Temperature Event: type=%d temp=%d. "\
"Firmware core dump initiated...",
tempType, temp);
status = emlxs_dump_file_create(hba, &fpTxtFile, 0, 0);
if (status != 0) {
mutex_exit(&EMLXS_DUMP_LOCK);
return (1);
}
(void) strlcpy(sBuf1, "WARNING: HBA Temperature Event:\n",
sizeof (sBuf1));
switch (tempType) {
case TEMP_TYPE_CRITICAL:
(void) snprintf(sBuf2, sizeof (sBuf2),
" Event Type = %d (Critical)\n", tempType);
break;
case TEMP_TYPE_THRESHOLD:
(void) snprintf(sBuf2, sizeof (sBuf2),
" Event Type = %d (Threshold)\n", tempType);
break;
case TEMP_TYPE_NORMAL:
(void) snprintf(sBuf2, sizeof (sBuf2),
" Event Type = %d (Normal)\n", tempType);
break;
default:
(void) snprintf(sBuf2, sizeof (sBuf2),
" Unknown Event Type = %d\n", tempType);
break;
}
(void) snprintf(sBuf3, sizeof (sBuf3), " Temperature = %d\n\n", temp);
(void) strlcat(sBuf1, sBuf2, sizeof (sBuf1));
(void) strlcat(sBuf1, sBuf3, sizeof (sBuf1));
(void) emlxs_dump_string_txtfile(fpTxtFile, sBuf1, 0, 0, 0);
(void) emlxs_dump_rev_info(hba, fpTxtFile, NULL);
(void) emlxs_dump_hba_info(hba, fpTxtFile, NULL, DUMP_TYPE_TEMP);
(void) emlxs_dump_file_terminate(hba, fpTxtFile, NULL, NULL);
(void) emlxs_dump_file_close(fpTxtFile, NULL, NULL);
mutex_exit(&EMLXS_DUMP_LOCK);
return (0);
}
extern uint32_t
emlxs_dump_drv_event(
emlxs_hba_t *hba)
{
emlxs_port_t *port = &PPORT;
uint32_t status;
emlxs_file_t *fpTxtFile;
emlxs_file_t *fpDmpFile;
emlxs_file_t *fpCeeFile;
mutex_enter(&EMLXS_DUMP_LOCK);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"Dump Event: Firmware core dump initiated...");
status =
emlxs_dump_file_create(hba, &fpTxtFile, &fpDmpFile, &fpCeeFile);
if (status != 0) {
mutex_exit(&EMLXS_DUMP_LOCK);
return (1);
}
if (hba->model_info.chip == EMLXS_SATURN_CHIP) {
(void) emlxs_set_hba_mode(hba, DDI_ONDI);
(void) emlxs_dump_saturn_log(hba, fpTxtFile, fpDmpFile);
}
if ((hba->model_info.chip == EMLXS_BE2_CHIP) ||
(hba->model_info.chip == EMLXS_BE3_CHIP)) {
(void) emlxs_dump_tigershark_log(hba, fpTxtFile, fpCeeFile);
}
if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
(void) emlxs_set_hba_mode(hba, DDI_DIAGDI);
}
(void) emlxs_dump_sli_interface(hba, fpTxtFile, fpDmpFile,
DUMP_TYPE_DRIVER);
if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
(void) emlxs_set_hba_mode(hba, DDI_WARMDI);
}
(void) emlxs_dump_hba(hba, fpTxtFile, fpDmpFile);
if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
(void) emlxs_set_hba_mode(hba, DDI_ONDI);
}
status = emlxs_menlo_set_mode(hba, MENLO_MAINTENANCE_MODE_ENABLE);
if (status == 0) {
(void) emlxs_dump_menlo_log(hba, fpCeeFile);
}
(void) emlxs_dump_rev_info(hba, fpTxtFile, fpDmpFile);
(void) emlxs_dump_hba_info(hba, fpTxtFile, fpDmpFile, DUMP_TYPE_DRIVER);
(void) emlxs_dump_parm_table(hba, fpTxtFile, fpDmpFile);
(void) emlxs_dump_cfg_regions(hba, fpTxtFile, fpDmpFile);
(void) emlxs_dump_file_terminate(hba, fpTxtFile, fpDmpFile, fpCeeFile);
(void) emlxs_dump_file_close(fpTxtFile, fpDmpFile, fpCeeFile);
(void) emlxs_menlo_reset(hba, MENLO_FW_OPERATIONAL);
(void) emlxs_set_hba_mode(hba, DDI_WARMDI);
mutex_exit(&EMLXS_DUMP_LOCK);
return (0);
}
extern void
emlxs_dump_drv_thread(emlxs_hba_t *hba,
void *arg1, void *arg2)
{
(void) emlxs_dump_drv_event(hba);
mutex_enter(&EMLXS_PORT_LOCK);
hba->flag &= ~FC_DUMP_ACTIVE;
mutex_exit(&EMLXS_PORT_LOCK);
return;
}
extern void
emlxs_dump_user_thread(emlxs_hba_t *hba,
void *arg1, void *arg2)
{
(void) emlxs_dump_user_event(hba);
mutex_enter(&EMLXS_PORT_LOCK);
hba->flag &= ~FC_DUMP_ACTIVE;
mutex_exit(&EMLXS_PORT_LOCK);
return;
}
extern void
emlxs_dump_temp_thread(emlxs_hba_t *hba,
void *arg1, void *arg2)
{
dump_temp_event_t *temp_event = (dump_temp_event_t *)arg1;
(void) emlxs_dump_temp_event(temp_event->hba, temp_event->type,
temp_event->temp);
kmem_free(temp_event, sizeof (dump_temp_event_t));
mutex_enter(&EMLXS_PORT_LOCK);
hba->flag &= ~FC_DUMP_ACTIVE;
mutex_exit(&EMLXS_PORT_LOCK);
return;
}
extern void
emlxs_dump(emlxs_hba_t *hba, uint32_t type, uint32_t temp_type, uint32_t temp)
{
emlxs_port_t *port = &PPORT;
dump_temp_event_t *temp_event = NULL;
mutex_enter(&EMLXS_PORT_LOCK);
if (!(hba->flag & FC_DUMP_SAFE)) {
mutex_exit(&EMLXS_PORT_LOCK);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"dump: Dump disabled.");
return;
}
if (hba->flag & FC_DUMP_ACTIVE) {
mutex_exit(&EMLXS_PORT_LOCK);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"dump: Dump already in progress.");
return;
}
switch (type) {
case EMLXS_DRV_DUMP:
case EMLXS_USER_DUMP:
break;
case EMLXS_TEMP_DUMP:
temp_event = (dump_temp_event_t *)kmem_alloc(
sizeof (dump_temp_event_t), KM_NOSLEEP);
if (temp_event == NULL) {
mutex_exit(&EMLXS_PORT_LOCK);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"dump: Unable to allocate temp object.");
return;
}
temp_event->hba = hba;
temp_event->type = temp_type;
temp_event->temp = temp;
break;
default:
mutex_exit(&EMLXS_PORT_LOCK);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
"dump: Error: Unknown dump type. (%x)",
type);
return;
}
hba->flag |= FC_DUMP_ACTIVE;
mutex_exit(&EMLXS_PORT_LOCK);
switch (type) {
case EMLXS_DRV_DUMP:
emlxs_thread_spawn(hba, emlxs_dump_drv_thread, NULL, NULL);
break;
case EMLXS_TEMP_DUMP:
emlxs_thread_spawn(hba, emlxs_dump_temp_thread,
(void *)temp_event, NULL);
break;
case EMLXS_USER_DUMP:
emlxs_thread_spawn(hba, emlxs_dump_user_thread, NULL, NULL);
break;
}
return;
}
extern void
emlxs_dump_wait(emlxs_hba_t *hba)
{
while ((hba->flag & FC_DUMP_ACTIVE)) {
BUSYWAIT_MS(1000);
}
}
#endif