dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / mdb / common / modules / emlxs / emlxs.c
blob9f99436402bb293e90fc9858a7cde851ec42b062
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at
9 * http://www.opensource.org/licenses/cddl1.txt.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2004-2011 Emulex. All rights reserved.
24 * Use is subject to license terms.
27 #define DUMP_SUPPORT
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},
44 { NULL }
47 static const mdb_modinfo_t modinfo =
49 MDB_API_VERSION,
50 dcmds,
51 NULL
54 const mdb_modinfo_t *
55 _mdb_init(void)
57 return (&modinfo);
62 * emlxs_msgbuf library
64 void
65 emlxs_msgbuf_help()
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() */
76 /*ARGSUSED*/
77 int emlxs_msgbuf(uintptr_t base_addr, uint_t flags, int argc,
78 const mdb_arg_t *argv)
80 uintptr_t addr;
81 emlxs_device_t device;
82 uint32_t brd_no;
83 emlxs_msg_log_t log;
84 uint32_t count;
85 uint32_t first;
86 uint32_t last;
87 uint32_t idx;
88 uint32_t i;
89 char *level;
90 emlxs_msg_t msg;
91 char merge[1024];
93 emlxs_msg_entry_t entry;
94 char buffer[256];
95 char buffer2[256];
96 int32_t instance[MAX_FC_BRDS];
97 char driver[32];
98 int32_t instance_count;
99 uint32_t ddiinst;
101 if (argc != 1) {
102 mdb_printf("Usage: ::%s_msgbuf <instance(hex)>\n",
103 DRIVER_NAME);
104 mdb_printf("mdb: try \"::help %s_msgbuf\" for more information",
105 DRIVER_NAME);
107 return (DCMD_ERR);
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);
115 mdb_warn(buffer2);
117 mdb_snprintf(buffer2, sizeof (buffer2),
118 "Is the %s driver loaded ?\n", DRIVER_NAME);
119 mdb_warn(buffer2);
120 return (DCMD_ERR);
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",
127 buffer);
128 mdb_warn(buffer2);
130 mdb_snprintf(buffer2, sizeof (buffer2),
131 "Is the %s driver loaded ?\n", DRIVER_NAME);
132 mdb_warn(buffer2);
133 return (DCMD_ERR);
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",
140 buffer);
141 mdb_warn(buffer2);
143 mdb_snprintf(buffer2, sizeof (buffer2),
144 "Is the %s driver loaded ?\n", DRIVER_NAME);
145 mdb_warn(buffer2);
146 return (DCMD_ERR);
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) {
153 break;
157 if (brd_no == instance_count) {
158 mdb_warn("Device instance not found. ddinst=%d\n", ddiinst);
159 return (DCMD_ERR);
162 /* Check if buffer is null */
163 addr = (uintptr_t)device.log[brd_no];
164 if (addr == 0) {
165 mdb_warn("Device instance not found. ddinst=%d\n", ddiinst);
166 return (0);
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);
173 return (0);
176 /* Check if buffer is empty */
177 if (log.count == 0) {
178 mdb_warn("Log buffer empty.\n");
179 return (0);
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;
188 idx = log.next;
189 } else {
190 /* Buffer not yet filled */
191 first = 0;
192 idx = 0;
195 /* Get the total number of messages available for return */
196 count = last - first + 1;
198 mdb_printf("\n");
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",
205 idx, count);
206 return (DCMD_ERR);
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",
212 idx, count);
213 return (DCMD_ERR);
216 switch (msg.level) {
217 case EMLXS_DEBUG:
218 level = " DEBUG";
219 break;
221 case EMLXS_NOTICE:
222 level = " NOTICE";
223 break;
225 case EMLXS_WARNING:
226 level = "WARNING";
227 break;
229 case EMLXS_ERROR:
230 level = " ERROR";
231 break;
233 case EMLXS_PANIC:
234 level = " PANIC";
235 break;
237 default:
238 level = "UNKNOWN";
239 break;
242 if (entry.vpi == 0) {
243 mdb_snprintf(driver, sizeof (driver), "%s%d",
244 DRIVER_NAME, entry.instance);
245 } else {
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);
264 } else {
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,
274 msg.buffer);
276 } else {
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,
287 entry.buffer);
289 } else {
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,
299 msg.buffer);
303 mdb_printf("%s", merge);
305 /* Increment index */
306 if (++idx >= log.size) {
307 idx = 0;
311 mdb_printf("\n");
313 return (0);
315 } /* emlxs_msgbuf() */
318 void
319 emlxs_dump_help()
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);
325 mdb_printf("\n");
326 mdb_printf(" txt Display firmware text summary " \
327 "file.\n");
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() */
339 /*ARGSUSED*/
341 emlxs_dump(uintptr_t base_addr, uint_t flags, int argc,
342 const mdb_arg_t *argv)
344 uintptr_t addr;
345 emlxs_device_t device;
346 uint32_t brd_no;
347 uint32_t i;
348 char buffer[256];
349 char buffer2[256];
350 int32_t instance[MAX_FC_BRDS];
351 int32_t instance_count;
352 uint32_t ddiinst;
353 uint8_t *bptr;
354 char *cptr;
355 emlxs_file_t dump_txtfile;
356 emlxs_file_t dump_dmpfile;
357 emlxs_file_t dump_ceefile;
358 uint32_t size;
359 uint32_t file;
361 if (argc != 2) {
362 goto usage;
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)) {
368 file = 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)) {
372 file = 1;
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)) {
376 file = 2;
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)) {
380 file = 3;
381 } else {
382 goto usage;
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);
390 mdb_warn(buffer2);
392 mdb_snprintf(buffer2, sizeof (buffer2),
393 "Is the %s driver loaded ?\n", DRIVER_NAME);
394 mdb_warn(buffer2);
395 return (DCMD_ERR);
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",
402 buffer);
403 mdb_warn(buffer2);
405 mdb_snprintf(buffer2, sizeof (buffer2),
406 "Is the %s driver loaded ?\n", DRIVER_NAME);
407 mdb_warn(buffer2);
408 return (DCMD_ERR);
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",
415 buffer);
416 mdb_warn(buffer2);
418 mdb_snprintf(buffer2, sizeof (buffer2),
419 "Is the %s driver loaded ?\n", DRIVER_NAME);
420 mdb_warn(buffer2);
421 return (DCMD_ERR);
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) {
428 break;
432 if (brd_no == instance_count) {
433 mdb_warn("Device instance not found. ddinst=%d\n", ddiinst);
434 return (DCMD_ERR);
437 if (file == 0 || file == 1) {
439 addr = (uintptr_t)device.dump_txtfile[brd_no];
440 if (addr == 0) {
441 mdb_warn("TXT file: Device instance not found. " \
442 "ddinst=%d\n", ddiinst);
443 goto dmp_file;
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);
450 goto dmp_file;
453 size = (uintptr_t)dump_txtfile.ptr -
454 (uintptr_t)dump_txtfile.buffer;
456 if (size == 0) {
457 mdb_printf("TXT file: Not available.\n");
458 goto dmp_file;
460 bptr = (uint8_t *)mdb_zalloc(size, UM_SLEEP|UM_GC);
462 if (bptr == 0) {
463 mdb_warn("TXT file: Unable to allocate file buffer. " \
464 "ddinst=%d size=%d\n", ddiinst, size);
465 goto dmp_file;
468 if (mdb_vread(bptr, size, (uintptr_t)dump_txtfile.buffer)
469 != size) {
470 mdb_warn("TXT file: Unable to read %d bytes @ %llx.\n",
471 size, dump_txtfile.buffer);
472 goto dmp_file;
475 mdb_printf("<TXT File Start>\n");
476 mdb_printf("\n");
477 mdb_printf("%s", bptr);
478 mdb_printf("\n");
479 mdb_printf("<TXT File End>\n");
482 dmp_file:
484 if (file == 0 || file == 2) {
485 addr = (uintptr_t)device.dump_dmpfile[brd_no];
486 if (addr == 0) {
487 mdb_warn("DMP file: Device instance not found. " \
488 "ddinst=%d\n", ddiinst);
489 goto cee_file;
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);
496 goto cee_file;
499 size = (uintptr_t)dump_dmpfile.ptr -
500 (uintptr_t)dump_dmpfile.buffer;
502 if (size == 0) {
503 mdb_printf("DMP file: Not available.\n");
504 goto cee_file;
507 bptr = (uint8_t *)mdb_zalloc(size, UM_SLEEP|UM_GC);
509 if (bptr == 0) {
510 mdb_warn("DMP file: Unable to allocate file buffer. " \
511 "ddinst=%d size=%d\n", ddiinst, size);
512 goto cee_file;
515 if (mdb_vread(bptr, size, (uintptr_t)dump_dmpfile.buffer)
516 != size) {
517 mdb_warn("DMP file: Unable to read %d bytes @ %llx.\n",
518 size, dump_dmpfile.buffer);
519 goto cee_file;
522 mdb_printf("<DMP File Start>\n");
523 mdb_printf("\n");
525 bzero(buffer2, sizeof (buffer2));
526 cptr = buffer2;
527 for (i = 0; i < size; i++) {
528 if (i && !(i % 16)) {
529 mdb_printf(" %s\n", buffer2);
530 bzero(buffer2, sizeof (buffer2));
531 cptr = buffer2;
534 if (!(i % 16)) {
535 mdb_printf("%08X: ", i);
538 if (!(i % 4)) {
539 mdb_printf(" ");
542 if ((*bptr >= 32) && (*bptr <= 126)) {
543 *cptr++ = *bptr;
544 } else {
545 *cptr++ = '.';
548 mdb_printf("%02X ", *bptr++);
551 size = 16 - (i % 16);
552 for (i = 0; size < 16 && i < size; i++) {
553 if (!(i % 4)) {
554 mdb_printf(" ");
557 mdb_printf(" ");
559 mdb_printf(" %s\n", buffer2);
560 mdb_printf("\n");
561 mdb_printf("<DMP File End>\n");
564 cee_file:
566 if (file == 0 || file == 3) {
568 addr = (uintptr_t)device.dump_ceefile[brd_no];
569 if (addr == 0) {
570 mdb_warn("CEE file: Device instance not found. " \
571 "ddinst=%d\n", ddiinst);
572 goto done;
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);
579 goto done;
582 size = (uintptr_t)dump_ceefile.ptr -
583 (uintptr_t)dump_ceefile.buffer;
585 if (size == 0) {
586 mdb_printf("CEE file: Not available.\n");
587 goto done;
590 bptr = (uint8_t *)mdb_zalloc(size, UM_SLEEP|UM_GC);
592 if (bptr == 0) {
593 mdb_warn("CEE file: Unable to allocate file buffer. " \
594 "ddinst=%d size=%d\n", ddiinst, size);
595 goto done;
598 if (mdb_vread(bptr, size, (uintptr_t)dump_ceefile.buffer)
599 != size) {
600 mdb_warn("CEE file: Unable to read %d bytes @ %llx.\n",
601 size, dump_ceefile.buffer);
602 goto done;
605 mdb_printf("<CEE File Start>\n");
606 mdb_printf("\n");
608 bzero(buffer2, sizeof (buffer2));
609 cptr = buffer2;
610 for (i = 0; i < size; i++) {
611 if (i && !(i % 16)) {
612 mdb_printf(" %s\n", buffer2);
613 bzero(buffer2, sizeof (buffer2));
614 cptr = buffer2;
617 if (!(i % 16)) {
618 mdb_printf("%08X: ", i);
621 if (!(i % 4)) {
622 mdb_printf(" ");
625 if ((*bptr >= 32) && (*bptr <= 126)) {
626 *cptr++ = *bptr;
627 } else {
628 *cptr++ = '.';
631 mdb_printf("%02X ", *bptr++);
634 size = 16 - (i % 16);
635 for (i = 0; size < 16 && i < size; i++) {
636 if (!(i % 4)) {
637 mdb_printf(" ");
640 mdb_printf(" ");
642 mdb_printf(" %s\n", buffer2);
643 mdb_printf("\n");
644 mdb_printf("<CEE File End>\n");
646 done:
648 mdb_printf("\n");
649 return (0);
651 usage:
652 mdb_printf("Usage: ::%s_dump <file> <instance (hex)>\n",
653 DRIVER_NAME);
654 mdb_printf("mdb: try \"::help %s_dump\" for more information",
655 DRIVER_NAME);
657 return (DCMD_ERR);
659 } /* emlxs_dump() */