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