Annotation of kernel/bsd/dev/ppc/drvApple96_SCSI/Apple96CurioPublic.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /**
                     26:  * Copyright (c) 1994-1996 NeXT Software, Inc.  All rights reserved. 
                     27:  * Copyright 1997 Apple Computer Inc. All Rights Reserved.
                     28:  * @author     Martin Minow    mailto:[email protected]
                     29:  * @revision   1997.02.17      Initial conversion from AMDPCSCSIDriver sources.
                     30:  *
                     31:  * Set tabs every 4 characters.
                     32:  *
                     33:  * Apple96CurioPublic.m - Chip-specific methods for Apple96 SCSI driver.
                     34:  *
                     35:  * Edit History
                     36:  * 1997.02.18  MM              Initial conversion from AMDPCSCSIDriver sources. 
                     37:  */
                     38: #import "Apple96SCSI.h"
                     39: #import "Apple96CurioPublic.h"
                     40: #import "Apple96CurioPrivate.h"
                     41: #import "Apple96HWPrivate.h"
                     42: #import "Apple96CurioDBDMA.h"
                     43: #import "Apple96ISR.h"
                     44: #import <driverkit/generalFuncs.h>
                     45: #import <kernserv/prototypes.h>
                     46: 
                     47: @implementation Apple96_SCSI(CurioPublic)
                     48: 
                     49: /*
                     50:  * This should be extended to perform a real chip self-test.
                     51:  * (See the code in Copland DR1)
                     52:  */
                     53: - (IOReturn) hardwareChipSelfTest
                     54: {
                     55:                IOReturn                        ioReturn = IO_R_SUCCESS;
                     56:                UInt8                           chipID;
                     57:                
                     58:                ENTRY("Cst hardwareChipSelfTest");
                     59:                [self disableAllInterrupts];
                     60:        CURIOresetChip();
                     61:        CURIOwriteRegister(rCF2, CF2_ENFEATURES);
                     62:        CURIOsetCommandRegister(cNOP | bDMDEnBit);  /* DMA Nop  */
                     63:        chipID = CURIOreadRegister(rTCH);
                     64:        CURIOresetChip();
                     65:                /*
                     66:                 * Allow the user to *disable* fast and sync if they
                     67:                 * were enabled by hardware probe, but do not allow the
                     68:                 * user to enable them if the hardware does not support
                     69:                 * the feature.
                     70:                 */
                     71:                switch (chipID) {
                     72:                case 0xA2:                                              /* NCR 53cf96           */
                     73:                case 0x12:                                              /* AMD 53cf96           */
                     74:                        gOptionSyncModeSupportedByHardware = 1;
                     75:                        gOptionFastModeSupportedByHardware = 1;
                     76:                        break;
                     77:                default:                                                /* NCR 53c96            */
                     78:                        gOptionSyncModeSupportedByHardware = 0;
                     79:                        gOptionFastModeSupportedByHardware = 0;
                     80:                        break;
                     81:                }
                     82:                /*
                     83:                 * To do: write a test pattern into the fifo and check
                     84:                 * for correct count and bits.
                     85:                 */
                     86:                RESULT(ioReturn);
                     87:                return (ioReturn);
                     88: }
                     89: 
                     90: /*
                     91:  * Reusable hardware initializer function. if resetSCSIBus is TRUE, this
                     92:  * includes a SCSI reset. Handling of ioComplete of active and disconnected
                     93:  * commands must be done elsewhere. Returns IO_R_SUCCESS.
                     94:  * This is called with interrupts disabled.
                     95:  */
                     96: - (IOReturn) curioHardwareReset
                     97:                                                : (Boolean) resetSCSIBus
                     98:                        reason          : (const char *) reason
                     99: {
                    100:                IOReturn                        ioReturn = IO_R_SUCCESS;
                    101:                UInt8                           configValue;
                    102:                UInt8                           clockConversionFactor;
                    103:                UInt8                           defaultSelectionTimeout;
                    104: 
                    105:                ENTRY("Chr curioHardwareReset");
                    106:        /*
                    107:         * Temp for debugging
                    108:         */
                    109:        scsiClockRate       = kChipDefaultBusClockMHz;
                    110:                /*
                    111:                 * First of all, reset interrupts, the SCSI chip, and the DMA engine.
                    112:                 */
                    113:        CURIOresetChip();               /* Clear out the chip       */
                    114:        DBDMAreset();                   /* Stop the DMA engine      */
                    115:        CURIOreadInterruptRegister();   /* Clear pending interrupt  */
                    116:                /*
                    117:                 * Initialize the chip.
                    118:                 */
                    119:        CURIOwriteRegister(rCF2, CF2_ENFEATURES);
                    120:        CURIOsetCommandRegister(cNOP | bDMDEnBit);  /* DMA Nop  */
                    121: 
                    122:                /*
                    123:                 * Init state variables.
                    124:                 */
                    125:                gFlagCheckForAnotherInterrupt   = 0;
                    126:                gBusState                               = SCS_DISCONNECTED;
                    127:                gFlagBusBusy                                    = FALSE;
                    128:                gCurrentBusPhase                = kBusPhaseBusFree;
                    129:                /*
                    130:                 * Smash all active command state (just in case).
                    131:                 */
                    132:                gActiveCommand                  = NULL;
                    133:                gCurrentTarget                  = kInvalidTarget;
                    134:                gCurrentLUN                             = kInvalidLUN;
                    135:                gMsgInState                             = kMsgInIdle;
                    136:                gMsgOutPtr = gMsgPutPtr = gMsgOutBuffer;
                    137: 
                    138:                /*
                    139:                 * Configuration Register 1
                    140:                 *      Disable interrupt on initiator-instantiated bus reset (is this correct?)
                    141:                 *      Enable parity.
                    142:                 *      Set default bus ID (7) (This should be overriden by the Inspector)
                    143:                 */
                    144:                gInitiatorID = kDefaultInitiatorID;
                    145:                configValue = CF1_SRD | CF1_ENABPAR | gInitiatorID;
                    146:                if (gOptionExtendTiming) {
                    147:                        /*
                    148:                         * Per instance table. This slows down transfers on the bus.
                    149:                         */
                    150:                        configValue |= CF1_SLOW;
                    151:                }
                    152:                ddmInit("Configuration 1 = 0x%x\n", configValue, 2,3,4,5);
                    153:        CURIOwriteRegister(rCF1, configValue);
                    154:                /*
                    155:                 * Clock factor and select timeout.
                    156:                 */
                    157:                ASSERT(scsiClockRate != 0);
                    158:                /*
                    159:                 * Use the clock frequency (in MHz) to select the clock conversion
                    160:                 * factor. According to the NCR53CF94/96 data manual, the conversion
                    161:                 * factor is defined by the following table: Currently, we don't allow
                    162:                 * the caller to change selection timeout from the ANSI standard 250 Msec
                    163:                 * to avoid having to support floating-point register manipulation
                    164:                 */
                    165:                if (scsiClockRate < 10) {
                    166:                        IOLog("Apple96_SCSI: Clock %d MHZ too low; using 10 MHz\n",
                    167:                                 scsiClockRate);
                    168:                        scsiClockRate = 10;
                    169:                }
                    170:                if (scsiClockRate > 40) {
                    171:                        IOLog("Apple96_SCSI: Clock %d MHZ too high; using 40 MHz\n",
                    172:                                 scsiClockRate);
                    173:                        scsiClockRate = 40;
                    174:                }
                    175:                if              (scsiClockRate <= 10) {
                    176:                        clockConversionFactor = ccf10MHz;
                    177:                        defaultSelectionTimeout = SelTO16Mhz;
                    178:                }
                    179:                else if (scsiClockRate <= 15) {
                    180:                        clockConversionFactor = ccf11to15MHz;
                    181:                        defaultSelectionTimeout = SelTO16Mhz;
                    182:                }
                    183:                else if (scsiClockRate <= 20) {
                    184:                        clockConversionFactor = ccf16to20MHz;
                    185:                        defaultSelectionTimeout = SelTO16Mhz;
                    186:                }
                    187:                else if (scsiClockRate <= 25) {
                    188:                        clockConversionFactor = ccf21to25MHz;
                    189:                        defaultSelectionTimeout = SelTO25Mhz;
                    190:                }
                    191:                else if (scsiClockRate <= 30) {
                    192:                        clockConversionFactor = ccf26to30MHz;
                    193:                        defaultSelectionTimeout = SelTO33Mhz;
                    194:                }
                    195:                else if (scsiClockRate <= 35) {
                    196:                        clockConversionFactor = ccf31to35MHz;
                    197:                        defaultSelectionTimeout = SelTO40Mhz;
                    198:                }
                    199:                else {
                    200:                        clockConversionFactor = ccf31to35MHz;
                    201:                        defaultSelectionTimeout = SelTO40Mhz;
                    202:                }
                    203:                ddmInit("clockFactor %d\n", clockConversionFactor, 2,3,4,5);
                    204:        CURIOwriteRegister(rCKF, clockConversionFactor);
                    205:                ddmInit("select timeout reg 0x%x\n", defaultSelectionTimeout, 2,3,4,5);
                    206:        CURIOsetSelectionTimeout(defaultSelectionTimeout);
                    207: 
                    208:                /*
                    209:                 * Configuration Register 2 - enable extended features
                    210:                 *              - mainly, 24-bit transfer count.
                    211:                 */
                    212:        CURIOwriteRegister(rCF2, CF2_ENFEATURES);
                    213:                /*
                    214:                 * Configuration Register 3
                    215:                 */
                    216:                configValue = 0;
                    217:                if ((gOptionFastModeEnable && gOptionFastModeSupportedByHardware)
                    218:                 || scsiClockRate > 25) {
                    219:                        configValue |= CF3_FASTSCSI;
                    220:                }
                    221:                ddmInit("control3 = 0x%x\n", configValue, 2,3,4,5);
                    222:        CURIOwriteRegister(rCF3, configValue);
                    223:                /*
                    224:                 * Configuration Register 4 - glitch eater, active negation.
                    225:                 * Let's not worry about these whizzy features just yet.
                    226:                 */
                    227:        CURIOwriteRegister(rCF4, 0);
                    228:                /*
                    229:                 * Go to async xfer mode for now. Sync gets enabled on a per-target 
                    230:                 * basis in -targetContext.
                    231:                 */
                    232:        CURIOsetSynchronousOffset(0);
                    233:                /*
                    234:                 * Reset SCSI bus, wait, clear possible interrupt.
                    235:                 */
                    236:                if (resetSCSIBus) {
                    237:                        if (reason != NULL) {
                    238:                                IOLog("%s: Resetting SCSI bus (%s)\n",
                    239:                                        [self name],
                    240:                                        reason
                    241:                                );
                    242:                        }
                    243:                        else {
                    244:                                IOLog("%s: Resetting SCSI bus\n", [self name]);
                    245:                        }
                    246:            CURIOresetSCSIBus();
                    247:                        IOSleep(APPLE_SCSI_RESET_DELAY);
                    248:            CURIOreadInterruptRegister();
                    249:                        ddmInit("hardwareReset: enabling interrupts\n", 1,2,3,4,5);
                    250:                }
                    251:                ddmInit("hardwareReset: DONE\n", 1,2,3,4,5);
                    252:                RESULT(ioReturn);
                    253:                return (ioReturn);
                    254: }
                    255: 
                    256: /*
                    257:  * Terminate a DMA, including FIFO flush if necessary. Returns number of 
                    258:  * bytes transferred.
                    259:  */
                    260: - (UInt32) curioDMAComplete
                    261: {
                    262:        UInt32          fifoResidualCount;
                    263:                UInt32                  actualTransferCount;
                    264:                UInt32                  dmaResidualCount;
                    265:                UInt8                   residualByte;
                    266:                
                    267:                ENTRY("Cdc curioDMAComplete");
                    268:        DBDMAstopTransfer();
                    269:                ASSERT(gActiveCommand != NULL && gActiveCommand->scsiReq != NULL);
                    270:                /*
                    271:                 * Get residual count from DMA transfer.
                    272:                 */
                    273:        SynchronizeIO();
                    274:        dmaResidualCount = CURIOgetTransferCount();
                    275:                actualTransferCount = gActiveCommand->thisTransferLength
                    276:                                                - dmaResidualCount;
                    277:                ddmChip("curioDMAComplete (dma): thisTransferLength %d, actualTransferCount %d\n",
                    278:                        gActiveCommand->thisTransferLength, actualTransferCount, 3,4,5);
                    279:                if (actualTransferCount > gActiveCommand->thisTransferLength) {
                    280:                        ddmError("fsmDMAComplete: DMA count exceeeded, %d expected, %d transferred\n",
                    281:                                gActiveCommand->thisTransferLength,
                    282:                                actualTransferCount,
                    283:                                3, 4, 5
                    284:                        );
                    285:                }
                    286:                /*
                    287:                 * Advance the current data index. Note that gActiveCommand->currentDataIndex
                    288:                 * will exceed scsiReq->maxTransfer if the target tries to transfer too much
                    289:                 * data. We need to add a bit-bucket handler here.
                    290:                 */
                    291:                gActiveCommand->currentDataIndex += actualTransferCount;
                    292:                [ gActiveCommand->mem setPosition : gActiveCommand->currentDataIndex ];
                    293:                /*
                    294:                 * Now, see if there are any bytes lurking in the fifo.
                    295:                 */
                    296:        SynchronizeIO();
                    297:        fifoResidualCount = CURIOgetFifoCount();
                    298:                if (fifoResidualCount != 0) {
                    299:                        ddmChip("curioDMAComplete: fifoResidualCount %d\n",
                    300:                                fifoResidualCount, 2, 3,4,5);
                    301:                        if (gActiveCommand->scsiReq->read) {
                    302:                                /*
                    303:                                 * Try to move residual data from the fifo into the
                    304:                                 * user's buffer.
                    305:                                 */
                    306: /* ++ Radar xxxxxx use IOMemoryDescriptor */
                    307:                [ gActiveCommand->mem setPosition : gActiveCommand->currentDataIndex ];
                    308:                for (;;) {
                    309:                    SynchronizeIO();
                    310:                    if (CURIOgetFifoCount() == 0) {
                    311:                        break;
                    312:                                }
                    313:                    else {
                    314:                        SynchronizeIO();
                    315:                        residualByte = CURIOgetFifoByte();
                    316:                        [gActiveCommand->mem writeToClient : &residualByte count : 1];
                    317:                                gActiveCommand->currentDataIndex++;
                    318:                        }
                    319:                }
                    320:                        actualTransferCount += fifoResidualCount;                                               /* Radar 2207320        */
                    321: /* -- Radar xxxxxx use IOMemoryDescriptor */
                    322:            }
                    323:                        else {
                    324:                                CURIOflushFifo();
                    325:                                CURIOclearTransferCountZeroBit();
                    326:                                actualTransferCount                                     -= fifoResidualCount;   /* Radar 2207320        */
                    327:                                gActiveCommand->currentDataIndex        -= fifoResidualCount;
                    328:                        }
                    329:                        if (  gActiveCommand->mem )                                                                             /* Radar 2211821        */
                    330:                                [ gActiveCommand->mem setPosition : gActiveCommand->currentDataIndex ];
                    331:                }
                    332:                RESULT(actualTransferCount);
                    333:                return (actualTransferCount);
                    334: }
                    335: 
                    336: /*
                    337:  * Prepare for power down. 
                    338:  *  -- reset SCSI bus to get targets back to known state
                    339:  *  -- reset chip
                    340:  * Note: this presumes that a higher-power has cleaned out all
                    341:  * pending and in-progress commands.
                    342:  */
                    343: - (void) powerDown
                    344: {
                    345:                ENTRY("Cpd powerDown");
                    346:        DBDMAreset();                   /* Stop the DMA engine      */
                    347:        CURIOresetSCSIBus();            /* Reset the SCSI bus       */
                    348:        IOSleep(APPLE_SCSI_RESET_DELAY);    /* Stall after reset        */
                    349:        CURIOreadInterruptRegister();   /* Clear the interrupt      */
                    350:        CURIOresetChip();               /* Clear out the chip       */
                    351:        CURIOreadInterruptRegister();   /* Clear pending interrupt  */
                    352:                EXIT();
                    353: }
                    354: 
                    355: - (void) logRegisters
                    356:                        : (Boolean) examineInterruptRegister
                    357:                reason  : (const char *) reason
                    358: {
                    359: #if 1 || DEBUG
                    360:        UInt8                   currentStatus;
                    361:        UInt8                   currentInterrupt;
                    362:        UInt8                   fifoDepth;
                    363:        UInt32                  transferCount;
                    364:                
                    365:        ENTRY("Clo logRegisters");
                    366:        if (reason != NULL) {
                    367:            IOLog("%s: *** Log registers: %s\n", [self name], reason);
                    368:        }
                    369:        IOLog("%s: *** last chip status 0x%02x, interrupt 0x%02x, command 0x%02x\n", 
                    370:                [self name],
                    371:                gSaveStatus,
                    372:                gSaveInterrupt,
                    373:                CURIOreadCommandRegister()
                    374:            );
                    375:        IOLog("%s: *** bus state %s, bus phase %s, bus %s\n",
                    376:                [self name],
                    377:                IOFindNameForValue(gBusState, gAutomatonStateValues),
                    378:                IOFindNameForValue(gCurrentBusPhase, scsiPhaseValues),
                    379:                (gFlagBusBusy) ? "busy" : "free"
                    380:            );
                    381:        currentStatus = CURIOreadStatusRegister();
                    382:        if (examineInterruptRegister) {
                    383:            currentInterrupt = CURIOreadInterruptRegister();    /* Possible problem */
                    384:            IOLog("%s: *** current status %02x current intrStatus %02x\n",
                    385:                    [self name],
                    386:                    currentStatus,
                    387:                    currentInterrupt
                    388:                );
                    389:        }
                    390:        else {
                    391:            IOLog("%s: *** current status %02x\n",
                    392:                    [self name],
                    393:                    currentStatus
                    394:                );
                    395:        }
                    396:        IOLog("%s: *** syncOffset %d  syncPeriod 0x%02x\n",
                    397:                [self name],
                    398:                gLastSynchronousOffset,
                    399:                gLastSynchronousPeriod
                    400:            );
                    401:        SynchronizeIO();
                    402:        fifoDepth           = CURIOgetFifoCount();
                    403:        SynchronizeIO();
                    404:        transferCount       = CURIOgetTransferCount();
                    405:        IOLog("%s: *** fifoDepth %d  transfer count %d\n",
                    406:                [self name],
                    407:                fifoDepth,
                    408:                transferCount
                    409:            );
                    410:        if (gActiveCommand != NULL) {
                    411:            [self logCommand
                    412:                            : gActiveCommand
                    413:                logMemory   : TRUE
                    414:                    reason  : "Active Command"
                    415:                ];
                    416:        }
                    417:        [self logChannelCommandArea : reason];
                    418:        [self logIOMemoryDescriptor : reason];
                    419:        [self logTimestamp : reason];
                    420:        EXIT();
                    421: #endif /* DEBUG */
                    422: }
                    423: 
                    424: - (void) logCommand
                    425:                        : (const CommandBuffer *) commandPtr
                    426:        logMemory       : (Boolean) isLogMemoryNeeded
                    427:        reason          : (const char *) reason;
                    428: {
                    429: #if DEBUG
                    430:        ENTRY("Clc logCommand");
                    431:        if (reason == NULL) {
                    432:            reason = "";
                    433:        }
                    434:        if (commandPtr == NULL) {
                    435:            IOLog("%s: *** no command to log: %s.\n",
                    436:                    [self name],
                    437:                    reason
                    438:                );
                    439:        }
                    440:        else {
                    441:            IOLog("%s: *** %s\n",
                    442:                    [self name],
                    443:                    reason
                    444:                );
                    445:            IOLog("%s: *** %scommand at %08x, tag %02x, cdbLength %d, scsiReq %08x\n",
                    446:                    [self name],
                    447:                    (commandPtr == gActiveCommand) ? "active " : "",
                    448:                    (UInt32) commandPtr,
                    449:                    commandPtr->queueTag,
                    450:                    commandPtr->cdbLength,
                    451:                    (UInt32) commandPtr->scsiReq
                    452:                );
                    453:            IOLog("%s: *** currentDataIndex %d, saved %d, thisTransfer %d\n",
                    454:                    [self name],
                    455:                    commandPtr->currentDataIndex,
                    456:                    commandPtr->savedDataIndex,
                    457:                    commandPtr->thisTransferLength
                    458:                );
                    459:            IOLog("%s: *** active %d, is autosense %d, sense status %02x\n",
                    460:                    [self name],
                    461:                    commandPtr->flagActive,
                    462:                    commandPtr->flagIsAutosense,
                    463:                    commandPtr->autosenseStatus
                    464:                );
                    465: #if __IO_MEMORY_DESCRIPTOR_DEBUG__
                    466:            if (commandPtr->mem != NULL) {
                    467:                [commandPtr->mem debugLogWithContainer : [self name]];
                    468:            }
                    469: #endif
                    470:            if (commandPtr->scsiReq != NULL) {
                    471:                IOSCSIRequest           *scsiReq = commandPtr->scsiReq;
                    472: #if (SERIOUS_DEBUGGING || DUMP_USER_BUFFER) && __IO_MEMORY_DESCRIPTOR_DEBUG__
                    473:                if (isLogMemoryNeeded
                    474:                 && scsiReq != NULL
                    475:                 && commandPtr->mem != NULL) {
                    476:                    IOMemoryDescriptorContext   context;
                    477:                    LogicalRange            range;
                    478:                    ByteCount           newPosition = 0;
                    479: 
                    480:                    [cmdbuf->mem context : &context];
                    481:                    [cmdbuf->mem setOffset : 0];
                    482:                    while (newPosition < scsiReq->bytesTransferred
                    483:                        && [cmdbuf->mem getLogicalRange
                    484:                                        : 1
                    485:                        maxByteCount    : scsiReq->bytesTransferred - newPosition
                    486:                        newPosition     : &newPosition
                    487:                        actualRanges    : NULL
                    488:                        logicalRanges   : &range] != 0) {
                    489:                        [self logMemory : range.address
                    490:                                length          : range.length
                    491:                                reason          : "User buffer at I/O Complete"
                    492:                            ];
                    493:                        }
                    494:                    [cmdbuf->mem setContext : &context];
                    495:                }
                    496: #endif /* (SERIOUS_DEBUGGING || DUMP_USER_BUFFER) && __IO_MEMORY_DESCRIPTOR_DEBUG__ */
                    497:                IOLog("%s: *** %d.%d, cdb: "
                    498:                        "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x\n",
                    499:                        [self name],
                    500:                        scsiReq->target,
                    501:                        scsiReq->lun,
                    502:                        ((UInt8 *) &scsiReq->cdb)[0],
                    503:                        ((UInt8 *) &scsiReq->cdb)[1],
                    504:                        ((UInt8 *) &scsiReq->cdb)[2],
                    505:                        ((UInt8 *) &scsiReq->cdb)[3],
                    506:                        ((UInt8 *) &scsiReq->cdb)[4],
                    507:                        ((UInt8 *) &scsiReq->cdb)[5],
                    508:                        ((UInt8 *) &scsiReq->cdb)[6],
                    509:                        ((UInt8 *) &scsiReq->cdb)[7],
                    510:                        ((UInt8 *) &scsiReq->cdb)[8],
                    511:                        ((UInt8 *) &scsiReq->cdb)[9],
                    512:                        ((UInt8 *) &scsiReq->cdb)[10],
                    513:                        ((UInt8 *) &scsiReq->cdb)[11]
                    514:                    );
                    515:                IOLog("%s: *** read %d, disconnect %d, maxTransfer %d, bytesTransferred %d\n",
                    516:                        [self name],
                    517:                        scsiReq->read,
                    518:                        scsiReq->disconnect,
                    519:                        scsiReq->maxTransfer,
                    520:                        scsiReq->bytesTransferred
                    521:                    );
                    522:                IOLog("%s: *** driverStatus %d, scsiStatus %02x, sense: "
                    523:                        "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x\n",
                    524:                        [self name],
                    525:                        scsiReq->driverStatus,
                    526:                        scsiReq->scsiStatus,
                    527:                        ((UInt8 *) &scsiReq->senseData)[0],
                    528:                        ((UInt8 *) &scsiReq->senseData)[1],
                    529:                        ((UInt8 *) &scsiReq->senseData)[2],
                    530:                        ((UInt8 *) &scsiReq->senseData)[3],
                    531:                        ((UInt8 *) &scsiReq->senseData)[4],
                    532:                        ((UInt8 *) &scsiReq->senseData)[5],
                    533:                        ((UInt8 *) &scsiReq->senseData)[6],
                    534:                        ((UInt8 *) &scsiReq->senseData)[7],
                    535:                        ((UInt8 *) &scsiReq->senseData)[8],
                    536:                        ((UInt8 *) &scsiReq->senseData)[9],
                    537:                        ((UInt8 *) &scsiReq->senseData)[10],
                    538:                        ((UInt8 *) &scsiReq->senseData)[11]
                    539:                    );
                    540:            }
                    541:        }
                    542:        EXIT();
                    543: #endif /* DEBUG */
                    544: }
                    545: 
                    546: - (void) logTimestamp
                    547:                : (const char *) reason
                    548: {
                    549: #if DEBUG
                    550: /*
                    551:  * kMaxTimestamp should be greater than twice the expected method depth
                    552:  * since, if we dump the timestamp after it has wrapped around, we expect
                    553:  * to lose earlier entries and, hence, the shallower method starts.
                    554:  */
                    555: #ifndef kMaxTimestampStack
                    556: #define kMaxTimestampStack     64
                    557: #endif
                    558: 
                    559:        TimestampDataRecord     stack[kMaxTimestampStack + 1];  /* Allocate one extra */                        
                    560:        UInt32                  index = 0;
                    561:        int                     start;
                    562:        UInt32                  count;
                    563:        UInt32                  maxDepth = 0;
                    564:        Boolean                 wasEnabled;
                    565:        char                    work[8];
                    566:        struct timeval          tv;
                    567:        ns_time_t               lastEventTime;
                    568:        UInt32                  elapsed;
                    569:        UInt32                  sinceMethodStart;
                    570:                                
                    571:        /* ENTRY("Clt logTimestamp");   ** No ENTRY so we don't corrupt timestamps */
                    572:        if (reason != NULL) {
                    573:            IOLog("%s: *** Log timestamp: %s\n", [self name], reason);
                    574:        }
                    575:        /*
                    576:         * In case something we call causes timestamping, we want to
                    577:         * avoid getting into an infinite loop.
                    578:         */
                    579:        wasEnabled = EnableTimestamp(FALSE);
                    580:        lastEventTime = stack[0].eventTime; /* Initialization hack */
                    581:        for (count = 1; ReadTimestamp(&stack[index]); count++) {
                    582:            work[0] = (stack[index].timestampTag) >> 24 & 0xFF;
                    583:            work[1] = (stack[index].timestampTag) >> 16 & 0xFF;
                    584:            work[2] = (stack[index].timestampTag) >>  8 & 0xFF;
                    585:            work[3] = (stack[index].timestampTag) >>  0 & 0xFF;
                    586:            work[4] = '\0';
                    587:            elapsed = (unsigned) stack[index].eventTime - lastEventTime;
                    588:            lastEventTime = stack[index].eventTime;
                    589:            ns_time_to_timeval(stack[index].eventTime, &tv);                                        switch (work[0]) {
                    590:            case '+':           /* Entering a method */
                    591:                IOLog("%s: '%s' %u.%06u %u.%03u 0.0 %d\n",
                    592:                        [self name],
                    593:                        work,
                    594:                        tv.tv_sec,
                    595:                        tv.tv_usec,
                    596:                        elapsed / 1000,
                    597:                        elapsed - ((elapsed / 1000) * 1000),
                    598:                        (int) stack[index].timestampValue
                    599:                    );
                    600:                if (index < kMaxTimestampStack) {
                    601:                    ++index;
                    602:                    if (index > maxDepth) {
                    603:                        maxDepth = index;
                    604:                    }
                    605:                }
                    606:                break;
                    607:            case '=':   /* Intermediate tag: find the method start      */
                    608:            case '-':   /* End of method: find the method start         */
                    609:                sinceMethodStart = 0;
                    610:                for (start = index - 1; start >= 0; --start) {
                    611:                    if ((stack[start].timestampTag & 0x00FFFFFF)
                    612:                            == (stack[index].timestampTag & 0x00FFFFFF)) {
                    613:                        sinceMethodStart = (unsigned) stack[index].eventTime
                    614:                                        - stack[start].eventTime;
                    615:                        break;
                    616:                    }
                    617:                }
                    618:                IOLog("%s: '%s' %u.%06u %u.%03u %u.%03u %d\n",
                    619:                        [self name],
                    620:                        work,
                    621:                        tv.tv_sec,
                    622:                        tv.tv_usec,
                    623:                        elapsed / 1000,
                    624:                        elapsed - ((elapsed / 1000) * 1000),
                    625:                        sinceMethodStart / 1000,
                    626:                        sinceMethodStart - ((sinceMethodStart / 1000) * 1000),
                    627:                        (int) stack[index].timestampValue
                    628:                    );
                    629:                if (start >= 0 && work[0] == '-') {
                    630:                    index = start;              /* Pop the stack */
                    631:                }
                    632:                break;
                    633:            case '>':   /* Tag: log the value in hex                    */
                    634:            case '<':   /* Tag: log the value in hex                    */
                    635:            case '*':   /* Tag: log the value in hex                    */
                    636:                IOLog("%s: '%s' %u.%06u %u.%03u 0.0 %08x\n",
                    637:                        [self name],
                    638:                        work,
                    639:                        tv.tv_sec,
                    640:                        tv.tv_usec,
                    641:                        elapsed / 1000,
                    642:                        elapsed - ((elapsed / 1000) * 1000),
                    643:                        stack[index].timestampValue
                    644:                    );
                    645:                /* The stack does not change */
                    646:                break;
                    647:            default:
                    648:                IOLog("%s: '%s' %u.%06u %u.%03u 0.0 %08x\n",
                    649:                        [self name],
                    650:                        work,
                    651:                        tv.tv_sec,
                    652:                        tv.tv_usec,
                    653:                        elapsed / 1000,
                    654:                        elapsed - ((elapsed / 1000) * 1000),
                    655:                        stack[index].timestampValue
                    656:                    );
                    657:                    break;
                    658:            }
                    659:        }
                    660:        IOLog("%s: *** %d timestamps, %d max method depth\n",
                    661:                [self name],
                    662:                count,
                    663:                maxDepth
                    664:            );
                    665:        EnableTimestamp(wasEnabled);
                    666:        /* EXIT(); ** No EXIT to avoid corrupting timestamps */
                    667: #endif /* DEBUG */
                    668: }
                    669: 
                    670: - (void) logMemory
                    671:                        : (const void *) buffer
                    672:        length          : (UInt32) length
                    673:        reason          : (const char *) reason
                    674: {
                    675: #ifndef kMaxLogMemoryLength
                    676: #define kMaxLogMemoryLength    512
                    677: #endif
                    678: #if DEBUG
                    679:        const UInt8             *ptr;
                    680:        UInt32                  start;
                    681:        UInt32                  i;
                    682:        char                    work[32];
                    683: 
                    684:        ENTRY("Clm logMemory");
                    685:        if (reason == NULL) {
                    686:            reason = "";
                    687:        }
                    688:        IOLog("%s: *** %s: log memory from %08x for %d bytes\n",
                    689:                [self name],
                    690:                reason,
                    691:                (UInt32) buffer,
                    692:                length
                    693:            );
                    694:        if (buffer != NULL) {
                    695:            if (length > kMaxLogMemoryLength) {
                    696:                length = kMaxLogMemoryLength;
                    697:                IOLog("%s: *** Logging first %d bytes\n", [self name], length);
                    698:            }
                    699:            ptr = (const UInt8 *) buffer;
                    700:            for (start = 0; start < length; start += 16) {
                    701:                IOLog("%s: *** %08x %3d:",
                    702:                        [self name],
                    703:                        (UInt32) &ptr[start],
                    704:                        start
                    705:                    );
                    706:                for (i = 0; i < 16; i++) {
                    707:                    if ((i % 4) == 0) {
                    708:                        IOLog(" ");
                    709:                    }
                    710:                    if (start + i >= length) {
                    711:                        IOLog("  ");
                    712:                        work[i] = '\0';
                    713:                    }
                    714:                    else {
                    715:                        IOLog("%02x", ptr[start + i]);
                    716:                        work[i] = (ptr[start + i] >= ' ' && ptr[start + i] <= '~')
                    717:                                ? ptr[start + i] : '.';
                    718:                    }
                    719:                }
                    720:                work[i] = '\0';
                    721:                IOLog(" %s\n", work);
                    722:            }
                    723:        }
                    724:        EXIT();
                    725: #endif /* DEBUG */
                    726: }
                    727: 
                    728: @end   /* Apple96_SCSI(CurioPublic) */
                    729: 
                    730: /* end of Apple96_Chip.m */
                    731: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.