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