4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at
9 * http://www.opensource.org/licenses/cddl1.txt.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2004-2011 Emulex. All rights reserved.
24 * Use is subject to license terms.
29 #include <emlxs_mdb.h>
30 #include <emlxs_msg.h>
31 #include <emlxs_dump.h>
32 #include <emlxs_device.h>
35 * MDB module linkage information:
38 static const mdb_dcmd_t dcmds
[] =
40 { DRIVER_NAME
"_msgbuf", "<instance>", "dumps the "DRIVER_NAME
41 " driver internal message buffer", emlxs_msgbuf
, emlxs_msgbuf_help
},
42 { DRIVER_NAME
"_dump", "<type> <instance>", "dumps the "DRIVER_NAME
43 " driver firmware core", emlxs_dump
, emlxs_dump_help
},
47 static const mdb_modinfo_t modinfo
=
62 * emlxs_msgbuf library
68 mdb_printf("Usage: ::%s_msgbuf <instance(hex)>\n\n", DRIVER_NAME
);
69 mdb_printf(" <instance> This is the %s driver instance " \
70 "number in hex.\n", DRIVER_NAME
);
71 mdb_printf(" (e.g. 0, 1,..., e, f, etc.)\n");
73 } /* emlxs_msgbuf_help() */
77 int emlxs_msgbuf(uintptr_t base_addr
, uint_t flags
, int argc
,
78 const mdb_arg_t
*argv
)
81 emlxs_device_t device
;
93 emlxs_msg_entry_t entry
;
96 int32_t instance
[MAX_FC_BRDS
];
98 int32_t instance_count
;
102 mdb_printf("Usage: ::%s_msgbuf <instance(hex)>\n",
104 mdb_printf("mdb: try \"::help %s_msgbuf\" for more information",
110 /* Get the device address */
111 mdb_snprintf(buffer
, sizeof (buffer
), "%s_device", DRIVER_NAME
);
112 if (mdb_readvar(&device
, buffer
) == -1) {
113 mdb_snprintf(buffer2
, sizeof (buffer2
),
114 "%s not found.\n", buffer
);
117 mdb_snprintf(buffer2
, sizeof (buffer2
),
118 "Is the %s driver loaded ?\n", DRIVER_NAME
);
123 /* Get the device instance table */
124 mdb_snprintf(buffer
, sizeof (buffer
), "%s_instance", DRIVER_NAME
);
125 if (mdb_readvar(&instance
, buffer
) == -1) {
126 mdb_snprintf(buffer2
, sizeof (buffer2
), "%s not found.\n",
130 mdb_snprintf(buffer2
, sizeof (buffer2
),
131 "Is the %s driver loaded ?\n", DRIVER_NAME
);
136 /* Get the device instance count */
137 mdb_snprintf(buffer
, sizeof (buffer
), "%s_instance_count", DRIVER_NAME
);
138 if (mdb_readvar(&instance_count
, buffer
) == -1) {
139 mdb_snprintf(buffer2
, sizeof (buffer2
), "%s not found.\n",
143 mdb_snprintf(buffer2
, sizeof (buffer2
),
144 "Is the %s driver loaded ?\n", DRIVER_NAME
);
149 ddiinst
= (uint32_t)mdb_strtoull(argv
[0].a_un
.a_str
);
151 for (brd_no
= 0; brd_no
< instance_count
; brd_no
++) {
152 if (instance
[brd_no
] == ddiinst
) {
157 if (brd_no
== instance_count
) {
158 mdb_warn("Device instance not found. ddinst=%d\n", ddiinst
);
162 /* Check if buffer is null */
163 addr
= (uintptr_t)device
.log
[brd_no
];
165 mdb_warn("Device instance not found. ddinst=%d\n", ddiinst
);
169 if (mdb_vread(&log
, sizeof (emlxs_msg_log_t
), addr
) !=
170 sizeof (emlxs_msg_log_t
)) {
171 mdb_warn("\nUnable to read %d bytes @ %llx.\n",
172 sizeof (emlxs_msg_log_t
), addr
);
176 /* Check if buffer is empty */
177 if (log
.count
== 0) {
178 mdb_warn("Log buffer empty.\n");
182 /* Get last entry id saved */
183 last
= log
.count
- 1;
185 /* Check if buffer has already been filled once */
186 if (log
.count
>= log
.size
) {
187 first
= log
.count
- log
.size
;
190 /* Buffer not yet filled */
195 /* Get the total number of messages available for return */
196 count
= last
- first
+ 1;
200 /* Print the messages */
201 for (i
= 0; i
< count
; i
++) {
202 if (mdb_vread(&entry
, sizeof (emlxs_msg_entry_t
),
203 (uintptr_t)&log
.entry
[idx
]) != sizeof (emlxs_msg_entry_t
)) {
204 mdb_warn("Cannot read log entry. index=%d count=%d\n",
209 if (mdb_vread(&msg
, sizeof (emlxs_msg_t
),
210 (uintptr_t)entry
.msg
) != sizeof (emlxs_msg_t
)) {
211 mdb_warn("Cannot read msg. index=%d count=%d\n",
242 if (entry
.vpi
== 0) {
243 mdb_snprintf(driver
, sizeof (driver
), "%s%d",
244 DRIVER_NAME
, entry
.instance
);
246 mdb_snprintf(driver
, sizeof (driver
), "%s%d.%d",
247 DRIVER_NAME
, entry
.instance
, entry
.vpi
);
250 /* Generate the message string */
251 if (msg
.buffer
[0] != 0) {
252 if (entry
.buffer
[0] != 0) {
253 mdb_snprintf(merge
, sizeof (merge
),
254 "[%Y:%03d:%03d:%03d] "
255 "%6d:[%1X.%04X]%s:%7s:%4d:\n%s\n(%s)\n",
256 entry
.id_time
.tv_sec
,
257 (int)entry
.id_time
.tv_nsec
/1000000,
258 (int)(entry
.id_time
.tv_nsec
/1000)%1000,
259 (int)entry
.id_time
.tv_nsec
%1000,
260 entry
.id
, entry
.fileno
,
261 entry
.line
, driver
, level
, msg
.id
,
262 msg
.buffer
, entry
.buffer
);
265 mdb_snprintf(merge
, sizeof (merge
),
266 "[%Y:%03d:%03d:%03d] "
267 "%6d:[%1X.%04X]%s:%7s:%4d:\n%s\n",
268 entry
.id_time
.tv_sec
,
269 (int)entry
.id_time
.tv_nsec
/1000000,
270 (int)(entry
.id_time
.tv_nsec
/1000)%1000,
271 (int)entry
.id_time
.tv_nsec
%1000,
272 entry
.id
, entry
.fileno
,
273 entry
.line
, driver
, level
, msg
.id
,
277 if (entry
.buffer
[0] != 0) {
278 mdb_snprintf(merge
, sizeof (merge
),
279 "[%Y:%03d:%03d:%03d] "
280 "%6d:[%1X.%04X]%s:%7s:%4d:\n(%s)\n",
281 entry
.id_time
.tv_sec
,
282 (int)entry
.id_time
.tv_nsec
/1000000,
283 (int)(entry
.id_time
.tv_nsec
/1000)%1000,
284 (int)entry
.id_time
.tv_nsec
%1000,
285 entry
.id
, entry
.fileno
,
286 entry
.line
, driver
, level
, msg
.id
,
290 mdb_snprintf(merge
, sizeof (merge
),
291 "[%Y:%03d:%03d:%03d] "
292 "%6d:[%1X.%04X]%s:%7s:%4d:\n%s\n",
293 entry
.id_time
.tv_sec
,
294 (int)entry
.id_time
.tv_nsec
/1000000,
295 (int)(entry
.id_time
.tv_nsec
/1000)%1000,
296 (int)entry
.id_time
.tv_nsec
%1000,
297 entry
.id
, entry
.fileno
,
298 entry
.line
, driver
, level
, msg
.id
,
303 mdb_printf("%s", merge
);
305 /* Increment index */
306 if (++idx
>= log
.size
) {
315 } /* emlxs_msgbuf() */
321 mdb_printf("Usage: ::%s_dump all <instance(hex)>\n", DRIVER_NAME
);
322 mdb_printf(" ::%s_dump txt <instance(hex)>\n", DRIVER_NAME
);
323 mdb_printf(" ::%s_dump dmp <instance(hex)>\n", DRIVER_NAME
);
324 mdb_printf(" ::%s_dump cee <instance(hex)>\n", DRIVER_NAME
);
326 mdb_printf(" txt Display firmware text summary " \
328 mdb_printf(" dmp Display firmware dmp binary file.\n");
329 mdb_printf(" cee Display firmware cee binary file. " \
330 "(FCOE adapters only)\n");
331 mdb_printf(" all Display all firmware core files.\n");
332 mdb_printf(" <instance> This is the %s driver instance " \
333 "number in hex.\n", DRIVER_NAME
);
334 mdb_printf(" (e.g. 0, 1,..., e, f, etc.)\n");
336 } /* emlxs_dump_help() */
341 emlxs_dump(uintptr_t base_addr
, uint_t flags
, int argc
,
342 const mdb_arg_t
*argv
)
345 emlxs_device_t device
;
350 int32_t instance
[MAX_FC_BRDS
];
351 int32_t instance_count
;
355 emlxs_file_t dump_txtfile
;
356 emlxs_file_t dump_dmpfile
;
357 emlxs_file_t dump_ceefile
;
365 if ((strcmp(argv
[0].a_un
.a_str
, "all") == 0) ||
366 (strcmp(argv
[0].a_un
.a_str
, "ALL") == 0) ||
367 (strcmp(argv
[0].a_un
.a_str
, "All") == 0)) {
369 } else if ((strcmp(argv
[0].a_un
.a_str
, "txt") == 0) ||
370 (strcmp(argv
[0].a_un
.a_str
, "TXT") == 0) ||
371 (strcmp(argv
[0].a_un
.a_str
, "Txt") == 0)) {
373 } else if ((strcmp(argv
[0].a_un
.a_str
, "dmp") == 0) ||
374 (strcmp(argv
[0].a_un
.a_str
, "DMP") == 0) ||
375 (strcmp(argv
[0].a_un
.a_str
, "Dmp") == 0)) {
377 } else if ((strcmp(argv
[0].a_un
.a_str
, "cee") == 0) ||
378 (strcmp(argv
[0].a_un
.a_str
, "CEE") == 0) ||
379 (strcmp(argv
[0].a_un
.a_str
, "Cee") == 0)) {
385 /* Get the device address */
386 mdb_snprintf(buffer
, sizeof (buffer
), "%s_device", DRIVER_NAME
);
387 if (mdb_readvar(&device
, buffer
) == -1) {
388 mdb_snprintf(buffer2
, sizeof (buffer2
),
389 "%s not found.\n", buffer
);
392 mdb_snprintf(buffer2
, sizeof (buffer2
),
393 "Is the %s driver loaded ?\n", DRIVER_NAME
);
398 /* Get the device instance table */
399 mdb_snprintf(buffer
, sizeof (buffer
), "%s_instance", DRIVER_NAME
);
400 if (mdb_readvar(&instance
, buffer
) == -1) {
401 mdb_snprintf(buffer2
, sizeof (buffer2
), "%s not found.\n",
405 mdb_snprintf(buffer2
, sizeof (buffer2
),
406 "Is the %s driver loaded ?\n", DRIVER_NAME
);
411 /* Get the device instance count */
412 mdb_snprintf(buffer
, sizeof (buffer
), "%s_instance_count", DRIVER_NAME
);
413 if (mdb_readvar(&instance_count
, buffer
) == -1) {
414 mdb_snprintf(buffer2
, sizeof (buffer2
), "%s not found.\n",
418 mdb_snprintf(buffer2
, sizeof (buffer2
),
419 "Is the %s driver loaded ?\n", DRIVER_NAME
);
424 ddiinst
= (uint32_t)mdb_strtoull(argv
[1].a_un
.a_str
);
426 for (brd_no
= 0; brd_no
< instance_count
; brd_no
++) {
427 if (instance
[brd_no
] == ddiinst
) {
432 if (brd_no
== instance_count
) {
433 mdb_warn("Device instance not found. ddinst=%d\n", ddiinst
);
437 if (file
== 0 || file
== 1) {
439 addr
= (uintptr_t)device
.dump_txtfile
[brd_no
];
441 mdb_warn("TXT file: Device instance not found. " \
442 "ddinst=%d\n", ddiinst
);
446 if (mdb_vread(&dump_txtfile
, sizeof (dump_txtfile
), addr
)
447 != sizeof (dump_txtfile
)) {
448 mdb_warn("TXT file: Unable to read %d bytes @ %llx.\n",
449 sizeof (dump_txtfile
), addr
);
453 size
= (uintptr_t)dump_txtfile
.ptr
-
454 (uintptr_t)dump_txtfile
.buffer
;
457 mdb_printf("TXT file: Not available.\n");
460 bptr
= (uint8_t *)mdb_zalloc(size
, UM_SLEEP
|UM_GC
);
463 mdb_warn("TXT file: Unable to allocate file buffer. " \
464 "ddinst=%d size=%d\n", ddiinst
, size
);
468 if (mdb_vread(bptr
, size
, (uintptr_t)dump_txtfile
.buffer
)
470 mdb_warn("TXT file: Unable to read %d bytes @ %llx.\n",
471 size
, dump_txtfile
.buffer
);
475 mdb_printf("<TXT File Start>\n");
477 mdb_printf("%s", bptr
);
479 mdb_printf("<TXT File End>\n");
484 if (file
== 0 || file
== 2) {
485 addr
= (uintptr_t)device
.dump_dmpfile
[brd_no
];
487 mdb_warn("DMP file: Device instance not found. " \
488 "ddinst=%d\n", ddiinst
);
492 if (mdb_vread(&dump_dmpfile
, sizeof (dump_dmpfile
), addr
)
493 != sizeof (dump_dmpfile
)) {
494 mdb_warn("DMP file: Unable to read %d bytes @ %llx.\n",
495 sizeof (dump_dmpfile
), addr
);
499 size
= (uintptr_t)dump_dmpfile
.ptr
-
500 (uintptr_t)dump_dmpfile
.buffer
;
503 mdb_printf("DMP file: Not available.\n");
507 bptr
= (uint8_t *)mdb_zalloc(size
, UM_SLEEP
|UM_GC
);
510 mdb_warn("DMP file: Unable to allocate file buffer. " \
511 "ddinst=%d size=%d\n", ddiinst
, size
);
515 if (mdb_vread(bptr
, size
, (uintptr_t)dump_dmpfile
.buffer
)
517 mdb_warn("DMP file: Unable to read %d bytes @ %llx.\n",
518 size
, dump_dmpfile
.buffer
);
522 mdb_printf("<DMP File Start>\n");
525 bzero(buffer2
, sizeof (buffer2
));
527 for (i
= 0; i
< size
; i
++) {
528 if (i
&& !(i
% 16)) {
529 mdb_printf(" %s\n", buffer2
);
530 bzero(buffer2
, sizeof (buffer2
));
535 mdb_printf("%08X: ", i
);
542 if ((*bptr
>= 32) && (*bptr
<= 126)) {
548 mdb_printf("%02X ", *bptr
++);
551 size
= 16 - (i
% 16);
552 for (i
= 0; size
< 16 && i
< size
; i
++) {
559 mdb_printf(" %s\n", buffer2
);
561 mdb_printf("<DMP File End>\n");
566 if (file
== 0 || file
== 3) {
568 addr
= (uintptr_t)device
.dump_ceefile
[brd_no
];
570 mdb_warn("CEE file: Device instance not found. " \
571 "ddinst=%d\n", ddiinst
);
575 if (mdb_vread(&dump_ceefile
, sizeof (dump_ceefile
), addr
)
576 != sizeof (dump_ceefile
)) {
577 mdb_warn("CEE file: Unable to read %d bytes @ %llx.\n",
578 sizeof (dump_ceefile
), addr
);
582 size
= (uintptr_t)dump_ceefile
.ptr
-
583 (uintptr_t)dump_ceefile
.buffer
;
586 mdb_printf("CEE file: Not available.\n");
590 bptr
= (uint8_t *)mdb_zalloc(size
, UM_SLEEP
|UM_GC
);
593 mdb_warn("CEE file: Unable to allocate file buffer. " \
594 "ddinst=%d size=%d\n", ddiinst
, size
);
598 if (mdb_vread(bptr
, size
, (uintptr_t)dump_ceefile
.buffer
)
600 mdb_warn("CEE file: Unable to read %d bytes @ %llx.\n",
601 size
, dump_ceefile
.buffer
);
605 mdb_printf("<CEE File Start>\n");
608 bzero(buffer2
, sizeof (buffer2
));
610 for (i
= 0; i
< size
; i
++) {
611 if (i
&& !(i
% 16)) {
612 mdb_printf(" %s\n", buffer2
);
613 bzero(buffer2
, sizeof (buffer2
));
618 mdb_printf("%08X: ", i
);
625 if ((*bptr
>= 32) && (*bptr
<= 126)) {
631 mdb_printf("%02X ", *bptr
++);
634 size
= 16 - (i
% 16);
635 for (i
= 0; size
< 16 && i
< size
; i
++) {
642 mdb_printf(" %s\n", buffer2
);
644 mdb_printf("<CEE File End>\n");
652 mdb_printf("Usage: ::%s_dump <file> <instance (hex)>\n",
654 mdb_printf("mdb: try \"::help %s_dump\" for more information",