1dce93cd0SAchim Leubner /*-
2*718cf2ccSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*718cf2ccSPedro F. Giffuni  *
4dce93cd0SAchim Leubner  * Copyright (c) 2006-2010 Adaptec, Inc.
5dce93cd0SAchim Leubner  * Copyright (c) 2010-2012 PMC-Sierra, Inc.
6dce93cd0SAchim Leubner  * All rights reserved.
7dce93cd0SAchim Leubner  *
8dce93cd0SAchim Leubner  * Redistribution and use in source and binary forms, with or without
9dce93cd0SAchim Leubner  * modification, are permitted provided that the following conditions
10dce93cd0SAchim Leubner  * are met:
11dce93cd0SAchim Leubner  * 1. Redistributions of source code must retain the above copyright
12dce93cd0SAchim Leubner  *    notice, this list of conditions and the following disclaimer.
13dce93cd0SAchim Leubner  * 2. Redistributions in binary form must reproduce the above copyright
14dce93cd0SAchim Leubner  *    notice, this list of conditions and the following disclaimer in the
15dce93cd0SAchim Leubner  *    documentation and/or other materials provided with the distribution.
16dce93cd0SAchim Leubner  *
17dce93cd0SAchim Leubner  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18dce93cd0SAchim Leubner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19dce93cd0SAchim Leubner  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20dce93cd0SAchim Leubner  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21dce93cd0SAchim Leubner  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22dce93cd0SAchim Leubner  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23dce93cd0SAchim Leubner  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24dce93cd0SAchim Leubner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25dce93cd0SAchim Leubner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26dce93cd0SAchim Leubner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27dce93cd0SAchim Leubner  * SUCH DAMAGE.
28dce93cd0SAchim Leubner  *
29dce93cd0SAchim Leubner  */
30dce93cd0SAchim Leubner 
31dce93cd0SAchim Leubner #include <sys/cdefs.h>
32dce93cd0SAchim Leubner __FBSDID("$FreeBSD$");
33dce93cd0SAchim Leubner 
34dce93cd0SAchim Leubner /*
35dce93cd0SAchim Leubner  * Debugging support.
36dce93cd0SAchim Leubner  */
37dce93cd0SAchim Leubner #include "opt_aacraid.h"
38dce93cd0SAchim Leubner 
39dce93cd0SAchim Leubner #include <sys/param.h>
40dce93cd0SAchim Leubner #include <sys/systm.h>
41dce93cd0SAchim Leubner #include <sys/kernel.h>
42dce93cd0SAchim Leubner #include <sys/conf.h>
43dce93cd0SAchim Leubner 
44dce93cd0SAchim Leubner #include <sys/bus.h>
45dce93cd0SAchim Leubner 
46dce93cd0SAchim Leubner #include <machine/resource.h>
47dce93cd0SAchim Leubner #include <machine/bus.h>
48dce93cd0SAchim Leubner 
49dce93cd0SAchim Leubner #include <dev/aacraid/aacraid_reg.h>
50dce93cd0SAchim Leubner #include <sys/aac_ioctl.h>
51dce93cd0SAchim Leubner #include <dev/aacraid/aacraid_var.h>
52dce93cd0SAchim Leubner #include <sys/param.h>
53dce93cd0SAchim Leubner #include <sys/systm.h>
54dce93cd0SAchim Leubner #include <sys/kernel.h>
55dce93cd0SAchim Leubner #include <sys/conf.h>
56dce93cd0SAchim Leubner 
57dce93cd0SAchim Leubner #include <sys/bus.h>
58dce93cd0SAchim Leubner #include <sys/rman.h>
59dce93cd0SAchim Leubner 
60dce93cd0SAchim Leubner #include <machine/resource.h>
61dce93cd0SAchim Leubner #include <machine/bus.h>
62dce93cd0SAchim Leubner #include <machine/stdarg.h>
63dce93cd0SAchim Leubner 
64dce93cd0SAchim Leubner #include <dev/aacraid/aacraid_debug.h>
65dce93cd0SAchim Leubner 
66dce93cd0SAchim Leubner #ifdef AACRAID_DEBUG
67dce93cd0SAchim Leubner /*
68dce93cd0SAchim Leubner  * Dump the command queue indices
69dce93cd0SAchim Leubner  */
70dce93cd0SAchim Leubner void
aacraid_print_queues(struct aac_softc * sc)71dce93cd0SAchim Leubner aacraid_print_queues(struct aac_softc *sc)
72dce93cd0SAchim Leubner {
73dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "AACQ_FREE      %d/%d\n",
74dce93cd0SAchim Leubner 	    sc->aac_qstat[AACQ_FREE].q_length, sc->aac_qstat[AACQ_FREE].q_max);
75dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "AACQ_READY     %d/%d\n",
76dce93cd0SAchim Leubner 	    sc->aac_qstat[AACQ_READY].q_length,
77dce93cd0SAchim Leubner 	    sc->aac_qstat[AACQ_READY].q_max);
78dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "AACQ_BUSY      %d/%d\n",
79dce93cd0SAchim Leubner 	    sc->aac_qstat[AACQ_BUSY].q_length, sc->aac_qstat[AACQ_BUSY].q_max);
80dce93cd0SAchim Leubner }
81dce93cd0SAchim Leubner 
82dce93cd0SAchim Leubner /*
83dce93cd0SAchim Leubner  * Print a FIB
84dce93cd0SAchim Leubner  */
85dce93cd0SAchim Leubner void
aacraid_print_fib(struct aac_softc * sc,struct aac_fib * fib,const char * caller)86dce93cd0SAchim Leubner aacraid_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
87dce93cd0SAchim Leubner {
88dce93cd0SAchim Leubner 	if (fib == NULL) {
89dce93cd0SAchim Leubner 		device_printf(sc->aac_dev,
90dce93cd0SAchim Leubner 			      "aac_print_fib called with NULL fib\n");
91dce93cd0SAchim Leubner 		return;
92dce93cd0SAchim Leubner 	}
93dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "%s: FIB @ %p\n", caller, fib);
94dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "  XferState %b\n", fib->Header.XferState,
95dce93cd0SAchim Leubner 		      "\20"
96dce93cd0SAchim Leubner 		      "\1HOSTOWNED"
97dce93cd0SAchim Leubner 		      "\2ADAPTEROWNED"
98dce93cd0SAchim Leubner 		      "\3INITIALISED"
99dce93cd0SAchim Leubner 		      "\4EMPTY"
100dce93cd0SAchim Leubner 		      "\5FROMPOOL"
101dce93cd0SAchim Leubner 		      "\6FROMHOST"
102dce93cd0SAchim Leubner 		      "\7FROMADAP"
103dce93cd0SAchim Leubner 		      "\10REXPECTED"
104dce93cd0SAchim Leubner 		      "\11RNOTEXPECTED"
105dce93cd0SAchim Leubner 		      "\12DONEADAP"
106dce93cd0SAchim Leubner 		      "\13DONEHOST"
107dce93cd0SAchim Leubner 		      "\14HIGH"
108dce93cd0SAchim Leubner 		      "\15NORM"
109dce93cd0SAchim Leubner 		      "\16ASYNC"
110dce93cd0SAchim Leubner 		      "\17PAGEFILEIO"
111dce93cd0SAchim Leubner 		      "\20SHUTDOWN"
112dce93cd0SAchim Leubner 		      "\21LAZYWRITE"
113dce93cd0SAchim Leubner 		      "\22ADAPMICROFIB"
114dce93cd0SAchim Leubner 		      "\23BIOSFIB"
115dce93cd0SAchim Leubner 		      "\24FAST_RESPONSE"
116dce93cd0SAchim Leubner 		      "\25APIFIB\n");
117dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "  Command       %d\n", fib->Header.Command);
118dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "  StructType    %d\n",
119dce93cd0SAchim Leubner 		      fib->Header.StructType);
120dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "  Size          %d\n", fib->Header.Size);
121dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "  SenderSize    %d\n",
122dce93cd0SAchim Leubner 		      fib->Header.SenderSize);
123dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "  SenderAddress 0x%x\n",
124dce93cd0SAchim Leubner 		      fib->Header.SenderFibAddress);
125dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "  RcvrAddress   0x%x\n",
126dce93cd0SAchim Leubner 		      fib->Header.u.ReceiverFibAddress);
127dce93cd0SAchim Leubner 	device_printf(sc->aac_dev, "  Handle    0x%x\n",
128dce93cd0SAchim Leubner 		      fib->Header.Handle);
129dce93cd0SAchim Leubner 	switch(fib->Header.Command) {
130dce93cd0SAchim Leubner 	case ContainerCommand:
131dce93cd0SAchim Leubner 	{
132dce93cd0SAchim Leubner 		struct aac_blockread *br;
133dce93cd0SAchim Leubner 		struct aac_blockwrite *bw;
134dce93cd0SAchim Leubner 		struct aac_sg_table *sg;
135dce93cd0SAchim Leubner 		int i;
136dce93cd0SAchim Leubner 
137dce93cd0SAchim Leubner 		br = (struct aac_blockread*)fib->data;
138dce93cd0SAchim Leubner 		bw = (struct aac_blockwrite*)fib->data;
139dce93cd0SAchim Leubner 		sg = NULL;
140dce93cd0SAchim Leubner 
141dce93cd0SAchim Leubner 		if (br->Command == VM_CtBlockRead) {
142dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
143dce93cd0SAchim Leubner 				      "  BlockRead: container %d  0x%x/%d\n",
144dce93cd0SAchim Leubner 				      br->ContainerId, br->BlockNumber,
145dce93cd0SAchim Leubner 				      br->ByteCount);
146dce93cd0SAchim Leubner 			sg = &br->SgMap;
147dce93cd0SAchim Leubner 		}
148dce93cd0SAchim Leubner 		if (bw->Command == VM_CtBlockWrite) {
149dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
150dce93cd0SAchim Leubner 				      "  BlockWrite: container %d  0x%x/%d "
151dce93cd0SAchim Leubner 				      "(%s)\n", bw->ContainerId,
152dce93cd0SAchim Leubner 				      bw->BlockNumber, bw->ByteCount,
153dce93cd0SAchim Leubner 				      bw->Stable == CSTABLE ? "stable" :
154dce93cd0SAchim Leubner 				      "unstable");
155dce93cd0SAchim Leubner 			sg = &bw->SgMap;
156dce93cd0SAchim Leubner 		}
157dce93cd0SAchim Leubner 		if (sg != NULL) {
158dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
159dce93cd0SAchim Leubner 				      "  %d s/g entries\n", sg->SgCount);
160dce93cd0SAchim Leubner 			for (i = 0; i < sg->SgCount; i++)
161dce93cd0SAchim Leubner 				device_printf(sc->aac_dev, "  0x%08x/%d\n",
162dce93cd0SAchim Leubner 					      sg->SgEntry[i].SgAddress,
163dce93cd0SAchim Leubner 					      sg->SgEntry[i].SgByteCount);
164dce93cd0SAchim Leubner 		}
165dce93cd0SAchim Leubner 		break;
166dce93cd0SAchim Leubner 	}
167dce93cd0SAchim Leubner 	default:
168dce93cd0SAchim Leubner 		device_printf(sc->aac_dev, "   %16D\n", fib->data, " ");
169dce93cd0SAchim Leubner 		device_printf(sc->aac_dev, "   %16D\n", fib->data + 16, " ");
170dce93cd0SAchim Leubner 		break;
171dce93cd0SAchim Leubner 	}
172dce93cd0SAchim Leubner }
173dce93cd0SAchim Leubner 
174dce93cd0SAchim Leubner /*
175dce93cd0SAchim Leubner  * Describe an AIF we have received.
176dce93cd0SAchim Leubner  */
177dce93cd0SAchim Leubner void
aacraid_print_aif(struct aac_softc * sc,struct aac_aif_command * aif)178dce93cd0SAchim Leubner aacraid_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
179dce93cd0SAchim Leubner {
180dce93cd0SAchim Leubner 	switch(aif->command) {
181dce93cd0SAchim Leubner 	case AifCmdEventNotify:
182dce93cd0SAchim Leubner 		device_printf(sc->aac_dev, "EventNotify(%d)\n", aif->seqNumber);
183dce93cd0SAchim Leubner 		switch(aif->data.EN.type) {
184dce93cd0SAchim Leubner 		case AifEnGeneric:		/* Generic notification */
185dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(Generic) %.*s\n",
186dce93cd0SAchim Leubner 				  (int)sizeof(aif->data.EN.data.EG),
187dce93cd0SAchim Leubner 				  aif->data.EN.data.EG.text);
188dce93cd0SAchim Leubner 			break;
189dce93cd0SAchim Leubner 		case AifEnTaskComplete:		/* Task has completed */
190dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(TaskComplete)\n");
191dce93cd0SAchim Leubner 			break;
192dce93cd0SAchim Leubner 		case AifEnConfigChange:		/* Adapter configuration change
193dce93cd0SAchim Leubner 						 * occurred */
194dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(ConfigChange)\n");
195dce93cd0SAchim Leubner 			break;
196dce93cd0SAchim Leubner 		case AifEnContainerChange:	/* Adapter specific container
197dce93cd0SAchim Leubner 						 * configuration change */
198dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(ContainerChange) "
199dce93cd0SAchim Leubner 				      "container %d,%d\n",
200dce93cd0SAchim Leubner 				      aif->data.EN.data.ECC.container[0],
201dce93cd0SAchim Leubner 				      aif->data.EN.data.ECC.container[1]);
202dce93cd0SAchim Leubner 			break;
203dce93cd0SAchim Leubner 		case AifEnDeviceFailure:	/* SCSI device failed */
204dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(DeviceFailure) "
205dce93cd0SAchim Leubner 				      "handle %d\n",
206dce93cd0SAchim Leubner 				      aif->data.EN.data.EDF.deviceHandle);
207dce93cd0SAchim Leubner 			break;
208dce93cd0SAchim Leubner 		case AifEnMirrorFailover:	/* Mirror failover started */
209dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(MirrorFailover) "
210dce93cd0SAchim Leubner 				      "container %d failed, "
211dce93cd0SAchim Leubner 				      "migrating from slice %d to %d\n",
212dce93cd0SAchim Leubner 				      aif->data.EN.data.EMF.container,
213dce93cd0SAchim Leubner 				      aif->data.EN.data.EMF.failedSlice,
214dce93cd0SAchim Leubner 				      aif->data.EN.data.EMF.creatingSlice);
215dce93cd0SAchim Leubner 			break;
216dce93cd0SAchim Leubner 		case AifEnContainerEvent:	/* Significant container
217dce93cd0SAchim Leubner 						 * event */
218dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(ContainerEvent) "
219dce93cd0SAchim Leubner 				      "container %d event "
220dce93cd0SAchim Leubner 				      "%d\n", aif->data.EN.data.ECE.container,
221dce93cd0SAchim Leubner 				      aif->data.EN.data.ECE.eventType);
222dce93cd0SAchim Leubner 			break;
223dce93cd0SAchim Leubner 		case AifEnFileSystemChange:	/* File system changed */
224dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(FileSystemChange)\n");
225dce93cd0SAchim Leubner 			break;
226dce93cd0SAchim Leubner 		case AifEnConfigPause:		/* Container pause event */
227dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(ConfigPause)\n");
228dce93cd0SAchim Leubner 			break;
229dce93cd0SAchim Leubner 		case AifEnConfigResume:		/* Container resume event */
230dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(ConfigResume)\n");
231dce93cd0SAchim Leubner 			break;
232dce93cd0SAchim Leubner 		case AifEnFailoverChange:	/* Failover space assignment
233dce93cd0SAchim Leubner 						 * changed */
234dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(FailoverChange)\n");
235dce93cd0SAchim Leubner 			break;
236dce93cd0SAchim Leubner 		case AifEnRAID5RebuildDone:	/* RAID5 rebuild finished */
237dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(RAID5RebuildDone)\n");
238dce93cd0SAchim Leubner 			break;
239dce93cd0SAchim Leubner 		case AifEnEnclosureManagement:	/* Enclosure management event */
240dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(EnclosureManagement) "
241dce93cd0SAchim Leubner 				      "EMPID %d unit %d "
242dce93cd0SAchim Leubner 				      "event %d\n", aif->data.EN.data.EEE.empID,
243dce93cd0SAchim Leubner 				      aif->data.EN.data.EEE.unitID,
244dce93cd0SAchim Leubner 				      aif->data.EN.data.EEE.eventType);
245dce93cd0SAchim Leubner 			break;
246dce93cd0SAchim Leubner 		case AifEnBatteryEvent:		/* Significant NV battery
247dce93cd0SAchim Leubner 						 * event */
248dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(BatteryEvent) %d "
249dce93cd0SAchim Leubner 				      "(state was %d, is %d\n",
250dce93cd0SAchim Leubner 				      aif->data.EN.data.EBE.transition_type,
251dce93cd0SAchim Leubner 				      aif->data.EN.data.EBE.current_state,
252dce93cd0SAchim Leubner 				      aif->data.EN.data.EBE.prior_state);
253dce93cd0SAchim Leubner 			break;
254dce93cd0SAchim Leubner 		case AifEnAddContainer:		/* A new container was
255dce93cd0SAchim Leubner 						 * created. */
256dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(AddContainer)\n");
257dce93cd0SAchim Leubner 			break;
258dce93cd0SAchim Leubner 		case AifEnDeleteContainer:	/* A container was deleted. */
259dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(DeleteContainer)\n");
260dce93cd0SAchim Leubner 			break;
261dce93cd0SAchim Leubner 		case AifEnBatteryNeedsRecond:	/* The battery needs
262dce93cd0SAchim Leubner 						 * reconditioning */
263dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(BatteryNeedsRecond)\n");
264dce93cd0SAchim Leubner 			break;
265dce93cd0SAchim Leubner 		case AifEnClusterEvent:		/* Some cluster event */
266dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
267dce93cd0SAchim Leubner 				      aif->data.EN.data.ECLE.eventType);
268dce93cd0SAchim Leubner 			break;
269453130d9SPedro F. Giffuni 		case AifEnDiskSetEvent:		/* A disk set event occurred. */
270dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(DiskSetEvent) event %d "
271dce93cd0SAchim Leubner 				      "diskset %jd creator %jd\n",
272dce93cd0SAchim Leubner 				      aif->data.EN.data.EDS.eventType,
273dce93cd0SAchim Leubner 				      (intmax_t)aif->data.EN.data.EDS.DsNum,
274dce93cd0SAchim Leubner 				      (intmax_t)aif->data.EN.data.EDS.CreatorId);
275dce93cd0SAchim Leubner 			break;
276dce93cd0SAchim Leubner 		case AifDenMorphComplete: 	/* A morph operation
277dce93cd0SAchim Leubner 						 * completed */
278dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(MorphComplete)\n");
279dce93cd0SAchim Leubner 			break;
280dce93cd0SAchim Leubner 		case AifDenVolumeExtendComplete: /* A volume expand operation
281dce93cd0SAchim Leubner 						  * completed */
282dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(VolumeExtendComplete)\n");
283dce93cd0SAchim Leubner 			break;
284dce93cd0SAchim Leubner 		default:
285dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(%d)\n", aif->data.EN.type);
286dce93cd0SAchim Leubner 			break;
287dce93cd0SAchim Leubner 		}
288dce93cd0SAchim Leubner 		break;
289dce93cd0SAchim Leubner 	case AifCmdJobProgress:
290dce93cd0SAchim Leubner 	{
291dce93cd0SAchim Leubner 		char	*status;
292dce93cd0SAchim Leubner 		switch(aif->data.PR[0].status) {
293dce93cd0SAchim Leubner 		case AifJobStsSuccess:
294dce93cd0SAchim Leubner 			status = "success"; break;
295dce93cd0SAchim Leubner 		case AifJobStsFinished:
296dce93cd0SAchim Leubner 			status = "finished"; break;
297dce93cd0SAchim Leubner 		case AifJobStsAborted:
298dce93cd0SAchim Leubner 			status = "aborted"; break;
299dce93cd0SAchim Leubner 		case AifJobStsFailed:
300dce93cd0SAchim Leubner 			status = "failed"; break;
301dce93cd0SAchim Leubner 		case AifJobStsSuspended:
302dce93cd0SAchim Leubner 			status = "suspended"; break;
303dce93cd0SAchim Leubner 		case AifJobStsRunning:
304dce93cd0SAchim Leubner 			status = "running"; break;
305dce93cd0SAchim Leubner 		default:
306dce93cd0SAchim Leubner 			status = "unknown status"; break;
307dce93cd0SAchim Leubner 		}
308dce93cd0SAchim Leubner 
309dce93cd0SAchim Leubner 		device_printf(sc->aac_dev, "JobProgress (%d) - %s (%d, %d)\n",
310dce93cd0SAchim Leubner 			      aif->seqNumber, status,
311dce93cd0SAchim Leubner 			      aif->data.PR[0].currentTick,
312dce93cd0SAchim Leubner 			      aif->data.PR[0].finalTick);
313dce93cd0SAchim Leubner 		switch(aif->data.PR[0].jd.type) {
314dce93cd0SAchim Leubner 		case AifJobScsiZero:		/* SCSI dev clear operation */
315dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(ScsiZero) handle %d\n",
316dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.scsi_dh);
317dce93cd0SAchim Leubner 			break;
318dce93cd0SAchim Leubner 		case AifJobScsiVerify:		/* SCSI device Verify operation
319dce93cd0SAchim Leubner 						 * NO REPAIR */
320dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(ScsiVerify) handle %d\n",
321dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.scsi_dh);
322dce93cd0SAchim Leubner 			break;
323dce93cd0SAchim Leubner 		case AifJobScsiExercise:	/* SCSI device Exercise
324dce93cd0SAchim Leubner 						 * operation */
325dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(ScsiExercise) handle %d\n",
326dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.scsi_dh);
327dce93cd0SAchim Leubner 			break;
328dce93cd0SAchim Leubner 		case AifJobScsiVerifyRepair:	/* SCSI device Verify operation
329dce93cd0SAchim Leubner 						 * WITH repair */
330dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
331dce93cd0SAchim Leubner 				      "(ScsiVerifyRepair) handle %d\n",
332dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.scsi_dh);
333dce93cd0SAchim Leubner 			break;
334dce93cd0SAchim Leubner 		case AifJobCtrZero:		/* Container clear operation */
335dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
336dce93cd0SAchim Leubner 				      "(ContainerZero) container %d\n",
337dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src);
338dce93cd0SAchim Leubner 			break;
339dce93cd0SAchim Leubner 		case AifJobCtrCopy:		/* Container copy operation */
340dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
341dce93cd0SAchim Leubner 				      "(ContainerCopy) container %d to %d\n",
342dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src,
343dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.dst);
344dce93cd0SAchim Leubner 			break;
345dce93cd0SAchim Leubner 		case AifJobCtrCreateMirror:	/* Container Create Mirror
346dce93cd0SAchim Leubner 						 * operation */
347dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
348dce93cd0SAchim Leubner 				      "(ContainerCreateMirror) container %d\n",
349dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src);
350dce93cd0SAchim Leubner 				      /* XXX two containers? */
351dce93cd0SAchim Leubner 			break;
352dce93cd0SAchim Leubner 		case AifJobCtrMergeMirror:	/* Container Merge Mirror
353dce93cd0SAchim Leubner 						 * operation */
354dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
355dce93cd0SAchim Leubner 				      "(ContainerMergeMirror) container %d\n",
356dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src);
357dce93cd0SAchim Leubner 				      /* XXX two containers? */
358dce93cd0SAchim Leubner 			break;
359dce93cd0SAchim Leubner 		case AifJobCtrScrubMirror:	/* Container Scrub Mirror
360dce93cd0SAchim Leubner 						 * operation */
361dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
362dce93cd0SAchim Leubner 				      "(ContainerScrubMirror) container %d\n",
363dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src);
364dce93cd0SAchim Leubner 			break;
365dce93cd0SAchim Leubner 		case AifJobCtrRebuildRaid5:	/* Container Rebuild Raid5
366dce93cd0SAchim Leubner 						 * operation */
367dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
368dce93cd0SAchim Leubner 				      "(ContainerRebuildRaid5) container %d\n",
369dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src);
370dce93cd0SAchim Leubner 			break;
371dce93cd0SAchim Leubner 		case AifJobCtrScrubRaid5:	/* Container Scrub Raid5
372dce93cd0SAchim Leubner 						 * operation */
373dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
374dce93cd0SAchim Leubner 				      "(ContainerScrubRaid5) container %d\n",
375dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src);
376dce93cd0SAchim Leubner 			break;
377dce93cd0SAchim Leubner 		case AifJobCtrMorph:		/* Container morph operation */
378dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
379dce93cd0SAchim Leubner 				      "(ContainerMorph) container %d\n",
380dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src);
381dce93cd0SAchim Leubner 				      /* XXX two containers? */
382dce93cd0SAchim Leubner 			break;
383dce93cd0SAchim Leubner 		case AifJobCtrPartCopy:		/* Container Partition copy
384dce93cd0SAchim Leubner 						 * operation */
385dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
386dce93cd0SAchim Leubner 				      "(ContainerPartCopy) container %d to "
387dce93cd0SAchim Leubner 				      "%d\n",
388dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src,
389dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.dst);
390dce93cd0SAchim Leubner 			break;
391dce93cd0SAchim Leubner 		case AifJobCtrRebuildMirror:	/* Container Rebuild Mirror
392dce93cd0SAchim Leubner 						 * operation */
393dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
394dce93cd0SAchim Leubner 				      "(ContainerRebuildMirror) container "
395dce93cd0SAchim Leubner 				      "%d\n",
396dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src);
397dce93cd0SAchim Leubner 			break;
398dce93cd0SAchim Leubner 		case AifJobCtrCrazyCache:	/* crazy cache */
399dce93cd0SAchim Leubner 			device_printf(sc->aac_dev,
400dce93cd0SAchim Leubner 				      "(ContainerCrazyCache) container %d\n",
401dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.client.container.src);
402dce93cd0SAchim Leubner 				      /* XXX two containers? */
403dce93cd0SAchim Leubner 			break;
404dce93cd0SAchim Leubner 		case AifJobFsCreate:		/* File System Create
405dce93cd0SAchim Leubner 						 * operation */
406dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(FsCreate)\n");
407dce93cd0SAchim Leubner 			break;
408dce93cd0SAchim Leubner 		case AifJobFsVerify:		/* File System Verify
409dce93cd0SAchim Leubner 						 * operation */
410dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(FsVerivy)\n");
411dce93cd0SAchim Leubner 			break;
412dce93cd0SAchim Leubner 		case AifJobFsExtend:		/* File System Extend
413dce93cd0SAchim Leubner 						 * operation */
414dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(FsExtend)\n");
415dce93cd0SAchim Leubner 			break;
416dce93cd0SAchim Leubner 		case AifJobApiFormatNTFS:	/* Format a drive to NTFS */
417dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(FormatNTFS)\n");
418dce93cd0SAchim Leubner 			break;
419dce93cd0SAchim Leubner 		case AifJobApiFormatFAT:	/* Format a drive to FAT */
420dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(FormatFAT)\n");
421dce93cd0SAchim Leubner 			break;
422dce93cd0SAchim Leubner 		case AifJobApiUpdateSnapshot:	/* update the read/write half
423dce93cd0SAchim Leubner 						 * of a snapshot */
424dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(UpdateSnapshot)\n");
425dce93cd0SAchim Leubner 			break;
426dce93cd0SAchim Leubner 		case AifJobApiFormatFAT32:	/* Format a drive to FAT32 */
427dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(FormatFAT32)\n");
428dce93cd0SAchim Leubner 			break;
429dce93cd0SAchim Leubner 		case AifJobCtlContinuousCtrVerify: /* Adapter operation */
430dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(ContinuousCtrVerify)\n");
431dce93cd0SAchim Leubner 			break;
432dce93cd0SAchim Leubner 		default:
433dce93cd0SAchim Leubner 			device_printf(sc->aac_dev, "(%d)\n",
434dce93cd0SAchim Leubner 				      aif->data.PR[0].jd.type);
435dce93cd0SAchim Leubner 			break;
436dce93cd0SAchim Leubner 		}
437dce93cd0SAchim Leubner 		break;
438dce93cd0SAchim Leubner 	}
439dce93cd0SAchim Leubner 	case AifCmdAPIReport:
440dce93cd0SAchim Leubner 		device_printf(sc->aac_dev, "APIReport (%d)\n", aif->seqNumber);
441dce93cd0SAchim Leubner 		break;
442dce93cd0SAchim Leubner 	case AifCmdDriverNotify:
443dce93cd0SAchim Leubner 		device_printf(sc->aac_dev, "DriverNotify (%d)\n",
444dce93cd0SAchim Leubner 			      aif->seqNumber);
445dce93cd0SAchim Leubner 		break;
446dce93cd0SAchim Leubner 	default:
447dce93cd0SAchim Leubner 		device_printf(sc->aac_dev, "AIF %d (%d)\n", aif->command,
448dce93cd0SAchim Leubner 			      aif->seqNumber);
449dce93cd0SAchim Leubner 		break;
450dce93cd0SAchim Leubner 	}
451dce93cd0SAchim Leubner }
452dce93cd0SAchim Leubner #endif /* AACRAID_DEBUG */
453dce93cd0SAchim Leubner 
454dce93cd0SAchim Leubner /*
455dce93cd0SAchim Leubner  * Debug flags to be put into the HBA flags field when initialized
456dce93cd0SAchim Leubner  */
457dce93cd0SAchim Leubner const unsigned long aacraid_debug_flags = /* Variable to setup with above flags. */
458dce93cd0SAchim Leubner /*			HBA_FLAGS_DBG_KERNEL_PRINT_B |		*/
459dce93cd0SAchim Leubner 			HBA_FLAGS_DBG_FW_PRINT_B |
460dce93cd0SAchim Leubner /*			HBA_FLAGS_DBG_FUNCTION_ENTRY_B |	*/
461dce93cd0SAchim Leubner 			HBA_FLAGS_DBG_FUNCTION_EXIT_B |
462dce93cd0SAchim Leubner 			HBA_FLAGS_DBG_ERROR_B |
463dce93cd0SAchim Leubner 			HBA_FLAGS_DBG_INIT_B |
464dce93cd0SAchim Leubner /*			HBA_FLAGS_DBG_OS_COMMANDS_B |		*/
465dce93cd0SAchim Leubner /*			HBA_FLAGS_DBG_SCAN_B |			*/
466dce93cd0SAchim Leubner /*			HBA_FLAGS_DBG_COALESCE_B |		*/
467dce93cd0SAchim Leubner /*			HBA_FLAGS_DBG_IOCTL_COMMANDS_B |	*/
468dce93cd0SAchim Leubner /*			HBA_FLAGS_DBG_SYNC_COMMANDS_B |		*/
469dce93cd0SAchim Leubner 			HBA_FLAGS_DBG_COMM_B |
470dce93cd0SAchim Leubner /*			HBA_FLAGS_DBG_AIF_B |			*/
471dce93cd0SAchim Leubner /*			HBA_FLAGS_DBG_CSMI_COMMANDS_B | 	*/
472dce93cd0SAchim Leubner 			HBA_FLAGS_DBG_DEBUG_B |
473dce93cd0SAchim Leubner /*			HBA_FLAGS_DBG_FLAGS_MASK | 		*/
474dce93cd0SAchim Leubner 0;
475dce93cd0SAchim Leubner 
aacraid_get_fw_debug_buffer(struct aac_softc * sc)476dce93cd0SAchim Leubner int aacraid_get_fw_debug_buffer(struct aac_softc *sc)
477dce93cd0SAchim Leubner {
478dce93cd0SAchim Leubner 	u_int32_t MonDriverBufferPhysAddrLow = 0;
479dce93cd0SAchim Leubner 	u_int32_t MonDriverBufferPhysAddrHigh = 0;
480dce93cd0SAchim Leubner 	u_int32_t MonDriverBufferSize = 0;
481dce93cd0SAchim Leubner 	u_int32_t MonDriverHeaderSize = 0;
482dce93cd0SAchim Leubner 
483dce93cd0SAchim Leubner 	/*
484dce93cd0SAchim Leubner 	 * Get the firmware print buffer parameters from the firmware
485dce93cd0SAchim Leubner 	 * If the command was successful map in the address.
486dce93cd0SAchim Leubner 	 */
487dce93cd0SAchim Leubner 	if (!aacraid_sync_command(sc, AAC_MONKER_GETDRVPROP, 0, 0, 0, 0, NULL, NULL)) {
488dce93cd0SAchim Leubner 		MonDriverBufferPhysAddrLow = AAC_GET_MAILBOX(sc, 1);
489dce93cd0SAchim Leubner 		MonDriverBufferPhysAddrHigh = AAC_GET_MAILBOX(sc, 2);
490dce93cd0SAchim Leubner 		MonDriverBufferSize = AAC_GET_MAILBOX(sc, 3);
491dce93cd0SAchim Leubner 		MonDriverHeaderSize = AAC_GET_MAILBOX(sc, 4);
492dce93cd0SAchim Leubner 		if (MonDriverBufferSize) {
493dce93cd0SAchim Leubner 			unsigned long Offset = MonDriverBufferPhysAddrLow
494dce93cd0SAchim Leubner 				- rman_get_start(sc->aac_regs_res1);
495dce93cd0SAchim Leubner 
496dce93cd0SAchim Leubner 			/*
497dce93cd0SAchim Leubner 			 * See if the address is already mapped in and if so set it up
498dce93cd0SAchim Leubner 			 * from the base address
499dce93cd0SAchim Leubner 			 */
500dce93cd0SAchim Leubner 			if ((MonDriverBufferPhysAddrHigh == 0) &&
501dce93cd0SAchim Leubner 				(Offset + MonDriverBufferSize <
502dce93cd0SAchim Leubner 				rman_get_size(sc->aac_regs_res1))) {
503dce93cd0SAchim Leubner 				sc->DebugOffset = Offset;
504dce93cd0SAchim Leubner 				sc->DebugHeaderSize = MonDriverHeaderSize;
505dce93cd0SAchim Leubner 				sc->FwDebugBufferSize = MonDriverBufferSize;
506dce93cd0SAchim Leubner 				sc->FwDebugFlags = 0;
507dce93cd0SAchim Leubner 				sc->DebugFlags = aacraid_debug_flags;
508dce93cd0SAchim Leubner 				return 1;
509dce93cd0SAchim Leubner 			}
510dce93cd0SAchim Leubner 		}
511dce93cd0SAchim Leubner 	}
512dce93cd0SAchim Leubner 
513dce93cd0SAchim Leubner 	/*
514dce93cd0SAchim Leubner 	 * The GET_DRIVER_BUFFER_PROPERTIES command failed
515dce93cd0SAchim Leubner 	 */
516dce93cd0SAchim Leubner 	return 0;
517dce93cd0SAchim Leubner }
518dce93cd0SAchim Leubner 
519dce93cd0SAchim Leubner #define PRINT_TIMEOUT 250000 /* 1/4 second */
520dce93cd0SAchim Leubner 
aacraid_fw_printf(struct aac_softc * sc,unsigned long PrintFlags,const char * fmt,...)521dce93cd0SAchim Leubner void aacraid_fw_printf(struct aac_softc *sc, unsigned long PrintFlags, const char * fmt, ...)
522dce93cd0SAchim Leubner {
523dce93cd0SAchim Leubner 	va_list args;
524dce93cd0SAchim Leubner 	u_int32_t Count, i;
525dce93cd0SAchim Leubner 	char PrintBuffer_P[PRINT_BUFFER_SIZE];
526dce93cd0SAchim Leubner 	unsigned long PrintType;
527dce93cd0SAchim Leubner 
528dce93cd0SAchim Leubner 	PrintType = PrintFlags &
529dce93cd0SAchim Leubner 		~(HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B);
530dce93cd0SAchim Leubner 	if (((PrintType!=0) && (sc!=NULL) && ((sc->DebugFlags & PrintType)==0))
531dce93cd0SAchim Leubner 		|| ((sc!=NULL) && (sc->DebugFlags
532dce93cd0SAchim Leubner 		& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B)) == 0))
533dce93cd0SAchim Leubner 		return;
534dce93cd0SAchim Leubner 
535dce93cd0SAchim Leubner 	/*
536dce93cd0SAchim Leubner 	 * Set up parameters and call sprintf function to format the data
537dce93cd0SAchim Leubner 	 */
538dce93cd0SAchim Leubner 	va_start(args, fmt);
539dce93cd0SAchim Leubner 	vsprintf(PrintBuffer_P, fmt, args);
540dce93cd0SAchim Leubner 	va_end(args);
541dce93cd0SAchim Leubner 
542dce93cd0SAchim Leubner 	/*
543dce93cd0SAchim Leubner 	 * Make sure the HBA structure has been passed in for this section
544dce93cd0SAchim Leubner 	 */
545dce93cd0SAchim Leubner 	if ((sc != NULL) && (sc->FwDebugBufferSize)) {
546dce93cd0SAchim Leubner 		/*
547dce93cd0SAchim Leubner 		 * If we are set up for a Firmware print
548dce93cd0SAchim Leubner 		 */
549dce93cd0SAchim Leubner 		if ((sc->DebugFlags & HBA_FLAGS_DBG_FW_PRINT_B)
550dce93cd0SAchim Leubner 			&& ((PrintFlags
551dce93cd0SAchim Leubner 			& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B))
552dce93cd0SAchim Leubner 			!= HBA_FLAGS_DBG_KERNEL_PRINT_B)) {
553dce93cd0SAchim Leubner 			/*
554dce93cd0SAchim Leubner 			 * Make sure the string size is within boundaries
555dce93cd0SAchim Leubner 			 */
556dce93cd0SAchim Leubner 			Count = strlen(PrintBuffer_P);
557dce93cd0SAchim Leubner 			if (Count > sc->FwDebugBufferSize)
558dce93cd0SAchim Leubner 				Count = (u_int16_t)sc->FwDebugBufferSize;
559dce93cd0SAchim Leubner 
560dce93cd0SAchim Leubner 			/*
561dce93cd0SAchim Leubner 			 * Wait for no more than PRINT_TIMEOUT for the previous
562dce93cd0SAchim Leubner 			 * message length to clear (the handshake).
563dce93cd0SAchim Leubner 			 */
564dce93cd0SAchim Leubner 			for (i = 0; i < PRINT_TIMEOUT; ++i) {
565dce93cd0SAchim Leubner 				if (!AAC_MEM1_GETREG4(sc,
566dce93cd0SAchim Leubner 					sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET)) {
567dce93cd0SAchim Leubner 					break;
568dce93cd0SAchim Leubner 				}
569dce93cd0SAchim Leubner 				DELAY(1);
570dce93cd0SAchim Leubner             }
571dce93cd0SAchim Leubner 
572dce93cd0SAchim Leubner 			/*
573dce93cd0SAchim Leubner 			 * If the Length is clear, copy over the message, the
574dce93cd0SAchim Leubner 			 * flags, and the length. Make sure the length is the
575dce93cd0SAchim Leubner 			 * last because that is the signal for the Firmware to
576dce93cd0SAchim Leubner 			 * pick it up.
577dce93cd0SAchim Leubner 			 */
578dce93cd0SAchim Leubner 			if (!AAC_MEM1_GETREG4(sc,
579dce93cd0SAchim Leubner 				sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET)) {
580dce93cd0SAchim Leubner 				for (i = 0; i < Count; ++i) {
581dce93cd0SAchim Leubner 					AAC_MEM1_SETREG1(sc, sc->DebugOffset + sc->DebugHeaderSize + i,
582dce93cd0SAchim Leubner 								PrintBuffer_P[i]);
583dce93cd0SAchim Leubner 				}
584dce93cd0SAchim Leubner 				AAC_MEM1_SETREG4(sc, sc->DebugOffset + FW_DEBUG_FLAGS_OFFSET,
585dce93cd0SAchim Leubner 							sc->FwDebugFlags);
586dce93cd0SAchim Leubner 				AAC_MEM1_SETREG4(sc, sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET,
587dce93cd0SAchim Leubner                             Count);
588dce93cd0SAchim Leubner 			} else
589dce93cd0SAchim Leubner 				sc->DebugFlags &= ~HBA_FLAGS_DBG_FW_PRINT_B;
590dce93cd0SAchim Leubner 		}
591dce93cd0SAchim Leubner 
592dce93cd0SAchim Leubner 		/*
593dce93cd0SAchim Leubner 		 * If the Kernel Debug Print flag is set, send it off to the
594dce93cd0SAchim Leubner 		 * Kernel debugger
595dce93cd0SAchim Leubner 		 */
596dce93cd0SAchim Leubner 		if ((sc->DebugFlags & HBA_FLAGS_DBG_KERNEL_PRINT_B)
597dce93cd0SAchim Leubner 			&& ((PrintFlags
598dce93cd0SAchim Leubner 			& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B))
599dce93cd0SAchim Leubner 			!= HBA_FLAGS_DBG_FW_PRINT_B)) {
600dce93cd0SAchim Leubner 			if (sc->FwDebugFlags & FW_DEBUG_FLAGS_NO_HEADERS_B)
601dce93cd0SAchim Leubner 				printf ("%s\n", PrintBuffer_P);
602dce93cd0SAchim Leubner 			else
603dce93cd0SAchim Leubner 				device_printf (sc->aac_dev, "%s\n", PrintBuffer_P);
604dce93cd0SAchim Leubner 		}
605dce93cd0SAchim Leubner 
606dce93cd0SAchim Leubner 	} else {
607dce93cd0SAchim Leubner 		/*
608dce93cd0SAchim Leubner 		 * No HBA structure passed in so it has to be for the Kernel Debugger
609dce93cd0SAchim Leubner 		 */
610dce93cd0SAchim Leubner 		if ((sc != NULL) && (sc->FwDebugFlags & FW_DEBUG_FLAGS_NO_HEADERS_B))
611dce93cd0SAchim Leubner 			printf ("%s\n", PrintBuffer_P);
612dce93cd0SAchim Leubner 		else if (sc != NULL)
613dce93cd0SAchim Leubner 			device_printf (sc->aac_dev, "%s\n", PrintBuffer_P);
614dce93cd0SAchim Leubner 		else
615dce93cd0SAchim Leubner 			printf("%s\n", PrintBuffer_P);
616dce93cd0SAchim Leubner 	}
617dce93cd0SAchim Leubner }
618dce93cd0SAchim Leubner 
aacraid_fw_print_mem(struct aac_softc * sc,unsigned long PrintFlags,u_int8_t * Addr,int Count)619dce93cd0SAchim Leubner void aacraid_fw_print_mem(struct aac_softc *sc, unsigned long PrintFlags, u_int8_t *Addr, int Count)
620dce93cd0SAchim Leubner {
621dce93cd0SAchim Leubner 	int Offset, i;
622dce93cd0SAchim Leubner 	u_int32_t DebugFlags = 0;
623dce93cd0SAchim Leubner 	char Buffer[100];
624dce93cd0SAchim Leubner 	char *LineBuffer_P;
625dce93cd0SAchim Leubner 
626dce93cd0SAchim Leubner 	/*
627dce93cd0SAchim Leubner 	 * If we have an HBA structure, save off the flags and set the no
628dce93cd0SAchim Leubner 	 * headers flag so we don't have garbage between our lines of data
629dce93cd0SAchim Leubner 	 */
630dce93cd0SAchim Leubner 	if (sc != NULL) {
631dce93cd0SAchim Leubner 		DebugFlags = sc->FwDebugFlags;
632dce93cd0SAchim Leubner 		sc->FwDebugFlags |= FW_DEBUG_FLAGS_NO_HEADERS_B;
633dce93cd0SAchim Leubner 	}
634dce93cd0SAchim Leubner 
635dce93cd0SAchim Leubner 	Offset = 0;
636dce93cd0SAchim Leubner 
637dce93cd0SAchim Leubner 	/*
638dce93cd0SAchim Leubner 	 * Loop through all the data
639dce93cd0SAchim Leubner 	 */
640dce93cd0SAchim Leubner 	while (Offset < Count) {
641dce93cd0SAchim Leubner 		/*
642dce93cd0SAchim Leubner 		 * We will format each line into a buffer and then print out
643dce93cd0SAchim Leubner 		 * the entire line so set the pointer to the beginning of the
644dce93cd0SAchim Leubner 		 * buffer
645dce93cd0SAchim Leubner 		 */
646dce93cd0SAchim Leubner 		LineBuffer_P = Buffer;
647dce93cd0SAchim Leubner 
648dce93cd0SAchim Leubner 		/*
649dce93cd0SAchim Leubner 		 * Set up the address in HEX
650dce93cd0SAchim Leubner 		 */
651dce93cd0SAchim Leubner 		sprintf(LineBuffer_P, "\n%04x  ", Offset);
652dce93cd0SAchim Leubner 		LineBuffer_P += 6;
653dce93cd0SAchim Leubner 
654dce93cd0SAchim Leubner 		/*
655dce93cd0SAchim Leubner 		 * Set up 16 bytes in HEX format
656dce93cd0SAchim Leubner 		 */
657dce93cd0SAchim Leubner 		for (i = 0; i < 16; ++i) {
658dce93cd0SAchim Leubner 			/*
659dce93cd0SAchim Leubner 			 * If we are past the count of data bytes to output,
660dce93cd0SAchim Leubner 			 * pad with blanks
661dce93cd0SAchim Leubner 			 */
662dce93cd0SAchim Leubner 			if ((Offset + i) >= Count)
663dce93cd0SAchim Leubner 				sprintf (LineBuffer_P, "   ");
664dce93cd0SAchim Leubner 			else
665dce93cd0SAchim Leubner 			  	sprintf (LineBuffer_P, "%02x ", Addr[Offset+i]);
666dce93cd0SAchim Leubner 			LineBuffer_P += 3;
667dce93cd0SAchim Leubner 
668dce93cd0SAchim Leubner 			/*
669dce93cd0SAchim Leubner 			 * At the mid point we will put in a divider
670dce93cd0SAchim Leubner 			 */
671dce93cd0SAchim Leubner 			if (i == 7) {
672dce93cd0SAchim Leubner 				sprintf (LineBuffer_P, "- ");
673dce93cd0SAchim Leubner 				LineBuffer_P += 2;
674dce93cd0SAchim Leubner 			}
675dce93cd0SAchim Leubner 		}
676dce93cd0SAchim Leubner 		/*
677dce93cd0SAchim Leubner 		 * Now do the same 16 bytes at the end of the line in ASCII
678dce93cd0SAchim Leubner 		 * format
679dce93cd0SAchim Leubner 		 */
680dce93cd0SAchim Leubner 		sprintf (LineBuffer_P, "  ");
681dce93cd0SAchim Leubner 		LineBuffer_P += 2;
682dce93cd0SAchim Leubner 		for (i = 0; i < 16; ++i) {
683dce93cd0SAchim Leubner 			/*
684dce93cd0SAchim Leubner 			 * If all data processed, OUT-O-HERE
685dce93cd0SAchim Leubner 			 */
686dce93cd0SAchim Leubner 			if ((Offset + i) >= Count)
687dce93cd0SAchim Leubner 				break;
688dce93cd0SAchim Leubner 
689dce93cd0SAchim Leubner 			/*
690dce93cd0SAchim Leubner 			 * If this is a printable ASCII character, convert it
691dce93cd0SAchim Leubner 			 */
692dce93cd0SAchim Leubner 			if ((Addr[Offset+i] > 0x1F) && (Addr[Offset+i] < 0x7F))
693dce93cd0SAchim Leubner 				sprintf (LineBuffer_P, "%c", Addr[Offset+i]);
694dce93cd0SAchim Leubner 			else
695dce93cd0SAchim Leubner 				sprintf (LineBuffer_P, ".");
696dce93cd0SAchim Leubner 			++LineBuffer_P;
697dce93cd0SAchim Leubner 		}
698dce93cd0SAchim Leubner 		/*
699dce93cd0SAchim Leubner 		 * The line is now formatted, so print it out
700dce93cd0SAchim Leubner 		 */
701dce93cd0SAchim Leubner 		aacraid_fw_printf(sc, PrintFlags, "%s", Buffer);
702dce93cd0SAchim Leubner 
703dce93cd0SAchim Leubner 		/*
704dce93cd0SAchim Leubner 		 * Bump the offset by 16 for the next line
705dce93cd0SAchim Leubner 		 */
706dce93cd0SAchim Leubner 		Offset += 16;
707dce93cd0SAchim Leubner 	}
708dce93cd0SAchim Leubner 
709dce93cd0SAchim Leubner 	/*
710dce93cd0SAchim Leubner 	 * Restore the saved off flags
711dce93cd0SAchim Leubner 	 */
712dce93cd0SAchim Leubner 	if (sc != NULL)
713dce93cd0SAchim Leubner 		sc->FwDebugFlags = DebugFlags;
714dce93cd0SAchim Leubner }
715