2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2000 Michael Smith
5 * Copyright (c) 2001 Scott Long
6 * Copyright (c) 2000 BSDi
7 * Copyright (c) 2001 Adaptec, Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
47 #include <machine/resource.h>
48 #include <machine/bus.h>
50 #include <dev/aac/aacreg.h>
51 #include <sys/aac_ioctl.h>
52 #include <dev/aac/aacvar.h>
55 int aac_debug_enable = 0;
56 void aac_printstate0(void);
59 * Dump the command queue indices
62 aac_print_queues(struct aac_softc *sc)
64 device_printf(sc->aac_dev, "FIB queue header at %p queues at %p\n",
65 &sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][0],
66 &sc->aac_queues->qt_HostNormCmdQueue[0]);
67 device_printf(sc->aac_dev, "HOST_NORM_CMD %d/%d (%d)\n",
68 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
70 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
72 AAC_HOST_NORM_CMD_ENTRIES);
73 device_printf(sc->aac_dev, "HOST_HIGH_CMD %d/%d (%d)\n",
74 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
76 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
78 AAC_HOST_HIGH_CMD_ENTRIES);
79 device_printf(sc->aac_dev, "ADAP_NORM_CMD %d/%d (%d)\n",
80 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
82 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
84 AAC_ADAP_NORM_CMD_ENTRIES);
85 device_printf(sc->aac_dev, "ADAP_HIGH_CMD %d/%d (%d)\n",
86 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
88 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
90 AAC_ADAP_HIGH_CMD_ENTRIES);
91 device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n",
92 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
94 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
96 AAC_HOST_NORM_RESP_ENTRIES);
97 device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n",
98 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
100 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
102 AAC_HOST_HIGH_RESP_ENTRIES);
103 device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n",
104 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
106 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
108 AAC_ADAP_NORM_RESP_ENTRIES);
109 device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n",
110 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
112 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
114 AAC_ADAP_HIGH_RESP_ENTRIES);
115 device_printf(sc->aac_dev, "AACQ_FREE %d/%d\n",
116 sc->aac_qstat[AACQ_FREE].q_length, sc->aac_qstat[AACQ_FREE].q_max);
117 device_printf(sc->aac_dev, "AACQ_BIO %d/%d\n",
118 sc->aac_qstat[AACQ_BIO].q_length, sc->aac_qstat[AACQ_BIO].q_max);
119 device_printf(sc->aac_dev, "AACQ_READY %d/%d\n",
120 sc->aac_qstat[AACQ_READY].q_length,
121 sc->aac_qstat[AACQ_READY].q_max);
122 device_printf(sc->aac_dev, "AACQ_BUSY %d/%d\n",
123 sc->aac_qstat[AACQ_BUSY].q_length, sc->aac_qstat[AACQ_BUSY].q_max);
127 * Print the command queue states for controller 0 (callable from DDB)
130 aac_printstate0(void)
132 struct aac_softc *sc;
134 sc = devclass_get_softc(devclass_find("aac"), 0);
136 aac_print_queues(sc);
137 switch (sc->aac_hwif) {
138 case AAC_HWIF_I960RX:
140 device_printf(sc->aac_dev, "IDBR 0x%08x IIMR 0x%08x "
141 "IISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_IDBR),
142 AAC_MEM0_GETREG4(sc, AAC_RX_IIMR), AAC_MEM0_GETREG4(sc, AAC_RX_IISR));
143 device_printf(sc->aac_dev, "ODBR 0x%08x OIMR 0x%08x "
144 "OISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_ODBR),
145 AAC_MEM0_GETREG4(sc, AAC_RX_OIMR), AAC_MEM0_GETREG4(sc, AAC_RX_OISR));
146 AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY |
147 AAC_DB_RESPONSE_READY | AAC_DB_PRINTF)*/);
148 device_printf(sc->aac_dev, "ODBR 0x%08x OIMR 0x%08x "
149 "OISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_ODBR),
150 AAC_MEM0_GETREG4(sc, AAC_RX_OIMR), AAC_MEM0_GETREG4(sc, AAC_RX_OISR));
152 case AAC_HWIF_STRONGARM:
159 * Panic in a slightly informative fashion
162 aac_panic(struct aac_softc *sc, char *reason)
164 aac_print_queues(sc);
172 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
175 device_printf(sc->aac_dev,
176 "aac_print_fib called with NULL fib\n");
179 device_printf(sc->aac_dev, "%s: FIB @ %p\n", caller, fib);
180 device_printf(sc->aac_dev, " XferState %b\n", fib->Header.XferState,
203 device_printf(sc->aac_dev, " Command %d\n", fib->Header.Command);
204 device_printf(sc->aac_dev, " StructType %d\n",
205 fib->Header.StructType);
206 device_printf(sc->aac_dev, " Flags 0x%x\n", fib->Header.Flags);
207 device_printf(sc->aac_dev, " Size %d\n", fib->Header.Size);
208 device_printf(sc->aac_dev, " SenderSize %d\n",
209 fib->Header.SenderSize);
210 device_printf(sc->aac_dev, " SenderAddress 0x%x\n",
211 fib->Header.SenderFibAddress);
212 device_printf(sc->aac_dev, " RcvrAddress 0x%x\n",
213 fib->Header.ReceiverFibAddress);
214 device_printf(sc->aac_dev, " SenderData 0x%x\n",
215 fib->Header.SenderData);
216 switch(fib->Header.Command) {
217 case ContainerCommand:
219 struct aac_blockread *br;
220 struct aac_blockwrite *bw;
221 struct aac_sg_table *sg;
224 br = (struct aac_blockread*)fib->data;
225 bw = (struct aac_blockwrite*)fib->data;
228 if (br->Command == VM_CtBlockRead) {
229 device_printf(sc->aac_dev,
230 " BlockRead: container %d 0x%x/%d\n",
231 br->ContainerId, br->BlockNumber,
235 if (bw->Command == VM_CtBlockWrite) {
236 device_printf(sc->aac_dev,
237 " BlockWrite: container %d 0x%x/%d "
238 "(%s)\n", bw->ContainerId,
239 bw->BlockNumber, bw->ByteCount,
240 bw->Stable == CSTABLE ? "stable" :
245 device_printf(sc->aac_dev,
246 " %d s/g entries\n", sg->SgCount);
247 for (i = 0; i < sg->SgCount; i++)
248 device_printf(sc->aac_dev, " 0x%08x/%d\n",
249 sg->SgEntry[i].SgAddress,
250 sg->SgEntry[i].SgByteCount);
255 device_printf(sc->aac_dev, " %16D\n", fib->data, " ");
256 device_printf(sc->aac_dev, " %16D\n", fib->data + 16, " ");
262 * Describe an AIF we have received.
265 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
267 switch(aif->command) {
268 case AifCmdEventNotify:
269 device_printf(sc->aac_dev, "EventNotify(%d)\n", aif->seqNumber);
270 switch(aif->data.EN.type) {
271 case AifEnGeneric: /* Generic notification */
272 device_printf(sc->aac_dev, "(Generic) %.*s\n",
273 (int)sizeof(aif->data.EN.data.EG),
274 aif->data.EN.data.EG.text);
276 case AifEnTaskComplete: /* Task has completed */
277 device_printf(sc->aac_dev, "(TaskComplete)\n");
279 case AifEnConfigChange: /* Adapter configuration change
281 device_printf(sc->aac_dev, "(ConfigChange)\n");
283 case AifEnContainerChange: /* Adapter specific container
284 * configuration change */
285 device_printf(sc->aac_dev, "(ContainerChange) "
287 aif->data.EN.data.ECC.container[0],
288 aif->data.EN.data.ECC.container[1]);
290 case AifEnDeviceFailure: /* SCSI device failed */
291 device_printf(sc->aac_dev, "(DeviceFailure) "
293 aif->data.EN.data.EDF.deviceHandle);
295 case AifEnMirrorFailover: /* Mirror failover started */
296 device_printf(sc->aac_dev, "(MirrorFailover) "
297 "container %d failed, "
298 "migrating from slice %d to %d\n",
299 aif->data.EN.data.EMF.container,
300 aif->data.EN.data.EMF.failedSlice,
301 aif->data.EN.data.EMF.creatingSlice);
303 case AifEnContainerEvent: /* Significant container
305 device_printf(sc->aac_dev, "(ContainerEvent) "
306 "container %d event "
307 "%d\n", aif->data.EN.data.ECE.container,
308 aif->data.EN.data.ECE.eventType);
310 case AifEnFileSystemChange: /* File system changed */
311 device_printf(sc->aac_dev, "(FileSystemChange)\n");
313 case AifEnConfigPause: /* Container pause event */
314 device_printf(sc->aac_dev, "(ConfigPause)\n");
316 case AifEnConfigResume: /* Container resume event */
317 device_printf(sc->aac_dev, "(ConfigResume)\n");
319 case AifEnFailoverChange: /* Failover space assignment
321 device_printf(sc->aac_dev, "(FailoverChange)\n");
323 case AifEnRAID5RebuildDone: /* RAID5 rebuild finished */
324 device_printf(sc->aac_dev, "(RAID5RebuildDone)\n");
326 case AifEnEnclosureManagement: /* Enclosure management event */
327 device_printf(sc->aac_dev, "(EnclosureManagement) "
329 "event %d\n", aif->data.EN.data.EEE.empID,
330 aif->data.EN.data.EEE.unitID,
331 aif->data.EN.data.EEE.eventType);
333 case AifEnBatteryEvent: /* Significant NV battery
335 device_printf(sc->aac_dev, "(BatteryEvent) %d "
336 "(state was %d, is %d\n",
337 aif->data.EN.data.EBE.transition_type,
338 aif->data.EN.data.EBE.current_state,
339 aif->data.EN.data.EBE.prior_state);
341 case AifEnAddContainer: /* A new container was
343 device_printf(sc->aac_dev, "(AddContainer)\n");
345 case AifEnDeleteContainer: /* A container was deleted. */
346 device_printf(sc->aac_dev, "(DeleteContainer)\n");
348 case AifEnBatteryNeedsRecond: /* The battery needs
350 device_printf(sc->aac_dev, "(BatteryNeedsRecond)\n");
352 case AifEnClusterEvent: /* Some cluster event */
353 device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
354 aif->data.EN.data.ECLE.eventType);
356 case AifEnDiskSetEvent: /* A disk set event occurred. */
357 device_printf(sc->aac_dev, "(DiskSetEvent) event %d "
358 "diskset %jd creator %jd\n",
359 aif->data.EN.data.EDS.eventType,
360 (intmax_t)aif->data.EN.data.EDS.DsNum,
361 (intmax_t)aif->data.EN.data.EDS.CreatorId);
363 case AifDenMorphComplete: /* A morph operation
365 device_printf(sc->aac_dev, "(MorphComplete)\n");
367 case AifDenVolumeExtendComplete: /* A volume expand operation
369 device_printf(sc->aac_dev, "(VolumeExtendComplete)\n");
372 device_printf(sc->aac_dev, "(%d)\n", aif->data.EN.type);
376 case AifCmdJobProgress:
379 switch(aif->data.PR[0].status) {
380 case AifJobStsSuccess:
381 status = "success"; break;
382 case AifJobStsFinished:
383 status = "finished"; break;
384 case AifJobStsAborted:
385 status = "aborted"; break;
386 case AifJobStsFailed:
387 status = "failed"; break;
388 case AifJobStsSuspended:
389 status = "suspended"; break;
390 case AifJobStsRunning:
391 status = "running"; break;
393 status = "unknown status"; break;
396 device_printf(sc->aac_dev, "JobProgress (%d) - %s (%d, %d)\n",
397 aif->seqNumber, status,
398 aif->data.PR[0].currentTick,
399 aif->data.PR[0].finalTick);
400 switch(aif->data.PR[0].jd.type) {
401 case AifJobScsiZero: /* SCSI dev clear operation */
402 device_printf(sc->aac_dev, "(ScsiZero) handle %d\n",
403 aif->data.PR[0].jd.client.scsi_dh);
405 case AifJobScsiVerify: /* SCSI device Verify operation
407 device_printf(sc->aac_dev, "(ScsiVerify) handle %d\n",
408 aif->data.PR[0].jd.client.scsi_dh);
410 case AifJobScsiExercise: /* SCSI device Exercise
412 device_printf(sc->aac_dev, "(ScsiExercise) handle %d\n",
413 aif->data.PR[0].jd.client.scsi_dh);
415 case AifJobScsiVerifyRepair: /* SCSI device Verify operation
417 device_printf(sc->aac_dev,
418 "(ScsiVerifyRepair) handle %d\n",
419 aif->data.PR[0].jd.client.scsi_dh);
421 case AifJobCtrZero: /* Container clear operation */
422 device_printf(sc->aac_dev,
423 "(ContainerZero) container %d\n",
424 aif->data.PR[0].jd.client.container.src);
426 case AifJobCtrCopy: /* Container copy operation */
427 device_printf(sc->aac_dev,
428 "(ContainerCopy) container %d to %d\n",
429 aif->data.PR[0].jd.client.container.src,
430 aif->data.PR[0].jd.client.container.dst);
432 case AifJobCtrCreateMirror: /* Container Create Mirror
434 device_printf(sc->aac_dev,
435 "(ContainerCreateMirror) container %d\n",
436 aif->data.PR[0].jd.client.container.src);
437 /* XXX two containers? */
439 case AifJobCtrMergeMirror: /* Container Merge Mirror
441 device_printf(sc->aac_dev,
442 "(ContainerMergeMirror) container %d\n",
443 aif->data.PR[0].jd.client.container.src);
444 /* XXX two containers? */
446 case AifJobCtrScrubMirror: /* Container Scrub Mirror
448 device_printf(sc->aac_dev,
449 "(ContainerScrubMirror) container %d\n",
450 aif->data.PR[0].jd.client.container.src);
452 case AifJobCtrRebuildRaid5: /* Container Rebuild Raid5
454 device_printf(sc->aac_dev,
455 "(ContainerRebuildRaid5) container %d\n",
456 aif->data.PR[0].jd.client.container.src);
458 case AifJobCtrScrubRaid5: /* Container Scrub Raid5
460 device_printf(sc->aac_dev,
461 "(ContainerScrubRaid5) container %d\n",
462 aif->data.PR[0].jd.client.container.src);
464 case AifJobCtrMorph: /* Container morph operation */
465 device_printf(sc->aac_dev,
466 "(ContainerMorph) container %d\n",
467 aif->data.PR[0].jd.client.container.src);
468 /* XXX two containers? */
470 case AifJobCtrPartCopy: /* Container Partition copy
472 device_printf(sc->aac_dev,
473 "(ContainerPartCopy) container %d to "
475 aif->data.PR[0].jd.client.container.src,
476 aif->data.PR[0].jd.client.container.dst);
478 case AifJobCtrRebuildMirror: /* Container Rebuild Mirror
480 device_printf(sc->aac_dev,
481 "(ContainerRebuildMirror) container "
483 aif->data.PR[0].jd.client.container.src);
485 case AifJobCtrCrazyCache: /* crazy cache */
486 device_printf(sc->aac_dev,
487 "(ContainerCrazyCache) container %d\n",
488 aif->data.PR[0].jd.client.container.src);
489 /* XXX two containers? */
491 case AifJobFsCreate: /* File System Create
493 device_printf(sc->aac_dev, "(FsCreate)\n");
495 case AifJobFsVerify: /* File System Verify
497 device_printf(sc->aac_dev, "(FsVerivy)\n");
499 case AifJobFsExtend: /* File System Extend
501 device_printf(sc->aac_dev, "(FsExtend)\n");
503 case AifJobApiFormatNTFS: /* Format a drive to NTFS */
504 device_printf(sc->aac_dev, "(FormatNTFS)\n");
506 case AifJobApiFormatFAT: /* Format a drive to FAT */
507 device_printf(sc->aac_dev, "(FormatFAT)\n");
509 case AifJobApiUpdateSnapshot: /* update the read/write half
511 device_printf(sc->aac_dev, "(UpdateSnapshot)\n");
513 case AifJobApiFormatFAT32: /* Format a drive to FAT32 */
514 device_printf(sc->aac_dev, "(FormatFAT32)\n");
516 case AifJobCtlContinuousCtrVerify: /* Adapter operation */
517 device_printf(sc->aac_dev, "(ContinuousCtrVerify)\n");
520 device_printf(sc->aac_dev, "(%d)\n",
521 aif->data.PR[0].jd.type);
526 case AifCmdAPIReport:
527 device_printf(sc->aac_dev, "APIReport (%d)\n", aif->seqNumber);
529 case AifCmdDriverNotify:
530 device_printf(sc->aac_dev, "DriverNotify (%d)\n",
534 device_printf(sc->aac_dev, "AIF %d (%d)\n", aif->command,
539 #endif /* AAC_DEBUG */