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