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