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