1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8*8f23e9faSHans Rosenfeld  * You can obtain a copy of the license at
9*8f23e9faSHans Rosenfeld  * http://www.opensource.org/licenses/cddl1.txt.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22fcf3ce44SJohn Forte /*
23*8f23e9faSHans Rosenfeld  * Copyright (c) 2004-2011 Emulex. All rights reserved.
2482527734SSukumar Swaminathan  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
27291a2b48SSukumar Swaminathan #define	DUMP_SUPPORT
28291a2b48SSukumar Swaminathan 
29291a2b48SSukumar Swaminathan #include <emlxs_mdb.h>
30291a2b48SSukumar Swaminathan #include <emlxs_msg.h>
31291a2b48SSukumar Swaminathan #include <emlxs_dump.h>
32291a2b48SSukumar Swaminathan #include <emlxs_device.h>
33fcf3ce44SJohn Forte 
34fcf3ce44SJohn Forte /*
35fcf3ce44SJohn Forte  * MDB module linkage information:
36fcf3ce44SJohn Forte  */
37fcf3ce44SJohn Forte 
38fcf3ce44SJohn Forte static const mdb_dcmd_t dcmds[] =
39fcf3ce44SJohn Forte {
40*8f23e9faSHans Rosenfeld 	{ DRIVER_NAME"_msgbuf", "<instance>", "dumps the "DRIVER_NAME
41*8f23e9faSHans Rosenfeld 	    " driver internal message buffer", emlxs_msgbuf, emlxs_msgbuf_help},
42*8f23e9faSHans Rosenfeld 	{ DRIVER_NAME"_dump", "<type> <instance>", "dumps the "DRIVER_NAME
43*8f23e9faSHans Rosenfeld 	    " driver firmware core", emlxs_dump, emlxs_dump_help},
44fcf3ce44SJohn Forte 	{ NULL }
45fcf3ce44SJohn Forte };
46fcf3ce44SJohn Forte 
47fcf3ce44SJohn Forte static const mdb_modinfo_t modinfo =
48fcf3ce44SJohn Forte {
49fcf3ce44SJohn Forte 	MDB_API_VERSION,
50fcf3ce44SJohn Forte 	dcmds,
51fcf3ce44SJohn Forte 	NULL
52fcf3ce44SJohn Forte };
53fcf3ce44SJohn Forte 
54fcf3ce44SJohn Forte const mdb_modinfo_t *
_mdb_init(void)55fcf3ce44SJohn Forte _mdb_init(void)
56fcf3ce44SJohn Forte {
57fcf3ce44SJohn Forte 	return (&modinfo);
58fcf3ce44SJohn Forte }
59fcf3ce44SJohn Forte 
60fcf3ce44SJohn Forte 
61fcf3ce44SJohn Forte /*
62fcf3ce44SJohn Forte  * emlxs_msgbuf library
63fcf3ce44SJohn Forte  */
64fcf3ce44SJohn Forte void
emlxs_msgbuf_help()65fcf3ce44SJohn Forte emlxs_msgbuf_help()
66fcf3ce44SJohn Forte {
67fcf3ce44SJohn Forte 
68291a2b48SSukumar Swaminathan 	mdb_printf("Usage:   ::%s_msgbuf  <instance(hex)>\n\n", DRIVER_NAME);
69291a2b48SSukumar Swaminathan 	mdb_printf("         <instance>   This is the %s driver instance " \
70291a2b48SSukumar Swaminathan 	    "number in hex.\n", DRIVER_NAME);
71fcf3ce44SJohn Forte 	mdb_printf("                      (e.g. 0, 1,..., e, f, etc.)\n");
72fcf3ce44SJohn Forte 
73fcf3ce44SJohn Forte } /* emlxs_msgbuf_help() */
74fcf3ce44SJohn Forte 
75fcf3ce44SJohn Forte 
76fcf3ce44SJohn Forte /*ARGSUSED*/
emlxs_msgbuf(uintptr_t base_addr,uint_t flags,int argc,const mdb_arg_t * argv)77fcf3ce44SJohn Forte int emlxs_msgbuf(uintptr_t base_addr, uint_t flags, int argc,
78fcf3ce44SJohn Forte 				const mdb_arg_t *argv)
79fcf3ce44SJohn Forte {
80fcf3ce44SJohn Forte 	uintptr_t  addr;
81fcf3ce44SJohn Forte 	emlxs_device_t device;
82fcf3ce44SJohn Forte 	uint32_t brd_no;
83fcf3ce44SJohn Forte 	emlxs_msg_log_t log;
84fcf3ce44SJohn Forte 	uint32_t count;
85fcf3ce44SJohn Forte 	uint32_t first;
86fcf3ce44SJohn Forte 	uint32_t last;
87fcf3ce44SJohn Forte 	uint32_t idx;
88fcf3ce44SJohn Forte 	uint32_t i;
89fcf3ce44SJohn Forte 	char *level;
90fcf3ce44SJohn Forte 	emlxs_msg_t msg;
9182527734SSukumar Swaminathan 	char	merge[1024];
9282527734SSukumar Swaminathan 
93fcf3ce44SJohn Forte 	emlxs_msg_entry_t entry;
94fcf3ce44SJohn Forte 	char buffer[256];
95fcf3ce44SJohn Forte 	char buffer2[256];
96fcf3ce44SJohn Forte 	int32_t instance[MAX_FC_BRDS];
97fcf3ce44SJohn Forte 	char driver[32];
98fcf3ce44SJohn Forte 	int32_t instance_count;
99fcf3ce44SJohn Forte 	uint32_t ddiinst;
100fcf3ce44SJohn Forte 
101fcf3ce44SJohn Forte 	if (argc != 1) {
102291a2b48SSukumar Swaminathan 		mdb_printf("Usage:   ::%s_msgbuf  <instance(hex)>\n",
103fcf3ce44SJohn Forte 		    DRIVER_NAME);
104fcf3ce44SJohn Forte 		mdb_printf("mdb: try \"::help %s_msgbuf\" for more information",
105fcf3ce44SJohn Forte 		    DRIVER_NAME);
106fcf3ce44SJohn Forte 
107fcf3ce44SJohn Forte 		return (DCMD_ERR);
108fcf3ce44SJohn Forte 	}
109fcf3ce44SJohn Forte 
110fcf3ce44SJohn Forte 	/* Get the device address */
111fcf3ce44SJohn Forte 	mdb_snprintf(buffer, sizeof (buffer), "%s_device", DRIVER_NAME);
112fcf3ce44SJohn Forte 	if (mdb_readvar(&device, buffer) == -1) {
113fcf3ce44SJohn Forte 		mdb_snprintf(buffer2, sizeof (buffer2),
114fcf3ce44SJohn Forte 		    "%s not found.\n", buffer);
115fcf3ce44SJohn Forte 		mdb_warn(buffer2);
116fcf3ce44SJohn Forte 
117fcf3ce44SJohn Forte 		mdb_snprintf(buffer2, sizeof (buffer2),
118fcf3ce44SJohn Forte 		    "Is the %s driver loaded ?\n", DRIVER_NAME);
119fcf3ce44SJohn Forte 		mdb_warn(buffer2);
120fcf3ce44SJohn Forte 		return (DCMD_ERR);
121fcf3ce44SJohn Forte 	}
122fcf3ce44SJohn Forte 
123fcf3ce44SJohn Forte 	/* Get the device instance table */
124fcf3ce44SJohn Forte 	mdb_snprintf(buffer, sizeof (buffer), "%s_instance", DRIVER_NAME);
125fcf3ce44SJohn Forte 	if (mdb_readvar(&instance, buffer) == -1) {
126fcf3ce44SJohn Forte 		mdb_snprintf(buffer2, sizeof (buffer2), "%s not found.\n",
127fcf3ce44SJohn Forte 		    buffer);
128fcf3ce44SJohn Forte 		mdb_warn(buffer2);
129fcf3ce44SJohn Forte 
130fcf3ce44SJohn Forte 		mdb_snprintf(buffer2, sizeof (buffer2),
131fcf3ce44SJohn Forte 		    "Is the %s driver loaded ?\n", DRIVER_NAME);
132fcf3ce44SJohn Forte 		mdb_warn(buffer2);
133fcf3ce44SJohn Forte 		return (DCMD_ERR);
134fcf3ce44SJohn Forte 	}
135fcf3ce44SJohn Forte 
136fcf3ce44SJohn Forte 	/* Get the device instance count */
137fcf3ce44SJohn Forte 	mdb_snprintf(buffer, sizeof (buffer), "%s_instance_count", DRIVER_NAME);
138fcf3ce44SJohn Forte 	if (mdb_readvar(&instance_count, buffer) == -1) {
139fcf3ce44SJohn Forte 		mdb_snprintf(buffer2, sizeof (buffer2), "%s not found.\n",
140fcf3ce44SJohn Forte 		    buffer);
141fcf3ce44SJohn Forte 		mdb_warn(buffer2);
142fcf3ce44SJohn Forte 
143fcf3ce44SJohn Forte 		mdb_snprintf(buffer2, sizeof (buffer2),
144fcf3ce44SJohn Forte 		    "Is the %s driver loaded ?\n", DRIVER_NAME);
145fcf3ce44SJohn Forte 		mdb_warn(buffer2);
146fcf3ce44SJohn Forte 		return (DCMD_ERR);
147fcf3ce44SJohn Forte 	}
148fcf3ce44SJohn Forte 
149fcf3ce44SJohn Forte 	ddiinst = (uint32_t)mdb_strtoull(argv[0].a_un.a_str);
150fcf3ce44SJohn Forte 
151fcf3ce44SJohn Forte 	for (brd_no = 0; brd_no < instance_count; brd_no++) {
152fcf3ce44SJohn Forte 		if (instance[brd_no] == ddiinst) {
153fcf3ce44SJohn Forte 			break;
154fcf3ce44SJohn Forte 		}
155fcf3ce44SJohn Forte 	}
156fcf3ce44SJohn Forte 
157fcf3ce44SJohn Forte 	if (brd_no == instance_count) {
158fcf3ce44SJohn Forte 		mdb_warn("Device instance not found. ddinst=%d\n", ddiinst);
159fcf3ce44SJohn Forte 		return (DCMD_ERR);
160fcf3ce44SJohn Forte 	}
161fcf3ce44SJohn Forte 
162fcf3ce44SJohn Forte 	/* Check if buffer is null */
163fcf3ce44SJohn Forte 	addr = (uintptr_t)device.log[brd_no];
164fcf3ce44SJohn Forte 	if (addr == 0) {
165fcf3ce44SJohn Forte 		mdb_warn("Device instance not found. ddinst=%d\n", ddiinst);
166fcf3ce44SJohn Forte 		return (0);
167fcf3ce44SJohn Forte 	}
168fcf3ce44SJohn Forte 
169fcf3ce44SJohn Forte 	if (mdb_vread(&log, sizeof (emlxs_msg_log_t), addr) !=
170fcf3ce44SJohn Forte 	    sizeof (emlxs_msg_log_t)) {
171fcf3ce44SJohn Forte 		mdb_warn("\nUnable to read %d bytes @ %llx.\n",
172fcf3ce44SJohn Forte 		    sizeof (emlxs_msg_log_t), addr);
173fcf3ce44SJohn Forte 		return (0);
174fcf3ce44SJohn Forte 	}
175fcf3ce44SJohn Forte 
176fcf3ce44SJohn Forte 	/* Check if buffer is empty */
177fcf3ce44SJohn Forte 	if (log.count == 0) {
178fcf3ce44SJohn Forte 		mdb_warn("Log buffer empty.\n");
179fcf3ce44SJohn Forte 		return (0);
180fcf3ce44SJohn Forte 	}
181fcf3ce44SJohn Forte 
182fcf3ce44SJohn Forte 	/* Get last entry id saved */
183fcf3ce44SJohn Forte 	last  = log.count - 1;
184fcf3ce44SJohn Forte 
185fcf3ce44SJohn Forte 	/* Check if buffer has already been filled once */
186fcf3ce44SJohn Forte 	if (log.count >= log.size) {
187fcf3ce44SJohn Forte 		first = log.count - log.size;
188fcf3ce44SJohn Forte 		idx = log.next;
189fcf3ce44SJohn Forte 	} else {
190fcf3ce44SJohn Forte 		/* Buffer not yet filled */
191fcf3ce44SJohn Forte 		first = 0;
192fcf3ce44SJohn Forte 		idx = 0;
193fcf3ce44SJohn Forte 	}
194fcf3ce44SJohn Forte 
195fcf3ce44SJohn Forte 	/* Get the total number of messages available for return */
196fcf3ce44SJohn Forte 	count = last - first + 1;
197fcf3ce44SJohn Forte 
198fcf3ce44SJohn Forte 	mdb_printf("\n");
199fcf3ce44SJohn Forte 
200fcf3ce44SJohn Forte 	/* Print the messages */
201fcf3ce44SJohn Forte 	for (i = 0; i < count; i++) {
202fcf3ce44SJohn Forte 		if (mdb_vread(&entry, sizeof (emlxs_msg_entry_t),
203fcf3ce44SJohn Forte 		    (uintptr_t)&log.entry[idx]) != sizeof (emlxs_msg_entry_t)) {
204fcf3ce44SJohn Forte 			mdb_warn("Cannot read log entry. index=%d count=%d\n",
205fcf3ce44SJohn Forte 			    idx, count);
206fcf3ce44SJohn Forte 			return (DCMD_ERR);
207fcf3ce44SJohn Forte 		}
208fcf3ce44SJohn Forte 
209fcf3ce44SJohn Forte 		if (mdb_vread(&msg, sizeof (emlxs_msg_t),
210fcf3ce44SJohn Forte 		    (uintptr_t)entry.msg) != sizeof (emlxs_msg_t)) {
211fcf3ce44SJohn Forte 			mdb_warn("Cannot read msg. index=%d count=%d\n",
212fcf3ce44SJohn Forte 			    idx, count);
213fcf3ce44SJohn Forte 			return (DCMD_ERR);
214fcf3ce44SJohn Forte 		}
215fcf3ce44SJohn Forte 
216fcf3ce44SJohn Forte 		switch (msg.level) {
217fcf3ce44SJohn Forte 		case EMLXS_DEBUG:
218fcf3ce44SJohn Forte 			level = "  DEBUG";
219fcf3ce44SJohn Forte 			break;
220fcf3ce44SJohn Forte 
221fcf3ce44SJohn Forte 		case EMLXS_NOTICE:
222fcf3ce44SJohn Forte 			level = " NOTICE";
223fcf3ce44SJohn Forte 			break;
224fcf3ce44SJohn Forte 
225fcf3ce44SJohn Forte 		case EMLXS_WARNING:
226fcf3ce44SJohn Forte 			level = "WARNING";
227fcf3ce44SJohn Forte 			break;
228fcf3ce44SJohn Forte 
229fcf3ce44SJohn Forte 		case EMLXS_ERROR:
230fcf3ce44SJohn Forte 			level = "  ERROR";
231fcf3ce44SJohn Forte 			break;
232fcf3ce44SJohn Forte 
233fcf3ce44SJohn Forte 		case EMLXS_PANIC:
234fcf3ce44SJohn Forte 			level = "  PANIC";
235fcf3ce44SJohn Forte 			break;
236fcf3ce44SJohn Forte 
237fcf3ce44SJohn Forte 		default:
238fcf3ce44SJohn Forte 			level = "UNKNOWN";
239fcf3ce44SJohn Forte 			break;
240fcf3ce44SJohn Forte 		}
241fcf3ce44SJohn Forte 
242fcf3ce44SJohn Forte 		if (entry.vpi == 0) {
243fcf3ce44SJohn Forte 			mdb_snprintf(driver, sizeof (driver), "%s%d",
244fcf3ce44SJohn Forte 			    DRIVER_NAME, entry.instance);
245fcf3ce44SJohn Forte 		} else {
246fcf3ce44SJohn Forte 			mdb_snprintf(driver, sizeof (driver), "%s%d.%d",
247fcf3ce44SJohn Forte 			    DRIVER_NAME, entry.instance, entry.vpi);
248fcf3ce44SJohn Forte 		}
249fcf3ce44SJohn Forte 
250fcf3ce44SJohn Forte 		/* Generate the message string */
251fcf3ce44SJohn Forte 		if (msg.buffer[0] != 0) {
252fcf3ce44SJohn Forte 			if (entry.buffer[0] != 0) {
25382527734SSukumar Swaminathan 				mdb_snprintf(merge, sizeof (merge),
25482527734SSukumar Swaminathan 				    "[%Y:%03d:%03d:%03d] "
255*8f23e9faSHans Rosenfeld 				    "%6d:[%1X.%04X]%s:%7s:%4d:\n%s\n(%s)\n",
25682527734SSukumar Swaminathan 				    entry.id_time.tv_sec,
25782527734SSukumar Swaminathan 				    (int)entry.id_time.tv_nsec/1000000,
25882527734SSukumar Swaminathan 				    (int)(entry.id_time.tv_nsec/1000)%1000,
25982527734SSukumar Swaminathan 				    (int)entry.id_time.tv_nsec%1000,
26082527734SSukumar Swaminathan 				    entry.id, entry.fileno,
261fcf3ce44SJohn Forte 				    entry.line, driver, level, msg.id,
262fcf3ce44SJohn Forte 				    msg.buffer, entry.buffer);
263fcf3ce44SJohn Forte 
264fcf3ce44SJohn Forte 			} else {
26582527734SSukumar Swaminathan 				mdb_snprintf(merge, sizeof (merge),
26682527734SSukumar Swaminathan 				    "[%Y:%03d:%03d:%03d] "
267*8f23e9faSHans Rosenfeld 				    "%6d:[%1X.%04X]%s:%7s:%4d:\n%s\n",
26882527734SSukumar Swaminathan 				    entry.id_time.tv_sec,
26982527734SSukumar Swaminathan 				    (int)entry.id_time.tv_nsec/1000000,
27082527734SSukumar Swaminathan 				    (int)(entry.id_time.tv_nsec/1000)%1000,
27182527734SSukumar Swaminathan 				    (int)entry.id_time.tv_nsec%1000,
27282527734SSukumar Swaminathan 				    entry.id, entry.fileno,
273fcf3ce44SJohn Forte 				    entry.line, driver, level, msg.id,
274fcf3ce44SJohn Forte 				    msg.buffer);
275fcf3ce44SJohn Forte 			}
276fcf3ce44SJohn Forte 		} else {
277fcf3ce44SJohn Forte 			if (entry.buffer[0] != 0) {
27882527734SSukumar Swaminathan 				mdb_snprintf(merge, sizeof (merge),
27982527734SSukumar Swaminathan 				    "[%Y:%03d:%03d:%03d] "
280fcf3ce44SJohn Forte 				    "%6d:[%1X.%04X]%s:%7s:%4d:\n(%s)\n",
28182527734SSukumar Swaminathan 				    entry.id_time.tv_sec,
28282527734SSukumar Swaminathan 				    (int)entry.id_time.tv_nsec/1000000,
28382527734SSukumar Swaminathan 				    (int)(entry.id_time.tv_nsec/1000)%1000,
28482527734SSukumar Swaminathan 				    (int)entry.id_time.tv_nsec%1000,
28582527734SSukumar Swaminathan 				    entry.id, entry.fileno,
286fcf3ce44SJohn Forte 				    entry.line, driver, level, msg.id,
287fcf3ce44SJohn Forte 				    entry.buffer);
28882527734SSukumar Swaminathan 
289fcf3ce44SJohn Forte 			} else {
29082527734SSukumar Swaminathan 				mdb_snprintf(merge, sizeof (merge),
29182527734SSukumar Swaminathan 				    "[%Y:%03d:%03d:%03d] "
292*8f23e9faSHans Rosenfeld 				    "%6d:[%1X.%04X]%s:%7s:%4d:\n%s\n",
29382527734SSukumar Swaminathan 				    entry.id_time.tv_sec,
29482527734SSukumar Swaminathan 				    (int)entry.id_time.tv_nsec/1000000,
29582527734SSukumar Swaminathan 				    (int)(entry.id_time.tv_nsec/1000)%1000,
29682527734SSukumar Swaminathan 				    (int)entry.id_time.tv_nsec%1000,
29782527734SSukumar Swaminathan 				    entry.id, entry.fileno,
29882527734SSukumar Swaminathan 				    entry.line, driver, level, msg.id,
29982527734SSukumar Swaminathan 				    msg.buffer);
300fcf3ce44SJohn Forte 			}
301fcf3ce44SJohn Forte 		}
302fcf3ce44SJohn Forte 
30382527734SSukumar Swaminathan 		mdb_printf("%s", merge);
304fcf3ce44SJohn Forte 
305fcf3ce44SJohn Forte 		/* Increment index */
306fcf3ce44SJohn Forte 		if (++idx >= log.size) {
307fcf3ce44SJohn Forte 			idx = 0;
308fcf3ce44SJohn Forte 		}
309fcf3ce44SJohn Forte 	}
310fcf3ce44SJohn Forte 
311fcf3ce44SJohn Forte 	mdb_printf("\n");
312fcf3ce44SJohn Forte 
313fcf3ce44SJohn Forte 	return (0);
314fcf3ce44SJohn Forte 
315fcf3ce44SJohn Forte } /* emlxs_msgbuf() */
316291a2b48SSukumar Swaminathan 
317291a2b48SSukumar Swaminathan 
318291a2b48SSukumar Swaminathan void
emlxs_dump_help()319291a2b48SSukumar Swaminathan emlxs_dump_help()
320291a2b48SSukumar Swaminathan {
321291a2b48SSukumar Swaminathan 	mdb_printf("Usage:   ::%s_dump all <instance(hex)>\n", DRIVER_NAME);
322291a2b48SSukumar Swaminathan 	mdb_printf("         ::%s_dump txt <instance(hex)>\n", DRIVER_NAME);
323291a2b48SSukumar Swaminathan 	mdb_printf("         ::%s_dump dmp <instance(hex)>\n", DRIVER_NAME);
324291a2b48SSukumar Swaminathan 	mdb_printf("         ::%s_dump cee <instance(hex)>\n", DRIVER_NAME);
325291a2b48SSukumar Swaminathan 	mdb_printf("\n");
326291a2b48SSukumar Swaminathan 	mdb_printf("                txt   Display firmware text summary " \
327291a2b48SSukumar Swaminathan 	    "file.\n");
328291a2b48SSukumar Swaminathan 	mdb_printf("                dmp   Display firmware dmp binary file.\n");
329291a2b48SSukumar Swaminathan 	mdb_printf("                cee   Display firmware cee binary file. " \
330291a2b48SSukumar Swaminathan 	    "(FCOE adapters only)\n");
331291a2b48SSukumar Swaminathan 	mdb_printf("                all   Display all firmware core files.\n");
332291a2b48SSukumar Swaminathan 	mdb_printf("         <instance>   This is the %s driver instance " \
333291a2b48SSukumar Swaminathan 	    "number in hex.\n", DRIVER_NAME);
334291a2b48SSukumar Swaminathan 	mdb_printf("                      (e.g. 0, 1,..., e, f, etc.)\n");
335291a2b48SSukumar Swaminathan 
336291a2b48SSukumar Swaminathan } /* emlxs_dump_help() */
337291a2b48SSukumar Swaminathan 
338291a2b48SSukumar Swaminathan 
339291a2b48SSukumar Swaminathan /*ARGSUSED*/
340291a2b48SSukumar Swaminathan int
emlxs_dump(uintptr_t base_addr,uint_t flags,int argc,const mdb_arg_t * argv)341291a2b48SSukumar Swaminathan emlxs_dump(uintptr_t base_addr, uint_t flags, int argc,
342291a2b48SSukumar Swaminathan 				const mdb_arg_t *argv)
343291a2b48SSukumar Swaminathan {
344291a2b48SSukumar Swaminathan 	uintptr_t  addr;
345291a2b48SSukumar Swaminathan 	emlxs_device_t device;
346291a2b48SSukumar Swaminathan 	uint32_t brd_no;
347291a2b48SSukumar Swaminathan 	uint32_t i;
348291a2b48SSukumar Swaminathan 	char buffer[256];
349291a2b48SSukumar Swaminathan 	char buffer2[256];
350291a2b48SSukumar Swaminathan 	int32_t instance[MAX_FC_BRDS];
351291a2b48SSukumar Swaminathan 	int32_t instance_count;
352291a2b48SSukumar Swaminathan 	uint32_t ddiinst;
353291a2b48SSukumar Swaminathan 	uint8_t *bptr;
354291a2b48SSukumar Swaminathan 	char *cptr;
355291a2b48SSukumar Swaminathan 	emlxs_file_t dump_txtfile;
356291a2b48SSukumar Swaminathan 	emlxs_file_t dump_dmpfile;
357291a2b48SSukumar Swaminathan 	emlxs_file_t dump_ceefile;
358291a2b48SSukumar Swaminathan 	uint32_t size;
359291a2b48SSukumar Swaminathan 	uint32_t file;
360291a2b48SSukumar Swaminathan 
361291a2b48SSukumar Swaminathan 	if (argc != 2) {
362291a2b48SSukumar Swaminathan 		goto usage;
363291a2b48SSukumar Swaminathan 	}
364291a2b48SSukumar Swaminathan 
365291a2b48SSukumar Swaminathan 	if ((strcmp(argv[0].a_un.a_str, "all") == 0) ||
366291a2b48SSukumar Swaminathan 	    (strcmp(argv[0].a_un.a_str, "ALL") == 0) ||
367291a2b48SSukumar Swaminathan 	    (strcmp(argv[0].a_un.a_str, "All") == 0)) {
368291a2b48SSukumar Swaminathan 		file = 0;
369291a2b48SSukumar Swaminathan 	} else if ((strcmp(argv[0].a_un.a_str, "txt") == 0) ||
370291a2b48SSukumar Swaminathan 	    (strcmp(argv[0].a_un.a_str, "TXT") == 0) ||
371291a2b48SSukumar Swaminathan 	    (strcmp(argv[0].a_un.a_str, "Txt") == 0)) {
372291a2b48SSukumar Swaminathan 		file = 1;
373291a2b48SSukumar Swaminathan 	} else if ((strcmp(argv[0].a_un.a_str, "dmp") == 0) ||
374291a2b48SSukumar Swaminathan 	    (strcmp(argv[0].a_un.a_str, "DMP") == 0) ||
375291a2b48SSukumar Swaminathan 	    (strcmp(argv[0].a_un.a_str, "Dmp") == 0)) {
376291a2b48SSukumar Swaminathan 		file = 2;
377291a2b48SSukumar Swaminathan 	} else if ((strcmp(argv[0].a_un.a_str, "cee") == 0) ||
378291a2b48SSukumar Swaminathan 	    (strcmp(argv[0].a_un.a_str, "CEE") == 0) ||
379291a2b48SSukumar Swaminathan 	    (strcmp(argv[0].a_un.a_str, "Cee") == 0)) {
380291a2b48SSukumar Swaminathan 		file = 3;
381291a2b48SSukumar Swaminathan 	} else {
382291a2b48SSukumar Swaminathan 		goto usage;
383291a2b48SSukumar Swaminathan 	}
384291a2b48SSukumar Swaminathan 
385291a2b48SSukumar Swaminathan 	/* Get the device address */
386291a2b48SSukumar Swaminathan 	mdb_snprintf(buffer, sizeof (buffer), "%s_device", DRIVER_NAME);
387291a2b48SSukumar Swaminathan 	if (mdb_readvar(&device, buffer) == -1) {
388291a2b48SSukumar Swaminathan 		mdb_snprintf(buffer2, sizeof (buffer2),
389291a2b48SSukumar Swaminathan 		    "%s not found.\n", buffer);
390291a2b48SSukumar Swaminathan 		mdb_warn(buffer2);
391291a2b48SSukumar Swaminathan 
392291a2b48SSukumar Swaminathan 		mdb_snprintf(buffer2, sizeof (buffer2),
393291a2b48SSukumar Swaminathan 		    "Is the %s driver loaded ?\n", DRIVER_NAME);
394291a2b48SSukumar Swaminathan 		mdb_warn(buffer2);
395291a2b48SSukumar Swaminathan 		return (DCMD_ERR);
396291a2b48SSukumar Swaminathan 	}
397291a2b48SSukumar Swaminathan 
398291a2b48SSukumar Swaminathan 	/* Get the device instance table */
399291a2b48SSukumar Swaminathan 	mdb_snprintf(buffer, sizeof (buffer), "%s_instance", DRIVER_NAME);
400291a2b48SSukumar Swaminathan 	if (mdb_readvar(&instance, buffer) == -1) {
401291a2b48SSukumar Swaminathan 		mdb_snprintf(buffer2, sizeof (buffer2), "%s not found.\n",
402291a2b48SSukumar Swaminathan 		    buffer);
403291a2b48SSukumar Swaminathan 		mdb_warn(buffer2);
404291a2b48SSukumar Swaminathan 
405291a2b48SSukumar Swaminathan 		mdb_snprintf(buffer2, sizeof (buffer2),
406291a2b48SSukumar Swaminathan 		    "Is the %s driver loaded ?\n", DRIVER_NAME);
407291a2b48SSukumar Swaminathan 		mdb_warn(buffer2);
408291a2b48SSukumar Swaminathan 		return (DCMD_ERR);
409291a2b48SSukumar Swaminathan 	}
410291a2b48SSukumar Swaminathan 
411291a2b48SSukumar Swaminathan 	/* Get the device instance count */
412291a2b48SSukumar Swaminathan 	mdb_snprintf(buffer, sizeof (buffer), "%s_instance_count", DRIVER_NAME);
413291a2b48SSukumar Swaminathan 	if (mdb_readvar(&instance_count, buffer) == -1) {
414291a2b48SSukumar Swaminathan 		mdb_snprintf(buffer2, sizeof (buffer2), "%s not found.\n",
415291a2b48SSukumar Swaminathan 		    buffer);
416291a2b48SSukumar Swaminathan 		mdb_warn(buffer2);
417291a2b48SSukumar Swaminathan 
418291a2b48SSukumar Swaminathan 		mdb_snprintf(buffer2, sizeof (buffer2),
419291a2b48SSukumar Swaminathan 		    "Is the %s driver loaded ?\n", DRIVER_NAME);
420291a2b48SSukumar Swaminathan 		mdb_warn(buffer2);
421291a2b48SSukumar Swaminathan 		return (DCMD_ERR);
422291a2b48SSukumar Swaminathan 	}
423291a2b48SSukumar Swaminathan 
424291a2b48SSukumar Swaminathan 	ddiinst = (uint32_t)mdb_strtoull(argv[1].a_un.a_str);
425291a2b48SSukumar Swaminathan 
426291a2b48SSukumar Swaminathan 	for (brd_no = 0; brd_no < instance_count; brd_no++) {
427291a2b48SSukumar Swaminathan 		if (instance[brd_no] == ddiinst) {
428291a2b48SSukumar Swaminathan 			break;
429291a2b48SSukumar Swaminathan 		}
430291a2b48SSukumar Swaminathan 	}
431291a2b48SSukumar Swaminathan 
432291a2b48SSukumar Swaminathan 	if (brd_no == instance_count) {
433291a2b48SSukumar Swaminathan 		mdb_warn("Device instance not found. ddinst=%d\n", ddiinst);
434291a2b48SSukumar Swaminathan 		return (DCMD_ERR);
435291a2b48SSukumar Swaminathan 	}
436291a2b48SSukumar Swaminathan 
437291a2b48SSukumar Swaminathan 	if (file == 0 || file == 1) {
438291a2b48SSukumar Swaminathan 
439291a2b48SSukumar Swaminathan 		addr = (uintptr_t)device.dump_txtfile[brd_no];
440291a2b48SSukumar Swaminathan 		if (addr == 0) {
441291a2b48SSukumar Swaminathan 			mdb_warn("TXT file: Device instance not found. " \
442291a2b48SSukumar Swaminathan 			    "ddinst=%d\n", ddiinst);
443291a2b48SSukumar Swaminathan 			goto dmp_file;
444291a2b48SSukumar Swaminathan 		}
445291a2b48SSukumar Swaminathan 
446291a2b48SSukumar Swaminathan 		if (mdb_vread(&dump_txtfile, sizeof (dump_txtfile), addr)
447291a2b48SSukumar Swaminathan 		    != sizeof (dump_txtfile)) {
448291a2b48SSukumar Swaminathan 			mdb_warn("TXT file: Unable to read %d bytes @ %llx.\n",
449291a2b48SSukumar Swaminathan 			    sizeof (dump_txtfile), addr);
450291a2b48SSukumar Swaminathan 			goto dmp_file;
451291a2b48SSukumar Swaminathan 		}
452291a2b48SSukumar Swaminathan 
453291a2b48SSukumar Swaminathan 		size = (uintptr_t)dump_txtfile.ptr -
454291a2b48SSukumar Swaminathan 		    (uintptr_t)dump_txtfile.buffer;
455291a2b48SSukumar Swaminathan 
456291a2b48SSukumar Swaminathan 		if (size == 0) {
457291a2b48SSukumar Swaminathan 			mdb_printf("TXT file: Not available.\n");
458291a2b48SSukumar Swaminathan 			goto dmp_file;
459291a2b48SSukumar Swaminathan 		}
460291a2b48SSukumar Swaminathan 		bptr  = (uint8_t *)mdb_zalloc(size, UM_SLEEP|UM_GC);
461291a2b48SSukumar Swaminathan 
462291a2b48SSukumar Swaminathan 		if (bptr == 0) {
463291a2b48SSukumar Swaminathan 			mdb_warn("TXT file: Unable to allocate file buffer. " \
464291a2b48SSukumar Swaminathan 			    "ddinst=%d size=%d\n", ddiinst, size);
465291a2b48SSukumar Swaminathan 			goto dmp_file;
466291a2b48SSukumar Swaminathan 		}
467291a2b48SSukumar Swaminathan 
468291a2b48SSukumar Swaminathan 		if (mdb_vread(bptr, size, (uintptr_t)dump_txtfile.buffer)
469291a2b48SSukumar Swaminathan 		    != size) {
470291a2b48SSukumar Swaminathan 			mdb_warn("TXT file: Unable to read %d bytes @ %llx.\n",
471291a2b48SSukumar Swaminathan 			    size, dump_txtfile.buffer);
472291a2b48SSukumar Swaminathan 			goto dmp_file;
473291a2b48SSukumar Swaminathan 		}
474291a2b48SSukumar Swaminathan 
475291a2b48SSukumar Swaminathan 		mdb_printf("<TXT File Start>\n");
476291a2b48SSukumar Swaminathan 		mdb_printf("\n");
477291a2b48SSukumar Swaminathan 		mdb_printf("%s", bptr);
478291a2b48SSukumar Swaminathan 		mdb_printf("\n");
479291a2b48SSukumar Swaminathan 		mdb_printf("<TXT File End>\n");
480291a2b48SSukumar Swaminathan 	}
481291a2b48SSukumar Swaminathan 
482291a2b48SSukumar Swaminathan dmp_file:
483291a2b48SSukumar Swaminathan 
484291a2b48SSukumar Swaminathan 	if (file == 0 || file == 2) {
485291a2b48SSukumar Swaminathan 		addr = (uintptr_t)device.dump_dmpfile[brd_no];
486291a2b48SSukumar Swaminathan 		if (addr == 0) {
487291a2b48SSukumar Swaminathan 			mdb_warn("DMP file: Device instance not found. " \
488291a2b48SSukumar Swaminathan 			    "ddinst=%d\n", ddiinst);
489291a2b48SSukumar Swaminathan 			goto cee_file;
490291a2b48SSukumar Swaminathan 		}
491291a2b48SSukumar Swaminathan 
492291a2b48SSukumar Swaminathan 		if (mdb_vread(&dump_dmpfile, sizeof (dump_dmpfile), addr)
493291a2b48SSukumar Swaminathan 		    != sizeof (dump_dmpfile)) {
494291a2b48SSukumar Swaminathan 			mdb_warn("DMP file: Unable to read %d bytes @ %llx.\n",
495291a2b48SSukumar Swaminathan 			    sizeof (dump_dmpfile), addr);
496291a2b48SSukumar Swaminathan 			goto cee_file;
497291a2b48SSukumar Swaminathan 		}
498291a2b48SSukumar Swaminathan 
499291a2b48SSukumar Swaminathan 		size = (uintptr_t)dump_dmpfile.ptr -
500291a2b48SSukumar Swaminathan 		    (uintptr_t)dump_dmpfile.buffer;
501291a2b48SSukumar Swaminathan 
502291a2b48SSukumar Swaminathan 		if (size == 0) {
503291a2b48SSukumar Swaminathan 			mdb_printf("DMP file: Not available.\n");
504291a2b48SSukumar Swaminathan 			goto cee_file;
505291a2b48SSukumar Swaminathan 		}
506291a2b48SSukumar Swaminathan 
507291a2b48SSukumar Swaminathan 		bptr  = (uint8_t *)mdb_zalloc(size, UM_SLEEP|UM_GC);
508291a2b48SSukumar Swaminathan 
509291a2b48SSukumar Swaminathan 		if (bptr == 0) {
510291a2b48SSukumar Swaminathan 			mdb_warn("DMP file: Unable to allocate file buffer. " \
511291a2b48SSukumar Swaminathan 			    "ddinst=%d size=%d\n", ddiinst, size);
512291a2b48SSukumar Swaminathan 			goto cee_file;
513291a2b48SSukumar Swaminathan 		}
514291a2b48SSukumar Swaminathan 
515291a2b48SSukumar Swaminathan 		if (mdb_vread(bptr, size, (uintptr_t)dump_dmpfile.buffer)
516291a2b48SSukumar Swaminathan 		    != size) {
517291a2b48SSukumar Swaminathan 			mdb_warn("DMP file: Unable to read %d bytes @ %llx.\n",
518291a2b48SSukumar Swaminathan 			    size, dump_dmpfile.buffer);
519291a2b48SSukumar Swaminathan 			goto cee_file;
520291a2b48SSukumar Swaminathan 		}
521291a2b48SSukumar Swaminathan 
522291a2b48SSukumar Swaminathan 		mdb_printf("<DMP File Start>\n");
523291a2b48SSukumar Swaminathan 		mdb_printf("\n");
524291a2b48SSukumar Swaminathan 
525291a2b48SSukumar Swaminathan 		bzero(buffer2, sizeof (buffer2));
526291a2b48SSukumar Swaminathan 		cptr = buffer2;
527291a2b48SSukumar Swaminathan 		for (i = 0; i < size; i++) {
528291a2b48SSukumar Swaminathan 			if (i && !(i % 16)) {
529291a2b48SSukumar Swaminathan 				mdb_printf(" %s\n", buffer2);
530291a2b48SSukumar Swaminathan 				bzero(buffer2, sizeof (buffer2));
531291a2b48SSukumar Swaminathan 				cptr = buffer2;
532291a2b48SSukumar Swaminathan 			}
533291a2b48SSukumar Swaminathan 
534291a2b48SSukumar Swaminathan 			if (!(i % 16)) {
535291a2b48SSukumar Swaminathan 				mdb_printf("%08X: ", i);
536291a2b48SSukumar Swaminathan 			}
537291a2b48SSukumar Swaminathan 
538291a2b48SSukumar Swaminathan 			if (!(i % 4)) {
539291a2b48SSukumar Swaminathan 				mdb_printf(" ");
540291a2b48SSukumar Swaminathan 			}
541291a2b48SSukumar Swaminathan 
542291a2b48SSukumar Swaminathan 			if ((*bptr >= 32) && (*bptr <= 126)) {
543291a2b48SSukumar Swaminathan 				*cptr++ = *bptr;
544291a2b48SSukumar Swaminathan 			} else {
545291a2b48SSukumar Swaminathan 				*cptr++ = '.';
546291a2b48SSukumar Swaminathan 			}
547291a2b48SSukumar Swaminathan 
548291a2b48SSukumar Swaminathan 			mdb_printf("%02X ", *bptr++);
549291a2b48SSukumar Swaminathan 		}
550291a2b48SSukumar Swaminathan 
551291a2b48SSukumar Swaminathan 		size = 16 - (i % 16);
552291a2b48SSukumar Swaminathan 		for (i = 0; size < 16 && i < size; i++) {
553291a2b48SSukumar Swaminathan 			if (!(i % 4)) {
554291a2b48SSukumar Swaminathan 				mdb_printf(" ");
555291a2b48SSukumar Swaminathan 			}
556291a2b48SSukumar Swaminathan 
557291a2b48SSukumar Swaminathan 			mdb_printf("   ");
558291a2b48SSukumar Swaminathan 		}
559291a2b48SSukumar Swaminathan 		mdb_printf(" %s\n", buffer2);
560291a2b48SSukumar Swaminathan 		mdb_printf("\n");
561291a2b48SSukumar Swaminathan 		mdb_printf("<DMP File End>\n");
562291a2b48SSukumar Swaminathan 	}
563291a2b48SSukumar Swaminathan 
564291a2b48SSukumar Swaminathan cee_file:
565291a2b48SSukumar Swaminathan 
566291a2b48SSukumar Swaminathan 	if (file == 0 || file == 3) {
567291a2b48SSukumar Swaminathan 
568291a2b48SSukumar Swaminathan 		addr = (uintptr_t)device.dump_ceefile[brd_no];
569291a2b48SSukumar Swaminathan 		if (addr == 0) {
570291a2b48SSukumar Swaminathan 			mdb_warn("CEE file: Device instance not found. " \
571291a2b48SSukumar Swaminathan 			    "ddinst=%d\n", ddiinst);
572291a2b48SSukumar Swaminathan 			goto done;
573291a2b48SSukumar Swaminathan 		}
574291a2b48SSukumar Swaminathan 
575291a2b48SSukumar Swaminathan 		if (mdb_vread(&dump_ceefile, sizeof (dump_ceefile), addr)
576291a2b48SSukumar Swaminathan 		    != sizeof (dump_ceefile)) {
577291a2b48SSukumar Swaminathan 			mdb_warn("CEE file: Unable to read %d bytes @ %llx.\n",
578291a2b48SSukumar Swaminathan 			    sizeof (dump_ceefile), addr);
579291a2b48SSukumar Swaminathan 			goto done;
580291a2b48SSukumar Swaminathan 		}
581291a2b48SSukumar Swaminathan 
582291a2b48SSukumar Swaminathan 		size = (uintptr_t)dump_ceefile.ptr -
583291a2b48SSukumar Swaminathan 		    (uintptr_t)dump_ceefile.buffer;
584291a2b48SSukumar Swaminathan 
585291a2b48SSukumar Swaminathan 		if (size == 0) {
586291a2b48SSukumar Swaminathan 			mdb_printf("CEE file: Not available.\n");
587291a2b48SSukumar Swaminathan 			goto done;
588291a2b48SSukumar Swaminathan 		}
589291a2b48SSukumar Swaminathan 
590291a2b48SSukumar Swaminathan 		bptr  = (uint8_t *)mdb_zalloc(size, UM_SLEEP|UM_GC);
591291a2b48SSukumar Swaminathan 
592291a2b48SSukumar Swaminathan 		if (bptr == 0) {
593291a2b48SSukumar Swaminathan 			mdb_warn("CEE file: Unable to allocate file buffer. " \
594291a2b48SSukumar Swaminathan 			    "ddinst=%d size=%d\n", ddiinst, size);
595291a2b48SSukumar Swaminathan 			goto done;
596291a2b48SSukumar Swaminathan 		}
597291a2b48SSukumar Swaminathan 
598291a2b48SSukumar Swaminathan 		if (mdb_vread(bptr, size, (uintptr_t)dump_ceefile.buffer)
599291a2b48SSukumar Swaminathan 		    != size) {
600291a2b48SSukumar Swaminathan 			mdb_warn("CEE file: Unable to read %d bytes @ %llx.\n",
601291a2b48SSukumar Swaminathan 			    size, dump_ceefile.buffer);
602291a2b48SSukumar Swaminathan 			goto done;
603291a2b48SSukumar Swaminathan 		}
604291a2b48SSukumar Swaminathan 
605291a2b48SSukumar Swaminathan 		mdb_printf("<CEE File Start>\n");
606291a2b48SSukumar Swaminathan 		mdb_printf("\n");
607291a2b48SSukumar Swaminathan 
608291a2b48SSukumar Swaminathan 		bzero(buffer2, sizeof (buffer2));
609291a2b48SSukumar Swaminathan 		cptr = buffer2;
610291a2b48SSukumar Swaminathan 		for (i = 0; i < size; i++) {
611291a2b48SSukumar Swaminathan 			if (i && !(i % 16)) {
612291a2b48SSukumar Swaminathan 				mdb_printf(" %s\n", buffer2);
613291a2b48SSukumar Swaminathan 				bzero(buffer2, sizeof (buffer2));
614291a2b48SSukumar Swaminathan 				cptr = buffer2;
615291a2b48SSukumar Swaminathan 			}
616291a2b48SSukumar Swaminathan 
617291a2b48SSukumar Swaminathan 			if (!(i % 16)) {
618291a2b48SSukumar Swaminathan 				mdb_printf("%08X: ", i);
619291a2b48SSukumar Swaminathan 			}
620291a2b48SSukumar Swaminathan 
621291a2b48SSukumar Swaminathan 			if (!(i % 4)) {
622291a2b48SSukumar Swaminathan 				mdb_printf(" ");
623291a2b48SSukumar Swaminathan 			}
624291a2b48SSukumar Swaminathan 
625291a2b48SSukumar Swaminathan 			if ((*bptr >= 32) && (*bptr <= 126)) {
626291a2b48SSukumar Swaminathan 				*cptr++ = *bptr;
627291a2b48SSukumar Swaminathan 			} else {
628291a2b48SSukumar Swaminathan 				*cptr++ = '.';
629291a2b48SSukumar Swaminathan 			}
630291a2b48SSukumar Swaminathan 
631291a2b48SSukumar Swaminathan 			mdb_printf("%02X ", *bptr++);
632291a2b48SSukumar Swaminathan 		}
633291a2b48SSukumar Swaminathan 
634291a2b48SSukumar Swaminathan 		size = 16 - (i % 16);
635291a2b48SSukumar Swaminathan 		for (i = 0; size < 16 && i < size; i++) {
636291a2b48SSukumar Swaminathan 			if (!(i % 4)) {
637291a2b48SSukumar Swaminathan 				mdb_printf(" ");
638291a2b48SSukumar Swaminathan 			}
639291a2b48SSukumar Swaminathan 
640291a2b48SSukumar Swaminathan 			mdb_printf("   ");
641291a2b48SSukumar Swaminathan 		}
642291a2b48SSukumar Swaminathan 		mdb_printf(" %s\n", buffer2);
643291a2b48SSukumar Swaminathan 		mdb_printf("\n");
644291a2b48SSukumar Swaminathan 		mdb_printf("<CEE File End>\n");
645291a2b48SSukumar Swaminathan 	}
646291a2b48SSukumar Swaminathan done:
647291a2b48SSukumar Swaminathan 
648291a2b48SSukumar Swaminathan 	mdb_printf("\n");
649291a2b48SSukumar Swaminathan 	return (0);
650291a2b48SSukumar Swaminathan 
651291a2b48SSukumar Swaminathan usage:
652291a2b48SSukumar Swaminathan 	mdb_printf("Usage:   ::%s_dump <file> <instance (hex)>\n",
653291a2b48SSukumar Swaminathan 	    DRIVER_NAME);
654291a2b48SSukumar Swaminathan 	mdb_printf("mdb: try \"::help %s_dump\" for more information",
655291a2b48SSukumar Swaminathan 	    DRIVER_NAME);
656291a2b48SSukumar Swaminathan 
657291a2b48SSukumar Swaminathan 	return (DCMD_ERR);
658291a2b48SSukumar Swaminathan 
659291a2b48SSukumar Swaminathan } /* emlxs_dump() */
660