2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2001 Scott Long
4 * Copyright (c) 2000 BSDi
5 * Copyright (c) 2001 Adaptec, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
45 #include <machine/resource.h>
46 #include <machine/bus.h>
48 #include <dev/aac/aacreg.h>
49 #include <sys/aac_ioctl.h>
50 #include <dev/aac/aacvar.h>
53 int aac_debug_enable = 0;
54 void aac_printstate0(void);
57 * Dump the command queue indices
60 aac_print_queues(struct aac_softc *sc)
62 device_printf(sc->aac_dev, "FIB queue header at %p queues at %p\n",
63 &sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][0],
64 &sc->aac_queues->qt_HostNormCmdQueue[0]);
65 device_printf(sc->aac_dev, "HOST_NORM_CMD %d/%d (%d)\n",
66 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
68 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
70 AAC_HOST_NORM_CMD_ENTRIES);
71 device_printf(sc->aac_dev, "HOST_HIGH_CMD %d/%d (%d)\n",
72 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
74 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
76 AAC_HOST_HIGH_CMD_ENTRIES);
77 device_printf(sc->aac_dev, "ADAP_NORM_CMD %d/%d (%d)\n",
78 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
80 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
82 AAC_ADAP_NORM_CMD_ENTRIES);
83 device_printf(sc->aac_dev, "ADAP_HIGH_CMD %d/%d (%d)\n",
84 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
86 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
88 AAC_ADAP_HIGH_CMD_ENTRIES);
89 device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n",
90 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
92 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
94 AAC_HOST_NORM_RESP_ENTRIES);
95 device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n",
96 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
98 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
100 AAC_HOST_HIGH_RESP_ENTRIES);
101 device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n",
102 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
104 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
106 AAC_ADAP_NORM_RESP_ENTRIES);
107 device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n",
108 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
110 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
112 AAC_ADAP_HIGH_RESP_ENTRIES);
113 device_printf(sc->aac_dev, "AACQ_FREE %d/%d\n",
114 sc->aac_qstat[AACQ_FREE].q_length, sc->aac_qstat[AACQ_FREE].q_max);
115 device_printf(sc->aac_dev, "AACQ_BIO %d/%d\n",
116 sc->aac_qstat[AACQ_BIO].q_length, sc->aac_qstat[AACQ_BIO].q_max);
117 device_printf(sc->aac_dev, "AACQ_READY %d/%d\n",
118 sc->aac_qstat[AACQ_READY].q_length,
119 sc->aac_qstat[AACQ_READY].q_max);
120 device_printf(sc->aac_dev, "AACQ_BUSY %d/%d\n",
121 sc->aac_qstat[AACQ_BUSY].q_length, sc->aac_qstat[AACQ_BUSY].q_max);
125 * Print the command queue states for controller 0 (callable from DDB)
128 aac_printstate0(void)
130 struct aac_softc *sc;
132 sc = devclass_get_softc(devclass_find("aac"), 0);
134 aac_print_queues(sc);
135 switch (sc->aac_hwif) {
136 case AAC_HWIF_I960RX:
137 device_printf(sc->aac_dev, "IDBR 0x%08x IIMR 0x%08x "
138 "IISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_IDBR),
139 AAC_GETREG4(sc, AAC_RX_IIMR), AAC_GETREG4(sc, AAC_RX_IISR));
140 device_printf(sc->aac_dev, "ODBR 0x%08x OIMR 0x%08x "
141 "OISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_ODBR),
142 AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
143 AAC_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY |
144 AAC_DB_RESPONSE_READY | AAC_DB_PRINTF)*/);
145 device_printf(sc->aac_dev, "ODBR 0x%08x OIMR 0x%08x "
146 "OISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_ODBR),
147 AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
149 case AAC_HWIF_STRONGARM:
156 * Panic in a slightly informative fashion
159 aac_panic(struct aac_softc *sc, char *reason)
161 aac_print_queues(sc);
169 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
172 device_printf(sc->aac_dev,
173 "aac_print_fib called with NULL fib\n");
176 device_printf(sc->aac_dev, "%s: FIB @ %p\n", caller, fib);
177 device_printf(sc->aac_dev, " XferState %b\n", fib->Header.XferState,
200 device_printf(sc->aac_dev, " Command %d\n", fib->Header.Command);
201 device_printf(sc->aac_dev, " StructType %d\n",
202 fib->Header.StructType);
203 device_printf(sc->aac_dev, " Flags 0x%x\n", fib->Header.Flags);
204 device_printf(sc->aac_dev, " Size %d\n", fib->Header.Size);
205 device_printf(sc->aac_dev, " SenderSize %d\n",
206 fib->Header.SenderSize);
207 device_printf(sc->aac_dev, " SenderAddress 0x%x\n",
208 fib->Header.SenderFibAddress);
209 device_printf(sc->aac_dev, " RcvrAddress 0x%x\n",
210 fib->Header.ReceiverFibAddress);
211 device_printf(sc->aac_dev, " SenderData 0x%x\n",
212 fib->Header.SenderData);
213 switch(fib->Header.Command) {
214 case ContainerCommand:
216 struct aac_blockread *br;
217 struct aac_blockwrite *bw;
218 struct aac_sg_table *sg;
221 br = (struct aac_blockread*)fib->data;
222 bw = (struct aac_blockwrite*)fib->data;
225 if (br->Command == VM_CtBlockRead) {
226 device_printf(sc->aac_dev,
227 " BlockRead: container %d 0x%x/%d\n",
228 br->ContainerId, br->BlockNumber,
232 if (bw->Command == VM_CtBlockWrite) {
233 device_printf(sc->aac_dev,
234 " BlockWrite: container %d 0x%x/%d "
235 "(%s)\n", bw->ContainerId,
236 bw->BlockNumber, bw->ByteCount,
237 bw->Stable == CSTABLE ? "stable" :
242 device_printf(sc->aac_dev,
243 " %d s/g entries\n", sg->SgCount);
244 for (i = 0; i < sg->SgCount; i++)
245 device_printf(sc->aac_dev, " 0x%08x/%d\n",
246 sg->SgEntry[i].SgAddress,
247 sg->SgEntry[i].SgByteCount);
252 device_printf(sc->aac_dev, " %16D\n", fib->data, " ");
253 device_printf(sc->aac_dev, " %16D\n", fib->data + 16, " ");
259 * Describe an AIF we have received.
262 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
264 switch(aif->command) {
265 case AifCmdEventNotify:
266 device_printf(sc->aac_dev, "EventNotify(%d)\n", aif->seqNumber);
267 switch(aif->data.EN.type) {
268 case AifEnGeneric: /* Generic notification */
269 device_printf(sc->aac_dev, "(Generic) %.*s\n",
270 (int)sizeof(aif->data.EN.data.EG),
271 aif->data.EN.data.EG.text);
273 case AifEnTaskComplete: /* Task has completed */
274 device_printf(sc->aac_dev, "(TaskComplete)\n");
276 case AifEnConfigChange: /* Adapter configuration change
278 device_printf(sc->aac_dev, "(ConfigChange)\n");
280 case AifEnContainerChange: /* Adapter specific container
281 * configuration change */
282 device_printf(sc->aac_dev, "(ContainerChange) "
284 aif->data.EN.data.ECC.container[0],
285 aif->data.EN.data.ECC.container[1]);
287 case AifEnDeviceFailure: /* SCSI device failed */
288 device_printf(sc->aac_dev, "(DeviceFailure) "
290 aif->data.EN.data.EDF.deviceHandle);
292 case AifEnMirrorFailover: /* Mirror failover started */
293 device_printf(sc->aac_dev, "(MirrorFailover) "
294 "container %d failed, "
295 "migrating from slice %d to %d\n",
296 aif->data.EN.data.EMF.container,
297 aif->data.EN.data.EMF.failedSlice,
298 aif->data.EN.data.EMF.creatingSlice);
300 case AifEnContainerEvent: /* Significant container
302 device_printf(sc->aac_dev, "(ContainerEvent) "
303 "container %d event "
304 "%d\n", aif->data.EN.data.ECE.container,
305 aif->data.EN.data.ECE.eventType);
307 case AifEnFileSystemChange: /* File system changed */
308 device_printf(sc->aac_dev, "(FileSystemChange)\n");
310 case AifEnConfigPause: /* Container pause event */
311 device_printf(sc->aac_dev, "(ConfigPause)\n");
313 case AifEnConfigResume: /* Container resume event */
314 device_printf(sc->aac_dev, "(ConfigResume)\n");
316 case AifEnFailoverChange: /* Failover space assignment
318 device_printf(sc->aac_dev, "(FailoverChange)\n");
320 case AifEnRAID5RebuildDone: /* RAID5 rebuild finished */
321 device_printf(sc->aac_dev, "(RAID5RebuildDone)\n");
323 case AifEnEnclosureManagement: /* Enclosure management event */
324 device_printf(sc->aac_dev, "(EnclosureManagement) "
326 "event %d\n", aif->data.EN.data.EEE.empID,
327 aif->data.EN.data.EEE.unitID,
328 aif->data.EN.data.EEE.eventType);
330 case AifEnBatteryEvent: /* Significant NV battery
332 device_printf(sc->aac_dev, "(BatteryEvent) %d "
333 "(state was %d, is %d\n",
334 aif->data.EN.data.EBE.transition_type,
335 aif->data.EN.data.EBE.current_state,
336 aif->data.EN.data.EBE.prior_state);
338 case AifEnAddContainer: /* A new container was
340 device_printf(sc->aac_dev, "(AddContainer)\n");
342 case AifEnDeleteContainer: /* A container was deleted. */
343 device_printf(sc->aac_dev, "(DeleteContainer)\n");
345 case AifEnBatteryNeedsRecond: /* The battery needs
347 device_printf(sc->aac_dev, "(BatteryNeedsRecond)\n");
349 case AifEnClusterEvent: /* Some cluster event */
350 device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
351 aif->data.EN.data.ECLE.eventType);
353 case AifEnDiskSetEvent: /* A disk set event occured. */
354 device_printf(sc->aac_dev, "(DiskSetEvent) event %d "
355 "diskset %jd creator %jd\n",
356 aif->data.EN.data.EDS.eventType,
357 (intmax_t)aif->data.EN.data.EDS.DsNum,
358 (intmax_t)aif->data.EN.data.EDS.CreatorId);
360 case AifDenMorphComplete: /* A morph operation
362 device_printf(sc->aac_dev, "(MorphComplete)\n");
364 case AifDenVolumeExtendComplete: /* A volume expand operation
366 device_printf(sc->aac_dev, "(VolumeExtendComplete)\n");
369 device_printf(sc->aac_dev, "(%d)\n", aif->data.EN.type);
373 case AifCmdJobProgress:
376 switch(aif->data.PR[0].status) {
377 case AifJobStsSuccess:
378 status = "success"; break;
379 case AifJobStsFinished:
380 status = "finished"; break;
381 case AifJobStsAborted:
382 status = "aborted"; break;
383 case AifJobStsFailed:
384 status = "failed"; break;
385 case AifJobStsSuspended:
386 status = "suspended"; break;
387 case AifJobStsRunning:
388 status = "running"; break;
390 status = "unknown status"; break;
393 device_printf(sc->aac_dev, "JobProgress (%d) - %s (%d, %d)\n",
394 aif->seqNumber, status,
395 aif->data.PR[0].currentTick,
396 aif->data.PR[0].finalTick);
397 switch(aif->data.PR[0].jd.type) {
398 case AifJobScsiZero: /* SCSI dev clear operation */
399 device_printf(sc->aac_dev, "(ScsiZero) handle %d\n",
400 aif->data.PR[0].jd.client.scsi_dh);
402 case AifJobScsiVerify: /* SCSI device Verify operation
404 device_printf(sc->aac_dev, "(ScsiVerify) handle %d\n",
405 aif->data.PR[0].jd.client.scsi_dh);
407 case AifJobScsiExercise: /* SCSI device Exercise
409 device_printf(sc->aac_dev, "(ScsiExercise) handle %d\n",
410 aif->data.PR[0].jd.client.scsi_dh);
412 case AifJobScsiVerifyRepair: /* SCSI device Verify operation
414 device_printf(sc->aac_dev,
415 "(ScsiVerifyRepair) handle %d\n",
416 aif->data.PR[0].jd.client.scsi_dh);
418 case AifJobCtrZero: /* Container clear operation */
419 device_printf(sc->aac_dev,
420 "(ContainerZero) container %d\n",
421 aif->data.PR[0].jd.client.container.src);
423 case AifJobCtrCopy: /* Container copy operation */
424 device_printf(sc->aac_dev,
425 "(ContainerCopy) container %d to %d\n",
426 aif->data.PR[0].jd.client.container.src,
427 aif->data.PR[0].jd.client.container.dst);
429 case AifJobCtrCreateMirror: /* Container Create Mirror
431 device_printf(sc->aac_dev,
432 "(ContainerCreateMirror) container %d\n",
433 aif->data.PR[0].jd.client.container.src);
434 /* XXX two containers? */
436 case AifJobCtrMergeMirror: /* Container Merge Mirror
438 device_printf(sc->aac_dev,
439 "(ContainerMergeMirror) container %d\n",
440 aif->data.PR[0].jd.client.container.src);
441 /* XXX two containers? */
443 case AifJobCtrScrubMirror: /* Container Scrub Mirror
445 device_printf(sc->aac_dev,
446 "(ContainerScrubMirror) container %d\n",
447 aif->data.PR[0].jd.client.container.src);
449 case AifJobCtrRebuildRaid5: /* Container Rebuild Raid5
451 device_printf(sc->aac_dev,
452 "(ContainerRebuildRaid5) container %d\n",
453 aif->data.PR[0].jd.client.container.src);
455 case AifJobCtrScrubRaid5: /* Container Scrub Raid5
457 device_printf(sc->aac_dev,
458 "(ContainerScrubRaid5) container %d\n",
459 aif->data.PR[0].jd.client.container.src);
461 case AifJobCtrMorph: /* Container morph operation */
462 device_printf(sc->aac_dev,
463 "(ContainerMorph) container %d\n",
464 aif->data.PR[0].jd.client.container.src);
465 /* XXX two containers? */
467 case AifJobCtrPartCopy: /* Container Partition copy
469 device_printf(sc->aac_dev,
470 "(ContainerPartCopy) container %d to "
472 aif->data.PR[0].jd.client.container.src,
473 aif->data.PR[0].jd.client.container.dst);
475 case AifJobCtrRebuildMirror: /* Container Rebuild Mirror
477 device_printf(sc->aac_dev,
478 "(ContainerRebuildMirror) container "
480 aif->data.PR[0].jd.client.container.src);
482 case AifJobCtrCrazyCache: /* crazy cache */
483 device_printf(sc->aac_dev,
484 "(ContainerCrazyCache) container %d\n",
485 aif->data.PR[0].jd.client.container.src);
486 /* XXX two containers? */
488 case AifJobFsCreate: /* File System Create
490 device_printf(sc->aac_dev, "(FsCreate)\n");
492 case AifJobFsVerify: /* File System Verify
494 device_printf(sc->aac_dev, "(FsVerivy)\n");
496 case AifJobFsExtend: /* File System Extend
498 device_printf(sc->aac_dev, "(FsExtend)\n");
500 case AifJobApiFormatNTFS: /* Format a drive to NTFS */
501 device_printf(sc->aac_dev, "(FormatNTFS)\n");
503 case AifJobApiFormatFAT: /* Format a drive to FAT */
504 device_printf(sc->aac_dev, "(FormatFAT)\n");
506 case AifJobApiUpdateSnapshot: /* update the read/write half
508 device_printf(sc->aac_dev, "(UpdateSnapshot)\n");
510 case AifJobApiFormatFAT32: /* Format a drive to FAT32 */
511 device_printf(sc->aac_dev, "(FormatFAT32)\n");
513 case AifJobCtlContinuousCtrVerify: /* Adapter operation */
514 device_printf(sc->aac_dev, "(ContinuousCtrVerify)\n");
517 device_printf(sc->aac_dev, "(%d)\n",
518 aif->data.PR[0].jd.type);
523 case AifCmdAPIReport:
524 device_printf(sc->aac_dev, "APIReport (%d)\n", aif->seqNumber);
526 case AifCmdDriverNotify:
527 device_printf(sc->aac_dev, "DriverNotify (%d)\n",
531 device_printf(sc->aac_dev, "AIF %d (%d)\n", aif->command,
536 #endif /* AAC_DEBUG */