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