xref: /freebsd/sys/dev/aac/aac_debug.c (revision 77a0943ded95b9e6438f7db70c4a28e4d93946d4)
1 /*-
2  * Copyright (c) 2000 Michael Smith
3  * Copyright (c) 2000 BSDi
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *	$FreeBSD$
28  */
29 
30 /*
31  * Debugging support.
32  */
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 
38 #include <dev/aac/aac_compat.h>
39 #include <sys/bus.h>
40 #include <sys/devicestat.h>
41 #include <sys/disk.h>
42 
43 #include <machine/resource.h>
44 #include <machine/bus.h>
45 
46 #include <dev/aac/aacreg.h>
47 #include <dev/aac/aacvar.h>
48 
49 void		aac_printstate0(void);
50 void		aac_intr0(void);
51 
52 /********************************************************************************
53  * Dump the command queue indices
54  */
55 void
56 aac_print_queues(struct aac_softc *sc)
57 {
58     device_printf(sc->aac_dev, "FIB queue header at %p  queues at %p\n",
59 		  &sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][0],
60 		  &sc->aac_queues->qt_HostNormCmdQueue[0]);
61     device_printf(sc->aac_dev, "HOST_NORM_CMD  %d/%d (%d)\n",
62 		  sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX],
63 		  sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX],
64 		  AAC_HOST_NORM_CMD_ENTRIES);
65     device_printf(sc->aac_dev, "HOST_HIGH_CMD  %d/%d (%d)\n",
66 		  sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX],
67 		  sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX],
68 		  AAC_HOST_HIGH_CMD_ENTRIES);
69     device_printf(sc->aac_dev, "ADAP_NORM_CMD  %d/%d (%d)\n",
70 		  sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX],
71 		  sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX],
72 		  AAC_ADAP_NORM_CMD_ENTRIES);
73     device_printf(sc->aac_dev, "ADAP_HIGH_CMD  %d/%d (%d)\n",
74 		  sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX],
75 		  sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX],
76 		  AAC_ADAP_HIGH_CMD_ENTRIES);
77     device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n",
78 		  sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX],
79 		  sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX],
80 		  AAC_HOST_NORM_RESP_ENTRIES);
81     device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n",
82 		  sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX],
83 		  sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX],
84 		  AAC_HOST_HIGH_RESP_ENTRIES);
85     device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n",
86 		  sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX],
87 		  sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX],
88 		  AAC_ADAP_NORM_RESP_ENTRIES);
89     device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n",
90 		  sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX],
91 		  sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX],
92 		  AAC_ADAP_HIGH_RESP_ENTRIES);
93 
94 }
95 
96 /********************************************************************************
97  * Print the command queue states for controller 0 (callable from DDB)
98  */
99 void
100 aac_printstate0(void)
101 {
102     struct aac_softc	*sc = devclass_get_softc(aac_devclass, 0);
103 
104     aac_print_queues(sc);
105     switch (sc->aac_hwif) {
106     case AAC_HWIF_I960RX:
107 	device_printf(sc->aac_dev, "IDBR 0x%08x  IIMR 0x%08x  IISR 0x%08x\n",
108 		      AAC_GETREG4(sc, AAC_RX_IDBR), AAC_GETREG4(sc, AAC_RX_IIMR), AAC_GETREG4(sc, AAC_RX_IISR));
109 	device_printf(sc->aac_dev, "ODBR 0x%08x  OIMR 0x%08x  OISR 0x%08x\n",
110 		      AAC_GETREG4(sc, AAC_RX_ODBR), AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
111 	AAC_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY | AAC_DB_RESPONSE_READY | AAC_DB_PRINTF)*/);
112 	device_printf(sc->aac_dev, "ODBR 0x%08x  OIMR 0x%08x  OISR 0x%08x\n",
113 		      AAC_GETREG4(sc, AAC_RX_ODBR), AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
114 	break;
115     case AAC_HWIF_STRONGARM:
116 	/* XXX implement */
117     }
118 }
119 
120 /********************************************************************************
121  * simulate an interrupt for controller 0
122  */
123 void
124 aac_intr0(void)
125 {
126     struct aac_softc	*sc = devclass_get_softc(aac_devclass, 0);
127 
128     aac_intr(sc);
129 }
130 
131 /********************************************************************************
132  * Panic in a slightly informative fashion
133  */
134 void
135 aac_panic(struct aac_softc *sc, char *reason)
136 {
137     aac_print_queues(sc);
138     panic(reason);
139 }
140 
141 /********************************************************************************
142  * Print a FIB
143  */
144 void
145 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller)
146 {
147     device_printf(sc->aac_dev, "%s: FIB @ %p\n", caller, fib);
148     device_printf(sc->aac_dev, "  XferState %b\n", fib->Header.XferState, "\20"
149 		  "\1HOSTOWNED"
150 		  "\2ADAPTEROWNED"
151 		  "\3INITIALISED"
152 		  "\4EMPTY"
153 		  "\5FROMPOOL"
154 		  "\6FROMHOST"
155 		  "\7FROMADAP"
156 		  "\10REXPECTED"
157 		  "\11RNOTEXPECTED"
158 		  "\12DONEADAP"
159 		  "\13DONEHOST"
160 		  "\14HIGH"
161 		  "\15NORM"
162 		  "\16ASYNC"
163 		  "\17PAGEFILEIO"
164 		  "\20SHUTDOWN"
165 		  "\21LAZYWRITE"
166 		  "\22ADAPMICROFIB"
167 		  "\23BIOSFIB"
168 		  "\24FAST_RESPONSE"
169 		  "\25APIFIB\n");
170     device_printf(sc->aac_dev, "  Command         %d\n", fib->Header.Command);
171     device_printf(sc->aac_dev, "  StructType      %d\n", fib->Header.StructType);
172     device_printf(sc->aac_dev, "  Flags           0x%x\n", fib->Header.Flags);
173     device_printf(sc->aac_dev, "  Size            %d\n", fib->Header.Size);
174     device_printf(sc->aac_dev, "  SenderSize      %d\n", fib->Header.SenderSize);
175     device_printf(sc->aac_dev, "  SenderAddress   0x%x\n", fib->Header.SenderFibAddress);
176     device_printf(sc->aac_dev, "  ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress);
177     device_printf(sc->aac_dev, "  SenderData      0x%x\n", fib->Header.SenderData);
178     switch(fib->Header.Command) {
179     case ContainerCommand:
180     {
181 	struct aac_blockread	*br = (struct aac_blockread *)fib->data;
182 	struct aac_blockwrite	*bw = (struct aac_blockwrite *)fib->data;
183 	struct aac_sg_table	*sg = NULL;
184 	int			i;
185 	if (br->Command == VM_CtBlockRead) {
186 	    device_printf(sc->aac_dev, "  BlockRead: container %d  0x%x/%d\n",
187 			  br->ContainerId, br->BlockNumber, br->ByteCount);
188 	    sg = &br->SgMap;
189 	}
190 	if (bw->Command == VM_CtBlockWrite) {
191 	    device_printf(sc->aac_dev, "  BlockWrite: container %d  0x%x/%d (%s)\n",
192 			  bw->ContainerId, bw->BlockNumber, bw->ByteCount,
193 			  bw->Stable == CSTABLE ? "stable" : "unstable");
194 	    sg = &bw->SgMap;
195 	}
196 	if (sg != NULL) {
197 	    device_printf(sc->aac_dev, "  %d s/g entries\n", sg->SgCount);
198 	    for (i = 0; i < sg->SgCount; i++)
199 		device_printf(sc->aac_dev, "  0x%08x/%d\n", sg->SgEntry[i].SgAddress, sg->SgEntry[i].SgByteCount);
200 	}
201 	break;
202     }
203     default:
204 	device_printf(sc->aac_dev, "   %16D\n", fib->data, " ");
205 	device_printf(sc->aac_dev, "   %16D\n", fib->data + 16, " ");
206 	break;
207     }
208 }
209 
210 /********************************************************************************
211  * Describe an AIF we have received.
212  */
213 void
214 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
215 {
216     switch(aif->command) {
217     case AifCmdEventNotify:
218 	device_printf(sc->aac_dev, "EventNotify (%d)\n", aif->seqNumber);
219 	switch(aif->data.EN.type) {
220 	case AifEnGeneric:			/* Generic notification */
221 	    device_printf(sc->aac_dev, "(Generic) %.*s\n",
222 			  (int)sizeof(aif->data.EN.data.EG), aif->data.EN.data.EG.text);
223 	    break;
224 	case AifEnTaskComplete:			/* Task has completed */
225 	    device_printf(sc->aac_dev, "(TaskComplete)\n");
226 	    break;
227 	case AifEnConfigChange:			/* Adapter configuration change occurred */
228 	    device_printf(sc->aac_dev, "(ConfigChange)\n");
229 	    break;
230 	case AifEnContainerChange:		/* Adapter specific container configuration change */
231 	    device_printf(sc->aac_dev, "(ContainerChange) container %d,%d\n",
232 			  aif->data.EN.data.ECC.container[0],
233 			  aif->data.EN.data.ECC.container[1]);
234 	    break;
235 	case AifEnDeviceFailure:		/* SCSI device failed */
236 	    device_printf(sc->aac_dev, "(DeviceFailure) handle %d\n",
237 			  aif->data.EN.data.EDF.deviceHandle);	/* XXX interpret */
238 	    break;
239 	case AifEnMirrorFailover:		/* Mirror failover started */
240 	    device_printf(sc->aac_dev, "(MirrorFailover) container %d failed, migrating from slice %d to %d\n",
241 			  aif->data.EN.data.EMF.container,
242 			  aif->data.EN.data.EMF.failedSlice,
243 			  aif->data.EN.data.EMF.creatingSlice);
244 	    break;
245 	case AifEnContainerEvent:		/* Significant container event */
246 	    device_printf(sc->aac_dev, "(ContainerEvent) container %d event %d\n",
247 			  aif->data.EN.data.ECE.container,
248 			  aif->data.EN.data.ECE.eventType);		/* XXX interpret? */
249 	    break;
250 	case AifEnFileSystemChange:		/* File system changed */
251 	    device_printf(sc->aac_dev, "(FileSystemChange)\n");
252 	    break;
253 	case AifEnConfigPause:			/* Container pause event */
254 	    device_printf(sc->aac_dev, "(ConfigPause)\n");
255 	    break;
256 	case AifEnConfigResume:			/* Container resume event */
257 	    device_printf(sc->aac_dev, "(ConfigResume)\n");
258 	    break;
259 	case AifEnFailoverChange:		/* Failover space assignment changed */
260 	    device_printf(sc->aac_dev, "(FailoverChange)\n");
261 	    break;
262 	case AifEnRAID5RebuildDone:		/* RAID5 rebuild finished */
263 	    device_printf(sc->aac_dev, "(RAID5RebuildDone)\n");
264 	    break;
265 	case AifEnEnclosureManagement:		/* Enclosure management event */
266 	    device_printf(sc->aac_dev, "(EnclosureManagement) EMPID %d unit %d event %d\n",
267 			  aif->data.EN.data.EEE.empID,
268 			  aif->data.EN.data.EEE.unitID,
269 			  aif->data.EN.data.EEE.eventType);
270 	    break;
271 	case AifEnBatteryEvent:			/* Significant NV battery event */
272 	    device_printf(sc->aac_dev, "(BatteryEvent) %d (state was %d, is %d)\n",
273 			  aif->data.EN.data.EBE.transition_type, 	/* XXX interpret */
274 			  aif->data.EN.data.EBE.current_state,
275 			  aif->data.EN.data.EBE.prior_state);
276 	    break;
277 	case AifEnAddContainer:			/* A new container was created. */
278 	    device_printf(sc->aac_dev, "(AddContainer)\n");
279 	    break;
280 	case AifEnDeleteContainer:		/* A container was deleted. */
281 	    device_printf(sc->aac_dev, "(DeleteContainer)\n");
282 	    break;
283 	case AifEnBatteryNeedsRecond:		/* The battery needs reconditioning */
284 	    device_printf(sc->aac_dev, "(BatteryNeedsRecond)\n");
285 	    break;
286 	case AifEnClusterEvent:			/* Some cluster event */
287 	    device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
288 			  aif->data.EN.data.ECLE.eventType);
289 	    break;
290 	case AifEnDiskSetEvent:			/* A disk set event occured. */
291 	    device_printf(sc->aac_dev, "(DiskSetEvent) event %d diskset %lld creator %lld\n",
292 			  aif->data.EN.data.EDS.eventType,
293 			  aif->data.EN.data.EDS.DsNum,
294 			  aif->data.EN.data.EDS.CreatorId);
295 	    break;
296 	case AifDenMorphComplete: 		/* A morph operation completed */
297 	    device_printf(sc->aac_dev, "(MorphComplete)\n");
298 	    break;
299 	case AifDenVolumeExtendComplete: 		/* A volume expand operation completed */
300 	    device_printf(sc->aac_dev, "(VolumeExtendComplete)\n");
301 	    break;
302 	default:
303 	    device_printf(sc->aac_dev, "(%d)\n", aif->data.EN.type);
304 	    break;
305 	}
306 	break;
307     case AifCmdJobProgress:
308     {
309 	char	*status;
310 	switch(aif->data.PR[0].status) {
311 	case AifJobStsSuccess:
312 	    status = "success"; break;
313 	case AifJobStsFinished:
314 	    status = "finished"; break;
315 	case AifJobStsAborted:
316 	    status = "aborted"; break;
317 	case AifJobStsFailed:
318 	    status = "failed"; break;
319 	case AifJobStsSuspended:
320 	    status = "suspended"; break;
321 	case AifJobStsRunning:
322 	    status = "running"; break;
323 	default:
324 	    status = "unknown status"; break;
325 	}
326 
327 	device_printf(sc->aac_dev, "JobProgress (%d) - %s (%d, %d)\n", aif->seqNumber, status,
328 		      aif->data.PR[0].currentTick, aif->data.PR[0].finalTick);
329 	switch(aif->data.PR[0].jd.type) {
330 	case AifJobScsiZero:			/* SCSI device clear operation */
331 	    device_printf(sc->aac_dev, "(ScsiZero) handle %d\n", aif->data.PR[0].jd.client.scsi_dh);
332 	    break;
333 	case AifJobScsiVerify:			/* SCSI device Verify operation NO REPAIR */
334 	    device_printf(sc->aac_dev, "(ScsiVerify) handle %d\n", aif->data.PR[0].jd.client.scsi_dh);
335 	    break;
336 	case AifJobScsiExercise:		/* SCSI device Exercise operation */
337 	    device_printf(sc->aac_dev, "(ScsiExercise) handle %d\n", aif->data.PR[0].jd.client.scsi_dh);
338 	    break;
339 	case AifJobScsiVerifyRepair:		/* SCSI device Verify operation WITH repair */
340 	    device_printf(sc->aac_dev, "(ScsiVerifyRepair) handle %d\n", aif->data.PR[0].jd.client.scsi_dh);
341 	    break;
342 	case AifJobCtrZero:			/* Container clear operation */
343 	    device_printf(sc->aac_dev, "(ConatainerZero) container %d\n",
344 			  aif->data.PR[0].jd.client.container.src);
345 	    break;
346 	case AifJobCtrCopy:			/* Container copy operation */
347 	    device_printf(sc->aac_dev, "(ConatainerCopy) container %d to %d\n",
348 			  aif->data.PR[0].jd.client.container.src, aif->data.PR[0].jd.client.container.dst);
349 	    break;
350 	case AifJobCtrCreateMirror:		/* Container Create Mirror operation */
351 	    device_printf(sc->aac_dev, "(ConatainerCreateMirror) container %d\n",
352 			  aif->data.PR[0].jd.client.container.src);	/* XXX two containers? */
353 	    break;
354 	case AifJobCtrMergeMirror:		/* Container Merge Mirror operation */
355 	    device_printf(sc->aac_dev, "(ConatainerMergeMirror) container %d\n",
356 			  aif->data.PR[0].jd.client.container.src);	/* XXX two containers? */
357 	    break;
358 	case AifJobCtrScrubMirror:		/* Container Scrub Mirror operation */
359 	    device_printf(sc->aac_dev, "(ConatainerScrubMirror) container %d\n",
360 			  aif->data.PR[0].jd.client.container.src);
361 	    break;
362 	case AifJobCtrRebuildRaid5:		/* Container Rebuild Raid5 operation */
363 	    device_printf(sc->aac_dev, "(ConatainerRebuildRaid5) container %d\n",
364 			  aif->data.PR[0].jd.client.container.src);
365 	    break;
366 	case AifJobCtrScrubRaid5:		/* Container Scrub Raid5 operation */
367 	    device_printf(sc->aac_dev, "(ConatainerScrubRaid5) container %d\n",
368 			  aif->data.PR[0].jd.client.container.src);
369 	    break;
370 	case AifJobCtrMorph:			/* Container morph operation */
371 	    device_printf(sc->aac_dev, "(ConatainerMorph) container %d\n",
372 			  aif->data.PR[0].jd.client.container.src);	/* XXX two containers? */
373 	    break;
374 	case AifJobCtrPartCopy:			/* Container Partition copy operation */
375 	    device_printf(sc->aac_dev, "(ConatainerPartCopy) container %d to %d\n",
376 			  aif->data.PR[0].jd.client.container.src, aif->data.PR[0].jd.client.container.dst);
377 	    break;
378 	case AifJobCtrRebuildMirror:		/* Container Rebuild Mirror operation */
379 	    device_printf(sc->aac_dev, "(ConatainerRebuildMirror) container %d\n",
380 			  aif->data.PR[0].jd.client.container.src);
381 	    break;
382 	case AifJobCtrCrazyCache:		/* crazy cache */
383 	    device_printf(sc->aac_dev, "(ConatainerCrazyCache) container %d\n",
384 			  aif->data.PR[0].jd.client.container.src);	/* XXX two containers? */
385 	    break;
386 	case AifJobFsCreate:			/* File System Create operation */
387 	    device_printf(sc->aac_dev, "(FsCreate)\n");
388 	    break;
389 	case AifJobFsVerify:			/* File System Verify operation */
390 	    device_printf(sc->aac_dev, "(FsVerivy)\n");
391 	    break;
392 	case AifJobFsExtend:			/* File System Extend operation */
393 	    device_printf(sc->aac_dev, "(FsExtend)\n");
394 	    break;
395 	case AifJobApiFormatNTFS:		/* Format a drive to NTFS */
396 	    device_printf(sc->aac_dev, "(FormatNTFS)\n");
397 	    break;
398 	case AifJobApiFormatFAT:		/* Format a drive to FAT */
399 	    device_printf(sc->aac_dev, "(FormatFAT)\n");
400 	    break;
401 	case AifJobApiUpdateSnapshot:		/* update the read/write half of a snapshot */
402 	    device_printf(sc->aac_dev, "(UpdateSnapshot)\n");
403 	    break;
404 	case AifJobApiFormatFAT32:		/* Format a drive to FAT32 */
405 	    device_printf(sc->aac_dev, "(FormatFAT32)\n");
406 	    break;
407 	case AifJobCtlContinuousCtrVerify:	/* Adapter operation */
408 	    device_printf(sc->aac_dev, "(ContinuousCtrVerify)\n");
409 	    break;
410 	default:
411 	    device_printf(sc->aac_dev, "(%d)\n", aif->data.PR[0].jd.type);
412 	    break;
413 	}
414 	break;
415     }
416     case AifCmdAPIReport:
417 	device_printf(sc->aac_dev, "APIReport (%d)\n", aif->seqNumber);
418 	break;
419     case AifCmdDriverNotify:
420 	device_printf(sc->aac_dev, "DriverNotify (%d)\n", aif->seqNumber);
421 	break;
422     default:
423 	device_printf(sc->aac_dev, "AIF %d (%d)\n", aif->command, aif->seqNumber);
424 	break;
425     }
426 }
427