Annotation of XNU/iokit/Drivers/scsi/drvMESH/mesh.h, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: 
                     23:        /**
                     24:         * Copyright � 1997-2000 Apple Computer Inc. All Rights Reserved.
                     25:         * @author   Mike Johnson
                     26:         *
                     27:         * Set tabs every 4 characters.
                     28:         *
                     29:         * Edit History
                     30:         * 25feb99   mlj      Initial conversion from banana.
                     31:         */
                     32: 
                     33: 
                     34: 
                     35:        /*****  For fans of kprintf, IOLog and debugging infrastructure of the  *****/
                     36:        /*****  string ilk, please modify the ELG and PAUSE macros or their             *****/
                     37:        /*****  associated EvLog and Pause functions to suit your taste. These  *****/
                     38:        /*****  macros currently are set up to log events to a wraparound               *****/
                     39:        /*****  buffer with minimal performance impact. They take 2 UInt32              *****/
                     40:        /*****  parameters so that when the buffer is dumped 16 bytes per line, *****/
                     41:        /*****  time stamps (~1 microsecond) run down the left side while               *****/
                     42:        /*****  unique 4-byte ASCII codes can be read down the right side.              *****/
                     43:        /*****  Preserving this convention facilitates different maintainers    *****/
                     44:        /*****  using different debugging styles with minimal code clutter.             *****/
                     45: 
                     46: #define USE_ELG   false                                // for debugging
                     47: #define kEvLogSize  (4096*16)          // 16 pages = 64K = 4096 events
                     48: 
                     49: #if USE_ELG /* (( */
                     50: #define ELG(A,B,ASCI,STRING)    EvLog( (UInt32)(A), (UInt32)(B), (UInt32)(ASCI), STRING )
                     51: #define PAUSE(A,B,ASCI,STRING)  Pause( (UInt32)(A), (UInt32)(B), (UInt32)(ASCI), STRING )
                     52: #else /* ) not USE_ELG: (   */
                     53: #define ELG(A,B,ASCI,S)
                     54: #define PAUSE(A,B,ASCI,STRING) IOLog( "MESH: %8x %8x " STRING "\n", (unsigned int)(A), (unsigned int)(B) )
                     55: #endif /* USE_ELG )) */
                     56: 
                     57: 
                     58: #ifndef SynchronizeIO
                     59: #define SynchronizeIO()     eieio()     /* TEMP */
                     60: #endif /* SynchronizeIO */
                     61: 
                     62:        enum { kMaxAutosenseByteCount = 255 };
                     63: 
                     64:        enum
                     65:        {
                     66:            kMESHRegisterBase   = 0,
                     67:            kDBDMARegisterBase  = 1,
                     68:            kNumberRegisters    = 2
                     69:        };
                     70: 
                     71:         /* Operation flags and options: */
                     72: 
                     73:     typedef enum BusPhase   /* These are the real SCSI bus phases (from busStatus0):   */
                     74:     {
                     75:         kBusPhaseDATO   = 0,
                     76:         kBusPhaseDATI,
                     77:         kBusPhaseCMD,
                     78:         kBusPhaseSTS,
                     79:         kBusPhaseReserved1,
                     80:         kBusPhaseReserved2,
                     81:         kBusPhaseMSGO,
                     82:         kBusPhaseMSGI
                     83:     } BusPhase;
                     84: 
                     85:         /* Command to be executed by IO thread.                     */
                     86:         /* These are ultimately derived from ioctl control values.  */
                     87: 
                     88:     typedef enum
                     89:     {   kCommandExecute,            /* Execute IOSCSIRequest    */
                     90:         kCommandResetBus,           /* Reset bus                */
                     91:         kCommandAbortRequest        /* Abort IO thread          */
                     92:     } CommandOperation;
                     93: 
                     94:         /* We read target messages using a simple state machine.    */
                     95:         /* On entrance to MSGI phase, fMsgInState = kMsgInInit.     */
                     96:         /* Continue reading messages until either                   */
                     97:         /* fMsgInState == kMsgInReady or the target changes phase   */
                     98:         /* (which is an error).                                     */
                     99:     typedef enum MsgInState
                    100:     {
                    101:         kMsgInInit = 0,     /*  0 Not reading a message (must be zero)      */
                    102:         kMsgInReading,      /*  1 MSG input state: reading counted data     */
                    103:         kMsgInCounting,     /*  2 MSG input state: reading count byte       */
                    104:         kMsgInReady         /*  3 MSG input state: a msg is now available   */
                    105:     } MsgInState;
                    106: 
                    107:                /* These values represent no active request:    */
                    108:     enum
                    109:     {   kInvalidTarget = 0xFF,
                    110:         kInvalidLUN            = 0xFF,
                    111:                kInvalidTag             = 0xFFFFFFFF
                    112:     };
                    113: 
                    114:         /* The default initiator bus ID (needs to be fetched from NVRAM).    */
                    115:     enum
                    116:        {
                    117:                kInitiatorIDDefault = 7,
                    118:                kMaxTargetID            = 8,
                    119:                kMaxDMATransfer         = 0xF000ul,
                    120:                kMaxMemCursorSegs       = 15
                    121:        };
                    122: #define APPLE_SCSI_RESET_DELAY  250 /* Msec */
                    123: 
                    124: 
                    125: 
                    126: 
                    127:     typedef struct MeshRegister     /* Mesh registers:  */
                    128:     {
                    129:         volatile UInt8      transferCount0;     UInt8   pad00[ 0x0F ];
                    130:         volatile UInt8      transferCount1;     UInt8   pad01[ 0x0F ];
                    131:         volatile UInt8      xFIFO;              UInt8   pad02[ 0x0F ];
                    132:         volatile UInt8      sequence;           UInt8   pad03[ 0x0F ];
                    133:         volatile UInt8      busStatus0;         UInt8   pad04[ 0x0F ];
                    134:         volatile UInt8      busStatus1;         UInt8   pad05[ 0x0F ];
                    135:         volatile UInt8      FIFOCount;          UInt8   pad06[ 0x0F ];
                    136:         volatile UInt8      exception;          UInt8   pad07[ 0x0F ];
                    137:         volatile UInt8      error;              UInt8   pad08[ 0x0F ];
                    138:         volatile UInt8      interruptMask;      UInt8   pad09[ 0x0F ];
                    139:         volatile UInt8      interrupt;          UInt8   pad10[ 0x0F ];
                    140:         volatile UInt8      sourceID;           UInt8   pad11[ 0x0F ];
                    141:         volatile UInt8      destinationID;      UInt8   pad12[ 0x0F ];
                    142:         volatile UInt8      syncParms;          UInt8   pad13[ 0x0F ];
                    143:         volatile UInt8      MESHID;             UInt8   pad14[ 0x0F ];
                    144:         volatile UInt8      selectionTimeOut;
                    145:     } MeshRegister;
                    146: 
                    147:         /* The following structure shadows the MESH chip registers: */
                    148: 
                    149:     typedef union MESHShadow
                    150:     {   UInt32      longWord[ 3 ];      /* for debugging ease.                  */
                    151:         struct
                    152:         {   UInt8   interrupt;          /* Interrupt                            */
                    153:             UInt8   error;              /* Error register                       */
                    154:             UInt8   exception;          /* Exception register                   */
                    155:             UInt8   FIFOCount;          /* FIFO count                           */
                    156: 
                    157:             UInt8   busStatus0;         /* Bus phase + REQ, ACK, & ATN signals  */
                    158:             UInt8   busStatus1;         /* RST, BSY, SEL                        */
                    159:             UInt8   interruptMask;      /* Interrupt mask for debugging         */
                    160:             UInt8   transferCount0;     /* low  order byte of transfer count    */
                    161: 
                    162:             UInt8   transferCount1;     /* high order byte of transfer count    */
                    163:             UInt8   sequence;           /* Sequence register                    */
                    164:             UInt8   syncParms;          /* syncParms for debugging              */
                    165:             UInt8   destinationID;      /* Target ID                            */
                    166:         } mesh;
                    167:     } MESHShadow;
                    168: 
                    169:         /* MESH Register set offsets    */
                    170: 
                    171:     enum
                    172:     {
                    173:         kMeshTransferCount0 =   0x00,
                    174:         kMeshTransferCount1 =   0x10,
                    175:         kMeshFIFO           =   0x20,
                    176:         kMeshSequence       =   0x30,
                    177:         kMeshBusStatus0     =   0x40,
                    178:         kMeshBusStatus1     =   0x50,
                    179:         kMeshFIFOCount      =   0x60,
                    180:         kMeshException      =   0x70,
                    181:         kMeshError          =   0x80,
                    182:         kMeshInterruptMask  =   0x90,
                    183:         kMeshInterrupt      =   0xA0,
                    184:         kMeshSourceID       =   0xB0,
                    185:         kMeshDestinationID  =   0xC0,
                    186:         kMeshSyncParms      =   0xD0,
                    187:         kMeshMESHID         =   0xE0,
                    188:         kMeshSelTimeOut     =   0xF0
                    189:     };
                    190: 
                    191:        enum { kMeshMESHID_Value = 0x02 };     /* Read value of kMESHID lo 5 bits only */
                    192: 
                    193: 
                    194:         /* MESH commands & modifiers for Sequence register: */
                    195: 
                    196:     typedef enum
                    197:     {
                    198:         kMeshNoOpCmd            =   0x00,
                    199:         kMeshArbitrateCmd       =   0x01,
                    200:         kMeshSelectCmd          =   0x02,
                    201:         kMeshCommandCmd         =   0x03,
                    202:         kMeshStatusCmd          =   0x04,
                    203:         kMeshDataOutCmd         =   0x05,
                    204:         kMeshDataInCmd          =   0x06,
                    205:         kMeshMessageOutCmd      =   0x07,
                    206:         kMeshMessageInCmd       =   0x08,
                    207:         kMeshBusFreeCmd         =   0x09,
                    208:                                                                        /* non interrupting:    */
                    209:         kMeshEnableParity       =   0x0A,
                    210:         kMeshDisableParity      =   0x0B,
                    211:         kMeshEnableReselect     =   0x0C,
                    212:         kMeshDisableReselect    =   0x0D,
                    213:         kMeshResetMESH          =   0x0E,
                    214:         kMeshFlushFIFO          =   0x0F,
                    215:             /* Sequence command modifier bits:  */
                    216:         kMeshSeqDMA     =   0x80,   /* Data Xfer for this command will use DMA  */
                    217:         kMeshSeqTMode   =   0x40,   /* Target mode - unused                     */
                    218:         kMeshSeqAtn     =   0x20    /* ATN is to be asserted after command      */
                    219:     } MeshCommand;
                    220: 
                    221:                /* The bus Status Registers 0 & 1 have the actual       */
                    222:                /* bus signals AT TIME OF READ.                                         */
                    223: 
                    224:     enum                        /* bus Status Register 0 bits:  */
                    225:     {
                    226:         kMeshIO     =   0x01,   /* phase bit    */
                    227:         kMeshCD     =   0x02,   /* phase bit    */
                    228:         kMeshMsg    =   0x04,   /* phase bit    */
                    229:         kMeshAtn    =   0x08,   /* Attention signal */
                    230:         kMeshAck    =   0x10,   /* Ack signal       */
                    231:         kMeshReq    =   0x20,   /* Request signal   */
                    232:         kMeshAck32  =   0x40,   /* unused - 32 bit bus  */
                    233:         kMeshReq32  =   0x80    /* unused - 32 bit bus  */
                    234:     };
                    235: 
                    236:     enum { kMeshPhaseMask = (kMeshMsg + kMeshCD + kMeshIO)   };
                    237: 
                    238:     enum                     /* bus Status Register 1 bits:  */
                    239:     {
                    240:         kMeshSel =   0x20,   /* Select signal    */
                    241:         kMeshBsy =   0x40,   /* Busy signal      */
                    242:         kMeshRst =   0x80    /* Reset signal     */
                    243:     };
                    244: 
                    245:     enum                                 /* Exception Register bits:   */
                    246:     {
                    247:         kMeshExcSelTO           =   0x01,   /* Selection timeout    */
                    248:         kMeshExcPhaseMM         =   0x02,   /* Phase mismatch       */
                    249:         kMeshExcArbLost         =   0x04,   /* lost arbitration     */
                    250:         kMeshExcResel           =   0x08,   /* reselection occurred */
                    251:         kMeshExcSelected        =   0x10,
                    252:         kMeshExcSelectedWAtn    =   0x20
                    253:     };
                    254: 
                    255:     enum                                    /* Error Register bits:     */
                    256:     {
                    257:         kMeshErrParity0         =   0x01,   /* parity error             */
                    258:         kMeshErrParity1         =   0x02,   /* unused - 32 bit bus      */
                    259:         kMeshErrParity2         =   0x04,   /* unused - 32 bit bus      */
                    260:         kMeshErrParity3         =   0x08,   /* unused - 32 bit bus      */
                    261:         kMeshErrSequence        =   0x10,   /* Sequence error           */
                    262:         kMeshErrSCSIRst         =   0x20,   /* Reset signal asserted    */
                    263:         kMeshErrDisconnected    =   0x40    /* unexpected disconnect    */
                    264:     };
                    265: 
                    266:     enum                                    /* Interrupt Register bits: */
                    267:     {
                    268:         kMeshIntrCmdDone    =   0x01,       /* command done             */
                    269:         kMeshIntrException  =   0x02,       /* exception occurred       */
                    270:         kMeshIntrError      =   0x04,       /* error     occurred       */
                    271:         kMeshIntrMask       =   (kMeshIntrCmdDone | kMeshIntrException | kMeshIntrError)
                    272:     };
                    273: 
                    274: 
                    275:     enum        /* Values for SyncParms MESH register:      */
                    276:     {           /* 1st nibble is offset, 2nd is period.     */
                    277:                 /* Zero offset means async.                 */
                    278:         kSyncParmsAsync = 0x02, /* Async with min period = 2            */
                    279:         kSyncParmsFast  = 0xF0  /* offset = 15, period = Fast (10 MB/s) */
                    280:     };
                    281: 
                    282:         /* The following are specific to the MESH CCL               */
                    283:         /* Stage Names. (These were originally 'xxxx' identifiers,  */
                    284:         /* which is convenient for debugging, but results in many   */
                    285:         /* warning messages from the NeXT compiler.                 */
                    286:     enum
                    287:     {                                                          /* kcclStageLabel:      */
                    288:         kcclStageIdle   = 0,        /*  0 - 'Idle'             */
                    289:         kcclStageInit,              /*  1 - 'Init'             */
                    290:         kcclStageCCLx,              /*  2 - 'CCL~'             */
                    291:         kcclStageArb,               /*  3 - ' Arb'             */
                    292:         kcclStageSelA,              /*  4 - 'SelA'             */
                    293:         kcclStageMsgO,              /*  5 - 'MsgO'             */
                    294:         kcclStageCmdO,              /*  6 - 'CmdO'             */
                    295:         kcclStageXfer,              /*  7 - 'Xfer'             */
                    296:         kcclStageBucket,            /*  8 - 'Buck'             */
                    297:         kcclStageSyncHack,          /*  9 - 'Hack'             */
                    298:         kcclStageStat,              /*  A - ' Sta'             */
                    299:         kcclStageMsgI,              /*  B - 'MsgI'             */
                    300:         kcclStageFree,              /*  C - 'Free'             */
                    301:         kcclStageGood,              /*  D - 'Good'             */
                    302:         kcclStageStop,              /*  E - '++++'             */
                    303:         kcclTerminatorWithoutComma
                    304:     };
                    305: 
                    306:     /* offsets into the Channel Command List page:  */
                    307: 
                    308: #define kcclProblem     0x00    // Interrupt & Stop channel commands for anomalies
                    309: #define kcclCMDOdata    0x20    // reserve for 6, 10, 12 byte commands
                    310: #define kcclMSGOdata    0x30    // reserve for Identify, Tag stuff
                    311: #define kcclMSGOLast    0x3F    // reserve for last or only msg0ut byte
                    312: #define kcclMSGIdata    0x40    // reserve for Message In data
                    313: #define kcclBucket      0x48    // Bit Bucket
                    314: #define kcclStatusData  0x4F    // reserve for Status byte
                    315: #define kcclSenseCDB    0x50    // CDB for (auto) Sense
                    316: #define kcclBatchSize   0x60    // Current MESH batch size
                    317: #define kcclStageLabel  0x6C    // storage for label of last stage entered.
                    318: #define kcclSense       0x70    // Channel Commands for (Auto)Sense
                    319: #define kcclPrototype   0xC0    // Prototype MESH 4-command Transfer sequence
                    320: #define kcclReadBuf8    0x100   // Buffer for non-8-byte-aligned reads
                    321: #define kcclStart       0x120   // Channel Program starts here with Arbitrate
                    322: #define kcclBrProblem   0x140   // channel command to wait for cmdDone & Br if problem
                    323: #define kcclMsgoStage   0x190   // Branch to single byte Message-Out
                    324: #define kcclMsgoBranch  0x1B0   // Branch to single byte Message-Out
                    325: #define kcclMsgoMTC     0x1D8   // MESH Transfer Count for MSGO (low order only)
                    326: #define kcclMsgoDTC     0x1F0   // DMA  Transfer Count for MSGO (low order only)
                    327: #define kcclLastMsgo    0x210   // Channel commands to put last/only byte of Message-Out
                    328: #define kcclCmdoStage   0x290   // Start of Command phase
                    329: #define kcclCmdoMTC     0x2C8   // MESH Transfer Count for CMDO (low order only)
                    330: #define kcclCmdoDTC     0x2E0   // DMA  Transfer Count for CMDO (low order only)
                    331: #define kcclReselect    0x2F0   // Reselect enters CCL here - Branch to xfer data
                    332: #define kcclOverrun     0x320   // data overrun - dump the excess in the bit bucket
                    333: #define kcclOverrunMESH 0x370   // data overrun - patch the MESH Seq Reg I/O
                    334: #define kcclOverrunDBDMA 0x380  // data overrun - patch the DBDMA I/O
                    335: #define kcclSyncCleanUp 0x3B0   // clean up at end of Sync xfer
                    336: #define kcclGetStatus   0x3D0   // Finish up with Status, Message In, and Bus Free
                    337: #define kcclMESHintr    0x4D0   // transaction done or going well
                    338: #define kcclSenseBuffer 0x500   // Buffer for Autosense data
                    339: #define kcclDataXfer    0x600   // INPUT or OUTPUT channel commands for data
                    340: #define kcclSenseResult 0x63C   // Result field in Sense INPUT channel command
                    341: 
                    342: 
                    343:     /* generic relocation types:    */
                    344: 
                    345: #define kRelNone    0x00    /* default - no relocation                      */
                    346: #define kRelMESH    0x01    /* Relocate to MESH register area               */
                    347: #define kRelCP      0x02    /* Relocate to Channel Program area             */
                    348: #define kRelCPdata  0x03    /* Relocate to Channel Program data structure   */
                    349: #define kRelPhys    0x04    /* Relocate to user Physical address space      */
                    350: #define kRelNoSwap  0x05    /* don't relocate or swap (Label)               */
                    351: 
                    352:     /* Relocatable ADDRESS types:   */
                    353: 
                    354: #define kRelAddress         0xFF        <<8 /* relocatable address mask         */
                    355: #define kRelAddressMESH     kRelMESH    <<8 /* MESH physical address            */
                    356: #define kRelAddressCP       kRelCP      <<8 /* Channel Program Physical address */
                    357: #define kRelAddressPhys     kRelPhys    <<8 /* User data Physical address       */
                    358: 
                    359:     /* Relocatable COMMAND-DEPENDENT types: */
                    360: 
                    361: #define kRelCmdDep      0xFF        /* relocatable command-dependent mask           */
                    362: #define kRelCmdDepCP    kRelCP      /* Channel Program command-dependent (branch)   */
                    363: #define kRelCmdDepLabel kRelNoSwap  /* Channel Program label - don't swap           */
                    364: 
                    365: 
                    366:     /* Channel Program macros:  */
                    367: 
                    368: #define STAGE(v)        STORE_QUAD  | KEY_SYSTEM    | 4, kcclStageLabel, v, kRelAddressCP | kRelCmdDepLabel
                    369: #define CLEAR_CMD_DONE  STORE_QUAD  | KEY_SYSTEM    | 1, kMeshInterrupt, kMeshIntrCmdDone, kRelAddressMESH
                    370: #define CLEAR_INT_REG   STORE_QUAD  | KEY_SYSTEM    | 1, kMeshInterrupt, kMeshIntrMask, kRelAddressMESH
                    371: #define CLR_PHASEMM     STORE_QUAD  | KEY_SYSTEM    | 1, kMeshInterrupt, kMeshIntrCmdDone | kMeshIntrException, kRelAddressMESH
                    372: #define MOVE_1(a,v,r)   STORE_QUAD  | KEY_SYSTEM    | 1, a, v, r
                    373: #define MOVE_4(a,v,r)   STORE_QUAD  | KEY_SYSTEM    | 4, a, v, r
                    374: #define MESH_REG(a,v)   STORE_QUAD  | KEY_SYSTEM    | 1, a, v, kRelAddressMESH
                    375: #define MESH_REG_WAIT(a,v)  STORE_QUAD  | KEY_SYSTEM | kWaitIfTrue | 1, a, v, kRelAddressMESH
                    376: 
                    377: #define SENSE(c)        INPUT_LAST  | kBranchIfFalse | kWaitIfTrue | c, kcclSenseBuffer,  kcclProblem, kRelAddressCP   | kRelCmdDepCP
                    378: #define MSGO(a,c)       OUTPUT_LAST | kBranchIfFalse | kWaitIfTrue | c, a,                kcclProblem, kRelAddressCP   | kRelCmdDepCP
                    379: #define CMDO(c)         OUTPUT_LAST | kBranchIfFalse | kWaitIfTrue | c, kcclCMDOdata,     kcclProblem, kRelAddressCP   | kRelCmdDepCP
                    380: #define MSGI(c)         INPUT_LAST  | kBranchIfFalse | kWaitIfTrue | c, kcclMSGIdata,     kcclProblem, kRelAddressCP   | kRelCmdDepCP
                    381: #define STATUS_IN       INPUT_LAST  | kBranchIfFalse | kWaitIfTrue | 1, kcclStatusData,   kcclProblem, kRelAddressCP   | kRelCmdDepCP
                    382: #define BUCKET          INPUT_LAST  | kBranchIfFalse               | 8, kcclBucket,       kcclProblem, kRelAddressCP   | kRelCmdDepCP
                    383: 
                    384: #define BRANCH(a)        NOP_CMD | kBranchAlways,                0, a, kRelCmdDepCP
                    385: #define BR_IF_PROBLEM    NOP_CMD | kBranchIfFalse | kWaitIfTrue, 0, kcclProblem, kRelCmdDepCP
                    386: #define BR_NO_PROBLEM(a) NOP_CMD | kBranchIfTrue               , 0, a, kRelCmdDepCP
                    387: #define STOP(L)          STOP_CMD,                               0, L, kRelCmdDepLabel
                    388: #define INTERRUPT(a)     NOP_CMD | kIntAlways, 0, a, 0
                    389: #define RESERVE          0xCEFECEFE, 0xCEFECEFE, 0xCEFECEFE, 0xCEFECEFE
                    390: #define WAIT_4_CMDDONE   NOP_CMD | kWaitIfTrue, 0, 0, 0
                    391: 
                    392: #define SWAP(x) (UInt32)OSSwapInt32( (UInt32)(x) )
                    393: 
                    394: 
                    395:         /* Return values from startCommand:    */
                    396: 
                    397:        enum
                    398:     {   kHardwareStartOK,       /* command started successfully */
                    399:                kHardwareStartBusy
                    400:     };
                    401: 
                    402: 
                    403: 
                    404:                /**** THESE NEED TO BE VOLATILE *****/
                    405:        struct DBDMAChannelRegisters            /*  DBDMA channel registers:    */
                    406:        {
                    407:                volatile UInt32         channelControl;
                    408:                volatile UInt32         channelStatus;
                    409:                volatile UInt32         commandPtrHi;           /* implementation optional              */
                    410:                volatile UInt32         commandPtrLo;
                    411:                volatile UInt32         interruptSelect;
                    412:                volatile UInt32         branchSelect;
                    413:                volatile UInt32         waitSelect;
                    414:                volatile UInt32         transferModes;
                    415:                volatile UInt32         data2PtrHi;                     /* implementation optional              */
                    416:                volatile UInt32         data2PtrLo;                     /* implementation optional              */
                    417: 
                    418:                volatile UInt32         reserved1;
                    419:                volatile UInt32         addressHi;                      /* implementation optional              */
                    420:                volatile UInt32         reserved2[4];
                    421:        };
                    422:     typedef struct DBDMAChannelRegisters       DBDMAChannelRegisters;
                    423: 
                    424: 
                    425:     struct DBDMADescriptor     /* Define the DBDMA Channel Command descriptor. */
                    426:     {
                    427:         UInt32  operation;       /* cmd | key | i | b | w | reqCount   */
                    428:         UInt32  address;
                    429:         UInt32  cmdDep;
                    430:         UInt32  result;         /* xferStatus | resCount   */
                    431:     };
                    432:     typedef struct DBDMADescriptor             DBDMADescriptor;
                    433: 
                    434:         /* Define the DBDMA channel command operations and modifiers:  */
                    435: 
                    436:     enum        /* Command.cmd operations   */
                    437:     {
                    438:         OUTPUT_MORE     = 0x00000000,
                    439:         OUTPUT_LAST     = 0x10000000,
                    440:         INPUT_MORE      = 0x20000000,
                    441:         INPUT_LAST      = 0x30000000,
                    442:         STORE_QUAD      = 0x40000000,
                    443:         LOAD_QUAD       = 0x50000000,
                    444:         NOP_CMD         = 0x60000000,
                    445:         STOP_CMD        = 0x70000000,
                    446:         kdbdmaCmdMask   = 0xF0000000
                    447:     };
                    448: 
                    449: 
                    450:     enum
                    451:     {       /* Command.key modifiers                            */
                    452:             /* (choose one for INPUT, OUTPUT, LOAD, and STORE)  */
                    453:         KEY_STREAM0         = 0x00000000,   /* default modifier*/
                    454:         KEY_STREAM1         = 0x01000000,
                    455:         KEY_STREAM2         = 0x02000000,
                    456:         KEY_STREAM3         = 0x03000000,
                    457:         KEY_REGS            = 0x05000000,
                    458:         KEY_SYSTEM          = 0x06000000,
                    459:         KEY_DEVICE          = 0x07000000,
                    460:         kdbdmaKeyMask       = 0x07000000,   /* Command.i modifiers (choose one for INPUT, OUTPUT, LOAD, STORE, and NOP)*/
                    461:         kIntNever           = 0x00000000,   /* default modifier     */
                    462:         kIntIfTrue          = 0x00100000,
                    463:         kIntIfFalse         = 0x00200000,
                    464:         kIntAlways          = 0x00300000,
                    465:         kdbdmaIMask         = 0x00300000,   /* Command.b modifiers (choose one for INPUT, OUTPUT, and NOP)*/
                    466:         kBranchNever        = 0x00000000,   /* default modifier     */
                    467:         kBranchIfTrue       = 0x00040000,
                    468:         kBranchIfFalse      = 0x00080000,
                    469:         kBranchAlways       = 0x000C0000,
                    470:         kdbdmaBMask         = 0x000C0000,   /* Command.w modifiers (choose one for INPUT, OUTPUT, LOAD, STORE, and NOP)*/
                    471:         kWaitNever          = 0x00000000,   /* default modifier     */
                    472:         kWaitIfTrue         = 0x00010000,
                    473:         kWaitIfFalse        = 0x00020000,
                    474:         kWaitAlways         = 0x00030000,
                    475:         kdbdmaWMask         = 0x00030000,    /* operation masks     */
                    476:     };
                    477: 
                    478: 
                    479:        class meshSCSIController;
                    480: 
                    481:     typedef struct globals      /* Globals for this module (not per instance)   */
                    482:     {
                    483:         UInt32       evLogFlag; // debugging only
                    484:         UInt8       *evLogBuf;
                    485:         UInt8       *evLogBufe;
                    486:         UInt8       *evLogBufp;
                    487:         UInt8       intLevel;
                    488: 
                    489:         MESHShadow  shadow; // move to per instance??? /* Last MESH register state      */
                    490: 
                    491:         UInt32      cclLogAddr,     cclPhysAddr;    // for debugging/miniMon ease
                    492:         UInt32      meshAddr;                       // for debugging/miniMon ease
                    493:                class meshSCSIController        *meshInstance;
                    494:     } globals;
                    495: 
                    496: 
                    497:        typedef struct PrivCmdData
                    498:        {
                    499:                IOMemoryDescriptor      *mdp;                           /* Memory Descriptor Pointer    */
                    500:                UInt32                          xferCount;
                    501:                UInt32                          savedDataPosition;      /* getPosition at disconnect    */
                    502:                SCSIResults                     results;
                    503:                bool                            isWrite;
                    504:        } PrivCmdData;
                    505: 
                    506: 
                    507: class meshSCSIController : public IOSCSIParallelController
                    508: {
                    509:     OSDeclareDefaultStructors( meshSCSIController )    /* Constructor & Destructor stuff       */
                    510: 
                    511: protected:
                    512: 
                    513:        bool    configure( IOService *provider, SCSIControllerInfo *controllerDataSize );
                    514:        void    executeCommand( IOSCSICommand* );
                    515:        void    cancelCommand(  IOSCSICommand* );
                    516:        void    resetCommand(   IOSCSICommand* );
                    517:        void    free();
                    518: 
                    519: private:    
                    520: 
                    521:        IOReturn        initializeHardware();
                    522:        IOReturn        getHardwareMemoryMaps();
                    523:        IOReturn        allocHdwAndChanMem();
                    524:        IOReturn        doHBASelfTest();
                    525:        void            initCP();
                    526: 
                    527:        void            interruptOccurred( IOInterruptEventSource *ies, int intCount );
                    528:        void            doHardwareInterrupt();
                    529:        void            processInterrupt();
                    530: 
                    531:        UInt8           startCommand();
                    532:        void            setupMsgO();
                    533:        void            clearCPResults();
                    534:        void            updateCP( bool reselecting );
                    535:        void            runDBDMA ( UInt32 offset, UInt32 stageLabel );
                    536:        void            completeCommand();
                    537: 
                    538:        void            disconnect();
                    539:        void            updateCurrentIndex();
                    540:        void        handleReselectionInterrupt(); /* Process a reselection interrupt. */
                    541:        bool            getReselectionTargetID();
                    542:        IOReturn        reselectNexus();
                    543: 
                    544: ///    void            initAutosenseCCL();
                    545:        void            startBucket();
                    546: 
                    547:        void            setSeqReg( MeshCommand meshCommand );
                    548:        void            getHBARegsAndClear( bool clearInts );
                    549:        void            setIntMask( UInt8 interruptMask );
                    550:        IOReturn        resetBus();
                    551:        IOReturn        waitForMesh( bool clearInterrupts );
                    552: 
                    553:        void            abortActiveCommand();
                    554:        void            abortDisconnectedCommand();
                    555: 
                    556:        void            doInterruptStageArb();
                    557:        void            doInterruptStageSelA();
                    558:        void            doInterruptStageMsgO();
                    559:        void            doInterruptStageCmdO();
                    560:        void            doInterruptStageXfer();
                    561: ///    void            doInterruptStageXferAutosense();
                    562:        void            doInterruptStageGood();
                    563: 
                    564:        IOReturn        DoMessageInPhase();           /* Handle MSGI phase.   */
                    565:        void        ProcessMSGI();
                    566:        
                    567: private:
                    568: 
                    569:     IOService                          *fProvider;
                    570:     IOSCSICommand                      *fCmd;
                    571:     PrivCmdData                                *fCmdData;
                    572:     IOMemoryMap                                *fIOMap;
                    573:     IOInterruptEventSource     *fInterruptEvent;
                    574: 
                    575:     IOMemoryMap                *fSCSIMemoryMap;
                    576:        MeshRegister    *fMESHAddr;                             /* MESH registers (logical)                     */
                    577:        UInt32                  fMESHPhysAddr;                  /* MESH registers (physical)            */
                    578: 
                    579:     IOMemoryMap                        *fDBDMAMemoryMap;
                    580:        UInt8                           *dbdmaAddr;                     /* DBDMA registers (logical)            */
                    581:        IOPhysicalAddress       dbdmaAddrPhys;          /* DBDMA registers (physical)           */
                    582: 
                    583:        IOPhysicalAddress fCCLPhysAddr;                 /* Channel Command List (physical)      */
                    584:        UInt8                   *fCCL;                                  /* Channel Command List (logical)       */
                    585:        UInt32                  fCCLSize;                               /* Channel Command List size            */
                    586:        UInt32                  fDBDMADescriptorMax;    /* max # Channel Commands                       */
                    587: 
                    588:     IOBigMemoryCursor  *fMemoryCursor;         // pointer to Big-endian memory Cursor
                    589: 
                    590:        UInt32                  fReadAlignmentCount;    // hack for DBDMA bug at start of
                    591:        UInt32                  fReadAlignmentIndex;    // Read when buffer is misaligned
                    592: 
                    593:        SCSITargetLun   fCurrentTargetLun;
                    594:        UInt32          fTag;                                   /* Last tag value                                       */
                    595:        UInt8                   fTagType;                               /* Last tag type - simple queue...      */
                    596:        UInt8                   fNegotiatingSDTR;
                    597:        UInt8                   fSyncParms[ 8 ];
                    598: 
                    599:     UInt8              *fMsgOutPtr;                    /* ptr to message-out data                      */
                    600: 
                    601:                /* These variables manage Message-In bus phase. Because the */
                    602:                /* Message-In handler uses programmed IO, fMsgInCount and   */
                    603:                /* fMsgInState are actually local variables to the message  */
                    604:                /* reader, and are here for debugging convenience.          */
                    605: 
                    606:     UInt8       fMsgInBuffer[ 16 ];
                    607:     SInt8       fMsgInCount;            /* Message bytes still to read  */
                    608:     MsgInState  fMsgInState;            /* How are we handling messages */
                    609: 
                    610: #define kFlagMsgIn_Reject       0x01
                    611: #define kFlagMsgIn_Disconnect   0x02
                    612:     UInt8       fMsgInFlag;
                    613: 
                    614: #define kFlagMsgOut_SDTR        0x01
                    615: #define kFlagMsgOut_Queuing     0x02
                    616:     UInt8       fMsgOutFlag;
                    617: 
                    618:     UInt8       fInitiatorID;           /* Our SCSI ID                                 */
                    619:     UInt8       fInitiatorIDMask;       /* BusID bitmask for selection */
                    620:     UInt8       fSelectionTimeout;      /* In MESH 10 msec units               */
                    621: 
                    622:     UInt8              fFlagIncompleteDBDMA;   /* Need more DMA                                */
                    623:     UInt8              fFlagReselecting;               /* Reselection in progress              */
                    624: 
                    625: };/* end class MESH */

unix.superglobalmegacorp.com

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