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