|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.