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