1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at
9 * http://www.opensource.org/licenses/cddl1.txt.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004-2012 Emulex. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <emlxs.h>
28
29 #ifdef DUMP_SUPPORT
30
31 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
32 EMLXS_MSG_DEF(EMLXS_DUMP_C);
33
34 /* ************************************************************************* */
35 /* Utility functions */
36 /* ************************************************************************* */
37
38 static uint32_t
emlxs_menlo_set_mode(emlxs_hba_t * hba,uint32_t mode)39 emlxs_menlo_set_mode(
40 emlxs_hba_t *hba,
41 uint32_t mode)
42 {
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;
49
50 if (hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
51 return (DFC_INVALID_ADAPTER);
52 }
53
54 cmd_size = sizeof (menlo_set_cmd_t);
55 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
56
57 rsp_size = 4;
58 rsp_buf = (menlo_rsp_t *)kmem_zalloc(rsp_size, KM_SLEEP);
59
60 cmd_buf->code = MENLO_CMD_SET_MODE;
61 cmd_buf->set.value1 = mode;
62 cmd_buf->set.value2 = 0;
63
64 #ifdef EMLXS_BIG_ENDIAN
65 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
66 #endif /* EMLXS_BIG_ENDIAN */
67
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;
73 }
74 #ifdef EMLXS_BIG_ENDIAN
75 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
76 #endif /* EMLXS_BIG_ENDIAN */
77
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);
82 }
83
84 rval = rsp_buf->code;
85
86 done:
87
88 if (cmd_buf) {
89 kmem_free(cmd_buf, sizeof (menlo_set_cmd_t));
90 }
91
92 if (rsp_buf) {
93 kmem_free(rsp_buf, 4);
94 }
95
96 return (rval);
97
98 } /* emlxs_menlo_set_mode() */
99
100
101 static uint32_t
emlxs_menlo_reset(emlxs_hba_t * hba,uint32_t firmware)102 emlxs_menlo_reset(
103 emlxs_hba_t *hba,
104 uint32_t firmware)
105 {
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;
112
113 if (hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
114 return (DFC_INVALID_ADAPTER);
115 }
116
117 cmd_size = sizeof (menlo_reset_cmd_t);
118 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
119
120 rsp_size = 4;
121 rsp_buf = (menlo_rsp_t *)kmem_zalloc(rsp_size, KM_SLEEP);
122
123 cmd_buf->code = MENLO_CMD_RESET;
124 cmd_buf->reset.firmware = firmware;
125
126 #ifdef EMLXS_BIG_ENDIAN
127 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
128 #endif /* EMLXS_BIG_ENDIAN */
129
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;
135 }
136 #ifdef EMLXS_BIG_ENDIAN
137 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
138 #endif /* EMLXS_BIG_ENDIAN */
139
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);
144 }
145
146 rval = rsp_buf->code;
147
148 done:
149
150 if (cmd_buf) {
151 kmem_free(cmd_buf, sizeof (menlo_reset_cmd_t));
152 }
153
154 if (rsp_buf) {
155 kmem_free(rsp_buf, 4);
156 }
157
158 return (rval);
159
160 } /* emlxs_menlo_reset() */
161
162
163 static uint32_t
emlxs_menlo_get_cfg(emlxs_hba_t * hba,menlo_get_config_rsp_t * rsp_buf,uint32_t rsp_size)164 emlxs_menlo_get_cfg(
165 emlxs_hba_t *hba,
166 menlo_get_config_rsp_t *rsp_buf,
167 uint32_t rsp_size)
168 {
169 emlxs_port_t *port = &PPORT;
170 uint32_t cmd_size;
171 menlo_cmd_t *cmd_buf = NULL;
172 uint32_t rval = 0;
173
174 if (hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
175 return (DFC_INVALID_ADAPTER);
176 }
177
178 cmd_size = sizeof (menlo_get_cmd_t);
179 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
180
181 rsp_size = sizeof (menlo_get_config_rsp_t);
182
183 cmd_buf->code = MENLO_CMD_GET_CONFIG;
184 cmd_buf->get.context = 0;
185 cmd_buf->get.length = rsp_size;
186
187 #ifdef EMLXS_BIG_ENDIAN
188 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
189 #endif /* EMLXS_BIG_ENDIAN */
190
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;
196 }
197 #ifdef EMLXS_BIG_ENDIAN
198 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
199 #endif /* EMLXS_BIG_ENDIAN */
200
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);
205 }
206
207 rval = rsp_buf->code;
208
209 done:
210
211 if (cmd_buf) {
212 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
213 }
214
215 return (rval);
216
217 } /* emlxs_menlo_get_cfg() */
218
219
220
221 static uint32_t
emlxs_menlo_get_logcfg(emlxs_hba_t * hba,menlo_rsp_t * rsp_buf,uint32_t rsp_size)222 emlxs_menlo_get_logcfg(
223 emlxs_hba_t *hba,
224 menlo_rsp_t *rsp_buf,
225 uint32_t rsp_size)
226 {
227 emlxs_port_t *port = &PPORT;
228 uint32_t cmd_size;
229 menlo_cmd_t *cmd_buf = NULL;
230 uint32_t rval = 0;
231
232 if (hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
233 return (DFC_INVALID_ADAPTER);
234 }
235
236 cmd_size = sizeof (menlo_get_cmd_t);
237 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
238
239 cmd_buf->code = MENLO_CMD_GET_LOG_CONFIG;
240 cmd_buf->get.context = 0;
241 cmd_buf->get.length = rsp_size;
242
243 #ifdef EMLXS_BIG_ENDIAN
244 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
245 #endif /* EMLXS_BIG_ENDIAN */
246
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;
252 }
253 #ifdef EMLXS_BIG_ENDIAN
254 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
255 #endif /* EMLXS_BIG_ENDIAN */
256
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);
261 }
262
263 rval = rsp_buf->code;
264
265 done:
266
267 if (cmd_buf) {
268 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
269 }
270
271 return (rval);
272
273 } /* emlxs_menlo_get_logcfg() */
274
275
276 static uint32_t
emlxs_menlo_get_log(emlxs_hba_t * hba,uint32_t id,menlo_rsp_t * rsp_buf,uint32_t rsp_size)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)
282 {
283 emlxs_port_t *port = &PPORT;
284 uint32_t cmd_size;
285 menlo_cmd_t *cmd_buf = NULL;
286 uint32_t rval = 0;
287
288 if (hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
289 return (DFC_INVALID_ADAPTER);
290 }
291
292 cmd_size = sizeof (menlo_get_cmd_t);
293 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
294
295 cmd_buf->code = MENLO_CMD_GET_LOG_DATA;
296 cmd_buf->get.context = id;
297 cmd_buf->get.length = rsp_size;
298
299 #ifdef EMLXS_BIG_ENDIAN
300 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
301 #endif /* EMLXS_BIG_ENDIAN */
302
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;
308 }
309 #ifdef EMLXS_BIG_ENDIAN
310 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
311 #endif /* EMLXS_BIG_ENDIAN */
312
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);
317 }
318
319 rval = rsp_buf->code;
320
321 done:
322
323 if (cmd_buf) {
324 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
325 }
326
327 return (rval);
328
329 } /* emlxs_menlo_get_log() */
330
331
332 static uint32_t
emlxs_menlo_get_paniclog(emlxs_hba_t * hba,menlo_rsp_t * rsp_buf,uint32_t rsp_size)333 emlxs_menlo_get_paniclog(
334 emlxs_hba_t *hba,
335 menlo_rsp_t *rsp_buf,
336 uint32_t rsp_size)
337 {
338 emlxs_port_t *port = &PPORT;
339 uint32_t cmd_size;
340 menlo_cmd_t *cmd_buf = NULL;
341 uint32_t rval = 0;
342
343 if (hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
344 return (DFC_INVALID_ADAPTER);
345 }
346
347 cmd_size = sizeof (menlo_get_cmd_t);
348 cmd_buf = (menlo_cmd_t *)kmem_zalloc(cmd_size, KM_SLEEP);
349
350 cmd_buf->code = MENLO_CMD_GET_PANIC_LOG;
351 cmd_buf->get.context = 0;
352 cmd_buf->get.length = rsp_size;
353
354 #ifdef EMLXS_BIG_ENDIAN
355 emlxs_swap32_buffer((uint8_t *)cmd_buf, cmd_size);
356 #endif /* EMLXS_BIG_ENDIAN */
357
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;
363 }
364 #ifdef EMLXS_BIG_ENDIAN
365 emlxs_swap32_buffer((uint8_t *)rsp_buf, rsp_size);
366 #endif /* EMLXS_BIG_ENDIAN */
367
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);
372 }
373
374 rval = rsp_buf->code;
375
376 done:
377
378 if (cmd_buf) {
379 kmem_free(cmd_buf, sizeof (menlo_get_cmd_t));
380 }
381
382 return (rval);
383
384 } /* emlxs_menlo_get_paniclog() */
385
386
387
388
389 extern void
emlxs_fflush(emlxs_file_t * fp)390 emlxs_fflush(
391 emlxs_file_t *fp)
392 {
393 uint32_t offset;
394
395 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
396
397 if (offset > fp->size) {
398 fp->ptr = fp->buffer + fp->size;
399 }
400
401 return;
402
403 } /* emlxs_fflush() */
404
405
406 extern uint32_t
emlxs_ftell(emlxs_file_t * fp)407 emlxs_ftell(
408 emlxs_file_t *fp)
409 {
410 uint32_t offset;
411
412 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
413
414 return (offset);
415
416 } /* emlxs_ftell() */
417
418
419 static void
emlxs_fputc(uint8_t value,emlxs_file_t * fp)420 emlxs_fputc(
421 uint8_t value,
422 emlxs_file_t *fp)
423 {
424 uint32_t offset;
425
426 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
427
428 if ((offset + 1) <= fp->size) {
429 *fp->ptr++ = value;
430 }
431
432 return;
433
434 } /* emlxs_fputc() */
435
436
437 static uint32_t
emlxs_fwrite(uint8_t * buffer,uint32_t size,uint32_t nitems,emlxs_file_t * fp)438 emlxs_fwrite(
439 uint8_t *buffer,
440 uint32_t size,
441 uint32_t nitems,
442 emlxs_file_t *fp)
443 {
444 uint32_t offset;
445 uint32_t length;
446
447 length = size * nitems;
448
449 if (length) {
450 offset =
451 (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
452
453 if ((offset + length) > fp->size) {
454 length = fp->size - offset;
455 }
456
457 if (length) {
458 bcopy(buffer, fp->ptr, length);
459 fp->ptr += length;
460 }
461 }
462
463 return (length);
464
465 } /* emlxs_fwrite() */
466
467
468 static uint32_t
emlxs_fprintf(emlxs_file_t * fp,const char * fmt,...)469 emlxs_fprintf(
470 emlxs_file_t *fp,
471 const char *fmt, ...)
472 {
473 va_list valist;
474 char va_str[1024];
475 uint32_t length;
476
477 va_start(valist, fmt);
478 (void) vsnprintf(va_str, sizeof (va_str), fmt, valist);
479 va_end(valist);
480
481 length = emlxs_fwrite((uint8_t *)va_str, strlen(va_str), 1, fp);
482
483 return (length);
484
485 } /* emlxs_fprintf() */
486
487
488 extern emlxs_file_t *
emlxs_fopen(emlxs_hba_t * hba,uint32_t file_type)489 emlxs_fopen(
490 emlxs_hba_t *hba,
491 uint32_t file_type)
492 {
493 emlxs_file_t *fp;
494
495 switch (file_type) {
496 case EMLXS_TXT_FILE:
497 fp = &hba->dump_txtfile;
498 fp->size = EMLXS_TXT_FILE_SIZE;
499 break;
500
501 case EMLXS_DMP_FILE:
502 fp = &hba->dump_dmpfile;
503 fp->size = EMLXS_DMP_FILE_SIZE;
504 break;
505
506 case EMLXS_CEE_FILE:
507 fp = &hba->dump_ceefile;
508 fp->size = EMLXS_CEE_FILE_SIZE;
509 break;
510
511 default:
512 return (NULL);
513 }
514
515 /* Make sure it is word aligned */
516 fp->size &= 0xFFFFFFFC;
517
518 if (!fp->buffer) {
519 fp->buffer =
520 (uint8_t *)kmem_zalloc(fp->size, KM_SLEEP);
521
522 } else {
523 bzero(fp->buffer, fp->size);
524 }
525
526 fp->ptr = fp->buffer;
527
528 return (fp);
529
530 } /* emlxs_fopen() */
531
532
533 extern uint32_t
emlxs_fclose(emlxs_file_t * fp)534 emlxs_fclose(
535 emlxs_file_t *fp)
536 {
537 uint32_t offset;
538
539 if (fp == NULL) {
540 return (0);
541 }
542
543 offset = (uint32_t)((uintptr_t)fp->ptr - (uintptr_t)fp->buffer);
544 offset = offset % 4;
545
546 switch (offset) {
547 case 0:
548 break;
549
550 case 1:
551 *fp->ptr++ = 0;
552 *fp->ptr++ = 0;
553 *fp->ptr++ = 0;
554 break;
555
556 case 2:
557 *fp->ptr++ = 0;
558 *fp->ptr++ = 0;
559 break;
560
561 case 3:
562 *fp->ptr++ = 0;
563 break;
564 }
565
566 return (0);
567
568 } /* emlxs_fclose() */
569
570
571 static void
emlxs_fdelete(emlxs_file_t * fp)572 emlxs_fdelete(
573 emlxs_file_t *fp)
574 {
575 if (fp == NULL) {
576 return;
577 }
578
579 if (fp->buffer && fp->size) {
580 kmem_free(fp->buffer, fp->size);
581 }
582
583 fp->buffer = NULL;
584 fp->ptr = NULL;
585 fp->size = 0;
586
587 return;
588
589 } /* emlxs_fdelete() */
590
591
592 /* This builds a single core buffer for the IOCTL interface */
593 extern uint32_t
emlxs_get_dump(emlxs_hba_t * hba,uint8_t * buffer,uint32_t * buflen)594 emlxs_get_dump(
595 emlxs_hba_t *hba,
596 uint8_t *buffer,
597 uint32_t *buflen)
598 {
599 emlxs_port_t *port = &PPORT;
600 int32_t i;
601 int32_t size;
602 int32_t count;
603 uint32_t size_dmp;
604 uint32_t size_txt;
605 uint32_t size_cee;
606 emlxs_file_t *fp_txt;
607 emlxs_file_t *fp_dmp;
608 emlxs_file_t *fp_cee;
609 uint32_t *wptr;
610 uint8_t *bptr;
611
612 if (!buflen) {
613 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
614 "get_dump: Buffer length = 0");
615 return (1);
616 }
617
618 fp_txt = &hba->dump_txtfile;
619 fp_dmp = &hba->dump_dmpfile;
620 fp_cee = &hba->dump_ceefile;
621
622 size_txt = emlxs_ftell(fp_txt);
623 size_dmp = emlxs_ftell(fp_dmp);
624 size_cee = emlxs_ftell(fp_cee);
625
626 size = 0;
627 count = 0;
628 if (size_txt) {
629 count++;
630 size += size_txt + 8;
631 }
632 if (size_dmp) {
633 count++;
634 size += size_dmp + 8;
635 }
636 if (size_cee) {
637 count++;
638 size += size_cee + 8;
639 }
640
641 if (size) {
642 size += 4;
643 }
644
645 if (!buffer) {
646 goto done;
647 }
648
649 bzero(buffer, *buflen);
650
651 if (*buflen < size) {
652 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
653 "get_dump: Buffer length too small. %d < %d",
654 *buflen, size);
655
656 *buflen = 0;
657 return (1);
658 }
659
660 wptr = (uint32_t *)buffer;
661 wptr[0] = count;
662 i = 1;
663
664 if (size_txt) {
665 wptr[i++] = EMLXS_TXT_FILE_ID;
666 wptr[i++] = size_txt;
667 }
668
669 if (size_dmp) {
670 wptr[i++] = EMLXS_DMP_FILE_ID;
671 wptr[i++] = size_dmp;
672 }
673
674 if (size_cee) {
675 if ((hba->model_info.chip == EMLXS_BE2_CHIP) ||
676 (hba->model_info.chip == EMLXS_BE3_CHIP)) {
677 wptr[i++] = EMLXS_FAT_FILE_ID;
678 } else {
679 wptr[i++] = EMLXS_CEE_FILE_ID;
680 }
681
682 wptr[i++] = size_cee;
683 }
684
685 bptr = (uint8_t *)&wptr[i];
686
687 if (size_txt) {
688 bcopy(fp_txt->buffer, bptr, size_txt);
689 bptr += size_txt;
690 }
691
692 if (size_dmp) {
693 bcopy(fp_dmp->buffer, bptr, size_dmp);
694 bptr += size_dmp;
695 }
696
697 if (size_cee) {
698 bcopy(fp_cee->buffer, bptr, size_cee);
699 bptr += size_cee;
700 }
701
702 done:
703
704 *buflen = size;
705
706 /* printf("Done. buflen=%d \n", *buflen); */
707
708 return (0);
709
710 } /* emlxs_get_dump() */
711
712
713 static uint32_t
emlxs_read_cfg_region(emlxs_hba_t * hba,uint32_t Identifier,uint32_t ByteCount,uint32_t * pRetByteCount,uint8_t * pBuffer)714 emlxs_read_cfg_region(
715 emlxs_hba_t *hba,
716 uint32_t Identifier,
717 uint32_t ByteCount,
718 uint32_t *pRetByteCount,
719 uint8_t *pBuffer)
720 {
721 emlxs_port_t *port = &PPORT;
722 MAILBOXQ *mbq;
723 uint32_t ByteCountRem; /* remaining portion of original byte count */
724 uint32_t ByteCountReq; /* requested byte count for a particular dump */
725 uint32_t CopyCount; /* bytes to copy after each successful dump */
726 uint32_t Offset; /* Offset into Config Region, for each dump */
727 uint8_t *pLocalBuf; /* ptr to buffer to receive each dump */
728
729 if (! ByteCount) {
730 return (0);
731 }
732
733 mbq =
734 (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP);
735
736 pLocalBuf = pBuffer; /* init local pointer to caller's buffer */
737 Offset = 0; /* start at offset 0 */
738 *pRetByteCount = 0; /* init returned byte count */
739 CopyCount = 0;
740
741 for (ByteCountRem = ByteCount; ByteCountRem > 0;
742 ByteCountRem -= CopyCount) {
743
744 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
745 MAILBOX4 *mb = (MAILBOX4 *)mbq;
746
747 ByteCountReq =
748 (ByteCountRem < hba->sli.sli4.dump_region.size) ?
749 ByteCountRem : hba->sli.sli4.dump_region.size;
750
751 /* Clear the local dump_region */
752 bzero(hba->sli.sli4.dump_region.virt,
753 hba->sli.sli4.dump_region.size);
754
755 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
756
757 mb->mbxCommand = MBX_DUMP_MEMORY;
758 mb->un.varDmp4.type = DMP_NV_PARAMS;
759 mb->un.varDmp4.entry_index = Offset;
760 mb->un.varDmp4.region_id = Identifier;
761
762 mb->un.varDmp4.available_cnt = ByteCountReq;
763 mb->un.varDmp4.addrHigh =
764 PADDR_HI(hba->sli.sli4.dump_region.phys);
765 mb->un.varDmp4.addrLow =
766 PADDR_LO(hba->sli.sli4.dump_region.phys);
767 mb->un.varDmp4.rsp_cnt = 0;
768
769 mb->mbxOwner = OWN_HOST;
770 mbq->mbox_cmpl = NULL;
771
772 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
773 MBX_SUCCESS) {
774 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
775 "Unable to read config region. id=%x "\
776 "offset=%x status=%x",
777 Identifier, Offset, mb->mbxStatus);
778
779 kmem_free(mbq, sizeof (MAILBOXQ));
780 return (1);
781 }
782
783 CopyCount = mb->un.varDmp4.rsp_cnt;
784
785 /* if no more data returned */
786 if (CopyCount == 0) {
787 break;
788 }
789
790 if (CopyCount > ByteCountReq) {
791 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
792 "read_cfg_region: " \
793 "Byte count too big. %d > %d\n",
794 CopyCount, ByteCountReq);
795
796 CopyCount = ByteCountReq;
797 }
798
799 bcopy((uint8_t *)hba->sli.sli4.dump_region.virt,
800 pLocalBuf, CopyCount);
801
802 } else {
803 MAILBOX *mb = (MAILBOX *)mbq;
804
805 ByteCountReq =
806 (ByteCountRem < DUMP_BC_MAX) ? ByteCountRem :
807 DUMP_BC_MAX;
808
809 bzero((void *)mb, MAILBOX_CMD_BSIZE);
810
811 mb->mbxCommand = MBX_DUMP_MEMORY;
812 mb->un.varDmp.type = DMP_NV_PARAMS;
813 mb->un.varDmp.cv = 1;
814 mb->un.varDmp.region_id = Identifier;
815 mb->un.varDmp.entry_index = Offset;
816 mb->un.varDmp.word_cnt = ByteCountReq / 4;
817 mb->mbxOwner = OWN_HOST;
818 mbq->mbox_cmpl = NULL;
819
820 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
821 MBX_SUCCESS) {
822 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
823 "Unable to read config region. id=%x "\
824 "offset=%x status=%x",
825 Identifier, Offset, mb->mbxStatus);
826
827 kmem_free(mbq, sizeof (MAILBOXQ));
828 return (1);
829 }
830
831 /* Note: for Type 2/3 Dumps, varDmp.word_cnt is */
832 /* actually a byte count. */
833 CopyCount = mb->un.varDmp.word_cnt;
834
835 /* if no more data returned */
836 if (CopyCount == 0) {
837 break;
838 }
839
840 if (CopyCount > ByteCountReq) {
841 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
842 "read_cfg_region: " \
843 "Byte count too big. %d > %d\n",
844 CopyCount, ByteCountReq);
845
846 CopyCount = ByteCountReq;
847 }
848
849 bcopy((uint8_t *)&mb->un.varDmp.resp_offset, pLocalBuf,
850 CopyCount);
851 }
852
853 pLocalBuf += CopyCount;
854 Offset += CopyCount;
855 *pRetByteCount += CopyCount;
856 }
857
858 return (0);
859
860 } /* emlxs_read_cfg_region() */
861
862
863
864 /* ************************************************************************* */
865 /* ************************************************************************* */
866 /* Dump Generators, Low-Level */
867 /* ************************************************************************* */
868 /* ************************************************************************* */
869
870 static uint32_t
emlxs_dump_string_txtfile(emlxs_file_t * fpTxtFile,char * pString,char * pSidLegend,char * pLidLegend,uint32_t pure)871 emlxs_dump_string_txtfile(
872 emlxs_file_t *fpTxtFile,
873 char *pString,
874 char *pSidLegend,
875 char *pLidLegend,
876 uint32_t pure)
877 {
878
879 if (!fpTxtFile) {
880 return (1);
881 }
882
883 if (pSidLegend && pLidLegend) {
884 (void) emlxs_fprintf(fpTxtFile, "%s: %s\n", pSidLegend,
885 pLidLegend);
886
887 if (pure == 0) {
888 emlxs_fputc(' ', fpTxtFile);
889 }
890
891 (void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1,
892 fpTxtFile);
893
894 if (pure == 0) {
895 emlxs_fputc('\n', fpTxtFile);
896 emlxs_fputc('\n', fpTxtFile);
897 }
898 } else {
899 if (pure == 0) {
900 emlxs_fputc(' ', fpTxtFile);
901 }
902 (void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1,
903 fpTxtFile);
904 }
905
906 emlxs_fflush(fpTxtFile);
907
908 return (0);
909
910 } /* emlxs_dump_string_txtfile() */
911
912
913 static uint32_t
emlxs_dump_word_txtfile(emlxs_file_t * fpTxtFile,uint32_t * pBuffer,uint32_t WordCount,char * pSidLegend,char * pLidLegend)914 emlxs_dump_word_txtfile(
915 emlxs_file_t *fpTxtFile,
916 uint32_t *pBuffer,
917 uint32_t WordCount,
918 char *pSidLegend,
919 char *pLidLegend)
920 {
921 char buf1[256];
922 char buf2[256];
923 uint32_t *ptr;
924 uint32_t j;
925
926 if (!fpTxtFile) {
927 return (1);
928 }
929
930 /* Write Legend String to the TXT File */
931 (void) emlxs_fprintf(fpTxtFile, "%s: %s\n", pSidLegend, pLidLegend);
932
933 /* Write the buffer to the TXT File */
934 ptr = pBuffer;
935
936 for (j = 0; j < WordCount; j++) {
937 buf1[0] = 0;
938 buf2[0] = 0;
939
940 if ((j & 0x03) == 0) {
941 (void) snprintf(buf1, sizeof (buf1), "\n%04x:", j * 4);
942 (void) strlcat(buf2, buf1, sizeof (buf2));
943 }
944 /* print 1 word */
945 (void) snprintf(buf1, sizeof (buf1), " %08x", ptr[j]);
946 (void) strlcat(buf2, buf1, sizeof (buf2));
947 (void) emlxs_fwrite((uint8_t *)buf2, strlen(buf2), 1,
948 fpTxtFile);
949 }
950
951 emlxs_fputc('\n', fpTxtFile);
952 emlxs_fputc('\n', fpTxtFile);
953 emlxs_fflush(fpTxtFile);
954 return (0);
955
956 } /* emlxs_dump_word_txtfile() */
957
958
959
960
961 static uint32_t
emlxs_dump_string_dmpfile(emlxs_file_t * fpDmpFile,char * pString,uint8_t sid,char * pSidLegend,char * pLidLegend)962 emlxs_dump_string_dmpfile(
963 emlxs_file_t *fpDmpFile,
964 char *pString,
965 uint8_t sid,
966 char *pSidLegend,
967 char *pLidLegend)
968 {
969 uint32_t length;
970 uint8_t byte;
971 uint32_t pos;
972
973 if (!fpDmpFile) {
974 return (1);
975 }
976
977 /* Write Legend SID to the DMP File */
978 emlxs_fputc(SID_LEGEND, fpDmpFile);
979
980 /* Write Argument SID to the DMP File */
981 emlxs_fputc(sid, fpDmpFile);
982
983 /* Write Legend String to the DMP File, including a Null Byte */
984 (void) emlxs_fprintf(fpDmpFile, "%s: %s", pSidLegend, pLidLegend);
985 emlxs_fputc(0, fpDmpFile);
986
987 /* Write Argument SID to the DMP File */
988 emlxs_fputc(sid, fpDmpFile);
989
990 /* Write Buffer Length to the DMP File */
991 length = (uint32_t)(strlen(pString) + 1);
992 #ifdef EMLXS_LITTLE_ENDIAN
993 byte = (uint8_t)(length & 0x0000FF);
994 emlxs_fputc(byte, fpDmpFile);
995 byte = (uint8_t)((length & 0x00FF00) >> 8);
996 emlxs_fputc(byte, fpDmpFile);
997 byte = (uint8_t)((length & 0xFF0000) >> 16);
998 emlxs_fputc(byte, fpDmpFile);
999 #endif /* EMLXS_LITTLE_ENDIAN */
1000
1001 #ifdef EMLXS_BIG_ENDIAN
1002 byte = (uint8_t)((length & 0xFF0000) >> 16);
1003 emlxs_fputc(byte, fpDmpFile);
1004 byte = (uint8_t)((length & 0x00FF00) >> 8);
1005 emlxs_fputc(byte, fpDmpFile);
1006 byte = (uint8_t)(length & 0x0000FF);
1007 emlxs_fputc(byte, fpDmpFile);
1008 #endif /* EMLXS_BIG_ENDIAN */
1009
1010 /* Write Argument String to the DMP File, including a Null Byte */
1011 (void) emlxs_fwrite((uint8_t *)pString, strlen(pString), 1, fpDmpFile);
1012 emlxs_fputc(0, fpDmpFile);
1013
1014 emlxs_fflush(fpDmpFile);
1015
1016 #if CC_DUMP_ENABLE_PAD
1017 /* check file size.. pad as necessary */
1018 pos = emlxs_ftell(fpDmpFile);
1019 switch (pos & 0x03) {
1020 case 0:
1021 break;
1022 case 1:
1023 emlxs_fputc(0, fpDmpFile);
1024 emlxs_fputc(0, fpDmpFile);
1025 emlxs_fputc(0, fpDmpFile);
1026 break;
1027 case 2:
1028 emlxs_fputc(0, fpDmpFile);
1029 emlxs_fputc(0, fpDmpFile);
1030 break;
1031 case 3:
1032 emlxs_fputc(0, fpDmpFile);
1033 break;
1034 }
1035 emlxs_fflush(fpDmpFile);
1036 #endif
1037
1038 return (0);
1039
1040 } /* emlxs_dump_string_dmpfile() */
1041
1042
1043 /* ************************************************************************** */
1044 /* emlxs_dump_word_dmpfile */
1045 /* If little endian, just write the buffer normally. */
1046 /* However, if Big Endian... Consider the following: */
1047 /* Automatic Dump, initiated by driver, Port Offline (FW WarmStart Mode), */
1048 /* Mailbox in SLIM. */
1049 /* On-Demand Dump, initiated by utility, Port Online (FW Normal Mode), */
1050 /* Mailbox in Host Memory. */
1051 /* We use the same IOCTL to get the DUMP Data, for both cases. */
1052 /* However, it normalizes the data before delivering it to us. */
1053 /* In the Dump File, we must always write the data in native mode. */
1054 /* So, if Big Endian, On-demand Dump, we must swap the words. */
1055 /* ************************************************************************* */
1056 /*ARGSUSED*/
1057 extern uint32_t
emlxs_dump_word_dmpfile(emlxs_file_t * fpDmpFile,uint8_t * pBuffer,uint32_t bufferLen,int fSwap)1058 emlxs_dump_word_dmpfile(
1059 emlxs_file_t *fpDmpFile,
1060 uint8_t *pBuffer,
1061 uint32_t bufferLen,
1062 int fSwap)
1063 {
1064 uint32_t i;
1065 uint32_t *wptr;
1066
1067 if (!fpDmpFile) {
1068 return (1);
1069 }
1070
1071 wptr = (uint32_t *)pBuffer;
1072 for (i = 0; i < bufferLen / 4; i++, wptr++) {
1073 if (fSwap) {
1074 uint32_t w1;
1075 w1 = *wptr;
1076 *wptr = BE_SWAP32(w1);
1077 }
1078
1079 (void) emlxs_fwrite((uint8_t *)wptr, 4, 1, fpDmpFile);
1080 }
1081
1082 emlxs_fflush(fpDmpFile);
1083
1084 return (0);
1085
1086 } /* emlxs_dump_word_dmpfile() */
1087
1088
1089 static uint32_t
emlxs_dump_port_block(emlxs_file_t * fpDmpFile,uint8_t * pBuffer,uint32_t bufferLen,DUMP_TABLE_ENTRY entry,int fSwap)1090 emlxs_dump_port_block(
1091 emlxs_file_t *fpDmpFile,
1092 uint8_t *pBuffer,
1093 uint32_t bufferLen,
1094 DUMP_TABLE_ENTRY entry,
1095 int fSwap)
1096 {
1097 uint32_t status;
1098 uint32_t w;
1099 uint8_t b;
1100
1101 if (!fpDmpFile) {
1102 return (1);
1103 }
1104
1105 /* Write Argument SID to the DMP File */
1106 b = (uint8_t)entry.un.PortBlock.un.s.sid;
1107 emlxs_fputc(b, fpDmpFile);
1108
1109 #ifdef EMLXS_LITTLE_ENDIAN
1110 /* Write Buffer Length to the DMP File */
1111 w = entry.un.PortBlock.un.s.bc;
1112 b = (uint8_t)(w & 0x000000FF);
1113 emlxs_fputc(b, fpDmpFile);
1114 b = (uint8_t)((w & 0x0000FF00) >> 8);
1115 emlxs_fputc(b, fpDmpFile);
1116 b = (uint8_t)((w & 0x00FF0000) >> 16);
1117 emlxs_fputc(b, fpDmpFile);
1118
1119 /* Write address to the DMP File */
1120 w = entry.un.PortBlock.un.s.addr;
1121 b = (uint8_t)(w & 0x000000FF);
1122 emlxs_fputc(b, fpDmpFile);
1123 b = (uint8_t)((w & 0x0000FF00) >> 8);
1124 emlxs_fputc(b, fpDmpFile);
1125 b = (uint8_t)((w & 0x00FF0000) >> 16);
1126 emlxs_fputc(b, fpDmpFile);
1127 b = (uint8_t)((w & 0xFF000000) >> 24);
1128 emlxs_fputc(b, fpDmpFile);
1129 #endif /* EMLXS_LITTLE_ENDIAN */
1130
1131 #ifdef EMLXS_BIG_ENDIAN
1132 /* Write Buffer Length to the DMP File */
1133 w = entry.un.PortBlock.un.s.bc;
1134 b = (uint8_t)((w & 0x00FF0000) >> 16);
1135 emlxs_fputc(b, fpDmpFile);
1136 b = (uint8_t)((w & 0x0000FF00) >> 8);
1137 emlxs_fputc(b, fpDmpFile);
1138 b = (uint8_t)(w & 0x000000FF);
1139 emlxs_fputc(b, fpDmpFile);
1140
1141 /* Write address to the DMP File */
1142 w = entry.un.PortBlock.un.s.addr;
1143 b = (uint8_t)((w & 0xFF000000) >> 24);
1144 emlxs_fputc(b, fpDmpFile);
1145 b = (uint8_t)((w & 0x00FF0000) >> 16);
1146 emlxs_fputc(b, fpDmpFile);
1147 b = (uint8_t)((w & 0x0000FF00) >> 8);
1148 emlxs_fputc(b, fpDmpFile);
1149 b = (uint8_t)(w & 0x000000FF);
1150 emlxs_fputc(b, fpDmpFile);
1151 #endif /* EMLXS_BIG_ENDIAN */
1152
1153 status =
1154 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
1155
1156 emlxs_fflush(fpDmpFile);
1157
1158 return (status);
1159
1160 } /* emlxs_dump_port_block() */
1161
1162
1163 static uint32_t
emlxs_dump_port_struct(emlxs_file_t * fpDmpFile,uint8_t * pBuffer,uint32_t bufferLen,DUMP_TABLE_ENTRY entry,int fSwap)1164 emlxs_dump_port_struct(
1165 emlxs_file_t *fpDmpFile,
1166 uint8_t *pBuffer,
1167 uint32_t bufferLen,
1168 DUMP_TABLE_ENTRY entry,
1169 int fSwap)
1170 {
1171 uint32_t status;
1172 uint32_t w;
1173 uint8_t b;
1174
1175 if (!fpDmpFile) {
1176 return (1);
1177 }
1178
1179 /* Write Argument SID to the DMP File */
1180 b = (uint8_t)entry.un.PortStruct.un.s.sid;
1181 emlxs_fputc(b, fpDmpFile);
1182
1183 /* Write Element Length to the DMP File */
1184 b = (uint8_t)entry.un.PortStruct.un.s.length;
1185 emlxs_fputc(b, fpDmpFile);
1186
1187 #ifdef EMLXS_LITTLE_ENDIAN
1188 /* Write Element Count to the DMP File */
1189 w = entry.un.PortStruct.un.s.count;
1190 b = (uint8_t)(w & 0x000000FF);
1191 emlxs_fputc(b, fpDmpFile);
1192 b = (uint8_t)((w & 0x0000FF00) >> 8);
1193 emlxs_fputc(b, fpDmpFile);
1194
1195 /* Write Address to the DMP File */
1196 w = entry.un.PortStruct.un.s.addr;
1197 b = (uint8_t)(w & 0x000000FF);
1198 emlxs_fputc(b, fpDmpFile);
1199 b = (uint8_t)((w & 0x0000FF00) >> 8);
1200 emlxs_fputc(b, fpDmpFile);
1201 b = (uint8_t)((w & 0x00FF0000) >> 16);
1202 emlxs_fputc(b, fpDmpFile);
1203 b = (uint8_t)((w & 0xFF000000) >> 24);
1204 emlxs_fputc(b, fpDmpFile);
1205 #endif /* EMLXS_LITTLE_ENDIAN */
1206
1207 #ifdef EMLXS_BIG_ENDIAN
1208 /* Write Element Count to the DMP File */
1209 w = entry.un.PortStruct.un.s.count;
1210 b = (uint8_t)((w & 0x0000FF00) >> 8);
1211 emlxs_fputc(b, fpDmpFile);
1212 b = (uint8_t)(w & 0x000000FF);
1213 emlxs_fputc(b, fpDmpFile);
1214
1215 /* Write Address to the DMP File */
1216 w = entry.un.PortStruct.un.s.addr;
1217 b = (uint8_t)((w & 0xFF000000) >> 24);
1218 emlxs_fputc(b, fpDmpFile);
1219 b = (uint8_t)((w & 0x00FF0000) >> 16);
1220 emlxs_fputc(b, fpDmpFile);
1221 b = (uint8_t)((w & 0x0000FF00) >> 8);
1222 emlxs_fputc(b, fpDmpFile);
1223 b = (uint8_t)(w & 0x000000FF);
1224 emlxs_fputc(b, fpDmpFile);
1225 #endif /* EMLXS_BIG_ENDIAN */
1226
1227 status =
1228 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
1229
1230 emlxs_fflush(fpDmpFile);
1231
1232 return (status);
1233
1234 } /* emlxs_dump_port_struct() */
1235
1236
1237 static uint32_t
emlxs_dump_host_block(emlxs_file_t * fpDmpFile,uint8_t * pBuffer,uint32_t bufferLen,uint8_t sid,char * pSidLegend,char * pLidLegend,int fSwap)1238 emlxs_dump_host_block(
1239 emlxs_file_t *fpDmpFile,
1240 uint8_t *pBuffer,
1241 uint32_t bufferLen,
1242 uint8_t sid,
1243 char *pSidLegend,
1244 char *pLidLegend,
1245 int fSwap)
1246 {
1247 uint32_t status;
1248 uint32_t length;
1249 uint8_t byte;
1250
1251 if (!fpDmpFile) {
1252 return (1);
1253 }
1254
1255 /* Write Legend SID to the DMP File */
1256 emlxs_fputc(SID_LEGEND, fpDmpFile);
1257
1258 /* Write Argument SID to the DMP File */
1259 emlxs_fputc(sid, fpDmpFile);
1260
1261 /* Write Legend String to the DMP File, including a Null Byte */
1262 (void) emlxs_fprintf(fpDmpFile, "%s: %s", pSidLegend, pLidLegend);
1263 emlxs_fputc(0, fpDmpFile);
1264
1265 /* Write Argument SID to the DMP File */
1266 emlxs_fputc(sid, fpDmpFile);
1267
1268 /* Write Buffer Length to the DMP File */
1269 length = bufferLen;
1270 #ifdef EMLXS_LITTLE_ENDIAN
1271 byte = (uint8_t)(length & 0x0000FF);
1272 emlxs_fputc(byte, fpDmpFile);
1273 byte = (uint8_t)((length & 0x00FF00) >> 8);
1274 emlxs_fputc(byte, fpDmpFile);
1275 byte = (uint8_t)((length & 0xFF0000) >> 16);
1276 emlxs_fputc(byte, fpDmpFile);
1277 #endif /* EMLXS_LITTLE_ENDIAN */
1278
1279 #ifdef EMLXS_BIG_ENDIAN
1280 byte = (uint8_t)((length & 0xFF0000) >> 16);
1281 emlxs_fputc(byte, fpDmpFile);
1282 byte = (uint8_t)((length & 0x00FF00) >> 8);
1283 emlxs_fputc(byte, fpDmpFile);
1284 byte = (uint8_t)(length & 0x0000FF);
1285 emlxs_fputc(byte, fpDmpFile);
1286 #endif /* EMLXS_BIG_ENDIAN */
1287
1288 status =
1289 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
1290
1291 emlxs_fflush(fpDmpFile);
1292
1293 return (status);
1294
1295 } /* emlxs_dump_host_block() */
1296
1297
1298 static uint32_t
emlxs_dump_host_struct(emlxs_file_t * fpDmpFile,uint8_t * pBuffer,uint32_t bufferLen,uint32_t elementLength,uint32_t elementCount,uint8_t sid,char * pSidLegend,char * pLidLegend,int fSwap)1299 emlxs_dump_host_struct(
1300 emlxs_file_t *fpDmpFile,
1301 uint8_t *pBuffer,
1302 uint32_t bufferLen,
1303 uint32_t elementLength,
1304 uint32_t elementCount,
1305 uint8_t sid,
1306 char *pSidLegend,
1307 char *pLidLegend,
1308 int fSwap)
1309 {
1310 uint32_t status;
1311 uint32_t w;
1312 uint8_t b;
1313
1314 if (!fpDmpFile) {
1315 return (1);
1316 }
1317
1318 /* Write Legend SID to the DMP File */
1319 emlxs_fputc(SID_LEGEND, fpDmpFile);
1320
1321 /* Write Argument SID to the DMP File */
1322 emlxs_fputc(sid, fpDmpFile);
1323
1324 /* Write Legend String to the DMP File, including a Null Byte */
1325 (void) emlxs_fprintf(fpDmpFile, "%s: %s", pSidLegend, pLidLegend);
1326 emlxs_fputc(0, fpDmpFile);
1327
1328 /* Write Argument SID to the DMP File */
1329 emlxs_fputc(sid, fpDmpFile);
1330
1331 /* Write Element Length to the DMP File */
1332 b = (uint8_t)elementLength;
1333 emlxs_fputc(b, fpDmpFile);
1334
1335 /* Write Element Count to the DMP File */
1336 w = elementCount;
1337 #ifdef EMLXS_LITTLE_ENDIAN
1338 b = (uint8_t)(w & 0x000000FF);
1339 emlxs_fputc(b, fpDmpFile);
1340 b = (uint8_t)((w & 0x0000FF00) >> 8);
1341 emlxs_fputc(b, fpDmpFile);
1342 #endif /* EMLXS_LITTLE_ENDIAN */
1343
1344 #ifdef EMLXS_BIG_ENDIAN
1345 b = (uint8_t)((w & 0x0000FF00) >> 8);
1346 emlxs_fputc(b, fpDmpFile);
1347 b = (uint8_t)(w & 0x000000FF);
1348 emlxs_fputc(b, fpDmpFile);
1349 #endif /* EMLXS_BIG_ENDIAN */
1350
1351 status =
1352 emlxs_dump_word_dmpfile(fpDmpFile, pBuffer, bufferLen, fSwap);
1353
1354 emlxs_fflush(fpDmpFile);
1355
1356 return (status);
1357
1358 } /* emlxs_dump_host_struct() */
1359
1360
1361 /* ************************************************************************* */
1362 /* ************************************************************************* */
1363 /* Dump Generators, Mid-Level */
1364 /* ************************************************************************* */
1365 /* ************************************************************************* */
1366
1367 static uint32_t
emlxs_dump_parm_table(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)1368 emlxs_dump_parm_table(
1369 emlxs_hba_t *hba,
1370 emlxs_file_t *fpTxtFile,
1371 emlxs_file_t *fpDmpFile)
1372 {
1373 emlxs_config_t *cfg = &CFG;
1374 uint32_t status;
1375 uint32_t i;
1376
1377 /* vars used to build the Dump String */
1378 char *buf1;
1379 char *buf2;
1380
1381 buf1 = (char *)kmem_zalloc(8192, KM_SLEEP);
1382 buf2 = (char *)kmem_zalloc(8192, KM_SLEEP);
1383
1384 /* Driver Parameters Heading */
1385 (void) snprintf(buf1, 8192,
1386 "IDX string Low "\
1387 "High Def Cur Exp Dyn");
1388
1389 /* Build the buffer containing all the Driver Params */
1390 for (i = 0; i < NUM_CFG_PARAM; i++) {
1391 (void) snprintf(buf2, 8192,
1392 "\n %02x: %25s %8x %8x %8x %8x %4x %4x", i,
1393 cfg[i].string, cfg[i].low, cfg[i].hi, cfg[i].def,
1394 cfg[i].current, (cfg[i].flags & PARM_HIDDEN) ? 0 : 1,
1395 (cfg[i].flags & PARM_DYNAMIC) ? 1 : 0);
1396
1397 (void) strlcat(buf1, buf2, 8192);
1398 }
1399
1400 status =
1401 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_DP_TABLE,
1402 LEGEND_NULL, 0);
1403
1404 status =
1405 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_DP_TABLE,
1406 LEGEND_DP_TABLE, LEGEND_NULL);
1407
1408 kmem_free(buf1, 8192);
1409 kmem_free(buf2, 8192);
1410
1411 return (status);
1412
1413 } /* emlxs_dump_parm_table() */
1414
1415
1416 static uint32_t
emlxs_dump_model(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)1417 emlxs_dump_model(
1418 emlxs_hba_t *hba,
1419 emlxs_file_t *fpTxtFile,
1420 emlxs_file_t *fpDmpFile)
1421 {
1422 emlxs_vpd_t *vpd = &VPD;
1423 uint32_t status;
1424
1425 /* vars used to build the Dump String */
1426 char buf1[512];
1427 char buf2[512];
1428
1429 /* Write the Model into the buffer */
1430 (void) snprintf(buf2, sizeof (buf2), "%s", vpd->model);
1431 (void) strlcpy(buf1, "Model: ", sizeof (buf1));
1432 (void) strlcat(buf1, buf2, sizeof (buf1));
1433
1434 /* Write the Model Description into the buffer */
1435 (void) snprintf(buf2, sizeof (buf2), "%s", vpd->model_desc);
1436 (void) strlcat(buf1, "\n Description: ", sizeof (buf1));
1437 (void) strlcat(buf1, buf2, sizeof (buf1));
1438
1439 status =
1440 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
1441 LEGEND_HBA_MODEL, 0);
1442
1443 status =
1444 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
1445 LEGEND_HBA_INFO, LEGEND_HBA_MODEL);
1446
1447 return (status);
1448
1449 } /* emlxs_dump_model() */
1450
1451
1452 static uint32_t
emlxs_dump_wwn(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)1453 emlxs_dump_wwn(
1454 emlxs_hba_t *hba,
1455 emlxs_file_t *fpTxtFile,
1456 emlxs_file_t *fpDmpFile)
1457 {
1458 uint32_t status;
1459
1460 /* vars used to build the Dump String */
1461 char buf1[512];
1462 char buf2[512];
1463 int i;
1464 uint8_t *p;
1465
1466 /* Write the WWPN into the buffer */
1467 (void) strlcpy(buf1, "Port WWN: ", sizeof (buf1));
1468 p = (uint8_t *)&hba->wwpn;
1469 for (i = 0; i < 7; i++) {
1470 (void) snprintf(buf2, sizeof (buf2), "%02x:", *p++);
1471 (void) strlcat(buf1, buf2, sizeof (buf1));
1472 }
1473 (void) snprintf(buf2, sizeof (buf2), "%02x", *p++);
1474 (void) strlcat(buf1, buf2, sizeof (buf1));
1475
1476 /* Write the WWNN into the buffer */
1477 (void) strlcat(buf1, "\n Node WWN: ", sizeof (buf1));
1478 p = (uint8_t *)&hba->wwnn;
1479 for (i = 0; i < 7; i++) {
1480 (void) snprintf(buf2, sizeof (buf2), "%02x:", *p++);
1481 (void) strlcat(buf1, buf2, sizeof (buf1));
1482 }
1483 (void) snprintf(buf2, sizeof (buf2), "%02x", *p++);
1484 (void) strlcat(buf1, buf2, sizeof (buf1));
1485
1486 status =
1487 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
1488 LEGEND_HBA_WWN, 0);
1489
1490 status =
1491 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
1492 LEGEND_HBA_INFO, LEGEND_HBA_WWN);
1493
1494 return (status);
1495
1496 } /* emlxs_dump_wwn() */
1497
1498
1499 static uint32_t
emlxs_dump_serial_number(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)1500 emlxs_dump_serial_number(
1501 emlxs_hba_t *hba,
1502 emlxs_file_t *fpTxtFile,
1503 emlxs_file_t *fpDmpFile)
1504 {
1505 emlxs_vpd_t *vpd = &VPD;
1506 uint32_t status;
1507
1508 /* vars used to build the Dump String */
1509 char buf1[512];
1510 char buf2[512];
1511
1512 /* Write the Serial Number into the buffer */
1513 (void) snprintf(buf2, sizeof (buf2), "%s", vpd->serial_num);
1514 (void) strlcpy(buf1, LEGEND_HBA_SN, sizeof (buf1));
1515 (void) strlcat(buf1, ": ", sizeof (buf1));
1516 (void) strlcat(buf1, buf2, sizeof (buf1));
1517
1518 status =
1519 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
1520 LEGEND_HBA_SN, 0);
1521
1522 status =
1523 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
1524 LEGEND_HBA_INFO, LEGEND_HBA_SN);
1525
1526 return (status);
1527
1528 } /* emlxs_dump_serial_number() */
1529
1530
1531 static uint32_t
emlxs_dump_fw_version(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)1532 emlxs_dump_fw_version(
1533 emlxs_hba_t *hba,
1534 emlxs_file_t *fpTxtFile,
1535 emlxs_file_t *fpDmpFile)
1536 {
1537 emlxs_vpd_t *vpd = &VPD;
1538 uint32_t status;
1539
1540 char *buf1;
1541 char *buf2;
1542 uint32_t buf1_size;
1543 uint32_t buf2_size;
1544
1545 buf1_size = 1024;
1546 buf2_size = 1024;
1547
1548 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
1549 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
1550
1551 /* Write the Firmware Version into the buffer */
1552 (void) snprintf(buf2, buf2_size, "%s", vpd->fw_version);
1553 (void) strlcpy(buf1, LEGEND_HBA_FW_VERSION, buf1_size);
1554 (void) strlcat(buf1, ": ", buf1_size);
1555 (void) strlcat(buf1, buf2, buf1_size);
1556
1557 /* Write the Operational FW Version into the buffer */
1558 (void) snprintf(buf2, buf2_size, "%s", vpd->opFwName);
1559 (void) strlcat(buf1, "\n ", buf1_size);
1560 (void) strlcat(buf1, LEGEND_HBA_FW_OPVERSION, buf1_size);
1561 (void) strlcat(buf1, ": ", buf1_size);
1562 (void) strlcat(buf1, buf2, buf1_size);
1563
1564 /* Write the SLI-1 FW Version into the buffer */
1565 (void) snprintf(buf2, buf2_size, "%s", vpd->sli1FwName);
1566 (void) strlcat(buf1, "\n ", buf1_size);
1567 (void) strlcat(buf1, LEGEND_HBA_FW_SLI1VERSION, buf1_size);
1568 (void) strlcat(buf1, ": ", buf1_size);
1569 (void) strlcat(buf1, buf2, buf1_size);
1570
1571 /* Write the SLI-2 FW Version into the buffer */
1572 (void) snprintf(buf2, buf2_size, "%s", vpd->sli2FwName);
1573 (void) strlcat(buf1, "\n ", buf1_size);
1574 (void) strlcat(buf1, LEGEND_HBA_FW_SLI2VERSION, buf1_size);
1575 (void) strlcat(buf1, ": ", buf1_size);
1576 (void) strlcat(buf1, buf2, buf1_size);
1577
1578 /* Write the SLI-3 FW Version into the buffer */
1579 (void) snprintf(buf2, buf2_size, "%s", vpd->sli3FwName);
1580 (void) strlcat(buf1, "\n ", buf1_size);
1581 (void) strlcat(buf1, LEGEND_HBA_FW_SLI3VERSION, buf1_size);
1582 (void) strlcat(buf1, ": ", buf1_size);
1583 (void) strlcat(buf1, buf2, buf1_size);
1584
1585 /* Write the Kernel FW Version into the buffer */
1586 (void) snprintf(buf2, buf2_size, "%s", vpd->postKernName);
1587 (void) strlcat(buf1, "\n ", buf1_size);
1588 (void) strlcat(buf1, LEGEND_HBA_FW_KERNELVERSION, buf1_size);
1589 (void) strlcat(buf1, ": ", buf1_size);
1590 (void) strlcat(buf1, buf2, buf1_size);
1591
1592 status =
1593 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
1594 LEGEND_HBA_FW_VERSION, 0);
1595
1596 status =
1597 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
1598 LEGEND_HBA_INFO, LEGEND_HBA_FW_VERSION);
1599
1600 kmem_free(buf1, buf1_size);
1601 kmem_free(buf2, buf2_size);
1602
1603 return (status);
1604
1605 } /* emlxs_dump_fw_version() */
1606
1607
1608 static uint32_t
emlxs_dump_boot_version(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)1609 emlxs_dump_boot_version(
1610 emlxs_hba_t *hba,
1611 emlxs_file_t *fpTxtFile,
1612 emlxs_file_t *fpDmpFile)
1613 {
1614 emlxs_vpd_t *vpd = &VPD;
1615 uint32_t status;
1616 uint32_t state;
1617
1618 char *buf1;
1619 char *buf2;
1620 uint32_t buf1_size;
1621 uint32_t buf2_size;
1622
1623 buf1_size = 1024;
1624 buf2_size = 1024;
1625
1626 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
1627 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
1628
1629 #ifdef EMLXS_SPARC
1630 if (strcmp(vpd->fcode_version, "none") == 0)
1631 #else
1632 if (strcmp(vpd->boot_version, "none") == 0)
1633 #endif /* EMLXS_SPARC */
1634 {
1635 state = 2; /* BOOT_BIOS_NOT_PRESENT */
1636 } else {
1637 state = emlxs_boot_code_state(hba);
1638 }
1639
1640 /* Write the Boot Bios State into the buffer */
1641 (void) snprintf(buf2, buf2_size, " %d", state);
1642 (void) strlcpy(buf1, LEGEND_HBA_BB_STATE, buf1_size);
1643 (void) strlcat(buf1, ": ", buf1_size);
1644 (void) strlcat(buf1, buf2, buf1_size);
1645
1646 /* Write the Boot Bios Version into the buffer */
1647 if (state == 2) {
1648 (void) snprintf(buf2, buf2_size, "%s", "unknown");
1649 } else {
1650 #ifdef EMLXS_SPARC
1651 (void) snprintf(buf2, buf2_size, "%s (FCode)",
1652 vpd->fcode_version);
1653 #else
1654 (void) snprintf(buf2, buf2_size, "%s", vpd->boot_version);
1655 #endif /* EMLXS_SPARC */
1656 }
1657
1658 (void) strlcat(buf1, "\n ", buf1_size);
1659 (void) strlcat(buf1, LEGEND_HBA_BB_VERSION, buf1_size);
1660 (void) strlcat(buf1, ": ", buf1_size);
1661 (void) strlcat(buf1, buf2, buf1_size);
1662
1663 status =
1664 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_INFO,
1665 LEGEND_HBA_BB_VERSION, 0);
1666
1667 status =
1668 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_HBA_INFO,
1669 LEGEND_HBA_INFO, LEGEND_HBA_BB_VERSION);
1670
1671 kmem_free(buf1, buf1_size);
1672 kmem_free(buf2, buf2_size);
1673
1674 return (status);
1675
1676 } /* emlxs_dump_boot_version() */
1677
1678
1679 /* ARGSUSED */
1680 static uint32_t
emlxs_dump_cfg_region4_decoded(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,char * pLidLegend,DUMP_WAKE_UP_PARAMS * pBuffer,uint32_t ByteCount)1681 emlxs_dump_cfg_region4_decoded(
1682 emlxs_hba_t *hba,
1683 emlxs_file_t *fpTxtFile,
1684 char *pLidLegend,
1685 DUMP_WAKE_UP_PARAMS *pBuffer,
1686 uint32_t ByteCount)
1687 {
1688 uint32_t status;
1689 char *buf1; /* text buffer */
1690 char *buf2; /* text buffer */
1691 uint32_t buf1_size;
1692 uint32_t buf2_size;
1693
1694 buf1_size = 1024;
1695 buf2_size = 1024;
1696
1697 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
1698 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
1699
1700 /* Write the Initial ID into the buffer */
1701 (void) snprintf(buf2, buf2_size, "%s: %08x %08x",
1702 LEGEND_CR4_INITIAL_LOAD,
1703 pBuffer->InitialId[0], pBuffer->InitialId[1]);
1704 (void) strlcat(buf1, buf2, buf1_size);
1705
1706 /* Write the Flags Word into the buffer */
1707 (void) snprintf(buf2, buf2_size, "\n %s: %08x", LEGEND_CR4_FLAGS,
1708 pBuffer->Flags);
1709 (void) strlcat(buf1, buf2, buf1_size);
1710
1711 /* Write the Boot Bios ID into the buffer */
1712 (void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
1713 LEGEND_CR4_BOOT_BIOS_ID,
1714 pBuffer->BootBiosId[0], pBuffer->BootBiosId[1]);
1715 (void) strlcat(buf1, buf2, buf1_size);
1716
1717 /* Write the SLI1 ID into the buffer */
1718 (void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
1719 LEGEND_CR4_SLI1_ID,
1720 pBuffer->Sli1Id[0], pBuffer->Sli1Id[1]);
1721 (void) strlcat(buf1, buf2, buf1_size);
1722
1723 /* Write the SLI2 ID into the buffer */
1724 (void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
1725 LEGEND_CR4_SLI2_ID,
1726 pBuffer->Sli2Id[0], pBuffer->Sli2Id[1]);
1727 (void) strlcat(buf1, buf2, buf1_size);
1728
1729 /* Write the SLI3 ID into the buffer */
1730 (void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
1731 LEGEND_CR4_SLI3_ID,
1732 pBuffer->Sli3Id[0], pBuffer->Sli3Id[1]);
1733 (void) strlcat(buf1, buf2, buf1_size);
1734
1735 /* Write the SLI4 ID into the buffer */
1736 (void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
1737 LEGEND_CR4_SLI4_ID,
1738 pBuffer->Sli4Id[0], pBuffer->Sli4Id[1]);
1739 (void) strlcat(buf1, buf2, buf1_size);
1740
1741 /* Write the Erom ID into the buffer */
1742 (void) snprintf(buf2, buf2_size, "\n %s: %08x %08x",
1743 LEGEND_CR4_EROM_ID,
1744 pBuffer->EromId[0], pBuffer->EromId[1]);
1745 (void) strlcat(buf1, buf2, buf1_size);
1746
1747 status =
1748 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_CONFIG_REGION,
1749 LEGEND_CONFIG_REGION_4, 0);
1750
1751 kmem_free(buf1, buf1_size);
1752 kmem_free(buf2, buf2_size);
1753
1754 return (status);
1755
1756 } /* emlxs_dump_cfg_region4_decoded() */
1757
1758
1759 /* ARGSUSED */
1760 uint32_t
emlxs_dump_cfg_region14_decoded(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,char * pLidLegend,char * pBuffer,uint32_t ByteCount)1761 emlxs_dump_cfg_region14_decoded(
1762 emlxs_hba_t *hba,
1763 emlxs_file_t *fpTxtFile,
1764 char *pLidLegend,
1765 char *pBuffer,
1766 uint32_t ByteCount)
1767 {
1768 uint32_t status;
1769 char *buf1; /* text buffer */
1770 char *buf2; /* text buffer */
1771 uint32_t buf1_size;
1772 uint32_t buf2_size;
1773 int i;
1774 uint8_t tag;
1775 uint16_t length;
1776 uint16_t length2;
1777 char mnemonic[4];
1778 int fDone = FALSE; /* flag to exit VPD loop */
1779
1780 #ifdef EMLXS_BIG_ENDIAN
1781 uint32_t *wptr;
1782 uint32_t w1;
1783 #endif
1784
1785 buf1_size = 1024;
1786 buf2_size = 1024;
1787
1788 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
1789 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
1790
1791 /* If Big Endian, swap the data in place, */
1792 /* because it's PCI Data (Little Endian) */
1793 #ifdef EMLXS_BIG_ENDIAN
1794 wptr = (uint32_t *)pBuffer;
1795 for (i = 0; i < (int)ByteCount / 4; i++, wptr++) {
1796 w1 = *wptr;
1797 *wptr = BE_SWAP32(w1);
1798 }
1799 #endif /* EMLXS_BIG_ENDIAN */
1800
1801 /* Decode the VPD Data and write it into the buffer */
1802
1803 /* CR 26941 */
1804 /* NOTE: The following code is correct, */
1805 /* should work, and used to work. */
1806 /* pBuffer points to char, and the symbol VPD_TAG_82 is 0x82. */
1807 /* The test is an equality test, not a relational test. */
1808 /* The compiler should generate an 8 bit test, and */
1809 /* sign extension does not apply. */
1810 /* I don't know when or why it stopped working, */
1811 /* and don't have time to dig. */
1812 /* The cast fixes it. */
1813
1814 if (((unsigned char)pBuffer[0]) != VPD_TAG_82) {
1815 (void) snprintf(buf1, buf1_size,
1816 "Bad VPD Data: (w0=0x%08x)", *(uint32_t *)pBuffer);
1817 } else { /* begin good data */
1818 i = 0;
1819 while (!fDone) {
1820 tag = pBuffer[i++];
1821 length = pBuffer[i++];
1822 length |= (pBuffer[i++] << 8);
1823
1824 switch (tag) {
1825 case VPD_TAG_82:
1826 (void) strncpy(buf2, &pBuffer[i],
1827 length > buf2_size ? buf2_size : length);
1828 buf2[length >
1829 (buf2_size - 1) ? (buf2_size -
1830 1) : length] = 0;
1831 (void) strlcat(buf1, "Name: ", buf1_size);
1832 (void) strlcat(buf1, buf2, buf1_size);
1833 i += length;
1834 break;
1835
1836 case VPD_TAG_90:
1837 for (;;) {
1838 mnemonic[0] = pBuffer[i++];
1839 mnemonic[1] = pBuffer[i++];
1840 mnemonic[2] = 0;
1841
1842 if (strcmp(mnemonic, "RV") == 0) {
1843 fDone = TRUE;
1844 break;
1845 }
1846
1847 if (mnemonic[0] == 0) {
1848 fDone = TRUE;
1849 break;
1850 }
1851
1852 length2 = pBuffer[i++];
1853 (void) snprintf(buf2, buf2_size,
1854 "\n %s: ", mnemonic);
1855 (void) strlcat(buf1, buf2,
1856 buf1_size);
1857 (void) strncpy(buf2, &pBuffer[i],
1858 length2 >
1859 buf2_size ? buf2_size : length2);
1860 buf2[length2 >
1861 (buf2_size - 1) ? (buf2_size -
1862 1) : length2] = 0;
1863 (void) strlcat(buf1, buf2,
1864 buf1_size);
1865 i += length2;
1866 }
1867 break;
1868
1869 default:
1870 break;
1871
1872 } /* end switch */
1873
1874 } /* end while */
1875
1876 } /* good data */
1877
1878 status =
1879 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_CONFIG_REGION,
1880 LEGEND_CONFIG_REGION_14, 0);
1881
1882 kmem_free(buf1, buf1_size);
1883 kmem_free(buf2, buf2_size);
1884
1885 return (status);
1886
1887 } /* emlxs_dump_cfg_region14_decoded() */
1888
1889
1890 static uint32_t
emlxs_dump_cfg_region(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile,uint8_t Region,char * pLidLegend,int fSwap)1891 emlxs_dump_cfg_region(
1892 emlxs_hba_t *hba,
1893 emlxs_file_t *fpTxtFile,
1894 emlxs_file_t *fpDmpFile,
1895 uint8_t Region,
1896 char *pLidLegend,
1897 int fSwap)
1898 {
1899 uint32_t status;
1900 uint32_t RetByteCount = 0; /* returned byte count */
1901 char *buf1; /* string ops buffer */
1902 char *buf2; /* string ops buffer */
1903 uint32_t buf1_size;
1904 uint32_t buf2_size;
1905 uint32_t *buffer;
1906 int i;
1907
1908 #ifdef EMLXS_LITTLE_ENDIAN
1909 fSwap = FALSE;
1910 #endif /* EMLXS_LITTLE_ENDIAN */
1911
1912 buf1_size = 4096;
1913 buf2_size = 1024;
1914
1915 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
1916 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
1917
1918 buffer =
1919 (uint32_t *)kmem_zalloc(DUMP_MAX_CONFIG_REGION_LENGTH, KM_SLEEP);
1920
1921 status =
1922 emlxs_read_cfg_region(hba, Region, DUMP_MAX_CONFIG_REGION_LENGTH,
1923 &RetByteCount, (uint8_t *)buffer);
1924
1925 if (status != 0) {
1926 kmem_free(buffer, DUMP_MAX_CONFIG_REGION_LENGTH);
1927 kmem_free(buf1, buf1_size);
1928 kmem_free(buf2, buf2_size);
1929 return (status);
1930 }
1931
1932 /* Write the Data into the buffer */
1933 for (i = 0; i < (int)RetByteCount / 4; i++) {
1934 if ((i % 8 == 0) && (i != 0)) {
1935 (void) strlcat((char *)buf1, "\n ", buf1_size);
1936 }
1937
1938 (void) snprintf(buf2, buf2_size, "%08x, ", buffer[i]);
1939 (void) strlcat((char *)buf1, buf2, buf1_size);
1940 }
1941
1942 status =
1943 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_CONFIG_REGION,
1944 pLidLegend, 0);
1945
1946 status = emlxs_dump_host_block(fpDmpFile,
1947 (uint8_t *)buffer,
1948 RetByteCount,
1949 SID_CONFIG_REGION, LEGEND_CONFIG_REGION, pLidLegend, fSwap);
1950
1951 if (Region == 4) {
1952 status =
1953 emlxs_dump_cfg_region4_decoded(hba, fpTxtFile, pLidLegend,
1954 (DUMP_WAKE_UP_PARAMS *)buffer, RetByteCount);
1955 }
1956
1957 if (Region == 14) {
1958 status =
1959 emlxs_dump_cfg_region14_decoded(hba, fpTxtFile,
1960 pLidLegend, (char *)buffer, RetByteCount);
1961 }
1962
1963 kmem_free(buffer, DUMP_MAX_CONFIG_REGION_LENGTH);
1964 kmem_free(buf1, buf1_size);
1965 kmem_free(buf2, buf2_size);
1966
1967 return (status);
1968
1969 } /* emlxs_dump_cfg_region() */
1970
1971
1972 static uint32_t
emlxs_dump_cfg_regions(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)1973 emlxs_dump_cfg_regions(
1974 emlxs_hba_t *hba,
1975 emlxs_file_t *fpTxtFile,
1976 emlxs_file_t *fpDmpFile)
1977 {
1978 uint32_t status;
1979
1980 status =
1981 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 0,
1982 LEGEND_CONFIG_REGION_0, FALSE);
1983
1984 status =
1985 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 1,
1986 LEGEND_CONFIG_REGION_1, FALSE);
1987
1988 status =
1989 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 2,
1990 LEGEND_CONFIG_REGION_2, FALSE);
1991
1992 status =
1993 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 3,
1994 LEGEND_CONFIG_REGION_3, FALSE);
1995
1996 status =
1997 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 4,
1998 LEGEND_CONFIG_REGION_4, FALSE);
1999
2000 status =
2001 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 5,
2002 LEGEND_CONFIG_REGION_5, FALSE);
2003
2004 status =
2005 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 6,
2006 LEGEND_CONFIG_REGION_6, FALSE);
2007
2008 status =
2009 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 7,
2010 LEGEND_CONFIG_REGION_7, FALSE);
2011
2012 status =
2013 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 8,
2014 LEGEND_CONFIG_REGION_8, TRUE);
2015
2016 status =
2017 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 9,
2018 LEGEND_CONFIG_REGION_9, TRUE);
2019
2020 status =
2021 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 10,
2022 LEGEND_CONFIG_REGION_10, TRUE);
2023
2024 status =
2025 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 11,
2026 LEGEND_CONFIG_REGION_11, FALSE);
2027
2028 status =
2029 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 12,
2030 LEGEND_CONFIG_REGION_12, FALSE);
2031
2032 status =
2033 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 13,
2034 LEGEND_CONFIG_REGION_13, FALSE);
2035
2036 status =
2037 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 14,
2038 LEGEND_CONFIG_REGION_14, FALSE);
2039
2040 status =
2041 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 15,
2042 LEGEND_CONFIG_REGION_15, FALSE);
2043
2044 status =
2045 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 16,
2046 LEGEND_CONFIG_REGION_16, FALSE);
2047
2048 status =
2049 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 17,
2050 LEGEND_CONFIG_REGION_17, FALSE);
2051
2052 status =
2053 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 18,
2054 LEGEND_CONFIG_REGION_18, FALSE);
2055
2056 status =
2057 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 19,
2058 LEGEND_CONFIG_REGION_19, FALSE);
2059
2060 status =
2061 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 20,
2062 LEGEND_CONFIG_REGION_20, FALSE);
2063
2064 status =
2065 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 21,
2066 LEGEND_CONFIG_REGION_21, FALSE);
2067
2068 status =
2069 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 22,
2070 LEGEND_CONFIG_REGION_22, FALSE);
2071
2072 status =
2073 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 23,
2074 LEGEND_CONFIG_REGION_23, FALSE);
2075
2076 status =
2077 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 24,
2078 LEGEND_CONFIG_REGION_24, FALSE);
2079
2080 status =
2081 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 25,
2082 LEGEND_CONFIG_REGION_25, FALSE);
2083
2084 status =
2085 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 26,
2086 LEGEND_CONFIG_REGION_26, FALSE);
2087
2088 status =
2089 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 27,
2090 LEGEND_CONFIG_REGION_27, FALSE);
2091
2092 status =
2093 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 28,
2094 LEGEND_CONFIG_REGION_28, FALSE);
2095
2096 status =
2097 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 29,
2098 LEGEND_CONFIG_REGION_29, FALSE);
2099
2100 status =
2101 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 30,
2102 LEGEND_CONFIG_REGION_30, FALSE);
2103
2104 status =
2105 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 31,
2106 LEGEND_CONFIG_REGION_31, FALSE);
2107
2108 status =
2109 emlxs_dump_cfg_region(hba, fpTxtFile, fpDmpFile, 32,
2110 LEGEND_CONFIG_REGION_32, FALSE);
2111
2112 return (status);
2113
2114 } /* emlxs_dump_cfg_regions() */
2115
2116
2117 /*ARGSUSED*/
2118 static uint32_t
emlxs_dump_os_version(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)2119 emlxs_dump_os_version(
2120 emlxs_hba_t *hba,
2121 emlxs_file_t *fpTxtFile,
2122 emlxs_file_t *fpDmpFile)
2123 {
2124 uint32_t status;
2125 char *buf1;
2126 char *buf2;
2127 uint32_t buf1_size;
2128 uint32_t buf2_size;
2129
2130 buf1_size = 1024;
2131 buf2_size = 1024;
2132
2133 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
2134 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
2135
2136 /* First, write the OS Name string into the buffer */
2137 (void) strlcpy(buf1, utsname.sysname, buf1_size);
2138
2139 /* Second, write the Version Info into the buffer */
2140 (void) snprintf(buf2, buf2_size, ", %s", utsname.release);
2141 (void) strlcat(buf1, buf2, buf1_size);
2142
2143 status =
2144 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_REV_INFO,
2145 LEGEND_REV_OS_VERSION, 0);
2146
2147 status =
2148 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_REV_INFO,
2149 LEGEND_REV_INFO, LEGEND_REV_OS_VERSION);
2150
2151 kmem_free(buf1, buf1_size);
2152 kmem_free(buf2, buf2_size);
2153
2154 return (status);
2155
2156 } /* emlxs_dump_os_version() */
2157
2158
2159 /*ARGSUSED*/
2160 static uint32_t
emlxs_dump_drv_version(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)2161 emlxs_dump_drv_version(
2162 emlxs_hba_t *hba,
2163 emlxs_file_t *fpTxtFile,
2164 emlxs_file_t *fpDmpFile)
2165 {
2166 uint32_t status;
2167 char *buf1;
2168 char *buf2;
2169 uint32_t buf1_size;
2170 uint32_t buf2_size;
2171
2172 buf1_size = 1024;
2173 buf2_size = 1024;
2174
2175 buf1 = (char *)kmem_zalloc(buf1_size, KM_SLEEP);
2176 buf2 = (char *)kmem_zalloc(buf2_size, KM_SLEEP);
2177
2178 /* Write the Driver Type into the buffer */
2179 (void) strlcpy(buf1, "Driver Type: ", buf1_size);
2180 (void) strlcat(buf1, DUMP_DRV_LEADVILLE, buf1_size);
2181
2182 /* Write the Driver Name into the buffer */
2183 (void) snprintf(buf2, buf2_size, "%s", DRIVER_NAME);
2184 (void) strlcat(buf1, "\n Driver Name: ", buf1_size);
2185 (void) strlcat(buf1, buf2, buf1_size);
2186
2187 /* Write the Driver Version into the buffer */
2188 (void) snprintf(buf2, buf2_size, "%s", emlxs_version);
2189 (void) strlcat(buf1, "\n Driver Version: ", buf1_size);
2190 (void) strlcat(buf1, buf2, buf1_size);
2191
2192 status =
2193 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_REV_INFO,
2194 LEGEND_REV_DRV_VERSION, 0);
2195
2196 status =
2197 emlxs_dump_string_dmpfile(fpDmpFile, buf1, SID_REV_INFO,
2198 LEGEND_REV_INFO, LEGEND_REV_DRV_VERSION);
2199
2200 kmem_free(buf1, buf1_size);
2201 kmem_free(buf2, buf2_size);
2202
2203 return (status);
2204
2205 } /* emlxs_dump_drv_version() */
2206
2207
2208 static uint32_t
emlxs_dump_file_create(emlxs_hba_t * hba,emlxs_file_t ** fpTxtFile,emlxs_file_t ** fpDmpFile,emlxs_file_t ** fpCeeFile)2209 emlxs_dump_file_create(
2210 emlxs_hba_t *hba,
2211 emlxs_file_t ** fpTxtFile,
2212 emlxs_file_t ** fpDmpFile,
2213 emlxs_file_t ** fpCeeFile)
2214 {
2215 if (fpTxtFile) {
2216 /* Create the Dump Files */
2217 if ((*fpTxtFile = emlxs_fopen(hba, EMLXS_TXT_FILE)) == NULL) {
2218 return (1);
2219 }
2220 }
2221
2222 if (fpCeeFile) {
2223 *fpCeeFile = NULL;
2224
2225 if ((hba->model_info.device_id == PCI_DEVICE_ID_HORNET) ||
2226 (hba->model_info.chip == EMLXS_BE2_CHIP) ||
2227 (hba->model_info.chip == EMLXS_BE3_CHIP)) {
2228 if ((*fpCeeFile =
2229 emlxs_fopen(hba, EMLXS_CEE_FILE)) == NULL) {
2230 emlxs_fdelete(*fpTxtFile);
2231 return (1);
2232 }
2233 }
2234 }
2235
2236 if (fpDmpFile) {
2237 if ((*fpDmpFile = emlxs_fopen(hba, EMLXS_DMP_FILE)) == NULL) {
2238 emlxs_fdelete(*fpTxtFile);
2239 emlxs_fdelete(*fpCeeFile);
2240 return (1);
2241 }
2242
2243 /* Initialize the DMP File */
2244 /* Write the single-byte Dump Identification */
2245 /* SID to the DMP File */
2246 #ifdef EMLXS_LITTLE_ENDIAN
2247 emlxs_fputc(SID_DUMP_ID_LE, *fpDmpFile);
2248 #endif /* EMLXS_LITTLE_ENDIAN */
2249
2250 #ifdef EMLXS_BIG_ENDIAN
2251 emlxs_fputc(SID_DUMP_ID_BE, *fpDmpFile);
2252 #endif /* EMLXS_BIG_ENDIAN */
2253
2254 emlxs_fputc(SID_NULL, *fpDmpFile);
2255 emlxs_fputc(SID_NULL, *fpDmpFile);
2256 emlxs_fputc(SID_NULL, *fpDmpFile);
2257 emlxs_fflush(*fpDmpFile);
2258 }
2259
2260 return (0);
2261
2262 } /* emlxs_dump_file_create() */
2263
2264
2265 static uint32_t
emlxs_dump_file_terminate(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile,emlxs_file_t * fpCeeFile)2266 emlxs_dump_file_terminate(
2267 emlxs_hba_t *hba,
2268 emlxs_file_t *fpTxtFile,
2269 emlxs_file_t *fpDmpFile,
2270 emlxs_file_t *fpCeeFile)
2271 {
2272
2273 if (fpTxtFile) {
2274 /* Write a suitable string to the Dump TXT File */
2275 (void) emlxs_fprintf(fpTxtFile, "Dump File End\n");
2276 emlxs_fflush(fpTxtFile);
2277 }
2278
2279 if (fpCeeFile) {
2280 if (hba->model_info.device_id == PCI_DEVICE_ID_HORNET) {
2281 (void) emlxs_fprintf(fpCeeFile, "Dump File End\n");
2282 }
2283
2284 emlxs_fflush(fpCeeFile);
2285 }
2286
2287 /* Write the single-byte Dump Termination SID to the DMP File */
2288 if (fpDmpFile) {
2289 emlxs_fputc(SID_DUMP_TERM, fpDmpFile);
2290 emlxs_fflush(fpDmpFile);
2291 }
2292
2293
2294 return (0);
2295
2296 } /* emlxs_dump_file_terminate() */
2297
2298
2299 static uint32_t
emlxs_dump_file_close(emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile,emlxs_file_t * fpCeeFile)2300 emlxs_dump_file_close(
2301 emlxs_file_t *fpTxtFile,
2302 emlxs_file_t *fpDmpFile,
2303 emlxs_file_t *fpCeeFile)
2304 {
2305
2306 if (fpTxtFile) {
2307 (void) emlxs_fclose(fpTxtFile);
2308 }
2309
2310 if (fpCeeFile) {
2311 (void) emlxs_fclose(fpCeeFile);
2312 }
2313
2314 if (fpDmpFile) {
2315 (void) emlxs_fclose(fpDmpFile);
2316 }
2317
2318 return (0);
2319
2320 } /* emlxs_dump_file_close() */
2321
2322
2323 /* ************************************************************************* */
2324 /* ************************************************************************* */
2325 /* Dump Generators, High Level */
2326 /* ************************************************************************* */
2327 /* ************************************************************************* */
2328
2329
2330 static uint32_t
emlxs_dump_rev_info(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)2331 emlxs_dump_rev_info(
2332 emlxs_hba_t *hba,
2333 emlxs_file_t *fpTxtFile,
2334 emlxs_file_t *fpDmpFile)
2335 {
2336 (void) emlxs_dump_os_version(hba, fpTxtFile, fpDmpFile);
2337 (void) emlxs_dump_drv_version(hba, fpTxtFile, fpDmpFile);
2338 return (0);
2339
2340 } /* emlxs_dump_rev_info() */
2341
2342
2343 /* ARGSUSED */
2344 static uint32_t
emlxs_dump_hba_info(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile,uint32_t dump_type)2345 emlxs_dump_hba_info(
2346 emlxs_hba_t *hba,
2347 emlxs_file_t *fpTxtFile,
2348 emlxs_file_t *fpDmpFile,
2349 uint32_t dump_type)
2350 {
2351 (void) emlxs_dump_model(hba, fpTxtFile, fpDmpFile);
2352 (void) emlxs_dump_wwn(hba, fpTxtFile, fpDmpFile);
2353 (void) emlxs_dump_serial_number(hba, fpTxtFile, fpDmpFile);
2354 (void) emlxs_dump_fw_version(hba, fpTxtFile, fpDmpFile);
2355 (void) emlxs_dump_boot_version(hba, fpTxtFile, fpDmpFile);
2356
2357
2358 return (0);
2359
2360 } /* emlxs_dump_hba_info() */
2361
2362
2363 /* ************************************************************************* */
2364 /* emlxs_dump_table_check */
2365 /* Examine Dump Table, and determine its size. */
2366 /* Count and include ID SIDs, and the TERM SID, */
2367 /* but not the Pointer at Addr 654. */
2368 /* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */
2369 /* ************************************************************************* */
2370 static uint32_t
emlxs_dump_table_check(emlxs_hba_t * hba,uint32_t * pSize)2371 emlxs_dump_table_check(
2372 emlxs_hba_t *hba,
2373 uint32_t *pSize)
2374 {
2375 emlxs_port_t *port = &PPORT;
2376 int fDone = FALSE; /* loop control flag */
2377 uint32_t tableSize = 0; /* dump table size (word count) */
2378 MAILBOX *mb;
2379 MAILBOXQ *mbq;
2380 uint32_t DumpTableAddr;
2381 DUMP_TABLE_ENTRY entry;
2382
2383 *pSize = 0;
2384
2385 /* Read 1 word from low memory at address 654; */
2386 /* save the returned Dump Table Base Address */
2387
2388 mbq =
2389 (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP);
2390 mb = (MAILBOX *) mbq;
2391
2392 /* Read the dump table address */
2393 emlxs_mb_dump(hba, mbq, 0x654, 1);
2394 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
2395 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
2396 "Unable to read dump table address. "\
2397 "offset=0x654 status=%x",
2398 mb->mbxStatus);
2399
2400 kmem_free(mbq, sizeof (MAILBOXQ));
2401 return (1);
2402 }
2403
2404 DumpTableAddr = mb->un.varDmp.resp_offset;
2405
2406 if (DumpTableAddr == 0) {
2407 kmem_free(mbq, sizeof (MAILBOXQ));
2408 return (1);
2409 }
2410
2411 /* Now loop reading Dump Table Entries.. */
2412 /* break out when we see a Terminator SID */
2413 while (!fDone) {
2414 emlxs_mb_dump(hba, mbq, DumpTableAddr, 2);
2415 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
2416 MBX_SUCCESS) {
2417 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
2418 "Unable to read dump table entry. "\
2419 "offset=%x status=%x",
2420 DumpTableAddr, mb->mbxStatus);
2421
2422 kmem_free(mbq, sizeof (MAILBOXQ));
2423 return (1);
2424 }
2425
2426 entry.un.PortBlock.un.w[0] = mb->un.varWords[4];
2427
2428 switch (entry.un.PortBlock.un.s.sid) {
2429 /* New Dump Table */
2430 case SID_ID01:
2431 tableSize++;
2432 DumpTableAddr += 4;
2433 break;
2434
2435 #ifdef CC_DUMP_USE_ALL_TABLES
2436 /* New Dump Table */
2437 case SID_ID02:
2438 case SID_ID03:
2439 tableSize++;
2440 DumpTableAddr += 4;
2441 break;
2442 #else
2443 /* New Dump Table */
2444 case SID_ID02:
2445 case SID_ID03:
2446 tableSize++;
2447 fDone = TRUE;
2448 break;
2449 #endif /* CC_DUMP_USE_ALL_TABLES */
2450
2451 /* Dump Table(s) Termination - all done */
2452 case SID_TERM:
2453 tableSize++;
2454 fDone = TRUE;
2455 break;
2456
2457 /* Dump Table Entry */
2458 default:
2459 tableSize += 2;
2460 DumpTableAddr += 8;
2461 break;
2462 }
2463
2464 } /* end while */
2465
2466 *pSize = (tableSize * 4); /* return the total Dump Table size */
2467
2468 kmem_free(mbq, sizeof (MAILBOXQ));
2469 return (0);
2470
2471 } /* emlxs_dump_table_check() */
2472
2473
2474 /* ************************************************************************ */
2475 /* emlxs_dump_table_read */
2476 /* Read the Dump Table and store it, for use */
2477 /* subsequently in emlxs_dump_hba_memory. */
2478 /* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */
2479 /* ************************************************************************ */
2480 static uint32_t
emlxs_dump_table_read(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,uint32_t ** ppDumpTable,uint32_t * pDumpTableSize)2481 emlxs_dump_table_read(
2482 emlxs_hba_t *hba,
2483 emlxs_file_t *fpTxtFile,
2484 uint32_t **ppDumpTable,
2485 uint32_t *pDumpTableSize)
2486 {
2487 emlxs_port_t *port = &PPORT;
2488 uint32_t status = 0;
2489 int fDone = FALSE;
2490 MAILBOXQ *mbq;
2491 MAILBOX *mb;
2492 uint32_t *pDumpTableEntry;
2493 uint32_t DumpTableAddr;
2494 DUMP_TABLE_ENTRY entry;
2495
2496 char buf2[256];
2497 char *buf1;
2498 uint32_t size = (32 * 1024);
2499
2500 /* First, check the dump table and if valid, get its size */
2501 status = emlxs_dump_table_check(hba, pDumpTableSize);
2502 if (status != 0) {
2503 return (status);
2504 }
2505
2506 buf1 = (char *)kmem_zalloc(size, KM_SLEEP);
2507
2508 /* Allocate a buffer to hold the Dump Table */
2509 *ppDumpTable = (uint32_t *)kmem_zalloc(*pDumpTableSize, KM_SLEEP);
2510
2511 pDumpTableEntry = *ppDumpTable;
2512
2513 /* Read 1 word from low memory at address 654; */
2514 /* save the returned Dump Table Base Address */
2515 mbq =
2516 (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP);
2517
2518 mb = (MAILBOX *) mbq;
2519
2520 /* Read the dump table address */
2521 emlxs_mb_dump(hba, mbq, 0x654, 1);
2522 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
2523 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
2524 "Unable to read dump table address. "\
2525 "offset=0x654 status=%x",
2526 mb->mbxStatus);
2527
2528 kmem_free(buf1, size);
2529 kmem_free(mbq, sizeof (MAILBOXQ));
2530
2531 kmem_free(*ppDumpTable, *pDumpTableSize);
2532 *pDumpTableSize = 0;
2533 *ppDumpTable = NULL;
2534
2535 return (1);
2536 }
2537
2538 DumpTableAddr = mb->un.varDmp.resp_offset;
2539
2540 if (DumpTableAddr == 0) {
2541 kmem_free(buf1, size);
2542 kmem_free(mbq, sizeof (MAILBOXQ));
2543
2544 kmem_free(*ppDumpTable, *pDumpTableSize);
2545 *pDumpTableSize = 0;
2546 *ppDumpTable = NULL;
2547
2548 return (1);
2549 }
2550
2551
2552 /* Now loop reading Dump Table Entries.. */
2553 /* break out when we see a Terminator SID */
2554 while (!fDone) {
2555 emlxs_mb_dump(hba, mbq, DumpTableAddr, 2);
2556 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
2557 MBX_SUCCESS) {
2558 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
2559 "Unable to read dump table entry. "\
2560 "offset=%x status=%x",
2561 DumpTableAddr, mb->mbxStatus);
2562
2563 kmem_free(buf1, size);
2564 kmem_free(mbq, sizeof (MAILBOXQ));
2565
2566 kmem_free(*ppDumpTable, *pDumpTableSize);
2567 *pDumpTableSize = 0;
2568 *ppDumpTable = NULL;
2569
2570 return (1);
2571 }
2572
2573 (void) snprintf(buf2, sizeof (buf2), "\n Addr=%08x: ",
2574 mb->un.varDmp.base_adr);
2575 (void) strlcat(buf1, buf2, size);
2576
2577 entry.un.PortBlock.un.w[0] = mb->un.varWords[4];
2578 *pDumpTableEntry++ = mb->un.varWords[4];
2579
2580 switch (entry.un.PortBlock.un.s.sid) {
2581 /* New Dump Table */
2582 case SID_ID01:
2583 (void) snprintf(buf2, sizeof (buf2), "w0=%08x",
2584 entry.un.PortBlock.un.w[0]);
2585 (void) strlcat(buf1, buf2, size);
2586 DumpTableAddr += 4;
2587 break;
2588
2589 #ifdef CC_DUMP_USE_ALL_TABLES
2590 /* New Dump Table */
2591 case SID_ID02:
2592 case SID_ID03:
2593 (void) snprintf(buf2, sizeof (buf2), "w0=%08x",
2594 entry.un.PortBlock.un.w[0]);
2595 (void) strlcat(buf1, buf2, size);
2596 DumpTableAddr += 4;
2597 break;
2598 #else
2599 /* New Dump Table */
2600 case SID_ID02:
2601 case SID_ID03:
2602 (void) snprintf(buf2, sizeof (buf2), "w0=%08x",
2603 entry.un.PortBlock.un.w[0]);
2604 (void) strlcat(buf1, buf2, size);
2605 fDone = TRUE;
2606 break;
2607 #endif /* CC_DUMP_USE_ALL_TABLES */
2608
2609 /* Dump Table(s) Termination - all done */
2610 case SID_TERM:
2611 (void) snprintf(buf2, sizeof (buf2), "w0=%08x",
2612 entry.un.PortBlock.un.w[0]);
2613 (void) strlcat(buf1, buf2, size);
2614 fDone = TRUE;
2615 break;
2616
2617 /* Dump Table Entry */
2618 default:
2619 entry.un.PortBlock.un.w[1] = mb->un.varWords[5];
2620 *pDumpTableEntry++ = mb->un.varWords[5];
2621
2622 (void) snprintf(buf2, sizeof (buf2), "w0=%08x, w1=%08x",
2623 entry.un.PortBlock.un.w[0],
2624 entry.un.PortBlock.un.w[1]);
2625 (void) strlcat(buf1, buf2, size);
2626 DumpTableAddr += 8;
2627 break;
2628 }
2629
2630 } /* end while */
2631
2632 status =
2633 emlxs_dump_string_txtfile(fpTxtFile, buf1, LEGEND_HBA_MEM_DUMP,
2634 LEGEND_HBA_MEM_DUMP_TABLE, 0);
2635
2636 kmem_free(buf1, size);
2637 kmem_free(mbq, sizeof (MAILBOXQ));
2638
2639 if (status != 0) {
2640 kmem_free(*ppDumpTable, *pDumpTableSize);
2641 *pDumpTableSize = 0;
2642 *ppDumpTable = NULL;
2643
2644 return (status);
2645 }
2646
2647 return (0);
2648
2649 } /* emlxs_dump_table_read() */
2650
2651
2652 /* ************************************************************************* */
2653 /* emlxs_dump_hba_memory */
2654 /* Guided by the Dump Table previously read in, */
2655 /* generate the Port Memory Dump. */
2656 /* See comments for CC_DUMP_USE_ALL_TABLES for additional description. */
2657 /* ************************************************************************* */
2658 static uint32_t
emlxs_dump_hba_memory(emlxs_hba_t * hba,emlxs_file_t * fpDmpFile,uint32_t * pDumpTable)2659 emlxs_dump_hba_memory(
2660 emlxs_hba_t *hba,
2661 emlxs_file_t *fpDmpFile,
2662 uint32_t *pDumpTable)
2663 {
2664 emlxs_port_t *port = &PPORT;
2665 uint32_t status = 0;
2666 int fDone = FALSE;
2667 DUMP_TABLE_ENTRY entry;
2668 MAILBOXQ *mbq;
2669 MAILBOX *mb;
2670 uint32_t byteCount;
2671 uint32_t byteCountRem;
2672 uint8_t *pBuf;
2673 uint8_t *p1;
2674 uint32_t portAddr;
2675 int fSwap = FALSE;
2676 uint32_t offset = 0;
2677 uint32_t wcount;
2678 uint32_t total = 0;
2679
2680 #ifdef EMLXS_BIG_ENDIAN
2681 fSwap = TRUE;
2682 #endif /* EMLXS_BIG_ENDIAN */
2683
2684 if (!fpDmpFile) {
2685 return (1);
2686 }
2687
2688 mbq =
2689 (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP);
2690
2691 mb = (MAILBOX *) mbq;
2692
2693 /* loop reading Dump Table Entries.. break out when */
2694 /* we see a Terminator SID */
2695 while (!fDone) {
2696 entry.un.PortBlock.un.w[0] = *pDumpTable++;
2697
2698 switch (entry.un.PortBlock.un.s.sid) {
2699
2700 /* New Dump Table */
2701 case SID_ID01:
2702 break;
2703
2704 #ifdef CC_DUMP_USE_ALL_TABLES
2705 /* New Dump Table */
2706 case SID_ID02:
2707 case SID_ID03:
2708 break;
2709 #else
2710 /* New Dump Table */
2711 case SID_ID02:
2712 case SID_ID03:
2713 fDone = TRUE;
2714 break;
2715 #endif /* CC_DUMP_USE_ALL_TABLES */
2716
2717 /* Dump Table(s) Termination - all done */
2718 case SID_TERM:
2719 fDone = TRUE;
2720 break;
2721
2722 default:
2723 /* Dump Table Entry */
2724 entry.un.PortBlock.un.w[1] = *pDumpTable++;
2725
2726 #ifdef CC_DUMP_FW_BUG_1
2727 if (entry.un.PortBlock.un.w[1] == 0x3E0000) {
2728 break;
2729 }
2730 #endif /* CC_DUMP_FW_BUG_1 */
2731
2732 /* Check if indirect address, and */
2733 /* obtain the new address if so */
2734 if ((entry.un.PortBlock.un.s.addr & 0x80000000) != 0) {
2735 offset =
2736 (entry.un.PortBlock.un.s.
2737 addr & 0x01FFFFFF);
2738 emlxs_mb_dump(hba, mbq, offset, 1);
2739 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT,
2740 0) != MBX_SUCCESS) {
2741 EMLXS_MSGF(EMLXS_CONTEXT,
2742 &emlxs_init_debug_msg,
2743 "Unable to read dump table entry. "\
2744 "offset=%x status=%x",
2745 offset, mb->mbxStatus);
2746
2747 kmem_free(mbq, sizeof (MAILBOXQ));
2748 return (1);
2749 }
2750
2751 /* replace the indirect address in the */
2752 /* Dump Table */
2753 entry.un.PortBlock.un.s.addr =
2754 mb->un.varWords[4];
2755 }
2756
2757 /* determine byte count to dump */
2758 byteCount = entry.un.PortBlock.un.s.bc;
2759 if (entry.un.PortBlock.un.s.sid & SID_MULT_ELEM) {
2760 if (entry.un.PortStruct.un.s.count == 0) {
2761 byteCount =
2762 256 *
2763 entry.un.PortStruct.un.s.length;
2764 } else {
2765 byteCount =
2766 entry.un.PortStruct.un.s.count *
2767 entry.un.PortStruct.un.s.length;
2768 }
2769 }
2770
2771 total += byteCount;
2772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
2773 "Dump: addr=%x count=%d total=%d", offset,
2774 byteCount, total);
2775
2776 /* allocate a buffer to receive the dump data */
2777 pBuf = (uint8_t *)kmem_zalloc(byteCount, KM_SLEEP);
2778
2779 /* loop issuing MBX commands, 18x measly words at */
2780 /* a time */
2781
2782 /* init vars */
2783 byteCountRem = byteCount;
2784 p1 = pBuf;
2785 portAddr = entry.un.PortBlock.un.s.addr;
2786
2787 for (;;) {
2788 if (byteCountRem == 0) {
2789 break;
2790 }
2791
2792 wcount =
2793 (byteCountRem / 4 >=
2794 0x18) ? 0x18 : (byteCountRem / 4);
2795 emlxs_mb_dump(hba, mbq, portAddr, wcount);
2796 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT,
2797 0) != MBX_SUCCESS) {
2798 EMLXS_MSGF(EMLXS_CONTEXT,
2799 &emlxs_init_debug_msg,
2800 "Unable to read dump table entry."\
2801 " offset=%x wc=%d status=%x",
2802 portAddr, wcount, mb->mbxStatus);
2803 break;
2804 }
2805
2806 bcopy((uint8_t *)&mb->un.varWords[4], p1,
2807 (mb->un.varDmp.word_cnt * 4));
2808
2809 byteCountRem -= (mb->un.varDmp.word_cnt * 4);
2810 p1 += (mb->un.varDmp.word_cnt * 4);
2811 portAddr += (mb->un.varDmp.word_cnt * 4);
2812
2813 } /* end for */
2814
2815 if (status == 0) {
2816 if (entry.un.PortBlock.un.s.
2817 sid & SID_MULT_ELEM) {
2818 status =
2819 emlxs_dump_port_struct(fpDmpFile,
2820 pBuf, byteCount, entry, fSwap);
2821 } else {
2822 status =
2823 emlxs_dump_port_block(fpDmpFile,
2824 pBuf, byteCount, entry, fSwap);
2825 }
2826 }
2827
2828 if (pBuf) {
2829 kmem_free(pBuf, byteCount);
2830 }
2831
2832 break;
2833
2834 } /* end switch */
2835
2836 } /* end while */
2837
2838 kmem_free(mbq, sizeof (MAILBOXQ));
2839
2840 return (status);
2841
2842 } /* emlxs_dump_hba_memory() */
2843
2844
2845 static uint32_t
emlxs_dump_hba(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)2846 emlxs_dump_hba(
2847 emlxs_hba_t *hba,
2848 emlxs_file_t *fpTxtFile,
2849 emlxs_file_t *fpDmpFile)
2850 {
2851 uint32_t status = 0;
2852 uint32_t *pDumpTable = 0;
2853 uint32_t DumpTableSize = 0;
2854
2855 if (hba->sli_mode >= EMLXS_HBA_SLI4_MODE) {
2856 return (1);
2857 }
2858
2859 /* HBA should be in WARM state here */
2860 status =
2861 emlxs_dump_table_read(hba, fpTxtFile, &pDumpTable,
2862 &DumpTableSize);
2863 if (status) {
2864 return (status);
2865 }
2866
2867 status = emlxs_dump_hba_memory(hba, fpDmpFile, pDumpTable);
2868
2869 if (pDumpTable != 0) {
2870 kmem_free(pDumpTable, DumpTableSize);
2871 }
2872
2873 return (status);
2874
2875 } /* emlxs_dump_hba() */
2876
2877
2878 /* ************************************************************************* */
2879 /* emlxs_dump_drv_region */
2880 /* Common subroutine for all the Dump_Sli"Structures" Routines */
2881 /* NOTE: This routine does not free pBuf. This is by design. */
2882 /* The caller does it. */
2883 /* ************************************************************************* */
2884 static uint32_t
emlxs_dump_drv_region(emlxs_hba_t * hba,uint32_t regionId,uint8_t ** pBuf,uint32_t * pBufLen)2885 emlxs_dump_drv_region(
2886 emlxs_hba_t *hba,
2887 uint32_t regionId,
2888 uint8_t **pBuf,
2889 uint32_t *pBufLen)
2890 { /* ptr to length of buffer */
2891 uint32_t status;
2892 uint32_t size;
2893
2894 *pBuf = NULL;
2895 *pBufLen = 0;
2896
2897 size = 0;
2898 status = emlxs_get_dump_region(hba, regionId, NULL, &size);
2899
2900 if (status != 0) {
2901 return (1);
2902 }
2903
2904 /* Now that we know the required length, request the actual data */
2905 *pBuf = (uint8_t *)kmem_zalloc(size, KM_SLEEP);
2906
2907 status = emlxs_get_dump_region(hba, regionId, *pBuf, &size);
2908
2909 if (status != 0) {
2910 kmem_free(*pBuf, size);
2911 *pBuf = NULL;
2912
2913 return (1);
2914 }
2915
2916 *pBufLen = size;
2917
2918 return (status);
2919
2920 } /* emlxs_dump_drv_region() */
2921
2922
2923 static uint32_t
emlxs_dump_sli_regs(emlxs_hba_t * hba,emlxs_file_t * fpDmpFile)2924 emlxs_dump_sli_regs(
2925 emlxs_hba_t *hba,
2926 emlxs_file_t *fpDmpFile)
2927 {
2928 uint32_t status;
2929 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */
2930 uint32_t bufLen = 0; /* length of buffer */
2931 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */
2932
2933 #ifdef EMLXS_BIG_ENDIAN
2934 fSwap = TRUE;
2935 #endif /* EMLXS_BIG_ENDIAN */
2936
2937 if (!fpDmpFile) {
2938 return (1);
2939 }
2940
2941 status = emlxs_dump_drv_region(hba, DR_SLI_REGS, &pBuf, &bufLen);
2942
2943 if (status != 0) {
2944 return (status);
2945 }
2946
2947 status =
2948 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_SLI_REGS,
2949 LEGEND_SLI_STRUCTURES, LEGEND_SLI_REGS, fSwap);
2950
2951 kmem_free(pBuf, bufLen);
2952
2953 return (status);
2954
2955 } /* emlxs_dump_sli_regs() */
2956
2957
2958 static uint32_t
emlxs_dump_slim(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile,uint32_t dump_type)2959 emlxs_dump_slim(
2960 emlxs_hba_t *hba,
2961 emlxs_file_t *fpTxtFile,
2962 emlxs_file_t *fpDmpFile,
2963 uint32_t dump_type)
2964 {
2965 uint32_t status;
2966 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */
2967 uint32_t bufLen = 0; /* length of buffer */
2968 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */
2969
2970 #ifdef EMLXS_BIG_ENDIAN
2971 fSwap = TRUE;
2972 #endif /* EMLXS_BIG_ENDIAN */
2973
2974 status = emlxs_dump_drv_region(hba, DR_SLIM, &pBuf, &bufLen);
2975
2976 if (status != 0) {
2977 return (status);
2978 }
2979
2980 /* The SLIM Dump is only useful if it's a */
2981 /* Driver-Initiated dump, say, after a HW Error */
2982 if (dump_type == DUMP_TYPE_DRIVER) {
2983 status =
2984 emlxs_dump_word_txtfile(fpTxtFile, (uint32_t *)pBuf,
2985 0x40, LEGEND_SLI_STRUCTURES, LEGEND_SLIM);
2986 }
2987
2988 status =
2989 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_SLIM,
2990 LEGEND_SLI_STRUCTURES, LEGEND_SLIM, fSwap);
2991
2992 kmem_free(pBuf, bufLen);
2993
2994 return (status);
2995
2996 } /* emlxs_dump_slim() */
2997
2998
2999 static uint32_t
emlxs_dump_pcb(emlxs_hba_t * hba,emlxs_file_t * fpDmpFile)3000 emlxs_dump_pcb(
3001 emlxs_hba_t *hba,
3002 emlxs_file_t *fpDmpFile)
3003 {
3004 uint32_t status;
3005 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */
3006 uint32_t bufLen = 0; /* length of buffer */
3007 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */
3008
3009 #ifdef EMLXS_BIG_ENDIAN
3010 fSwap = TRUE;
3011 #endif /* EMLXS_BIG_ENDIAN */
3012
3013 if (!fpDmpFile) {
3014 return (1);
3015 }
3016
3017 status = emlxs_dump_drv_region(hba, DR_PCB, &pBuf, &bufLen);
3018 if (status != 0) {
3019 return (status);
3020 }
3021
3022 status =
3023 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_PCB,
3024 LEGEND_SLI_STRUCTURES, LEGEND_PCB, fSwap);
3025
3026 kmem_free(pBuf, bufLen);
3027
3028 return (status);
3029
3030 } /* emlxs_dump_pcb() */
3031
3032
3033 static uint32_t
emlxs_dump_mbox(emlxs_hba_t * hba,emlxs_file_t * fpDmpFile)3034 emlxs_dump_mbox(
3035 emlxs_hba_t *hba,
3036 emlxs_file_t *fpDmpFile)
3037 {
3038 uint32_t status;
3039 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */
3040 uint32_t bufLen = 0; /* length of buffer */
3041 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */
3042
3043 #ifdef EMLXS_BIG_ENDIAN
3044 fSwap = TRUE;
3045 #endif /* EMLXS_BIG_ENDIAN */
3046
3047 if (!fpDmpFile) {
3048 return (1);
3049 }
3050
3051 status = emlxs_dump_drv_region(hba, DR_MBX, &pBuf, &bufLen);
3052 if (status != 0) {
3053 return (status);
3054 }
3055
3056 status =
3057 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_MBX,
3058 LEGEND_SLI_STRUCTURES, LEGEND_MBX, fSwap);
3059
3060 kmem_free(pBuf, bufLen);
3061
3062 return (status);
3063
3064 } /* emlxs_dump_mbox() */
3065
3066
3067 static uint32_t
emlxs_dump_host_pointers(emlxs_hba_t * hba,emlxs_file_t * fpDmpFile)3068 emlxs_dump_host_pointers(
3069 emlxs_hba_t *hba,
3070 emlxs_file_t *fpDmpFile)
3071 {
3072 uint32_t status;
3073 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */
3074 uint32_t bufLen = 0; /* length of buffer */
3075 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */
3076
3077 #ifdef EMLXS_BIG_ENDIAN
3078 fSwap = TRUE;
3079 #endif /* EMLXS_BIG_ENDIAN */
3080
3081 if (!fpDmpFile) {
3082 return (1);
3083 }
3084
3085 status = emlxs_dump_drv_region(hba, DR_HOST_PTRS, &pBuf, &bufLen);
3086 if (status != 0) {
3087 return (status);
3088 }
3089
3090 status =
3091 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_HOST_PTRS,
3092 LEGEND_SLI_STRUCTURES, LEGEND_HOST_PTRS, fSwap);
3093
3094 kmem_free(pBuf, bufLen);
3095
3096 return (status);
3097
3098 } /* emlxs_dump_host_pointers() */
3099
3100
3101 static uint32_t
emlxs_dump_port_pointers(emlxs_hba_t * hba,emlxs_file_t * fpDmpFile)3102 emlxs_dump_port_pointers(
3103 emlxs_hba_t *hba,
3104 emlxs_file_t *fpDmpFile)
3105 {
3106 uint32_t status;
3107 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */
3108 uint32_t bufLen = 0; /* length of buffer */
3109 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */
3110
3111 #ifdef EMLXS_BIG_ENDIAN
3112 fSwap = TRUE;
3113 #endif /* EMLXS_BIG_ENDIAN */
3114
3115 if (!fpDmpFile) {
3116 return (1);
3117 }
3118
3119 status = emlxs_dump_drv_region(hba, DR_PORT_PTRS, &pBuf, &bufLen);
3120 if (status != 0) {
3121 return (status);
3122 }
3123
3124 status =
3125 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_PORT_PTRS,
3126 LEGEND_SLI_STRUCTURES, LEGEND_PORT_PTRS, fSwap);
3127
3128 kmem_free(pBuf, bufLen);
3129
3130 return (status);
3131
3132 } /* emlxs_dump_port_pointers() */
3133
3134
3135 static uint32_t
emlxs_dump_rings(emlxs_hba_t * hba,emlxs_file_t * fpDmpFile)3136 emlxs_dump_rings(
3137 emlxs_hba_t *hba,
3138 emlxs_file_t *fpDmpFile)
3139 {
3140 uint32_t status;
3141 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */
3142 uint32_t bufLen = 0; /* length of buffer */
3143 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */
3144
3145 #ifdef EMLXS_BIG_ENDIAN
3146 fSwap = TRUE;
3147 #endif /* EMLXS_BIG_ENDIAN */
3148
3149 if (!fpDmpFile) {
3150 return (1);
3151 }
3152
3153 status = emlxs_dump_drv_region(hba, DR_RINGS, &pBuf, &bufLen);
3154 if (status != 0) {
3155 return (status);
3156 }
3157
3158 status =
3159 emlxs_dump_host_struct(fpDmpFile, pBuf, bufLen, sizeof (IOCB),
3160 bufLen / sizeof (IOCB), SID_RINGS, LEGEND_SLI_STRUCTURES,
3161 LEGEND_RINGS, fSwap);
3162
3163 kmem_free(pBuf, bufLen);
3164
3165 return (status);
3166
3167 } /* emlxs_dump_rings() */
3168
3169
3170 static uint32_t
emlxs_dump_drv_internals(emlxs_hba_t * hba,emlxs_file_t * fpDmpFile)3171 emlxs_dump_drv_internals(
3172 emlxs_hba_t *hba,
3173 emlxs_file_t *fpDmpFile)
3174 {
3175 uint32_t status;
3176 uint8_t *pBuf; /* ptr to data buffer to receive Dump Region Data */
3177 uint32_t bufLen = 0; /* length of buffer */
3178 int fSwap = FALSE; /* flag to pass to emlxs_dump_word_dmpfile */
3179
3180 #ifdef EMLXS_BIG_ENDIAN
3181 fSwap = TRUE;
3182 #endif /* EMLXS_BIG_ENDIAN */
3183
3184 if (!fpDmpFile) {
3185 return (1);
3186 }
3187
3188 status = emlxs_dump_drv_region(hba, DR_INTERNAL, &pBuf, &bufLen);
3189 if (status != 0) {
3190 return (status);
3191 }
3192
3193 status =
3194 emlxs_dump_host_block(fpDmpFile, pBuf, bufLen, SID_INTERNAL_SOL,
3195 LEGEND_SLI_STRUCTURES, LEGEND_DRIVER_SPEC, fSwap);
3196
3197 kmem_free(pBuf, bufLen);
3198
3199 return (status);
3200
3201 } /* emlxs_dump_drv_internals() */
3202
3203
3204 static uint32_t
emlxs_dump_sli_interface(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile,uint32_t dump_type)3205 emlxs_dump_sli_interface(
3206 emlxs_hba_t *hba,
3207 emlxs_file_t *fpTxtFile,
3208 emlxs_file_t *fpDmpFile,
3209 uint32_t dump_type)
3210 {
3211
3212 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
3213 /* HBA should be in OFFLINE state here */
3214
3215 (void) emlxs_dump_sli_regs(hba, fpDmpFile);
3216 (void) emlxs_dump_slim(hba, fpTxtFile, fpDmpFile, dump_type);
3217 (void) emlxs_dump_pcb(hba, fpDmpFile);
3218 (void) emlxs_dump_mbox(hba, fpDmpFile);
3219 (void) emlxs_dump_host_pointers(hba, fpDmpFile);
3220 (void) emlxs_dump_port_pointers(hba, fpDmpFile);
3221 (void) emlxs_dump_rings(hba, fpDmpFile);
3222 }
3223
3224 (void) emlxs_dump_drv_internals(hba, fpDmpFile);
3225
3226 return (0);
3227
3228 } /* emlxs_dump_sli_interface() */
3229
3230
3231 static uint32_t
emlxs_dump_menlo_log(emlxs_hba_t * hba,emlxs_file_t * fpCeeFile)3232 emlxs_dump_menlo_log(
3233 emlxs_hba_t *hba,
3234 emlxs_file_t *fpCeeFile)
3235 {
3236 uint32_t RmStatus;
3237 int i, j;
3238 int isWrapped = FALSE;
3239 char buf1[2048] = { 0 };
3240 char buf2[2048] = { 0 };
3241
3242 /* Get Config Command vars */
3243 menlo_get_config_rsp_t GcBuf;
3244 menlo_get_config_rsp_t *pGcBuf = &GcBuf;
3245
3246 /* Get Log Config Command vars */
3247 uint32_t LcBufSize;
3248 menlo_rsp_t *pLcBuf = NULL;
3249 uint32_t NumLogs;
3250 menlo_log_t *pLcEntry;
3251
3252 /* Get Log Data Command vars */
3253 uint32_t LdBufSize;
3254 menlo_rsp_t *pLdBuf = NULL;
3255 uint16_t Head;
3256 uint8_t *pLogEntry;
3257 char *pLogString;
3258
3259 /* Get Panic Log Command vars */
3260 uint32_t PlBufSize;
3261 menlo_rsp_t *pPlBuf = NULL;
3262 uint32_t PanicLogEntryCount;
3263 uint32_t PanicLogEntrySize;
3264
3265 if (hba->model_info.device_id != PCI_DEVICE_ID_HORNET) {
3266 return (DFC_INVALID_ADAPTER);
3267 }
3268
3269 /* First, issue a GetConfig command, which gives us */
3270 /* the Log Config and Panic Log sizes */
3271
3272 RmStatus =
3273 emlxs_menlo_get_cfg(hba, pGcBuf, sizeof (menlo_get_config_rsp_t));
3274
3275 if (RmStatus != 0) {
3276 goto done;
3277 }
3278
3279 LcBufSize = GcBuf.log_cfg_size + 8;
3280 PlBufSize = GcBuf.panic_log_size;
3281
3282 pLcBuf = (menlo_rsp_t *)kmem_zalloc(LcBufSize, KM_SLEEP);
3283
3284 RmStatus = emlxs_menlo_get_logcfg(hba, pLcBuf, LcBufSize);
3285
3286 if (RmStatus != 0) {
3287 goto done;
3288 }
3289
3290 buf1[0] = 0;
3291 RmStatus =
3292 emlxs_dump_string_txtfile(fpCeeFile, buf1,
3293 LEGEND_MENLO_LOG_CONFIG, LEGEND_NULL, 0);
3294
3295 NumLogs = pLcBuf->log_cfg.num_logs;
3296 pLcEntry = (menlo_log_t *)&pLcBuf->log_cfg.data;
3297
3298 buf1[0] = 0;
3299 (void) snprintf(buf2, sizeof (buf2), "LogId Entries Size Name");
3300 (void) strlcat(buf1, buf2, sizeof (buf1));
3301 (void) snprintf(buf2, sizeof (buf2), "\n----- ------- ---- ----");
3302 (void) strlcat(buf1, buf2, sizeof (buf1));
3303
3304 RmStatus = emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
3305
3306 for (i = 0; i < (int)NumLogs; i++) {
3307 buf1[0] = 0;
3308 (void) snprintf(buf2, sizeof (buf2),
3309 "\n %2d %4d %4d %s",
3310 pLcEntry[i].id,
3311 pLcEntry[i].num_entries,
3312 pLcEntry[i].entry_size, pLcEntry[i].name);
3313 (void) strlcat(buf1, buf2, sizeof (buf1));
3314 RmStatus =
3315 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
3316 }
3317
3318 /* Now issue a series of GetLogData commands, */
3319 /* which gives us the actual Logs */
3320
3321 for (i = 0; i < (int)NumLogs; i++) {
3322 LdBufSize =
3323 (pLcEntry[i].num_entries *pLcEntry[i].entry_size) + 8;
3324
3325 pLdBuf = (menlo_rsp_t *)kmem_zalloc(LdBufSize, KM_SLEEP);
3326
3327 RmStatus = emlxs_menlo_get_log(hba, i, pLdBuf, LdBufSize);
3328
3329 if (RmStatus != 0) {
3330 goto done;
3331 }
3332
3333 /* print a caption for the current log */
3334 buf1[0] = 0;
3335 (void) snprintf(buf2, sizeof (buf2), "\n\nLog %d:", i);
3336 (void) strlcat(buf1, buf2, sizeof (buf1));
3337 (void) snprintf(buf2, sizeof (buf2), " %s", pLcEntry[i].name);
3338 (void) strlcat(buf1, buf2, sizeof (buf1));
3339 (void) snprintf(buf2, sizeof (buf2), "\n");
3340
3341 for (j = 0; j < 75; j++) {
3342 (void) strlcat(buf2, "-", sizeof (buf2));
3343 }
3344
3345 (void) strlcat(buf1, buf2, sizeof (buf1));
3346 RmStatus =
3347 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
3348
3349 /* check the head entry to determine whether */
3350 /* the log has wrapped or not */
3351 Head = pLdBuf->log.head;
3352 pLogEntry = (uint8_t *)&pLdBuf->log.data;
3353 pLogString =
3354 (char *)&(pLogEntry[Head *pLcEntry[i].entry_size]);
3355
3356 isWrapped = FALSE;
3357 if (strlen(pLogString) != 0) {
3358 isWrapped = TRUE;
3359 }
3360
3361 /* if log is wrapped, get entries from the */
3362 /* Head through the End */
3363 if (isWrapped) {
3364 for (j = Head; j < (int)pLcEntry[i].num_entries; j++) {
3365 pLogString =
3366 (char *)&(pLogEntry[j *
3367 pLcEntry[i].entry_size]);
3368 buf1[0] = 0;
3369 (void) snprintf(buf2, sizeof (buf2),
3370 "\n%3d: %s", j, pLogString);
3371 (void) strlcat(buf1, buf2, sizeof (buf1));
3372 RmStatus =
3373 emlxs_dump_string_txtfile(fpCeeFile, buf1,
3374 0, 0, 1);
3375 }
3376 }
3377
3378 /* if wrapped or not, get entries from the Top */
3379 /* through the Head */
3380 for (j = 0; j < Head; j++) {
3381 pLogString =
3382 (char *)&(pLogEntry[j * pLcEntry[i].entry_size]);
3383 buf1[0] = 0;
3384 (void) snprintf(buf2, sizeof (buf2), "\n%3d: %s", j,
3385 pLogString);
3386 (void) strlcat(buf1, buf2, sizeof (buf1));
3387 RmStatus =
3388 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0,
3389 1);
3390 }
3391 } /* end for i */
3392
3393 /* Now issue a GetPanicLog command, which gives us the Panic Log */
3394
3395 /* print a caption for the current log */
3396 (void) strlcpy(buf1, LEGEND_MENLO_LOG_PANIC_REGS, sizeof (buf1));
3397 buf2[0] = 0;
3398 for (j = 0; j < 75; j++) {
3399 (void) strlcat(buf2, "-", sizeof (buf2));
3400 }
3401 (void) strlcat(buf1, buf2, sizeof (buf1));
3402 RmStatus = emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
3403
3404 pPlBuf = (menlo_rsp_t *)kmem_zalloc(PlBufSize, KM_SLEEP);
3405
3406 RmStatus = emlxs_menlo_get_paniclog(hba, pPlBuf, PlBufSize);
3407
3408 if (RmStatus == 0) {
3409 buf1[0] = 0;
3410 (void) snprintf(buf2, sizeof (buf2), "\nType = %x",
3411 pPlBuf->panic_log.type);
3412 (void) strlcat(buf1, buf2, sizeof (buf1));
3413 (void) snprintf(buf2, sizeof (buf2), "\nRegsEpc = %08x",
3414 pPlBuf->panic_log.regs_epc);
3415 (void) strlcat(buf1, buf2, sizeof (buf1));
3416 (void) snprintf(buf2, sizeof (buf2), "\nRegsCp0Cause = %08x",
3417 pPlBuf->panic_log.regs_cp0_cause);
3418 (void) strlcat(buf1, buf2, sizeof (buf1));
3419 (void) snprintf(buf2, sizeof (buf2), "\nRegsCp0Stat = %08x",
3420 pPlBuf->panic_log.regs_cp0_status);
3421 (void) strlcat(buf1, buf2, sizeof (buf1));
3422 RmStatus =
3423 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
3424
3425 buf1[0] = 0;
3426 for (i = 0; i < MENLO_NUM_GP_REGS; i++) {
3427 (void) snprintf(buf2, sizeof (buf2),
3428 "\nRegsGp[%02x] = %08x", i,
3429 pPlBuf->panic_log.regs_gp[i]);
3430 (void) strlcat(buf1, buf2, sizeof (buf1));
3431 }
3432 RmStatus =
3433 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
3434
3435 buf1[0] = 0;
3436 (void) snprintf(buf2, sizeof (buf2), "\nLogPresent = %08x",
3437 pPlBuf->panic_log.log_present);
3438 (void) strlcat(buf1, buf2, sizeof (buf1));
3439 PanicLogEntryCount = pPlBuf->panic_log.num_entries;
3440 (void) snprintf(buf2, sizeof (buf2), "\nNumEntries = %08x",
3441 PanicLogEntryCount);
3442 (void) strlcat(buf1, buf2, sizeof (buf1));
3443 PanicLogEntrySize = pPlBuf->panic_log.entry_size;
3444 (void) snprintf(buf2, sizeof (buf2), "\nEntrySize = %d.",
3445 PanicLogEntrySize);
3446 (void) strlcat(buf1, buf2, sizeof (buf1));
3447 (void) snprintf(buf2, sizeof (buf2), "\nHead Entry = %d.",
3448 pPlBuf->panic_log.head);
3449 (void) strlcat(buf1, buf2, sizeof (buf1));
3450 RmStatus =
3451 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
3452
3453 /* print a caption for the current log */
3454 (void) strlcpy(buf1, LEGEND_MENLO_LOG_PANIC_LOGS,
3455 sizeof (buf1));
3456 buf2[0] = 0;
3457 for (j = 0; j < 75; j++) {
3458 (void) strlcat(buf2, "-", sizeof (buf2));
3459 }
3460 (void) strlcat(buf1, buf2, sizeof (buf2));
3461 RmStatus =
3462 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0, 1);
3463
3464 /* check the head entry to determine whether the */
3465 /* log has wrapped or not */
3466 Head = pPlBuf->panic_log.head;
3467 pLogEntry = (uint8_t *)&pPlBuf->panic_log.data;
3468 pLogString = (char *)&(pLogEntry[Head * PanicLogEntrySize]);
3469 isWrapped = FALSE;
3470 if (strlen(pLogString) != 0) {
3471 isWrapped = TRUE;
3472 }
3473
3474 /* if log is wrapped, get entries from the */
3475 /* Head through the End */
3476 if (isWrapped) {
3477 for (j = Head; j < (int)PanicLogEntryCount; j++) {
3478 pLogString =
3479 (char *)&(pLogEntry[j *
3480 PanicLogEntrySize]);
3481 buf1[0] = 0;
3482 (void) snprintf(buf2, sizeof (buf2),
3483 "\n%3d: %s", j, pLogString);
3484 (void) strlcat(buf1, buf2, sizeof (buf2));
3485 RmStatus =
3486 emlxs_dump_string_txtfile(fpCeeFile, buf1,
3487 0, 0, 1);
3488 }
3489 }
3490 /* if wrapped or not, get entries from the Top */
3491 /* through the Head */
3492 for (j = 0; j < Head; j++) {
3493 pLogString =
3494 (char *)&(pLogEntry[j * PanicLogEntrySize]);
3495 buf1[0] = 0;
3496 (void) snprintf(buf2, sizeof (buf2), "\n%3d: %s", j,
3497 pLogString);
3498 (void) strlcat(buf1, buf2, sizeof (buf2));
3499 RmStatus =
3500 emlxs_dump_string_txtfile(fpCeeFile, buf1, 0, 0,
3501 1);
3502 }
3503 }
3504
3505 RmStatus = emlxs_dump_string_txtfile(fpCeeFile, "\n\n", 0, 0, 1);
3506
3507 done:
3508
3509 if (pLdBuf != 0) {
3510 kmem_free(pLdBuf, LdBufSize);
3511 }
3512
3513 if (pLcBuf != 0) {
3514 kmem_free(pLcBuf, LcBufSize);
3515 }
3516
3517 if (pPlBuf != 0) {
3518 kmem_free(pPlBuf, PlBufSize);
3519 }
3520
3521 return (RmStatus);
3522
3523 } /* emlxs_dump_menlo_log() */
3524
3525
3526 static uint32_t
emlxs_dump_saturn_log(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpDmpFile)3527 emlxs_dump_saturn_log(
3528 emlxs_hba_t *hba,
3529 emlxs_file_t *fpTxtFile,
3530 emlxs_file_t *fpDmpFile)
3531 {
3532 emlxs_port_t *port = &PPORT;
3533 MAILBOXQ *mbq;
3534 MAILBOX *mb;
3535 MATCHMAP *mp = NULL;
3536 uint32_t status;
3537 uint32_t logSize = 0;
3538 uintptr_t tempAddress;
3539 int fSwap = FALSE;
3540 uint32_t i;
3541 uint32_t block_size;
3542 uint32_t offset;
3543
3544 #ifdef EMLXS_BIG_ENDIAN
3545 fSwap = TRUE;
3546 #endif /* EMLXS_BIG_ENDIAN */
3547
3548 if (hba->model_info.chip != EMLXS_SATURN_CHIP) {
3549 return (1);
3550 }
3551
3552 mbq =
3553 (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ), KM_SLEEP);
3554
3555 mb = (MAILBOX *) mbq;
3556
3557 /* Step 1: Call MBX_READ_EVENT_LOG_STATUS to get the log size. */
3558 for (i = 0; i < 10; i++) {
3559 bzero((void *)mb, MAILBOX_CMD_BSIZE);
3560 mb->mbxCommand = MBX_READ_EVENT_LOG_STATUS;
3561 mbq->mbox_cmpl = NULL;
3562
3563 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) ==
3564 MBX_SUCCESS) {
3565 break;
3566 }
3567
3568 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3569 "Unable to read event log status. status=%x",
3570 mb->mbxStatus);
3571
3572 if ((mb->mbxStatus & 0xFFFF) == MBXERR_NOT_SUPPORTED ||
3573 (mb->mbxStatus & 0xFFFF) == MBX_DRVR_ERROR) {
3574 (void) emlxs_dump_string_txtfile(fpTxtFile,
3575 NV_LOG_NOT_INCLUDED_IN_DMP,
3576 LEGEND_NON_VOLATILE_LOG,
3577 LEGEND_NV_LOG_DRIVER_NOT_SUPPORTED, 0);
3578
3579 kmem_free(mbq, sizeof (MAILBOXQ));
3580 return (1);
3581 }
3582
3583 /* The call to get the log size simply fails. */
3584 /* Retry up to 10 times. */
3585 if ((mb->mbxStatus & 0xFFFF) != MBX_BUSY) {
3586 /* Mailbox fails for some unknown reason. */
3587 /* Put something in the txt to indicate this case. */
3588 (void) emlxs_dump_string_txtfile(fpTxtFile,
3589 NV_LOG_NOT_INCLUDED_IN_DMP,
3590 LEGEND_NON_VOLATILE_LOG,
3591 LEGEND_NV_LOG_STATUS_ERROR, 0);
3592
3593 kmem_free(mbq, sizeof (MAILBOXQ));
3594 return (1);
3595 }
3596 }
3597
3598 if (i >= 10) {
3599 (void) emlxs_dump_string_txtfile(fpTxtFile,
3600 NV_LOG_NOT_INCLUDED_IN_DMP, LEGEND_NON_VOLATILE_LOG,
3601 LEGEND_NV_LOG_STATUS_ERROR, 0);
3602
3603 kmem_free(mbq, sizeof (MAILBOXQ));
3604 return (1);
3605 }
3606
3607 /* Step 2: Use the log size from step 1 to call MBX_READ_EVENT_LOG */
3608 logSize = mb->un.varLogStat.size;
3609
3610 if ((mp = emlxs_mem_buf_alloc(hba, logSize)) == 0) {
3611 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3612 "Unable to allocate receive buffer. "
3613 "size=%d",
3614 logSize);
3615
3616 kmem_free(mbq, sizeof (MAILBOXQ));
3617 return (1);
3618 }
3619
3620 for (offset = 0; offset < logSize; offset = offset + 1024) {
3621 if (logSize - offset < 1024) {
3622 block_size = logSize - offset;
3623 } else {
3624 block_size = 1024;
3625 }
3626
3627 tempAddress = (uintptr_t)(mp->phys + offset);
3628
3629 bzero((void *)mb, MAILBOX_CMD_BSIZE);
3630 mb->mbxCommand = MBX_READ_EVENT_LOG; /* 0x38 */
3631 mb->un.varRdEvtLog.read_log = 1; /* read log */
3632 mb->un.varRdEvtLog.mbox_rsp = 0; /* not using Mailbox */
3633 mb->un.varRdEvtLog.offset = offset;
3634 mb->un.varRdEvtLog.un.sp64.tus.f.bdeFlags = 0x0;
3635 mb->un.varRdEvtLog.un.sp64.tus.f.bdeSize = block_size;
3636 mb->un.varRdEvtLog.un.sp64.addrLow = PADDR_LO(tempAddress);
3637 mb->un.varRdEvtLog.un.sp64.addrHigh = PADDR_HI(tempAddress);
3638 mbq->mbox_cmpl = NULL;
3639
3640 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
3641 MBX_SUCCESS) {
3642 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
3643 "Unable to read event log. status=%x",
3644 mb->mbxStatus);
3645
3646 emlxs_mem_buf_free(hba, mp);
3647 kmem_free(mbq, sizeof (MAILBOXQ));
3648 return (1);
3649 }
3650 }
3651
3652 /* Step 3: Dump the log to the DMP file as raw data. */
3653
3654 /* Write a string to text file to direct the user to the DMP */
3655 /* file for the actual log. */
3656 status =
3657 emlxs_dump_string_txtfile(fpTxtFile, NV_LOG_INCLUDED_IN_DMP,
3658 LEGEND_NON_VOLATILE_LOG, LEGEND_NULL, 0);
3659
3660 /* Write the real log to the DMP file. */
3661 EMLXS_MPDATA_SYNC(mp->dma_handle, 0, logSize, DDI_DMA_SYNC_FORKERNEL);
3662
3663 status =
3664 emlxs_dump_host_block(fpDmpFile, mp->virt, logSize,
3665 SID_NON_VOLATILE_LOG, LEGEND_NON_VOLATILE_LOG, LEGEND_NULL,
3666 fSwap);
3667
3668 #ifdef FMA_SUPPORT
3669 if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
3670 != DDI_FM_OK) {
3671 EMLXS_MSGF(EMLXS_CONTEXT,
3672 &emlxs_invalid_dma_handle_msg,
3673 "dump_saturn_log: hdl=%p",
3674 mp->dma_handle);
3675 status = 1;
3676 }
3677 #endif /* FMA_SUPPORT */
3678
3679 emlxs_mem_buf_free(hba, mp);
3680 kmem_free(mbq, sizeof (MAILBOXQ));
3681 return (status);
3682
3683 } /* emlxs_dump_saturn_log() */
3684
3685
3686 static uint32_t
emlxs_dump_tigershark_log(emlxs_hba_t * hba,emlxs_file_t * fpTxtFile,emlxs_file_t * fpCeeFile)3687 emlxs_dump_tigershark_log(
3688 emlxs_hba_t *hba,
3689 emlxs_file_t *fpTxtFile,
3690 emlxs_file_t *fpCeeFile)
3691 {
3692 emlxs_port_t *port = &PPORT;
3693 uint32_t rval = 0;
3694 uint32_t offset;
3695 uint32_t log_size;
3696 uint32_t xfer_size;
3697 uint32_t buffer_size;
3698 uint8_t *buffer = NULL;
3699 uint8_t *bptr;
3700 uint8_t *payload;
3701 MAILBOXQ *mbq = NULL;
3702 MAILBOX4 *mb = NULL;
3703 MATCHMAP *mp = NULL;
3704 IOCTL_COMMON_MANAGE_FAT *fat;
3705 mbox_req_hdr_t *hdr_req;
3706
3707 if ((hba->model_info.chip != EMLXS_BE2_CHIP) &&
3708 (hba->model_info.chip != EMLXS_BE3_CHIP)) {
3709 return (1);
3710 }
3711
3712 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3713 "Querying FAT...");
3714
3715 mbq = (MAILBOXQ *)kmem_zalloc(sizeof (MAILBOXQ),
3716 KM_SLEEP);
3717
3718 mb = (MAILBOX4*)mbq;
3719
3720 if ((mp = emlxs_mem_buf_alloc(hba, (sizeof (mbox_req_hdr_t) +
3721 sizeof (IOCTL_COMMON_MANAGE_FAT) + BE_MAX_XFER_SIZE))) == NULL) {
3722 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3723 "Unable to allocate FAT buffer.");
3724
3725 rval = 1;
3726 goto done;
3727 }
3728
3729 /* Query FAT */
3730 mb->un.varSLIConfig.be.embedded = 0;
3731 mbq->nonembed = (void *)mp;
3732 mbq->mbox_cmpl = NULL;
3733
3734 mb->mbxCommand = MBX_SLI_CONFIG;
3735 mb->mbxOwner = OWN_HOST;
3736
3737 hdr_req = (mbox_req_hdr_t *)mp->virt;
3738 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
3739 hdr_req->opcode = COMMON_OPCODE_MANAGE_FAT;
3740 hdr_req->timeout = 0;
3741 hdr_req->req_length = sizeof (IOCTL_COMMON_MANAGE_FAT);
3742
3743 fat = (IOCTL_COMMON_MANAGE_FAT *)(hdr_req + 1);
3744 fat->params.request.fat_operation = QUERY_FAT;
3745 fat->params.request.read_log_offset = 0;
3746 fat->params.request.read_log_length = 0;
3747 fat->params.request.data_buffer_size = BE_MAX_XFER_SIZE;
3748
3749 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
3750 MBX_SUCCESS) {
3751 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3752 "FAT Query failed. status=%x",
3753 mb->mbxStatus);
3754
3755 rval = 1;
3756 goto done;
3757 }
3758
3759 log_size = fat->params.response.log_size;
3760 buffer_size = fat->params.response.log_size;
3761
3762 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3763 "FAT: log_size=%d", log_size);
3764
3765 if (buffer_size == 0) {
3766 goto done;
3767 }
3768
3769 if ((buffer = (uint8_t *)kmem_alloc(
3770 buffer_size, KM_NOSLEEP)) == NULL) {
3771 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3772 "Unable to allocate log buffer.");
3773
3774 rval = 1;
3775 goto done;
3776 }
3777 bzero(buffer, buffer_size);
3778
3779 /* Upload Log */
3780 bptr = buffer;
3781 offset = 0;
3782
3783 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3784 "Uploading log... (%d bytes)", log_size);
3785
3786 while (log_size) {
3787 bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
3788 bzero((void *) mp->virt, mp->size);
3789
3790 xfer_size = min(BE_MAX_XFER_SIZE, log_size);
3791
3792 mb->un.varSLIConfig.be.embedded = 0;
3793 mbq->nonembed = (void *)mp;
3794 mbq->mbox_cmpl = NULL;
3795
3796 mb->mbxCommand = MBX_SLI_CONFIG;
3797 mb->mbxOwner = OWN_HOST;
3798
3799 hdr_req = (mbox_req_hdr_t *)mp->virt;
3800 hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
3801 hdr_req->opcode = COMMON_OPCODE_MANAGE_FAT;
3802 hdr_req->timeout = 0;
3803 hdr_req->req_length =
3804 sizeof (IOCTL_COMMON_MANAGE_FAT) + xfer_size;
3805
3806 fat = (IOCTL_COMMON_MANAGE_FAT *)(hdr_req + 1);
3807 fat->params.request.fat_operation = RETRIEVE_FAT;
3808 fat->params.request.read_log_offset = offset;
3809 fat->params.request.read_log_length = xfer_size;
3810 fat->params.request.data_buffer_size = BE_MAX_XFER_SIZE;
3811
3812 if (EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0) !=
3813 MBX_SUCCESS) {
3814 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3815 "Failed to upload log. status=%x",
3816 mb->mbxStatus);
3817
3818 (void) emlxs_dump_string_txtfile(fpTxtFile,
3819 NV_LOG_NOT_INCLUDED_IN_FAT,
3820 LEGEND_NON_VOLATILE_LOG,
3821 LEGEND_NV_LOG_STATUS_ERROR, 0);
3822
3823 rval = 1;
3824 goto done;
3825 }
3826
3827 payload = (uint8_t *)(&fat->params.response.data_buffer);
3828
3829 BE_SWAP32_BCOPY(payload, bptr, xfer_size);
3830
3831 log_size -= xfer_size;
3832 offset += xfer_size;
3833 bptr += xfer_size;
3834 }
3835
3836 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3837 "Log upload complete.");
3838
3839 /* Write a string to text file to direct the user to the CEE */
3840 /* file for the actual log. */
3841 rval =
3842 emlxs_dump_string_txtfile(fpTxtFile, NV_LOG_INCLUDED_IN_FAT,
3843 LEGEND_NON_VOLATILE_LOG, LEGEND_NULL, 0);
3844
3845
3846 /* Write the log to the CEE file. */
3847 /* First word is the log size */
3848 bptr = buffer + sizeof (uint32_t);
3849 log_size = buffer_size - sizeof (uint32_t);
3850 rval = emlxs_dump_word_dmpfile(fpCeeFile, (uint8_t *)bptr,
3851 log_size, 0);
3852
3853 done:
3854
3855 if (mbq) {
3856 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
3857 }
3858
3859 if (mp) {
3860 emlxs_mem_buf_free(hba, mp);
3861 }
3862
3863 if (buffer) {
3864 kmem_free(buffer, buffer_size);
3865 }
3866
3867 if (rval == 0) {
3868 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3869 "Dump complete.");
3870 }
3871
3872 return (rval);
3873
3874 } /* emlxs_dump_tigershark_log() */
3875
3876
3877 extern uint32_t
emlxs_dump_user_event(emlxs_hba_t * hba)3878 emlxs_dump_user_event(
3879 emlxs_hba_t *hba)
3880 {
3881 emlxs_port_t *port = &PPORT;
3882 uint32_t status;
3883 emlxs_file_t *fpTxtFile;
3884 emlxs_file_t *fpDmpFile;
3885 emlxs_file_t *fpCeeFile;
3886
3887 mutex_enter(&EMLXS_DUMP_LOCK);
3888
3889 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3890 "User Event: Firmware core dump initiated...");
3891
3892 status =
3893 emlxs_dump_file_create(hba, &fpTxtFile, &fpDmpFile, &fpCeeFile);
3894 if (status != 0) {
3895 mutex_exit(&EMLXS_DUMP_LOCK);
3896 return (1);
3897 }
3898
3899 (void) emlxs_dump_rev_info(hba, fpTxtFile, fpDmpFile);
3900 (void) emlxs_dump_hba_info(hba, fpTxtFile, fpDmpFile, DUMP_TYPE_USER);
3901 (void) emlxs_dump_parm_table(hba, fpTxtFile, fpDmpFile);
3902 (void) emlxs_dump_cfg_regions(hba, fpTxtFile, fpDmpFile);
3903
3904 if (hba->model_info.chip == EMLXS_SATURN_CHIP) {
3905 (void) emlxs_set_hba_mode(hba, DDI_ONDI);
3906 (void) emlxs_dump_saturn_log(hba, fpTxtFile, fpDmpFile);
3907 }
3908
3909 if ((hba->model_info.chip == EMLXS_BE2_CHIP) ||
3910 (hba->model_info.chip == EMLXS_BE3_CHIP)) {
3911 (void) emlxs_dump_tigershark_log(hba, fpTxtFile, fpCeeFile);
3912 }
3913
3914 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
3915 (void) emlxs_set_hba_mode(hba, DDI_DIAGDI);
3916 }
3917
3918 (void) emlxs_dump_sli_interface(hba, fpTxtFile, fpDmpFile,
3919 DUMP_TYPE_USER);
3920
3921 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
3922 (void) emlxs_set_hba_mode(hba, DDI_WARMDI);
3923 }
3924
3925 (void) emlxs_dump_hba(hba, fpTxtFile, fpDmpFile);
3926
3927 (void) emlxs_set_hba_mode(hba, DDI_ONDI);
3928
3929 status = emlxs_menlo_set_mode(hba, MENLO_MAINTENANCE_MODE_ENABLE);
3930 if (status == 0) {
3931 (void) emlxs_dump_menlo_log(hba, fpCeeFile);
3932 (void) emlxs_menlo_set_mode(hba,
3933 MENLO_MAINTENANCE_MODE_DISABLE);
3934 }
3935
3936 (void) emlxs_dump_file_terminate(hba, fpTxtFile, fpDmpFile, fpCeeFile);
3937 (void) emlxs_dump_file_close(fpTxtFile, fpDmpFile, fpCeeFile);
3938
3939 mutex_exit(&EMLXS_DUMP_LOCK);
3940 return (0);
3941
3942 } /* emlxs_dump_user_event() */
3943
3944
3945 extern uint32_t
emlxs_dump_temp_event(emlxs_hba_t * hba,uint32_t tempType,uint32_t temp)3946 emlxs_dump_temp_event(
3947 emlxs_hba_t *hba,
3948 uint32_t tempType,
3949 uint32_t temp)
3950 {
3951 emlxs_port_t *port = &PPORT;
3952 uint32_t status;
3953 emlxs_file_t *fpTxtFile;
3954
3955 /* misc vars */
3956 char sBuf1[512]; /* general purpose string buffer */
3957 char sBuf2[256]; /* general purpose string buffer */
3958 char sBuf3[256]; /* general purpose string buffer */
3959
3960 if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3961 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3962 "Temperature Event: type=%d temp=%d. "\
3963 "Invalid SLI4 event.",
3964 tempType, temp);
3965
3966 return (1);
3967 }
3968
3969 mutex_enter(&EMLXS_DUMP_LOCK);
3970
3971 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
3972 "Temperature Event: type=%d temp=%d. "\
3973 "Firmware core dump initiated...",
3974 tempType, temp);
3975
3976 status = emlxs_dump_file_create(hba, &fpTxtFile, 0, 0);
3977 if (status != 0) {
3978 mutex_exit(&EMLXS_DUMP_LOCK);
3979 return (1);
3980 }
3981
3982 /* Now generate the Dump */
3983 /* Note: ignore return (status); if one part fails, */
3984 /* keep trying to dump more stuff. */
3985
3986 /* Write a warning at the top of the file */
3987 (void) strlcpy(sBuf1, "WARNING: HBA Temperature Event:\n",
3988 sizeof (sBuf1));
3989 switch (tempType) {
3990 case TEMP_TYPE_CRITICAL:
3991 (void) snprintf(sBuf2, sizeof (sBuf2),
3992 " Event Type = %d (Critical)\n", tempType);
3993 break;
3994 case TEMP_TYPE_THRESHOLD:
3995 (void) snprintf(sBuf2, sizeof (sBuf2),
3996 " Event Type = %d (Threshold)\n", tempType);
3997 break;
3998 case TEMP_TYPE_NORMAL:
3999 (void) snprintf(sBuf2, sizeof (sBuf2),
4000 " Event Type = %d (Normal)\n", tempType);
4001 break;
4002 default:
4003 (void) snprintf(sBuf2, sizeof (sBuf2),
4004 " Unknown Event Type = %d\n", tempType);
4005 break;
4006 }
4007 (void) snprintf(sBuf3, sizeof (sBuf3), " Temperature = %d\n\n", temp);
4008 (void) strlcat(sBuf1, sBuf2, sizeof (sBuf1));
4009 (void) strlcat(sBuf1, sBuf3, sizeof (sBuf1));
4010
4011 (void) emlxs_dump_string_txtfile(fpTxtFile, sBuf1, 0, 0, 0);
4012
4013 (void) emlxs_dump_rev_info(hba, fpTxtFile, NULL);
4014 (void) emlxs_dump_hba_info(hba, fpTxtFile, NULL, DUMP_TYPE_TEMP);
4015
4016 (void) emlxs_dump_file_terminate(hba, fpTxtFile, NULL, NULL);
4017 (void) emlxs_dump_file_close(fpTxtFile, NULL, NULL);
4018
4019 mutex_exit(&EMLXS_DUMP_LOCK);
4020 return (0);
4021
4022 } /* emlxs_dump_temp_event() */
4023
4024
4025 extern uint32_t
emlxs_dump_drv_event(emlxs_hba_t * hba)4026 emlxs_dump_drv_event(
4027 emlxs_hba_t *hba)
4028 {
4029 emlxs_port_t *port = &PPORT;
4030 uint32_t status;
4031 emlxs_file_t *fpTxtFile;
4032 emlxs_file_t *fpDmpFile;
4033 emlxs_file_t *fpCeeFile;
4034
4035 mutex_enter(&EMLXS_DUMP_LOCK);
4036
4037 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
4038 "Dump Event: Firmware core dump initiated...");
4039
4040 status =
4041 emlxs_dump_file_create(hba, &fpTxtFile, &fpDmpFile, &fpCeeFile);
4042 if (status != 0) {
4043 mutex_exit(&EMLXS_DUMP_LOCK);
4044 return (1);
4045 }
4046
4047 if (hba->model_info.chip == EMLXS_SATURN_CHIP) {
4048 (void) emlxs_set_hba_mode(hba, DDI_ONDI);
4049 (void) emlxs_dump_saturn_log(hba, fpTxtFile, fpDmpFile);
4050 }
4051
4052 if ((hba->model_info.chip == EMLXS_BE2_CHIP) ||
4053 (hba->model_info.chip == EMLXS_BE3_CHIP)) {
4054 (void) emlxs_dump_tigershark_log(hba, fpTxtFile, fpCeeFile);
4055 }
4056
4057 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
4058 (void) emlxs_set_hba_mode(hba, DDI_DIAGDI);
4059 }
4060
4061 (void) emlxs_dump_sli_interface(hba, fpTxtFile, fpDmpFile,
4062 DUMP_TYPE_DRIVER);
4063
4064 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
4065 (void) emlxs_set_hba_mode(hba, DDI_WARMDI);
4066 }
4067
4068 (void) emlxs_dump_hba(hba, fpTxtFile, fpDmpFile);
4069
4070 if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
4071 (void) emlxs_set_hba_mode(hba, DDI_ONDI);
4072 }
4073
4074 status = emlxs_menlo_set_mode(hba, MENLO_MAINTENANCE_MODE_ENABLE);
4075 if (status == 0) {
4076 (void) emlxs_dump_menlo_log(hba, fpCeeFile);
4077 }
4078
4079 /* Now generate the rest of the Dump */
4080 (void) emlxs_dump_rev_info(hba, fpTxtFile, fpDmpFile);
4081 (void) emlxs_dump_hba_info(hba, fpTxtFile, fpDmpFile, DUMP_TYPE_DRIVER);
4082 (void) emlxs_dump_parm_table(hba, fpTxtFile, fpDmpFile);
4083 (void) emlxs_dump_cfg_regions(hba, fpTxtFile, fpDmpFile);
4084
4085 (void) emlxs_dump_file_terminate(hba, fpTxtFile, fpDmpFile, fpCeeFile);
4086 (void) emlxs_dump_file_close(fpTxtFile, fpDmpFile, fpCeeFile);
4087
4088 /* The last step of the Menlo Dump. */
4089 (void) emlxs_menlo_reset(hba, MENLO_FW_OPERATIONAL);
4090
4091 (void) emlxs_set_hba_mode(hba, DDI_WARMDI);
4092
4093 mutex_exit(&EMLXS_DUMP_LOCK);
4094
4095
4096 return (0);
4097
4098 } /* emlxs_dump_drv_event() */
4099
4100
4101 /* ARGSUSED */
4102 extern void
emlxs_dump_drv_thread(emlxs_hba_t * hba,void * arg1,void * arg2)4103 emlxs_dump_drv_thread(emlxs_hba_t *hba,
4104 void *arg1, void *arg2)
4105 {
4106 (void) emlxs_dump_drv_event(hba);
4107
4108 /* Clear the Dump flag */
4109 mutex_enter(&EMLXS_PORT_LOCK);
4110 hba->flag &= ~FC_DUMP_ACTIVE;
4111 mutex_exit(&EMLXS_PORT_LOCK);
4112
4113 return;
4114
4115 } /* emlxs_dump_drv_thread() */
4116
4117
4118 /* ARGSUSED */
4119 extern void
emlxs_dump_user_thread(emlxs_hba_t * hba,void * arg1,void * arg2)4120 emlxs_dump_user_thread(emlxs_hba_t *hba,
4121 void *arg1, void *arg2)
4122 {
4123 (void) emlxs_dump_user_event(hba);
4124
4125 /* Clear the Dump flag */
4126 mutex_enter(&EMLXS_PORT_LOCK);
4127 hba->flag &= ~FC_DUMP_ACTIVE;
4128 mutex_exit(&EMLXS_PORT_LOCK);
4129
4130 return;
4131
4132 } /* emlxs_dump_user_thread() */
4133
4134
4135 /* ARGSUSED */
4136 extern void
emlxs_dump_temp_thread(emlxs_hba_t * hba,void * arg1,void * arg2)4137 emlxs_dump_temp_thread(emlxs_hba_t *hba,
4138 void *arg1, void *arg2)
4139 {
4140 dump_temp_event_t *temp_event = (dump_temp_event_t *)arg1;
4141
4142 (void) emlxs_dump_temp_event(temp_event->hba, temp_event->type,
4143 temp_event->temp);
4144
4145 /* Free the temp event object */
4146 kmem_free(temp_event, sizeof (dump_temp_event_t));
4147
4148 /* Clear the Dump flag */
4149 mutex_enter(&EMLXS_PORT_LOCK);
4150 hba->flag &= ~FC_DUMP_ACTIVE;
4151 mutex_exit(&EMLXS_PORT_LOCK);
4152
4153 return;
4154
4155 } /* emlxs_dump_temp_thread() */
4156
4157
4158 /* Schedules a dump thread */
4159 /* temp_type and temp are only valid for type=EMLXS_TEMP_DUMP */
4160 extern void
emlxs_dump(emlxs_hba_t * hba,uint32_t type,uint32_t temp_type,uint32_t temp)4161 emlxs_dump(emlxs_hba_t *hba, uint32_t type, uint32_t temp_type, uint32_t temp)
4162 {
4163 emlxs_port_t *port = &PPORT;
4164 dump_temp_event_t *temp_event = NULL;
4165
4166 mutex_enter(&EMLXS_PORT_LOCK);
4167
4168 /* Check if it is safe to dump */
4169 if (!(hba->flag & FC_DUMP_SAFE)) {
4170 mutex_exit(&EMLXS_PORT_LOCK);
4171
4172 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
4173 "dump: Dump disabled.");
4174
4175 return;
4176 }
4177
4178 /* Check if a dump is already in progess */
4179 if (hba->flag & FC_DUMP_ACTIVE) {
4180 mutex_exit(&EMLXS_PORT_LOCK);
4181
4182 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
4183 "dump: Dump already in progress.");
4184
4185 return;
4186 }
4187
4188 /* Prepare to schedule dump */
4189 switch (type) {
4190 case EMLXS_DRV_DUMP:
4191 case EMLXS_USER_DUMP:
4192 break;
4193
4194 case EMLXS_TEMP_DUMP:
4195 temp_event = (dump_temp_event_t *)kmem_alloc(
4196 sizeof (dump_temp_event_t), KM_NOSLEEP);
4197
4198 if (temp_event == NULL) {
4199 mutex_exit(&EMLXS_PORT_LOCK);
4200
4201 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
4202 "dump: Unable to allocate temp object.");
4203
4204 return;
4205 }
4206
4207 temp_event->hba = hba;
4208 temp_event->type = temp_type;
4209 temp_event->temp = temp;
4210 break;
4211
4212 default:
4213 mutex_exit(&EMLXS_PORT_LOCK);
4214
4215 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fw_dump_msg,
4216 "dump: Error: Unknown dump type. (%x)",
4217 type);
4218
4219 return;
4220 }
4221
4222 /* Set the Dump-in-progess flag */
4223 hba->flag |= FC_DUMP_ACTIVE;
4224 mutex_exit(&EMLXS_PORT_LOCK);
4225
4226 /* Create a separate thread to run the dump event */
4227 switch (type) {
4228 case EMLXS_DRV_DUMP:
4229 emlxs_thread_spawn(hba, emlxs_dump_drv_thread, NULL, NULL);
4230 break;
4231
4232 case EMLXS_TEMP_DUMP:
4233 emlxs_thread_spawn(hba, emlxs_dump_temp_thread,
4234 (void *)temp_event, NULL);
4235 break;
4236
4237 case EMLXS_USER_DUMP:
4238 emlxs_thread_spawn(hba, emlxs_dump_user_thread, NULL, NULL);
4239 break;
4240 }
4241
4242 return;
4243
4244 } /* emlxs_dump() */
4245
4246 extern void
emlxs_dump_wait(emlxs_hba_t * hba)4247 emlxs_dump_wait(emlxs_hba_t *hba)
4248 {
4249 /* Wait for the Dump flag to clear */
4250 while ((hba->flag & FC_DUMP_ACTIVE)) {
4251 BUSYWAIT_MS(1000);
4252 }
4253
4254 } /* emlxs_dump_wait() */
4255
4256
4257 #endif /* DUMP_SUPPORT */
4258