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