Annotation of kernel/bsd/dev/ppc/drvApple96_SCSI/Apple96Curio.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 1993-1995 by Apple Computer, Inc., all rights reserved.
                     28:  * Copyright 1997 Apple Computer Inc. All Rights Reserved.
                     29:  * @author  Martin Minow    mailto:[email protected]
                     30:  * @revision   1997.02.13  Initial conversion from AMDPCSCSIDriver sources.
                     31:  * Accessor functions for the 53C96 registers and commands.
                     32:  * As noted above, the class provides an instance variable defined as:
                     33:  *     volatile UInt8 *gSCSILogicalAddress             The chip's LogicalAddress
                     34:  *
                     35:  * Set tabs every 4 characters.
                     36:  * Edit History
                     37:  * 1997.02.13  MM      Initial conversion from AMDPCSCSIDriver sources. 
                     38:  * 1997.07.18  MM      Added USE_CURIO_METHODS and wrote macros for the
                     39:  *                     one-liner methods.
                     40:  */
                     41: 
                     42: #import "Apple96CurioPrivate.h"
                     43: #import "Apple96CurioPublic.h"
                     44: #import "Apple96CurioDBDMA.h"
                     45: #import "MacSCSICommand.h"
                     46: #import <driverkit/generalFuncs.h>
                     47: #import <kernserv/prototypes.h>
                     48: 
                     49: extern IONamedValue gAutomatonStateValues[];
                     50: 
                     51: @implementation Apple96_SCSI(Curio)
                     52: 
                     53: /*
                     54:  * This spin-loop looks for another chip operation - it prevents
                     55:  * exiting the interrupt service routine if the chip presents
                     56:  * another operation within ten microseconds. Note that this
                     57:  * must be called from an IOThread, not from a "real" primary
                     58:  * interrupt service routine.
                     59:  */
                     60: - (Boolean) curioQuickCheckForChipInterrupt
                     61: {
                     62:                ns_time_t                       startTime;
                     63:                ns_time_t                       endTime;
                     64:                unsigned                        elapsedNSec;
                     65:                Boolean                         result;
                     66: 
                     67:                ENTRY("Cin curioQuickCheckForChipInterrupt");
                     68:                IOGetTimestamp(&startTime);
                     69:                result = FALSE;
                     70:                do {
                     71:            if (CURIOinterruptPending()) {
                     72:                                result = TRUE;
                     73:                                break;
                     74:                        }
                     75:                        IOGetTimestamp(&endTime);
                     76:                        elapsedNSec = (unsigned) (endTime - startTime);
                     77:                } while (elapsedNSec < 10000U);
                     78:                RESULT(result);
                     79:                return (result);
                     80: }
                     81: 
                     82: /*
                     83:  * Determine if SCSI interrupt is pending. If so, store the current
                     84:  * chip state. Note that reading the interrupt register clears the
                     85:  * interrupt source, so this should be done once for each interrupt.
                     86:  */
                     87: - (Boolean) curioInterruptPending
                     88: {
                     89:        UInt8           chipStatus;
                     90:        Boolean         result = FALSE;
                     91: 
                     92: 
                     93:        ENTRY( "Cip curioInterruptPending" );
                     94: 
                     95:                /* mlj - use WHILE to check for double interrupts       */
                     96:                /* and get get most recent conditions.                          */
                     97:        while (((chipStatus = CURIOreadStatusRegister()) & sIntPend) != 0)
                     98:        {
                     99:                result = TRUE;
                    100:                gSaveStatus             = chipStatus;
                    101:                gSaveSeqStep    = CURIOreadSequenceStateRegister();
                    102:                gSaveInterrupt  = CURIOreadInterruptRegister();
                    103:        }
                    104:        RESULT( result );
                    105:        return  result;
                    106: }/* end curioInterruptPending */
                    107: 
                    108: 
                    109: /*
                    110:  * Store the current command into the fifo. If this is an autosense,
                    111:  * store a REQUEST SENSE command.
                    112:  */
                    113: - (void)               curioPutCommandIntoFifo
                    114: {
                    115:                IOSCSIRequest                   *scsiReq;
                    116:                UInt32                                  i;
                    117:                
                    118:                ENTRY("Cpc curioPutCommandIntoFifo");
                    119:                ASSERT(gActiveCommand != NULL && gActiveCommand->scsiReq != NULL);
                    120:                scsiReq = gActiveCommand->scsiReq;
                    121:                if (gActiveCommand->flagIsAutosense) {
                    122:                        UInt32                          actualAutosenseTransferLength;
                    123:                        /*
                    124:                         * This should be provided by the client (and checked that it is
                    125:                         * less than or equal to kMaxAutosenseByteCount). Note that this
                    126:                         * sequence is duplicated in Apple96HWPrivate.m.
                    127:                         */
                    128:                        actualAutosenseTransferLength = (sizeof (esense_reply_t) < kMaxAutosenseByteCount)
                    129:                                        ? (sizeof (esense_reply_t)) : kMaxAutosenseByteCount;
                    130:                        ASSERT(actualAutosenseTransferLength <= 255);
                    131:                        /*
                    132:                         * Put the autosense command into the fifo.
                    133:                         */
                    134:            CURIOputByteIntoFifo(kScsiCmdRequestSense);
                    135:            CURIOputByteIntoFifo(scsiReq->lun << 5);
                    136:            CURIOputByteIntoFifo(0);
                    137:            CURIOputByteIntoFifo(0);
                    138:            CURIOputByteIntoFifo(actualAutosenseTransferLength);
                    139:            CURIOputByteIntoFifo(0);
                    140:                }
                    141:                else {
                    142:                        /*
                    143:                         * Put the original command into the fifo.
                    144:                         */
                    145:                        for (i = 0; i < gActiveCommand->cdbLength; i++) {
                    146:                CURIOputByteIntoFifo(((UInt8 *) &scsiReq->cdb)[i]);
                    147:                        }
                    148:                }
                    149:                EXIT();
                    150: }
                    151: 
                    152: /*
                    153:  * Reset the chip to hardware power on state.
                    154:  */
                    155: - (void)               curioResetChip
                    156: {
                    157:                ENTRY("Crc curioResetChip");
                    158:        CURIOsetCommandRegister(cRstSChp);          /* Reset chip       */
                    159:                IODelay(50);                                                                    /* Chip settle          */
                    160:        CURIOnop();                                 /* Re-enable chip   */
                    161:        CURIOflushFifo();                           /* In a clean state */
                    162:        EXIT();
                    163: }
                    164: 
                    165: /**
                    166:  * The caller (hardwareReset and the bus reset interrupt handler) must delay for 250 msec
                    167:  * after resetting the bus or detecting a bus reset. This serves two purposes: "The 53C96
                    168:  * needs a vacation of about 100 msec after a reset otherwise it gets cranky" -- according
                    169:  * to notes in HALc96.c. Also, some devices don't respond if we issue another command too
                    170:  * quickly after bus reset.
                    171:  */
                    172: - (void)       curioResetSCSIBus
                    173: {
                    174:        ENTRY("Crb curioResetSCSIBus");
                    175:        SynchronizeIO();
                    176:        CURIOsetCommandRegister(cRstSBus);
                    177:                EXIT();
                    178: }
                    179: 
                    180: #if USE_CURIO_METHODS
                    181: /*
                    182:  * These are stub methods that implement the exact same code as
                    183:  * the inline macros.
                    184:  */
                    185: 
                    186: /**
                    187:  * Retrieve the status register. This can be done without disturbing
                    188:  * the chip operation state.
                    189:  */
                    190: - (UInt8)              curioReadStatusRegister
                    191: {
                    192:        return (__CURIOreadStatusRegister());
                    193: }
                    194: 
                    195: /**
                    196:  * Retrieve the internal state register. This is done after an interrupt.
                    197:  */
                    198: - (UInt8)              curioReadSequenceStateRegister
                    199: {
                    200:        return (__CURIOreadSequenceStateRegister());
                    201: }
                    202: 
                    203: /**
                    204:  * Retrieve the interrupt register. This is done after an interrupt.
                    205:  * Note: reading this register "releases" the chip. Registers must
                    206:  * be read in the following order:
                    207:  *     1.      Status (skip the rest if the interrupt bit is clear)
                    208:  *     2.      SequenceStep
                    209:  *     3.      Interrupt
                    210:  */
                    211: - (UInt8)              curioReadInterruptRegister
                    212: {
                    213:        return (__CURIOreadInterruptRegister());
                    214: }
                    215: 
                    216: /**
                    217:  * The target is in MSGI phase. Start the transfer.
                    218:  */
                    219: - (void)               curioStartMSGIAction
                    220: {
                    221:        __CURIOstartMSGIAction();
                    222: }
                    223: 
                    224: /**
                    225:  * CurioNop is a temporizing command to give the chip time to stabalize
                    226:  * its internal registers.
                    227:  */
                    228: - (void)               curioNop
                    229: {
                    230:        __CURIOnop();                               /* Restart the chip     */
                    231: }
                    232: 
                    233: /**
                    234:  * Start a byte-by-byte transfer that does not involve the DMA subsystem.
                    235:  */
                    236: - (void)               curioStartNonDMATransfer
                    237: {
                    238:        __CURIOstartNonDMATransfer();           /* Start a non-DMA transfer     */
                    239: }
                    240: 
                    241: /**
                    242:  * Start a DMA transfer.
                    243:  */
                    244: - (void)               curioStartDMATransfer
                    245:                                                : (UInt32) transferCount
                    246: {
                    247:                ENTRY("Cds curioStartDMATransfer");
                    248:        __CURIOstartDMATransfer(transferCount);
                    249:                EXIT();
                    250: }
                    251: 
                    252: - (void)               curioTransferPad
                    253:                                                : (Boolean) forOutput
                    254: {
                    255:        __CURIOtransferPad(forOutput);
                    256: }
                    257: 
                    258: /**
                    259:  * CurioClearTransferCountZeroBit
                    260:  * This is called after DMA transfers to stabalize the DMA and clear its fifo.
                    261:  * It is needed to keep the process alive in the following sequence:
                    262:  *     DATO            Start DMA transfer to the target
                    263:  *     MSGI            Target changes to message in in order to disconnect.
                    264:  */
                    265: - (void)               curioClearTransferCountZeroBit
                    266: {
                    267:        __CURIOclearTransferCountZeroBit();     /* Clear TC zero bit        */
                    268: }
                    269: 
                    270: /**
                    271:  * Return the current transfer count. This is generally zero after DMA, but will be
                    272:  * non-zero if some data was not transferred.
                    273:  */
                    274: - (UInt32)             curioGetTransferCount
                    275: {
                    276:                UInt32                                  result;
                    277: 
                    278:                ENTRY("Cgt curioGetTransferCount");
                    279:        result = __CURIOgetTransferCount();
                    280:                RESULT(result);
                    281:                return (result);
                    282: }
                    283: 
                    284: /** 
                    285:  * Load the target destination id register.
                    286:  */
                    287: - (void)               curioSetDestinationID
                    288:                                                : (UInt8) targetID
                    289: {
                    290:        __CURIOsetDestinationID(targetID);
                    291: }
                    292: 
                    293: /**
                    294:  * Start an initiator-initiated command-complete sequence.
                    295:  */
                    296: - (void)               curioInitiatorCommandComplete
                    297: {
                    298:        __CURIOinitiatorCommandComplete();
                    299: }
                    300: 
                    301: /**
                    302:  * The bus is (presumably) free: allow us to be reselected.
                    303:  */
                    304: - (void)               curioEnableSelectionOrReselection
                    305: {
                    306:        __CURIOenableSelectionOrReselection();
                    307: }
                    308: 
                    309: /**
                    310:  * Disconnect from the SCSI bus.
                    311:  */
                    312: - (void)               curioDisconnect
                    313: {
                    314:        __CURIOdisconnect();
                    315: }
                    316: 
                    317: 
                    318: /**
                    319:  * Manipulate the FIFO
                    320:  * CurioGetFifoByte                    Return the current fifo byte.
                    321:  * CurioPutByteIntoFifo                Store a byte into the fifo
                    322:  * CurioFlushFifo                      Clear the fifo
                    323:  * CurioGetFifoCount           Get the number of bytes in the fifo.
                    324:  *                                                     Note: the fifo only holds 16 bytes. For some reason,
                    325:  *                                                     we ignore the 0x10 bit (follows Copland DR1 debugging).
                    326:  */
                    327: - (UInt8)              curioGetFifoByte
                    328: {
                    329:        return (__CURIOgetFifoByte());
                    330: }
                    331: 
                    332: - (void)               curioPutByteIntoFifo
                    333:                                        : (UInt8) theByte
                    334: {
                    335:        __CURIOputByteIntoFifo(theByte);
                    336: }
                    337: 
                    338: - (void)               curioFlushFifo
                    339: {
                    340:        __CURIOflushFifo();
                    341: }
                    342: 
                    343: - (UInt32)             curioGetFifoCount
                    344: {
                    345:        return (__CURIOgetFifoCount());
                    346: }
                    347:                
                    348: /**
                    349:  * Configure the 53C96 chip.
                    350:  */
                    351: - (void)               curioSetSelectionTimeout
                    352:                                                : (UInt8) selectionTimeout
                    353: {
                    354:        __CURIOsetSelectionTimeout(selectionTimeout);
                    355: }
                    356: 
                    357: - (void)               curioConfigForNonDMA
                    358: {
                    359:        __CURIOconfigForNonDMA();
                    360: }
                    361: 
                    362: - (void)               curioConfigForDMA
                    363: {
                    364:        __CURIOconfigForDMA();
                    365: }
                    366: 
                    367: /**
                    368:  * Manage Message Phase
                    369:  */
                    370: - (void)               curioMessageAccept
                    371: {
                    372:        __CURIOmessageAccept();
                    373: }
                    374: 
                    375: - (void)               curioMessageReject
                    376: {
                    377:        __CURIOmessageReject();
                    378: }
                    379: 
                    380: - (void)               curioSetATN
                    381: {
                    382:        __CURIOsetATN();
                    383: }
                    384: 
                    385: - (void)               curioClearATN
                    386: {
                    387:        __CURIOclearATN();
                    388: }
                    389: 
                    390: 
                    391: /*
                    392:  * Sync negotiation methods 
                    393:  * To do: don't load a register if its shadow has the same value..
                    394:  */
                    395: - (void)               curioSetSynchronousOffset
                    396:                                                : (UInt8) synchronousOffset
                    397: {
                    398:        __CURIOsetSynchronousOffset(synchronousOffset);
                    399: }
                    400: 
                    401: - (void)               curioSetSynchronousPeriod
                    402:                                                : (UInt8) synchronousPeriod
                    403: {
                    404:        __CURIOsetSynchronousPeriod(synchronousPeriod);
                    405: }
                    406: 
                    407: /**
                    408:  * Write a random register (used for configuration registers)
                    409:  */
                    410: - (void)               curioWriteRegister
                    411:                                                : (UInt8)       curioRegister
                    412:                value                   : (UInt8)       value
                    413: {
                    414:        __CURIOwriteRegister(curioRegister, value);
                    415: }
                    416: 
                    417: /**
                    418:  * Read a random register (used for configuration registers)
                    419:  */
                    420: - (UInt8)              curioReadRegister
                    421:                                                : (UInt8)       curioRegister
                    422: {
                    423:        return (__CURIOreadRegister(curioRegister));
                    424: }
                    425: 
                    426: /**
                    427:  * This is the only place that the command register is written.
                    428:  */
                    429: - (void)               curioSetCommandRegister
                    430:                : (UInt8) commandByte
                    431: {
                    432:        __CURIOsetCommandRegister(commandByte);
                    433: }
                    434: 
                    435: /**
                    436:  * Error recovery needs to peek at the last command
                    437:  */
                    438: - (UInt8)              curioReadCommandRegister
                    439: {
                    440:        return (__CURIOreadCommandRegister());
                    441: }
                    442: 
                    443: /*
                    444:  * Convert the selection timeout to the value that must be stored in the
                    445:  * chip registers.
                    446:  */
                    447: - (UInt32)  curioSelectTimeout
                    448:                        : (UInt32)  selectTimeoutMSec
                    449:     curioClockMHz      : (UInt32)  chipClockRateMHz
                    450:     curioClockFactor   : (UInt32)  chipClockFactor
                    451: {
                    452:        return (
                    453:                __CURIOsetSelectTimeout(
                    454:                    selectTimeoutMSec,
                    455:                    chipClockRateMHz,
                    456:                    chipClockFactor)
                    457:            );
                    458: }
                    459: #endif /* USE_CURIO_METHODS */
                    460: 
                    461: @end /* Apple96_SCSI(Curio) */
                    462: 
                    463: #if USE_CURIO_METHODS || WRITE_CHIP_OPERATION_INTO_TIMESTAMP_LOG
                    464: volatile UInt8
                    465: __CurioReadRegister__(
                    466:                volatile UInt8          *scsiLogicalAddress,
                    467:                UInt32                          index
                    468:     )
                    469: {
                    470:        volatile UInt8                  result = scsiLogicalAddress[index];
                    471:        const char                              *why;
                    472:        const char                              *what;
                    473:        switch (index) {
                    474:        case rXCL:      what    = "XCL";        break;
                    475:        case rXCM:      what    = "XCM";        break;
                    476:        case rFFO:      what    = "FFO";        break;
                    477:        case rCMD:      what    = "CMD";        break;
                    478:        case rSTA:      what    = "STA";        break;
                    479:        case rINT:      what    = "INT";        break;
                    480:        case rSQS:      what    = "SQS";        break;
                    481:        case rFOS:      what    = "FOS";        break;
                    482:        case rCF1:      what    = "CF1";        break;
                    483:        case rCKF:      what    = "CKF";        break;
                    484:        case rTST:      what    = "TST";        break;
                    485:        case rCF2:      what    = "CF2";        break;
                    486:        case rCF3:      what    = "CF3";        break;
                    487:        case rCF4:      what    = "CF4";        break;
                    488:        case rTCH:      what    = "TCH";        break;
                    489:        case rDMA:      what    = "DMA";        break;
                    490:        default:        what    = "?\?\?";      break;
                    491:        }
                    492:        RAW_TAG(OSTag('<', what), (index << 8) | result);
                    493:        return (result);
                    494: }
                    495: 
                    496: void
                    497: __CurioWriteRegister__(
                    498:                volatile UInt8          *scsiLogicalAddress,
                    499:                UInt32                          index,
                    500:                UInt8                           value
                    501:     )
                    502: {
                    503:        const char                              *what;
                    504:        switch (index) {
                    505:        case rXCL:      what    = "XCL";        break;
                    506:        case rXCM:      what    = "XCM";        break;
                    507:        case rFFO:      what    = "FFO";        break;
                    508:        case rCMD:      what    = "CMD";        break;
                    509:        case rSTA:      what    = "DST";        break;
                    510:        case rINT:      what    = "TMO";        break;
                    511:        case rSQS:      what    = "SQS";        break;
                    512:        case rFOS:      what    = "FOS";        break;
                    513:        case rCF1:      what    = "CF1";        break;
                    514:        case rCKF:      what    = "CKF";        break;
                    515:        case rTST:      what    = "TST";        break;
                    516:        case rCF2:      what    = "CF2";        break;
                    517:        case rCF3:      what    = "CF3";        break;
                    518:        case rCF4:      what    = "CF4";        break;
                    519:        case rTCH:      what    = "TCH";        break;
                    520:        case rDMA:      what    = "DMA";        break;
                    521:        default:        what    = "?\?\?";      break;
                    522:        }
                    523:        RAW_TAG(OSTag('>', what), (index << 8) | value);
                    524:        scsiLogicalAddress[index] = value;
                    525: }
                    526: #endif /* USE_CURIO_METHODS */
                    527: 

unix.superglobalmegacorp.com

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