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