Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / fibre-channel / fca / emlxs / emlxs_dump.c
blobf2870cc835fb05f80b0ef2f2ae08b105fab39110
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright (c) 2004-2012 Emulex. All rights reserved.
24 * Use is subject to license terms.
27 #include <emlxs.h>
29 #ifdef DUMP_SUPPORT
31 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
32 EMLXS_MSG_DEF(EMLXS_DUMP_C);
34 /* ************************************************************************* */
35 /* Utility functions */
36 /* ************************************************************************* */
38 static uint32_t
39 emlxs_menlo_set_mode(
40 emlxs_hba_t *hba,
41 uint32_t mode)
43 emlxs_port_t *port = &PPORT;
44 uint32_t cmd_size;
45 uint32_t rsp_size;
46 menlo_cmd_t *cmd_buf = NULL;
47 menlo_rsp_t *rsp_buf = NULL;
48 uint32_t rval = 0;
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);
57 rsp_size = 4;
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.");
72 goto done;
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",
81 rsp_buf->code);
84 rval = rsp_buf->code;
86 done:
88 if (cmd_buf) {
89 kmem_free(cmd_buf, sizeof (menlo_set_cmd_t));
92 if (rsp_buf) {
93 kmem_free(rsp_buf, 4);
96 return (rval);
98 } /* emlxs_menlo_set_mode() */
101 static uint32_t
102 emlxs_menlo_reset(
103 emlxs_hba_t *hba,
104 uint32_t firmware)
106 emlxs_port_t *port = &PPORT;
107 uint32_t cmd_size;
108 uint32_t rsp_size;
109 menlo_cmd_t *cmd_buf = NULL;
110 menlo_rsp_t *rsp_buf = NULL;
111 uint32_t rval = 0;
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);
120 rsp_size = 4;
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.");
134 goto done;
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",
143 rsp_buf->code);
146 rval = rsp_buf->code;
148 done:
150 if (cmd_buf) {
151 kmem_free(cmd_buf, sizeof (menlo_reset_cmd_t));
154 if (rsp_buf) {
155 kmem_free(rsp_buf, 4);
158 return (rval);
160 } /* emlxs_menlo_reset() */
163 static uint32_t
164 emlxs_menlo_get_cfg(
165 emlxs_hba_t *hba,
166 menlo_get_config_rsp_t *rsp_buf,
167 uint32_t rsp_size)
169 emlxs_port_t *port = &PPORT;
170 uint32_t cmd_size;
171 menlo_cmd_t *cmd_buf = NULL;
172 uint32_t rval = 0;
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.");
195 goto done;
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",
204 rsp_buf->code);
207 rval = rsp_buf->code;
209 done:
211 if (cmd_buf) {
212 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
215 return (rval);
217 } /* emlxs_menlo_get_cfg() */
221 static uint32_t
222 emlxs_menlo_get_logcfg(
223 emlxs_hba_t *hba,
224 menlo_rsp_t *rsp_buf,
225 uint32_t rsp_size)
227 emlxs_port_t *port = &PPORT;
228 uint32_t cmd_size;
229 menlo_cmd_t *cmd_buf = NULL;
230 uint32_t rval = 0;
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.");
251 goto done;
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",
260 rsp_buf->code);
263 rval = rsp_buf->code;
265 done:
267 if (cmd_buf) {
268 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
271 return (rval);
273 } /* emlxs_menlo_get_logcfg() */
276 static uint32_t
277 emlxs_menlo_get_log(
278 emlxs_hba_t *hba,
279 uint32_t id,
280 menlo_rsp_t *rsp_buf,
281 uint32_t rsp_size)
283 emlxs_port_t *port = &PPORT;
284 uint32_t cmd_size;
285 menlo_cmd_t *cmd_buf = NULL;
286 uint32_t rval = 0;
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.");
307 goto done;
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",
316 rsp_buf->code);
319 rval = rsp_buf->code;
321 done:
323 if (cmd_buf) {
324 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
327 return (rval);
329 } /* emlxs_menlo_get_log() */
332 static uint32_t
333 emlxs_menlo_get_paniclog(
334 emlxs_hba_t *hba,
335 menlo_rsp_t *rsp_buf,
336 uint32_t rsp_size)
338 emlxs_port_t *port = &PPORT;
339 uint32_t cmd_size;
340 menlo_cmd_t *cmd_buf = NULL;
341 uint32_t rval = 0;
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.");
362 goto done;
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",
371 rsp_buf->code);
374 rval = rsp_buf->code;
376 done:
378 if (cmd_buf) {
379 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
382 return (rval);
384 } /* emlxs_menlo_get_paniclog() */
389 extern void
390 emlxs_fflush(
391 emlxs_file_t *fp)
393 uint32_t offset;
395 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
397 if (offset > fp->size) {
398 fp->ptr = fp->buffer + fp->size;
401 return;
403 } /* emlxs_fflush() */
406 extern uint32_t
407 emlxs_ftell(
408 emlxs_file_t *fp)
410 uint32_t offset;
412 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
414 return (offset);
416 } /* emlxs_ftell() */
419 static void
420 emlxs_fputc(
421 uint8_t value,
422 emlxs_file_t *fp)
424 uint32_t offset;
426 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
428 if ((offset + 1) <= fp->size) {
429 *fp->ptr++ = value;
432 return;
434 } /* emlxs_fputc() */
437 static uint32_t
438 emlxs_fwrite(
439 uint8_t *buffer,
440 uint32_t size,
441 uint32_t nitems,
442 emlxs_file_t *fp)
444 uint32_t offset;
445 uint32_t length;
447 length = size * nitems;
449 if (length) {
450 offset =
451 (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
453 if ((offset + length) > fp->size) {
454 length = fp->size - offset;
457 if (length) {
458 bcopy(buffer, fp->ptr, length);
459 fp->ptr += length;
463 return (length);
465 } /* emlxs_fwrite() */
468 static uint32_t
469 emlxs_fprintf(
470 emlxs_file_t *fp,
471 const char *fmt, ...)
473 va_list valist;
474 char va_str[1024];
475 uint32_t length;
477 va_start(valist, fmt);
478 (void) vsnprintf(va_str, sizeof (va_str), fmt, valist);
479 va_end(valist);
481 length = emlxs_fwrite((uint8_t *)va_str, strlen(va_str), 1, fp);
483 return (length);
485 } /* emlxs_fprintf() */
488 extern emlxs_file_t *
489 emlxs_fopen(
490 emlxs_hba_t *hba,
491 uint32_t file_type)
493 emlxs_file_t *fp;
495 switch (file_type) {
496 case EMLXS_TXT_FILE:
497 fp = &hba->dump_txtfile;
498 fp->size = EMLXS_TXT_FILE_SIZE;
499 break;
501 case EMLXS_DMP_FILE:
502 fp = &hba->dump_dmpfile;
503 fp->size = EMLXS_DMP_FILE_SIZE;
504 break;
506 case EMLXS_CEE_FILE:
507 fp = &hba->dump_ceefile;
508 fp->size = EMLXS_CEE_FILE_SIZE;
509 break;
511 default:
512 return (NULL);
515 /* Make sure it is word aligned */
516 fp->size &= 0xFFFFFFFC;
518 if (!fp->buffer) {
519 fp->buffer = kmem_zalloc(fp->size, KM_SLEEP);
521 } else {
522 bzero(fp->buffer, fp->size);
525 fp->ptr = fp->buffer;
527 return (fp);
529 } /* emlxs_fopen() */
532 extern uint32_t
533 emlxs_fclose(
534 emlxs_file_t *fp)
536 uint32_t offset;
538 if (fp == NULL) {
539 return (0);
542 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
543 offset = offset % 4;
545 switch (offset) {
546 case 0:
547 break;
549 case 1:
550 *fp->ptr++ = 0;
551 *fp->ptr++ = 0;
552 *fp->ptr++ = 0;
553 break;
555 case 2:
556 *fp->ptr++ = 0;
557 *fp->ptr++ = 0;
558 break;
560 case 3:
561 *fp->ptr++ = 0;
562 break;
565 return (0);
567 } /* emlxs_fclose() */
570 static void
571 emlxs_fdelete(
572 emlxs_file_t *fp)
574 if (fp == NULL) {
575 return;
578 if (fp->buffer && fp->size) {
579 kmem_free(fp->buffer, fp->size);
582 fp->buffer = NULL;
583 fp->ptr = NULL;
584 fp->size = 0;
586 return;
588 } /* emlxs_fdelete() */
591 /* This builds a single core buffer for the IOCTL interface */
592 extern uint32_t
593 emlxs_get_dump(
594 emlxs_hba_t *hba,
595 uint8_t *buffer,
596 uint32_t *buflen)
598 emlxs_port_t *port = &PPORT;
599 int32_t i;
600 int32_t size;
601 int32_t count;
602 uint32_t size_dmp;
603 uint32_t size_txt;
604 uint32_t size_cee;
605 emlxs_file_t *fp_txt;
606 emlxs_file_t *fp_dmp;
607 emlxs_file_t *fp_cee;
608 uint32_t *wptr;
609 uint8_t *bptr;
611 if (!buflen) {
612 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
613 "get_dump: Buffer length = 0");
614 return (1);
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);
625 size = 0;
626 count = 0;
627 if (size_txt) {
628 count++;
629 size += size_txt + 8;
631 if (size_dmp) {
632 count++;
633 size += size_dmp + 8;
635 if (size_cee) {
636 count++;
637 size += size_cee + 8;
640 if (size) {
641 size += 4;
644 if (!buffer) {
645 goto done;
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",
653 *buflen, size);
655 *buflen = 0;
656 return (1);
659 wptr = (uint32_t *)buffer;
660 wptr[0] = count;
661 i = 1;
663 if (size_txt) {
664 wptr[i++] = EMLXS_TXT_FILE_ID;
665 wptr[i++] = size_txt;
668 if (size_dmp) {
669 wptr[i++] = EMLXS_DMP_FILE_ID;
670 wptr[i++] = size_dmp;
673 if (size_cee) {
674 if ((hba->model_info.chip == EMLXS_BE2_CHIP) ||
675 (hba->model_info.chip == EMLXS_BE3_CHIP)) {
676 wptr[i++] = EMLXS_FAT_FILE_ID;
677 } else {
678 wptr[i++] = EMLXS_CEE_FILE_ID;
681 wptr[i++] = size_cee;
684 bptr = (uint8_t *)&wptr[i];
686 if (size_txt) {
687 bcopy(fp_txt->buffer, bptr, size_txt);
688 bptr += size_txt;
691 if (size_dmp) {
692 bcopy(fp_dmp->buffer, bptr, size_dmp);
693 bptr += size_dmp;
696 if (size_cee) {
697 bcopy(fp_cee->buffer, bptr, size_cee);
698 bptr += size_cee;
701 done:
703 *buflen = size;
705 /* printf("Done. buflen=%d \n", *buflen); */
707 return (0);
709 } /* emlxs_get_dump() */
712 static uint32_t
713 emlxs_read_cfg_region(
714 emlxs_hba_t *hba,
715 uint32_t Identifier,
716 uint32_t ByteCount,
717 uint32_t *pRetByteCount,
718 uint8_t *pBuffer)
720 emlxs_port_t *port = &PPORT;
721 MAILBOXQ *mbq;
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 */
728 if (! ByteCount) {
729 return (0);
732 mbq =
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 */
738 CopyCount = 0;
740 for (ByteCountRem = ByteCount; ByteCountRem > 0;
741 ByteCountRem -= CopyCount) {
743 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
744 MAILBOX4 *mb = (MAILBOX4 *)mbq;
746 ByteCountReq =
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) !=
772 MBX_SUCCESS) {
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));
779 return (1);
782 CopyCount = mb->un.varDmp4.rsp_cnt;
784 /* if no more data returned */
785 if (CopyCount == 0) {
786 break;
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);
801 } else {
802 MAILBOX *mb = (MAILBOX *)mbq;
804 ByteCountReq =
805 (ByteCountRem < DUMP_BC_MAX) ? ByteCountRem :
806 DUMP_BC_MAX;
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) !=
820 MBX_SUCCESS) {
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));
827 return (1);
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) {
836 break;
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,
849 CopyCount);
852 pLocalBuf += CopyCount;
853 Offset += CopyCount;
854 *pRetByteCount += CopyCount;
857 return (0);
859 } /* emlxs_read_cfg_region() */
863 /* ************************************************************************* */
864 /* ************************************************************************* */
865 /* Dump Generators, Low-Level */
866 /* ************************************************************************* */
867 /* ************************************************************************* */
869 static uint32_t
870 emlxs_dump_string_txtfile(
871 emlxs_file_t *fpTxtFile,
872 char *pString,
873 char *pSidLegend,
874 char *pLidLegend,
875 uint32_t pure)
878 if (!fpTxtFile) {
879 return (1);
882 if (pSidLegend && pLidLegend) {
883 (void) emlxs_fprintf(fpTxtFile, "%s: %s\n", pSidLegend,
884 pLidLegend);
886 if (pure == 0) {
887 emlxs_fputc(' ', fpTxtFile);
890 (void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1,
891 fpTxtFile);
893 if (pure == 0) {
894 emlxs_fputc('\n', fpTxtFile);
895 emlxs_fputc('\n', fpTxtFile);
897 } else {
898 if (pure == 0) {
899 emlxs_fputc(' ', fpTxtFile);
901 (void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1,
902 fpTxtFile);
905 emlxs_fflush(fpTxtFile);
907 return (0);
909 } /* emlxs_dump_string_txtfile() */
912 static uint32_t
913 emlxs_dump_word_txtfile(
914 emlxs_file_t *fpTxtFile,
915 uint32_t *pBuffer,
916 uint32_t WordCount,
917 char *pSidLegend,
918 char *pLidLegend)
920 char buf1[256];
921 char buf2[256];
922 uint32_t *ptr;
923 uint32_t j;
925 if (!fpTxtFile) {
926 return (1);
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 */
933 ptr = pBuffer;
935 for (j = 0; j < WordCount; j++) {
936 buf1[0] = 0;
937 buf2[0] = 0;
939 if ((j & 0x03) == 0) {
940 (void) snprintf(buf1, sizeof (buf1), "\n%04x:", j * 4);
941 (void) strlcat(buf2, buf1, sizeof (buf2));
943 /* print 1 word */
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,
947 fpTxtFile);
950 emlxs_fputc('\n', fpTxtFile);
951 emlxs_fputc('\n', fpTxtFile);
952 emlxs_fflush(fpTxtFile);
953 return (0);
955 } /* emlxs_dump_word_txtfile() */
960 static uint32_t
961 emlxs_dump_string_dmpfile(
962 emlxs_file_t *fpDmpFile,
963 char *pString,
964 uint8_t sid,
965 char *pSidLegend,
966 char *pLidLegend)
968 uint32_t length;
969 uint8_t byte;
970 uint32_t pos;
972 if (!fpDmpFile) {
973 return (1);
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) {
1019 case 0:
1020 break;
1021 case 1:
1022 emlxs_fputc(0, fpDmpFile);
1023 emlxs_fputc(0, fpDmpFile);
1024 emlxs_fputc(0, fpDmpFile);
1025 break;
1026 case 2:
1027 emlxs_fputc(0, fpDmpFile);
1028 emlxs_fputc(0, fpDmpFile);
1029 break;
1030 case 3:
1031 emlxs_fputc(0, fpDmpFile);
1032 break;
1034 emlxs_fflush(fpDmpFile);
1035 #endif
1037 return (0);
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 /* ************************************************************************* */
1055 /*ARGSUSED*/
1056 extern uint32_t
1057 emlxs_dump_word_dmpfile(
1058 emlxs_file_t *fpDmpFile,
1059 uint8_t *pBuffer,
1060 uint32_t bufferLen,
1061 int fSwap)
1063 uint32_t i;
1064 uint32_t *wptr;
1066 if (!fpDmpFile) {
1067 return (1);
1070 wptr = (uint32_t *)pBuffer;
1071 for (i = 0; i < bufferLen / 4; i++, wptr++) {
1072 if (fSwap) {
1073 uint32_t w1;
1074 w1 = *wptr;
1075 *wptr = BE_SWAP32(w1);
1078 (void) emlxs_fwrite((uint8_t *)wptr, 4, 1, fpDmpFile);
1081 emlxs_fflush(fpDmpFile);
1083 return (0);
1085 } /* emlxs_dump_word_dmpfile() */
1088 static uint32_t
1089 emlxs_dump_port_block(
1090 emlxs_file_t *fpDmpFile,
1091 uint8_t *pBuffer,
1092 uint32_t bufferLen,
1093 DUMP_TABLE_ENTRY entry,
1094 int fSwap)
1096 uint32_t status;
1097 uint32_t w;
1098 uint8_t b;
1100 if (!fpDmpFile) {
1101 return (1);
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 */
1152 status =
1153 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
1155 emlxs_fflush(fpDmpFile);
1157 return (status);
1159 } /* emlxs_dump_port_block() */
1162 static uint32_t
1163 emlxs_dump_port_struct(
1164 emlxs_file_t *fpDmpFile,
1165 uint8_t *pBuffer,
1166 uint32_t bufferLen,
1167 DUMP_TABLE_ENTRY entry,
1168 int fSwap)
1170 uint32_t status;
1171 uint32_t w;
1172 uint8_t b;
1174 if (!fpDmpFile) {
1175 return (1);
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 */
1226 status =
1227 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
1229 emlxs_fflush(fpDmpFile);
1231 return (status);
1233 } /* emlxs_dump_port_struct() */
1236 static uint32_t
1237 emlxs_dump_host_block(
1238 emlxs_file_t *fpDmpFile,
1239 uint8_t *pBuffer,
1240 uint32_t bufferLen,
1241 uint8_t sid,
1242 char *pSidLegend,
1243 char *pLidLegend,
1244 int fSwap)
1246 uint32_t status;
1247 uint32_t length;
1248 uint8_t byte;
1250 if (!fpDmpFile) {
1251 return (1);
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 */
1268 length = bufferLen;
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 */
1287 status =
1288 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
1290 emlxs_fflush(fpDmpFile);
1292 return (status);
1294 } /* emlxs_dump_host_block() */
1297 static uint32_t
1298 emlxs_dump_host_struct(
1299 emlxs_file_t *fpDmpFile,
1300 uint8_t *pBuffer,
1301 uint32_t bufferLen,
1302 uint32_t elementLength,
1303 uint32_t elementCount,
1304 uint8_t sid,
1305 char *pSidLegend,
1306 char *pLidLegend,
1307 int fSwap)
1309 uint32_t status;
1310 uint32_t w;
1311 uint8_t b;
1313 if (!fpDmpFile) {
1314 return (1);
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 */
1335 w = elementCount;
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 */
1350 status =
1351 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
1353 emlxs_fflush(fpDmpFile);
1355 return (status);
1357 } /* emlxs_dump_host_struct() */
1360 /* ************************************************************************* */
1361 /* ************************************************************************* */
1362 /* Dump Generators, Mid-Level */
1363 /* ************************************************************************* */
1364 /* ************************************************************************* */
1366 static uint32_t
1367 emlxs_dump_parm_table(
1368 emlxs_hba_t *hba,
1369 emlxs_file_t *fpTxtFile,
1370 emlxs_file_t *fpDmpFile)
1372 emlxs_config_t *cfg = &CFG;
1373 uint32_t status;
1374 uint32_t i;
1376 /* vars used to build the Dump String */
1377 char *buf1;
1378 char *buf2;
1380 buf1 = kmem_zalloc(8192, KM_SLEEP);
1381 buf2 = kmem_zalloc(8192, KM_SLEEP);
1383 /* Driver Parameters Heading */
1384 (void) snprintf(buf1, 8192,
1385 "IDX string Low "\
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);
1399 status =
1400 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_DP_TABLE,
1401 LEGEND_NULL, 0);
1403 status =
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);
1410 return (status);
1412 } /* emlxs_dump_parm_table() */
1415 static uint32_t
1416 emlxs_dump_model(
1417 emlxs_hba_t *hba,
1418 emlxs_file_t *fpTxtFile,
1419 emlxs_file_t *fpDmpFile)
1421 emlxs_vpd_t *vpd = &VPD;
1422 uint32_t status;
1424 /* vars used to build the Dump String */
1425 char buf1[512];
1426 char buf2[512];
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));
1438 status =
1439 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
1440 LEGEND_HBA_MODEL, 0);
1442 status =
1443 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
1444 LEGEND_HBA_INFO, LEGEND_HBA_MODEL);
1446 return (status);
1448 } /* emlxs_dump_model() */
1451 static uint32_t
1452 emlxs_dump_wwn(
1453 emlxs_hba_t *hba,
1454 emlxs_file_t *fpTxtFile,
1455 emlxs_file_t *fpDmpFile)
1457 uint32_t status;
1459 /* vars used to build the Dump String */
1460 char buf1[512];
1461 char buf2[512];
1462 int i;
1463 uint8_t *p;
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));
1485 status =
1486 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
1487 LEGEND_HBA_WWN, 0);
1489 status =
1490 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
1491 LEGEND_HBA_INFO, LEGEND_HBA_WWN);
1493 return (status);
1495 } /* emlxs_dump_wwn() */
1498 static uint32_t
1499 emlxs_dump_serial_number(
1500 emlxs_hba_t *hba,
1501 emlxs_file_t *fpTxtFile,
1502 emlxs_file_t *fpDmpFile)
1504 emlxs_vpd_t *vpd = &VPD;
1505 uint32_t status;
1507 /* vars used to build the Dump String */
1508 char buf1[512];
1509 char buf2[512];
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));
1517 status =
1518 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
1519 LEGEND_HBA_SN, 0);
1521 status =
1522 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
1523 LEGEND_HBA_INFO, LEGEND_HBA_SN);
1525 return (status);
1527 } /* emlxs_dump_serial_number() */
1530 static uint32_t
1531 emlxs_dump_fw_version(
1532 emlxs_hba_t *hba,
1533 emlxs_file_t *fpTxtFile,
1534 emlxs_file_t *fpDmpFile)
1536 emlxs_vpd_t *vpd = &VPD;
1537 uint32_t status;
1539 char *buf1;
1540 char *buf2;
1541 uint32_t buf1_size;
1542 uint32_t buf2_size;
1544 buf1_size = 1024;
1545 buf2_size = 1024;
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);
1591 status =
1592 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
1593 LEGEND_HBA_FW_VERSION, 0);
1595 status =
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);
1602 return (status);
1604 } /* emlxs_dump_fw_version() */
1607 static uint32_t
1608 emlxs_dump_boot_version(
1609 emlxs_hba_t *hba,
1610 emlxs_file_t *fpTxtFile,
1611 emlxs_file_t *fpDmpFile)
1613 emlxs_vpd_t *vpd = &VPD;
1614 uint32_t status;
1615 uint32_t state;
1617 char *buf1;
1618 char *buf2;
1619 uint32_t buf1_size;
1620 uint32_t buf2_size;
1622 buf1_size = 1024;
1623 buf2_size = 1024;
1625 buf1 = kmem_zalloc(buf1_size, KM_SLEEP);
1626 buf2 = kmem_zalloc(buf2_size, KM_SLEEP);
1628 #ifdef EMLXS_SPARC
1629 if (strcmp(vpd->fcode_version, "none") == 0)
1630 #else
1631 if (strcmp(vpd->boot_version, "none") == 0)
1632 #endif /* EMLXS_SPARC */
1634 state = 2; /* BOOT_BIOS_NOT_PRESENT */
1635 } else {
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 */
1646 if (state == 2) {
1647 (void) snprintf(buf2, buf2_size, "%s", "unknown");
1648 } else {
1649 #ifdef EMLXS_SPARC
1650 (void) snprintf(buf2, buf2_size, "%s (FCode)",
1651 vpd->fcode_version);
1652 #else
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);
1662 status =
1663 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
1664 LEGEND_HBA_BB_VERSION, 0);
1666 status =
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);
1673 return (status);
1675 } /* emlxs_dump_boot_version() */
1678 /* ARGSUSED */
1679 static uint32_t
1680 emlxs_dump_cfg_region4_decoded(
1681 emlxs_hba_t *hba,
1682 emlxs_file_t *fpTxtFile,
1683 char *pLidLegend,
1684 DUMP_WAKE_UP_PARAMS *pBuffer,
1685 uint32_t ByteCount)
1687 uint32_t status;
1688 char *buf1; /* text buffer */
1689 char *buf2; /* text buffer */
1690 uint32_t buf1_size;
1691 uint32_t buf2_size;
1693 buf1_size = 1024;
1694 buf2_size = 1024;
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,
1707 pBuffer->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",
1718 LEGEND_CR4_SLI1_ID,
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",
1724 LEGEND_CR4_SLI2_ID,
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",
1730 LEGEND_CR4_SLI3_ID,
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",
1736 LEGEND_CR4_SLI4_ID,
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",
1742 LEGEND_CR4_EROM_ID,
1743 pBuffer->EromId[0], pBuffer->EromId[1]);
1744 (void) strlcat(buf1, buf2, buf1_size);
1746 status =
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);
1753 return (status);
1755 } /* emlxs_dump_cfg_region4_decoded() */
1758 /* ARGSUSED */
1759 uint32_t
1760 emlxs_dump_cfg_region14_decoded(
1761 emlxs_hba_t *hba,
1762 emlxs_file_t *fpTxtFile,
1763 char *pLidLegend,
1764 char *pBuffer,
1765 uint32_t ByteCount)
1767 uint32_t status;
1768 char *buf1; /* text buffer */
1769 char *buf2; /* text buffer */
1770 uint32_t buf1_size;
1771 uint32_t buf2_size;
1772 int i;
1773 uint8_t tag;
1774 uint16_t length;
1775 uint16_t length2;
1776 char mnemonic[4];
1777 int fDone = FALSE; /* flag to exit VPD loop */
1779 #ifdef EMLXS_BIG_ENDIAN
1780 uint32_t *wptr;
1781 uint32_t w1;
1782 #endif
1784 buf1_size = 1024;
1785 buf2_size = 1024;
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++) {
1795 w1 = *wptr;
1796 *wptr = BE_SWAP32(w1);
1798 #endif /* EMLXS_BIG_ENDIAN */
1800 /* Decode the VPD Data and write it into the buffer */
1802 /* CR 26941 */
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 */
1817 i = 0;
1818 while (!fDone) {
1819 tag = pBuffer[i++];
1820 length = pBuffer[i++];
1821 length |= (pBuffer[i++] << 8);
1823 switch (tag) {
1824 case VPD_TAG_82:
1825 (void) strncpy(buf2, &pBuffer[i],
1826 length > buf2_size ? buf2_size : length);
1827 buf2[length >
1828 (buf2_size - 1) ? (buf2_size -
1829 1) : length] = 0;
1830 (void) strlcat(buf1, "Name: ", buf1_size);
1831 (void) strlcat(buf1, buf2, buf1_size);
1832 i += length;
1833 break;
1835 case VPD_TAG_90:
1836 for (;;) {
1837 mnemonic[0] = pBuffer[i++];
1838 mnemonic[1] = pBuffer[i++];
1839 mnemonic[2] = 0;
1841 if (strcmp(mnemonic, "RV") == 0) {
1842 fDone = TRUE;
1843 break;
1846 if (mnemonic[0] == 0) {
1847 fDone = TRUE;
1848 break;
1851 length2 = pBuffer[i++];
1852 (void) snprintf(buf2, buf2_size,
1853 "\n %s: ", mnemonic);
1854 (void) strlcat(buf1, buf2,
1855 buf1_size);
1856 (void) strncpy(buf2, &pBuffer[i],
1857 length2 >
1858 buf2_size ? buf2_size : length2);
1859 buf2[length2 >
1860 (buf2_size - 1) ? (buf2_size -
1861 1) : length2] = 0;
1862 (void) strlcat(buf1, buf2,
1863 buf1_size);
1864 i += length2;
1866 break;
1868 default:
1869 break;
1871 } /* end switch */
1873 } /* end while */
1875 } /* good data */
1877 status =
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);
1884 return (status);
1886 } /* emlxs_dump_cfg_region14_decoded() */
1889 static uint32_t
1890 emlxs_dump_cfg_region(
1891 emlxs_hba_t *hba,
1892 emlxs_file_t *fpTxtFile,
1893 emlxs_file_t *fpDmpFile,
1894 uint8_t Region,
1895 char *pLidLegend,
1896 int fSwap)
1898 uint32_t status;
1899 uint32_t RetByteCount = 0; /* returned byte count */
1900 char *buf1; /* string ops buffer */
1901 char *buf2; /* string ops buffer */
1902 uint32_t buf1_size;
1903 uint32_t buf2_size;
1904 uint32_t *buffer;
1905 int i;
1907 #ifdef EMLXS_LITTLE_ENDIAN
1908 fSwap = FALSE;
1909 #endif /* EMLXS_LITTLE_ENDIAN */
1911 buf1_size = 4096;
1912 buf2_size = 1024;
1914 buf1 = kmem_zalloc(buf1_size, KM_SLEEP);
1915 buf2 = kmem_zalloc(buf2_size, KM_SLEEP);
1917 buffer =
1918 kmem_zalloc(DUMP_MAX_CONFIG_REGION_LENGTH, KM_SLEEP);
1920 status =
1921 emlxs_read_cfg_region(hba, Region, DUMP_MAX_CONFIG_REGION_LENGTH,
1922 &RetByteCount, (uint8_t *)buffer);
1924 if (status != 0) {
1925 kmem_free(buffer, DUMP_MAX_CONFIG_REGION_LENGTH);
1926 kmem_free(buf1, buf1_size);
1927 kmem_free(buf2, buf2_size);
1928 return (status);
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);
1941 status =
1942 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_CONFIG_REGION,
1943 pLidLegend, 0);
1945 status = emlxs_dump_host_block(fpDmpFile,
1946 (uint8_t *)buffer,
1947 RetByteCount,
1948 SID_CONFIG_REGION, LEGEND_CONFIG_REGION, pLidLegend, fSwap);
1950 if (Region == 4) {
1951 status =
1952 emlxs_dump_cfg_region4_decoded(hba, fpTxtFile, pLidLegend,
1953 (DUMP_WAKE_UP_PARAMS *)buffer, RetByteCount);
1956 if (Region == 14) {
1957 status =
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);
1966 return (status);
1968 } /* emlxs_dump_cfg_region() */
1971 static uint32_t
1972 emlxs_dump_cfg_regions(
1973 emlxs_hba_t *hba,
1974 emlxs_file_t *fpTxtFile,
1975 emlxs_file_t *fpDmpFile)
1977 uint32_t status;
1979 status =
1980 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 0,
1981 LEGEND_CONFIG_REGION_0, FALSE);
1983 status =
1984 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 1,
1985 LEGEND_CONFIG_REGION_1, FALSE);
1987 status =
1988 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 2,
1989 LEGEND_CONFIG_REGION_2, FALSE);
1991 status =
1992 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 3,
1993 LEGEND_CONFIG_REGION_3, FALSE);
1995 status =
1996 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 4,
1997 LEGEND_CONFIG_REGION_4, FALSE);
1999 status =
2000 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 5,
2001 LEGEND_CONFIG_REGION_5, FALSE);
2003 status =
2004 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 6,
2005 LEGEND_CONFIG_REGION_6, FALSE);
2007 status =
2008 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 7,
2009 LEGEND_CONFIG_REGION_7, FALSE);
2011 status =
2012 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 8,
2013 LEGEND_CONFIG_REGION_8, TRUE);
2015 status =
2016 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 9,
2017 LEGEND_CONFIG_REGION_9, TRUE);
2019 status =
2020 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 10,
2021 LEGEND_CONFIG_REGION_10, TRUE);
2023 status =
2024 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 11,
2025 LEGEND_CONFIG_REGION_11, FALSE);
2027 status =
2028 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 12,
2029 LEGEND_CONFIG_REGION_12, FALSE);
2031 status =
2032 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 13,
2033 LEGEND_CONFIG_REGION_13, FALSE);
2035 status =
2036 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 14,
2037 LEGEND_CONFIG_REGION_14, FALSE);
2039 status =
2040 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 15,
2041 LEGEND_CONFIG_REGION_15, FALSE);
2043 status =
2044 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 16,
2045 LEGEND_CONFIG_REGION_16, FALSE);
2047 status =
2048 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 17,
2049 LEGEND_CONFIG_REGION_17, FALSE);
2051 status =
2052 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 18,
2053 LEGEND_CONFIG_REGION_18, FALSE);
2055 status =
2056 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 19,
2057 LEGEND_CONFIG_REGION_19, FALSE);
2059 status =
2060 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 20,
2061 LEGEND_CONFIG_REGION_20, FALSE);
2063 status =
2064 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 21,
2065 LEGEND_CONFIG_REGION_21, FALSE);
2067 status =
2068 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 22,
2069 LEGEND_CONFIG_REGION_22, FALSE);
2071 status =
2072 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 23,
2073 LEGEND_CONFIG_REGION_23, FALSE);
2075 status =
2076 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 24,
2077 LEGEND_CONFIG_REGION_24, FALSE);
2079 status =
2080 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 25,
2081 LEGEND_CONFIG_REGION_25, FALSE);
2083 status =
2084 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 26,
2085 LEGEND_CONFIG_REGION_26, FALSE);
2087 status =
2088 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 27,
2089 LEGEND_CONFIG_REGION_27, FALSE);
2091 status =
2092 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 28,
2093 LEGEND_CONFIG_REGION_28, FALSE);
2095 status =
2096 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 29,
2097 LEGEND_CONFIG_REGION_29, FALSE);
2099 status =
2100 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 30,
2101 LEGEND_CONFIG_REGION_30, FALSE);
2103 status =
2104 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 31,
2105 LEGEND_CONFIG_REGION_31, FALSE);
2107 status =
2108 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 32,
2109 LEGEND_CONFIG_REGION_32, FALSE);
2111 return (status);
2113 } /* emlxs_dump_cfg_regions() */
2116 /*ARGSUSED*/
2117 static uint32_t
2118 emlxs_dump_os_version(
2119 emlxs_hba_t *hba,
2120 emlxs_file_t *fpTxtFile,
2121 emlxs_file_t *fpDmpFile)
2123 uint32_t status;
2124 char *buf1;
2125 char *buf2;
2126 uint32_t buf1_size;
2127 uint32_t buf2_size;
2129 buf1_size = 1024;
2130 buf2_size = 1024;
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);
2142 status =
2143 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_REV_INFO,
2144 LEGEND_REV_OS_VERSION, 0);
2146 status =
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);
2153 return (status);
2155 } /* emlxs_dump_os_version() */
2158 /*ARGSUSED*/
2159 static uint32_t
2160 emlxs_dump_drv_version(
2161 emlxs_hba_t *hba,
2162 emlxs_file_t *fpTxtFile,
2163 emlxs_file_t *fpDmpFile)
2165 uint32_t status;
2166 char *buf1;
2167 char *buf2;
2168 uint32_t buf1_size;
2169 uint32_t buf2_size;
2171 buf1_size = 1024;
2172 buf2_size = 1024;
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);
2191 status =
2192 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_REV_INFO,
2193 LEGEND_REV_DRV_VERSION, 0);
2195 status =
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);
2202 return (status);
2204 } /* emlxs_dump_drv_version() */
2207 static uint32_t
2208 emlxs_dump_file_create(
2209 emlxs_hba_t *hba,
2210 emlxs_file_t ** fpTxtFile,
2211 emlxs_file_t ** fpDmpFile,
2212 emlxs_file_t ** fpCeeFile)
2214 if (fpTxtFile) {
2215 /* Create the Dump Files */
2216 if ((*fpTxtFile = emlxs_fopen(hba, EMLXS_TXT_FILE)) == NULL) {
2217 return (1);
2221 if (fpCeeFile) {
2222 *fpCeeFile = 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)) {
2227 if ((*fpCeeFile =
2228 emlxs_fopen(hba, EMLXS_CEE_FILE)) == NULL) {
2229 emlxs_fdelete(*fpTxtFile);
2230 return (1);
2235 if (fpDmpFile) {
2236 if ((*fpDmpFile = emlxs_fopen(hba, EMLXS_DMP_FILE)) == NULL) {
2237 emlxs_fdelete(*fpTxtFile);
2238 emlxs_fdelete(*fpCeeFile);
2239 return (1);
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);
2259 return (0);
2261 } /* emlxs_dump_file_create() */
2264 static uint32_t
2265 emlxs_dump_file_terminate(
2266 emlxs_hba_t *hba,
2267 emlxs_file_t *fpTxtFile,
2268 emlxs_file_t *fpDmpFile,
2269 emlxs_file_t *fpCeeFile)
2272 if (fpTxtFile) {
2273 /* Write a suitable string to the Dump TXT File */
2274 (void) emlxs_fprintf(fpTxtFile, "Dump File End\n");
2275 emlxs_fflush(fpTxtFile);
2278 if (fpCeeFile) {
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 */
2287 if (fpDmpFile) {
2288 emlxs_fputc(SID_DUMP_TERM, fpDmpFile);
2289 emlxs_fflush(fpDmpFile);
2293 return (0);
2295 } /* emlxs_dump_file_terminate() */
2298 static uint32_t
2299 emlxs_dump_file_close(
2300 emlxs_file_t *fpTxtFile,
2301 emlxs_file_t *fpDmpFile,
2302 emlxs_file_t *fpCeeFile)
2305 if (fpTxtFile) {
2306 (void) emlxs_fclose(fpTxtFile);
2309 if (fpCeeFile) {
2310 (void) emlxs_fclose(fpCeeFile);
2313 if (fpDmpFile) {
2314 (void) emlxs_fclose(fpDmpFile);
2317 return (0);
2319 } /* emlxs_dump_file_close() */
2322 /* ************************************************************************* */
2323 /* ************************************************************************* */
2324 /* Dump Generators, High Level */
2325 /* ************************************************************************* */
2326 /* ************************************************************************* */
2329 static uint32_t
2330 emlxs_dump_rev_info(
2331 emlxs_hba_t *hba,
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);
2337 return (0);
2339 } /* emlxs_dump_rev_info() */
2342 /* ARGSUSED */
2343 static uint32_t
2344 emlxs_dump_hba_info(
2345 emlxs_hba_t *hba,
2346 emlxs_file_t *fpTxtFile,
2347 emlxs_file_t *fpDmpFile,
2348 uint32_t dump_type)
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);
2357 return (0);
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 /* ************************************************************************* */
2369 static uint32_t
2370 emlxs_dump_table_check(
2371 emlxs_hba_t *hba,
2372 uint32_t *pSize)
2374 emlxs_port_t *port = &PPORT;
2375 int fDone = FALSE; /* loop control flag */
2376 uint32_t tableSize = 0; /* dump table size (word count) */
2377 MAILBOX *mb;
2378 MAILBOXQ *mbq;
2379 uint32_t DumpTableAddr;
2380 DUMP_TABLE_ENTRY entry;
2382 *pSize = 0;
2384 /* Read 1 word from low memory at address 654; */
2385 /* save the returned Dump Table Base Address */
2387 mbq =
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",
2397 mb->mbxStatus);
2399 kmem_free(mbq, sizeof (MAILBOXQ));
2400 return (1);
2403 DumpTableAddr = mb->un.varDmp.resp_offset;
2405 if (DumpTableAddr == 0) {
2406 kmem_free(mbq, sizeof (MAILBOXQ));
2407 return (1);
2410 /* Now loop reading Dump Table Entries.. */
2411 /* break out when we see a Terminator SID */
2412 while (!fDone) {
2413 emlxs_mb_dump(hba, mbq, DumpTableAddr, 2);
2414 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
2415 MBX_SUCCESS) {
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));
2422 return (1);
2425 entry.un.PortBlock.un.w[0] = mb->un.varWords[4];
2427 switch (entry.un.PortBlock.un.s.sid) {
2428 /* New Dump Table */
2429 case SID_ID01:
2430 tableSize++;
2431 DumpTableAddr += 4;
2432 break;
2434 #ifdef CC_DUMP_USE_ALL_TABLES
2435 /* New Dump Table */
2436 case SID_ID02:
2437 case SID_ID03:
2438 tableSize++;
2439 DumpTableAddr += 4;
2440 break;
2441 #else
2442 /* New Dump Table */
2443 case SID_ID02:
2444 case SID_ID03:
2445 tableSize++;
2446 fDone = TRUE;
2447 break;
2448 #endif /* CC_DUMP_USE_ALL_TABLES */
2450 /* Dump Table(s) Termination - all done */
2451 case SID_TERM:
2452 tableSize++;
2453 fDone = TRUE;
2454 break;
2456 /* Dump Table Entry */
2457 default:
2458 tableSize += 2;
2459 DumpTableAddr += 8;
2460 break;
2463 } /* end while */
2465 *pSize = (tableSize * 4); /* return the total Dump Table size */
2467 kmem_free(mbq, sizeof (MAILBOXQ));
2468 return (0);
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 /* ************************************************************************ */
2479 static uint32_t
2480 emlxs_dump_table_read(
2481 emlxs_hba_t *hba,
2482 emlxs_file_t *fpTxtFile,
2483 uint32_t **ppDumpTable,
2484 uint32_t *pDumpTableSize)
2486 emlxs_port_t *port = &PPORT;
2487 uint32_t status = 0;
2488 int fDone = FALSE;
2489 MAILBOXQ *mbq;
2490 MAILBOX *mb;
2491 uint32_t *pDumpTableEntry;
2492 uint32_t DumpTableAddr;
2493 DUMP_TABLE_ENTRY entry;
2495 char buf2[256];
2496 char *buf1;
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);
2501 if (status != 0) {
2502 return (status);
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 */
2514 mbq =
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",
2525 mb->mbxStatus);
2527 kmem_free(buf1, size);
2528 kmem_free(mbq, sizeof (MAILBOXQ));
2530 kmem_free(*ppDumpTable, *pDumpTableSize);
2531 *pDumpTableSize = 0;
2532 *ppDumpTable = NULL;
2534 return (1);
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;
2547 return (1);
2551 /* Now loop reading Dump Table Entries.. */
2552 /* break out when we see a Terminator SID */
2553 while (!fDone) {
2554 emlxs_mb_dump(hba, mbq, DumpTableAddr, 2);
2555 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
2556 MBX_SUCCESS) {
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;
2569 return (1);
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 */
2581 case SID_ID01:
2582 (void) snprintf(buf2, sizeof (buf2), "w0=%08x",
2583 entry.un.PortBlock.un.w[0]);
2584 (void) strlcat(buf1, buf2, size);
2585 DumpTableAddr += 4;
2586 break;
2588 #ifdef CC_DUMP_USE_ALL_TABLES
2589 /* New Dump Table */
2590 case SID_ID02:
2591 case SID_ID03:
2592 (void) snprintf(buf2, sizeof (buf2), "w0=%08x",
2593 entry.un.PortBlock.un.w[0]);
2594 (void) strlcat(buf1, buf2, size);
2595 DumpTableAddr += 4;
2596 break;
2597 #else
2598 /* New Dump Table */
2599 case SID_ID02:
2600 case SID_ID03:
2601 (void) snprintf(buf2, sizeof (buf2), "w0=%08x",
2602 entry.un.PortBlock.un.w[0]);
2603 (void) strlcat(buf1, buf2, size);
2604 fDone = TRUE;
2605 break;
2606 #endif /* CC_DUMP_USE_ALL_TABLES */
2608 /* Dump Table(s) Termination - all done */
2609 case SID_TERM:
2610 (void) snprintf(buf2, sizeof (buf2), "w0=%08x",
2611 entry.un.PortBlock.un.w[0]);
2612 (void) strlcat(buf1, buf2, size);
2613 fDone = TRUE;
2614 break;
2616 /* Dump Table Entry */
2617 default:
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);
2625 DumpTableAddr += 8;
2626 break;
2629 } /* end while */
2631 status =
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));
2638 if (status != 0) {
2639 kmem_free(*ppDumpTable, *pDumpTableSize);
2640 *pDumpTableSize = 0;
2641 *ppDumpTable = NULL;
2643 return (status);
2646 return (0);
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 /* ************************************************************************* */
2657 static uint32_t
2658 emlxs_dump_hba_memory(
2659 emlxs_hba_t *hba,
2660 emlxs_file_t *fpDmpFile,
2661 uint32_t *pDumpTable)
2663 emlxs_port_t *port = &PPORT;
2664 uint32_t status = 0;
2665 int fDone = FALSE;
2666 DUMP_TABLE_ENTRY entry;
2667 MAILBOXQ *mbq;
2668 MAILBOX *mb;
2669 uint32_t byteCount;
2670 uint32_t byteCountRem;
2671 uint8_t *pBuf;
2672 uint8_t *p1;
2673 uint32_t portAddr;
2674 int fSwap = FALSE;
2675 uint32_t offset = 0;
2676 uint32_t wcount;
2677 uint32_t total = 0;
2679 #ifdef EMLXS_BIG_ENDIAN
2680 fSwap = TRUE;
2681 #endif /* EMLXS_BIG_ENDIAN */
2683 if (!fpDmpFile) {
2684 return (1);
2687 mbq =
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 */
2694 while (!fDone) {
2695 entry.un.PortBlock.un.w[0] = *pDumpTable++;
2697 switch (entry.un.PortBlock.un.s.sid) {
2699 /* New Dump Table */
2700 case SID_ID01:
2701 break;
2703 #ifdef CC_DUMP_USE_ALL_TABLES
2704 /* New Dump Table */
2705 case SID_ID02:
2706 case SID_ID03:
2707 break;
2708 #else
2709 /* New Dump Table */
2710 case SID_ID02:
2711 case SID_ID03:
2712 fDone = TRUE;
2713 break;
2714 #endif /* CC_DUMP_USE_ALL_TABLES */
2716 /* Dump Table(s) Termination - all done */
2717 case SID_TERM:
2718 fDone = TRUE;
2719 break;
2721 default:
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) {
2727 break;
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) {
2734 offset =
2735 (entry.un.PortBlock.un.s.
2736 addr & 0x01FFFFFF);
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));
2747 return (1);
2750 /* replace the indirect address in the */
2751 /* Dump Table */
2752 entry.un.PortBlock.un.s.addr =
2753 mb->un.varWords[4];
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) {
2760 byteCount =
2761 256 *
2762 entry.un.PortStruct.un.s.length;
2763 } else {
2764 byteCount =
2765 entry.un.PortStruct.un.s.count *
2766 entry.un.PortStruct.un.s.length;
2770 total += byteCount;
2771 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
2772 "Dump: addr=%x count=%d total=%d", offset,
2773 byteCount, total);
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 */
2779 /* a time */
2781 /* init vars */
2782 byteCountRem = byteCount;
2783 p1 = pBuf;
2784 portAddr = entry.un.PortBlock.un.s.addr;
2786 for (;;) {
2787 if (byteCountRem == 0) {
2788 break;
2791 wcount =
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);
2802 break;
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);
2812 } /* end for */
2814 if (status == 0) {
2815 if (entry.un.PortBlock.un.s.
2816 sid & SID_MULT_ELEM) {
2817 status =
2818 emlxs_dump_port_struct(fpDmpFile,
2819 pBuf, byteCount, entry, fSwap);
2820 } else {
2821 status =
2822 emlxs_dump_port_block(fpDmpFile,
2823 pBuf, byteCount, entry, fSwap);
2827 if (pBuf) {
2828 kmem_free(pBuf, byteCount);
2831 break;
2833 } /* end switch */
2835 } /* end while */
2837 kmem_free(mbq, sizeof (MAILBOXQ));
2839 return (status);
2841 } /* emlxs_dump_hba_memory() */
2844 static uint32_t
2845 emlxs_dump_hba(
2846 emlxs_hba_t *hba,
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) {
2855 return (1);
2858 /* HBA should be in WARM state here */
2859 status =
2860 emlxs_dump_table_read(hba, fpTxtFile, &pDumpTable,
2861 &DumpTableSize);
2862 if (status) {
2863 return (status);
2866 status = emlxs_dump_hba_memory(hba, fpDmpFile, pDumpTable);
2868 if (pDumpTable != 0) {
2869 kmem_free(pDumpTable, DumpTableSize);
2872 return (status);
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 /* ************************************************************************* */
2883 static uint32_t
2884 emlxs_dump_drv_region(
2885 emlxs_hba_t *hba,
2886 uint32_t regionId,
2887 uint8_t **pBuf,
2888 uint32_t *pBufLen)
2889 { /* ptr to length of buffer */
2890 uint32_t status;
2891 uint32_t size;
2893 *pBuf = NULL;
2894 *pBufLen = 0;
2896 size = 0;
2897 status = emlxs_get_dump_region(hba, regionId, NULL, &size);
2899 if (status != 0) {
2900 return (1);
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);
2908 if (status != 0) {
2909 kmem_free(*pBuf, size);
2910 *pBuf = NULL;
2912 return (1);
2915 *pBufLen = size;
2917 return (status);
2919 } /* emlxs_dump_drv_region() */
2922 static uint32_t
2923 emlxs_dump_sli_regs(
2924 emlxs_hba_t *hba,
2925 emlxs_file_t *fpDmpFile)
2927 uint32_t status;
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
2933 fSwap = TRUE;
2934 #endif /* EMLXS_BIG_ENDIAN */
2936 if (!fpDmpFile) {
2937 return (1);
2940 status = emlxs_dump_drv_region(hba, DR_SLI_REGS, &pBuf, &bufLen);
2942 if (status != 0) {
2943 return (status);
2946 status =
2947 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_SLI_REGS,
2948 LEGEND_SLI_STRUCTURES, LEGEND_SLI_REGS, fSwap);
2950 kmem_free(pBuf, bufLen);
2952 return (status);
2954 } /* emlxs_dump_sli_regs() */
2957 static uint32_t
2958 emlxs_dump_slim(
2959 emlxs_hba_t *hba,
2960 emlxs_file_t *fpTxtFile,
2961 emlxs_file_t *fpDmpFile,
2962 uint32_t dump_type)
2964 uint32_t status;
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
2970 fSwap = TRUE;
2971 #endif /* EMLXS_BIG_ENDIAN */
2973 status = emlxs_dump_drv_region(hba, DR_SLIM, &pBuf, &bufLen);
2975 if (status != 0) {
2976 return (status);
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) {
2982 status =
2983 emlxs_dump_word_txtfile(fpTxtFile, (uint32_t *)pBuf,
2984 0x40, LEGEND_SLI_STRUCTURES, LEGEND_SLIM);
2987 status =
2988 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_SLIM,
2989 LEGEND_SLI_STRUCTURES, LEGEND_SLIM, fSwap);
2991 kmem_free(pBuf, bufLen);
2993 return (status);
2995 } /* emlxs_dump_slim() */
2998 static uint32_t
2999 emlxs_dump_pcb(
3000 emlxs_hba_t *hba,
3001 emlxs_file_t *fpDmpFile)
3003 uint32_t status;
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
3009 fSwap = TRUE;
3010 #endif /* EMLXS_BIG_ENDIAN */
3012 if (!fpDmpFile) {
3013 return (1);
3016 status = emlxs_dump_drv_region(hba, DR_PCB, &pBuf, &bufLen);
3017 if (status != 0) {
3018 return (status);
3021 status =
3022 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_PCB,
3023 LEGEND_SLI_STRUCTURES, LEGEND_PCB, fSwap);
3025 kmem_free(pBuf, bufLen);
3027 return (status);
3029 } /* emlxs_dump_pcb() */
3032 static uint32_t
3033 emlxs_dump_mbox(
3034 emlxs_hba_t *hba,
3035 emlxs_file_t *fpDmpFile)
3037 uint32_t status;
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
3043 fSwap = TRUE;
3044 #endif /* EMLXS_BIG_ENDIAN */
3046 if (!fpDmpFile) {
3047 return (1);
3050 status = emlxs_dump_drv_region(hba, DR_MBX, &pBuf, &bufLen);
3051 if (status != 0) {
3052 return (status);
3055 status =
3056 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_MBX,
3057 LEGEND_SLI_STRUCTURES, LEGEND_MBX, fSwap);
3059 kmem_free(pBuf, bufLen);
3061 return (status);
3063 } /* emlxs_dump_mbox() */
3066 static uint32_t
3067 emlxs_dump_host_pointers(
3068 emlxs_hba_t *hba,
3069 emlxs_file_t *fpDmpFile)
3071 uint32_t status;
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
3077 fSwap = TRUE;
3078 #endif /* EMLXS_BIG_ENDIAN */
3080 if (!fpDmpFile) {
3081 return (1);
3084 status = emlxs_dump_drv_region(hba, DR_HOST_PTRS, &pBuf, &bufLen);
3085 if (status != 0) {
3086 return (status);
3089 status =
3090 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_HOST_PTRS,
3091 LEGEND_SLI_STRUCTURES, LEGEND_HOST_PTRS, fSwap);
3093 kmem_free(pBuf, bufLen);
3095 return (status);
3097 } /* emlxs_dump_host_pointers() */
3100 static uint32_t
3101 emlxs_dump_port_pointers(
3102 emlxs_hba_t *hba,
3103 emlxs_file_t *fpDmpFile)
3105 uint32_t status;
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
3111 fSwap = TRUE;
3112 #endif /* EMLXS_BIG_ENDIAN */
3114 if (!fpDmpFile) {
3115 return (1);
3118 status = emlxs_dump_drv_region(hba, DR_PORT_PTRS, &pBuf, &bufLen);
3119 if (status != 0) {
3120 return (status);
3123 status =
3124 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_PORT_PTRS,
3125 LEGEND_SLI_STRUCTURES, LEGEND_PORT_PTRS, fSwap);
3127 kmem_free(pBuf, bufLen);
3129 return (status);
3131 } /* emlxs_dump_port_pointers() */
3134 static uint32_t
3135 emlxs_dump_rings(
3136 emlxs_hba_t *hba,
3137 emlxs_file_t *fpDmpFile)
3139 uint32_t status;
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
3145 fSwap = TRUE;
3146 #endif /* EMLXS_BIG_ENDIAN */
3148 if (!fpDmpFile) {
3149 return (1);
3152 status = emlxs_dump_drv_region(hba, DR_RINGS, &pBuf, &bufLen);
3153 if (status != 0) {
3154 return (status);
3157 status =
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);
3164 return (status);
3166 } /* emlxs_dump_rings() */
3169 static uint32_t
3170 emlxs_dump_drv_internals(
3171 emlxs_hba_t *hba,
3172 emlxs_file_t *fpDmpFile)
3174 uint32_t status;
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
3180 fSwap = TRUE;
3181 #endif /* EMLXS_BIG_ENDIAN */
3183 if (!fpDmpFile) {
3184 return (1);
3187 status = emlxs_dump_drv_region(hba, DR_INTERNAL, &pBuf, &bufLen);
3188 if (status != 0) {
3189 return (status);
3192 status =
3193 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_INTERNAL_SOL,
3194 LEGEND_SLI_STRUCTURES, LEGEND_DRIVER_SPEC, fSwap);
3196 kmem_free(pBuf, bufLen);
3198 return (status);
3200 } /* emlxs_dump_drv_internals() */
3203 static uint32_t
3204 emlxs_dump_sli_interface(
3205 emlxs_hba_t *hba,
3206 emlxs_file_t *fpTxtFile,
3207 emlxs_file_t *fpDmpFile,
3208 uint32_t dump_type)
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);
3225 return (0);
3227 } /* emlxs_dump_sli_interface() */
3230 static uint32_t
3231 emlxs_dump_menlo_log(
3232 emlxs_hba_t *hba,
3233 emlxs_file_t *fpCeeFile)
3235 uint32_t RmStatus;
3236 int i, j;
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 */
3246 uint32_t LcBufSize;
3247 menlo_rsp_t *pLcBuf = NULL;
3248 uint32_t NumLogs;
3249 menlo_log_t *pLcEntry;
3251 /* Get Log Data Command vars */
3252 uint32_t LdBufSize;
3253 menlo_rsp_t *pLdBuf = NULL;
3254 uint16_t Head;
3255 uint8_t *pLogEntry;
3256 char *pLogString;
3258 /* Get Panic Log Command vars */
3259 uint32_t PlBufSize;
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 */
3271 RmStatus =
3272 emlxs_menlo_get_cfg(hba, pGcBuf, sizeof (menlo_get_config_rsp_t));
3274 if (RmStatus != 0) {
3275 goto done;
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) {
3286 goto done;
3289 buf1[0] = 0;
3290 RmStatus =
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;
3297 buf1[0] = 0;
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++) {
3306 buf1[0] = 0;
3307 (void) snprintf(buf2, sizeof (buf2),
3308 "\n %2d %4d %4d %s",
3309 pLcEntry[i].id,
3310 pLcEntry[i].num_entries,
3311 pLcEntry[i].entry_size, pLcEntry[i].name);
3312 (void) strlcat(buf1, buf2, sizeof (buf1));
3313 RmStatus =
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++) {
3321 LdBufSize =
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) {
3329 goto done;
3332 /* print a caption for the current log */
3333 buf1[0] = 0;
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));
3345 RmStatus =
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;
3352 pLogString =
3353 (char *)&(pLogEntry[Head *pLcEntry[i].entry_size]);
3355 isWrapped = FALSE;
3356 if (strlen(pLogString) != 0) {
3357 isWrapped = TRUE;
3360 /* if log is wrapped, get entries from the */
3361 /* Head through the End */
3362 if (isWrapped) {
3363 for (j = Head; j < (int)pLcEntry[i].num_entries; j++) {
3364 pLogString =
3365 (char *)&(pLogEntry[j *
3366 pLcEntry[i].entry_size]);
3367 buf1[0] = 0;
3368 (void) snprintf(buf2, sizeof (buf2),
3369 "\n%3d: %s", j, pLogString);
3370 (void) strlcat(buf1, buf2, sizeof (buf1));
3371 RmStatus =
3372 emlxs_dump_string_txtfile(fpCeeFile, buf1,
3373 0, 0, 1);
3377 /* if wrapped or not, get entries from the Top */
3378 /* through the Head */
3379 for (j = 0; j < Head; j++) {
3380 pLogString =
3381 (char *)&(pLogEntry[j * pLcEntry[i].entry_size]);
3382 buf1[0] = 0;
3383 (void) snprintf(buf2, sizeof (buf2), "\n%3d: %s", j,
3384 pLogString);
3385 (void) strlcat(buf1, buf2, sizeof (buf1));
3386 RmStatus =
3387 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0,
3390 } /* end for i */
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));
3396 buf2[0] = 0;
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) {
3408 buf1[0] = 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));
3421 RmStatus =
3422 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
3424 buf1[0] = 0;
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));
3431 RmStatus =
3432 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
3434 buf1[0] = 0;
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.",
3444 PanicLogEntrySize);
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));
3449 RmStatus =
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,
3454 sizeof (buf1));
3455 buf2[0] = 0;
3456 for (j = 0; j < 75; j++) {
3457 (void) strlcat(buf2, "-", sizeof (buf2));
3459 (void) strlcat(buf1, buf2, sizeof (buf2));
3460 RmStatus =
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]);
3468 isWrapped = FALSE;
3469 if (strlen(pLogString) != 0) {
3470 isWrapped = TRUE;
3473 /* if log is wrapped, get entries from the */
3474 /* Head through the End */
3475 if (isWrapped) {
3476 for (j = Head; j < (int)PanicLogEntryCount; j++) {
3477 pLogString =
3478 (char *)&(pLogEntry[j *
3479 PanicLogEntrySize]);
3480 buf1[0] = 0;
3481 (void) snprintf(buf2, sizeof (buf2),
3482 "\n%3d: %s", j, pLogString);
3483 (void) strlcat(buf1, buf2, sizeof (buf2));
3484 RmStatus =
3485 emlxs_dump_string_txtfile(fpCeeFile, buf1,
3486 0, 0, 1);
3489 /* if wrapped or not, get entries from the Top */
3490 /* through the Head */
3491 for (j = 0; j < Head; j++) {
3492 pLogString =
3493 (char *)&(pLogEntry[j * PanicLogEntrySize]);
3494 buf1[0] = 0;
3495 (void) snprintf(buf2, sizeof (buf2), "\n%3d: %s", j,
3496 pLogString);
3497 (void) strlcat(buf1, buf2, sizeof (buf2));
3498 RmStatus =
3499 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0,
3504 RmStatus = emlxs_dump_string_txtfile(fpCeeFile, "\n\n", 0, 0, 1);
3506 done:
3508 if (pLdBuf != 0) {
3509 kmem_free(pLdBuf, LdBufSize);
3512 if (pLcBuf != 0) {
3513 kmem_free(pLcBuf, LcBufSize);
3516 if (pPlBuf != 0) {
3517 kmem_free(pPlBuf, PlBufSize);
3520 return (RmStatus);
3522 } /* emlxs_dump_menlo_log() */
3525 static uint32_t
3526 emlxs_dump_saturn_log(
3527 emlxs_hba_t *hba,
3528 emlxs_file_t *fpTxtFile,
3529 emlxs_file_t *fpDmpFile)
3531 emlxs_port_t *port = &PPORT;
3532 MAILBOXQ *mbq;
3533 MAILBOX *mb;
3534 MATCHMAP *mp = NULL;
3535 uint32_t status;
3536 uint32_t logSize = 0;
3537 uintptr_t tempAddress;
3538 int fSwap = FALSE;
3539 uint32_t i;
3540 uint32_t block_size;
3541 uint32_t offset;
3543 #ifdef EMLXS_BIG_ENDIAN
3544 fSwap = TRUE;
3545 #endif /* EMLXS_BIG_ENDIAN */
3547 if (hba->model_info.chip != EMLXS_SATURN_CHIP) {
3548 return (1);
3551 mbq =
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) ==
3563 MBX_SUCCESS) {
3564 break;
3567 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3568 "Unable to read event log status. status=%x",
3569 mb->mbxStatus);
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));
3579 return (1);
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));
3593 return (1);
3597 if (i >= 10) {
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));
3603 return (1);
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. "
3612 "size=%d",
3613 logSize);
3615 kmem_free(mbq, sizeof (MAILBOXQ));
3616 return (1);
3619 for (offset = 0; offset < logSize; offset = offset + 1024) {
3620 if (logSize - offset < 1024) {
3621 block_size = logSize - offset;
3622 } else {
3623 block_size = 1024;
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) !=
3640 MBX_SUCCESS) {
3641 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3642 "Unable to read event log. status=%x",
3643 mb->mbxStatus);
3645 emlxs_mem_buf_free(hba, mp);
3646 kmem_free(mbq, sizeof (MAILBOXQ));
3647 return (1);
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. */
3655 status =
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);
3662 status =
3663 emlxs_dump_host_block(fpDmpFile, mp->virt, logSize,
3664 SID_NON_VOLATILE_LOG, LEGEND_NON_VOLATILE_LOG, LEGEND_NULL,
3665 fSwap);
3667 #ifdef FMA_SUPPORT
3668 if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
3669 != DDI_FM_OK) {
3670 EMLXS_MSGF(EMLXS_CONTEXT,
3671 &emlxs_invalid_dma_handle_msg,
3672 "dump_saturn_log: hdl=%p",
3673 mp->dma_handle);
3674 status = 1;
3676 #endif /* FMA_SUPPORT */
3678 emlxs_mem_buf_free(hba, mp);
3679 kmem_free(mbq, sizeof (MAILBOXQ));
3680 return (status);
3682 } /* emlxs_dump_saturn_log() */
3685 static uint32_t
3686 emlxs_dump_tigershark_log(
3687 emlxs_hba_t *hba,
3688 emlxs_file_t *fpTxtFile,
3689 emlxs_file_t *fpCeeFile)
3691 emlxs_port_t *port = &PPORT;
3692 uint32_t rval = 0;
3693 uint32_t offset;
3694 uint32_t log_size;
3695 uint32_t xfer_size;
3696 uint32_t buffer_size;
3697 uint8_t *buffer = NULL;
3698 uint8_t *bptr;
3699 uint8_t *payload;
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)) {
3708 return (1);
3711 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3712 "Querying FAT...");
3714 mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
3715 KM_SLEEP);
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.");
3724 rval = 1;
3725 goto done;
3728 /* Query FAT */
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) !=
3749 MBX_SUCCESS) {
3750 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3751 "FAT Query failed. status=%x",
3752 mb->mbxStatus);
3754 rval = 1;
3755 goto done;
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) {
3765 goto done;
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.");
3772 rval = 1;
3773 goto done;
3775 bzero(buffer, buffer_size);
3777 /* Upload Log */
3778 bptr = buffer;
3779 offset = 0;
3781 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3782 "Uploading log... (%d bytes)", log_size);
3784 while (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) !=
3811 MBX_SUCCESS) {
3812 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3813 "Failed to upload log. status=%x",
3814 mb->mbxStatus);
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);
3821 rval = 1;
3822 goto done;
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;
3831 bptr += 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. */
3839 rval =
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,
3849 log_size, 0);
3851 done:
3853 if (mbq) {
3854 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
3857 if (mp) {
3858 emlxs_mem_buf_free(hba, mp);
3861 if (buffer) {
3862 kmem_free(buffer, buffer_size);
3865 if (rval == 0) {
3866 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3867 "Dump complete.");
3870 return (rval);
3872 } /* emlxs_dump_tigershark_log() */
3875 extern uint32_t
3876 emlxs_dump_user_event(
3877 emlxs_hba_t *hba)
3879 emlxs_port_t *port = &PPORT;
3880 uint32_t status;
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...");
3890 status =
3891 emlxs_dump_file_create(hba, &fpTxtFile, &fpDmpFile, &fpCeeFile);
3892 if (status != 0) {
3893 mutex_exit(&EMLXS_DUMP_LOCK);
3894 return (1);
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,
3917 DUMP_TYPE_USER);
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);
3928 if (status == 0) {
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);
3938 return (0);
3940 } /* emlxs_dump_user_event() */
3943 extern uint32_t
3944 emlxs_dump_temp_event(
3945 emlxs_hba_t *hba,
3946 uint32_t tempType,
3947 uint32_t temp)
3949 emlxs_port_t *port = &PPORT;
3950 uint32_t status;
3951 emlxs_file_t *fpTxtFile;
3953 /* misc vars */
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.",
3962 tempType, temp);
3964 return (1);
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...",
3972 tempType, temp);
3974 status = emlxs_dump_file_create(hba, &fpTxtFile, 0, 0);
3975 if (status != 0) {
3976 mutex_exit(&EMLXS_DUMP_LOCK);
3977 return (1);
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",
3986 sizeof (sBuf1));
3987 switch (tempType) {
3988 case TEMP_TYPE_CRITICAL:
3989 (void) snprintf(sBuf2, sizeof (sBuf2),
3990 " Event Type = %d (Critical)\n", tempType);
3991 break;
3992 case TEMP_TYPE_THRESHOLD:
3993 (void) snprintf(sBuf2, sizeof (sBuf2),
3994 " Event Type = %d (Threshold)\n", tempType);
3995 break;
3996 case TEMP_TYPE_NORMAL:
3997 (void) snprintf(sBuf2, sizeof (sBuf2),
3998 " Event Type = %d (Normal)\n", tempType);
3999 break;
4000 default:
4001 (void) snprintf(sBuf2, sizeof (sBuf2),
4002 " Unknown Event Type = %d\n", tempType);
4003 break;
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);
4018 return (0);
4020 } /* emlxs_dump_temp_event() */
4023 extern uint32_t
4024 emlxs_dump_drv_event(
4025 emlxs_hba_t *hba)
4027 emlxs_port_t *port = &PPORT;
4028 uint32_t status;
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...");
4038 status =
4039 emlxs_dump_file_create(hba, &fpTxtFile, &fpDmpFile, &fpCeeFile);
4040 if (status != 0) {
4041 mutex_exit(&EMLXS_DUMP_LOCK);
4042 return (1);
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,
4060 DUMP_TYPE_DRIVER);
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);
4073 if (status == 0) {
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);
4094 return (0);
4096 } /* emlxs_dump_drv_event() */
4099 /* ARGSUSED */
4100 extern void
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);
4111 return;
4113 } /* emlxs_dump_drv_thread() */
4116 /* ARGSUSED */
4117 extern void
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);
4128 return;
4130 } /* emlxs_dump_user_thread() */
4133 /* ARGSUSED */
4134 extern void
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,
4141 temp_event->temp);
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);
4151 return;
4153 } /* emlxs_dump_temp_thread() */
4156 /* Schedules a dump thread */
4157 /* temp_type and temp are only valid for type=EMLXS_TEMP_DUMP */
4158 extern void
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.");
4173 return;
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.");
4183 return;
4186 /* Prepare to schedule dump */
4187 switch (type) {
4188 case EMLXS_DRV_DUMP:
4189 case EMLXS_USER_DUMP:
4190 break;
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.");
4202 return;
4205 temp_event->hba = hba;
4206 temp_event->type = temp_type;
4207 temp_event->temp = temp;
4208 break;
4210 default:
4211 mutex_exit(&EMLXS_PORT_LOCK);
4213 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
4214 "dump: Error: Unknown dump type. (%x)",
4215 type);
4217 return;
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 */
4225 switch (type) {
4226 case EMLXS_DRV_DUMP:
4227 emlxs_thread_spawn(hba, emlxs_dump_drv_thread, NULL, NULL);
4228 break;
4230 case EMLXS_TEMP_DUMP:
4231 emlxs_thread_spawn(hba, emlxs_dump_temp_thread,
4232 (void *)temp_event, NULL);
4233 break;
4235 case EMLXS_USER_DUMP:
4236 emlxs_thread_spawn(hba, emlxs_dump_user_thread, NULL, NULL);
4237 break;
4240 return;
4242 } /* emlxs_dump() */
4244 extern void
4245 emlxs_dump_wait(emlxs_hba_t *hba)
4247 /* Wait for the Dump flag to clear */
4248 while ((hba->flag & FC_DUMP_ACTIVE)) {
4249 BUSYWAIT_MS(1000);
4252 } /* emlxs_dump_wait() */
4255 #endif /* DUMP_SUPPORT */