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