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
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
41 #include <dev/aac/aac_compat.h>
43 #include <sys/devicestat.h>
46 #include <machine/resource.h>
47 #include <machine/bus.h>
49 #include <dev/aac/aacreg.h>
50 #include <dev/aac/aac_ioctl.h>
51 #include <dev/aac/aacvar.h>
54 void aac_printstate0(void);
58 * Dump the command queue indices
61 aac_print_queues(struct aac_softc *sc)
63 device_printf(sc->aac_dev, "FIB queue header at %p queues at %p\n",
64 &sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][0],
65 &sc->aac_queues->qt_HostNormCmdQueue[0]);
66 device_printf(sc->aac_dev, "HOST_NORM_CMD %d/%d (%d)\n",
67 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
69 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
71 AAC_HOST_NORM_CMD_ENTRIES);
72 device_printf(sc->aac_dev, "HOST_HIGH_CMD %d/%d (%d)\n",
73 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
75 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
77 AAC_HOST_HIGH_CMD_ENTRIES);
78 device_printf(sc->aac_dev, "ADAP_NORM_CMD %d/%d (%d)\n",
79 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
81 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
83 AAC_ADAP_NORM_CMD_ENTRIES);
84 device_printf(sc->aac_dev, "ADAP_HIGH_CMD %d/%d (%d)\n",
85 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
87 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
89 AAC_ADAP_HIGH_CMD_ENTRIES);
90 device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n",
91 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
93 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
95 AAC_HOST_NORM_RESP_ENTRIES);
96 device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n",
97 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
99 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
101 AAC_HOST_HIGH_RESP_ENTRIES);
102 device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n",
103 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
105 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
107 AAC_ADAP_NORM_RESP_ENTRIES);
108 device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n",
109 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
111 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
113 AAC_ADAP_HIGH_RESP_ENTRIES);
114 device_printf(sc->aac_dev, "AACQ_FREE %d/%d\n",
115 sc->aac_qstat[AACQ_FREE].q_length, sc->aac_qstat[AACQ_FREE].q_max);
116 device_printf(sc->aac_dev, "AACQ_BIO %d/%d\n",
117 sc->aac_qstat[AACQ_BIO].q_length, sc->aac_qstat[AACQ_BIO].q_max);
118 device_printf(sc->aac_dev, "AACQ_READY %d/%d\n",
119 sc->aac_qstat[AACQ_READY].q_length,
120 sc->aac_qstat[AACQ_READY].q_max);
121 device_printf(sc->aac_dev, "AACQ_BUSY %d/%d\n",
122 sc->aac_qstat[AACQ_BUSY].q_length, sc->aac_qstat[AACQ_BUSY].q_max);
123 device_printf(sc->aac_dev, "AACQ_COMPLETE %d/%d\n",
124 sc->aac_qstat[AACQ_COMPLETE].q_length,
125 sc->aac_qstat[AACQ_COMPLETE].q_max);
129 * Print the command queue states for controller 0 (callable from DDB)
132 aac_printstate0(void)
134 struct aac_softc *sc;
136 sc = devclass_get_softc(devclass_find("aac"), 0);
138 aac_print_queues(sc);
139 switch (sc->aac_hwif) {
140 case AAC_HWIF_I960RX:
141 device_printf(sc->aac_dev, "IDBR 0x%08x IIMR 0x%08x "
142 "IISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_IDBR),
143 AAC_GETREG4(sc, AAC_RX_IIMR), AAC_GETREG4(sc, AAC_RX_IISR));
144 device_printf(sc->aac_dev, "ODBR 0x%08x OIMR 0x%08x "
145 "OISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_ODBR),
146 AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
147 AAC_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY |
148 AAC_DB_RESPONSE_READY | AAC_DB_PRINTF)*/);
149 device_printf(sc->aac_dev, "ODBR 0x%08x OIMR 0x%08x "
150 "OISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_ODBR),
151 AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
153 case AAC_HWIF_STRONGARM:
160 * simulate an interrupt for controller 0
165 struct aac_softc *sc;
167 sc = devclass_get_softc(devclass_find("aac"), 0);
173 * Panic in a slightly informative fashion
176 aac_panic(struct aac_softc *sc, char *reason)
178 aac_print_queues(sc);
186 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
188 device_printf(sc->aac_dev, "%s: FIB @ %p\n", caller, fib);
189 device_printf(sc->aac_dev, " XferState %b\n", fib->Header.XferState,
212 device_printf(sc->aac_dev, " Command %d\n", fib->Header.Command);
213 device_printf(sc->aac_dev, " StructType %d\n",
214 fib->Header.StructType);
215 device_printf(sc->aac_dev, " Flags 0x%x\n", fib->Header.Flags);
216 device_printf(sc->aac_dev, " Size %d\n", fib->Header.Size);
217 device_printf(sc->aac_dev, " SenderSize %d\n",
218 fib->Header.SenderSize);
219 device_printf(sc->aac_dev, " SenderAddress 0x%x\n",
220 fib->Header.SenderFibAddress);
221 device_printf(sc->aac_dev, " RcvrAddress 0x%x\n",
222 fib->Header.ReceiverFibAddress);
223 device_printf(sc->aac_dev, " SenderData 0x%x\n",
224 fib->Header.SenderData);
225 switch(fib->Header.Command) {
226 case ContainerCommand:
228 struct aac_blockread *br;
229 struct aac_blockwrite *bw;
230 struct aac_sg_table *sg;
233 br = (struct aac_blockread*)fib->data;
234 bw = (struct aac_blockwrite*)fib->data;
237 if (br->Command == VM_CtBlockRead) {
238 device_printf(sc->aac_dev,
239 " BlockRead: container %d 0x%x/%d\n",
240 br->ContainerId, br->BlockNumber,
244 if (bw->Command == VM_CtBlockWrite) {
245 device_printf(sc->aac_dev,
246 " BlockWrite: container %d 0x%x/%d "
247 "(%s)\n", bw->ContainerId,
248 bw->BlockNumber, bw->ByteCount,
249 bw->Stable == CSTABLE ? "stable" :
254 device_printf(sc->aac_dev,
255 " %d s/g entries\n", sg->SgCount);
256 for (i = 0; i < sg->SgCount; i++)
257 device_printf(sc->aac_dev, " 0x%08x/%d\n",
258 sg->SgEntry[i].SgAddress,
259 sg->SgEntry[i].SgByteCount);
264 device_printf(sc->aac_dev, " %16D\n", fib->data, " ");
265 device_printf(sc->aac_dev, " %16D\n", fib->data + 16, " ");
271 * Describe an AIF we have received.
274 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
276 switch(aif->command) {
277 case AifCmdEventNotify:
278 device_printf(sc->aac_dev, "EventNotify(%d)\n", aif->seqNumber);
279 switch(aif->data.EN.type) {
280 case AifEnGeneric: /* Generic notification */
281 device_printf(sc->aac_dev, "(Generic) %.*s\n",
282 (int)sizeof(aif->data.EN.data.EG),
283 aif->data.EN.data.EG.text);
285 case AifEnTaskComplete: /* Task has completed */
286 device_printf(sc->aac_dev, "(TaskComplete)\n");
288 case AifEnConfigChange: /* Adapter configuration change
290 device_printf(sc->aac_dev, "(ConfigChange)\n");
292 case AifEnContainerChange: /* Adapter specific container
293 * configuration change */
294 device_printf(sc->aac_dev, "(ContainerChange) "
296 aif->data.EN.data.ECC.container[0],
297 aif->data.EN.data.ECC.container[1]);
299 case AifEnDeviceFailure: /* SCSI device failed */
300 device_printf(sc->aac_dev, "(DeviceFailure) "
302 aif->data.EN.data.EDF.deviceHandle);
304 case AifEnMirrorFailover: /* Mirror failover started */
305 device_printf(sc->aac_dev, "(MirrorFailover) "
306 "container %d failed, "
307 "migrating from slice %d to %d\n",
308 aif->data.EN.data.EMF.container,
309 aif->data.EN.data.EMF.failedSlice,
310 aif->data.EN.data.EMF.creatingSlice);
312 case AifEnContainerEvent: /* Significant container
314 device_printf(sc->aac_dev, "(ContainerEvent) "
315 "container %d event "
316 "%d\n", aif->data.EN.data.ECE.container,
317 aif->data.EN.data.ECE.eventType);
319 case AifEnFileSystemChange: /* File system changed */
320 device_printf(sc->aac_dev, "(FileSystemChange)\n");
322 case AifEnConfigPause: /* Container pause event */
323 device_printf(sc->aac_dev, "(ConfigPause)\n");
325 case AifEnConfigResume: /* Container resume event */
326 device_printf(sc->aac_dev, "(ConfigResume)\n");
328 case AifEnFailoverChange: /* Failover space assignment
330 device_printf(sc->aac_dev, "(FailoverChange)\n");
332 case AifEnRAID5RebuildDone: /* RAID5 rebuild finished */
333 device_printf(sc->aac_dev, "(RAID5RebuildDone)\n");
335 case AifEnEnclosureManagement: /* Enclosure management event */
336 device_printf(sc->aac_dev, "(EnclosureManagement) "
338 "event %d\n", aif->data.EN.data.EEE.empID,
339 aif->data.EN.data.EEE.unitID,
340 aif->data.EN.data.EEE.eventType);
342 case AifEnBatteryEvent: /* Significant NV battery
344 device_printf(sc->aac_dev, "(BatteryEvent) %d "
345 "(state was %d, is %d\n",
346 aif->data.EN.data.EBE.transition_type,
347 aif->data.EN.data.EBE.current_state,
348 aif->data.EN.data.EBE.prior_state);
350 case AifEnAddContainer: /* A new container was
352 device_printf(sc->aac_dev, "(AddContainer)\n");
354 case AifEnDeleteContainer: /* A container was deleted. */
355 device_printf(sc->aac_dev, "(DeleteContainer)\n");
357 case AifEnBatteryNeedsRecond: /* The battery needs
359 device_printf(sc->aac_dev, "(BatteryNeedsRecond)\n");
361 case AifEnClusterEvent: /* Some cluster event */
362 device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
363 aif->data.EN.data.ECLE.eventType);
365 case AifEnDiskSetEvent: /* A disk set event occured. */
366 device_printf(sc->aac_dev, "(DiskSetEvent) event %d "
367 "diskset %lld creator %lld\n",
368 aif->data.EN.data.EDS.eventType,
369 aif->data.EN.data.EDS.DsNum,
370 aif->data.EN.data.EDS.CreatorId);
372 case AifDenMorphComplete: /* A morph operation
374 device_printf(sc->aac_dev, "(MorphComplete)\n");
376 case AifDenVolumeExtendComplete: /* A volume expand operation
378 device_printf(sc->aac_dev, "(VolumeExtendComplete)\n");
381 device_printf(sc->aac_dev, "(%d)\n", aif->data.EN.type);
385 case AifCmdJobProgress:
388 switch(aif->data.PR[0].status) {
389 case AifJobStsSuccess:
390 status = "success"; break;
391 case AifJobStsFinished:
392 status = "finished"; break;
393 case AifJobStsAborted:
394 status = "aborted"; break;
395 case AifJobStsFailed:
396 status = "failed"; break;
397 case AifJobStsSuspended:
398 status = "suspended"; break;
399 case AifJobStsRunning:
400 status = "running"; break;
402 status = "unknown status"; break;
405 device_printf(sc->aac_dev, "JobProgress (%d) - %s (%d, %d)\n",
406 aif->seqNumber, status,
407 aif->data.PR[0].currentTick,
408 aif->data.PR[0].finalTick);
409 switch(aif->data.PR[0].jd.type) {
410 case AifJobScsiZero: /* SCSI dev clear operation */
411 device_printf(sc->aac_dev, "(ScsiZero) handle %d\n",
412 aif->data.PR[0].jd.client.scsi_dh);
414 case AifJobScsiVerify: /* SCSI device Verify operation
416 device_printf(sc->aac_dev, "(ScsiVerify) handle %d\n",
417 aif->data.PR[0].jd.client.scsi_dh);
419 case AifJobScsiExercise: /* SCSI device Exercise
421 device_printf(sc->aac_dev, "(ScsiExercise) handle %d\n",
422 aif->data.PR[0].jd.client.scsi_dh);
424 case AifJobScsiVerifyRepair: /* SCSI device Verify operation
426 device_printf(sc->aac_dev,
427 "(ScsiVerifyRepair) handle %d\n",
428 aif->data.PR[0].jd.client.scsi_dh);
430 case AifJobCtrZero: /* Container clear operation */
431 device_printf(sc->aac_dev,
432 "(ConatainerZero) container %d\n",
433 aif->data.PR[0].jd.client.container.src);
435 case AifJobCtrCopy: /* Container copy operation */
436 device_printf(sc->aac_dev,
437 "(ConatainerCopy) container %d to %d\n",
438 aif->data.PR[0].jd.client.container.src,
439 aif->data.PR[0].jd.client.container.dst);
441 case AifJobCtrCreateMirror: /* Container Create Mirror
443 device_printf(sc->aac_dev,
444 "(ConatainerCreateMirror) container %d\n",
445 aif->data.PR[0].jd.client.container.src);
446 /* XXX two containers? */
448 case AifJobCtrMergeMirror: /* Container Merge Mirror
450 device_printf(sc->aac_dev,
451 "(ConatainerMergeMirror) container %d\n",
452 aif->data.PR[0].jd.client.container.src);
453 /* XXX two containers? */
455 case AifJobCtrScrubMirror: /* Container Scrub Mirror
457 device_printf(sc->aac_dev,
458 "(ConatainerScrubMirror) container %d\n",
459 aif->data.PR[0].jd.client.container.src);
461 case AifJobCtrRebuildRaid5: /* Container Rebuild Raid5
463 device_printf(sc->aac_dev,
464 "(ConatainerRebuildRaid5) container %d\n",
465 aif->data.PR[0].jd.client.container.src);
467 case AifJobCtrScrubRaid5: /* Container Scrub Raid5
469 device_printf(sc->aac_dev,
470 "(ConatainerScrubRaid5) container %d\n",
471 aif->data.PR[0].jd.client.container.src);
473 case AifJobCtrMorph: /* Container morph operation */
474 device_printf(sc->aac_dev,
475 "(ConatainerMorph) container %d\n",
476 aif->data.PR[0].jd.client.container.src);
477 /* XXX two containers? */
479 case AifJobCtrPartCopy: /* Container Partition copy
481 device_printf(sc->aac_dev,
482 "(ConatainerPartCopy) container %d to "
484 aif->data.PR[0].jd.client.container.src,
485 aif->data.PR[0].jd.client.container.dst);
487 case AifJobCtrRebuildMirror: /* Container Rebuild Mirror
489 device_printf(sc->aac_dev,
490 "(ConatainerRebuildMirror) container "
492 aif->data.PR[0].jd.client.container.src);
494 case AifJobCtrCrazyCache: /* crazy cache */
495 device_printf(sc->aac_dev,
496 "(ConatainerCrazyCache) container %d\n",
497 aif->data.PR[0].jd.client.container.src);
498 /* XXX two containers? */
500 case AifJobFsCreate: /* File System Create
502 device_printf(sc->aac_dev, "(FsCreate)\n");
504 case AifJobFsVerify: /* File System Verify
506 device_printf(sc->aac_dev, "(FsVerivy)\n");
508 case AifJobFsExtend: /* File System Extend
510 device_printf(sc->aac_dev, "(FsExtend)\n");
512 case AifJobApiFormatNTFS: /* Format a drive to NTFS */
513 device_printf(sc->aac_dev, "(FormatNTFS)\n");
515 case AifJobApiFormatFAT: /* Format a drive to FAT */
516 device_printf(sc->aac_dev, "(FormatFAT)\n");
518 case AifJobApiUpdateSnapshot: /* update the read/write half
520 device_printf(sc->aac_dev, "(UpdateSnapshot)\n");
522 case AifJobApiFormatFAT32: /* Format a drive to FAT32 */
523 device_printf(sc->aac_dev, "(FormatFAT32)\n");
525 case AifJobCtlContinuousCtrVerify: /* Adapter operation */
526 device_printf(sc->aac_dev, "(ContinuousCtrVerify)\n");
529 device_printf(sc->aac_dev, "(%d)\n",
530 aif->data.PR[0].jd.type);
535 case AifCmdAPIReport:
536 device_printf(sc->aac_dev, "APIReport (%d)\n", aif->seqNumber);
538 case AifCmdDriverNotify:
539 device_printf(sc->aac_dev, "DriverNotify (%d)\n",
543 device_printf(sc->aac_dev, "AIF %d (%d)\n", aif->command,
548 #endif /* AAC_DEBUG */