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