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