xref: /illumos-gate/usr/src/cmd/mdb/common/modules/emlxs/emlxs.c (revision 6e375c8351497b82ffa4f33cbf61d712999b4605)
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 2008 Emulex.  All rights reserved.
24  * Use is subject to License terms.
25  */
26 
27 #include "emlxs_mdb.h"
28 #include "emlxs_msg.h"
29 #include "emlxs_device.h"
30 
31 /*
32  * MDB module linkage information:
33  */
34 
35 static const mdb_dcmd_t dcmds[] =
36 {
37 	{ "emlxs_msgbuf", "<instance>",
38 	"dumps the emlxs driver internal message buffer",
39 	emlxs_msgbuf, emlxs_msgbuf_help},
40 	{ NULL }
41 };
42 
43 static const mdb_modinfo_t modinfo =
44 {
45 	MDB_API_VERSION,
46 	dcmds,
47 	NULL
48 };
49 
50 const mdb_modinfo_t *
51 _mdb_init(void)
52 {
53 	return (&modinfo);
54 }
55 
56 
57 /*
58  * emlxs_msgbuf library
59  */
60 void
61 emlxs_msgbuf_help()
62 {
63 
64 	mdb_printf("Usage:   ::%s_msgbuf <instance (in hex)>\n\n", DRIVER_NAME);
65 	mdb_printf(
66 	"         <instance>  This is the %s driver instance number in hex.\n",
67 	    DRIVER_NAME);
68 	mdb_printf("                      (e.g. 0, 1,..., e, f, etc.)\n");
69 
70 } /* emlxs_msgbuf_help() */
71 
72 
73 /*ARGSUSED*/
74 int emlxs_msgbuf(uintptr_t base_addr, uint_t flags, int argc,
75 				const mdb_arg_t *argv)
76 {
77 	uintptr_t  addr;
78 	emlxs_device_t device;
79 	uint32_t brd_no;
80 	emlxs_msg_log_t log;
81 	uint32_t count;
82 	uint32_t first;
83 	uint32_t last;
84 	uint32_t idx;
85 	uint32_t i;
86 	char *level;
87 	emlxs_msg_t msg;
88 	uint32_t secs;
89 	uint32_t hsecs;
90 	emlxs_msg_entry_t entry;
91 	char buffer[256];
92 	char buffer2[256];
93 	int32_t instance[MAX_FC_BRDS];
94 	char driver[32];
95 	int32_t instance_count;
96 	uint32_t ddiinst;
97 
98 
99 	if (argc != 1) {
100 		mdb_printf("Usage:   ::%s_msgbuf  <instance (in hex)>\n",
101 		    DRIVER_NAME);
102 		mdb_printf("mdb: try \"::help %s_msgbuf\" for more information",
103 		    DRIVER_NAME);
104 
105 		return (DCMD_ERR);
106 	}
107 
108 	/* Get the device address */
109 	mdb_snprintf(buffer, sizeof (buffer), "%s_device", DRIVER_NAME);
110 	if (mdb_readvar(&device, buffer) == -1) {
111 		mdb_snprintf(buffer2, sizeof (buffer2),
112 		    "%s not found.\n", buffer);
113 		mdb_warn(buffer2);
114 
115 		mdb_snprintf(buffer2, sizeof (buffer2),
116 		    "Is the %s driver loaded ?\n", DRIVER_NAME);
117 		mdb_warn(buffer2);
118 		return (DCMD_ERR);
119 	}
120 
121 	/* Get the device instance table */
122 	mdb_snprintf(buffer, sizeof (buffer), "%s_instance", DRIVER_NAME);
123 	if (mdb_readvar(&instance, buffer) == -1) {
124 		mdb_snprintf(buffer2, sizeof (buffer2), "%s not found.\n",
125 		    buffer);
126 		mdb_warn(buffer2);
127 
128 		mdb_snprintf(buffer2, sizeof (buffer2),
129 		    "Is the %s driver loaded ?\n", DRIVER_NAME);
130 		mdb_warn(buffer2);
131 		return (DCMD_ERR);
132 	}
133 
134 	/* Get the device instance count */
135 	mdb_snprintf(buffer, sizeof (buffer), "%s_instance_count", DRIVER_NAME);
136 	if (mdb_readvar(&instance_count, buffer) == -1) {
137 		mdb_snprintf(buffer2, sizeof (buffer2), "%s not found.\n",
138 		    buffer);
139 		mdb_warn(buffer2);
140 
141 		mdb_snprintf(buffer2, sizeof (buffer2),
142 		    "Is the %s driver loaded ?\n", DRIVER_NAME);
143 		mdb_warn(buffer2);
144 		return (DCMD_ERR);
145 	}
146 
147 	ddiinst = (uint32_t)mdb_strtoull(argv[0].a_un.a_str);
148 
149 	for (brd_no = 0; brd_no < instance_count; brd_no++) {
150 		if (instance[brd_no] == ddiinst) {
151 			break;
152 		}
153 	}
154 
155 	if (brd_no == instance_count) {
156 		mdb_warn("Device instance not found. ddinst=%d\n", ddiinst);
157 		return (DCMD_ERR);
158 	}
159 
160 	/* Check if buffer is null */
161 	addr = (uintptr_t)device.log[brd_no];
162 	if (addr == 0) {
163 		mdb_warn("Device instance not found. ddinst=%d\n", ddiinst);
164 		return (0);
165 	}
166 
167 	if (mdb_vread(&log, sizeof (emlxs_msg_log_t), addr) !=
168 	    sizeof (emlxs_msg_log_t)) {
169 		mdb_warn("\nUnable to read %d bytes @ %llx.\n",
170 		    sizeof (emlxs_msg_log_t), addr);
171 		return (0);
172 	}
173 
174 	/* Check if buffer is empty */
175 	if (log.count == 0) {
176 		mdb_warn("Log buffer empty.\n");
177 		return (0);
178 	}
179 
180 	/* Get last entry id saved */
181 	last  = log.count - 1;
182 
183 	/* Check if buffer has already been filled once */
184 	if (log.count >= log.size) {
185 		first = log.count - log.size;
186 		idx = log.next;
187 	} else {
188 		/* Buffer not yet filled */
189 		first = 0;
190 		idx = 0;
191 	}
192 
193 	/* Get the total number of messages available for return */
194 	count = last - first + 1;
195 
196 	mdb_printf("\n");
197 
198 	/* Print the messages */
199 	for (i = 0; i < count; i++) {
200 		if (mdb_vread(&entry, sizeof (emlxs_msg_entry_t),
201 		    (uintptr_t)&log.entry[idx]) != sizeof (emlxs_msg_entry_t)) {
202 			mdb_warn("Cannot read log entry. index=%d count=%d\n",
203 			    idx, count);
204 			return (DCMD_ERR);
205 		}
206 
207 		if (mdb_vread(&msg, sizeof (emlxs_msg_t),
208 		    (uintptr_t)entry.msg) != sizeof (emlxs_msg_t)) {
209 			mdb_warn("Cannot read msg. index=%d count=%d\n",
210 			    idx, count);
211 			return (DCMD_ERR);
212 		}
213 
214 		hsecs = (entry.time%100);
215 		secs  = entry.time/100;
216 
217 		switch (msg.level) {
218 		case EMLXS_DEBUG:
219 			level = "  DEBUG";
220 			break;
221 
222 		case EMLXS_NOTICE:
223 			level = " NOTICE";
224 			break;
225 
226 		case EMLXS_WARNING:
227 			level = "WARNING";
228 			break;
229 
230 		case EMLXS_ERROR:
231 			level = "  ERROR";
232 			break;
233 
234 		case EMLXS_PANIC:
235 			level = "  PANIC";
236 			break;
237 
238 		case EMLXS_EVENT:
239 			level = "  EVENT";
240 			break;
241 
242 		default:
243 			level = "UNKNOWN";
244 			break;
245 		}
246 
247 		if (entry.vpi == 0) {
248 			mdb_snprintf(driver, sizeof (driver), "%s%d",
249 			    DRIVER_NAME, entry.instance);
250 		} else {
251 			mdb_snprintf(driver, sizeof (driver), "%s%d.%d",
252 			    DRIVER_NAME, entry.instance, entry.vpi);
253 		}
254 
255 		/* Generate the message string */
256 		if (msg.buffer[0] != 0) {
257 			if (entry.buffer[0] != 0) {
258 				mdb_snprintf(buffer, sizeof (buffer),
259 				    "%8d.%02d: "
260 				    "%6d:[%1X.%04X]%s:%7s:%4d: %s\n(%s)\n",
261 				    secs, hsecs, entry.id, entry.fileno,
262 				    entry.line, driver, level, msg.id,
263 				    msg.buffer, entry.buffer);
264 
265 			} else {
266 				mdb_snprintf(buffer, sizeof (buffer),
267 				    "%8d.%02d: %6d:[%1X.%04X]%s:%7s:%4d: %s\n",
268 				    secs, hsecs, entry.id, entry.fileno,
269 				    entry.line, driver, level, msg.id,
270 				    msg.buffer);
271 			}
272 		} else {
273 			if (entry.buffer[0] != 0) {
274 				mdb_snprintf(buffer, sizeof (buffer),
275 				    "%8d.%02d: "
276 				    "%6d:[%1X.%04X]%s:%7s:%4d:\n(%s)\n",
277 				    secs, hsecs, entry.id, entry.fileno,
278 				    entry.line, driver, level, msg.id,
279 				    entry.buffer);
280 			} else {
281 				mdb_snprintf(buffer, sizeof (buffer),
282 				    "%8d.%02d: %6d:[%1X.%04X]%s:%7s:%4d:\n",
283 				    secs, hsecs, entry.id, entry.fileno,
284 				    entry.line, driver, level, msg.id);
285 			}
286 		}
287 
288 		mdb_printf("%s", buffer);
289 
290 		/* Increment index */
291 		if (++idx >= log.size) {
292 			idx = 0;
293 		}
294 	}
295 
296 	mdb_printf("\n");
297 
298 	return (0);
299 
300 } /* emlxs_msgbuf() */
301