Source to iokit/Drivers/scsi/drvMESH/mesh.h
/*
* Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 1.1 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/**
* Copyright � 1997-2000 Apple Computer Inc. All Rights Reserved.
* @author Mike Johnson
*
* Set tabs every 4 characters.
*
* Edit History
* 25feb99 mlj Initial conversion from banana.
*/
/***** For fans of kprintf, IOLog and debugging infrastructure of the *****/
/***** string ilk, please modify the ELG and PAUSE macros or their *****/
/***** associated EvLog and Pause functions to suit your taste. These *****/
/***** macros currently are set up to log events to a wraparound *****/
/***** buffer with minimal performance impact. They take 2 UInt32 *****/
/***** parameters so that when the buffer is dumped 16 bytes per line, *****/
/***** time stamps (~1 microsecond) run down the left side while *****/
/***** unique 4-byte ASCII codes can be read down the right side. *****/
/***** Preserving this convention facilitates different maintainers *****/
/***** using different debugging styles with minimal code clutter. *****/
#define USE_ELG false // for debugging
#define kEvLogSize (4096*16) // 16 pages = 64K = 4096 events
#if USE_ELG /* (( */
#define ELG(A,B,ASCI,STRING) EvLog( (UInt32)(A), (UInt32)(B), (UInt32)(ASCI), STRING )
#define PAUSE(A,B,ASCI,STRING) Pause( (UInt32)(A), (UInt32)(B), (UInt32)(ASCI), STRING )
#else /* ) not USE_ELG: ( */
#define ELG(A,B,ASCI,S)
#define PAUSE(A,B,ASCI,STRING) IOLog( "MESH: %8x %8x " STRING "\n", (unsigned int)(A), (unsigned int)(B) )
#endif /* USE_ELG )) */
#ifndef SynchronizeIO
#define SynchronizeIO() eieio() /* TEMP */
#endif /* SynchronizeIO */
enum { kMaxAutosenseByteCount = 255 };
enum
{
kMESHRegisterBase = 0,
kDBDMARegisterBase = 1,
kNumberRegisters = 2
};
/* Operation flags and options: */
typedef enum BusPhase /* These are the real SCSI bus phases (from busStatus0): */
{
kBusPhaseDATO = 0,
kBusPhaseDATI,
kBusPhaseCMD,
kBusPhaseSTS,
kBusPhaseReserved1,
kBusPhaseReserved2,
kBusPhaseMSGO,
kBusPhaseMSGI
} BusPhase;
/* Command to be executed by IO thread. */
/* These are ultimately derived from ioctl control values. */
typedef enum
{ kCommandExecute, /* Execute IOSCSIRequest */
kCommandResetBus, /* Reset bus */
kCommandAbortRequest /* Abort IO thread */
} CommandOperation;
/* We read target messages using a simple state machine. */
/* On entrance to MSGI phase, fMsgInState = kMsgInInit. */
/* Continue reading messages until either */
/* fMsgInState == kMsgInReady or the target changes phase */
/* (which is an error). */
typedef enum MsgInState
{
kMsgInInit = 0, /* 0 Not reading a message (must be zero) */
kMsgInReading, /* 1 MSG input state: reading counted data */
kMsgInCounting, /* 2 MSG input state: reading count byte */
kMsgInReady /* 3 MSG input state: a msg is now available */
} MsgInState;
/* These values represent no active request: */
enum
{ kInvalidTarget = 0xFF,
kInvalidLUN = 0xFF,
kInvalidTag = 0xFFFFFFFF
};
/* The default initiator bus ID (needs to be fetched from NVRAM). */
enum
{
kInitiatorIDDefault = 7,
kMaxTargetID = 8,
kMaxDMATransfer = 0xF000ul,
kMaxMemCursorSegs = 15
};
#define APPLE_SCSI_RESET_DELAY 250 /* Msec */
typedef struct MeshRegister /* Mesh registers: */
{
volatile UInt8 transferCount0; UInt8 pad00[ 0x0F ];
volatile UInt8 transferCount1; UInt8 pad01[ 0x0F ];
volatile UInt8 xFIFO; UInt8 pad02[ 0x0F ];
volatile UInt8 sequence; UInt8 pad03[ 0x0F ];
volatile UInt8 busStatus0; UInt8 pad04[ 0x0F ];
volatile UInt8 busStatus1; UInt8 pad05[ 0x0F ];
volatile UInt8 FIFOCount; UInt8 pad06[ 0x0F ];
volatile UInt8 exception; UInt8 pad07[ 0x0F ];
volatile UInt8 error; UInt8 pad08[ 0x0F ];
volatile UInt8 interruptMask; UInt8 pad09[ 0x0F ];
volatile UInt8 interrupt; UInt8 pad10[ 0x0F ];
volatile UInt8 sourceID; UInt8 pad11[ 0x0F ];
volatile UInt8 destinationID; UInt8 pad12[ 0x0F ];
volatile UInt8 syncParms; UInt8 pad13[ 0x0F ];
volatile UInt8 MESHID; UInt8 pad14[ 0x0F ];
volatile UInt8 selectionTimeOut;
} MeshRegister;
/* The following structure shadows the MESH chip registers: */
typedef union MESHShadow
{ UInt32 longWord[ 3 ]; /* for debugging ease. */
struct
{ UInt8 interrupt; /* Interrupt */
UInt8 error; /* Error register */
UInt8 exception; /* Exception register */
UInt8 FIFOCount; /* FIFO count */
UInt8 busStatus0; /* Bus phase + REQ, ACK, & ATN signals */
UInt8 busStatus1; /* RST, BSY, SEL */
UInt8 interruptMask; /* Interrupt mask for debugging */
UInt8 transferCount0; /* low order byte of transfer count */
UInt8 transferCount1; /* high order byte of transfer count */
UInt8 sequence; /* Sequence register */
UInt8 syncParms; /* syncParms for debugging */
UInt8 destinationID; /* Target ID */
} mesh;
} MESHShadow;
/* MESH Register set offsets */
enum
{
kMeshTransferCount0 = 0x00,
kMeshTransferCount1 = 0x10,
kMeshFIFO = 0x20,
kMeshSequence = 0x30,
kMeshBusStatus0 = 0x40,
kMeshBusStatus1 = 0x50,
kMeshFIFOCount = 0x60,
kMeshException = 0x70,
kMeshError = 0x80,
kMeshInterruptMask = 0x90,
kMeshInterrupt = 0xA0,
kMeshSourceID = 0xB0,
kMeshDestinationID = 0xC0,
kMeshSyncParms = 0xD0,
kMeshMESHID = 0xE0,
kMeshSelTimeOut = 0xF0
};
enum { kMeshMESHID_Value = 0x02 }; /* Read value of kMESHID lo 5 bits only */
/* MESH commands & modifiers for Sequence register: */
typedef enum
{
kMeshNoOpCmd = 0x00,
kMeshArbitrateCmd = 0x01,
kMeshSelectCmd = 0x02,
kMeshCommandCmd = 0x03,
kMeshStatusCmd = 0x04,
kMeshDataOutCmd = 0x05,
kMeshDataInCmd = 0x06,
kMeshMessageOutCmd = 0x07,
kMeshMessageInCmd = 0x08,
kMeshBusFreeCmd = 0x09,
/* non interrupting: */
kMeshEnableParity = 0x0A,
kMeshDisableParity = 0x0B,
kMeshEnableReselect = 0x0C,
kMeshDisableReselect = 0x0D,
kMeshResetMESH = 0x0E,
kMeshFlushFIFO = 0x0F,
/* Sequence command modifier bits: */
kMeshSeqDMA = 0x80, /* Data Xfer for this command will use DMA */
kMeshSeqTMode = 0x40, /* Target mode - unused */
kMeshSeqAtn = 0x20 /* ATN is to be asserted after command */
} MeshCommand;
/* The bus Status Registers 0 & 1 have the actual */
/* bus signals AT TIME OF READ. */
enum /* bus Status Register 0 bits: */
{
kMeshIO = 0x01, /* phase bit */
kMeshCD = 0x02, /* phase bit */
kMeshMsg = 0x04, /* phase bit */
kMeshAtn = 0x08, /* Attention signal */
kMeshAck = 0x10, /* Ack signal */
kMeshReq = 0x20, /* Request signal */
kMeshAck32 = 0x40, /* unused - 32 bit bus */
kMeshReq32 = 0x80 /* unused - 32 bit bus */
};
enum { kMeshPhaseMask = (kMeshMsg + kMeshCD + kMeshIO) };
enum /* bus Status Register 1 bits: */
{
kMeshSel = 0x20, /* Select signal */
kMeshBsy = 0x40, /* Busy signal */
kMeshRst = 0x80 /* Reset signal */
};
enum /* Exception Register bits: */
{
kMeshExcSelTO = 0x01, /* Selection timeout */
kMeshExcPhaseMM = 0x02, /* Phase mismatch */
kMeshExcArbLost = 0x04, /* lost arbitration */
kMeshExcResel = 0x08, /* reselection occurred */
kMeshExcSelected = 0x10,
kMeshExcSelectedWAtn = 0x20
};
enum /* Error Register bits: */
{
kMeshErrParity0 = 0x01, /* parity error */
kMeshErrParity1 = 0x02, /* unused - 32 bit bus */
kMeshErrParity2 = 0x04, /* unused - 32 bit bus */
kMeshErrParity3 = 0x08, /* unused - 32 bit bus */
kMeshErrSequence = 0x10, /* Sequence error */
kMeshErrSCSIRst = 0x20, /* Reset signal asserted */
kMeshErrDisconnected = 0x40 /* unexpected disconnect */
};
enum /* Interrupt Register bits: */
{
kMeshIntrCmdDone = 0x01, /* command done */
kMeshIntrException = 0x02, /* exception occurred */
kMeshIntrError = 0x04, /* error occurred */
kMeshIntrMask = (kMeshIntrCmdDone | kMeshIntrException | kMeshIntrError)
};
enum /* Values for SyncParms MESH register: */
{ /* 1st nibble is offset, 2nd is period. */
/* Zero offset means async. */
kSyncParmsAsync = 0x02, /* Async with min period = 2 */
kSyncParmsFast = 0xF0 /* offset = 15, period = Fast (10 MB/s) */
};
/* The following are specific to the MESH CCL */
/* Stage Names. (These were originally 'xxxx' identifiers, */
/* which is convenient for debugging, but results in many */
/* warning messages from the NeXT compiler. */
enum
{ /* kcclStageLabel: */
kcclStageIdle = 0, /* 0 - 'Idle' */
kcclStageInit, /* 1 - 'Init' */
kcclStageCCLx, /* 2 - 'CCL~' */
kcclStageArb, /* 3 - ' Arb' */
kcclStageSelA, /* 4 - 'SelA' */
kcclStageMsgO, /* 5 - 'MsgO' */
kcclStageCmdO, /* 6 - 'CmdO' */
kcclStageXfer, /* 7 - 'Xfer' */
kcclStageBucket, /* 8 - 'Buck' */
kcclStageSyncHack, /* 9 - 'Hack' */
kcclStageStat, /* A - ' Sta' */
kcclStageMsgI, /* B - 'MsgI' */
kcclStageFree, /* C - 'Free' */
kcclStageGood, /* D - 'Good' */
kcclStageStop, /* E - '++++' */
kcclTerminatorWithoutComma
};
/* offsets into the Channel Command List page: */
#define kcclProblem 0x00 // Interrupt & Stop channel commands for anomalies
#define kcclCMDOdata 0x20 // reserve for 6, 10, 12 byte commands
#define kcclMSGOdata 0x30 // reserve for Identify, Tag stuff
#define kcclMSGOLast 0x3F // reserve for last or only msg0ut byte
#define kcclMSGIdata 0x40 // reserve for Message In data
#define kcclBucket 0x48 // Bit Bucket
#define kcclStatusData 0x4F // reserve for Status byte
#define kcclSenseCDB 0x50 // CDB for (auto) Sense
#define kcclBatchSize 0x60 // Current MESH batch size
#define kcclStageLabel 0x6C // storage for label of last stage entered.
#define kcclSense 0x70 // Channel Commands for (Auto)Sense
#define kcclPrototype 0xC0 // Prototype MESH 4-command Transfer sequence
#define kcclReadBuf8 0x100 // Buffer for non-8-byte-aligned reads
#define kcclStart 0x120 // Channel Program starts here with Arbitrate
#define kcclBrProblem 0x140 // channel command to wait for cmdDone & Br if problem
#define kcclMsgoStage 0x190 // Branch to single byte Message-Out
#define kcclMsgoBranch 0x1B0 // Branch to single byte Message-Out
#define kcclMsgoMTC 0x1D8 // MESH Transfer Count for MSGO (low order only)
#define kcclMsgoDTC 0x1F0 // DMA Transfer Count for MSGO (low order only)
#define kcclLastMsgo 0x210 // Channel commands to put last/only byte of Message-Out
#define kcclCmdoStage 0x290 // Start of Command phase
#define kcclCmdoMTC 0x2C8 // MESH Transfer Count for CMDO (low order only)
#define kcclCmdoDTC 0x2E0 // DMA Transfer Count for CMDO (low order only)
#define kcclReselect 0x2F0 // Reselect enters CCL here - Branch to xfer data
#define kcclOverrun 0x320 // data overrun - dump the excess in the bit bucket
#define kcclOverrunMESH 0x370 // data overrun - patch the MESH Seq Reg I/O
#define kcclOverrunDBDMA 0x380 // data overrun - patch the DBDMA I/O
#define kcclSyncCleanUp 0x3B0 // clean up at end of Sync xfer
#define kcclGetStatus 0x3D0 // Finish up with Status, Message In, and Bus Free
#define kcclMESHintr 0x4D0 // transaction done or going well
#define kcclSenseBuffer 0x500 // Buffer for Autosense data
#define kcclDataXfer 0x600 // INPUT or OUTPUT channel commands for data
#define kcclSenseResult 0x63C // Result field in Sense INPUT channel command
/* generic relocation types: */
#define kRelNone 0x00 /* default - no relocation */
#define kRelMESH 0x01 /* Relocate to MESH register area */
#define kRelCP 0x02 /* Relocate to Channel Program area */
#define kRelCPdata 0x03 /* Relocate to Channel Program data structure */
#define kRelPhys 0x04 /* Relocate to user Physical address space */
#define kRelNoSwap 0x05 /* don't relocate or swap (Label) */
/* Relocatable ADDRESS types: */
#define kRelAddress 0xFF <<8 /* relocatable address mask */
#define kRelAddressMESH kRelMESH <<8 /* MESH physical address */
#define kRelAddressCP kRelCP <<8 /* Channel Program Physical address */
#define kRelAddressPhys kRelPhys <<8 /* User data Physical address */
/* Relocatable COMMAND-DEPENDENT types: */
#define kRelCmdDep 0xFF /* relocatable command-dependent mask */
#define kRelCmdDepCP kRelCP /* Channel Program command-dependent (branch) */
#define kRelCmdDepLabel kRelNoSwap /* Channel Program label - don't swap */
/* Channel Program macros: */
#define STAGE(v) STORE_QUAD | KEY_SYSTEM | 4, kcclStageLabel, v, kRelAddressCP | kRelCmdDepLabel
#define CLEAR_CMD_DONE STORE_QUAD | KEY_SYSTEM | 1, kMeshInterrupt, kMeshIntrCmdDone, kRelAddressMESH
#define CLEAR_INT_REG STORE_QUAD | KEY_SYSTEM | 1, kMeshInterrupt, kMeshIntrMask, kRelAddressMESH
#define CLR_PHASEMM STORE_QUAD | KEY_SYSTEM | 1, kMeshInterrupt, kMeshIntrCmdDone | kMeshIntrException, kRelAddressMESH
#define MOVE_1(a,v,r) STORE_QUAD | KEY_SYSTEM | 1, a, v, r
#define MOVE_4(a,v,r) STORE_QUAD | KEY_SYSTEM | 4, a, v, r
#define MESH_REG(a,v) STORE_QUAD | KEY_SYSTEM | 1, a, v, kRelAddressMESH
#define MESH_REG_WAIT(a,v) STORE_QUAD | KEY_SYSTEM | kWaitIfTrue | 1, a, v, kRelAddressMESH
#define SENSE(c) INPUT_LAST | kBranchIfFalse | kWaitIfTrue | c, kcclSenseBuffer, kcclProblem, kRelAddressCP | kRelCmdDepCP
#define MSGO(a,c) OUTPUT_LAST | kBranchIfFalse | kWaitIfTrue | c, a, kcclProblem, kRelAddressCP | kRelCmdDepCP
#define CMDO(c) OUTPUT_LAST | kBranchIfFalse | kWaitIfTrue | c, kcclCMDOdata, kcclProblem, kRelAddressCP | kRelCmdDepCP
#define MSGI(c) INPUT_LAST | kBranchIfFalse | kWaitIfTrue | c, kcclMSGIdata, kcclProblem, kRelAddressCP | kRelCmdDepCP
#define STATUS_IN INPUT_LAST | kBranchIfFalse | kWaitIfTrue | 1, kcclStatusData, kcclProblem, kRelAddressCP | kRelCmdDepCP
#define BUCKET INPUT_LAST | kBranchIfFalse | 8, kcclBucket, kcclProblem, kRelAddressCP | kRelCmdDepCP
#define BRANCH(a) NOP_CMD | kBranchAlways, 0, a, kRelCmdDepCP
#define BR_IF_PROBLEM NOP_CMD | kBranchIfFalse | kWaitIfTrue, 0, kcclProblem, kRelCmdDepCP
#define BR_NO_PROBLEM(a) NOP_CMD | kBranchIfTrue , 0, a, kRelCmdDepCP
#define STOP(L) STOP_CMD, 0, L, kRelCmdDepLabel
#define INTERRUPT(a) NOP_CMD | kIntAlways, 0, a, 0
#define RESERVE 0xCEFECEFE, 0xCEFECEFE, 0xCEFECEFE, 0xCEFECEFE
#define WAIT_4_CMDDONE NOP_CMD | kWaitIfTrue, 0, 0, 0
#define SWAP(x) (UInt32)OSSwapInt32( (UInt32)(x) )
/* Return values from startCommand: */
enum
{ kHardwareStartOK, /* command started successfully */
kHardwareStartBusy
};
/**** THESE NEED TO BE VOLATILE *****/
struct DBDMAChannelRegisters /* DBDMA channel registers: */
{
volatile UInt32 channelControl;
volatile UInt32 channelStatus;
volatile UInt32 commandPtrHi; /* implementation optional */
volatile UInt32 commandPtrLo;
volatile UInt32 interruptSelect;
volatile UInt32 branchSelect;
volatile UInt32 waitSelect;
volatile UInt32 transferModes;
volatile UInt32 data2PtrHi; /* implementation optional */
volatile UInt32 data2PtrLo; /* implementation optional */
volatile UInt32 reserved1;
volatile UInt32 addressHi; /* implementation optional */
volatile UInt32 reserved2[4];
};
typedef struct DBDMAChannelRegisters DBDMAChannelRegisters;
struct DBDMADescriptor /* Define the DBDMA Channel Command descriptor. */
{
UInt32 operation; /* cmd | key | i | b | w | reqCount */
UInt32 address;
UInt32 cmdDep;
UInt32 result; /* xferStatus | resCount */
};
typedef struct DBDMADescriptor DBDMADescriptor;
/* Define the DBDMA channel command operations and modifiers: */
enum /* Command.cmd operations */
{
OUTPUT_MORE = 0x00000000,
OUTPUT_LAST = 0x10000000,
INPUT_MORE = 0x20000000,
INPUT_LAST = 0x30000000,
STORE_QUAD = 0x40000000,
LOAD_QUAD = 0x50000000,
NOP_CMD = 0x60000000,
STOP_CMD = 0x70000000,
kdbdmaCmdMask = 0xF0000000
};
enum
{ /* Command.key modifiers */
/* (choose one for INPUT, OUTPUT, LOAD, and STORE) */
KEY_STREAM0 = 0x00000000, /* default modifier*/
KEY_STREAM1 = 0x01000000,
KEY_STREAM2 = 0x02000000,
KEY_STREAM3 = 0x03000000,
KEY_REGS = 0x05000000,
KEY_SYSTEM = 0x06000000,
KEY_DEVICE = 0x07000000,
kdbdmaKeyMask = 0x07000000, /* Command.i modifiers (choose one for INPUT, OUTPUT, LOAD, STORE, and NOP)*/
kIntNever = 0x00000000, /* default modifier */
kIntIfTrue = 0x00100000,
kIntIfFalse = 0x00200000,
kIntAlways = 0x00300000,
kdbdmaIMask = 0x00300000, /* Command.b modifiers (choose one for INPUT, OUTPUT, and NOP)*/
kBranchNever = 0x00000000, /* default modifier */
kBranchIfTrue = 0x00040000,
kBranchIfFalse = 0x00080000,
kBranchAlways = 0x000C0000,
kdbdmaBMask = 0x000C0000, /* Command.w modifiers (choose one for INPUT, OUTPUT, LOAD, STORE, and NOP)*/
kWaitNever = 0x00000000, /* default modifier */
kWaitIfTrue = 0x00010000,
kWaitIfFalse = 0x00020000,
kWaitAlways = 0x00030000,
kdbdmaWMask = 0x00030000, /* operation masks */
};
class meshSCSIController;
typedef struct globals /* Globals for this module (not per instance) */
{
UInt32 evLogFlag; // debugging only
UInt8 *evLogBuf;
UInt8 *evLogBufe;
UInt8 *evLogBufp;
UInt8 intLevel;
MESHShadow shadow; // move to per instance??? /* Last MESH register state */
UInt32 cclLogAddr, cclPhysAddr; // for debugging/miniMon ease
UInt32 meshAddr; // for debugging/miniMon ease
class meshSCSIController *meshInstance;
} globals;
typedef struct PrivCmdData
{
IOMemoryDescriptor *mdp; /* Memory Descriptor Pointer */
UInt32 xferCount;
UInt32 savedDataPosition; /* getPosition at disconnect */
SCSIResults results;
bool isWrite;
} PrivCmdData;
class meshSCSIController : public IOSCSIParallelController
{
OSDeclareDefaultStructors( meshSCSIController ) /* Constructor & Destructor stuff */
protected:
bool configure( IOService *provider, SCSIControllerInfo *controllerDataSize );
void executeCommand( IOSCSICommand* );
void cancelCommand( IOSCSICommand* );
void resetCommand( IOSCSICommand* );
void free();
private:
IOReturn initializeHardware();
IOReturn getHardwareMemoryMaps();
IOReturn allocHdwAndChanMem();
IOReturn doHBASelfTest();
void initCP();
void interruptOccurred( IOInterruptEventSource *ies, int intCount );
void doHardwareInterrupt();
void processInterrupt();
UInt8 startCommand();
void setupMsgO();
void clearCPResults();
void updateCP( bool reselecting );
void runDBDMA ( UInt32 offset, UInt32 stageLabel );
void completeCommand();
void disconnect();
void updateCurrentIndex();
void handleReselectionInterrupt(); /* Process a reselection interrupt. */
bool getReselectionTargetID();
IOReturn reselectNexus();
/// void initAutosenseCCL();
void startBucket();
void setSeqReg( MeshCommand meshCommand );
void getHBARegsAndClear( bool clearInts );
void setIntMask( UInt8 interruptMask );
IOReturn resetBus();
IOReturn waitForMesh( bool clearInterrupts );
void abortActiveCommand();
void abortDisconnectedCommand();
void doInterruptStageArb();
void doInterruptStageSelA();
void doInterruptStageMsgO();
void doInterruptStageCmdO();
void doInterruptStageXfer();
/// void doInterruptStageXferAutosense();
void doInterruptStageGood();
IOReturn DoMessageInPhase(); /* Handle MSGI phase. */
void ProcessMSGI();
private:
IOService *fProvider;
IOSCSICommand *fCmd;
PrivCmdData *fCmdData;
IOMemoryMap *fIOMap;
IOInterruptEventSource *fInterruptEvent;
IOMemoryMap *fSCSIMemoryMap;
MeshRegister *fMESHAddr; /* MESH registers (logical) */
UInt32 fMESHPhysAddr; /* MESH registers (physical) */
IOMemoryMap *fDBDMAMemoryMap;
UInt8 *dbdmaAddr; /* DBDMA registers (logical) */
IOPhysicalAddress dbdmaAddrPhys; /* DBDMA registers (physical) */
IOPhysicalAddress fCCLPhysAddr; /* Channel Command List (physical) */
UInt8 *fCCL; /* Channel Command List (logical) */
UInt32 fCCLSize; /* Channel Command List size */
UInt32 fDBDMADescriptorMax; /* max # Channel Commands */
IOBigMemoryCursor *fMemoryCursor; // pointer to Big-endian memory Cursor
UInt32 fReadAlignmentCount; // hack for DBDMA bug at start of
UInt32 fReadAlignmentIndex; // Read when buffer is misaligned
SCSITargetLun fCurrentTargetLun;
UInt32 fTag; /* Last tag value */
UInt8 fTagType; /* Last tag type - simple queue... */
UInt8 fNegotiatingSDTR;
UInt8 fSyncParms[ 8 ];
UInt8 *fMsgOutPtr; /* ptr to message-out data */
/* These variables manage Message-In bus phase. Because the */
/* Message-In handler uses programmed IO, fMsgInCount and */
/* fMsgInState are actually local variables to the message */
/* reader, and are here for debugging convenience. */
UInt8 fMsgInBuffer[ 16 ];
SInt8 fMsgInCount; /* Message bytes still to read */
MsgInState fMsgInState; /* How are we handling messages */
#define kFlagMsgIn_Reject 0x01
#define kFlagMsgIn_Disconnect 0x02
UInt8 fMsgInFlag;
#define kFlagMsgOut_SDTR 0x01
#define kFlagMsgOut_Queuing 0x02
UInt8 fMsgOutFlag;
UInt8 fInitiatorID; /* Our SCSI ID */
UInt8 fInitiatorIDMask; /* BusID bitmask for selection */
UInt8 fSelectionTimeout; /* In MESH 10 msec units */
UInt8 fFlagIncompleteDBDMA; /* Need more DMA */
UInt8 fFlagReselecting; /* Reselection in progress */