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