4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at
9 * http://www.opensource.org/licenses/cddl1.txt.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2004-2012 Emulex. All rights reserved.
24 * Use is subject to license terms.
31 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
32 EMLXS_MSG_DEF(EMLXS_DUMP_C
);
34 /* ************************************************************************* */
35 /* Utility functions */
36 /* ************************************************************************* */
43 emlxs_port_t
*port
= &PPORT
;
46 menlo_cmd_t
*cmd_buf
= NULL
;
47 menlo_rsp_t
*rsp_buf
= NULL
;
50 if (hba
->model_info
.device_id
!= PCI_DEVICE_ID_HORNET
) {
51 return (DFC_INVALID_ADAPTER
);
54 cmd_size
= sizeof (menlo_set_cmd_t
);
55 cmd_buf
= (menlo_cmd_t
*)kmem_zalloc(cmd_size
, KM_SLEEP
);
58 rsp_buf
= (menlo_rsp_t
*)kmem_zalloc(rsp_size
, KM_SLEEP
);
60 cmd_buf
->code
= MENLO_CMD_SET_MODE
;
61 cmd_buf
->set
.value1
= mode
;
62 cmd_buf
->set
.value2
= 0;
64 #ifdef EMLXS_BIG_ENDIAN
65 emlxs_swap32_buffer((uint8_t *)cmd_buf
, cmd_size
);
66 #endif /* EMLXS_BIG_ENDIAN */
68 if (rval
= emlxs_send_menlo_cmd(hba
, (uint8_t *)cmd_buf
, cmd_size
,
69 (uint8_t *)rsp_buf
, &rsp_size
)) {
70 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
71 "menlo_set_mode: Unable to send command.");
74 #ifdef EMLXS_BIG_ENDIAN
75 emlxs_swap32_buffer((uint8_t *)rsp_buf
, rsp_size
);
76 #endif /* EMLXS_BIG_ENDIAN */
78 if (rsp_buf
->code
!= 0) {
79 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
80 "menlo_set_mode: Menlo command error. code=%d.\n",
89 kmem_free(cmd_buf
, sizeof (menlo_set_cmd_t
));
93 kmem_free(rsp_buf
, 4);
98 } /* emlxs_menlo_set_mode() */
106 emlxs_port_t
*port
= &PPORT
;
109 menlo_cmd_t
*cmd_buf
= NULL
;
110 menlo_rsp_t
*rsp_buf
= NULL
;
113 if (hba
->model_info
.device_id
!= PCI_DEVICE_ID_HORNET
) {
114 return (DFC_INVALID_ADAPTER
);
117 cmd_size
= sizeof (menlo_reset_cmd_t
);
118 cmd_buf
= (menlo_cmd_t
*)kmem_zalloc(cmd_size
, KM_SLEEP
);
121 rsp_buf
= (menlo_rsp_t
*)kmem_zalloc(rsp_size
, KM_SLEEP
);
123 cmd_buf
->code
= MENLO_CMD_RESET
;
124 cmd_buf
->reset
.firmware
= firmware
;
126 #ifdef EMLXS_BIG_ENDIAN
127 emlxs_swap32_buffer((uint8_t *)cmd_buf
, cmd_size
);
128 #endif /* EMLXS_BIG_ENDIAN */
130 if (rval
= emlxs_send_menlo_cmd(hba
, (uint8_t *)cmd_buf
, cmd_size
,
131 (uint8_t *)rsp_buf
, &rsp_size
)) {
132 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
133 "menlo_reset: Unable to send command.");
136 #ifdef EMLXS_BIG_ENDIAN
137 emlxs_swap32_buffer((uint8_t *)rsp_buf
, rsp_size
);
138 #endif /* EMLXS_BIG_ENDIAN */
140 if (rsp_buf
->code
!= 0) {
141 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
142 "menlo_reset: Menlo command error. code=%d.\n",
146 rval
= rsp_buf
->code
;
151 kmem_free(cmd_buf
, sizeof (menlo_reset_cmd_t
));
155 kmem_free(rsp_buf
, 4);
160 } /* emlxs_menlo_reset() */
166 menlo_get_config_rsp_t
*rsp_buf
,
169 emlxs_port_t
*port
= &PPORT
;
171 menlo_cmd_t
*cmd_buf
= NULL
;
174 if (hba
->model_info
.device_id
!= PCI_DEVICE_ID_HORNET
) {
175 return (DFC_INVALID_ADAPTER
);
178 cmd_size
= sizeof (menlo_get_cmd_t
);
179 cmd_buf
= (menlo_cmd_t
*)kmem_zalloc(cmd_size
, KM_SLEEP
);
181 rsp_size
= sizeof (menlo_get_config_rsp_t
);
183 cmd_buf
->code
= MENLO_CMD_GET_CONFIG
;
184 cmd_buf
->get
.context
= 0;
185 cmd_buf
->get
.length
= rsp_size
;
187 #ifdef EMLXS_BIG_ENDIAN
188 emlxs_swap32_buffer((uint8_t *)cmd_buf
, cmd_size
);
189 #endif /* EMLXS_BIG_ENDIAN */
191 if (rval
= emlxs_send_menlo_cmd(hba
, (uint8_t *)cmd_buf
, cmd_size
,
192 (uint8_t *)rsp_buf
, &rsp_size
)) {
193 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
194 "menlo_get_cfg: Unable to send command.");
197 #ifdef EMLXS_BIG_ENDIAN
198 emlxs_swap32_buffer((uint8_t *)rsp_buf
, rsp_size
);
199 #endif /* EMLXS_BIG_ENDIAN */
201 if (rsp_buf
->code
!= 0) {
202 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
203 "menlo_get_cfg: Menlo command error. code=%d.\n",
207 rval
= rsp_buf
->code
;
212 kmem_free(cmd_buf
, sizeof (menlo_get_cmd_t
));
217 } /* emlxs_menlo_get_cfg() */
222 emlxs_menlo_get_logcfg(
224 menlo_rsp_t
*rsp_buf
,
227 emlxs_port_t
*port
= &PPORT
;
229 menlo_cmd_t
*cmd_buf
= NULL
;
232 if (hba
->model_info
.device_id
!= PCI_DEVICE_ID_HORNET
) {
233 return (DFC_INVALID_ADAPTER
);
236 cmd_size
= sizeof (menlo_get_cmd_t
);
237 cmd_buf
= (menlo_cmd_t
*)kmem_zalloc(cmd_size
, KM_SLEEP
);
239 cmd_buf
->code
= MENLO_CMD_GET_LOG_CONFIG
;
240 cmd_buf
->get
.context
= 0;
241 cmd_buf
->get
.length
= rsp_size
;
243 #ifdef EMLXS_BIG_ENDIAN
244 emlxs_swap32_buffer((uint8_t *)cmd_buf
, cmd_size
);
245 #endif /* EMLXS_BIG_ENDIAN */
247 if (rval
= emlxs_send_menlo_cmd(hba
, (uint8_t *)cmd_buf
, cmd_size
,
248 (uint8_t *)rsp_buf
, &rsp_size
)) {
249 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
250 "menlo_get_logcfg: Unable to send command.");
253 #ifdef EMLXS_BIG_ENDIAN
254 emlxs_swap32_buffer((uint8_t *)rsp_buf
, rsp_size
);
255 #endif /* EMLXS_BIG_ENDIAN */
257 if (rsp_buf
->code
!= 0) {
258 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
259 "menlo_get_logcfg: Menlo command error. code=%d.\n",
263 rval
= rsp_buf
->code
;
268 kmem_free(cmd_buf
, sizeof (menlo_get_cmd_t
));
273 } /* emlxs_menlo_get_logcfg() */
280 menlo_rsp_t
*rsp_buf
,
283 emlxs_port_t
*port
= &PPORT
;
285 menlo_cmd_t
*cmd_buf
= NULL
;
288 if (hba
->model_info
.device_id
!= PCI_DEVICE_ID_HORNET
) {
289 return (DFC_INVALID_ADAPTER
);
292 cmd_size
= sizeof (menlo_get_cmd_t
);
293 cmd_buf
= (menlo_cmd_t
*)kmem_zalloc(cmd_size
, KM_SLEEP
);
295 cmd_buf
->code
= MENLO_CMD_GET_LOG_DATA
;
296 cmd_buf
->get
.context
= id
;
297 cmd_buf
->get
.length
= rsp_size
;
299 #ifdef EMLXS_BIG_ENDIAN
300 emlxs_swap32_buffer((uint8_t *)cmd_buf
, cmd_size
);
301 #endif /* EMLXS_BIG_ENDIAN */
303 if (rval
= emlxs_send_menlo_cmd(hba
, (uint8_t *)cmd_buf
, cmd_size
,
304 (uint8_t *)rsp_buf
, &rsp_size
)) {
305 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
306 "menlo_get_log: Unable to send command.");
309 #ifdef EMLXS_BIG_ENDIAN
310 emlxs_swap32_buffer((uint8_t *)rsp_buf
, rsp_size
);
311 #endif /* EMLXS_BIG_ENDIAN */
313 if (rsp_buf
->code
!= 0) {
314 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
315 "menlo_get_log: Menlo command error. code=%d.\n",
319 rval
= rsp_buf
->code
;
324 kmem_free(cmd_buf
, sizeof (menlo_get_cmd_t
));
329 } /* emlxs_menlo_get_log() */
333 emlxs_menlo_get_paniclog(
335 menlo_rsp_t
*rsp_buf
,
338 emlxs_port_t
*port
= &PPORT
;
340 menlo_cmd_t
*cmd_buf
= NULL
;
343 if (hba
->model_info
.device_id
!= PCI_DEVICE_ID_HORNET
) {
344 return (DFC_INVALID_ADAPTER
);
347 cmd_size
= sizeof (menlo_get_cmd_t
);
348 cmd_buf
= (menlo_cmd_t
*)kmem_zalloc(cmd_size
, KM_SLEEP
);
350 cmd_buf
->code
= MENLO_CMD_GET_PANIC_LOG
;
351 cmd_buf
->get
.context
= 0;
352 cmd_buf
->get
.length
= rsp_size
;
354 #ifdef EMLXS_BIG_ENDIAN
355 emlxs_swap32_buffer((uint8_t *)cmd_buf
, cmd_size
);
356 #endif /* EMLXS_BIG_ENDIAN */
358 if (rval
= emlxs_send_menlo_cmd(hba
, (uint8_t *)cmd_buf
, cmd_size
,
359 (uint8_t *)rsp_buf
, &rsp_size
)) {
360 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
361 "menlo_get_paniclog: Unable to send command.");
364 #ifdef EMLXS_BIG_ENDIAN
365 emlxs_swap32_buffer((uint8_t *)rsp_buf
, rsp_size
);
366 #endif /* EMLXS_BIG_ENDIAN */
368 if (rsp_buf
->code
!= 0) {
369 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_sli_detail_msg
,
370 "menlo_get_paniclog: Menlo command error. code=%d.\n",
374 rval
= rsp_buf
->code
;
379 kmem_free(cmd_buf
, sizeof (menlo_get_cmd_t
));
384 } /* emlxs_menlo_get_paniclog() */
395 offset
= (uint32_t)((uintptr_t)fp
->ptr
- (uintptr_t)fp
->buffer
);
397 if (offset
> fp
->size
) {
398 fp
->ptr
= fp
->buffer
+ fp
->size
;
403 } /* emlxs_fflush() */
412 offset
= (uint32_t)((uintptr_t)fp
->ptr
- (uintptr_t)fp
->buffer
);
416 } /* emlxs_ftell() */
426 offset
= (uint32_t)((uintptr_t)fp
->ptr
- (uintptr_t)fp
->buffer
);
428 if ((offset
+ 1) <= fp
->size
) {
434 } /* emlxs_fputc() */
447 length
= size
* nitems
;
451 (uint32_t)((uintptr_t)fp
->ptr
- (uintptr_t)fp
->buffer
);
453 if ((offset
+ length
) > fp
->size
) {
454 length
= fp
->size
- offset
;
458 bcopy(buffer
, fp
->ptr
, length
);
465 } /* emlxs_fwrite() */
471 const char *fmt
, ...)
477 va_start(valist
, fmt
);
478 (void) vsnprintf(va_str
, sizeof (va_str
), fmt
, valist
);
481 length
= emlxs_fwrite((uint8_t *)va_str
, strlen(va_str
), 1, fp
);
485 } /* emlxs_fprintf() */
488 extern emlxs_file_t
*
497 fp
= &hba
->dump_txtfile
;
498 fp
->size
= EMLXS_TXT_FILE_SIZE
;
502 fp
= &hba
->dump_dmpfile
;
503 fp
->size
= EMLXS_DMP_FILE_SIZE
;
507 fp
= &hba
->dump_ceefile
;
508 fp
->size
= EMLXS_CEE_FILE_SIZE
;
515 /* Make sure it is word aligned */
516 fp
->size
&= 0xFFFFFFFC;
519 fp
->buffer
= kmem_zalloc(fp
->size
, KM_SLEEP
);
522 bzero(fp
->buffer
, fp
->size
);
525 fp
->ptr
= fp
->buffer
;
529 } /* emlxs_fopen() */
542 offset
= (uint32_t)((uintptr_t)fp
->ptr
- (uintptr_t)fp
->buffer
);
567 } /* emlxs_fclose() */
578 if (fp
->buffer
&& fp
->size
) {
579 kmem_free(fp
->buffer
, fp
->size
);
588 } /* emlxs_fdelete() */
591 /* This builds a single core buffer for the IOCTL interface */
598 emlxs_port_t
*port
= &PPORT
;
605 emlxs_file_t
*fp_txt
;
606 emlxs_file_t
*fp_dmp
;
607 emlxs_file_t
*fp_cee
;
612 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
613 "get_dump: Buffer length = 0");
617 fp_txt
= &hba
->dump_txtfile
;
618 fp_dmp
= &hba
->dump_dmpfile
;
619 fp_cee
= &hba
->dump_ceefile
;
621 size_txt
= emlxs_ftell(fp_txt
);
622 size_dmp
= emlxs_ftell(fp_dmp
);
623 size_cee
= emlxs_ftell(fp_cee
);
629 size
+= size_txt
+ 8;
633 size
+= size_dmp
+ 8;
637 size
+= size_cee
+ 8;
648 bzero(buffer
, *buflen
);
650 if (*buflen
< size
) {
651 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
652 "get_dump: Buffer length too small. %d < %d",
659 wptr
= (uint32_t *)buffer
;
664 wptr
[i
++] = EMLXS_TXT_FILE_ID
;
665 wptr
[i
++] = size_txt
;
669 wptr
[i
++] = EMLXS_DMP_FILE_ID
;
670 wptr
[i
++] = size_dmp
;
674 if ((hba
->model_info
.chip
== EMLXS_BE2_CHIP
) ||
675 (hba
->model_info
.chip
== EMLXS_BE3_CHIP
)) {
676 wptr
[i
++] = EMLXS_FAT_FILE_ID
;
678 wptr
[i
++] = EMLXS_CEE_FILE_ID
;
681 wptr
[i
++] = size_cee
;
684 bptr
= (uint8_t *)&wptr
[i
];
687 bcopy(fp_txt
->buffer
, bptr
, size_txt
);
692 bcopy(fp_dmp
->buffer
, bptr
, size_dmp
);
697 bcopy(fp_cee
->buffer
, bptr
, size_cee
);
705 /* printf("Done. buflen=%d \n", *buflen); */
709 } /* emlxs_get_dump() */
713 emlxs_read_cfg_region(
717 uint32_t *pRetByteCount
,
720 emlxs_port_t
*port
= &PPORT
;
722 uint32_t ByteCountRem
; /* remaining portion of original byte count */
723 uint32_t ByteCountReq
; /* requested byte count for a particular dump */
724 uint32_t CopyCount
; /* bytes to copy after each successful dump */
725 uint32_t Offset
; /* Offset into Config Region, for each dump */
726 uint8_t *pLocalBuf
; /* ptr to buffer to receive each dump */
733 (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
), KM_SLEEP
);
735 pLocalBuf
= pBuffer
; /* init local pointer to caller's buffer */
736 Offset
= 0; /* start at offset 0 */
737 *pRetByteCount
= 0; /* init returned byte count */
740 for (ByteCountRem
= ByteCount
; ByteCountRem
> 0;
741 ByteCountRem
-= CopyCount
) {
743 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
744 MAILBOX4
*mb
= (MAILBOX4
*)mbq
;
747 (ByteCountRem
< hba
->sli
.sli4
.dump_region
.size
) ?
748 ByteCountRem
: hba
->sli
.sli4
.dump_region
.size
;
750 /* Clear the local dump_region */
751 bzero(hba
->sli
.sli4
.dump_region
.virt
,
752 hba
->sli
.sli4
.dump_region
.size
);
754 bzero((void *) mb
, MAILBOX_CMD_SLI4_BSIZE
);
756 mb
->mbxCommand
= MBX_DUMP_MEMORY
;
757 mb
->un
.varDmp4
.type
= DMP_NV_PARAMS
;
758 mb
->un
.varDmp4
.entry_index
= Offset
;
759 mb
->un
.varDmp4
.region_id
= Identifier
;
761 mb
->un
.varDmp4
.available_cnt
= ByteCountReq
;
762 mb
->un
.varDmp4
.addrHigh
=
763 PADDR_HI(hba
->sli
.sli4
.dump_region
.phys
);
764 mb
->un
.varDmp4
.addrLow
=
765 PADDR_LO(hba
->sli
.sli4
.dump_region
.phys
);
766 mb
->un
.varDmp4
.rsp_cnt
= 0;
768 mb
->mbxOwner
= OWN_HOST
;
769 mbq
->mbox_cmpl
= NULL
;
771 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
773 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
774 "Unable to read config region. id=%x "\
775 "offset=%x status=%x",
776 Identifier
, Offset
, mb
->mbxStatus
);
778 kmem_free(mbq
, sizeof (MAILBOXQ
));
782 CopyCount
= mb
->un
.varDmp4
.rsp_cnt
;
784 /* if no more data returned */
785 if (CopyCount
== 0) {
789 if (CopyCount
> ByteCountReq
) {
790 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
791 "read_cfg_region: " \
792 "Byte count too big. %d > %d\n",
793 CopyCount
, ByteCountReq
);
795 CopyCount
= ByteCountReq
;
798 bcopy((uint8_t *)hba
->sli
.sli4
.dump_region
.virt
,
799 pLocalBuf
, CopyCount
);
802 MAILBOX
*mb
= (MAILBOX
*)mbq
;
805 (ByteCountRem
< DUMP_BC_MAX
) ? ByteCountRem
:
808 bzero((void *)mb
, MAILBOX_CMD_BSIZE
);
810 mb
->mbxCommand
= MBX_DUMP_MEMORY
;
811 mb
->un
.varDmp
.type
= DMP_NV_PARAMS
;
812 mb
->un
.varDmp
.cv
= 1;
813 mb
->un
.varDmp
.region_id
= Identifier
;
814 mb
->un
.varDmp
.entry_index
= Offset
;
815 mb
->un
.varDmp
.word_cnt
= ByteCountReq
/ 4;
816 mb
->mbxOwner
= OWN_HOST
;
817 mbq
->mbox_cmpl
= NULL
;
819 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
821 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
822 "Unable to read config region. id=%x "\
823 "offset=%x status=%x",
824 Identifier
, Offset
, mb
->mbxStatus
);
826 kmem_free(mbq
, sizeof (MAILBOXQ
));
830 /* Note: for Type 2/3 Dumps, varDmp.word_cnt is */
831 /* actually a byte count. */
832 CopyCount
= mb
->un
.varDmp
.word_cnt
;
834 /* if no more data returned */
835 if (CopyCount
== 0) {
839 if (CopyCount
> ByteCountReq
) {
840 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
841 "read_cfg_region: " \
842 "Byte count too big. %d > %d\n",
843 CopyCount
, ByteCountReq
);
845 CopyCount
= ByteCountReq
;
848 bcopy((uint8_t *)&mb
->un
.varDmp
.resp_offset
, pLocalBuf
,
852 pLocalBuf
+= CopyCount
;
854 *pRetByteCount
+= CopyCount
;
859 } /* emlxs_read_cfg_region() */
863 /* ************************************************************************* */
864 /* ************************************************************************* */
865 /* Dump Generators, Low-Level */
866 /* ************************************************************************* */
867 /* ************************************************************************* */
870 emlxs_dump_string_txtfile(
871 emlxs_file_t
*fpTxtFile
,
882 if (pSidLegend
&& pLidLegend
) {
883 (void) emlxs_fprintf(fpTxtFile
, "%s: %s\n", pSidLegend
,
887 emlxs_fputc(' ', fpTxtFile
);
890 (void) emlxs_fwrite((uint8_t *)pString
, strlen(pString
), 1,
894 emlxs_fputc('\n', fpTxtFile
);
895 emlxs_fputc('\n', fpTxtFile
);
899 emlxs_fputc(' ', fpTxtFile
);
901 (void) emlxs_fwrite((uint8_t *)pString
, strlen(pString
), 1,
905 emlxs_fflush(fpTxtFile
);
909 } /* emlxs_dump_string_txtfile() */
913 emlxs_dump_word_txtfile(
914 emlxs_file_t
*fpTxtFile
,
929 /* Write Legend String to the TXT File */
930 (void) emlxs_fprintf(fpTxtFile
, "%s: %s\n", pSidLegend
, pLidLegend
);
932 /* Write the buffer to the TXT File */
935 for (j
= 0; j
< WordCount
; j
++) {
939 if ((j
& 0x03) == 0) {
940 (void) snprintf(buf1
, sizeof (buf1
), "\n%04x:", j
* 4);
941 (void) strlcat(buf2
, buf1
, sizeof (buf2
));
944 (void) snprintf(buf1
, sizeof (buf1
), " %08x", ptr
[j
]);
945 (void) strlcat(buf2
, buf1
, sizeof (buf2
));
946 (void) emlxs_fwrite((uint8_t *)buf2
, strlen(buf2
), 1,
950 emlxs_fputc('\n', fpTxtFile
);
951 emlxs_fputc('\n', fpTxtFile
);
952 emlxs_fflush(fpTxtFile
);
955 } /* emlxs_dump_word_txtfile() */
961 emlxs_dump_string_dmpfile(
962 emlxs_file_t
*fpDmpFile
,
976 /* Write Legend SID to the DMP File */
977 emlxs_fputc(SID_LEGEND
, fpDmpFile
);
979 /* Write Argument SID to the DMP File */
980 emlxs_fputc(sid
, fpDmpFile
);
982 /* Write Legend String to the DMP File, including a Null Byte */
983 (void) emlxs_fprintf(fpDmpFile
, "%s: %s", pSidLegend
, pLidLegend
);
984 emlxs_fputc(0, fpDmpFile
);
986 /* Write Argument SID to the DMP File */
987 emlxs_fputc(sid
, fpDmpFile
);
989 /* Write Buffer Length to the DMP File */
990 length
= (uint32_t)(strlen(pString
) + 1);
991 #ifdef EMLXS_LITTLE_ENDIAN
992 byte
= (uint8_t)(length
& 0x0000FF);
993 emlxs_fputc(byte
, fpDmpFile
);
994 byte
= (uint8_t)((length
& 0x00FF00) >> 8);
995 emlxs_fputc(byte
, fpDmpFile
);
996 byte
= (uint8_t)((length
& 0xFF0000) >> 16);
997 emlxs_fputc(byte
, fpDmpFile
);
998 #endif /* EMLXS_LITTLE_ENDIAN */
1000 #ifdef EMLXS_BIG_ENDIAN
1001 byte
= (uint8_t)((length
& 0xFF0000) >> 16);
1002 emlxs_fputc(byte
, fpDmpFile
);
1003 byte
= (uint8_t)((length
& 0x00FF00) >> 8);
1004 emlxs_fputc(byte
, fpDmpFile
);
1005 byte
= (uint8_t)(length
& 0x0000FF);
1006 emlxs_fputc(byte
, fpDmpFile
);
1007 #endif /* EMLXS_BIG_ENDIAN */
1009 /* Write Argument String to the DMP File, including a Null Byte */
1010 (void) emlxs_fwrite((uint8_t *)pString
, strlen(pString
), 1, fpDmpFile
);
1011 emlxs_fputc(0, fpDmpFile
);
1013 emlxs_fflush(fpDmpFile
);
1015 #if CC_DUMP_ENABLE_PAD
1016 /* check file size.. pad as necessary */
1017 pos
= emlxs_ftell(fpDmpFile
);
1018 switch (pos
& 0x03) {
1022 emlxs_fputc(0, fpDmpFile
);
1023 emlxs_fputc(0, fpDmpFile
);
1024 emlxs_fputc(0, fpDmpFile
);
1027 emlxs_fputc(0, fpDmpFile
);
1028 emlxs_fputc(0, fpDmpFile
);
1031 emlxs_fputc(0, fpDmpFile
);
1034 emlxs_fflush(fpDmpFile
);
1039 } /* emlxs_dump_string_dmpfile() */
1042 /* ************************************************************************** */
1043 /* emlxs_dump_word_dmpfile */
1044 /* If little endian, just write the buffer normally. */
1045 /* However, if Big Endian... Consider the following: */
1046 /* Automatic Dump, initiated by driver, Port Offline (FW WarmStart Mode), */
1047 /* Mailbox in SLIM. */
1048 /* On-Demand Dump, initiated by utility, Port Online (FW Normal Mode), */
1049 /* Mailbox in Host Memory. */
1050 /* We use the same IOCTL to get the DUMP Data, for both cases. */
1051 /* However, it normalizes the data before delivering it to us. */
1052 /* In the Dump File, we must always write the data in native mode. */
1053 /* So, if Big Endian, On-demand Dump, we must swap the words. */
1054 /* ************************************************************************* */
1057 emlxs_dump_word_dmpfile(
1058 emlxs_file_t
*fpDmpFile
,
1070 wptr
= (uint32_t *)pBuffer
;
1071 for (i
= 0; i
< bufferLen
/ 4; i
++, wptr
++) {
1075 *wptr
= BE_SWAP32(w1
);
1078 (void) emlxs_fwrite((uint8_t *)wptr
, 4, 1, fpDmpFile
);
1081 emlxs_fflush(fpDmpFile
);
1085 } /* emlxs_dump_word_dmpfile() */
1089 emlxs_dump_port_block(
1090 emlxs_file_t
*fpDmpFile
,
1093 DUMP_TABLE_ENTRY entry
,
1104 /* Write Argument SID to the DMP File */
1105 b
= (uint8_t)entry
.un
.PortBlock
.un
.s
.sid
;
1106 emlxs_fputc(b
, fpDmpFile
);
1108 #ifdef EMLXS_LITTLE_ENDIAN
1109 /* Write Buffer Length to the DMP File */
1110 w
= entry
.un
.PortBlock
.un
.s
.bc
;
1111 b
= (uint8_t)(w
& 0x000000FF);
1112 emlxs_fputc(b
, fpDmpFile
);
1113 b
= (uint8_t)((w
& 0x0000FF00) >> 8);
1114 emlxs_fputc(b
, fpDmpFile
);
1115 b
= (uint8_t)((w
& 0x00FF0000) >> 16);
1116 emlxs_fputc(b
, fpDmpFile
);
1118 /* Write address to the DMP File */
1119 w
= entry
.un
.PortBlock
.un
.s
.addr
;
1120 b
= (uint8_t)(w
& 0x000000FF);
1121 emlxs_fputc(b
, fpDmpFile
);
1122 b
= (uint8_t)((w
& 0x0000FF00) >> 8);
1123 emlxs_fputc(b
, fpDmpFile
);
1124 b
= (uint8_t)((w
& 0x00FF0000) >> 16);
1125 emlxs_fputc(b
, fpDmpFile
);
1126 b
= (uint8_t)((w
& 0xFF000000) >> 24);
1127 emlxs_fputc(b
, fpDmpFile
);
1128 #endif /* EMLXS_LITTLE_ENDIAN */
1130 #ifdef EMLXS_BIG_ENDIAN
1131 /* Write Buffer Length to the DMP File */
1132 w
= entry
.un
.PortBlock
.un
.s
.bc
;
1133 b
= (uint8_t)((w
& 0x00FF0000) >> 16);
1134 emlxs_fputc(b
, fpDmpFile
);
1135 b
= (uint8_t)((w
& 0x0000FF00) >> 8);
1136 emlxs_fputc(b
, fpDmpFile
);
1137 b
= (uint8_t)(w
& 0x000000FF);
1138 emlxs_fputc(b
, fpDmpFile
);
1140 /* Write address to the DMP File */
1141 w
= entry
.un
.PortBlock
.un
.s
.addr
;
1142 b
= (uint8_t)((w
& 0xFF000000) >> 24);
1143 emlxs_fputc(b
, fpDmpFile
);
1144 b
= (uint8_t)((w
& 0x00FF0000) >> 16);
1145 emlxs_fputc(b
, fpDmpFile
);
1146 b
= (uint8_t)((w
& 0x0000FF00) >> 8);
1147 emlxs_fputc(b
, fpDmpFile
);
1148 b
= (uint8_t)(w
& 0x000000FF);
1149 emlxs_fputc(b
, fpDmpFile
);
1150 #endif /* EMLXS_BIG_ENDIAN */
1153 emlxs_dump_word_dmpfile(fpDmpFile
, pBuffer
, bufferLen
, fSwap
);
1155 emlxs_fflush(fpDmpFile
);
1159 } /* emlxs_dump_port_block() */
1163 emlxs_dump_port_struct(
1164 emlxs_file_t
*fpDmpFile
,
1167 DUMP_TABLE_ENTRY entry
,
1178 /* Write Argument SID to the DMP File */
1179 b
= (uint8_t)entry
.un
.PortStruct
.un
.s
.sid
;
1180 emlxs_fputc(b
, fpDmpFile
);
1182 /* Write Element Length to the DMP File */
1183 b
= (uint8_t)entry
.un
.PortStruct
.un
.s
.length
;
1184 emlxs_fputc(b
, fpDmpFile
);
1186 #ifdef EMLXS_LITTLE_ENDIAN
1187 /* Write Element Count to the DMP File */
1188 w
= entry
.un
.PortStruct
.un
.s
.count
;
1189 b
= (uint8_t)(w
& 0x000000FF);
1190 emlxs_fputc(b
, fpDmpFile
);
1191 b
= (uint8_t)((w
& 0x0000FF00) >> 8);
1192 emlxs_fputc(b
, fpDmpFile
);
1194 /* Write Address to the DMP File */
1195 w
= entry
.un
.PortStruct
.un
.s
.addr
;
1196 b
= (uint8_t)(w
& 0x000000FF);
1197 emlxs_fputc(b
, fpDmpFile
);
1198 b
= (uint8_t)((w
& 0x0000FF00) >> 8);
1199 emlxs_fputc(b
, fpDmpFile
);
1200 b
= (uint8_t)((w
& 0x00FF0000) >> 16);
1201 emlxs_fputc(b
, fpDmpFile
);
1202 b
= (uint8_t)((w
& 0xFF000000) >> 24);
1203 emlxs_fputc(b
, fpDmpFile
);
1204 #endif /* EMLXS_LITTLE_ENDIAN */
1206 #ifdef EMLXS_BIG_ENDIAN
1207 /* Write Element Count to the DMP File */
1208 w
= entry
.un
.PortStruct
.un
.s
.count
;
1209 b
= (uint8_t)((w
& 0x0000FF00) >> 8);
1210 emlxs_fputc(b
, fpDmpFile
);
1211 b
= (uint8_t)(w
& 0x000000FF);
1212 emlxs_fputc(b
, fpDmpFile
);
1214 /* Write Address to the DMP File */
1215 w
= entry
.un
.PortStruct
.un
.s
.addr
;
1216 b
= (uint8_t)((w
& 0xFF000000) >> 24);
1217 emlxs_fputc(b
, fpDmpFile
);
1218 b
= (uint8_t)((w
& 0x00FF0000) >> 16);
1219 emlxs_fputc(b
, fpDmpFile
);
1220 b
= (uint8_t)((w
& 0x0000FF00) >> 8);
1221 emlxs_fputc(b
, fpDmpFile
);
1222 b
= (uint8_t)(w
& 0x000000FF);
1223 emlxs_fputc(b
, fpDmpFile
);
1224 #endif /* EMLXS_BIG_ENDIAN */
1227 emlxs_dump_word_dmpfile(fpDmpFile
, pBuffer
, bufferLen
, fSwap
);
1229 emlxs_fflush(fpDmpFile
);
1233 } /* emlxs_dump_port_struct() */
1237 emlxs_dump_host_block(
1238 emlxs_file_t
*fpDmpFile
,
1254 /* Write Legend SID to the DMP File */
1255 emlxs_fputc(SID_LEGEND
, fpDmpFile
);
1257 /* Write Argument SID to the DMP File */
1258 emlxs_fputc(sid
, fpDmpFile
);
1260 /* Write Legend String to the DMP File, including a Null Byte */
1261 (void) emlxs_fprintf(fpDmpFile
, "%s: %s", pSidLegend
, pLidLegend
);
1262 emlxs_fputc(0, fpDmpFile
);
1264 /* Write Argument SID to the DMP File */
1265 emlxs_fputc(sid
, fpDmpFile
);
1267 /* Write Buffer Length to the DMP File */
1269 #ifdef EMLXS_LITTLE_ENDIAN
1270 byte
= (uint8_t)(length
& 0x0000FF);
1271 emlxs_fputc(byte
, fpDmpFile
);
1272 byte
= (uint8_t)((length
& 0x00FF00) >> 8);
1273 emlxs_fputc(byte
, fpDmpFile
);
1274 byte
= (uint8_t)((length
& 0xFF0000) >> 16);
1275 emlxs_fputc(byte
, fpDmpFile
);
1276 #endif /* EMLXS_LITTLE_ENDIAN */
1278 #ifdef EMLXS_BIG_ENDIAN
1279 byte
= (uint8_t)((length
& 0xFF0000) >> 16);
1280 emlxs_fputc(byte
, fpDmpFile
);
1281 byte
= (uint8_t)((length
& 0x00FF00) >> 8);
1282 emlxs_fputc(byte
, fpDmpFile
);
1283 byte
= (uint8_t)(length
& 0x0000FF);
1284 emlxs_fputc(byte
, fpDmpFile
);
1285 #endif /* EMLXS_BIG_ENDIAN */
1288 emlxs_dump_word_dmpfile(fpDmpFile
, pBuffer
, bufferLen
, fSwap
);
1290 emlxs_fflush(fpDmpFile
);
1294 } /* emlxs_dump_host_block() */
1298 emlxs_dump_host_struct(
1299 emlxs_file_t
*fpDmpFile
,
1302 uint32_t elementLength
,
1303 uint32_t elementCount
,
1317 /* Write Legend SID to the DMP File */
1318 emlxs_fputc(SID_LEGEND
, fpDmpFile
);
1320 /* Write Argument SID to the DMP File */
1321 emlxs_fputc(sid
, fpDmpFile
);
1323 /* Write Legend String to the DMP File, including a Null Byte */
1324 (void) emlxs_fprintf(fpDmpFile
, "%s: %s", pSidLegend
, pLidLegend
);
1325 emlxs_fputc(0, fpDmpFile
);
1327 /* Write Argument SID to the DMP File */
1328 emlxs_fputc(sid
, fpDmpFile
);
1330 /* Write Element Length to the DMP File */
1331 b
= (uint8_t)elementLength
;
1332 emlxs_fputc(b
, fpDmpFile
);
1334 /* Write Element Count to the DMP File */
1336 #ifdef EMLXS_LITTLE_ENDIAN
1337 b
= (uint8_t)(w
& 0x000000FF);
1338 emlxs_fputc(b
, fpDmpFile
);
1339 b
= (uint8_t)((w
& 0x0000FF00) >> 8);
1340 emlxs_fputc(b
, fpDmpFile
);
1341 #endif /* EMLXS_LITTLE_ENDIAN */
1343 #ifdef EMLXS_BIG_ENDIAN
1344 b
= (uint8_t)((w
& 0x0000FF00) >> 8);
1345 emlxs_fputc(b
, fpDmpFile
);
1346 b
= (uint8_t)(w
& 0x000000FF);
1347 emlxs_fputc(b
, fpDmpFile
);
1348 #endif /* EMLXS_BIG_ENDIAN */
1351 emlxs_dump_word_dmpfile(fpDmpFile
, pBuffer
, bufferLen
, fSwap
);
1353 emlxs_fflush(fpDmpFile
);
1357 } /* emlxs_dump_host_struct() */
1360 /* ************************************************************************* */
1361 /* ************************************************************************* */
1362 /* Dump Generators, Mid-Level */
1363 /* ************************************************************************* */
1364 /* ************************************************************************* */
1367 emlxs_dump_parm_table(
1369 emlxs_file_t
*fpTxtFile
,
1370 emlxs_file_t
*fpDmpFile
)
1372 emlxs_config_t
*cfg
= &CFG
;
1376 /* vars used to build the Dump String */
1380 buf1
= kmem_zalloc(8192, KM_SLEEP
);
1381 buf2
= kmem_zalloc(8192, KM_SLEEP
);
1383 /* Driver Parameters Heading */
1384 (void) snprintf(buf1
, 8192,
1386 "High Def Cur Exp Dyn");
1388 /* Build the buffer containing all the Driver Params */
1389 for (i
= 0; i
< NUM_CFG_PARAM
; i
++) {
1390 (void) snprintf(buf2
, 8192,
1391 "\n %02x: %25s %8x %8x %8x %8x %4x %4x", i
,
1392 cfg
[i
].string
, cfg
[i
].low
, cfg
[i
].hi
, cfg
[i
].def
,
1393 cfg
[i
].current
, (cfg
[i
].flags
& PARM_HIDDEN
) ? 0 : 1,
1394 (cfg
[i
].flags
& PARM_DYNAMIC
) ? 1 : 0);
1396 (void) strlcat(buf1
, buf2
, 8192);
1400 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_DP_TABLE
,
1404 emlxs_dump_string_dmpfile(fpDmpFile
, buf1
, SID_DP_TABLE
,
1405 LEGEND_DP_TABLE
, LEGEND_NULL
);
1407 kmem_free(buf1
, 8192);
1408 kmem_free(buf2
, 8192);
1412 } /* emlxs_dump_parm_table() */
1418 emlxs_file_t
*fpTxtFile
,
1419 emlxs_file_t
*fpDmpFile
)
1421 emlxs_vpd_t
*vpd
= &VPD
;
1424 /* vars used to build the Dump String */
1428 /* Write the Model into the buffer */
1429 (void) snprintf(buf2
, sizeof (buf2
), "%s", vpd
->model
);
1430 (void) strlcpy(buf1
, "Model: ", sizeof (buf1
));
1431 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
1433 /* Write the Model Description into the buffer */
1434 (void) snprintf(buf2
, sizeof (buf2
), "%s", vpd
->model_desc
);
1435 (void) strlcat(buf1
, "\n Description: ", sizeof (buf1
));
1436 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
1439 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_HBA_INFO
,
1440 LEGEND_HBA_MODEL
, 0);
1443 emlxs_dump_string_dmpfile(fpDmpFile
, buf1
, SID_HBA_INFO
,
1444 LEGEND_HBA_INFO
, LEGEND_HBA_MODEL
);
1448 } /* emlxs_dump_model() */
1454 emlxs_file_t
*fpTxtFile
,
1455 emlxs_file_t
*fpDmpFile
)
1459 /* vars used to build the Dump String */
1465 /* Write the WWPN into the buffer */
1466 (void) strlcpy(buf1
, "Port WWN: ", sizeof (buf1
));
1467 p
= (uint8_t *)&hba
->wwpn
;
1468 for (i
= 0; i
< 7; i
++) {
1469 (void) snprintf(buf2
, sizeof (buf2
), "%02x:", *p
++);
1470 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
1472 (void) snprintf(buf2
, sizeof (buf2
), "%02x", *p
++);
1473 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
1475 /* Write the WWNN into the buffer */
1476 (void) strlcat(buf1
, "\n Node WWN: ", sizeof (buf1
));
1477 p
= (uint8_t *)&hba
->wwnn
;
1478 for (i
= 0; i
< 7; i
++) {
1479 (void) snprintf(buf2
, sizeof (buf2
), "%02x:", *p
++);
1480 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
1482 (void) snprintf(buf2
, sizeof (buf2
), "%02x", *p
++);
1483 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
1486 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_HBA_INFO
,
1490 emlxs_dump_string_dmpfile(fpDmpFile
, buf1
, SID_HBA_INFO
,
1491 LEGEND_HBA_INFO
, LEGEND_HBA_WWN
);
1495 } /* emlxs_dump_wwn() */
1499 emlxs_dump_serial_number(
1501 emlxs_file_t
*fpTxtFile
,
1502 emlxs_file_t
*fpDmpFile
)
1504 emlxs_vpd_t
*vpd
= &VPD
;
1507 /* vars used to build the Dump String */
1511 /* Write the Serial Number into the buffer */
1512 (void) snprintf(buf2
, sizeof (buf2
), "%s", vpd
->serial_num
);
1513 (void) strlcpy(buf1
, LEGEND_HBA_SN
, sizeof (buf1
));
1514 (void) strlcat(buf1
, ": ", sizeof (buf1
));
1515 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
1518 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_HBA_INFO
,
1522 emlxs_dump_string_dmpfile(fpDmpFile
, buf1
, SID_HBA_INFO
,
1523 LEGEND_HBA_INFO
, LEGEND_HBA_SN
);
1527 } /* emlxs_dump_serial_number() */
1531 emlxs_dump_fw_version(
1533 emlxs_file_t
*fpTxtFile
,
1534 emlxs_file_t
*fpDmpFile
)
1536 emlxs_vpd_t
*vpd
= &VPD
;
1547 buf1
= kmem_zalloc(buf1_size
, KM_SLEEP
);
1548 buf2
= kmem_zalloc(buf2_size
, KM_SLEEP
);
1550 /* Write the Firmware Version into the buffer */
1551 (void) snprintf(buf2
, buf2_size
, "%s", vpd
->fw_version
);
1552 (void) strlcpy(buf1
, LEGEND_HBA_FW_VERSION
, buf1_size
);
1553 (void) strlcat(buf1
, ": ", buf1_size
);
1554 (void) strlcat(buf1
, buf2
, buf1_size
);
1556 /* Write the Operational FW Version into the buffer */
1557 (void) snprintf(buf2
, buf2_size
, "%s", vpd
->opFwName
);
1558 (void) strlcat(buf1
, "\n ", buf1_size
);
1559 (void) strlcat(buf1
, LEGEND_HBA_FW_OPVERSION
, buf1_size
);
1560 (void) strlcat(buf1
, ": ", buf1_size
);
1561 (void) strlcat(buf1
, buf2
, buf1_size
);
1563 /* Write the SLI-1 FW Version into the buffer */
1564 (void) snprintf(buf2
, buf2_size
, "%s", vpd
->sli1FwName
);
1565 (void) strlcat(buf1
, "\n ", buf1_size
);
1566 (void) strlcat(buf1
, LEGEND_HBA_FW_SLI1VERSION
, buf1_size
);
1567 (void) strlcat(buf1
, ": ", buf1_size
);
1568 (void) strlcat(buf1
, buf2
, buf1_size
);
1570 /* Write the SLI-2 FW Version into the buffer */
1571 (void) snprintf(buf2
, buf2_size
, "%s", vpd
->sli2FwName
);
1572 (void) strlcat(buf1
, "\n ", buf1_size
);
1573 (void) strlcat(buf1
, LEGEND_HBA_FW_SLI2VERSION
, buf1_size
);
1574 (void) strlcat(buf1
, ": ", buf1_size
);
1575 (void) strlcat(buf1
, buf2
, buf1_size
);
1577 /* Write the SLI-3 FW Version into the buffer */
1578 (void) snprintf(buf2
, buf2_size
, "%s", vpd
->sli3FwName
);
1579 (void) strlcat(buf1
, "\n ", buf1_size
);
1580 (void) strlcat(buf1
, LEGEND_HBA_FW_SLI3VERSION
, buf1_size
);
1581 (void) strlcat(buf1
, ": ", buf1_size
);
1582 (void) strlcat(buf1
, buf2
, buf1_size
);
1584 /* Write the Kernel FW Version into the buffer */
1585 (void) snprintf(buf2
, buf2_size
, "%s", vpd
->postKernName
);
1586 (void) strlcat(buf1
, "\n ", buf1_size
);
1587 (void) strlcat(buf1
, LEGEND_HBA_FW_KERNELVERSION
, buf1_size
);
1588 (void) strlcat(buf1
, ": ", buf1_size
);
1589 (void) strlcat(buf1
, buf2
, buf1_size
);
1592 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_HBA_INFO
,
1593 LEGEND_HBA_FW_VERSION
, 0);
1596 emlxs_dump_string_dmpfile(fpDmpFile
, buf1
, SID_HBA_INFO
,
1597 LEGEND_HBA_INFO
, LEGEND_HBA_FW_VERSION
);
1599 kmem_free(buf1
, buf1_size
);
1600 kmem_free(buf2
, buf2_size
);
1604 } /* emlxs_dump_fw_version() */
1608 emlxs_dump_boot_version(
1610 emlxs_file_t
*fpTxtFile
,
1611 emlxs_file_t
*fpDmpFile
)
1613 emlxs_vpd_t
*vpd
= &VPD
;
1625 buf1
= kmem_zalloc(buf1_size
, KM_SLEEP
);
1626 buf2
= kmem_zalloc(buf2_size
, KM_SLEEP
);
1629 if (strcmp(vpd
->fcode_version
, "none") == 0)
1631 if (strcmp(vpd
->boot_version
, "none") == 0)
1632 #endif /* EMLXS_SPARC */
1634 state
= 2; /* BOOT_BIOS_NOT_PRESENT */
1636 state
= emlxs_boot_code_state(hba
);
1639 /* Write the Boot Bios State into the buffer */
1640 (void) snprintf(buf2
, buf2_size
, " %d", state
);
1641 (void) strlcpy(buf1
, LEGEND_HBA_BB_STATE
, buf1_size
);
1642 (void) strlcat(buf1
, ": ", buf1_size
);
1643 (void) strlcat(buf1
, buf2
, buf1_size
);
1645 /* Write the Boot Bios Version into the buffer */
1647 (void) snprintf(buf2
, buf2_size
, "%s", "unknown");
1650 (void) snprintf(buf2
, buf2_size
, "%s (FCode)",
1651 vpd
->fcode_version
);
1653 (void) snprintf(buf2
, buf2_size
, "%s", vpd
->boot_version
);
1654 #endif /* EMLXS_SPARC */
1657 (void) strlcat(buf1
, "\n ", buf1_size
);
1658 (void) strlcat(buf1
, LEGEND_HBA_BB_VERSION
, buf1_size
);
1659 (void) strlcat(buf1
, ": ", buf1_size
);
1660 (void) strlcat(buf1
, buf2
, buf1_size
);
1663 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_HBA_INFO
,
1664 LEGEND_HBA_BB_VERSION
, 0);
1667 emlxs_dump_string_dmpfile(fpDmpFile
, buf1
, SID_HBA_INFO
,
1668 LEGEND_HBA_INFO
, LEGEND_HBA_BB_VERSION
);
1670 kmem_free(buf1
, buf1_size
);
1671 kmem_free(buf2
, buf2_size
);
1675 } /* emlxs_dump_boot_version() */
1680 emlxs_dump_cfg_region4_decoded(
1682 emlxs_file_t
*fpTxtFile
,
1684 DUMP_WAKE_UP_PARAMS
*pBuffer
,
1688 char *buf1
; /* text buffer */
1689 char *buf2
; /* text buffer */
1696 buf1
= kmem_zalloc(buf1_size
, KM_SLEEP
);
1697 buf2
= kmem_zalloc(buf2_size
, KM_SLEEP
);
1699 /* Write the Initial ID into the buffer */
1700 (void) snprintf(buf2
, buf2_size
, "%s: %08x %08x",
1701 LEGEND_CR4_INITIAL_LOAD
,
1702 pBuffer
->InitialId
[0], pBuffer
->InitialId
[1]);
1703 (void) strlcat(buf1
, buf2
, buf1_size
);
1705 /* Write the Flags Word into the buffer */
1706 (void) snprintf(buf2
, buf2_size
, "\n %s: %08x", LEGEND_CR4_FLAGS
,
1708 (void) strlcat(buf1
, buf2
, buf1_size
);
1710 /* Write the Boot Bios ID into the buffer */
1711 (void) snprintf(buf2
, buf2_size
, "\n %s: %08x %08x",
1712 LEGEND_CR4_BOOT_BIOS_ID
,
1713 pBuffer
->BootBiosId
[0], pBuffer
->BootBiosId
[1]);
1714 (void) strlcat(buf1
, buf2
, buf1_size
);
1716 /* Write the SLI1 ID into the buffer */
1717 (void) snprintf(buf2
, buf2_size
, "\n %s: %08x %08x",
1719 pBuffer
->Sli1Id
[0], pBuffer
->Sli1Id
[1]);
1720 (void) strlcat(buf1
, buf2
, buf1_size
);
1722 /* Write the SLI2 ID into the buffer */
1723 (void) snprintf(buf2
, buf2_size
, "\n %s: %08x %08x",
1725 pBuffer
->Sli2Id
[0], pBuffer
->Sli2Id
[1]);
1726 (void) strlcat(buf1
, buf2
, buf1_size
);
1728 /* Write the SLI3 ID into the buffer */
1729 (void) snprintf(buf2
, buf2_size
, "\n %s: %08x %08x",
1731 pBuffer
->Sli3Id
[0], pBuffer
->Sli3Id
[1]);
1732 (void) strlcat(buf1
, buf2
, buf1_size
);
1734 /* Write the SLI4 ID into the buffer */
1735 (void) snprintf(buf2
, buf2_size
, "\n %s: %08x %08x",
1737 pBuffer
->Sli4Id
[0], pBuffer
->Sli4Id
[1]);
1738 (void) strlcat(buf1
, buf2
, buf1_size
);
1740 /* Write the Erom ID into the buffer */
1741 (void) snprintf(buf2
, buf2_size
, "\n %s: %08x %08x",
1743 pBuffer
->EromId
[0], pBuffer
->EromId
[1]);
1744 (void) strlcat(buf1
, buf2
, buf1_size
);
1747 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_CONFIG_REGION
,
1748 LEGEND_CONFIG_REGION_4
, 0);
1750 kmem_free(buf1
, buf1_size
);
1751 kmem_free(buf2
, buf2_size
);
1755 } /* emlxs_dump_cfg_region4_decoded() */
1760 emlxs_dump_cfg_region14_decoded(
1762 emlxs_file_t
*fpTxtFile
,
1768 char *buf1
; /* text buffer */
1769 char *buf2
; /* text buffer */
1777 int fDone
= FALSE
; /* flag to exit VPD loop */
1779 #ifdef EMLXS_BIG_ENDIAN
1787 buf1
= kmem_zalloc(buf1_size
, KM_SLEEP
);
1788 buf2
= kmem_zalloc(buf2_size
, KM_SLEEP
);
1790 /* If Big Endian, swap the data in place, */
1791 /* because it's PCI Data (Little Endian) */
1792 #ifdef EMLXS_BIG_ENDIAN
1793 wptr
= (uint32_t *)pBuffer
;
1794 for (i
= 0; i
< (int)ByteCount
/ 4; i
++, wptr
++) {
1796 *wptr
= BE_SWAP32(w1
);
1798 #endif /* EMLXS_BIG_ENDIAN */
1800 /* Decode the VPD Data and write it into the buffer */
1803 /* NOTE: The following code is correct, */
1804 /* should work, and used to work. */
1805 /* pBuffer points to char, and the symbol VPD_TAG_82 is 0x82. */
1806 /* The test is an equality test, not a relational test. */
1807 /* The compiler should generate an 8 bit test, and */
1808 /* sign extension does not apply. */
1809 /* I don't know when or why it stopped working, */
1810 /* and don't have time to dig. */
1811 /* The cast fixes it. */
1813 if (((unsigned char)pBuffer
[0]) != VPD_TAG_82
) {
1814 (void) snprintf(buf1
, buf1_size
,
1815 "Bad VPD Data: (w0=0x%08x)", *(uint32_t *)pBuffer
);
1816 } else { /* begin good data */
1820 length
= pBuffer
[i
++];
1821 length
|= (pBuffer
[i
++] << 8);
1825 (void) strncpy(buf2
, &pBuffer
[i
],
1826 length
> buf2_size
? buf2_size
: length
);
1828 (buf2_size
- 1) ? (buf2_size
-
1830 (void) strlcat(buf1
, "Name: ", buf1_size
);
1831 (void) strlcat(buf1
, buf2
, buf1_size
);
1837 mnemonic
[0] = pBuffer
[i
++];
1838 mnemonic
[1] = pBuffer
[i
++];
1841 if (strcmp(mnemonic
, "RV") == 0) {
1846 if (mnemonic
[0] == 0) {
1851 length2
= pBuffer
[i
++];
1852 (void) snprintf(buf2
, buf2_size
,
1853 "\n %s: ", mnemonic
);
1854 (void) strlcat(buf1
, buf2
,
1856 (void) strncpy(buf2
, &pBuffer
[i
],
1858 buf2_size
? buf2_size
: length2
);
1860 (buf2_size
- 1) ? (buf2_size
-
1862 (void) strlcat(buf1
, buf2
,
1878 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_CONFIG_REGION
,
1879 LEGEND_CONFIG_REGION_14
, 0);
1881 kmem_free(buf1
, buf1_size
);
1882 kmem_free(buf2
, buf2_size
);
1886 } /* emlxs_dump_cfg_region14_decoded() */
1890 emlxs_dump_cfg_region(
1892 emlxs_file_t
*fpTxtFile
,
1893 emlxs_file_t
*fpDmpFile
,
1899 uint32_t RetByteCount
= 0; /* returned byte count */
1900 char *buf1
; /* string ops buffer */
1901 char *buf2
; /* string ops buffer */
1907 #ifdef EMLXS_LITTLE_ENDIAN
1909 #endif /* EMLXS_LITTLE_ENDIAN */
1914 buf1
= kmem_zalloc(buf1_size
, KM_SLEEP
);
1915 buf2
= kmem_zalloc(buf2_size
, KM_SLEEP
);
1918 kmem_zalloc(DUMP_MAX_CONFIG_REGION_LENGTH
, KM_SLEEP
);
1921 emlxs_read_cfg_region(hba
, Region
, DUMP_MAX_CONFIG_REGION_LENGTH
,
1922 &RetByteCount
, (uint8_t *)buffer
);
1925 kmem_free(buffer
, DUMP_MAX_CONFIG_REGION_LENGTH
);
1926 kmem_free(buf1
, buf1_size
);
1927 kmem_free(buf2
, buf2_size
);
1931 /* Write the Data into the buffer */
1932 for (i
= 0; i
< (int)RetByteCount
/ 4; i
++) {
1933 if ((i
% 8 == 0) && (i
!= 0)) {
1934 (void) strlcat((char *)buf1
, "\n ", buf1_size
);
1937 (void) snprintf(buf2
, buf2_size
, "%08x, ", buffer
[i
]);
1938 (void) strlcat((char *)buf1
, buf2
, buf1_size
);
1942 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_CONFIG_REGION
,
1945 status
= emlxs_dump_host_block(fpDmpFile
,
1948 SID_CONFIG_REGION
, LEGEND_CONFIG_REGION
, pLidLegend
, fSwap
);
1952 emlxs_dump_cfg_region4_decoded(hba
, fpTxtFile
, pLidLegend
,
1953 (DUMP_WAKE_UP_PARAMS
*)buffer
, RetByteCount
);
1958 emlxs_dump_cfg_region14_decoded(hba
, fpTxtFile
,
1959 pLidLegend
, (char *)buffer
, RetByteCount
);
1962 kmem_free(buffer
, DUMP_MAX_CONFIG_REGION_LENGTH
);
1963 kmem_free(buf1
, buf1_size
);
1964 kmem_free(buf2
, buf2_size
);
1968 } /* emlxs_dump_cfg_region() */
1972 emlxs_dump_cfg_regions(
1974 emlxs_file_t
*fpTxtFile
,
1975 emlxs_file_t
*fpDmpFile
)
1980 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 0,
1981 LEGEND_CONFIG_REGION_0
, FALSE
);
1984 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 1,
1985 LEGEND_CONFIG_REGION_1
, FALSE
);
1988 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 2,
1989 LEGEND_CONFIG_REGION_2
, FALSE
);
1992 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 3,
1993 LEGEND_CONFIG_REGION_3
, FALSE
);
1996 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 4,
1997 LEGEND_CONFIG_REGION_4
, FALSE
);
2000 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 5,
2001 LEGEND_CONFIG_REGION_5
, FALSE
);
2004 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 6,
2005 LEGEND_CONFIG_REGION_6
, FALSE
);
2008 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 7,
2009 LEGEND_CONFIG_REGION_7
, FALSE
);
2012 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 8,
2013 LEGEND_CONFIG_REGION_8
, TRUE
);
2016 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 9,
2017 LEGEND_CONFIG_REGION_9
, TRUE
);
2020 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 10,
2021 LEGEND_CONFIG_REGION_10
, TRUE
);
2024 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 11,
2025 LEGEND_CONFIG_REGION_11
, FALSE
);
2028 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 12,
2029 LEGEND_CONFIG_REGION_12
, FALSE
);
2032 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 13,
2033 LEGEND_CONFIG_REGION_13
, FALSE
);
2036 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 14,
2037 LEGEND_CONFIG_REGION_14
, FALSE
);
2040 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 15,
2041 LEGEND_CONFIG_REGION_15
, FALSE
);
2044 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 16,
2045 LEGEND_CONFIG_REGION_16
, FALSE
);
2048 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 17,
2049 LEGEND_CONFIG_REGION_17
, FALSE
);
2052 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 18,
2053 LEGEND_CONFIG_REGION_18
, FALSE
);
2056 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 19,
2057 LEGEND_CONFIG_REGION_19
, FALSE
);
2060 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 20,
2061 LEGEND_CONFIG_REGION_20
, FALSE
);
2064 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 21,
2065 LEGEND_CONFIG_REGION_21
, FALSE
);
2068 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 22,
2069 LEGEND_CONFIG_REGION_22
, FALSE
);
2072 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 23,
2073 LEGEND_CONFIG_REGION_23
, FALSE
);
2076 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 24,
2077 LEGEND_CONFIG_REGION_24
, FALSE
);
2080 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 25,
2081 LEGEND_CONFIG_REGION_25
, FALSE
);
2084 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 26,
2085 LEGEND_CONFIG_REGION_26
, FALSE
);
2088 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 27,
2089 LEGEND_CONFIG_REGION_27
, FALSE
);
2092 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 28,
2093 LEGEND_CONFIG_REGION_28
, FALSE
);
2096 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 29,
2097 LEGEND_CONFIG_REGION_29
, FALSE
);
2100 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 30,
2101 LEGEND_CONFIG_REGION_30
, FALSE
);
2104 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 31,
2105 LEGEND_CONFIG_REGION_31
, FALSE
);
2108 emlxs_dump_cfg_region(hba
, fpTxtFile
, fpDmpFile
, 32,
2109 LEGEND_CONFIG_REGION_32
, FALSE
);
2113 } /* emlxs_dump_cfg_regions() */
2118 emlxs_dump_os_version(
2120 emlxs_file_t
*fpTxtFile
,
2121 emlxs_file_t
*fpDmpFile
)
2132 buf1
= kmem_zalloc(buf1_size
, KM_SLEEP
);
2133 buf2
= kmem_zalloc(buf2_size
, KM_SLEEP
);
2135 /* First, write the OS Name string into the buffer */
2136 (void) strlcpy(buf1
, utsname
.sysname
, buf1_size
);
2138 /* Second, write the Version Info into the buffer */
2139 (void) snprintf(buf2
, buf2_size
, ", %s", utsname
.release
);
2140 (void) strlcat(buf1
, buf2
, buf1_size
);
2143 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_REV_INFO
,
2144 LEGEND_REV_OS_VERSION
, 0);
2147 emlxs_dump_string_dmpfile(fpDmpFile
, buf1
, SID_REV_INFO
,
2148 LEGEND_REV_INFO
, LEGEND_REV_OS_VERSION
);
2150 kmem_free(buf1
, buf1_size
);
2151 kmem_free(buf2
, buf2_size
);
2155 } /* emlxs_dump_os_version() */
2160 emlxs_dump_drv_version(
2162 emlxs_file_t
*fpTxtFile
,
2163 emlxs_file_t
*fpDmpFile
)
2174 buf1
= kmem_zalloc(buf1_size
, KM_SLEEP
);
2175 buf2
= kmem_zalloc(buf2_size
, KM_SLEEP
);
2177 /* Write the Driver Type into the buffer */
2178 (void) strlcpy(buf1
, "Driver Type: ", buf1_size
);
2179 (void) strlcat(buf1
, DUMP_DRV_LEADVILLE
, buf1_size
);
2181 /* Write the Driver Name into the buffer */
2182 (void) snprintf(buf2
, buf2_size
, "%s", DRIVER_NAME
);
2183 (void) strlcat(buf1
, "\n Driver Name: ", buf1_size
);
2184 (void) strlcat(buf1
, buf2
, buf1_size
);
2186 /* Write the Driver Version into the buffer */
2187 (void) snprintf(buf2
, buf2_size
, "%s", emlxs_version
);
2188 (void) strlcat(buf1
, "\n Driver Version: ", buf1_size
);
2189 (void) strlcat(buf1
, buf2
, buf1_size
);
2192 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_REV_INFO
,
2193 LEGEND_REV_DRV_VERSION
, 0);
2196 emlxs_dump_string_dmpfile(fpDmpFile
, buf1
, SID_REV_INFO
,
2197 LEGEND_REV_INFO
, LEGEND_REV_DRV_VERSION
);
2199 kmem_free(buf1
, buf1_size
);
2200 kmem_free(buf2
, buf2_size
);
2204 } /* emlxs_dump_drv_version() */
2208 emlxs_dump_file_create(
2210 emlxs_file_t
** fpTxtFile
,
2211 emlxs_file_t
** fpDmpFile
,
2212 emlxs_file_t
** fpCeeFile
)
2215 /* Create the Dump Files */
2216 if ((*fpTxtFile
= emlxs_fopen(hba
, EMLXS_TXT_FILE
)) == NULL
) {
2224 if ((hba
->model_info
.device_id
== PCI_DEVICE_ID_HORNET
) ||
2225 (hba
->model_info
.chip
== EMLXS_BE2_CHIP
) ||
2226 (hba
->model_info
.chip
== EMLXS_BE3_CHIP
)) {
2228 emlxs_fopen(hba
, EMLXS_CEE_FILE
)) == NULL
) {
2229 emlxs_fdelete(*fpTxtFile
);
2236 if ((*fpDmpFile
= emlxs_fopen(hba
, EMLXS_DMP_FILE
)) == NULL
) {
2237 emlxs_fdelete(*fpTxtFile
);
2238 emlxs_fdelete(*fpCeeFile
);
2242 /* Initialize the DMP File */
2243 /* Write the single-byte Dump Identification */
2244 /* SID to the DMP File */
2245 #ifdef EMLXS_LITTLE_ENDIAN
2246 emlxs_fputc(SID_DUMP_ID_LE
, *fpDmpFile
);
2247 #endif /* EMLXS_LITTLE_ENDIAN */
2249 #ifdef EMLXS_BIG_ENDIAN
2250 emlxs_fputc(SID_DUMP_ID_BE
, *fpDmpFile
);
2251 #endif /* EMLXS_BIG_ENDIAN */
2253 emlxs_fputc(SID_NULL
, *fpDmpFile
);
2254 emlxs_fputc(SID_NULL
, *fpDmpFile
);
2255 emlxs_fputc(SID_NULL
, *fpDmpFile
);
2256 emlxs_fflush(*fpDmpFile
);
2261 } /* emlxs_dump_file_create() */
2265 emlxs_dump_file_terminate(
2267 emlxs_file_t
*fpTxtFile
,
2268 emlxs_file_t
*fpDmpFile
,
2269 emlxs_file_t
*fpCeeFile
)
2273 /* Write a suitable string to the Dump TXT File */
2274 (void) emlxs_fprintf(fpTxtFile
, "Dump File End\n");
2275 emlxs_fflush(fpTxtFile
);
2279 if (hba
->model_info
.device_id
== PCI_DEVICE_ID_HORNET
) {
2280 (void) emlxs_fprintf(fpCeeFile
, "Dump File End\n");
2283 emlxs_fflush(fpCeeFile
);
2286 /* Write the single-byte Dump Termination SID to the DMP File */
2288 emlxs_fputc(SID_DUMP_TERM
, fpDmpFile
);
2289 emlxs_fflush(fpDmpFile
);
2295 } /* emlxs_dump_file_terminate() */
2299 emlxs_dump_file_close(
2300 emlxs_file_t
*fpTxtFile
,
2301 emlxs_file_t
*fpDmpFile
,
2302 emlxs_file_t
*fpCeeFile
)
2306 (void) emlxs_fclose(fpTxtFile
);
2310 (void) emlxs_fclose(fpCeeFile
);
2314 (void) emlxs_fclose(fpDmpFile
);
2319 } /* emlxs_dump_file_close() */
2322 /* ************************************************************************* */
2323 /* ************************************************************************* */
2324 /* Dump Generators, High Level */
2325 /* ************************************************************************* */
2326 /* ************************************************************************* */
2330 emlxs_dump_rev_info(
2332 emlxs_file_t
*fpTxtFile
,
2333 emlxs_file_t
*fpDmpFile
)
2335 (void) emlxs_dump_os_version(hba
, fpTxtFile
, fpDmpFile
);
2336 (void) emlxs_dump_drv_version(hba
, fpTxtFile
, fpDmpFile
);
2339 } /* emlxs_dump_rev_info() */
2344 emlxs_dump_hba_info(
2346 emlxs_file_t
*fpTxtFile
,
2347 emlxs_file_t
*fpDmpFile
,
2350 (void) emlxs_dump_model(hba
, fpTxtFile
, fpDmpFile
);
2351 (void) emlxs_dump_wwn(hba
, fpTxtFile
, fpDmpFile
);
2352 (void) emlxs_dump_serial_number(hba
, fpTxtFile
, fpDmpFile
);
2353 (void) emlxs_dump_fw_version(hba
, fpTxtFile
, fpDmpFile
);
2354 (void) emlxs_dump_boot_version(hba
, fpTxtFile
, fpDmpFile
);
2359 } /* emlxs_dump_hba_info() */
2362 /* ************************************************************************* */
2363 /* emlxs_dump_table_check */
2364 /* Examine Dump Table, and determine its size. */
2365 /* Count and include ID SIDs, and the TERM SID, */
2366 /* but not the Pointer at Addr 654. */
2367 /* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */
2368 /* ************************************************************************* */
2370 emlxs_dump_table_check(
2374 emlxs_port_t
*port
= &PPORT
;
2375 int fDone
= FALSE
; /* loop control flag */
2376 uint32_t tableSize
= 0; /* dump table size (word count) */
2379 uint32_t DumpTableAddr
;
2380 DUMP_TABLE_ENTRY entry
;
2384 /* Read 1 word from low memory at address 654; */
2385 /* save the returned Dump Table Base Address */
2388 (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
), KM_SLEEP
);
2389 mb
= (MAILBOX
*) mbq
;
2391 /* Read the dump table address */
2392 emlxs_mb_dump(hba
, mbq
, 0x654, 1);
2393 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
2394 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
2395 "Unable to read dump table address. "\
2396 "offset=0x654 status=%x",
2399 kmem_free(mbq
, sizeof (MAILBOXQ
));
2403 DumpTableAddr
= mb
->un
.varDmp
.resp_offset
;
2405 if (DumpTableAddr
== 0) {
2406 kmem_free(mbq
, sizeof (MAILBOXQ
));
2410 /* Now loop reading Dump Table Entries.. */
2411 /* break out when we see a Terminator SID */
2413 emlxs_mb_dump(hba
, mbq
, DumpTableAddr
, 2);
2414 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
2416 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
2417 "Unable to read dump table entry. "\
2418 "offset=%x status=%x",
2419 DumpTableAddr
, mb
->mbxStatus
);
2421 kmem_free(mbq
, sizeof (MAILBOXQ
));
2425 entry
.un
.PortBlock
.un
.w
[0] = mb
->un
.varWords
[4];
2427 switch (entry
.un
.PortBlock
.un
.s
.sid
) {
2428 /* New Dump Table */
2434 #ifdef CC_DUMP_USE_ALL_TABLES
2435 /* New Dump Table */
2442 /* New Dump Table */
2448 #endif /* CC_DUMP_USE_ALL_TABLES */
2450 /* Dump Table(s) Termination - all done */
2456 /* Dump Table Entry */
2465 *pSize
= (tableSize
* 4); /* return the total Dump Table size */
2467 kmem_free(mbq
, sizeof (MAILBOXQ
));
2470 } /* emlxs_dump_table_check() */
2473 /* ************************************************************************ */
2474 /* emlxs_dump_table_read */
2475 /* Read the Dump Table and store it, for use */
2476 /* subsequently in emlxs_dump_hba_memory. */
2477 /* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */
2478 /* ************************************************************************ */
2480 emlxs_dump_table_read(
2482 emlxs_file_t
*fpTxtFile
,
2483 uint32_t **ppDumpTable
,
2484 uint32_t *pDumpTableSize
)
2486 emlxs_port_t
*port
= &PPORT
;
2487 uint32_t status
= 0;
2491 uint32_t *pDumpTableEntry
;
2492 uint32_t DumpTableAddr
;
2493 DUMP_TABLE_ENTRY entry
;
2497 uint32_t size
= (32 * 1024);
2499 /* First, check the dump table and if valid, get its size */
2500 status
= emlxs_dump_table_check(hba
, pDumpTableSize
);
2505 buf1
= kmem_zalloc(size
, KM_SLEEP
);
2507 /* Allocate a buffer to hold the Dump Table */
2508 *ppDumpTable
= kmem_zalloc(*pDumpTableSize
, KM_SLEEP
);
2510 pDumpTableEntry
= *ppDumpTable
;
2512 /* Read 1 word from low memory at address 654; */
2513 /* save the returned Dump Table Base Address */
2515 (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
), KM_SLEEP
);
2517 mb
= (MAILBOX
*) mbq
;
2519 /* Read the dump table address */
2520 emlxs_mb_dump(hba
, mbq
, 0x654, 1);
2521 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) != MBX_SUCCESS
) {
2522 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
2523 "Unable to read dump table address. "\
2524 "offset=0x654 status=%x",
2527 kmem_free(buf1
, size
);
2528 kmem_free(mbq
, sizeof (MAILBOXQ
));
2530 kmem_free(*ppDumpTable
, *pDumpTableSize
);
2531 *pDumpTableSize
= 0;
2532 *ppDumpTable
= NULL
;
2537 DumpTableAddr
= mb
->un
.varDmp
.resp_offset
;
2539 if (DumpTableAddr
== 0) {
2540 kmem_free(buf1
, size
);
2541 kmem_free(mbq
, sizeof (MAILBOXQ
));
2543 kmem_free(*ppDumpTable
, *pDumpTableSize
);
2544 *pDumpTableSize
= 0;
2545 *ppDumpTable
= NULL
;
2551 /* Now loop reading Dump Table Entries.. */
2552 /* break out when we see a Terminator SID */
2554 emlxs_mb_dump(hba
, mbq
, DumpTableAddr
, 2);
2555 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
2557 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
2558 "Unable to read dump table entry. "\
2559 "offset=%x status=%x",
2560 DumpTableAddr
, mb
->mbxStatus
);
2562 kmem_free(buf1
, size
);
2563 kmem_free(mbq
, sizeof (MAILBOXQ
));
2565 kmem_free(*ppDumpTable
, *pDumpTableSize
);
2566 *pDumpTableSize
= 0;
2567 *ppDumpTable
= NULL
;
2572 (void) snprintf(buf2
, sizeof (buf2
), "\n Addr=%08x: ",
2573 mb
->un
.varDmp
.base_adr
);
2574 (void) strlcat(buf1
, buf2
, size
);
2576 entry
.un
.PortBlock
.un
.w
[0] = mb
->un
.varWords
[4];
2577 *pDumpTableEntry
++ = mb
->un
.varWords
[4];
2579 switch (entry
.un
.PortBlock
.un
.s
.sid
) {
2580 /* New Dump Table */
2582 (void) snprintf(buf2
, sizeof (buf2
), "w0=%08x",
2583 entry
.un
.PortBlock
.un
.w
[0]);
2584 (void) strlcat(buf1
, buf2
, size
);
2588 #ifdef CC_DUMP_USE_ALL_TABLES
2589 /* New Dump Table */
2592 (void) snprintf(buf2
, sizeof (buf2
), "w0=%08x",
2593 entry
.un
.PortBlock
.un
.w
[0]);
2594 (void) strlcat(buf1
, buf2
, size
);
2598 /* New Dump Table */
2601 (void) snprintf(buf2
, sizeof (buf2
), "w0=%08x",
2602 entry
.un
.PortBlock
.un
.w
[0]);
2603 (void) strlcat(buf1
, buf2
, size
);
2606 #endif /* CC_DUMP_USE_ALL_TABLES */
2608 /* Dump Table(s) Termination - all done */
2610 (void) snprintf(buf2
, sizeof (buf2
), "w0=%08x",
2611 entry
.un
.PortBlock
.un
.w
[0]);
2612 (void) strlcat(buf1
, buf2
, size
);
2616 /* Dump Table Entry */
2618 entry
.un
.PortBlock
.un
.w
[1] = mb
->un
.varWords
[5];
2619 *pDumpTableEntry
++ = mb
->un
.varWords
[5];
2621 (void) snprintf(buf2
, sizeof (buf2
), "w0=%08x, w1=%08x",
2622 entry
.un
.PortBlock
.un
.w
[0],
2623 entry
.un
.PortBlock
.un
.w
[1]);
2624 (void) strlcat(buf1
, buf2
, size
);
2632 emlxs_dump_string_txtfile(fpTxtFile
, buf1
, LEGEND_HBA_MEM_DUMP
,
2633 LEGEND_HBA_MEM_DUMP_TABLE
, 0);
2635 kmem_free(buf1
, size
);
2636 kmem_free(mbq
, sizeof (MAILBOXQ
));
2639 kmem_free(*ppDumpTable
, *pDumpTableSize
);
2640 *pDumpTableSize
= 0;
2641 *ppDumpTable
= NULL
;
2648 } /* emlxs_dump_table_read() */
2651 /* ************************************************************************* */
2652 /* emlxs_dump_hba_memory */
2653 /* Guided by the Dump Table previously read in, */
2654 /* generate the Port Memory Dump. */
2655 /* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */
2656 /* ************************************************************************* */
2658 emlxs_dump_hba_memory(
2660 emlxs_file_t
*fpDmpFile
,
2661 uint32_t *pDumpTable
)
2663 emlxs_port_t
*port
= &PPORT
;
2664 uint32_t status
= 0;
2666 DUMP_TABLE_ENTRY entry
;
2670 uint32_t byteCountRem
;
2675 uint32_t offset
= 0;
2679 #ifdef EMLXS_BIG_ENDIAN
2681 #endif /* EMLXS_BIG_ENDIAN */
2688 (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
), KM_SLEEP
);
2690 mb
= (MAILBOX
*) mbq
;
2692 /* loop reading Dump Table Entries.. break out when */
2693 /* we see a Terminator SID */
2695 entry
.un
.PortBlock
.un
.w
[0] = *pDumpTable
++;
2697 switch (entry
.un
.PortBlock
.un
.s
.sid
) {
2699 /* New Dump Table */
2703 #ifdef CC_DUMP_USE_ALL_TABLES
2704 /* New Dump Table */
2709 /* New Dump Table */
2714 #endif /* CC_DUMP_USE_ALL_TABLES */
2716 /* Dump Table(s) Termination - all done */
2722 /* Dump Table Entry */
2723 entry
.un
.PortBlock
.un
.w
[1] = *pDumpTable
++;
2725 #ifdef CC_DUMP_FW_BUG_1
2726 if (entry
.un
.PortBlock
.un
.w
[1] == 0x3E0000) {
2729 #endif /* CC_DUMP_FW_BUG_1 */
2731 /* Check if indirect address, and */
2732 /* obtain the new address if so */
2733 if ((entry
.un
.PortBlock
.un
.s
.addr
& 0x80000000) != 0) {
2735 (entry
.un
.PortBlock
.un
.s
.
2737 emlxs_mb_dump(hba
, mbq
, offset
, 1);
2738 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
,
2739 0) != MBX_SUCCESS
) {
2740 EMLXS_MSGF(EMLXS_CONTEXT
,
2741 &emlxs_init_debug_msg
,
2742 "Unable to read dump table entry. "\
2743 "offset=%x status=%x",
2744 offset
, mb
->mbxStatus
);
2746 kmem_free(mbq
, sizeof (MAILBOXQ
));
2750 /* replace the indirect address in the */
2752 entry
.un
.PortBlock
.un
.s
.addr
=
2756 /* determine byte count to dump */
2757 byteCount
= entry
.un
.PortBlock
.un
.s
.bc
;
2758 if (entry
.un
.PortBlock
.un
.s
.sid
& SID_MULT_ELEM
) {
2759 if (entry
.un
.PortStruct
.un
.s
.count
== 0) {
2762 entry
.un
.PortStruct
.un
.s
.length
;
2765 entry
.un
.PortStruct
.un
.s
.count
*
2766 entry
.un
.PortStruct
.un
.s
.length
;
2771 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
2772 "Dump: addr=%x count=%d total=%d", offset
,
2775 /* allocate a buffer to receive the dump data */
2776 pBuf
= kmem_zalloc(byteCount
, KM_SLEEP
);
2778 /* loop issuing MBX commands, 18x measly words at */
2782 byteCountRem
= byteCount
;
2784 portAddr
= entry
.un
.PortBlock
.un
.s
.addr
;
2787 if (byteCountRem
== 0) {
2792 (byteCountRem
/ 4 >=
2793 0x18) ? 0x18 : (byteCountRem
/ 4);
2794 emlxs_mb_dump(hba
, mbq
, portAddr
, wcount
);
2795 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
,
2796 0) != MBX_SUCCESS
) {
2797 EMLXS_MSGF(EMLXS_CONTEXT
,
2798 &emlxs_init_debug_msg
,
2799 "Unable to read dump table entry."\
2800 " offset=%x wc=%d status=%x",
2801 portAddr
, wcount
, mb
->mbxStatus
);
2805 bcopy((uint8_t *)&mb
->un
.varWords
[4], p1
,
2806 (mb
->un
.varDmp
.word_cnt
* 4));
2808 byteCountRem
-= (mb
->un
.varDmp
.word_cnt
* 4);
2809 p1
+= (mb
->un
.varDmp
.word_cnt
* 4);
2810 portAddr
+= (mb
->un
.varDmp
.word_cnt
* 4);
2815 if (entry
.un
.PortBlock
.un
.s
.
2816 sid
& SID_MULT_ELEM
) {
2818 emlxs_dump_port_struct(fpDmpFile
,
2819 pBuf
, byteCount
, entry
, fSwap
);
2822 emlxs_dump_port_block(fpDmpFile
,
2823 pBuf
, byteCount
, entry
, fSwap
);
2828 kmem_free(pBuf
, byteCount
);
2837 kmem_free(mbq
, sizeof (MAILBOXQ
));
2841 } /* emlxs_dump_hba_memory() */
2847 emlxs_file_t
*fpTxtFile
,
2848 emlxs_file_t
*fpDmpFile
)
2850 uint32_t status
= 0;
2851 uint32_t *pDumpTable
= 0;
2852 uint32_t DumpTableSize
= 0;
2854 if (hba
->sli_mode
>= EMLXS_HBA_SLI4_MODE
) {
2858 /* HBA should be in WARM state here */
2860 emlxs_dump_table_read(hba
, fpTxtFile
, &pDumpTable
,
2866 status
= emlxs_dump_hba_memory(hba
, fpDmpFile
, pDumpTable
);
2868 if (pDumpTable
!= 0) {
2869 kmem_free(pDumpTable
, DumpTableSize
);
2874 } /* emlxs_dump_hba() */
2877 /* ************************************************************************* */
2878 /* emlxs_dump_drv_region */
2879 /* Common subroutine for all the Dump_Sli"Structures" Routines */
2880 /* NOTE: This routine does not free pBuf. This is by design. */
2881 /* The caller does it. */
2882 /* ************************************************************************* */
2884 emlxs_dump_drv_region(
2889 { /* ptr to length of buffer */
2897 status
= emlxs_get_dump_region(hba
, regionId
, NULL
, &size
);
2903 /* Now that we know the required length, request the actual data */
2904 *pBuf
= kmem_zalloc(size
, KM_SLEEP
);
2906 status
= emlxs_get_dump_region(hba
, regionId
, *pBuf
, &size
);
2909 kmem_free(*pBuf
, size
);
2919 } /* emlxs_dump_drv_region() */
2923 emlxs_dump_sli_regs(
2925 emlxs_file_t
*fpDmpFile
)
2928 uint8_t *pBuf
; /* ptr to data buffer to receive Dump Region Data */
2929 uint32_t bufLen
= 0; /* length of buffer */
2930 int fSwap
= FALSE
; /* flag to pass to emlxs_dump_word_dmpfile */
2932 #ifdef EMLXS_BIG_ENDIAN
2934 #endif /* EMLXS_BIG_ENDIAN */
2940 status
= emlxs_dump_drv_region(hba
, DR_SLI_REGS
, &pBuf
, &bufLen
);
2947 emlxs_dump_host_block(fpDmpFile
, pBuf
, bufLen
, SID_SLI_REGS
,
2948 LEGEND_SLI_STRUCTURES
, LEGEND_SLI_REGS
, fSwap
);
2950 kmem_free(pBuf
, bufLen
);
2954 } /* emlxs_dump_sli_regs() */
2960 emlxs_file_t
*fpTxtFile
,
2961 emlxs_file_t
*fpDmpFile
,
2965 uint8_t *pBuf
; /* ptr to data buffer to receive Dump Region Data */
2966 uint32_t bufLen
= 0; /* length of buffer */
2967 int fSwap
= FALSE
; /* flag to pass to emlxs_dump_word_dmpfile */
2969 #ifdef EMLXS_BIG_ENDIAN
2971 #endif /* EMLXS_BIG_ENDIAN */
2973 status
= emlxs_dump_drv_region(hba
, DR_SLIM
, &pBuf
, &bufLen
);
2979 /* The SLIM Dump is only useful if it's a */
2980 /* Driver-Initiated dump, say, after a HW Error */
2981 if (dump_type
== DUMP_TYPE_DRIVER
) {
2983 emlxs_dump_word_txtfile(fpTxtFile
, (uint32_t *)pBuf
,
2984 0x40, LEGEND_SLI_STRUCTURES
, LEGEND_SLIM
);
2988 emlxs_dump_host_block(fpDmpFile
, pBuf
, bufLen
, SID_SLIM
,
2989 LEGEND_SLI_STRUCTURES
, LEGEND_SLIM
, fSwap
);
2991 kmem_free(pBuf
, bufLen
);
2995 } /* emlxs_dump_slim() */
3001 emlxs_file_t
*fpDmpFile
)
3004 uint8_t *pBuf
; /* ptr to data buffer to receive Dump Region Data */
3005 uint32_t bufLen
= 0; /* length of buffer */
3006 int fSwap
= FALSE
; /* flag to pass to emlxs_dump_word_dmpfile */
3008 #ifdef EMLXS_BIG_ENDIAN
3010 #endif /* EMLXS_BIG_ENDIAN */
3016 status
= emlxs_dump_drv_region(hba
, DR_PCB
, &pBuf
, &bufLen
);
3022 emlxs_dump_host_block(fpDmpFile
, pBuf
, bufLen
, SID_PCB
,
3023 LEGEND_SLI_STRUCTURES
, LEGEND_PCB
, fSwap
);
3025 kmem_free(pBuf
, bufLen
);
3029 } /* emlxs_dump_pcb() */
3035 emlxs_file_t
*fpDmpFile
)
3038 uint8_t *pBuf
; /* ptr to data buffer to receive Dump Region Data */
3039 uint32_t bufLen
= 0; /* length of buffer */
3040 int fSwap
= FALSE
; /* flag to pass to emlxs_dump_word_dmpfile */
3042 #ifdef EMLXS_BIG_ENDIAN
3044 #endif /* EMLXS_BIG_ENDIAN */
3050 status
= emlxs_dump_drv_region(hba
, DR_MBX
, &pBuf
, &bufLen
);
3056 emlxs_dump_host_block(fpDmpFile
, pBuf
, bufLen
, SID_MBX
,
3057 LEGEND_SLI_STRUCTURES
, LEGEND_MBX
, fSwap
);
3059 kmem_free(pBuf
, bufLen
);
3063 } /* emlxs_dump_mbox() */
3067 emlxs_dump_host_pointers(
3069 emlxs_file_t
*fpDmpFile
)
3072 uint8_t *pBuf
; /* ptr to data buffer to receive Dump Region Data */
3073 uint32_t bufLen
= 0; /* length of buffer */
3074 int fSwap
= FALSE
; /* flag to pass to emlxs_dump_word_dmpfile */
3076 #ifdef EMLXS_BIG_ENDIAN
3078 #endif /* EMLXS_BIG_ENDIAN */
3084 status
= emlxs_dump_drv_region(hba
, DR_HOST_PTRS
, &pBuf
, &bufLen
);
3090 emlxs_dump_host_block(fpDmpFile
, pBuf
, bufLen
, SID_HOST_PTRS
,
3091 LEGEND_SLI_STRUCTURES
, LEGEND_HOST_PTRS
, fSwap
);
3093 kmem_free(pBuf
, bufLen
);
3097 } /* emlxs_dump_host_pointers() */
3101 emlxs_dump_port_pointers(
3103 emlxs_file_t
*fpDmpFile
)
3106 uint8_t *pBuf
; /* ptr to data buffer to receive Dump Region Data */
3107 uint32_t bufLen
= 0; /* length of buffer */
3108 int fSwap
= FALSE
; /* flag to pass to emlxs_dump_word_dmpfile */
3110 #ifdef EMLXS_BIG_ENDIAN
3112 #endif /* EMLXS_BIG_ENDIAN */
3118 status
= emlxs_dump_drv_region(hba
, DR_PORT_PTRS
, &pBuf
, &bufLen
);
3124 emlxs_dump_host_block(fpDmpFile
, pBuf
, bufLen
, SID_PORT_PTRS
,
3125 LEGEND_SLI_STRUCTURES
, LEGEND_PORT_PTRS
, fSwap
);
3127 kmem_free(pBuf
, bufLen
);
3131 } /* emlxs_dump_port_pointers() */
3137 emlxs_file_t
*fpDmpFile
)
3140 uint8_t *pBuf
; /* ptr to data buffer to receive Dump Region Data */
3141 uint32_t bufLen
= 0; /* length of buffer */
3142 int fSwap
= FALSE
; /* flag to pass to emlxs_dump_word_dmpfile */
3144 #ifdef EMLXS_BIG_ENDIAN
3146 #endif /* EMLXS_BIG_ENDIAN */
3152 status
= emlxs_dump_drv_region(hba
, DR_RINGS
, &pBuf
, &bufLen
);
3158 emlxs_dump_host_struct(fpDmpFile
, pBuf
, bufLen
, sizeof (IOCB
),
3159 bufLen
/ sizeof (IOCB
), SID_RINGS
, LEGEND_SLI_STRUCTURES
,
3160 LEGEND_RINGS
, fSwap
);
3162 kmem_free(pBuf
, bufLen
);
3166 } /* emlxs_dump_rings() */
3170 emlxs_dump_drv_internals(
3172 emlxs_file_t
*fpDmpFile
)
3175 uint8_t *pBuf
; /* ptr to data buffer to receive Dump Region Data */
3176 uint32_t bufLen
= 0; /* length of buffer */
3177 int fSwap
= FALSE
; /* flag to pass to emlxs_dump_word_dmpfile */
3179 #ifdef EMLXS_BIG_ENDIAN
3181 #endif /* EMLXS_BIG_ENDIAN */
3187 status
= emlxs_dump_drv_region(hba
, DR_INTERNAL
, &pBuf
, &bufLen
);
3193 emlxs_dump_host_block(fpDmpFile
, pBuf
, bufLen
, SID_INTERNAL_SOL
,
3194 LEGEND_SLI_STRUCTURES
, LEGEND_DRIVER_SPEC
, fSwap
);
3196 kmem_free(pBuf
, bufLen
);
3200 } /* emlxs_dump_drv_internals() */
3204 emlxs_dump_sli_interface(
3206 emlxs_file_t
*fpTxtFile
,
3207 emlxs_file_t
*fpDmpFile
,
3211 if (hba
->sli_mode
<= EMLXS_HBA_SLI3_MODE
) {
3212 /* HBA should be in OFFLINE state here */
3214 (void) emlxs_dump_sli_regs(hba
, fpDmpFile
);
3215 (void) emlxs_dump_slim(hba
, fpTxtFile
, fpDmpFile
, dump_type
);
3216 (void) emlxs_dump_pcb(hba
, fpDmpFile
);
3217 (void) emlxs_dump_mbox(hba
, fpDmpFile
);
3218 (void) emlxs_dump_host_pointers(hba
, fpDmpFile
);
3219 (void) emlxs_dump_port_pointers(hba
, fpDmpFile
);
3220 (void) emlxs_dump_rings(hba
, fpDmpFile
);
3223 (void) emlxs_dump_drv_internals(hba
, fpDmpFile
);
3227 } /* emlxs_dump_sli_interface() */
3231 emlxs_dump_menlo_log(
3233 emlxs_file_t
*fpCeeFile
)
3237 int isWrapped
= FALSE
;
3238 char buf1
[2048] = { 0 };
3239 char buf2
[2048] = { 0 };
3241 /* Get Config Command vars */
3242 menlo_get_config_rsp_t GcBuf
;
3243 menlo_get_config_rsp_t
*pGcBuf
= &GcBuf
;
3245 /* Get Log Config Command vars */
3247 menlo_rsp_t
*pLcBuf
= NULL
;
3249 menlo_log_t
*pLcEntry
;
3251 /* Get Log Data Command vars */
3253 menlo_rsp_t
*pLdBuf
= NULL
;
3258 /* Get Panic Log Command vars */
3260 menlo_rsp_t
*pPlBuf
= NULL
;
3261 uint32_t PanicLogEntryCount
;
3262 uint32_t PanicLogEntrySize
;
3264 if (hba
->model_info
.device_id
!= PCI_DEVICE_ID_HORNET
) {
3265 return (DFC_INVALID_ADAPTER
);
3268 /* First, issue a GetConfig command, which gives us */
3269 /* the Log Config and Panic Log sizes */
3272 emlxs_menlo_get_cfg(hba
, pGcBuf
, sizeof (menlo_get_config_rsp_t
));
3274 if (RmStatus
!= 0) {
3278 LcBufSize
= GcBuf
.log_cfg_size
+ 8;
3279 PlBufSize
= GcBuf
.panic_log_size
;
3281 pLcBuf
= (menlo_rsp_t
*)kmem_zalloc(LcBufSize
, KM_SLEEP
);
3283 RmStatus
= emlxs_menlo_get_logcfg(hba
, pLcBuf
, LcBufSize
);
3285 if (RmStatus
!= 0) {
3291 emlxs_dump_string_txtfile(fpCeeFile
, buf1
,
3292 LEGEND_MENLO_LOG_CONFIG
, LEGEND_NULL
, 0);
3294 NumLogs
= pLcBuf
->log_cfg
.num_logs
;
3295 pLcEntry
= (menlo_log_t
*)&pLcBuf
->log_cfg
.data
;
3298 (void) snprintf(buf2
, sizeof (buf2
), "LogId Entries Size Name");
3299 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3300 (void) snprintf(buf2
, sizeof (buf2
), "\n----- ------- ---- ----");
3301 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3303 RmStatus
= emlxs_dump_string_txtfile(fpCeeFile
, buf1
, 0, 0, 1);
3305 for (i
= 0; i
< (int)NumLogs
; i
++) {
3307 (void) snprintf(buf2
, sizeof (buf2
),
3308 "\n %2d %4d %4d %s",
3310 pLcEntry
[i
].num_entries
,
3311 pLcEntry
[i
].entry_size
, pLcEntry
[i
].name
);
3312 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3314 emlxs_dump_string_txtfile(fpCeeFile
, buf1
, 0, 0, 1);
3317 /* Now issue a series of GetLogData commands, */
3318 /* which gives us the actual Logs */
3320 for (i
= 0; i
< (int)NumLogs
; i
++) {
3322 (pLcEntry
[i
].num_entries
*pLcEntry
[i
].entry_size
) + 8;
3324 pLdBuf
= (menlo_rsp_t
*)kmem_zalloc(LdBufSize
, KM_SLEEP
);
3326 RmStatus
= emlxs_menlo_get_log(hba
, i
, pLdBuf
, LdBufSize
);
3328 if (RmStatus
!= 0) {
3332 /* print a caption for the current log */
3334 (void) snprintf(buf2
, sizeof (buf2
), "\n\nLog %d:", i
);
3335 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3336 (void) snprintf(buf2
, sizeof (buf2
), " %s", pLcEntry
[i
].name
);
3337 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3338 (void) snprintf(buf2
, sizeof (buf2
), "\n");
3340 for (j
= 0; j
< 75; j
++) {
3341 (void) strlcat(buf2
, "-", sizeof (buf2
));
3344 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3346 emlxs_dump_string_txtfile(fpCeeFile
, buf1
, 0, 0, 1);
3348 /* check the head entry to determine whether */
3349 /* the log has wrapped or not */
3350 Head
= pLdBuf
->log
.head
;
3351 pLogEntry
= (uint8_t *)&pLdBuf
->log
.data
;
3353 (char *)&(pLogEntry
[Head
*pLcEntry
[i
].entry_size
]);
3356 if (strlen(pLogString
) != 0) {
3360 /* if log is wrapped, get entries from the */
3361 /* Head through the End */
3363 for (j
= Head
; j
< (int)pLcEntry
[i
].num_entries
; j
++) {
3365 (char *)&(pLogEntry
[j
*
3366 pLcEntry
[i
].entry_size
]);
3368 (void) snprintf(buf2
, sizeof (buf2
),
3369 "\n%3d: %s", j
, pLogString
);
3370 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3372 emlxs_dump_string_txtfile(fpCeeFile
, buf1
,
3377 /* if wrapped or not, get entries from the Top */
3378 /* through the Head */
3379 for (j
= 0; j
< Head
; j
++) {
3381 (char *)&(pLogEntry
[j
* pLcEntry
[i
].entry_size
]);
3383 (void) snprintf(buf2
, sizeof (buf2
), "\n%3d: %s", j
,
3385 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3387 emlxs_dump_string_txtfile(fpCeeFile
, buf1
, 0, 0,
3392 /* Now issue a GetPanicLog command, which gives us the Panic Log */
3394 /* print a caption for the current log */
3395 (void) strlcpy(buf1
, LEGEND_MENLO_LOG_PANIC_REGS
, sizeof (buf1
));
3397 for (j
= 0; j
< 75; j
++) {
3398 (void) strlcat(buf2
, "-", sizeof (buf2
));
3400 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3401 RmStatus
= emlxs_dump_string_txtfile(fpCeeFile
, buf1
, 0, 0, 1);
3403 pPlBuf
= (menlo_rsp_t
*)kmem_zalloc(PlBufSize
, KM_SLEEP
);
3405 RmStatus
= emlxs_menlo_get_paniclog(hba
, pPlBuf
, PlBufSize
);
3407 if (RmStatus
== 0) {
3409 (void) snprintf(buf2
, sizeof (buf2
), "\nType = %x",
3410 pPlBuf
->panic_log
.type
);
3411 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3412 (void) snprintf(buf2
, sizeof (buf2
), "\nRegsEpc = %08x",
3413 pPlBuf
->panic_log
.regs_epc
);
3414 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3415 (void) snprintf(buf2
, sizeof (buf2
), "\nRegsCp0Cause = %08x",
3416 pPlBuf
->panic_log
.regs_cp0_cause
);
3417 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3418 (void) snprintf(buf2
, sizeof (buf2
), "\nRegsCp0Stat = %08x",
3419 pPlBuf
->panic_log
.regs_cp0_status
);
3420 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3422 emlxs_dump_string_txtfile(fpCeeFile
, buf1
, 0, 0, 1);
3425 for (i
= 0; i
< MENLO_NUM_GP_REGS
; i
++) {
3426 (void) snprintf(buf2
, sizeof (buf2
),
3427 "\nRegsGp[%02x] = %08x", i
,
3428 pPlBuf
->panic_log
.regs_gp
[i
]);
3429 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3432 emlxs_dump_string_txtfile(fpCeeFile
, buf1
, 0, 0, 1);
3435 (void) snprintf(buf2
, sizeof (buf2
), "\nLogPresent = %08x",
3436 pPlBuf
->panic_log
.log_present
);
3437 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3438 PanicLogEntryCount
= pPlBuf
->panic_log
.num_entries
;
3439 (void) snprintf(buf2
, sizeof (buf2
), "\nNumEntries = %08x",
3440 PanicLogEntryCount
);
3441 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3442 PanicLogEntrySize
= pPlBuf
->panic_log
.entry_size
;
3443 (void) snprintf(buf2
, sizeof (buf2
), "\nEntrySize = %d.",
3445 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3446 (void) snprintf(buf2
, sizeof (buf2
), "\nHead Entry = %d.",
3447 pPlBuf
->panic_log
.head
);
3448 (void) strlcat(buf1
, buf2
, sizeof (buf1
));
3450 emlxs_dump_string_txtfile(fpCeeFile
, buf1
, 0, 0, 1);
3452 /* print a caption for the current log */
3453 (void) strlcpy(buf1
, LEGEND_MENLO_LOG_PANIC_LOGS
,
3456 for (j
= 0; j
< 75; j
++) {
3457 (void) strlcat(buf2
, "-", sizeof (buf2
));
3459 (void) strlcat(buf1
, buf2
, sizeof (buf2
));
3461 emlxs_dump_string_txtfile(fpCeeFile
, buf1
, 0, 0, 1);
3463 /* check the head entry to determine whether the */
3464 /* log has wrapped or not */
3465 Head
= pPlBuf
->panic_log
.head
;
3466 pLogEntry
= (uint8_t *)&pPlBuf
->panic_log
.data
;
3467 pLogString
= (char *)&(pLogEntry
[Head
* PanicLogEntrySize
]);
3469 if (strlen(pLogString
) != 0) {
3473 /* if log is wrapped, get entries from the */
3474 /* Head through the End */
3476 for (j
= Head
; j
< (int)PanicLogEntryCount
; j
++) {
3478 (char *)&(pLogEntry
[j
*
3479 PanicLogEntrySize
]);
3481 (void) snprintf(buf2
, sizeof (buf2
),
3482 "\n%3d: %s", j
, pLogString
);
3483 (void) strlcat(buf1
, buf2
, sizeof (buf2
));
3485 emlxs_dump_string_txtfile(fpCeeFile
, buf1
,
3489 /* if wrapped or not, get entries from the Top */
3490 /* through the Head */
3491 for (j
= 0; j
< Head
; j
++) {
3493 (char *)&(pLogEntry
[j
* PanicLogEntrySize
]);
3495 (void) snprintf(buf2
, sizeof (buf2
), "\n%3d: %s", j
,
3497 (void) strlcat(buf1
, buf2
, sizeof (buf2
));
3499 emlxs_dump_string_txtfile(fpCeeFile
, buf1
, 0, 0,
3504 RmStatus
= emlxs_dump_string_txtfile(fpCeeFile
, "\n\n", 0, 0, 1);
3509 kmem_free(pLdBuf
, LdBufSize
);
3513 kmem_free(pLcBuf
, LcBufSize
);
3517 kmem_free(pPlBuf
, PlBufSize
);
3522 } /* emlxs_dump_menlo_log() */
3526 emlxs_dump_saturn_log(
3528 emlxs_file_t
*fpTxtFile
,
3529 emlxs_file_t
*fpDmpFile
)
3531 emlxs_port_t
*port
= &PPORT
;
3534 MATCHMAP
*mp
= NULL
;
3536 uint32_t logSize
= 0;
3537 uintptr_t tempAddress
;
3540 uint32_t block_size
;
3543 #ifdef EMLXS_BIG_ENDIAN
3545 #endif /* EMLXS_BIG_ENDIAN */
3547 if (hba
->model_info
.chip
!= EMLXS_SATURN_CHIP
) {
3552 (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
), KM_SLEEP
);
3554 mb
= (MAILBOX
*) mbq
;
3556 /* Step 1: Call MBX_READ_EVENT_LOG_STATUS to get the log size. */
3557 for (i
= 0; i
< 10; i
++) {
3558 bzero((void *)mb
, MAILBOX_CMD_BSIZE
);
3559 mb
->mbxCommand
= MBX_READ_EVENT_LOG_STATUS
;
3560 mbq
->mbox_cmpl
= NULL
;
3562 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) ==
3567 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3568 "Unable to read event log status. status=%x",
3571 if ((mb
->mbxStatus
& 0xFFFF) == MBXERR_NOT_SUPPORTED
||
3572 (mb
->mbxStatus
& 0xFFFF) == MBX_DRVR_ERROR
) {
3573 (void) emlxs_dump_string_txtfile(fpTxtFile
,
3574 NV_LOG_NOT_INCLUDED_IN_DMP
,
3575 LEGEND_NON_VOLATILE_LOG
,
3576 LEGEND_NV_LOG_DRIVER_NOT_SUPPORTED
, 0);
3578 kmem_free(mbq
, sizeof (MAILBOXQ
));
3582 /* The call to get the log size simply fails. */
3583 /* Retry up to 10 times. */
3584 if ((mb
->mbxStatus
& 0xFFFF) != MBX_BUSY
) {
3585 /* Mailbox fails for some unknown reason. */
3586 /* Put something in the txt to indicate this case. */
3587 (void) emlxs_dump_string_txtfile(fpTxtFile
,
3588 NV_LOG_NOT_INCLUDED_IN_DMP
,
3589 LEGEND_NON_VOLATILE_LOG
,
3590 LEGEND_NV_LOG_STATUS_ERROR
, 0);
3592 kmem_free(mbq
, sizeof (MAILBOXQ
));
3598 (void) emlxs_dump_string_txtfile(fpTxtFile
,
3599 NV_LOG_NOT_INCLUDED_IN_DMP
, LEGEND_NON_VOLATILE_LOG
,
3600 LEGEND_NV_LOG_STATUS_ERROR
, 0);
3602 kmem_free(mbq
, sizeof (MAILBOXQ
));
3606 /* Step 2: Use the log size from step 1 to call MBX_READ_EVENT_LOG */
3607 logSize
= mb
->un
.varLogStat
.size
;
3609 if ((mp
= emlxs_mem_buf_alloc(hba
, logSize
)) == 0) {
3610 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3611 "Unable to allocate receive buffer. "
3615 kmem_free(mbq
, sizeof (MAILBOXQ
));
3619 for (offset
= 0; offset
< logSize
; offset
= offset
+ 1024) {
3620 if (logSize
- offset
< 1024) {
3621 block_size
= logSize
- offset
;
3626 tempAddress
= (uintptr_t)(mp
->phys
+ offset
);
3628 bzero((void *)mb
, MAILBOX_CMD_BSIZE
);
3629 mb
->mbxCommand
= MBX_READ_EVENT_LOG
; /* 0x38 */
3630 mb
->un
.varRdEvtLog
.read_log
= 1; /* read log */
3631 mb
->un
.varRdEvtLog
.mbox_rsp
= 0; /* not using Mailbox */
3632 mb
->un
.varRdEvtLog
.offset
= offset
;
3633 mb
->un
.varRdEvtLog
.un
.sp64
.tus
.f
.bdeFlags
= 0x0;
3634 mb
->un
.varRdEvtLog
.un
.sp64
.tus
.f
.bdeSize
= block_size
;
3635 mb
->un
.varRdEvtLog
.un
.sp64
.addrLow
= PADDR_LO(tempAddress
);
3636 mb
->un
.varRdEvtLog
.un
.sp64
.addrHigh
= PADDR_HI(tempAddress
);
3637 mbq
->mbox_cmpl
= NULL
;
3639 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
3641 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_init_debug_msg
,
3642 "Unable to read event log. status=%x",
3645 emlxs_mem_buf_free(hba
, mp
);
3646 kmem_free(mbq
, sizeof (MAILBOXQ
));
3651 /* Step 3: Dump the log to the DMP file as raw data. */
3653 /* Write a string to text file to direct the user to the DMP */
3654 /* file for the actual log. */
3656 emlxs_dump_string_txtfile(fpTxtFile
, NV_LOG_INCLUDED_IN_DMP
,
3657 LEGEND_NON_VOLATILE_LOG
, LEGEND_NULL
, 0);
3659 /* Write the real log to the DMP file. */
3660 EMLXS_MPDATA_SYNC(mp
->dma_handle
, 0, logSize
, DDI_DMA_SYNC_FORKERNEL
);
3663 emlxs_dump_host_block(fpDmpFile
, mp
->virt
, logSize
,
3664 SID_NON_VOLATILE_LOG
, LEGEND_NON_VOLATILE_LOG
, LEGEND_NULL
,
3668 if (emlxs_fm_check_dma_handle(hba
, mp
->dma_handle
)
3670 EMLXS_MSGF(EMLXS_CONTEXT
,
3671 &emlxs_invalid_dma_handle_msg
,
3672 "dump_saturn_log: hdl=%p",
3676 #endif /* FMA_SUPPORT */
3678 emlxs_mem_buf_free(hba
, mp
);
3679 kmem_free(mbq
, sizeof (MAILBOXQ
));
3682 } /* emlxs_dump_saturn_log() */
3686 emlxs_dump_tigershark_log(
3688 emlxs_file_t
*fpTxtFile
,
3689 emlxs_file_t
*fpCeeFile
)
3691 emlxs_port_t
*port
= &PPORT
;
3696 uint32_t buffer_size
;
3697 uint8_t *buffer
= NULL
;
3700 MAILBOXQ
*mbq
= NULL
;
3701 MAILBOX4
*mb
= NULL
;
3702 MATCHMAP
*mp
= NULL
;
3703 IOCTL_COMMON_MANAGE_FAT
*fat
;
3704 mbox_req_hdr_t
*hdr_req
;
3706 if ((hba
->model_info
.chip
!= EMLXS_BE2_CHIP
) &&
3707 (hba
->model_info
.chip
!= EMLXS_BE3_CHIP
)) {
3711 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3714 mbq
= (MAILBOXQ
*)kmem_zalloc(sizeof (MAILBOXQ
),
3717 mb
= (MAILBOX4
*)mbq
;
3719 if ((mp
= emlxs_mem_buf_alloc(hba
, (sizeof (mbox_req_hdr_t
) +
3720 sizeof (IOCTL_COMMON_MANAGE_FAT
) + BE_MAX_XFER_SIZE
))) == NULL
) {
3721 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3722 "Unable to allocate FAT buffer.");
3729 mb
->un
.varSLIConfig
.be
.embedded
= 0;
3730 mbq
->nonembed
= (void *)mp
;
3731 mbq
->mbox_cmpl
= NULL
;
3733 mb
->mbxCommand
= MBX_SLI_CONFIG
;
3734 mb
->mbxOwner
= OWN_HOST
;
3736 hdr_req
= (mbox_req_hdr_t
*)mp
->virt
;
3737 hdr_req
->subsystem
= IOCTL_SUBSYSTEM_COMMON
;
3738 hdr_req
->opcode
= COMMON_OPCODE_MANAGE_FAT
;
3739 hdr_req
->timeout
= 0;
3740 hdr_req
->req_length
= sizeof (IOCTL_COMMON_MANAGE_FAT
);
3742 fat
= (IOCTL_COMMON_MANAGE_FAT
*)(hdr_req
+ 1);
3743 fat
->params
.request
.fat_operation
= QUERY_FAT
;
3744 fat
->params
.request
.read_log_offset
= 0;
3745 fat
->params
.request
.read_log_length
= 0;
3746 fat
->params
.request
.data_buffer_size
= BE_MAX_XFER_SIZE
;
3748 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
3750 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3751 "FAT Query failed. status=%x",
3758 log_size
= fat
->params
.response
.log_size
;
3759 buffer_size
= fat
->params
.response
.log_size
;
3761 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3762 "FAT: log_size=%d", log_size
);
3764 if (buffer_size
== 0) {
3768 if ((buffer
= kmem_alloc(buffer_size
, KM_NOSLEEP
)) == NULL
) {
3769 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3770 "Unable to allocate log buffer.");
3775 bzero(buffer
, buffer_size
);
3781 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3782 "Uploading log... (%d bytes)", log_size
);
3785 bzero((void *) mb
, MAILBOX_CMD_SLI4_BSIZE
);
3786 bzero((void *) mp
->virt
, mp
->size
);
3788 xfer_size
= min(BE_MAX_XFER_SIZE
, log_size
);
3790 mb
->un
.varSLIConfig
.be
.embedded
= 0;
3791 mbq
->nonembed
= (void *)mp
;
3792 mbq
->mbox_cmpl
= NULL
;
3794 mb
->mbxCommand
= MBX_SLI_CONFIG
;
3795 mb
->mbxOwner
= OWN_HOST
;
3797 hdr_req
= (mbox_req_hdr_t
*)mp
->virt
;
3798 hdr_req
->subsystem
= IOCTL_SUBSYSTEM_COMMON
;
3799 hdr_req
->opcode
= COMMON_OPCODE_MANAGE_FAT
;
3800 hdr_req
->timeout
= 0;
3801 hdr_req
->req_length
=
3802 sizeof (IOCTL_COMMON_MANAGE_FAT
) + xfer_size
;
3804 fat
= (IOCTL_COMMON_MANAGE_FAT
*)(hdr_req
+ 1);
3805 fat
->params
.request
.fat_operation
= RETRIEVE_FAT
;
3806 fat
->params
.request
.read_log_offset
= offset
;
3807 fat
->params
.request
.read_log_length
= xfer_size
;
3808 fat
->params
.request
.data_buffer_size
= BE_MAX_XFER_SIZE
;
3810 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba
, mbq
, MBX_WAIT
, 0) !=
3812 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3813 "Failed to upload log. status=%x",
3816 (void) emlxs_dump_string_txtfile(fpTxtFile
,
3817 NV_LOG_NOT_INCLUDED_IN_FAT
,
3818 LEGEND_NON_VOLATILE_LOG
,
3819 LEGEND_NV_LOG_STATUS_ERROR
, 0);
3825 payload
= (uint8_t *)(&fat
->params
.response
.data_buffer
);
3827 BE_SWAP32_BCOPY(payload
, bptr
, xfer_size
);
3829 log_size
-= xfer_size
;
3830 offset
+= xfer_size
;
3834 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3835 "Log upload complete.");
3837 /* Write a string to text file to direct the user to the CEE */
3838 /* file for the actual log. */
3840 emlxs_dump_string_txtfile(fpTxtFile
, NV_LOG_INCLUDED_IN_FAT
,
3841 LEGEND_NON_VOLATILE_LOG
, LEGEND_NULL
, 0);
3844 /* Write the log to the CEE file. */
3845 /* First word is the log size */
3846 bptr
= buffer
+ sizeof (uint32_t);
3847 log_size
= buffer_size
- sizeof (uint32_t);
3848 rval
= emlxs_dump_word_dmpfile(fpCeeFile
, (uint8_t *)bptr
,
3854 emlxs_mem_put(hba
, MEM_MBOX
, (void *)mbq
);
3858 emlxs_mem_buf_free(hba
, mp
);
3862 kmem_free(buffer
, buffer_size
);
3866 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3872 } /* emlxs_dump_tigershark_log() */
3876 emlxs_dump_user_event(
3879 emlxs_port_t
*port
= &PPORT
;
3881 emlxs_file_t
*fpTxtFile
;
3882 emlxs_file_t
*fpDmpFile
;
3883 emlxs_file_t
*fpCeeFile
;
3885 mutex_enter(&EMLXS_DUMP_LOCK
);
3887 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3888 "User Event: Firmware core dump initiated...");
3891 emlxs_dump_file_create(hba
, &fpTxtFile
, &fpDmpFile
, &fpCeeFile
);
3893 mutex_exit(&EMLXS_DUMP_LOCK
);
3897 (void) emlxs_dump_rev_info(hba
, fpTxtFile
, fpDmpFile
);
3898 (void) emlxs_dump_hba_info(hba
, fpTxtFile
, fpDmpFile
, DUMP_TYPE_USER
);
3899 (void) emlxs_dump_parm_table(hba
, fpTxtFile
, fpDmpFile
);
3900 (void) emlxs_dump_cfg_regions(hba
, fpTxtFile
, fpDmpFile
);
3902 if (hba
->model_info
.chip
== EMLXS_SATURN_CHIP
) {
3903 (void) emlxs_set_hba_mode(hba
, DDI_ONDI
);
3904 (void) emlxs_dump_saturn_log(hba
, fpTxtFile
, fpDmpFile
);
3907 if ((hba
->model_info
.chip
== EMLXS_BE2_CHIP
) ||
3908 (hba
->model_info
.chip
== EMLXS_BE3_CHIP
)) {
3909 (void) emlxs_dump_tigershark_log(hba
, fpTxtFile
, fpCeeFile
);
3912 if (hba
->sli_mode
<= EMLXS_HBA_SLI3_MODE
) {
3913 (void) emlxs_set_hba_mode(hba
, DDI_DIAGDI
);
3916 (void) emlxs_dump_sli_interface(hba
, fpTxtFile
, fpDmpFile
,
3919 if (hba
->sli_mode
<= EMLXS_HBA_SLI3_MODE
) {
3920 (void) emlxs_set_hba_mode(hba
, DDI_WARMDI
);
3923 (void) emlxs_dump_hba(hba
, fpTxtFile
, fpDmpFile
);
3925 (void) emlxs_set_hba_mode(hba
, DDI_ONDI
);
3927 status
= emlxs_menlo_set_mode(hba
, MENLO_MAINTENANCE_MODE_ENABLE
);
3929 (void) emlxs_dump_menlo_log(hba
, fpCeeFile
);
3930 (void) emlxs_menlo_set_mode(hba
,
3931 MENLO_MAINTENANCE_MODE_DISABLE
);
3934 (void) emlxs_dump_file_terminate(hba
, fpTxtFile
, fpDmpFile
, fpCeeFile
);
3935 (void) emlxs_dump_file_close(fpTxtFile
, fpDmpFile
, fpCeeFile
);
3937 mutex_exit(&EMLXS_DUMP_LOCK
);
3940 } /* emlxs_dump_user_event() */
3944 emlxs_dump_temp_event(
3949 emlxs_port_t
*port
= &PPORT
;
3951 emlxs_file_t
*fpTxtFile
;
3954 char sBuf1
[512]; /* general purpose string buffer */
3955 char sBuf2
[256]; /* general purpose string buffer */
3956 char sBuf3
[256]; /* general purpose string buffer */
3958 if (hba
->sli_mode
== EMLXS_HBA_SLI4_MODE
) {
3959 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3960 "Temperature Event: type=%d temp=%d. "\
3961 "Invalid SLI4 event.",
3967 mutex_enter(&EMLXS_DUMP_LOCK
);
3969 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
3970 "Temperature Event: type=%d temp=%d. "\
3971 "Firmware core dump initiated...",
3974 status
= emlxs_dump_file_create(hba
, &fpTxtFile
, 0, 0);
3976 mutex_exit(&EMLXS_DUMP_LOCK
);
3980 /* Now generate the Dump */
3981 /* Note: ignore return (status); if one part fails, */
3982 /* keep trying to dump more stuff. */
3984 /* Write a warning at the top of the file */
3985 (void) strlcpy(sBuf1
, "WARNING: HBA Temperature Event:\n",
3988 case TEMP_TYPE_CRITICAL
:
3989 (void) snprintf(sBuf2
, sizeof (sBuf2
),
3990 " Event Type = %d (Critical)\n", tempType
);
3992 case TEMP_TYPE_THRESHOLD
:
3993 (void) snprintf(sBuf2
, sizeof (sBuf2
),
3994 " Event Type = %d (Threshold)\n", tempType
);
3996 case TEMP_TYPE_NORMAL
:
3997 (void) snprintf(sBuf2
, sizeof (sBuf2
),
3998 " Event Type = %d (Normal)\n", tempType
);
4001 (void) snprintf(sBuf2
, sizeof (sBuf2
),
4002 " Unknown Event Type = %d\n", tempType
);
4005 (void) snprintf(sBuf3
, sizeof (sBuf3
), " Temperature = %d\n\n", temp
);
4006 (void) strlcat(sBuf1
, sBuf2
, sizeof (sBuf1
));
4007 (void) strlcat(sBuf1
, sBuf3
, sizeof (sBuf1
));
4009 (void) emlxs_dump_string_txtfile(fpTxtFile
, sBuf1
, 0, 0, 0);
4011 (void) emlxs_dump_rev_info(hba
, fpTxtFile
, NULL
);
4012 (void) emlxs_dump_hba_info(hba
, fpTxtFile
, NULL
, DUMP_TYPE_TEMP
);
4014 (void) emlxs_dump_file_terminate(hba
, fpTxtFile
, NULL
, NULL
);
4015 (void) emlxs_dump_file_close(fpTxtFile
, NULL
, NULL
);
4017 mutex_exit(&EMLXS_DUMP_LOCK
);
4020 } /* emlxs_dump_temp_event() */
4024 emlxs_dump_drv_event(
4027 emlxs_port_t
*port
= &PPORT
;
4029 emlxs_file_t
*fpTxtFile
;
4030 emlxs_file_t
*fpDmpFile
;
4031 emlxs_file_t
*fpCeeFile
;
4033 mutex_enter(&EMLXS_DUMP_LOCK
);
4035 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
4036 "Dump Event: Firmware core dump initiated...");
4039 emlxs_dump_file_create(hba
, &fpTxtFile
, &fpDmpFile
, &fpCeeFile
);
4041 mutex_exit(&EMLXS_DUMP_LOCK
);
4045 if (hba
->model_info
.chip
== EMLXS_SATURN_CHIP
) {
4046 (void) emlxs_set_hba_mode(hba
, DDI_ONDI
);
4047 (void) emlxs_dump_saturn_log(hba
, fpTxtFile
, fpDmpFile
);
4050 if ((hba
->model_info
.chip
== EMLXS_BE2_CHIP
) ||
4051 (hba
->model_info
.chip
== EMLXS_BE3_CHIP
)) {
4052 (void) emlxs_dump_tigershark_log(hba
, fpTxtFile
, fpCeeFile
);
4055 if (hba
->sli_mode
<= EMLXS_HBA_SLI3_MODE
) {
4056 (void) emlxs_set_hba_mode(hba
, DDI_DIAGDI
);
4059 (void) emlxs_dump_sli_interface(hba
, fpTxtFile
, fpDmpFile
,
4062 if (hba
->sli_mode
<= EMLXS_HBA_SLI3_MODE
) {
4063 (void) emlxs_set_hba_mode(hba
, DDI_WARMDI
);
4066 (void) emlxs_dump_hba(hba
, fpTxtFile
, fpDmpFile
);
4068 if (hba
->sli_mode
<= EMLXS_HBA_SLI3_MODE
) {
4069 (void) emlxs_set_hba_mode(hba
, DDI_ONDI
);
4072 status
= emlxs_menlo_set_mode(hba
, MENLO_MAINTENANCE_MODE_ENABLE
);
4074 (void) emlxs_dump_menlo_log(hba
, fpCeeFile
);
4077 /* Now generate the rest of the Dump */
4078 (void) emlxs_dump_rev_info(hba
, fpTxtFile
, fpDmpFile
);
4079 (void) emlxs_dump_hba_info(hba
, fpTxtFile
, fpDmpFile
, DUMP_TYPE_DRIVER
);
4080 (void) emlxs_dump_parm_table(hba
, fpTxtFile
, fpDmpFile
);
4081 (void) emlxs_dump_cfg_regions(hba
, fpTxtFile
, fpDmpFile
);
4083 (void) emlxs_dump_file_terminate(hba
, fpTxtFile
, fpDmpFile
, fpCeeFile
);
4084 (void) emlxs_dump_file_close(fpTxtFile
, fpDmpFile
, fpCeeFile
);
4086 /* The last step of the Menlo Dump. */
4087 (void) emlxs_menlo_reset(hba
, MENLO_FW_OPERATIONAL
);
4089 (void) emlxs_set_hba_mode(hba
, DDI_WARMDI
);
4091 mutex_exit(&EMLXS_DUMP_LOCK
);
4096 } /* emlxs_dump_drv_event() */
4101 emlxs_dump_drv_thread(emlxs_hba_t
*hba
,
4102 void *arg1
, void *arg2
)
4104 (void) emlxs_dump_drv_event(hba
);
4106 /* Clear the Dump flag */
4107 mutex_enter(&EMLXS_PORT_LOCK
);
4108 hba
->flag
&= ~FC_DUMP_ACTIVE
;
4109 mutex_exit(&EMLXS_PORT_LOCK
);
4113 } /* emlxs_dump_drv_thread() */
4118 emlxs_dump_user_thread(emlxs_hba_t
*hba
,
4119 void *arg1
, void *arg2
)
4121 (void) emlxs_dump_user_event(hba
);
4123 /* Clear the Dump flag */
4124 mutex_enter(&EMLXS_PORT_LOCK
);
4125 hba
->flag
&= ~FC_DUMP_ACTIVE
;
4126 mutex_exit(&EMLXS_PORT_LOCK
);
4130 } /* emlxs_dump_user_thread() */
4135 emlxs_dump_temp_thread(emlxs_hba_t
*hba
,
4136 void *arg1
, void *arg2
)
4138 dump_temp_event_t
*temp_event
= (dump_temp_event_t
*)arg1
;
4140 (void) emlxs_dump_temp_event(temp_event
->hba
, temp_event
->type
,
4143 /* Free the temp event object */
4144 kmem_free(temp_event
, sizeof (dump_temp_event_t
));
4146 /* Clear the Dump flag */
4147 mutex_enter(&EMLXS_PORT_LOCK
);
4148 hba
->flag
&= ~FC_DUMP_ACTIVE
;
4149 mutex_exit(&EMLXS_PORT_LOCK
);
4153 } /* emlxs_dump_temp_thread() */
4156 /* Schedules a dump thread */
4157 /* temp_type and temp are only valid for type=EMLXS_TEMP_DUMP */
4159 emlxs_dump(emlxs_hba_t
*hba
, uint32_t type
, uint32_t temp_type
, uint32_t temp
)
4161 emlxs_port_t
*port
= &PPORT
;
4162 dump_temp_event_t
*temp_event
= NULL
;
4164 mutex_enter(&EMLXS_PORT_LOCK
);
4166 /* Check if it is safe to dump */
4167 if (!(hba
->flag
& FC_DUMP_SAFE
)) {
4168 mutex_exit(&EMLXS_PORT_LOCK
);
4170 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
4171 "dump: Dump disabled.");
4176 /* Check if a dump is already in progess */
4177 if (hba
->flag
& FC_DUMP_ACTIVE
) {
4178 mutex_exit(&EMLXS_PORT_LOCK
);
4180 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
4181 "dump: Dump already in progress.");
4186 /* Prepare to schedule dump */
4188 case EMLXS_DRV_DUMP
:
4189 case EMLXS_USER_DUMP
:
4192 case EMLXS_TEMP_DUMP
:
4193 temp_event
= (dump_temp_event_t
*)kmem_alloc(
4194 sizeof (dump_temp_event_t
), KM_NOSLEEP
);
4196 if (temp_event
== NULL
) {
4197 mutex_exit(&EMLXS_PORT_LOCK
);
4199 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
4200 "dump: Unable to allocate temp object.");
4205 temp_event
->hba
= hba
;
4206 temp_event
->type
= temp_type
;
4207 temp_event
->temp
= temp
;
4211 mutex_exit(&EMLXS_PORT_LOCK
);
4213 EMLXS_MSGF(EMLXS_CONTEXT
, &emlxs_fw_dump_msg
,
4214 "dump: Error: Unknown dump type. (%x)",
4220 /* Set the Dump-in-progess flag */
4221 hba
->flag
|= FC_DUMP_ACTIVE
;
4222 mutex_exit(&EMLXS_PORT_LOCK
);
4224 /* Create a separate thread to run the dump event */
4226 case EMLXS_DRV_DUMP
:
4227 emlxs_thread_spawn(hba
, emlxs_dump_drv_thread
, NULL
, NULL
);
4230 case EMLXS_TEMP_DUMP
:
4231 emlxs_thread_spawn(hba
, emlxs_dump_temp_thread
,
4232 (void *)temp_event
, NULL
);
4235 case EMLXS_USER_DUMP
:
4236 emlxs_thread_spawn(hba
, emlxs_dump_user_thread
, NULL
, NULL
);
4242 } /* emlxs_dump() */
4245 emlxs_dump_wait(emlxs_hba_t
*hba
)
4247 /* Wait for the Dump flag to clear */
4248 while ((hba
->flag
& FC_DUMP_ACTIVE
)) {
4252 } /* emlxs_dump_wait() */
4255 #endif /* DUMP_SUPPORT */