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