xref: /titanic_52/usr/src/cmd/mdb/common/modules/qlc/qlc.c (revision 5705cefc5ef4cb218637b543df189a91959c6aa9)
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 /* Copyright 2009 QLogic Corporation */
23 
24 /*
25  * ISP2xxx Solaris Fibre Channel Adapter (FCA) qlc mdb source file.
26  *
27  * ***********************************************************************
28  * *									**
29  * *				NOTICE					**
30  * *		COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION		**
31  * *			ALL RIGHTS RESERVED				**
32  * *									**
33  * ***********************************************************************
34  *
35  */
36 
37 #pragma ident	"Copyright 2009 QLogic Corporation; ql_mdb.c"
38 
39 #include <sys/mdb_modapi.h>
40 #include <ql_apps.h>
41 #include <ql_api.h>
42 #include <ql_init.h>
43 #include <ql_debug.h>
44 
45 /*
46  * local prototypes
47  */
48 static int32_t ql_doprint(uintptr_t, int8_t *);
49 static void ql_dump_flags(uint64_t, int8_t **);
50 static int qlclinks_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
51 static int qlcstate_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
52 static int qlc_osc_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
53 static int qlc_wdog_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
54 static int qlc_getdump_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
55 static int qlc_gettrace_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
56 #if 0
57 static int qlc_triggerdump_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
58 #endif
59 static int qlcver_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *);
60 static int qlstates_walk_init(mdb_walk_state_t *);
61 static int qlstates_walk_step(mdb_walk_state_t *);
62 static void qlstates_walk_fini(mdb_walk_state_t *);
63 static int qlsrb_walk_init(mdb_walk_state_t *);
64 static int qlsrb_walk_step(mdb_walk_state_t *);
65 static void qlsrb_walk_fini(mdb_walk_state_t *);
66 static int get_next_link(ql_link_t *);
67 static int get_first_link(ql_head_t *, ql_link_t *);
68 
69 static int ql_24xx_dump_dcmd(ql_adapter_state_t *, uint_t, int,
70     const mdb_arg_t *);
71 static int ql_23xx_dump_dcmd(ql_adapter_state_t *, uint_t, int,
72     const mdb_arg_t *);
73 static int ql_25xx_dump_dcmd(ql_adapter_state_t *, uint_t, int,
74     const mdb_arg_t *);
75 static void ql_elog_common(ql_adapter_state_t *, boolean_t);
76 
77 /*
78  * local adapter state flags strings
79  */
80 int8_t *adapter_state_flags[] = {
81 	"FCA_BOUND",
82 	"QL_OPENED",
83 	"ONLINE",
84 	"INTERRUPTS_ENABLED",
85 	"ABORT_CMDS_LOOP_DOWN_TMO",
86 	"POINT_TO_POINT",
87 	"IP_ENABLED",
88 	"IP_INITIALIZED",
89 	"TARGET_MODE_INITIALIZED",
90 	"ADAPTER_SUSPENDED",
91 	"ADAPTER_TIMER_BUSY",
92 	"PARITY_ERROR",
93 	"FLASH_ERRLOG_MARKER",
94 	"VP_ENABLED",
95 	"FDISC_ENABLED",
96 	"MENLO_LOGIN_OPERATIONAL",
97 	NULL
98 };
99 
100 int8_t *adapter_config_flags[] = {
101 	"ENABLE_HARD_ADDRESS",
102 	"ENABLE_64BIT_ADDRESSING",
103 	"ENABLE_LIP_RESET",
104 	"ENABLE_FULL_LIP_LOGIN",
105 	"ENABLE_TARGET_RESET",
106 	"ENABLE_LINK_DOWN_REPORTING",
107 	"ENABLE_TARGET_MODE",
108 	"ENABLE_FCP_2_SUPPORT",
109 	"MULTI_CHIP_ADAPTER",
110 	"SBUS_CARD",
111 	"CTRL_2300",
112 	"CTRL_6322",
113 	"CTRL_2200",
114 	"CTRL_2422",
115 	"CTRL_25XX",
116 	"ENABLE_EXTENDED_LOGGING",
117 	"DISABLE_RISC_CODE_LOAD",
118 	"SET_CACHE_LINE_SIZE_1",
119 	"TARGET_MODE_ENABLE",
120 	"EXT_FW_INTERFACE",
121 	"LOAD_FLASH_FW",
122 	"DUMP_MAILBOX_TIMEOUT",
123 	"DUMP_ISP_SYSTEM_ERROR",
124 	"DUMP_DRIVER_COMMAND_TIMEOUT",
125 	"DUMP_LOOP_OFFLINE_TIMEOUT",
126 	"ENABLE_FWEXTTRACE",
127 	"ENABLE_FWFCETRACE",
128 	"FW_MISMATCH",
129 	"CTRL_MENLO",
130 	"DISABLE_EXTENDED_LOGGING_TRACE",
131 	NULL
132 };
133 
134 /*
135  * local task daemon flags strings
136  */
137 int8_t *task_daemon_flags[] = {
138 	"TASK_DAEMON_STOP_FLG",
139 	"TASK_DAEMON_SLEEPING_FLG",
140 	"TASK_DAEMON_ALIVE_FLG",
141 	"TASK_DAEMON_IDLE_CHK_FLG",
142 	"SUSPENDED_WAKEUP_FLG",
143 	"FC_STATE_CHANGE",
144 	"NEED_UNSOLICITED_BUFFERS",
145 	"RESET_MARKER_NEEDED",
146 	"RESET_ACTIVE",
147 	"ISP_ABORT_NEEDED",
148 	"ABORT_ISP_ACTIVE",
149 	"LOOP_RESYNC_NEEDED",
150 	"LOOP_RESYNC_ACTIVE",
151 	"LOOP_DOWN",
152 	"DRIVER_STALL",
153 	"COMMAND_WAIT_NEEDED",
154 	"COMMAND_WAIT_ACTIVE",
155 	"STATE_ONLINE",
156 	"ABORT_QUEUES_NEEDED",
157 	"TASK_DAEMON_STALLED_FLG",
158 	"TASK_THREAD_CALLED",
159 	"FIRMWARE_UP",
160 	"LIP_RESET_PENDING",
161 	"FIRMWARE_LOADED",
162 	"RSCN_UPDATE_NEEDED",
163 	"HANDLE_PORT_BYPASS_CHANGE",
164 	"PORT_RETRY_NEEDED",
165 	"TASK_DAEMON_POWERING_DOWN",
166 	"TD_IIDMA_NEEDED",
167 	NULL
168 };
169 
170 /*
171  * local interrupt aif flags
172  */
173 int8_t *aif_flags[] = {
174 	"IFLG_INTR_LEGACY",
175 	"IFLG_INTR_MSI",
176 	"IFLG_INTR_FIXED",
177 	NULL
178 };
179 
180 int8_t *qlsrb_flags[] = {
181 	"SRB_ISP_STARTED",
182 	"SRB_ISP_COMPLETED",
183 	"SRB_RETRY",
184 	"SRB_POLL",
185 	"SRB_WATCHDOG_ENABLED",
186 	"SRB_ABORT",
187 	"SRB_UB_IN_FCA",
188 	"SRB_UB_IN_ISP",
189 	"SRB_UB_CALLBACK",
190 	"SRB_UB_RSCN",
191 	"SRB_UB_FCP",
192 	"SRB_FCP_CMD_PKT",
193 	"SRB_FCP_DATA_PKT",
194 	"SRB_FCP_RSP_PKT",
195 	"SRB_IP_PKT",
196 	"SRB_GENERIC_SERVICES_PKT",
197 	"SRB_COMMAND_TIMEOUT",
198 	"SRB_ABORTING",
199 	"SRB_IN_DEVICE_QUEUE",
200 	"SRB_IN_TOKEN_ARRAY",
201 	"SRB_UB_FREE_REQUESTED",
202 	"SRB_UB_ACQUIRED",
203 	"SRB_MS_PKT",
204 	NULL
205 };
206 
207 int8_t *qllun_flags[] = {
208 	"LQF_UNTAGGED_PENDING",
209 	NULL
210 };
211 
212 
213 int8_t *qltgt_flags[] = {
214 	"TQF_TAPE_DEVICE",
215 	"TQF_QUEUE_SUSPENDED",
216 	"TQF_FABRIC_DEVICE",
217 	"TQF_INITIATOR_DEVICE",
218 	"TQF_RSCN_RCVD",
219 	"TQF_NEED_AUTHENTICATION",
220 	"TQF_PLOGI_PROGRS",
221 	"TQF_IIDMA_NEEDED",
222 	NULL
223 };
224 
225 int8_t *qldump_flags[] = {
226 	"QL_DUMPING",
227 	"QL_DUMP_VALID",
228 	"QL_DUMP_UPLOADED",
229 	NULL
230 };
231 
232 /*
233  * qlclinks_dcmd
234  *	mdb dcmd which prints out the ql_hba pointers
235  *
236  * Input:
237  *	addr  = User supplied address -- error if supplied.
238  *	flags = mdb flags.
239  *	argc  = Number of user supplied args -- error if non-zero.
240  *	argv  = Arg array.
241  *
242  * Returns:
243  *	DCMD_ERR, DCMD_USAGE, or DCMD_OK
244  *
245  * Context:
246  *	User context.
247  *
248  */
249 /*ARGSUSED*/
250 static int
251 qlclinks_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
252 {
253 	ql_head_t		ql_hba;
254 	ql_adapter_state_t	*qlstate;
255 	uintptr_t		hbaptr = NULL;
256 
257 	if ((flags & DCMD_ADDRSPEC) || argc != 0) {
258 		return (DCMD_USAGE);
259 	}
260 
261 	if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
262 		mdb_warn("failed to read ql_hba structure");
263 		return (DCMD_ERR);
264 	}
265 
266 	if (&ql_hba == NULL) {
267 		mdb_warn("failed to read ql_hba structure -- is qlc loaded?");
268 		return (DCMD_ERR);
269 	}
270 
271 	mdb_printf("\nqlc adapter state linkages (f=0x%llx, l=0x%llx)\n\n",
272 	    ql_hba.first, ql_hba.last);
273 
274 	if ((qlstate = (ql_adapter_state_t *)mdb_alloc(
275 	    sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
276 		mdb_warn("Unable to allocate memory for ql_adapter_state\n");
277 		return (DCMD_OK);
278 	}
279 
280 	(void) mdb_inc_indent((ulong_t)4);
281 	mdb_printf("%<u>%-?s\t%-45s%</u>\n\n", "baseaddr", "instance");
282 
283 	hbaptr = (uintptr_t)ql_hba.first;
284 	while (hbaptr != NULL) {
285 
286 		if (mdb_vread(qlstate, sizeof (ql_adapter_state_t),
287 		    hbaptr) == -1) {
288 			mdb_free(qlstate, sizeof (ql_adapter_state_t));
289 			mdb_warn("failed to read ql_adapter_state at %p",
290 			    hbaptr);
291 			return (DCMD_OK);
292 		}
293 
294 		mdb_printf("%<b>0x%016p%t%d%</b>\n",
295 		    qlstate->hba.base_address, qlstate->instance);
296 
297 		/*
298 		 * If vp exists, loop through those
299 		 */
300 
301 		if ((qlstate->flags & VP_ENABLED) &&
302 		    (qlstate->vp_next != NULL)) {
303 
304 			ql_adapter_state_t	*vqlstate;
305 			uintptr_t		vhbaptr = NULL;
306 
307 			vhbaptr = (uintptr_t)qlstate->vp_next;
308 
309 			if ((vqlstate = (ql_adapter_state_t *)mdb_alloc(
310 			    sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
311 				mdb_warn("Unable to allocate memory for "
312 				    "ql_adapter_state vp\n");
313 				mdb_free(qlstate, sizeof (ql_adapter_state_t));
314 				return (DCMD_OK);
315 			}
316 
317 			(void) mdb_inc_indent((ulong_t)30);
318 
319 			mdb_printf("%<u>vp baseaddr\t\tvp index%</u>\n");
320 
321 			while (vhbaptr != NULL) {
322 
323 				if (mdb_vread(vqlstate,
324 				    sizeof (ql_adapter_state_t), vhbaptr) ==
325 				    -1) {
326 					mdb_free(vqlstate,
327 					    sizeof (ql_adapter_state_t));
328 					mdb_free(qlstate,
329 					    sizeof (ql_adapter_state_t));
330 					mdb_warn("failed to read vp "
331 					    "ql_adapter_state at %p", vhbaptr);
332 					return (DCMD_OK);
333 				}
334 
335 				mdb_printf("%<b>0x%016p%t%d%</b>\n",
336 				    vqlstate->hba.base_address,
337 				    vqlstate->vp_index);
338 
339 				vhbaptr = (uintptr_t)vqlstate->vp_next;
340 			}
341 
342 			mdb_free(vqlstate, sizeof (ql_adapter_state_t));
343 
344 			(void) mdb_dec_indent((ulong_t)30);
345 
346 			mdb_printf("\n");
347 		}
348 
349 		hbaptr = (uintptr_t)qlstate->hba.next;
350 	}
351 
352 	(void) mdb_dec_indent((ulong_t)4);
353 
354 	mdb_free(qlstate, sizeof (ql_adapter_state_t));
355 
356 	return (DCMD_OK);
357 }
358 
359 /*
360  * qlcver_dcmd
361  *	mdb dcmd which prints out the qlc driver version the mdb
362  *	module was compiled with, and the verison of qlc which is
363  *	currently loaded on the machine.
364  *
365  * Input:
366  *	addr  = User supplied address -- error if supplied.
367  *	flags = mdb flags.
368  *	argc  = Number of user supplied args -- error if non-zero.
369  *	argv  = Arg array.
370  *
371  * Returns:
372  *	DCMD_USAGE, or DCMD_OK
373  *
374  * Context:
375  *	User context.
376  *
377  */
378 /*ARGSUSED*/
379 static int
380 qlcver_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
381 {
382 	int8_t		qlcversion[100];
383 	struct fw_table	fw_table[10], *fwt = NULL;
384 	uint8_t		*fwverptr = NULL;
385 	ql_head_t	ql_hba;
386 	uint32_t	found = 0;
387 
388 	if ((flags & DCMD_ADDRSPEC) || argc != 0) {
389 		return (DCMD_USAGE);
390 	}
391 
392 	if (mdb_readvar(&qlcversion, "qlc_driver_version") == -1) {
393 		mdb_warn("unable to read qlc driver version\n");
394 	} else {
395 		mdb_printf("\n%s version currently loaded is: %s\n",
396 		    QL_NAME, qlcversion);
397 	}
398 
399 	mdb_printf("qlc mdb library compiled with %s version: %s\n",
400 	    QL_NAME, QL_VERSION);
401 
402 	if ((fwverptr = (uint8_t *)(mdb_alloc(50, UM_SLEEP))) == NULL) {
403 		mdb_warn("unable to alloc fwverptr\n");
404 		return (DCMD_OK);
405 	}
406 
407 	if (mdb_readvar(&fw_table, "fw_table") == -1) {
408 		mdb_warn("unable to read firmware table\n");
409 	} else {
410 		ql_adapter_state_t	*qlstate;
411 		uintptr_t		hbaptr = NULL;
412 
413 		if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
414 			mdb_warn("failed to read ql_hba structure");
415 			return (DCMD_ERR);
416 		}
417 
418 		if ((qlstate = (ql_adapter_state_t *)mdb_alloc(
419 		    sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
420 			mdb_warn("Unable to allocate memory for "
421 			    "ql_adapter_state\n");
422 			return (DCMD_OK);
423 		}
424 
425 		mdb_printf("\n%-8s%-11s%s\n", "f/w", "compiled", "loaded");
426 		mdb_printf("%<u>%-8s%-11s%-13s%s%</u>\n\n", "class", "version",
427 		    "version", "instance list");
428 
429 		for (fwt = &fw_table[0]; fwt->fw_class; fwt++) {
430 
431 			if (mdb_vread(fwverptr, sizeof (void *),
432 			    (uintptr_t)fwt->fw_version) == -1) {
433 				mdb_warn("unable to read fwverptr\n");
434 				mdb_free(fwverptr, sizeof (void *));
435 				mdb_free(qlstate, sizeof (ql_adapter_state_t));
436 				return (DCMD_OK);
437 			}
438 
439 			mdb_printf("%x\t%-11s", fwt->fw_class, fwverptr);
440 
441 			if (&ql_hba == NULL) {
442 				mdb_warn("failed to read ql_hba structure");
443 				hbaptr = NULL;
444 			} else {
445 				hbaptr = (uintptr_t)ql_hba.first;
446 			}
447 
448 			found = 0;
449 			while (hbaptr != NULL) {
450 
451 				if (mdb_vread(qlstate,
452 				    sizeof (ql_adapter_state_t), hbaptr) ==
453 				    -1) {
454 					mdb_warn("failed to read "
455 					    "ql_adapter_state at %p", hbaptr);
456 					break;
457 				}
458 
459 				if (qlstate->fw_class == fwt->fw_class) {
460 					if (found == 0) {
461 						mdb_printf("%x.%02x.%02x\t",
462 						    qlstate->fw_major_version,
463 						    qlstate->fw_minor_version,
464 						    qlstate->
465 						    fw_subminor_version);
466 						mdb_printf("%d",
467 						    qlstate->instance);
468 					} else {
469 						mdb_printf(", %d",
470 						    qlstate->instance);
471 					}
472 					found = 1;
473 				}
474 
475 				hbaptr = (uintptr_t)qlstate->hba.next;
476 			}
477 
478 			if (found == 1) {
479 				mdb_printf("\n");
480 			} else {
481 				mdb_printf("not loaded\n");
482 			}
483 		}
484 
485 		mdb_free(qlstate, sizeof (ql_adapter_state_t));
486 		mdb_free(fwverptr, sizeof (void *));
487 	}
488 
489 	return (DCMD_OK);
490 }
491 
492 /*
493  * qlc_el_dcmd
494  *	mdb dcmd which turns the extended logging bit on or off
495  *	for the specificed qlc instance(s).
496  *
497  * Input:
498  *	addr  = User supplied address -- error if supplied.
499  *	flags = mdb flags.
500  *	argc  = Number of user supplied args -- error if non-zero.
501  *	argv  = Arg array.
502  *
503  * Returns:
504  *	DCMD_USAGE, or DCMD_OK
505  *
506  * Context:
507  *	User context.
508  *
509  */
510 /*ARGSUSED*/
511 static int
512 qlc_el_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
513 {
514 	int8_t			qlcversion[100];
515 	boolean_t		elswitch;
516 	uint32_t		argcnt;
517 	int			mdbs;
518 	uint32_t		instance;
519 	uint32_t		qlsize = sizeof (ql_adapter_state_t);
520 	ql_adapter_state_t	*qlstate;
521 	uintptr_t		hbaptr = NULL;
522 	ql_head_t		ql_hba;
523 
524 	if ((mdbs = mdb_get_state()) == MDB_STATE_DEAD) {
525 		mdb_warn("Cannot change core file data (state=%xh)\n", mdbs);
526 		return (DCMD_OK);
527 	}
528 
529 	if ((flags & DCMD_ADDRSPEC) || argc < 2) {
530 		return (DCMD_USAGE);
531 	}
532 
533 	/*
534 	 * Check and make sure the driver version and the mdb versions
535 	 * match so all the structures and flags line up
536 	 */
537 
538 	if (mdb_readvar(&qlcversion, "qlc_driver_version") == -1) {
539 		mdb_warn("unable to read qlc driver version\n");
540 		return (DCMD_OK);
541 	}
542 
543 	if ((strcmp(QL_VERSION, (const char *)&qlcversion)) != 0) {
544 		mdb_warn("Error: qlc driver/qlc mdb version mismatch\n");
545 		mdb_printf("\tqlc mdb library compiled version is: %s\n",
546 		    QL_VERSION);
547 		mdb_printf("\tqlc driver version is: %s\n", qlcversion);
548 
549 		return (DCMD_OK);
550 	}
551 
552 	if ((strcasecmp(argv[0].a_un.a_str, "on")) == 0) {
553 		elswitch = TRUE;
554 	} else if ((strcasecmp(argv[0].a_un.a_str, "off")) == 0) {
555 		elswitch = FALSE;
556 	} else {
557 		return (DCMD_USAGE);
558 	}
559 
560 	if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
561 		mdb_warn("failed to read ql_hba structure");
562 		return (DCMD_ERR);
563 	}
564 
565 	if (&ql_hba == NULL) {
566 		mdb_warn("failed to read ql_hba structure - is qlc loaded?");
567 		return (DCMD_ERR);
568 	}
569 
570 	if ((qlstate = (ql_adapter_state_t *)mdb_alloc(qlsize,
571 	    UM_SLEEP)) == NULL) {
572 		mdb_warn("Unable to allocate memory for "
573 		    "ql_adapter_state\n");
574 		return (DCMD_OK);
575 	}
576 
577 
578 	if ((strcasecmp(argv[1].a_un.a_str, "all")) == 0) {
579 
580 		if (argc != 2) {
581 			mdb_free(qlstate, qlsize);
582 			return (DCMD_USAGE);
583 		}
584 
585 		hbaptr = (uintptr_t)ql_hba.first;
586 
587 		while (hbaptr != NULL) {
588 
589 			if (mdb_vread(qlstate, qlsize, hbaptr) == -1) {
590 				mdb_free(qlstate, qlsize);
591 				mdb_warn("failed to read ql_adapter_state "
592 				    "at %p", hbaptr);
593 				return (DCMD_OK);
594 			}
595 
596 			ql_elog_common(qlstate, elswitch);
597 
598 			hbaptr = (uintptr_t)qlstate->hba.next;
599 		}
600 	} else {
601 		for (argcnt = 1; argcnt < argc; argcnt++) {
602 
603 			instance = (uint32_t)mdb_strtoull(
604 			    argv[argcnt].a_un.a_str);
605 
606 			/* find the correct instance to change */
607 			hbaptr = (uintptr_t)ql_hba.first;
608 			while (hbaptr != NULL) {
609 
610 				if (mdb_vread(qlstate, qlsize, hbaptr) == -1) {
611 					mdb_free(qlstate, qlsize);
612 					mdb_warn("failed to read "
613 					    "ql_adapter_state at %p", hbaptr);
614 					return (DCMD_OK);
615 				}
616 
617 				if (qlstate->instance == instance) {
618 					break;
619 				}
620 
621 				hbaptr = (uintptr_t)qlstate->hba.next;
622 			}
623 
624 			if (hbaptr == NULL) {
625 				mdb_printf("instance %d is not loaded",
626 				    instance);
627 				continue;
628 			}
629 
630 			ql_elog_common(qlstate, elswitch);
631 		}
632 	}
633 
634 	mdb_free(qlstate, qlsize);
635 
636 	return (DCMD_OK);
637 }
638 
639 /*
640  * qlc_elog_common
641  *	mdb helper function which set/resets the extended logging bit
642  *
643  * Input:
644  *	qlstate  = adapter state structure
645  *	elswitch = boolean which specifies to reset (0) or set (1) the
646  *		   extended logging bit.
647  *
648  * Returns:
649  *
650  * Context:
651  *	User context.
652  *
653  */
654 static void
655 ql_elog_common(ql_adapter_state_t *qlstate, boolean_t elswitch)
656 {
657 	uintptr_t	hbaptr = (uintptr_t)qlstate->hba.base_address;
658 	size_t		qlsize = sizeof (ql_adapter_state_t);
659 
660 	if (elswitch) {
661 		if ((qlstate->cfg_flags & CFG_ENABLE_EXTENDED_LOGGING) == 0) {
662 
663 			qlstate->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING;
664 
665 			if ((mdb_vwrite((const void *)qlstate, qlsize,
666 			    hbaptr)) != (ssize_t)qlsize) {
667 				mdb_warn("instance %d - unable to update",
668 				    qlstate->instance);
669 			} else {
670 				mdb_printf("instance %d extended logging is "
671 				    "now on\n", qlstate->instance);
672 			}
673 		} else {
674 			mdb_printf("instance %d extended logging is "
675 			    "already on\n", qlstate->instance);
676 		}
677 	} else {
678 		if ((qlstate->cfg_flags & CFG_ENABLE_EXTENDED_LOGGING) != 0) {
679 
680 			qlstate->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
681 
682 			if ((mdb_vwrite((const void *)qlstate, qlsize,
683 			    hbaptr)) != (ssize_t)qlsize) {
684 				mdb_warn("instance %d - unable to update",
685 				    qlstate->instance);
686 			} else {
687 				mdb_printf("instance %d extended logging is "
688 				    "now off\n", qlstate->instance);
689 			}
690 		} else {
691 			mdb_printf("instance %d extended logging is "
692 			    "already off\n", qlstate->instance);
693 		}
694 	}
695 }
696 
697 /*
698  * qlc_ocs_dcmd
699  *	mdb dcmd which prints out the outstanding command array using
700  *	caller supplied address (which sb the ha structure).
701  *
702  * Input:
703  *	addr  = User supplied ha address.
704  *	flags = mdb flags.
705  *	argc  = Number of user supplied args.
706  *	argv  = Arg array.
707  *
708  * Returns:
709  *	DCMD_USAGE, or DCMD_OK
710  *
711  * Context:
712  *	User context.
713  *
714  *
715  */
716 static int
717 /*ARGSUSED*/
718 qlc_osc_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
719 {
720 	ql_adapter_state_t	*qlstate;
721 	uintptr_t		qlosc, ptr1;
722 	uint32_t		indx, found = 0;
723 	ql_srb_t		*qlsrb;
724 
725 	if (!(flags & DCMD_ADDRSPEC)) {
726 		return (DCMD_USAGE);
727 	}
728 
729 	if ((qlstate = (ql_adapter_state_t *)
730 	    mdb_alloc(sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
731 		mdb_warn("Unable to allocate memory for ql_adapter_state\n");
732 		return (DCMD_OK);
733 	}
734 	if (mdb_vread(qlstate, sizeof (ql_adapter_state_t), addr) == -1) {
735 		mdb_free(qlstate, sizeof (ql_adapter_state_t));
736 		mdb_warn("failed to read ql_adapter_state at %p", addr);
737 		return (DCMD_OK);
738 	}
739 
740 	qlosc = (uintptr_t)qlstate->outstanding_cmds;
741 	mdb_printf("qlc instance: %d, base addr = %llx, osc base = %p\n",
742 	    qlstate->instance, qlstate->hba.base_address, qlosc);
743 
744 
745 	if ((qlsrb = (ql_srb_t *)mdb_alloc(sizeof (ql_srb_t), UM_SLEEP)) ==
746 	    NULL) {
747 		mdb_free(qlstate, sizeof (ql_adapter_state_t));
748 		mdb_warn("failed to allocate space for srb_t\n");
749 		return (DCMD_OK);
750 	}
751 	for (indx = 0; indx < MAX_OUTSTANDING_COMMANDS; indx++, qlosc += 8) {
752 		if (mdb_vread(&ptr1, 8, qlosc) == -1) {
753 			mdb_warn("failed to read ptr1, indx=%d", indx);
754 			break;
755 		}
756 		if (ptr1 == 0) {
757 			continue;
758 		}
759 
760 		mdb_printf("osc ptr = %p, indx = %xh\n", ptr1, indx);
761 
762 		if (mdb_vread(qlsrb, sizeof (ql_srb_t), ptr1) == -1) {
763 			mdb_warn("failed to read ql_srb_t at %p", ptr1);
764 			break;
765 		}
766 		(void) ql_doprint(ptr1, "struct ql_srb");
767 		found++;
768 	}
769 
770 	mdb_free(qlsrb, sizeof (ql_srb_t));
771 	mdb_free(qlstate, sizeof (ql_adapter_state_t));
772 
773 	mdb_printf("number of outstanding command srb's is: %d\n", found);
774 
775 	return (DCMD_OK);
776 }
777 
778 /*
779  * qlc_wdog_dcmd
780  *	mdb dcmd which prints out the commands which are linked
781  *	on the watchdog linked list. Caller supplied address (which
782  *	sb the ha structure).
783  *
784  * Input:
785  *	addr  = User supplied ha address.
786  *	flags = mdb flags.
787  *	argc  = Number of user supplied args.
788  *	argv  = Arg array.
789  *
790  * Returns:
791  *	DCMD_USAGE, or DCMD_OK
792  *
793  * Context:
794  *	User context.
795  *
796  *
797  */
798 static int
799 /*ARGSUSED*/
800 qlc_wdog_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
801 {
802 	ql_adapter_state_t	*qlstate;
803 	uint16_t		index, count;
804 	ql_head_t		*dev;
805 	ql_srb_t		*srb;
806 	ql_tgt_t		*tq;
807 	ql_lun_t		*lq;
808 	ql_link_t		*tqlink, *srblink, *lqlink;
809 	int			nextlink;
810 
811 	if (!(flags & DCMD_ADDRSPEC)) {
812 		mdb_warn("Address required\n", addr);
813 		return (DCMD_USAGE);
814 	}
815 
816 	if ((qlstate = (ql_adapter_state_t *)
817 	    mdb_alloc(sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
818 		mdb_warn("Unable to allocate memory for ql_adapter_state\n");
819 		return (DCMD_OK);
820 	}
821 
822 	if (mdb_vread(qlstate, sizeof (ql_adapter_state_t), addr) == -1) {
823 		mdb_free(qlstate, sizeof (ql_adapter_state_t));
824 		mdb_warn("failed to read ql_adapter_state at %p", addr);
825 		return (DCMD_OK);
826 	}
827 
828 	/*
829 	 * Read in the device array
830 	 */
831 	dev = (ql_head_t *)
832 	    mdb_alloc(sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE, UM_SLEEP);
833 
834 	if (mdb_vread(dev, sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE,
835 	    (uintptr_t)qlstate->dev) == -1) {
836 		mdb_warn("failed to read ql_head_t (dev) at %p", qlstate->dev);
837 		mdb_free(qlstate, sizeof (ql_adapter_state_t));
838 		mdb_free(dev, sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE);
839 		return (DCMD_OK);
840 	}
841 
842 	tqlink = (ql_link_t *)mdb_alloc(sizeof (ql_link_t), UM_SLEEP);
843 	tq = (ql_tgt_t *)mdb_alloc(sizeof (ql_tgt_t), UM_SLEEP);
844 	lqlink = (ql_link_t *)mdb_alloc(sizeof (ql_link_t), UM_SLEEP);
845 	lq = (ql_lun_t *)mdb_alloc(sizeof (ql_lun_t), UM_SLEEP);
846 	srblink = (ql_link_t *)mdb_alloc(sizeof (ql_link_t), UM_SLEEP);
847 	srb = (ql_srb_t *)mdb_alloc(sizeof (ql_srb_t), UM_SLEEP);
848 
849 	/*
850 	 * Validate the devices watchdog queue
851 	 */
852 	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
853 
854 		/* Skip empty ones */
855 		if (dev[index].first == NULL) {
856 			continue;
857 		}
858 
859 		mdb_printf("dev array index = %x\n", index);
860 
861 		/* Loop through targets on device linked list */
862 		/* get the first link */
863 
864 		nextlink = get_first_link(&dev[index], tqlink);
865 
866 		/*
867 		 * traverse the targets linked list at this device array index.
868 		 */
869 		while (nextlink == DCMD_OK) {
870 			/* Get the target */
871 			if (mdb_vread(tq, sizeof (ql_tgt_t),
872 			    (uintptr_t)(tqlink->base_address)) == -1) {
873 				mdb_warn("failed to read ql_tgt at %p",
874 				    tqlink->base_address);
875 				break;
876 			}
877 			mdb_printf("tgt q base = %llx, ",
878 			    tqlink->base_address);
879 
880 			mdb_printf("flags: (%xh)", tq->flags);
881 
882 			if (tq->flags) {
883 				ql_dump_flags((uint64_t)tq->flags, qltgt_flags);
884 			}
885 
886 			mdb_printf("tgt: %02x%02x%02x%02x%02x%02x%02x%02x ",
887 			    tq->node_name[0], tq->node_name[1],
888 			    tq->node_name[2], tq->node_name[3],
889 			    tq->node_name[4], tq->node_name[5],
890 			    tq->node_name[6], tq->node_name[7]);
891 
892 			/*
893 			 * Loop through commands on this targets watchdog queue.
894 			 */
895 
896 			/* Get the first link on the targets cmd wdg q. */
897 			if (tq->wdg.first == NULL) {
898 				mdb_printf(" watchdog list empty ");
899 				break;
900 			} else {
901 				if (mdb_vread(srblink, sizeof (ql_link_t),
902 				    (uintptr_t)tq->wdg.first) == -1) {
903 					mdb_warn("failed to read ql_link_t"
904 					    " at %p", tq->wdg.first);
905 					break;
906 				}
907 				/* There is aleast one. */
908 				count = 1;
909 				/*
910 				 * Count the remaining items in the
911 				 * cmd watchdog list.
912 				 */
913 				while (srblink->next != NULL) {
914 					/* Read in the next ql_link_t header */
915 					if (mdb_vread(srblink,
916 					    sizeof (ql_link_t),
917 					    (uintptr_t)srblink->next) == -1) {
918 						mdb_warn("failed to read"
919 						    " ql_link_t next at %p",
920 						    srblink->next);
921 						break;
922 					}
923 					count = (uint16_t)(count + 1);
924 				}
925 				mdb_printf(" watchdog list: %d entries\n",
926 				    count);
927 				/* get the first one again */
928 				if (mdb_vread(srblink, sizeof (ql_link_t),
929 				    (uintptr_t)tq->wdg.first) == -1) {
930 					mdb_warn("failed to read ql_link_t"
931 					    " at %p", tq->wdg.first);
932 					break;
933 				}
934 			}
935 			/*
936 			 * Traverse the targets cmd watchdog linked list
937 			 * verifying srb's from the list are on a lun cmd list.
938 			 */
939 			while (nextlink == DCMD_OK) {
940 				int	found = 0;
941 				/* get the srb */
942 				if (mdb_vread(srb, sizeof (ql_srb_t),
943 				    (uintptr_t)srblink->base_address) == -1) {
944 					mdb_warn("failed to read ql_srb_t"
945 					" at %p", srblink->base_address);
946 					break;
947 				}
948 				mdb_printf("ql_srb %llx ",
949 				    srblink->base_address);
950 
951 				/*
952 				 * Get the lun q the srb is on
953 				 */
954 				if (mdb_vread(lq, sizeof (ql_lun_t),
955 				    (uintptr_t)srb->lun_queue) == -1) {
956 					mdb_warn("failed to read ql_srb_t"
957 					    " at %p", srb->lun_queue);
958 					break;
959 				}
960 				nextlink = get_first_link(&lq->cmd, lqlink);
961 				/*
962 				 * traverse the lun cmd linked list looking
963 				 * for the srb from the targets watchdog list
964 				 */
965 				while (nextlink == DCMD_OK) {
966 					if (srblink->base_address ==
967 					    lqlink->base_address) {
968 						mdb_printf("on lun %d cmd q\n",
969 						    lq->lun_no);
970 						found = 1;
971 						break;
972 					}
973 					/* get next item on lun cmd list */
974 					nextlink = get_next_link(lqlink);
975 				}
976 				if (!found) {
977 					mdb_printf("not found on lun cmd q\n");
978 				}
979 				/* get next item in the watchdog list */
980 				nextlink = get_next_link(srblink);
981 			} /* End targets command watchdog list */
982 			/* get next item in this target list */
983 			nextlink = get_next_link(tqlink);
984 		} /* End traverse the device targets linked list */
985 		mdb_printf("\n");
986 	} /* End device array */
987 
988 	mdb_free(tq, sizeof (ql_tgt_t));
989 	mdb_free(lq, sizeof (ql_lun_t));
990 	mdb_free(srb, sizeof (ql_srb_t));
991 	mdb_free(tqlink, sizeof (ql_link_t));
992 	mdb_free(srblink, sizeof (ql_link_t));
993 	mdb_free(lqlink, sizeof (ql_link_t));
994 	mdb_free(qlstate, sizeof (ql_adapter_state_t));
995 	mdb_free(dev, sizeof (ql_head_t)*DEVICE_HEAD_LIST_SIZE);
996 
997 	return (DCMD_OK);
998 }
999 
1000 /*
1001  * get_first_link
1002  *	Gets the first ql_link_t header on ql_head.
1003  *
1004  * Input:
1005  *	ql_head  = pointer to a ql_head_t structure.
1006  *	ql_link  = pointer to a ql_link_t structure.
1007  *
1008  * Returns:
1009  *	DCMD_ABORT, or DCMD_OK
1010  *
1011  * Context:
1012  *	User context.
1013  *
1014  */
1015 static int
1016 get_first_link(ql_head_t *qlhead, ql_link_t *qllink)
1017 {
1018 	int	rval = DCMD_ABORT;
1019 
1020 	if (qlhead != NULL) {
1021 		if (qlhead->first != NULL) {
1022 			/* Read in the first ql_link_t header */
1023 			if (mdb_vread(qllink, sizeof (ql_link_t),
1024 			    (uintptr_t)(qlhead->first)) == -1) {
1025 				mdb_warn("failed to read ql_link_t "
1026 				    "next at %p", qlhead->first);
1027 			} else {
1028 				rval = DCMD_OK;
1029 			}
1030 		}
1031 	}
1032 	return (rval);
1033 }
1034 
1035 /*
1036  * get_next_link
1037  *	Gets the next ql_link_t structure.
1038  *
1039  * Input:
1040  *	ql_link  = pointer to a ql_link_t structure.
1041  *
1042  * Returns:
1043  *	DCMD_ABORT, or DCMD_OK
1044  *
1045  * Context:
1046  *	User context.
1047  *
1048  */
1049 static int
1050 get_next_link(ql_link_t *qllink)
1051 {
1052 	int	rval = DCMD_ABORT;
1053 
1054 	if (qllink != NULL) {
1055 		if (qllink->next != NULL) {
1056 			/* Read in the next ql_link_t header */
1057 			if (mdb_vread(qllink, sizeof (ql_link_t),
1058 			    (uintptr_t)(qllink->next)) == -1) {
1059 				mdb_warn("failed to read ql_link_t "
1060 				    "next at %p", qllink->next);
1061 			} else {
1062 				rval = DCMD_OK;
1063 			}
1064 		}
1065 	}
1066 	return (rval);
1067 }
1068 
1069 
1070 /*
1071  * qlcstate_dcmd
1072  *	mdb dcmd which prints out the ql_state info using
1073  *	caller supplied address.
1074  *
1075  * Input:
1076  *	addr  = User supplied address.
1077  *	flags = mdb flags.
1078  *	argc  = Number of user supplied args.
1079  *	argv  = Arg array.
1080  *
1081  * Returns:
1082  *	DCMD_USAGE, or DCMD_OK
1083  *
1084  * Context:
1085  *	User context.
1086  *
1087  */
1088 static int
1089 qlcstate_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1090 {
1091 	ql_adapter_state_t	*qlstate;
1092 	int			verbose = 0;
1093 
1094 	if (!(flags & DCMD_ADDRSPEC)) {
1095 		return (DCMD_USAGE);
1096 	}
1097 
1098 	if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose) !=
1099 	    argc) {
1100 		return (DCMD_USAGE);
1101 	}
1102 
1103 	if ((qlstate = (ql_adapter_state_t *)
1104 	    mdb_alloc(sizeof (ql_adapter_state_t), UM_SLEEP)) == NULL) {
1105 		mdb_warn("failed to allocate memory for ql_adapter_state\n");
1106 		return (DCMD_OK);
1107 	}
1108 	if (mdb_vread(qlstate, sizeof (ql_adapter_state_t), addr) == -1) {
1109 		mdb_free(qlstate, sizeof (ql_adapter_state_t));
1110 		mdb_warn("failed to read ql_adapter_state at %p", addr);
1111 		return (DCMD_OK);
1112 	}
1113 
1114 	mdb_printf("qlc instance: %d, base addr = %llx\n", qlstate->instance,
1115 	    addr);
1116 
1117 	mdb_printf("\nadapter state flags:\n");
1118 	ql_dump_flags((uint64_t)qlstate->flags, adapter_state_flags);
1119 	mdb_printf("\nadapter cfg flags:\n");
1120 	ql_dump_flags((uint64_t)qlstate->cfg_flags, adapter_config_flags);
1121 	mdb_printf("\ntask daemon state flags:\n");
1122 	ql_dump_flags((uint64_t)qlstate->task_daemon_flags,
1123 	    task_daemon_flags);
1124 
1125 	if (verbose) {
1126 		(void) ql_doprint(addr, "struct ql_adapter_state");
1127 	}
1128 
1129 	mdb_free(qlstate, sizeof (ql_adapter_state_t));
1130 
1131 	return (DCMD_OK);
1132 }
1133 
1134 /*
1135  * qlcstates_walk_init
1136  *	mdb walker init which prints out all qlc states info.
1137  *
1138  * Input:
1139  *	wsp - Pointer to walker state struct
1140  *
1141  * Returns:
1142  *	WALK_ERR, or WALK_NEXT
1143  *
1144  * Context:
1145  *	User context.
1146  *
1147  */
1148 static int
1149 qlstates_walk_init(mdb_walk_state_t *wsp)
1150 {
1151 	ql_head_t	ql_hba;
1152 
1153 	if (wsp->walk_addr == NULL) {
1154 		if ((mdb_readvar(&ql_hba, "ql_hba") == -1) ||
1155 		    (&ql_hba == NULL)) {
1156 			mdb_warn("failed to read ql_hba structure");
1157 			return (WALK_ERR);
1158 		}
1159 
1160 		wsp->walk_addr = (uintptr_t)ql_hba.first;
1161 		wsp->walk_data = mdb_alloc(sizeof (ql_adapter_state_t),
1162 		    UM_SLEEP);
1163 		return (WALK_NEXT);
1164 	} else {
1165 		return (ql_doprint(wsp->walk_addr, "struct ql_adapter_state"));
1166 	}
1167 }
1168 
1169 /*
1170  * qlstates_walk_step
1171  *	mdb walker step which prints out all qlc states info.
1172  *
1173  * Input:
1174  *	wsp - Pointer to walker state struct
1175  *
1176  * Returns:
1177  *	WALK_DONE, or WALK_NEXT
1178  *
1179  * Context:
1180  *	User context.
1181  *
1182  */
1183 static int
1184 qlstates_walk_step(mdb_walk_state_t *wsp)
1185 {
1186 	ql_adapter_state_t	*qlstate;
1187 
1188 	if (wsp->walk_addr == NULL) {
1189 		return (WALK_DONE);
1190 	}
1191 
1192 	if (mdb_vread(wsp->walk_data, sizeof (ql_adapter_state_t),
1193 	    wsp->walk_addr) == -1) {
1194 		mdb_warn("failed to read ql_adapter_state at %p",
1195 		    wsp->walk_addr);
1196 		return (WALK_DONE);
1197 	}
1198 
1199 	qlstate = (ql_adapter_state_t *)(wsp->walk_data);
1200 	mdb_printf("qlc instance: %d, base addr = %llx\n",
1201 	    qlstate->instance, wsp->walk_addr);
1202 
1203 	mdb_printf("\nadapter state flags:\n");
1204 	ql_dump_flags((uint64_t)qlstate->flags, adapter_state_flags);
1205 	mdb_printf("\nadapter cfg flags:\n");
1206 	ql_dump_flags((uint64_t)qlstate->cfg_flags, adapter_config_flags);
1207 	mdb_printf("\ntask daemon state flags:\n");
1208 	ql_dump_flags((uint64_t)qlstate->task_daemon_flags,
1209 	    task_daemon_flags);
1210 
1211 	mdb_printf("\nadapter state:\n");
1212 	(void) ql_doprint(wsp->walk_addr, "struct ql_adapter_state");
1213 
1214 	mdb_printf("\n");
1215 
1216 	wsp->walk_addr = (uintptr_t)
1217 	    (((ql_adapter_state_t *)wsp->walk_data)->hba.next);
1218 
1219 	return (WALK_NEXT);
1220 }
1221 
1222 /*
1223  * qlstates_walk_fini
1224  *	mdb walker fini which wraps up the walker
1225  *
1226  * Input:
1227  *	wsp - Pointer to walker state struct
1228  *
1229  * Returns:
1230  *
1231  * Context:
1232  *	User context.
1233  *
1234  */
1235 static void
1236 qlstates_walk_fini(mdb_walk_state_t *wsp)
1237 {
1238 	mdb_free(wsp->walk_data, sizeof (ql_adapter_state_t));
1239 }
1240 
1241 /*
1242  * qlsrb_walk_init
1243  *	mdb walker init which prints out linked srb's
1244  *
1245  * Input:
1246  *	wsp - Pointer to walker ql_srb struct
1247  *
1248  * Returns:
1249  *	WALK_ERR, or WALK_NEXT
1250  *
1251  * Context:
1252  *	User context.
1253  *
1254  */
1255 static int
1256 qlsrb_walk_init(mdb_walk_state_t *wsp)
1257 {
1258 	if (wsp->walk_addr == NULL) {
1259 		mdb_warn("failed to read ql_srb addr at %p",
1260 		    wsp->walk_addr);
1261 		return (WALK_ERR);
1262 	}
1263 
1264 	wsp->walk_data = mdb_alloc(sizeof (ql_srb_t), UM_SLEEP);
1265 
1266 	return (WALK_NEXT);
1267 }
1268 
1269 /*
1270  * qlcsrb_walk_step
1271  *	mdb walker step which prints out linked ql_srb structures
1272  *
1273  * Input:
1274  *	wsp - Pointer to walker srb struct
1275  *
1276  * Returns:
1277  *	WALK_DONE, or WALK_NEXT
1278  *
1279  * Context:
1280  *	User context.
1281  *
1282  */
1283 static int
1284 qlsrb_walk_step(mdb_walk_state_t *wsp)
1285 {
1286 	ql_srb_t	*qlsrb;
1287 
1288 	if (wsp->walk_addr == NULL)
1289 		return (WALK_DONE);
1290 
1291 	if (mdb_vread(wsp->walk_data, sizeof (ql_srb_t),
1292 	    wsp->walk_addr) == -1) {
1293 		mdb_warn("failed to read ql_srb at %p", wsp->walk_addr);
1294 		return (WALK_DONE);
1295 	}
1296 
1297 	qlsrb = (ql_srb_t *)(wsp->walk_data);
1298 	mdb_printf("ql_srb base addr = %llx\n", wsp->walk_addr);
1299 
1300 	mdb_printf("\nql_srb flags:\n");
1301 	ql_dump_flags((uint64_t)qlsrb->flags, qlsrb_flags);
1302 
1303 	mdb_printf("\nql_srb:\n");
1304 	(void) ql_doprint(wsp->walk_addr, "struct ql_srb");
1305 
1306 	mdb_printf("\n");
1307 
1308 	wsp->walk_addr = (uintptr_t)
1309 	    (((ql_srb_t *)wsp->walk_data)->cmd.next);
1310 
1311 	return (WALK_NEXT);
1312 }
1313 
1314 /*
1315  * qlsrb_walk_fini
1316  *	mdb walker fini which wraps up the walker
1317  *
1318  * Input:
1319  *	wsp - Pointer to walker state struct
1320  *
1321  * Returns:
1322  *
1323  * Context:
1324  *	User context.
1325  *
1326  */
1327 static void
1328 qlsrb_walk_fini(mdb_walk_state_t *wsp)
1329 {
1330 	mdb_free(wsp->walk_data, sizeof (ql_srb_t));
1331 }
1332 
1333 /*
1334  * qllunq_dcmd
1335  *	mdb walker which prints out lun q's
1336  *
1337  * Input:
1338  *	wsp - Pointer to walker ql_lun struct
1339  *
1340  * Returns:
1341  *	WALK_ERR, or WALK_NEXT
1342  *
1343  * Context:
1344  *	User context.
1345  *
1346  */
1347 static int
1348 qllunq_walk_init(mdb_walk_state_t *wsp)
1349 {
1350 	if (wsp->walk_addr == NULL) {
1351 		mdb_warn("failed to read ql_lun addr at %p",
1352 		    wsp->walk_addr);
1353 		return (WALK_ERR);
1354 	}
1355 
1356 	wsp->walk_data = mdb_alloc(sizeof (ql_lun_t), UM_SLEEP);
1357 
1358 	return (WALK_NEXT);
1359 }
1360 
1361 /*
1362  * qlclunq_walk_step
1363  *	mdb walker step which prints out linked ql_lun structures
1364  *
1365  * Input:
1366  *	wsp - Pointer to walker srb struct
1367  *
1368  * Returns:
1369  *	WALK_DONE, or WALK_NEXT
1370  *
1371  * Context:
1372  *	User context.
1373  *
1374  */
1375 static int
1376 qllunq_walk_step(mdb_walk_state_t *wsp)
1377 {
1378 	ql_lun_t	*qllun;
1379 	ql_link_t	ql_link;
1380 	ql_link_t	*qllink;
1381 
1382 	if (wsp->walk_addr == NULL)
1383 		return (WALK_DONE);
1384 
1385 	if (mdb_vread(wsp->walk_data, sizeof (ql_lun_t),
1386 	    wsp->walk_addr) == -1) {
1387 		mdb_warn("failed to read ql_lun at %p", wsp->walk_addr);
1388 		return (WALK_DONE);
1389 	}
1390 
1391 	qllun = (ql_lun_t *)(wsp->walk_data);
1392 	mdb_printf("ql_lun base addr = %llx\n", wsp->walk_addr);
1393 
1394 	mdb_printf("\nql_lun flags:\n");
1395 	ql_dump_flags((uint64_t)qllun->flags, qllun_flags);
1396 
1397 	mdb_printf("\nql_lun:\n");
1398 	(void) ql_doprint(wsp->walk_addr, "struct ql_lun");
1399 
1400 	mdb_printf("\n");
1401 
1402 	qllink = (ql_link_t *)
1403 	    (((ql_lun_t *)wsp->walk_data)->link.next);
1404 
1405 	if (qllink == NULL) {
1406 		return (WALK_DONE);
1407 	} else {
1408 		/*
1409 		 * Read in the next link_t header
1410 		 */
1411 		if (mdb_vread(&ql_link, sizeof (ql_link_t),
1412 		    (uintptr_t)qllink) == -1) {
1413 			mdb_warn("failed to read ql_link_t "
1414 			    "next at %p", qllink->next);
1415 			return (WALK_DONE);
1416 		}
1417 		qllink = &ql_link;
1418 	}
1419 
1420 	wsp->walk_addr = (uintptr_t)qllink->base_address;
1421 
1422 	return (WALK_NEXT);
1423 }
1424 
1425 /*
1426  * qllunq_walk_fini
1427  *	mdb walker fini which wraps up the walker
1428  *
1429  * Input:
1430  *	wsp - Pointer to walker state struct
1431  *
1432  * Returns:
1433  *
1434  * Context:
1435  *	User context.
1436  *
1437  */
1438 static void
1439 qllunq_walk_fini(mdb_walk_state_t *wsp)
1440 {
1441 	mdb_free(wsp->walk_data, sizeof (ql_lun_t));
1442 }
1443 
1444 /*
1445  * qltgtq_dcmd
1446  *	mdb dcmd which prints out an hs's tq struct info.
1447  *
1448  * Input:
1449  *	addr  = User supplied address. (NB: nust be an ha)
1450  *	flags = mdb flags.
1451  *	argc  = Number of user supplied args.
1452  *	argv  = Arg array.
1453  *
1454  * Returns:
1455  *	DCMD_USAGE, or DCMD_OK
1456  *
1457  * Context:
1458  *	User context.
1459  *
1460  */
1461 /*ARGSUSED*/
1462 static int
1463 qltgtq_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1464 {
1465 	ql_adapter_state_t	*ha;
1466 	ql_link_t		*link;
1467 	ql_tgt_t		*tq;
1468 	uint32_t		index;
1469 	ql_head_t		*dev;
1470 
1471 	if ((!(flags & DCMD_ADDRSPEC)) || addr == NULL) {
1472 		mdb_warn("ql_hba structure addr is required");
1473 		return (DCMD_USAGE);
1474 	}
1475 
1476 	/*
1477 	 * Get the adapter state struct which was passed
1478 	 */
1479 
1480 	ha = (ql_adapter_state_t *)mdb_alloc(sizeof (ql_adapter_state_t),
1481 	    UM_SLEEP);
1482 
1483 	if (mdb_vread(ha, sizeof (ql_adapter_state_t), addr) == -1) {
1484 		mdb_warn("failed to read ql_adapter_state at %p", addr);
1485 		mdb_free(ha, sizeof (ql_adapter_state_t));
1486 		return (DCMD_OK);
1487 	}
1488 
1489 	if (ha->dev == NULL) {
1490 		mdb_warn("dev ptr is NULL for ha: %p", addr);
1491 		mdb_free(ha, sizeof (ql_adapter_state_t));
1492 		return (DCMD_OK);
1493 	}
1494 
1495 	/*
1496 	 * Read in the device array
1497 	 */
1498 	dev = (ql_head_t *)
1499 	    mdb_alloc(sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE, UM_SLEEP);
1500 
1501 	if (mdb_vread(dev, sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE,
1502 	    (uintptr_t)ha->dev) == -1) {
1503 		mdb_warn("failed to read ql_head_t (dev) at %p", ha->dev);
1504 		mdb_free(ha, sizeof (ql_adapter_state_t));
1505 		mdb_free(dev, sizeof (ql_head_t) * DEVICE_HEAD_LIST_SIZE);
1506 	}
1507 
1508 	tq = (ql_tgt_t *)mdb_alloc(sizeof (ql_tgt_t), UM_SLEEP);
1509 	link = (ql_link_t *)mdb_alloc(sizeof (ql_link_t), UM_SLEEP);
1510 
1511 	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
1512 
1513 		if (dev[index].first == NULL) {
1514 			continue;
1515 		}
1516 
1517 		if (mdb_vread(link, sizeof (ql_link_t),
1518 		    (uintptr_t)dev[index].first) == -1) {
1519 			mdb_warn("failed to read ql_link_t at %p",
1520 			    dev[index].first);
1521 			break;
1522 		}
1523 
1524 		while (link != NULL) {
1525 			if (mdb_vread(tq, sizeof (ql_tgt_t),
1526 			    (uintptr_t)(link->base_address)) == -1) {
1527 				mdb_warn("failed to read ql_tgt at %p",
1528 				    link->base_address);
1529 				break;
1530 			}
1531 
1532 			mdb_printf("tgt queue base addr = %llx\n",
1533 			    link->base_address);
1534 
1535 			mdb_printf("\ntgt queue flags: (%xh)\n", tq->flags);
1536 			ql_dump_flags((uint64_t)tq->flags, qltgt_flags);
1537 
1538 			mdb_printf("\ntgt queue:\n");
1539 
1540 			(void) ql_doprint((uintptr_t)link->base_address,
1541 			    "struct ql_target");
1542 
1543 			mdb_printf("\n");
1544 
1545 			if (get_next_link(link) != DCMD_OK) {
1546 				break;
1547 			}
1548 		}
1549 	}
1550 
1551 	mdb_free(ha, sizeof (ql_adapter_state_t));
1552 	mdb_free(tq, sizeof (ql_tgt_t));
1553 	mdb_free(link, sizeof (ql_link_t));
1554 	mdb_free(dev, sizeof (ql_head_t)*DEVICE_HEAD_LIST_SIZE);
1555 
1556 	return (DCMD_OK);
1557 }
1558 
1559 /*
1560  * ql_triggerdump_dcmd
1561  *	Triggers the driver to take a firmware dump
1562  *
1563  * Input:
1564  *	addr  = User supplied address (optional)
1565  *	flags = mdb flags.
1566  *	argc  = Number of user supplied args.
1567  *	argv  = Arg array (instance #, optional).
1568  *
1569  * Returns:
1570  *	DCMD_OK or DCMD_ERR
1571  *
1572  * Context:
1573  *	User context.
1574  *
1575  */
1576 
1577 #if 0
1578 
1579 /*ARGSUSED*/
1580 static int
1581 qlc_triggerdump_dcmd(uintptr_t addr, uint_t flags, int argc,
1582     const mdb_arg_t *argv)
1583 {
1584 	ql_adapter_state_t	*qlstate;
1585 	uintptr_t		hbaptr = NULL;
1586 	ql_head_t		ql_hba;
1587 	uint32_t		qlsize = sizeof (ql_adapter_state_t);
1588 	int			mdbs;
1589 
1590 	if ((mdbs = mdb_get_state()) == MDB_STATE_DEAD) {
1591 		mdb_warn("Cannot change core file data (state=%xh)\n", mdbs);
1592 		return (DCMD_OK);
1593 	}
1594 
1595 	if ((qlstate = (ql_adapter_state_t *)mdb_alloc(qlsize,
1596 	    UM_SLEEP)) == NULL) {
1597 		mdb_warn("Unable to allocate memory for ql_adapter_state\n");
1598 		return (DCMD_OK);
1599 	}
1600 
1601 	if (addr == NULL) {
1602 		char		*tptr;
1603 		uint32_t	instance;
1604 
1605 		if (argc == 0) {
1606 			mdb_warn("must specify either the ha addr or "
1607 			    "the instance number\n");
1608 			mdb_free(qlstate, qlsize);
1609 			return (DCMD_OK);
1610 		}
1611 
1612 		/*
1613 		 * find the specified instance in the ha list
1614 		 */
1615 
1616 		instance = (uint32_t)strtol(argv[1].a_un.a_str, &tptr, 16);
1617 		if (tptr == argv[1].a_un.a_str) {
1618 			mdb_printf("instance # is illegal: '%s'\n",
1619 			    argv[1].a_un.a_str);
1620 			mdb_free(qlstate, qlsize);
1621 			return (DCMD_OK);
1622 		}
1623 
1624 		if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
1625 			mdb_warn("failed to read ql_hba structure");
1626 			mdb_free(qlstate, qlsize);
1627 			return (DCMD_ERR);
1628 		}
1629 
1630 		if (&ql_hba == NULL) {
1631 			mdb_warn("failed to read ql_hba structure - "
1632 			    "is qlc loaded?");
1633 			mdb_free(qlstate, qlsize);
1634 			return (DCMD_ERR);
1635 		}
1636 
1637 		hbaptr = (uintptr_t)ql_hba.first;
1638 		while (hbaptr != NULL) {
1639 
1640 			if (mdb_vread(qlstate, qlsize, hbaptr) == -1) {
1641 				mdb_free(qlstate, qlsize);
1642 				mdb_warn("failed to read "
1643 				    "ql_adapter_state at %p", hbaptr);
1644 				return (DCMD_OK);
1645 			}
1646 
1647 			if (qlstate->instance == instance) {
1648 				break;
1649 			}
1650 
1651 			hbaptr = (uintptr_t)qlstate->hba.next;
1652 		}
1653 	} else {
1654 
1655 		/*
1656 		 * verify the addr specified
1657 		 */
1658 
1659 		if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
1660 			mdb_warn("failed to read ql_hba structure");
1661 			mdb_free(qlstate, qlsize);
1662 			return (DCMD_ERR);
1663 		}
1664 
1665 		if (&ql_hba == NULL) {
1666 			mdb_warn("failed to read ql_hba structure - "
1667 			    "is qlc loaded?");
1668 			mdb_free(qlstate, qlsize);
1669 			return (DCMD_ERR);
1670 		}
1671 
1672 		hbaptr = (uintptr_t)ql_hba.first;
1673 		while (hbaptr != NULL) {
1674 
1675 			if (mdb_vread(qlstate, qlsize, hbaptr) == -1) {
1676 				mdb_free(qlstate, qlsize);
1677 				mdb_warn("failed to read "
1678 				    "ql_adapter_state at %p", hbaptr);
1679 				return (DCMD_OK);
1680 			}
1681 
1682 			if (hbaptr == addr) {
1683 				break;
1684 			}
1685 
1686 			hbaptr = (uintptr_t)qlstate->hba.next;
1687 		}
1688 	}
1689 
1690 	if (hbaptr == NULL) {
1691 		mdb_free(qlstate, qlsize);
1692 		if (argc == 0) {
1693 			mdb_warn("addr specified is not in the hba list\n");
1694 		} else {
1695 			mdb_warn("instance specified does not exist\n");
1696 		}
1697 		return (DCMD_OK);
1698 	}
1699 
1700 	if (((qlstate->ql_dump_state & QL_DUMP_VALID) != 0) ||
1701 	    (qlstate->ql_dump_ptr != NULL)) {
1702 		mdb_warn("instance %d already has a valid dump\n",
1703 		    qlstate->instance);
1704 		mdb_free(qlstate, qlsize);
1705 		return (DCMD_OK);
1706 	}
1707 
1708 
1709 }
1710 #endif
1711 
1712 /*
1713  * ql_getdump_dcmd
1714  *	prints out the firmware dump buffer
1715  *
1716  * Input:
1717  *	addr  = User supplied address. (NB: must be an ha)
1718  *	flags = mdb flags.
1719  *	argc  = Number of user supplied args.
1720  *	argv  = Arg array.
1721  *
1722  * Returns:
1723  *	DCMD_OK or DCMD_ERR
1724  *
1725  * Context:
1726  *	User context.
1727  *
1728  */
1729 static int
1730 qlc_getdump_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1731 {
1732 	ql_adapter_state_t	*ha;
1733 	ql_head_t		ql_hba;
1734 	uintptr_t		hbaptr = NULL;
1735 	int			verbose = 0;
1736 
1737 	if ((!(flags & DCMD_ADDRSPEC)) || addr == NULL) {
1738 		mdb_warn("ql_adapter_state structure addr is required");
1739 		return (DCMD_USAGE);
1740 	}
1741 
1742 	if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose) !=
1743 	    argc) {
1744 		return (DCMD_USAGE);
1745 	}
1746 
1747 	/*
1748 	 * Get the adapter state struct which was passed
1749 	 */
1750 	if ((ha = (ql_adapter_state_t *)mdb_alloc(sizeof (ql_adapter_state_t),
1751 	    UM_SLEEP)) == NULL) {
1752 		mdb_warn("failed to allocate memory for ql_adapter_state\n");
1753 		return (DCMD_OK);
1754 	}
1755 
1756 	/*
1757 	 * show user which instances have valid f/w dumps available if
1758 	 * user has specified verbose option
1759 	 */
1760 	if (mdb_readvar(&ql_hba, "ql_hba") == -1) {
1761 		mdb_warn("failed to read ql_hba structure");
1762 	} else if (&ql_hba == NULL) {
1763 		mdb_warn("failed to read ql_hba structure -- is qlc loaded?");
1764 	} else if (verbose) {
1765 		hbaptr = (uintptr_t)ql_hba.first;
1766 		while (hbaptr != NULL) {
1767 
1768 			if (mdb_vread(ha, sizeof (ql_adapter_state_t),
1769 			    hbaptr) == -1) {
1770 				mdb_free(ha, sizeof (ql_adapter_state_t));
1771 				mdb_warn("failed read ql_adapter_state at %p",
1772 				    hbaptr);
1773 				return (DCMD_OK);
1774 			}
1775 
1776 			mdb_printf("instance %d:\n", ha->instance);
1777 			(void) mdb_inc_indent((ulong_t)4);
1778 
1779 			if (ha->ql_dump_state == 0) {
1780 				mdb_printf("no dump flags\n");
1781 			} else {
1782 				ql_dump_flags((uint64_t)ha->ql_dump_state,
1783 				    qldump_flags);
1784 			}
1785 
1786 			if (ha->ql_dump_ptr == NULL) {
1787 				mdb_printf("no dump address\n");
1788 			} else {
1789 				mdb_printf("dump address is: %p\n",
1790 				    ha->ql_dump_ptr);
1791 			}
1792 
1793 			(void) mdb_dec_indent((ulong_t)4);
1794 
1795 			hbaptr = (uintptr_t)ha->hba.next;
1796 		}
1797 		mdb_printf("\n");
1798 	}
1799 
1800 	if (mdb_vread(ha, sizeof (ql_adapter_state_t), addr) == -1) {
1801 		mdb_warn("failed to read ql_adapter_state at %p", addr);
1802 		mdb_free(ha, sizeof (ql_adapter_state_t));
1803 		return (DCMD_OK);
1804 	}
1805 
1806 	/*
1807 	 * If its not a valid dump or there's not a f/w dump binary (???)
1808 	 * then bail out
1809 	 */
1810 	if (((ha->ql_dump_state & QL_DUMP_VALID) == 0) ||
1811 	    (ha->ql_dump_ptr == NULL)) {
1812 		mdb_warn("dump does not exist for instance %d (%x, %p)\n",
1813 		    ha->instance, ha->ql_dump_state, ha->ql_dump_ptr);
1814 		mdb_free(ha, sizeof (ql_adapter_state_t));
1815 		return (DCMD_OK);
1816 	}
1817 
1818 	if (CFG_IST(ha, CFG_CTRL_2422)) {
1819 		(void) ql_24xx_dump_dcmd(ha, flags, argc, argv);
1820 	} else if (CFG_IST(ha, CFG_CTRL_25XX))  {
1821 		(void) ql_25xx_dump_dcmd(ha, flags, argc, argv);
1822 	} else {
1823 		(void) ql_23xx_dump_dcmd(ha, flags, argc, argv);
1824 	}
1825 
1826 	mdb_free(ha, sizeof (ql_adapter_state_t));
1827 
1828 	return (DCMD_OK);
1829 }
1830 
1831 /*
1832  * ql_23xx_dump_dcmd
1833  *	prints out a firmware dump buffer
1834  *
1835  * Input:
1836  *	addr  = User supplied address. (NB: nust be an ha)
1837  *	flags = mdb flags.
1838  *	argc  = Number of user supplied args.
1839  *	argv  = Arg array.
1840  *
1841  * Returns:
1842  *	DCMD_OK or DCMD_ERR
1843  *
1844  * Context:
1845  *	User context.
1846  *
1847  */
1848 /*ARGSUSED*/
1849 static int
1850 ql_23xx_dump_dcmd(ql_adapter_state_t *ha, uint_t flags, int argc,
1851     const mdb_arg_t *argv)
1852 {
1853 	ql_fw_dump_t	*fw;
1854 	uint32_t	cnt = 0;
1855 	int		mbox_cnt;
1856 
1857 	fw = (ql_fw_dump_t *)mdb_alloc(ha->ql_dump_size, UM_SLEEP);
1858 
1859 	if (mdb_vread(fw, ha->ql_dump_size,
1860 	    (uintptr_t)ha->ql_dump_ptr) == -1) {
1861 		mdb_warn("failed to read ql_dump_ptr (no f/w dump active?)");
1862 		mdb_free(fw, ha->ql_dump_size);
1863 		return (DCMD_OK);
1864 	}
1865 
1866 	if (ha->cfg_flags & CFG_CTRL_2300) {
1867 		mdb_printf("\nISP 2300IP ");
1868 	} else if (ha->cfg_flags & CFG_CTRL_6322) {
1869 		mdb_printf("\nISP 6322FLX ");
1870 	} else {
1871 		mdb_printf("\nISP 2200IP ");
1872 	}
1873 
1874 	mdb_printf("Firmware Version %d.%d.%d\n",
1875 	    ha->fw_major_version, ha->fw_minor_version,
1876 	    ha->fw_subminor_version);
1877 
1878 	mdb_printf("\nPBIU Registers:");
1879 	for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) {
1880 		if (cnt % 8 == 0) {
1881 			mdb_printf("\n");
1882 		}
1883 		mdb_printf("%04x  ", fw->pbiu_reg[cnt]);
1884 	}
1885 
1886 	if (ha->cfg_flags & (CFG_CTRL_2300 | CFG_CTRL_6322)) {
1887 		mdb_printf("\n\nReqQ-RspQ-Risc2Host Status registers:");
1888 		for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) {
1889 			if (cnt % 8 == 0) {
1890 				mdb_printf("\n");
1891 			}
1892 			mdb_printf("%04x  ", fw->risc_host_reg[cnt]);
1893 		}
1894 	}
1895 
1896 	mdb_printf("\n\nMailbox Registers:");
1897 	mbox_cnt = (ha->cfg_flags & (CFG_CTRL_2300 | CFG_CTRL_6322)) ? 16 : 8;
1898 	for (cnt = 0; cnt < mbox_cnt; cnt++) {
1899 		if (cnt % 8 == 0) {
1900 			mdb_printf("\n");
1901 		}
1902 		mdb_printf("%04x  ", fw->mailbox_reg[cnt]);
1903 	}
1904 
1905 	if (ha->cfg_flags & (CFG_CTRL_2300 | CFG_CTRL_6322)) {
1906 		mdb_printf("\n\nAuto Request Response DMA Registers:");
1907 		for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) {
1908 			if (cnt % 8 == 0) {
1909 				mdb_printf("\n");
1910 			}
1911 			mdb_printf("%04x  ", fw->resp_dma_reg[cnt]);
1912 		}
1913 	}
1914 
1915 	mdb_printf("\n\nDMA Registers:");
1916 	for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) {
1917 		if (cnt % 8 == 0) {
1918 			mdb_printf("\n");
1919 		}
1920 		mdb_printf("%04x  ", fw->dma_reg[cnt]);
1921 	}
1922 
1923 	mdb_printf("\n\nRISC Hardware Registers:");
1924 	for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) {
1925 		if (cnt % 8 == 0) {
1926 			mdb_printf("\n");
1927 		}
1928 		mdb_printf("%04x  ", fw->risc_hdw_reg[cnt]);
1929 	}
1930 
1931 	mdb_printf("\n\nRISC GP0 Registers:");
1932 	for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) {
1933 		if (cnt % 8 == 0) {
1934 			mdb_printf("\n");
1935 		}
1936 		mdb_printf("%04x  ", fw->risc_gp0_reg[cnt]);
1937 	}
1938 
1939 	mdb_printf("\n\nRISC GP1 Registers:");
1940 	for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) {
1941 		if (cnt % 8 == 0) {
1942 			mdb_printf("\n");
1943 		}
1944 		mdb_printf("%04x  ", fw->risc_gp1_reg[cnt]);
1945 	}
1946 
1947 	mdb_printf("\n\nRISC GP2 Registers:");
1948 	for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) {
1949 		if (cnt % 8 == 0) {
1950 			mdb_printf("\n");
1951 		}
1952 		mdb_printf("%04x  ", fw->risc_gp2_reg[cnt]);
1953 	}
1954 
1955 	mdb_printf("\n\nRISC GP3 Registers:");
1956 	for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) {
1957 		if (cnt % 8 == 0) {
1958 			mdb_printf("\n");
1959 		}
1960 		mdb_printf("%04x  ", fw->risc_gp3_reg[cnt]);
1961 	}
1962 
1963 	mdb_printf("\n\nRISC GP4 Registers:");
1964 	for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) {
1965 		if (cnt % 8 == 0) {
1966 			mdb_printf("\n");
1967 		}
1968 		mdb_printf("%04x  ", fw->risc_gp4_reg[cnt]);
1969 	}
1970 
1971 	mdb_printf("\n\nRISC GP5 Registers:");
1972 	for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) {
1973 		if (cnt % 8 == 0) {
1974 			mdb_printf("\n");
1975 		}
1976 		mdb_printf("%04x  ", fw->risc_gp5_reg[cnt]);
1977 	}
1978 
1979 	mdb_printf("\n\nRISC GP6 Registers:");
1980 	for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) {
1981 		if (cnt % 8 == 0) {
1982 			mdb_printf("\n");
1983 		}
1984 		mdb_printf("%04x  ", fw->risc_gp6_reg[cnt]);
1985 	}
1986 
1987 	mdb_printf("\n\nRISC GP7 Registers:");
1988 	for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) {
1989 		if (cnt % 8 == 0) {
1990 			mdb_printf("\n");
1991 		}
1992 		mdb_printf("%04x  ", fw->risc_gp7_reg[cnt]);
1993 	}
1994 
1995 	mdb_printf("\n\nFrame Buffer Hardware Registers:");
1996 	for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) {
1997 		if ((cnt == 16) &&
1998 		    ((ha->cfg_flags & (CFG_CTRL_2300 | CFG_CTRL_6322)) == 0)) {
1999 			break;
2000 		}
2001 		if (cnt % 8 == 0) {
2002 			mdb_printf("\n");
2003 		}
2004 		mdb_printf("%04x  ", fw->frame_buf_hdw_reg[cnt]);
2005 	}
2006 
2007 	mdb_printf("\n\nFPM B0 Registers:");
2008 	for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) {
2009 		if (cnt % 8 == 0) {
2010 			mdb_printf("\n");
2011 		}
2012 		mdb_printf("%04x  ", fw->fpm_b0_reg[cnt]);
2013 	}
2014 
2015 	mdb_printf("\n\nFPM B1 Registers:");
2016 	for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) {
2017 		if (cnt % 8 == 0) {
2018 			mdb_printf("\n");
2019 		}
2020 		mdb_printf("%04x  ", fw->fpm_b1_reg[cnt]);
2021 	}
2022 
2023 	if (ha->cfg_flags & (CFG_CTRL_2300 | CFG_CTRL_6322)) {
2024 		mdb_printf("\n\nCode RAM Dump:");
2025 		for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) {
2026 			if (cnt % 8 == 0) {
2027 				mdb_printf("\n%05x: ", cnt + 0x0800);
2028 			}
2029 			mdb_printf("%04x  ", fw->risc_ram[cnt]);
2030 		}
2031 
2032 		mdb_printf("\n\nStack RAM Dump:");
2033 		for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) {
2034 			if (cnt % 8 == 0) {
2035 				mdb_printf("\n%05x: ", cnt + 0x010000);
2036 			}
2037 			mdb_printf("%04x  ", fw->stack_ram[cnt]);
2038 		}
2039 
2040 		mdb_printf("\n\nData RAM Dump:");
2041 		for (cnt = 0; cnt < sizeof (fw->data_ram) / 2; cnt++) {
2042 			if (cnt % 8 == 0) {
2043 				mdb_printf("\n%05x: ", cnt + 0x010800);
2044 			}
2045 			mdb_printf("%04x  ", fw->data_ram[cnt]);
2046 		}
2047 
2048 		mdb_printf("\n\n[<==END] ISP Debug Dump.\n");
2049 
2050 		mdb_printf("\n\nRequest Queue");
2051 
2052 		for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
2053 			if (cnt % 8 == 0) {
2054 				mdb_printf("\n%08x: ", cnt);
2055 			}
2056 			mdb_printf("%08x ", fw->req_q[cnt]);
2057 		}
2058 
2059 		mdb_printf("\n\nResponse Queue");
2060 
2061 		for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
2062 			if (cnt % 8 == 0) {
2063 				mdb_printf("\n%08x: ", cnt);
2064 			}
2065 			mdb_printf("%08x ", fw->rsp_q[cnt]);
2066 		}
2067 
2068 		mdb_printf("\n");
2069 
2070 	} else {
2071 		mdb_printf("\n\nRISC SRAM:");
2072 		for (cnt = 0; cnt < 0xf000; cnt++) {
2073 			if (cnt % 8 == 0) {
2074 				mdb_printf("\n%04x: ", cnt + 0x1000);
2075 			}
2076 			mdb_printf("%04x  ", fw->risc_ram[cnt]);
2077 		}
2078 	}
2079 
2080 	mdb_free(fw, ha->ql_dump_size);
2081 
2082 	return (DCMD_OK);
2083 }
2084 
2085 /*
2086  * ql_24xx_dump_dcmd
2087  *	prints out a firmware dump buffer
2088  *
2089  * Input:
2090  *	addr  = User supplied address. (NB: nust be an ha)
2091  *	flags = mdb flags.
2092  *	argc  = Number of user supplied args.
2093  *	argv  = Arg array.
2094  *
2095  * Returns:
2096  *	DCMD_OK or DCMD_ERR
2097  *
2098  * Context:
2099  *	User context.
2100  *
2101  */
2102 /*ARGSUSED*/
2103 static int
2104 ql_24xx_dump_dcmd(ql_adapter_state_t *ha, uint_t flags, int argc,
2105     const mdb_arg_t *argv)
2106 {
2107 	ql_24xx_fw_dump_t	*fw;
2108 	uint32_t		cnt = 0;
2109 
2110 	fw = (ql_24xx_fw_dump_t *)mdb_alloc(ha->ql_dump_size, UM_SLEEP);
2111 
2112 	if (mdb_vread(fw, ha->ql_dump_size,
2113 	    (uintptr_t)ha->ql_dump_ptr) == -1) {
2114 		mdb_warn("failed to read ql_dump_ptr (no f/w dump active?)");
2115 		mdb_free(fw, ha->ql_dump_size);
2116 		return (DCMD_OK);
2117 	}
2118 
2119 	mdb_printf("ISP FW Version %d.%02d.%02d Attributes %X\n",
2120 	    ha->fw_major_version, ha->fw_minor_version,
2121 	    ha->fw_subminor_version, ha->fw_attributes);
2122 
2123 	mdb_printf("\nHCCR Register\n%08x\n", fw->hccr);
2124 
2125 	mdb_printf("\nHost Interface Registers");
2126 	for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
2127 		if (cnt % 8 == 0) {
2128 			mdb_printf("\n");
2129 		}
2130 		mdb_printf("%08x ", fw->host_reg[cnt]);
2131 	}
2132 
2133 	mdb_printf("\n\nMailbox Registers");
2134 	for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
2135 		if (cnt % 16 == 0) {
2136 			mdb_printf("\n");
2137 		}
2138 		mdb_printf("%04x ", fw->mailbox_reg[cnt]);
2139 	}
2140 
2141 	mdb_printf("\n\nXSEQ GP Registers");
2142 	for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
2143 		if (cnt % 8 == 0) {
2144 			mdb_printf("\n");
2145 		}
2146 		mdb_printf("%08x ", fw->xseq_gp_reg[cnt]);
2147 	}
2148 
2149 	mdb_printf("\n\nXSEQ-0 Registers");
2150 	for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
2151 		if (cnt % 8 == 0) {
2152 			mdb_printf("\n");
2153 		}
2154 		mdb_printf("%08x ", fw->xseq_0_reg[cnt]);
2155 	}
2156 
2157 	mdb_printf("\n\nXSEQ-1 Registers");
2158 	for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
2159 		if (cnt % 8 == 0) {
2160 			mdb_printf("\n");
2161 		}
2162 		mdb_printf("%08x ", fw->xseq_1_reg[cnt]);
2163 	}
2164 
2165 	mdb_printf("\n\nRSEQ GP Registers");
2166 	for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
2167 		if (cnt % 8 == 0) {
2168 			mdb_printf("\n");
2169 		}
2170 		mdb_printf("%08x ", fw->rseq_gp_reg[cnt]);
2171 	}
2172 
2173 	mdb_printf("\n\nRSEQ-0 Registers");
2174 	for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
2175 		if (cnt % 8 == 0) {
2176 			mdb_printf("\n");
2177 		}
2178 		mdb_printf("%08x ", fw->rseq_0_reg[cnt]);
2179 	}
2180 
2181 	mdb_printf("\n\nRSEQ-1 Registers");
2182 	for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
2183 		if (cnt % 8 == 0) {
2184 			mdb_printf("\n");
2185 		}
2186 		mdb_printf("%08x ", fw->rseq_1_reg[cnt]);
2187 	}
2188 
2189 	mdb_printf("\n\nRSEQ-2 Registers");
2190 	for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
2191 		if (cnt % 8 == 0) {
2192 			mdb_printf("\n");
2193 		}
2194 		mdb_printf("%08x ", fw->rseq_2_reg[cnt]);
2195 	}
2196 
2197 	mdb_printf("\n\nCommand DMA Registers");
2198 	for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
2199 		if (cnt % 8 == 0) {
2200 			mdb_printf("\n");
2201 		}
2202 		mdb_printf("%08x ", fw->cmd_dma_reg[cnt]);
2203 	}
2204 
2205 	mdb_printf("\n\nRequest0 Queue DMA Channel Registers");
2206 	for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
2207 		if (cnt % 8 == 0) {
2208 			mdb_printf("\n");
2209 		}
2210 		mdb_printf("%08x ", fw->req0_dma_reg[cnt]);
2211 	}
2212 
2213 	mdb_printf("\n\nResponse0 Queue DMA Channel Registers");
2214 	for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
2215 		if (cnt % 8 == 0) {
2216 			mdb_printf("\n");
2217 		}
2218 		mdb_printf("%08x ", fw->resp0_dma_reg[cnt]);
2219 	}
2220 
2221 	mdb_printf("\n\nRequest1 Queue DMA Channel Registers");
2222 	for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
2223 		if (cnt % 8 == 0) {
2224 			mdb_printf("\n");
2225 		}
2226 		mdb_printf("%08x ", fw->req1_dma_reg[cnt]);
2227 	}
2228 
2229 	mdb_printf("\n\nXMT0 Data DMA Registers");
2230 	for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
2231 		if (cnt % 8 == 0) {
2232 			mdb_printf("\n");
2233 		}
2234 		mdb_printf("%08x ", fw->xmt0_dma_reg[cnt]);
2235 	}
2236 
2237 	mdb_printf("\n\nXMT1 Data DMA Registers");
2238 	for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
2239 		if (cnt % 8 == 0) {
2240 			mdb_printf("\n");
2241 		}
2242 		mdb_printf("%08x ", fw->xmt1_dma_reg[cnt]);
2243 	}
2244 
2245 	mdb_printf("\n\nXMT2 Data DMA Registers");
2246 	for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
2247 		if (cnt % 8 == 0) {
2248 			mdb_printf("\n");
2249 		}
2250 		mdb_printf("%08x ", fw->xmt2_dma_reg[cnt]);
2251 	}
2252 
2253 	mdb_printf("\n\nXMT3 Data DMA Registers");
2254 	for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
2255 		if (cnt % 8 == 0) {
2256 			mdb_printf("\n");
2257 		}
2258 		mdb_printf("%08x ", fw->xmt3_dma_reg[cnt]);
2259 	}
2260 
2261 	mdb_printf("\n\nXMT4 Data DMA Registers");
2262 	for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
2263 		if (cnt % 8 == 0) {
2264 			mdb_printf("\n");
2265 		}
2266 		mdb_printf("%08x ", fw->xmt4_dma_reg[cnt]);
2267 	}
2268 
2269 	mdb_printf("\n\nXMT Data DMA Common Registers");
2270 	for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
2271 		if (cnt % 8 == 0) {
2272 			mdb_printf("\n");
2273 		}
2274 		mdb_printf("%08x ", fw->xmt_data_dma_reg[cnt]);
2275 	}
2276 
2277 	mdb_printf("\n\nRCV Thread 0 Data DMA Registers");
2278 	for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
2279 		if (cnt % 8 == 0) {
2280 			mdb_printf("\n");
2281 		}
2282 		mdb_printf("%08x ", fw->rcvt0_data_dma_reg[cnt]);
2283 	}
2284 
2285 	mdb_printf("\n\nRCV Thread 1 Data DMA Registers");
2286 	for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
2287 		if (cnt % 8 == 0) {
2288 			mdb_printf("\n");
2289 		}
2290 		mdb_printf("%08x ", fw->rcvt1_data_dma_reg[cnt]);
2291 	}
2292 
2293 	mdb_printf("\n\nRISC GP Registers");
2294 	for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
2295 		if (cnt % 8 == 0) {
2296 			mdb_printf("\n");
2297 		}
2298 		mdb_printf("%08x ", fw->risc_gp_reg[cnt]);
2299 	}
2300 
2301 	mdb_printf("\n\nShadow Registers");
2302 	for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
2303 		if (cnt % 8 == 0) {
2304 			mdb_printf("\n");
2305 		}
2306 		mdb_printf("%08x ", fw->shadow_reg[cnt]);
2307 	}
2308 
2309 	mdb_printf("\n\nLMC Registers");
2310 	for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
2311 		if (cnt % 8 == 0) {
2312 			mdb_printf("\n");
2313 		}
2314 		mdb_printf("%08x ", fw->lmc_reg[cnt]);
2315 	}
2316 
2317 	mdb_printf("\n\nFPM Hardware Registers");
2318 	for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) {
2319 		if (cnt % 8 == 0) {
2320 			mdb_printf("\n");
2321 		}
2322 		mdb_printf("%08x ", fw->fpm_hdw_reg[cnt]);
2323 	}
2324 
2325 	mdb_printf("\n\nFB Hardware Registers");
2326 	for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) {
2327 		if (cnt % 8 == 0) {
2328 			mdb_printf("\n");
2329 		}
2330 		mdb_printf("%08x ", fw->fb_hdw_reg[cnt]);
2331 	}
2332 
2333 	mdb_printf("\n\nCode RAM");
2334 	for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
2335 		if (cnt % 8 == 0) {
2336 			mdb_printf("\n%08x: ", cnt + 0x20000);
2337 		}
2338 		mdb_printf("%08x ", fw->code_ram[cnt]);
2339 	}
2340 
2341 	mdb_printf("\n\nExternal Memory");
2342 	for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
2343 		if (cnt % 8 == 0) {
2344 			mdb_printf("\n%08x: ", cnt + 0x100000);
2345 		}
2346 		mdb_printf("%08x ", fw->ext_mem[cnt]);
2347 	}
2348 
2349 	mdb_printf("\n[<==END] ISP Debug Dump");
2350 
2351 	mdb_printf("\n\nRequest Queue");
2352 
2353 	for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
2354 		if (cnt % 8 == 0) {
2355 			mdb_printf("\n%08x: ", cnt);
2356 		}
2357 		mdb_printf("%08x ", fw->req_q[cnt]);
2358 	}
2359 
2360 	mdb_printf("\n\nResponse Queue");
2361 
2362 	for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
2363 		if (cnt % 8 == 0) {
2364 			mdb_printf("\n%08x: ", cnt);
2365 		}
2366 		mdb_printf("%08x ", fw->rsp_q[cnt]);
2367 	}
2368 
2369 	if ((ha->cfg_flags & CFG_ENABLE_FWEXTTRACE) &&
2370 	    (ha->fwexttracebuf.bp != NULL)) {
2371 		uint32_t cnt_b = 0;
2372 		uint32_t *w32 = ha->fwexttracebuf.bp;
2373 
2374 		mdb_printf("\n\nExtended Trace Buffer Memory");
2375 		/* show data address as a byte address, data as long words */
2376 		for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
2377 			cnt_b = cnt * 4;
2378 			if (cnt_b % 32 == 0) {
2379 				mdb_printf("\n%08x: ", w32 + cnt_b);
2380 			}
2381 			mdb_printf("%08x ", fw->ext_trace_buf[cnt]);
2382 		}
2383 	}
2384 
2385 	if ((ha->cfg_flags & CFG_ENABLE_FWFCETRACE) &&
2386 	    (ha->fwfcetracebuf.bp != NULL)) {
2387 		uint32_t cnt_b = 0;
2388 		uint32_t *w32 = ha->fwfcetracebuf.bp;
2389 
2390 		mdb_printf("\n\nFC Event Trace Buffer Memory");
2391 		/* show data address as a byte address, data as long words */
2392 		for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
2393 			cnt_b = cnt * 4;
2394 			if (cnt_b % 32 == 0) {
2395 				mdb_printf("\n%08x: ", w32 + cnt_b);
2396 			}
2397 			mdb_printf("%08x ", fw->fce_trace_buf[cnt]);
2398 		}
2399 	}
2400 	mdb_free(fw, ha->ql_dump_size);
2401 
2402 	return (DCMD_OK);
2403 }
2404 
2405 /*
2406  * ql_25xx_dump_dcmd
2407  *	prints out a firmware dump buffer
2408  *
2409  * Input:
2410  *	addr  = User supplied address. (NB: nust be an ha)
2411  *	flags = mdb flags.
2412  *	argc  = Number of user supplied args.
2413  *	argv  = Arg array.
2414  *
2415  * Returns:
2416  *	DCMD_OK or DCMD_ERR
2417  *
2418  * Context:
2419  *	User context.
2420  *
2421  */
2422 /*ARGSUSED*/
2423 static int
2424 ql_25xx_dump_dcmd(ql_adapter_state_t *ha, uint_t flags, int argc,
2425     const mdb_arg_t *argv)
2426 {
2427 	ql_25xx_fw_dump_t	*fw;
2428 	uint32_t		cnt = 0;
2429 
2430 	fw = (ql_25xx_fw_dump_t *)mdb_alloc(ha->ql_dump_size, UM_SLEEP);
2431 
2432 	if (mdb_vread(fw, ha->ql_dump_size,
2433 	    (uintptr_t)ha->ql_dump_ptr) == -1) {
2434 		mdb_warn("failed to read ql_dump_ptr (no f/w dump active?)");
2435 		mdb_free(fw, ha->ql_dump_size);
2436 		return (DCMD_OK);
2437 	}
2438 
2439 	mdb_printf("\nISP FW Version %d.%02d.%02d Attributes %X\n",
2440 	    ha->fw_major_version, ha->fw_minor_version,
2441 	    ha->fw_subminor_version, ha->fw_attributes);
2442 
2443 	mdb_printf("\nR2H Register\n%08x\n", fw->r2h_status);
2444 
2445 	mdb_printf("\n\nHostRisc Registers");
2446 	for (cnt = 0; cnt < sizeof (fw->hostrisc_reg) / 4; cnt++) {
2447 		if (cnt % 8 == 0) {
2448 			mdb_printf("\n");
2449 		}
2450 		mdb_printf("%08x ", fw->hostrisc_reg[cnt]);
2451 	}
2452 
2453 	mdb_printf("\n\nPCIe Registers");
2454 	for (cnt = 0; cnt < sizeof (fw->pcie_reg) / 4; cnt++) {
2455 		if (cnt % 8 == 0) {
2456 			mdb_printf("\n");
2457 		}
2458 		mdb_printf("%08x ", fw->pcie_reg[cnt]);
2459 	}
2460 
2461 	mdb_printf("\n\nHost Interface Registers");
2462 	for (cnt = 0; cnt < sizeof (fw->host_reg) / 4; cnt++) {
2463 		if (cnt % 8 == 0) {
2464 			mdb_printf("\n");
2465 		}
2466 		mdb_printf("%08x ", fw->host_reg[cnt]);
2467 	}
2468 
2469 	mdb_printf("\n\nShadow Registers");
2470 	for (cnt = 0; cnt < sizeof (fw->shadow_reg) / 4; cnt++) {
2471 		if (cnt % 8 == 0) {
2472 			mdb_printf("\n");
2473 		}
2474 
2475 		mdb_printf("%08x ", fw->shadow_reg[cnt]);
2476 	}
2477 
2478 	mdb_printf("\n\nMailbox Registers");
2479 	for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {
2480 		if (cnt % 16 == 0) {
2481 			mdb_printf("\n");
2482 		}
2483 		mdb_printf("%04x ", fw->mailbox_reg[cnt]);
2484 	}
2485 
2486 	mdb_printf("\n\nXSEQ GP Registers");
2487 	for (cnt = 0; cnt < sizeof (fw->xseq_gp_reg) / 4; cnt++) {
2488 		if (cnt % 8 == 0) {
2489 			mdb_printf("\n");
2490 		}
2491 		mdb_printf("%08x ", fw->xseq_gp_reg[cnt]);
2492 	}
2493 
2494 	mdb_printf("\n\nXSEQ-0 Registers");
2495 	for (cnt = 0; cnt < sizeof (fw->xseq_0_reg) / 4; cnt++) {
2496 		if (cnt % 8 == 0) {
2497 			mdb_printf("\n");
2498 		}
2499 		mdb_printf("%08x ", fw->xseq_0_reg[cnt]);
2500 	}
2501 
2502 	mdb_printf("\n\nXSEQ-1 Registers");
2503 	for (cnt = 0; cnt < sizeof (fw->xseq_1_reg) / 4; cnt++) {
2504 		if (cnt % 8 == 0) {
2505 			mdb_printf("\n");
2506 		}
2507 		mdb_printf("%08x ", fw->xseq_1_reg[cnt]);
2508 	}
2509 
2510 	mdb_printf("\n\nRSEQ GP Registers");
2511 	for (cnt = 0; cnt < sizeof (fw->rseq_gp_reg) / 4; cnt++) {
2512 		if (cnt % 8 == 0) {
2513 			mdb_printf("\n");
2514 		}
2515 		mdb_printf("%08x ", fw->rseq_gp_reg[cnt]);
2516 	}
2517 
2518 	mdb_printf("\n\nRSEQ-0 Registers");
2519 	for (cnt = 0; cnt < sizeof (fw->rseq_0_reg) / 4; cnt++) {
2520 		if (cnt % 8 == 0) {
2521 			mdb_printf("\n");
2522 		}
2523 		mdb_printf("%08x ", fw->rseq_0_reg[cnt]);
2524 	}
2525 
2526 	mdb_printf("\n\nRSEQ-1 Registers");
2527 	for (cnt = 0; cnt < sizeof (fw->rseq_1_reg) / 4; cnt++) {
2528 		if (cnt % 8 == 0) {
2529 			mdb_printf("\n");
2530 		}
2531 		mdb_printf("%08x ", fw->rseq_1_reg[cnt]);
2532 	}
2533 
2534 	mdb_printf("\n\nRSEQ-2 Registers");
2535 	for (cnt = 0; cnt < sizeof (fw->rseq_2_reg) / 4; cnt++) {
2536 		if (cnt % 8 == 0) {
2537 			mdb_printf("\n");
2538 		}
2539 		mdb_printf("%08x ", fw->rseq_2_reg[cnt]);
2540 	}
2541 
2542 	mdb_printf("\n\nASEQ GP Registers");
2543 	for (cnt = 0; cnt < sizeof (fw->aseq_gp_reg) / 4; cnt++) {
2544 		if (cnt % 8 == 0) {
2545 			mdb_printf("\n");
2546 		}
2547 		mdb_printf("%08x ", fw->aseq_gp_reg[cnt]);
2548 	}
2549 
2550 	mdb_printf("\n\nASEQ-0 GP Registers");
2551 	for (cnt = 0; cnt < sizeof (fw->aseq_0_reg) / 4; cnt++) {
2552 		if (cnt % 8 == 0) {
2553 			mdb_printf("\n");
2554 		}
2555 
2556 		mdb_printf("%08x ", fw->aseq_0_reg[cnt]);
2557 	}
2558 
2559 	mdb_printf("\n\nASEQ-1 GP Registers");
2560 	for (cnt = 0; cnt < sizeof (fw->aseq_1_reg) / 4; cnt++) {
2561 		if (cnt % 8 == 0) {
2562 			mdb_printf("\n");
2563 		}
2564 
2565 		mdb_printf("%08x ", fw->aseq_1_reg[cnt]);
2566 	}
2567 
2568 	mdb_printf("\n\nASEQ-2 GP Registers");
2569 	for (cnt = 0; cnt < sizeof (fw->aseq_2_reg) / 4; cnt++) {
2570 		if (cnt % 8 == 0) {
2571 			mdb_printf("\n");
2572 		}
2573 		mdb_printf("%08x ", fw->aseq_2_reg[cnt]);
2574 	}
2575 
2576 	mdb_printf("\n\nCommand DMA Registers");
2577 	for (cnt = 0; cnt < sizeof (fw->cmd_dma_reg) / 4; cnt++) {
2578 		if (cnt % 8 == 0) {
2579 			mdb_printf("\n");
2580 		}
2581 		mdb_printf("%08x ", fw->cmd_dma_reg[cnt]);
2582 	}
2583 
2584 	mdb_printf("\n\nRequest0 Queue DMA Channel Registers");
2585 	for (cnt = 0; cnt < sizeof (fw->req0_dma_reg) / 4; cnt++) {
2586 		if (cnt % 8 == 0) {
2587 			mdb_printf("\n");
2588 		}
2589 		mdb_printf("%08x ", fw->req0_dma_reg[cnt]);
2590 	}
2591 
2592 	mdb_printf("\n\nResponse0 Queue DMA Channel Registers");
2593 	for (cnt = 0; cnt < sizeof (fw->resp0_dma_reg) / 4; cnt++) {
2594 		if (cnt % 8 == 0) {
2595 			mdb_printf("\n");
2596 		}
2597 		mdb_printf("%08x ", fw->resp0_dma_reg[cnt]);
2598 	}
2599 
2600 	mdb_printf("\n\nRequest1 Queue DMA Channel Registers");
2601 	for (cnt = 0; cnt < sizeof (fw->req1_dma_reg) / 4; cnt++) {
2602 		if (cnt % 8 == 0) {
2603 			mdb_printf("\n");
2604 		}
2605 		mdb_printf("%08x ", fw->req1_dma_reg[cnt]);
2606 	}
2607 
2608 	mdb_printf("\n\nXMT0 Data DMA Registers");
2609 	for (cnt = 0; cnt < sizeof (fw->xmt0_dma_reg) / 4; cnt++) {
2610 		if (cnt % 8 == 0) {
2611 			mdb_printf("\n");
2612 		}
2613 		mdb_printf("%08x ", fw->xmt0_dma_reg[cnt]);
2614 	}
2615 
2616 	mdb_printf("\n\nXMT1 Data DMA Registers");
2617 	for (cnt = 0; cnt < sizeof (fw->xmt1_dma_reg) / 4; cnt++) {
2618 		if (cnt % 8 == 0) {
2619 			mdb_printf("\n");
2620 		}
2621 		mdb_printf("%08x ", fw->xmt1_dma_reg[cnt]);
2622 	}
2623 
2624 	mdb_printf("\n\nXMT2 Data DMA Registers");
2625 	for (cnt = 0; cnt < sizeof (fw->xmt2_dma_reg) / 4; cnt++) {
2626 		if (cnt % 8 == 0) {
2627 			mdb_printf("\n");
2628 		}
2629 		mdb_printf("%08x ", fw->xmt2_dma_reg[cnt]);
2630 	}
2631 
2632 	mdb_printf("\n\nXMT3 Data DMA Registers");
2633 	for (cnt = 0; cnt < sizeof (fw->xmt3_dma_reg) / 4; cnt++) {
2634 		if (cnt % 8 == 0) {
2635 			mdb_printf("\n");
2636 		}
2637 		mdb_printf("%08x ", fw->xmt3_dma_reg[cnt]);
2638 	}
2639 
2640 	mdb_printf("\n\nXMT4 Data DMA Registers");
2641 	for (cnt = 0; cnt < sizeof (fw->xmt4_dma_reg) / 4; cnt++) {
2642 		if (cnt % 8 == 0) {
2643 			mdb_printf("\n");
2644 		}
2645 		mdb_printf("%08x ", fw->xmt4_dma_reg[cnt]);
2646 	}
2647 
2648 	mdb_printf("\n\nXMT Data DMA Common Registers");
2649 	for (cnt = 0; cnt < sizeof (fw->xmt_data_dma_reg) / 4; cnt++) {
2650 		if (cnt % 8 == 0) {
2651 			mdb_printf("\n");
2652 		}
2653 		mdb_printf("%08x ", fw->xmt_data_dma_reg[cnt]);
2654 	}
2655 
2656 	mdb_printf("\n\nRCV Thread 0 Data DMA Registers");
2657 	for (cnt = 0; cnt < sizeof (fw->rcvt0_data_dma_reg) / 4; cnt++) {
2658 		if (cnt % 8 == 0) {
2659 			mdb_printf("\n");
2660 		}
2661 		mdb_printf("%08x ", fw->rcvt0_data_dma_reg[cnt]);
2662 	}
2663 
2664 	mdb_printf("\n\nRCV Thread 1 Data DMA Registers");
2665 	for (cnt = 0; cnt < sizeof (fw->rcvt1_data_dma_reg) / 4; cnt++) {
2666 		if (cnt % 8 == 0) {
2667 			mdb_printf("\n");
2668 		}
2669 		mdb_printf("%08x ", fw->rcvt1_data_dma_reg[cnt]);
2670 	}
2671 
2672 	mdb_printf("\n\nRISC GP Registers");
2673 	for (cnt = 0; cnt < sizeof (fw->risc_gp_reg) / 4; cnt++) {
2674 		if (cnt % 8 == 0) {
2675 			mdb_printf("\n");
2676 		}
2677 		mdb_printf("%08x ", fw->risc_gp_reg[cnt]);
2678 	}
2679 
2680 	mdb_printf("\n\nRISC IO Register\n%08x", fw->risc_io);
2681 
2682 	mdb_printf("\n\nLMC Registers");
2683 	for (cnt = 0; cnt < sizeof (fw->lmc_reg) / 4; cnt++) {
2684 		if (cnt % 8 == 0) {
2685 			mdb_printf("\n");
2686 		}
2687 		mdb_printf("%08x ", fw->lmc_reg[cnt]);
2688 	}
2689 
2690 	mdb_printf("\n\nFPM Hardware Registers");
2691 	for (cnt = 0; cnt < sizeof (fw->fpm_hdw_reg) / 4; cnt++) {
2692 		if (cnt % 8 == 0) {
2693 			mdb_printf("\n");
2694 		}
2695 		mdb_printf("%08x ", fw->fpm_hdw_reg[cnt]);
2696 	}
2697 
2698 	mdb_printf("\n\nFB Hardware Registers");
2699 	for (cnt = 0; cnt < sizeof (fw->fb_hdw_reg) / 4; cnt++) {
2700 		if (cnt % 8 == 0) {
2701 			mdb_printf("\n");
2702 		}
2703 		mdb_printf("%08x ", fw->fb_hdw_reg[cnt]);
2704 	}
2705 
2706 	mdb_printf("\n\nCode RAM");
2707 	for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) {
2708 		if (cnt % 8 == 0) {
2709 			mdb_printf("\n%08x: ", cnt + 0x20000);
2710 		}
2711 		mdb_printf("%08x ", fw->code_ram[cnt]);
2712 	}
2713 
2714 	mdb_printf("\n\nExternal Memory");
2715 	for (cnt = 0; cnt < ha->fw_ext_memory_size / 4; cnt++) {
2716 		if (cnt % 8 == 0) {
2717 			mdb_printf("\n%08x: ", cnt + 0x100000);
2718 		}
2719 		mdb_printf("%08x ", fw->ext_mem[cnt]);
2720 	}
2721 
2722 	mdb_printf("\n[<==END] ISP Debug Dump");
2723 
2724 	mdb_printf("\n\nRequest Queue");
2725 
2726 	for (cnt = 0; cnt < REQUEST_QUEUE_SIZE / 4; cnt++) {
2727 		if (cnt % 8 == 0) {
2728 			mdb_printf("\n%08x: ", cnt);
2729 		}
2730 		mdb_printf("%08x ", fw->req_q[cnt]);
2731 	}
2732 
2733 	mdb_printf("\n\nResponse Queue");
2734 
2735 	for (cnt = 0; cnt < RESPONSE_QUEUE_SIZE / 4; cnt++) {
2736 		if (cnt % 8 == 0) {
2737 			mdb_printf("\n%08x: ", cnt);
2738 		}
2739 		mdb_printf("%08x ", fw->rsp_q[cnt]);
2740 	}
2741 
2742 	if ((ha->cfg_flags & CFG_ENABLE_FWEXTTRACE) &&
2743 	    (ha->fwexttracebuf.bp != NULL)) {
2744 		uint32_t cnt_b = 0;
2745 		uint32_t *w32 = ha->fwexttracebuf.bp;
2746 
2747 		mdb_printf("\n\nExtended Trace Buffer Memory");
2748 		/* show data address as a byte address, data as long words */
2749 		for (cnt = 0; cnt < FWEXTSIZE / 4; cnt++) {
2750 			cnt_b = cnt * 4;
2751 			if (cnt_b % 32 == 0) {
2752 				mdb_printf("\n%08x: ", w32 + cnt_b);
2753 			}
2754 			mdb_printf("%08x ", fw->ext_trace_buf[cnt]);
2755 		}
2756 	}
2757 
2758 	if ((ha->cfg_flags & CFG_ENABLE_FWFCETRACE) &&
2759 	    (ha->fwfcetracebuf.bp != NULL)) {
2760 		uint32_t cnt_b = 0;
2761 		uint32_t *w32 = ha->fwfcetracebuf.bp;
2762 
2763 		mdb_printf("\n\nFC Event Trace Buffer Memory");
2764 		/* show data address as a byte address, data as long words */
2765 		for (cnt = 0; cnt < FWFCESIZE / 4; cnt++) {
2766 			cnt_b = cnt * 4;
2767 			if (cnt_b % 32 == 0) {
2768 				mdb_printf("\n%08x: ", w32 + cnt_b);
2769 			}
2770 			mdb_printf("%08x ", fw->fce_trace_buf[cnt]);
2771 		}
2772 	}
2773 
2774 	mdb_free(fw, ha->ql_dump_size);
2775 
2776 	mdb_printf("\n\nreturn exit\n");
2777 
2778 	return (DCMD_OK);
2779 }
2780 
2781 /*
2782  * ql_gettrace_dcmd
2783  *	prints out the Extended Logging trace buffer
2784  *
2785  * Input:
2786  *	addr  = User supplied address. (NB: must be an ha)
2787  *	flags = mdb flags.
2788  *	argc  = Number of user supplied args.
2789  *	argv  = Arg array.
2790  *
2791  * Returns:
2792  *	DCMD_OK or DCMD_ERR
2793  *
2794  * Context:
2795  *	User context.
2796  *
2797  */
2798 static int
2799 qlc_gettrace_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2800 {
2801 	ql_adapter_state_t	*ha;
2802 	int			verbose = 0;
2803 	int			wrapped = 0;
2804 	char			*trace_start;
2805 	char			*trace_end;
2806 	char			*dump_start = 0;
2807 	char			*trace_next  = 0;
2808 	char			*dump_current  = 0;
2809 	el_trace_desc_t		*trace_desc;
2810 
2811 	if ((!(flags & DCMD_ADDRSPEC)) || addr == NULL) {
2812 		mdb_warn("ql_adapter_state structure addr is required");
2813 		return (DCMD_USAGE);
2814 	}
2815 
2816 	if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose) !=
2817 	    argc) {
2818 		return (DCMD_USAGE);
2819 	}
2820 
2821 	/*
2822 	 * Get the adapter state struct which was passed
2823 	 */
2824 	if ((ha = (ql_adapter_state_t *)mdb_alloc(sizeof (ql_adapter_state_t),
2825 	    UM_SLEEP)) == NULL) {
2826 		mdb_warn("failed to allocate memory for ql_adapter_state\n");
2827 		return (DCMD_OK);
2828 	}
2829 
2830 	if (mdb_vread(ha, sizeof (ql_adapter_state_t), addr) == -1) {
2831 		mdb_warn("failed to read ql_adapter_state at %p", addr);
2832 		mdb_free(ha, sizeof (ql_adapter_state_t));
2833 		return (DCMD_OK);
2834 	}
2835 
2836 	/*
2837 	 * If its not a valid trace descriptor then bail out
2838 	 */
2839 	if (ha->el_trace_desc == NULL) {
2840 		mdb_warn("trace descriptor does not exist for instance %d\n",
2841 		    ha->instance);
2842 		mdb_free(ha, sizeof (ql_adapter_state_t));
2843 		return (DCMD_OK);
2844 	} else {
2845 		trace_desc = (el_trace_desc_t *)
2846 		    mdb_alloc(sizeof (el_trace_desc_t), UM_SLEEP);
2847 		if (mdb_vread(trace_desc, sizeof (el_trace_desc_t),
2848 		    (uintptr_t)ha->el_trace_desc) == -1) {
2849 			mdb_warn("failed to read ql_adapter_state at %p",
2850 			    addr);
2851 			mdb_free(trace_desc, sizeof (el_trace_desc_t));
2852 			mdb_free(ha, sizeof (ql_adapter_state_t));
2853 			return (DCMD_OK);
2854 		}
2855 		if (trace_desc->trace_buffer == NULL) {
2856 			mdb_warn("trace buffer does not exist for "
2857 			    "instance %d\n", ha->instance);
2858 			mdb_free(trace_desc, sizeof (el_trace_desc_t));
2859 			mdb_free(ha, sizeof (ql_adapter_state_t));
2860 			return (DCMD_OK);
2861 		}
2862 	}
2863 
2864 	/* Get the trace buffer */
2865 
2866 	trace_start = (char *)
2867 	    mdb_zalloc(trace_desc->trace_buffer_size, UM_SLEEP);
2868 
2869 	if (mdb_vread(trace_start, trace_desc->trace_buffer_size,
2870 	    (uintptr_t)trace_desc->trace_buffer) == -1) {
2871 		mdb_warn("failed to read trace buffer?)");
2872 		mdb_free(trace_start, trace_desc->trace_buffer_size);
2873 		mdb_free(ha, sizeof (ql_adapter_state_t));
2874 		return (DCMD_OK);
2875 	}
2876 
2877 	/* set the end of the trace buffer. */
2878 	trace_end = trace_start + trace_desc->trace_buffer_size;
2879 
2880 	/* Find the start point of trace. */
2881 	trace_next = trace_start + trace_desc->next;
2882 
2883 	/*
2884 	 * If the buffer has not wrapped next will point at a null so
2885 	 * start is the begining of the buffer.  If next points at a char
2886 	 * then we must traverse the buffer further until a null is detected.
2887 	 * The location after the null will be the beginning of the oldest
2888 	 * whole object in the buffer, which we use as the start.
2889 	 */
2890 
2891 	if ((trace_next + EL_BUFFER_RESERVE) >= trace_end) {
2892 		dump_start = trace_start;
2893 	} else if (*trace_next != NULL) {
2894 		dump_start = trace_next + (strlen(trace_next) + 1);
2895 	} else {
2896 		dump_start = trace_start;
2897 	}
2898 
2899 	dump_current = dump_start;
2900 
2901 	mdb_printf("\nExtended Logging trace buffer @%x, start @%x, "
2902 	    "size=%d\n\n", trace_start, dump_current,
2903 	    trace_desc->trace_buffer_size);
2904 
2905 	/* Don't run off the end, no matter what. */
2906 	while (((uintptr_t)dump_current - (uintptr_t)trace_start) <=
2907 	    (uintptr_t)trace_desc->trace_buffer_size) {
2908 		/* Show it... */
2909 		mdb_printf("%s", dump_current);
2910 		/* Calculate the next and make it the current */
2911 		dump_current += (strlen(dump_current) + 1);
2912 		/* check for wrap */
2913 		if ((dump_current + EL_BUFFER_RESERVE) >= trace_end) {
2914 			mdb_printf("Wraping %x\n", dump_current);
2915 			dump_current = trace_start;
2916 			wrapped = 1;
2917 		} else if (wrapped) {
2918 			/*   Don't go past next. */
2919 			if ((trace_start + trace_desc->next) <= dump_current) {
2920 				mdb_printf("Done %x", dump_current);
2921 				break;
2922 			}
2923 		} else if (*dump_current == NULL) {
2924 			mdb_printf("Done %x(null)", dump_current);
2925 			break;
2926 		}
2927 	}
2928 
2929 	mdb_free(ha, sizeof (ql_adapter_state_t));
2930 	mdb_free(trace_start, trace_desc->trace_buffer_size);
2931 	mdb_free(trace_desc, sizeof (el_trace_desc_t));
2932 
2933 	return (DCMD_OK);
2934 }
2935 /*
2936  * ql_doprint
2937  *	ql generic function to call the print dcmd
2938  *
2939  * Input:
2940  *	addr - address to struct
2941  *	prtsting - address to string
2942  *
2943  * Returns:
2944  *	WALK_DONE
2945  *
2946  * Context:
2947  *	User context.
2948  *
2949  */
2950 static int32_t
2951 ql_doprint(uintptr_t addr, int8_t *prtstring)
2952 {
2953 	struct	mdb_arg		printarg;
2954 
2955 	printarg.a_un.a_str = (int8_t *)(mdb_zalloc(strlen(prtstring),
2956 	    UM_SLEEP));
2957 	printarg.a_type = MDB_TYPE_STRING;
2958 	(void) strcpy((int8_t *)(printarg.a_un.a_str), prtstring);
2959 
2960 	if ((mdb_call_dcmd("print", addr, DCMD_ADDRSPEC, 1,
2961 	    &printarg)) == -1) {
2962 		mdb_warn("ql_doprint: failed print dcmd: %s"
2963 		    "at addr: %llxh", prtstring, addr);
2964 	}
2965 
2966 	mdb_free((void *)(printarg.a_un.a_str), strlen(prtstring));
2967 	return (WALK_DONE);
2968 }
2969 
2970 /*
2971  * ql_dump_flags
2972  *	mdb utility to print the flag string
2973  *
2974  * Input:
2975  *	flags - flags to print
2976  *	strings - text to print when flag is set
2977  *
2978  * Returns:
2979  *
2980  *
2981  * Context:
2982  *	User context.
2983  *
2984  */
2985 static void
2986 ql_dump_flags(uint64_t flags, int8_t **strings)
2987 {
2988 	int		i, linel, first = 1;
2989 	uint64_t	mask = 1;
2990 
2991 	linel = 8;
2992 	mdb_printf("\t");
2993 	for (i = 0; i < 64; i++) {
2994 		if (strings[i] == NULL)
2995 			break;
2996 		if (flags & mask) {
2997 			if (!first) {
2998 				mdb_printf(" | ");
2999 			} else {
3000 				first = 0;
3001 			}
3002 			linel += (int32_t)strlen(strings[i]) + 3;
3003 			if (linel > 80) {
3004 				mdb_printf("\n\t");
3005 				linel = (int32_t)strlen(strings[i]) + 1 + 8;
3006 			}
3007 			mdb_printf("%s", strings[i]);
3008 		}
3009 		mask <<= 1;
3010 	}
3011 	mdb_printf("\n");
3012 }
3013 
3014 /*
3015  * MDB module linkage information
3016  *
3017  *
3018  * dcmd structures for the _mdb_init function
3019  */
3020 static const mdb_dcmd_t dcmds[] = {
3021 	{ "qlclinks", NULL, "Prints qlc link information", qlclinks_dcmd },
3022 	{ "qlcosc", NULL, "Prints outstanding cmd info", qlc_osc_dcmd },
3023 	{ "qlcver", NULL, "Prints driver/mdb version", qlcver_dcmd },
3024 	{ "qlc_elog", "[on|off] [<inst #>|all]", "Turns qlc extended logging "
3025 	    "on / off", qlc_el_dcmd },
3026 	{ "qlcstate", ":[-v]", "Prints qlc adapter state information",
3027 	    qlcstate_dcmd },
3028 	{ "qlctgtq", NULL, "Prints qlc target queues", qltgtq_dcmd },
3029 	{ "qlcwdog", NULL, "Prints out watchdog linked list", qlc_wdog_dcmd},
3030 	{ "qlcgetdump", ":[-v]", "Retrieves the ASCII f/w dump",
3031 	    qlc_getdump_dcmd },
3032 	{ "qlcgettrace", ":[-v]", "Retrieves the ASCII Extended Logging trace",
3033 	    qlc_gettrace_dcmd },
3034 	{ NULL }
3035 };
3036 
3037 /*
3038  * walker structures for the _mdb_init function
3039  */
3040 static const mdb_walker_t walkers[] = {
3041 	{ "qlcstates", "walk list of qlc ql_state_t structures",
3042 	    qlstates_walk_init, qlstates_walk_step, qlstates_walk_fini },
3043 	{ "qlcsrbs", "walk list of qlc ql_srb_t strctures",
3044 	    qlsrb_walk_init, qlsrb_walk_step, qlsrb_walk_fini },
3045 	{ "qlclunq", "walk list of qlc ql_lun_t strctures",
3046 	    qllunq_walk_init, qllunq_walk_step, qllunq_walk_fini },
3047 	{ NULL }
3048 };
3049 
3050 static const mdb_modinfo_t ql_mdb_modinfo = {
3051 	MDB_API_VERSION, dcmds, walkers
3052 };
3053 
3054 /*
3055  * Registration function which lists the dcmds and walker structures
3056  */
3057 const mdb_modinfo_t *
3058 _mdb_init(void)
3059 {
3060 	return (&ql_mdb_modinfo);
3061 }
3062