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