bsd/hfs/hfscommon/BTree/BTreeAllocate.c optional hfs
bsd/hfs/hfscommon/BTree/BTreeMiscOps.c optional hfs
bsd/hfs/hfscommon/BTree/BTreeNodeOps.c optional hfs
+bsd/hfs/hfscommon/BTree/BTreeScanner.c optional hfs
bsd/hfs/hfscommon/BTree/BTreeTreeOps.c optional hfs
bsd/hfs/hfscommon/Catalog/Catalog.c optional hfs
bsd/hfs/hfscommon/Catalog/CatalogIterators.c optional hfs
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include "hfscommon/headers/FileMgrInternal.h"
#include "hfscommon/headers/CatalogPrivate.h"
#include "hfscommon/headers/HFSUnicodeWrappers.h"
-
-
-/* Private description used in hfs_search */
-/*
- * ============ W A R N I N G ! ============
- * DO NOT INCREASE THE SIZE OF THIS STRUCT!
- * It must match the size of the opaque
- * searchstate struct (in sys/attr.h).
- */
-struct SearchState {
- long searchBits;
- BTreeIterator btreeIterator;
-};
-typedef struct SearchState SearchState;
+#include "hfscommon/headers/BTreesPrivate.h"
+#include "hfscommon/headers/BTreeScanner.h"
static int UnpackSearchAttributeBlock(struct vnode *vp, struct attrlist *alist, searchinfospec_t *searchInfo, void *attributeBuffer);
-Boolean CheckCriteria(ExtendedVCB *vcb, const SearchState *searchState,
+Boolean CheckCriteria(ExtendedVCB *vcb,
u_long searchBits, struct attrlist *attrList,
CatalogNodeData *cnp, CatalogKey *key,
searchinfospec_t *searchInfo1, searchinfospec_t *searchInfo2);
struct searchstate *a_searchstate;
*/
{
- CatalogNodeData cnode;
- BTreeKey *key;
- FSBufferDescriptor btRecord;
FCB* catalogFCB;
- SearchState *searchState;
searchinfospec_t searchInfo1;
searchinfospec_t searchInfo2;
void *attributesBuffer;
u_long fixedBlockSize;
u_long eachReturnBufferSize;
struct proc *p = current_proc();
- u_long nodesToCheck = 30; /* After we search 30 nodes we must give up time */
+ CatalogNodeData myCNodeData;
+ CatalogNodeData * myCNodeDataPtr;
+ CatalogKey * myCurrentKeyPtr;
+ CatalogRecord * myCurrentDataPtr;
+ CatPosition * myCatPositionPtr;
+ BTScanState myBTScanState;
+ Boolean timerExpired = false;
u_long lastNodeNum = 0XFFFFFFFF;
ExtendedVCB *vcb = VTOVCB(ap->a_vp);
int err = E_NONE;
return (EINVAL);
isHFSPlus = (vcb->vcbSigWord == kHFSPlusSigWord);
- searchState = (SearchState *)ap->a_searchstate;
-
- /*
- * Check if this is the first time we are being called.
- * If it is, allocate SearchState and we'll move it to the users space on exit
- */
- if ( ap->a_options & SRCHFS_START ) {
- bzero( (caddr_t)searchState, sizeof(SearchState) );
- operation = kBTreeFirstRecord;
- ap->a_options &= ~SRCHFS_START;
- } else {
- operation = kBTreeCurrentRecord;
- }
/* UnPack the search boundries, searchInfo1, searchInfo2 */
err = UnpackSearchAttributeBlock( ap->a_vp, ap->a_searchattrs, &searchInfo1, ap->a_searchparams1 );
err = UnpackSearchAttributeBlock( ap->a_vp, ap->a_searchattrs, &searchInfo2, ap->a_searchparams2 );
if (err) return err;
- btRecord.itemCount = 1;
- if (isHFSPlus) {
- btRecord.itemSize = sizeof(cnode);
- btRecord.bufferAddress = &cnode;
- } else {
- btRecord.itemSize = sizeof(HFSCatalogFile);
- btRecord.bufferAddress = &cnode.cnd_extra;
- }
- catalogFCB = VTOFCB( vcb->catalogRefNum );
- key = (BTreeKey*) &(searchState->btreeIterator.key);
fixedBlockSize = sizeof(u_long) + AttributeBlockSize( ap->a_returnattrs ); /* u_long for length longword */
eachReturnBufferSize = fixedBlockSize;
goto ExitThisRoutine;
};
+ catalogFCB = VTOFCB( vcb->catalogRefNum );
+ myCurrentKeyPtr = NULL;
+ myCurrentDataPtr = NULL;
+ myCatPositionPtr = (CatPosition *)ap->a_searchstate;
+
+ if (ap->a_options & SRCHFS_START) {
+ /* Starting a new search. */
+ ap->a_options &= ~SRCHFS_START;
+ bzero( (caddr_t)myCatPositionPtr, sizeof( *myCatPositionPtr ) );
+ err = BTScanInitialize(catalogFCB, 0, 0, 0, kCatSearchBufferSize, &myBTScanState);
+ } else {
+ /* Resuming a search. */
+ err = BTScanInitialize(catalogFCB, myCatPositionPtr->nextNode,
+ myCatPositionPtr->nextRecord,
+ myCatPositionPtr->recordsFound,
+ kCatSearchBufferSize,
+ &myBTScanState);
+#if 0
+ /* Make sure Catalog hasn't changed. */
+ if (err == 0
+ && myCatPositionPtr->writeCount != myBTScanState.btcb->writeCount) {
+ myCatPositionPtr->writeCount = myBTScanState.btcb->writeCount;
+ err = EBUSY; /* catChangedErr */
+ }
+#endif
+ }
+
+ /* Unlock catalog b-tree */
+ (void) hfs_metafilelocking(VTOHFS(ap->a_vp), kHFSCatalogFileID, LK_RELEASE, p);
+ if (err)
+ goto ExitThisRoutine;
+
/*
- * Iterate over all the catalog btree records
+ * Check all the catalog btree records...
+ * return the attributes for matching items
*/
-
- err = BTIterateRecord( catalogFCB, operation, &(searchState->btreeIterator), &btRecord, &recordSize );
+ for (;;) {
+ struct timeval myCurrentTime;
+ struct timeval myElapsedTime;
+
+ err = BTScanNextRecord(&myBTScanState, timerExpired,
+ (void **)&myCurrentKeyPtr, (void **)&myCurrentDataPtr,
+ NULL);
+ if (err)
+ break;
- while( err == E_NONE ) {
- if (!isHFSPlus)
- CopyCatalogNodeData(vcb, (CatalogRecord*)&cnode.cnd_extra, &cnode);
-
- if ( CheckCriteria( vcb, searchState, ap->a_options, ap->a_searchattrs, &cnode,
- (CatalogKey *)key, &searchInfo1, &searchInfo2 ) &&
- CheckAccess(&cnode, (CatalogKey *)key, ap->a_uio->uio_procp)) {
- err = InsertMatch(ap->a_vp, ap->a_uio, &cnode, (CatalogKey *)key,
- ap->a_returnattrs, attributesBuffer, variableBuffer,
- eachReturnBufferSize, ap->a_nummatches);
- if ( err != E_NONE )
- break;
+ if ( isHFSPlus ) {
+ // HFSPlus vols have CatalogRecords that map exactly to CatalogNodeData so there is no need
+ // to copy.
+ myCNodeDataPtr = (CatalogNodeData *) myCurrentDataPtr;
+ } else {
+ CopyCatalogNodeData( vcb, myCurrentDataPtr, &myCNodeData );
+ myCNodeDataPtr = &myCNodeData;
}
-
- err = BTIterateRecord( catalogFCB, kBTreeNextRecord, &(searchState->btreeIterator), &btRecord, &recordSize );
-
- if ( *(ap->a_nummatches) >= ap->a_maxmatches )
+
+ if (CheckCriteria(vcb, ap->a_options, ap->a_searchattrs, myCNodeDataPtr,
+ myCurrentKeyPtr, &searchInfo1, &searchInfo2) &&
+ CheckAccess(myCNodeDataPtr, myCurrentKeyPtr, ap->a_uio->uio_procp)) {
+
+ err = InsertMatch(ap->a_vp, ap->a_uio, myCNodeDataPtr,
+ myCurrentKeyPtr, ap->a_returnattrs,
+ attributesBuffer, variableBuffer,
+ eachReturnBufferSize, ap->a_nummatches);
+ if (err) {
+ /*
+ * The last match didn't fit so come back
+ * to this record on the next trip.
+ */
+ --myBTScanState.recordsFound;
+ --myBTScanState.recordNum;
break;
+ }
+ if (*(ap->a_nummatches) >= ap->a_maxmatches)
+ break;
+ }
- if ( searchState->btreeIterator.hint.nodeNum != lastNodeNum ) {
- lastNodeNum = searchState->btreeIterator.hint.nodeNum;
- if ( --nodesToCheck == 0 )
- break; /* We must leave the kernel to give up time */
+ /*
+ * Check our elapsed time and bail if we've hit the max.
+ * The idea here is to throttle the amount of time we
+ * spend in the kernel.
+ */
+ myCurrentTime = time;
+ timersub(&myCurrentTime, &myBTScanState.startTime, &myElapsedTime);
+ /* Note: assumes kMaxMicroSecsInKernel is less than 1,000,000 */
+ if (myElapsedTime.tv_sec > 0
+ || myElapsedTime.tv_usec >= kMaxMicroSecsInKernel) {
+ timerExpired = true;
}
}
- /* Unlock catalog b-tree */
- (void) hfs_metafilelocking( VTOHFS(ap->a_vp), kHFSCatalogFileID, LK_RELEASE, p );
+ /* Update catalog position */
+ myCatPositionPtr->writeCount = myBTScanState.btcb->writeCount;
+ BTScanTerminate(&myBTScanState, &myCatPositionPtr->nextNode,
+ &myCatPositionPtr->nextRecord,
+ &myCatPositionPtr->recordsFound);
if ( err == E_NONE ) {
err = EAGAIN; /* signal to the user to call searchfs again */
err = ENOBUFS;
} else if ( err == btNotFound ) {
err = E_NONE; /* the entire disk has been searched */
+ } else if ( err == fsBTTimeOutErr ) {
+ err = EAGAIN;
}
ExitThisRoutine:
FREE( attributesBuffer, M_TEMP );
- return( err );
+ return (MacToVFSError(err));
}
}
Boolean
-CheckCriteria( ExtendedVCB *vcb, const SearchState *searchState, u_long searchBits,
+CheckCriteria( ExtendedVCB *vcb, u_long searchBits,
struct attrlist *attrList, CatalogNodeData *cnp, CatalogKey *key,
searchinfospec_t *searchInfo1, searchinfospec_t *searchInfo2 )
{
/* Now that we have a record worth searching, see if it matches the search attributes */
if (cnp->cnd_type == kCatalogFileNode) {
- if ((attrList->dirattr & ~ATTR_FILE_VALIDMASK) != 0) { /* attr we do know about */
+ if ((attrList->fileattr & ~ATTR_FILE_VALIDMASK) != 0) { /* attr we do know about */
matched = false;
goto TestDone;
}
- else if ((attrList->dirattr & ATTR_FILE_VALIDMASK) != 0) {
+ else if ((attrList->fileattr & ATTR_FILE_VALIDMASK) != 0) {
searchAttributes = attrList->fileattr;
/* File logical length (data fork) */
--- /dev/null
+/*
+ * Copyright (c) 1996-2002 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@
+ *
+ * @(#)BTreeScanner.c
+ */
+#include <sys/kernel.h>
+
+#include "../headers/BTreeScanner.h"
+
+static int FindNextLeafNode( BTScanState *scanState, Boolean avoidIO );
+static int ReadMultipleNodes( BTScanState *scanState );
+
+
+//_________________________________________________________________________________
+//
+// Routine: BTScanNextRecord
+//
+// Purpose: Return the next leaf record in a scan.
+//
+// Inputs:
+// scanState Scanner's current state
+// avoidIO If true, don't do any I/O to refill the buffer
+//
+// Outputs:
+// key Key of found record (points into buffer)
+// data Data of found record (points into buffer)
+// dataSize Size of data in found record
+//
+// Result:
+// noErr Found a valid record
+// btNotFound No more records
+// ??? Needed to do I/O to get next node, but avoidIO set
+//
+// Notes:
+// This routine returns pointers to the found record's key and data. It
+// does not copy the key or data to a caller-supplied buffer (like
+// GetBTreeRecord would). The caller must not modify the key or data.
+//_________________________________________________________________________________
+
+int BTScanNextRecord( BTScanState * scanState,
+ Boolean avoidIO,
+ void * * key,
+ void * * data,
+ u_int32_t * dataSize )
+{
+ int err;
+ u_int16_t dataSizeShort;
+
+ err = noErr;
+
+ //
+ // If this is the first call, there won't be any nodes in the buffer, so go
+ // find the first first leaf node (if any).
+ //
+ if ( scanState->nodesLeftInBuffer == 0 )
+ {
+ err = FindNextLeafNode( scanState, avoidIO );
+ }
+
+ while ( err == noErr )
+ {
+ // See if we have a record in the current node
+ err = GetRecordByIndex( scanState->btcb, scanState->currentNodePtr,
+ scanState->recordNum, (KeyPtr *) key,
+ (UInt8 **) data, &dataSizeShort );
+
+ if ( err == noErr )
+ {
+ ++scanState->recordsFound;
+ ++scanState->recordNum;
+ if (dataSize != NULL)
+ *dataSize = dataSizeShort;
+ return noErr;
+ }
+ else if (err > 0)
+ {
+ // We didn't get the node through the cache, so we can't invalidate it.
+ //XXX Should we do something else to avoid seeing the same record again?
+ return err;
+ }
+
+ // We're done with the current node. See if we've returned all the records
+ if ( scanState->recordsFound >= scanState->btcb->leafRecords )
+ {
+ return btNotFound;
+ }
+
+ // Move to the first record of the next leaf node
+ scanState->recordNum = 0;
+ err = FindNextLeafNode( scanState, avoidIO );
+ }
+
+ //
+ // If we got an EOF error from FindNextLeafNode, then there are no more leaf
+ // records to be found.
+ //
+ if ( err == fsEndOfIterationErr )
+ err = btNotFound;
+
+ return err;
+
+} /* BTScanNextRecord */
+
+
+//_________________________________________________________________________________
+//
+// Routine: FindNextLeafNode
+//
+// Purpose: Point to the next leaf node in the buffer. Read more nodes
+// into the buffer if needed (and allowed).
+//
+// Inputs:
+// scanState Scanner's current state
+// avoidIO If true, don't do any I/O to refill the buffer
+//
+// Result:
+// noErr Found a valid record
+// fsEndOfIterationErr No more nodes in file
+// ??? Needed to do I/O to get next node, but avoidIO set
+//_________________________________________________________________________________
+
+static int FindNextLeafNode( BTScanState *scanState, Boolean avoidIO )
+{
+ int err;
+
+ err = noErr; // Assume everything will be OK
+
+ while ( 1 )
+ {
+ if ( scanState->nodesLeftInBuffer == 0 )
+ {
+ // Time to read some more nodes into the buffer
+ if ( avoidIO )
+ {
+ return fsBTTimeOutErr;
+ }
+ else
+ {
+ // read some more nodes into buffer
+ err = ReadMultipleNodes( scanState );
+ if ( err != noErr )
+ break;
+ }
+ }
+ else
+ {
+ // Adjust the node counters and point to the next node in the buffer
+ ++scanState->nodeNum;
+ --scanState->nodesLeftInBuffer;
+
+ // If we've looked at all nodes in the tree, then we're done
+ if ( scanState->nodeNum >= scanState->btcb->totalNodes )
+ return fsEndOfIterationErr;
+
+ if ( scanState->nodesLeftInBuffer == 0 )
+ {
+ scanState->recordNum = 0;
+ continue;
+ }
+
+ (u_int8_t *) scanState->currentNodePtr += scanState->btcb->nodeSize;
+ }
+
+ // Make sure this is a valid node
+ if ( CheckNode( scanState->btcb, scanState->currentNodePtr ) != noErr )
+ {
+ continue;
+ }
+
+ if ( scanState->currentNodePtr->kind == kBTLeafNode )
+ break;
+ }
+
+ return err;
+
+} /* FindNextLeafNode */
+
+
+//_________________________________________________________________________________
+//
+// Routine: ReadMultipleNodes
+//
+// Purpose: Read one or more nodes into the buffer.
+//
+// Inputs:
+// theScanStatePtr Scanner's current state
+//
+// Result:
+// noErr One or nodes were read
+// fsEndOfIterationErr No nodes left in file, none in buffer
+//_________________________________________________________________________________
+
+static int ReadMultipleNodes( BTScanState *theScanStatePtr )
+{
+ int myErr = E_NONE;
+ BTreeControlBlockPtr myBTreeCBPtr;
+ daddr_t myPhyBlockNum;
+ u_int32_t myBufferSize;
+ struct vnode * myDevPtr;
+ int myBlockRun;
+ u_int32_t myBlocksInBufferCount;
+
+ // release old buffer if we have one
+ if ( theScanStatePtr->bufferPtr != NULL )
+ {
+ theScanStatePtr->bufferPtr->b_flags |= (B_INVAL | B_AGE);
+ brelse( theScanStatePtr->bufferPtr );
+ theScanStatePtr->bufferPtr = NULL;
+ theScanStatePtr->currentNodePtr = NULL;
+ }
+
+ myBTreeCBPtr = theScanStatePtr->btcb;
+
+ // map logical block in catalog btree file to physical block on volume
+ myErr = VOP_BMAP( myBTreeCBPtr->fileRefNum, theScanStatePtr->nodeNum,
+ &myDevPtr, &myPhyBlockNum, &myBlockRun );
+ if ( myErr != E_NONE )
+ {
+ goto ExitThisRoutine;
+ }
+
+ // bmap block run gives us the remaining number of valid blocks (number of blocks
+ // minus the first). so if there are 10 valid blocks our run number will be 9.
+ // blocks, in our case is the same as nodes (both are 4K)
+ myBlocksInBufferCount = (theScanStatePtr->bufferSize / myBTreeCBPtr->nodeSize );
+ myBufferSize = theScanStatePtr->bufferSize;
+ if ( (myBlockRun + 1) < myBlocksInBufferCount )
+ {
+ myBufferSize = (myBlockRun + 1) * myBTreeCBPtr->nodeSize;
+ }
+
+ // now read blocks from the device
+ myErr = bread( myDevPtr,
+ myPhyBlockNum,
+ myBufferSize,
+ NOCRED,
+ &theScanStatePtr->bufferPtr );
+ if ( myErr != E_NONE )
+ {
+ goto ExitThisRoutine;
+ }
+
+ theScanStatePtr->nodesLeftInBuffer = theScanStatePtr->bufferPtr->b_bcount / theScanStatePtr->btcb->nodeSize;
+ theScanStatePtr->currentNodePtr = (BTNodeDescriptor *) theScanStatePtr->bufferPtr->b_data;
+
+ExitThisRoutine:
+ return myErr;
+
+} /* ReadMultipleNodes */
+
+
+
+//_________________________________________________________________________________
+//
+// Routine: BTScanInitialize
+//
+// Purpose: Prepare to start a new BTree scan, or resume a previous one.
+//
+// Inputs:
+// btreeFile The B-Tree's file control block
+// startingNode Initial node number
+// startingRecord Initial record number within node
+// recordsFound Number of valid records found so far
+// bufferSize Size (in bytes) of buffer
+//
+// Outputs:
+// scanState Scanner's current state; pass to other scanner calls
+//
+// Notes:
+// To begin a new scan and see all records in the B-Tree, pass zeroes for
+// startingNode, startingRecord, and recordsFound.
+//
+// To resume a scan from the point of a previous BTScanTerminate, use the
+// values returned by BTScanTerminate as input for startingNode, startingRecord,
+// and recordsFound.
+//
+// When resuming a scan, the caller should check the B-tree's write count. If
+// it is different from the write count when the scan was terminated, then the
+// tree may have changed and the current state may be incorrect. In particular,
+// you may see some records more than once, or never see some records. Also,
+// the scanner may not be able to detect when all leaf records have been seen,
+// and will have to scan through many empty nodes.
+//
+// XXXÊPerhaps the write count should be managed by BTScanInitialize and
+// XXX BTScanTerminate? This would avoid the caller having to peek at
+// XXX internal B-Tree structures.
+//_________________________________________________________________________________
+
+int BTScanInitialize( const FCB * btreeFile,
+ u_int32_t startingNode,
+ u_int32_t startingRecord,
+ u_int32_t recordsFound,
+ u_int32_t bufferSize,
+ BTScanState * scanState )
+{
+ BTreeControlBlock *btcb;
+
+ //
+ // Make sure this is a valid B-Tree file
+ //
+ btcb = (BTreeControlBlock *) btreeFile->fcbBTCBPtr;
+ if (btcb == NULL)
+ return fsBTInvalidFileErr;
+
+ //
+ // Make sure buffer size is big enough, and a multiple of the
+ // B-Tree node size
+ //
+ if ( bufferSize < btcb->nodeSize )
+ return paramErr;
+ bufferSize = (bufferSize / btcb->nodeSize) * btcb->nodeSize;
+
+ //
+ // Set up the scanner's state
+ //
+ scanState->bufferSize = bufferSize;
+ scanState->bufferPtr = NULL;
+ scanState->btcb = btcb;
+ scanState->nodeNum = startingNode;
+ scanState->recordNum = startingRecord;
+ scanState->currentNodePtr = NULL;
+ scanState->nodesLeftInBuffer = 0; // no nodes currently in buffer
+ scanState->recordsFound = recordsFound;
+ scanState->startTime = time; // initialize our throttle
+
+ return noErr;
+
+} /* BTScanInitialize */
+
+
+//_________________________________________________________________________________
+//
+// Routine: BTScanTerminate
+//
+// Purpose: Return state information about a scan so that it can be resumed
+// later via BTScanInitialize.
+//
+// Inputs:
+// scanState Scanner's current state
+//
+// Outputs:
+// nextNode Node number to resume a scan (pass to BTScanInitialize)
+// nextRecord Record number to resume a scan (pass to BTScanInitialize)
+// recordsFound Valid records seen so far (pass to BTScanInitialize)
+//_________________________________________________________________________________
+
+int BTScanTerminate( BTScanState * scanState,
+ u_int32_t * startingNode,
+ u_int32_t * startingRecord,
+ u_int32_t * recordsFound )
+{
+ *startingNode = scanState->nodeNum;
+ *startingRecord = scanState->recordNum;
+ *recordsFound = scanState->recordsFound;
+
+ if ( scanState->bufferPtr != NULL )
+ {
+ scanState->bufferPtr->b_flags |= (B_INVAL | B_AGE);
+ brelse( scanState->bufferPtr );
+ scanState->bufferPtr = NULL;
+ scanState->currentNodePtr = NULL;
+ }
+
+ return noErr;
+
+} /* BTScanTerminate */
+
+
--- /dev/null
+/*
+ * Copyright (c) 1996-2002 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@
+ *
+ * @(#)BTreeScanner.h
+ */
+
+#ifndef _BTREESCANNER_H_
+#define _BTREESCANNER_H_
+
+#include <sys/time.h>
+
+#include "FileMgrInternal.h"
+#include "BTreesPrivate.h"
+
+// amount of time we are allowed to process a catalog search (in µ secs)
+// NOTE - code assumes kMaxMicroSecsInKernel is less than 1,000,000
+// jertodo - what should we set this to?
+enum { kMaxMicroSecsInKernel = (1000 * 100) }; // 1 tenth of a second
+
+// btree node scanner buffer size. at 32K we get 8 nodes. this is the size used
+// in Mac OS 9
+enum { kCatSearchBufferSize = (32 * 1024) };
+
+
+/*
+ * ============ W A R N I N G ! ============
+ * DO NOT INCREASE THE SIZE OF THIS STRUCT!
+ * It must be less than or equal to the size of
+ * the opaque searchstate struct (in sys/attr.h).
+ */
+/* Private description used in hfs_search */
+struct CatPosition
+{
+ u_int32_t writeCount; /* The BTree's write count (to see if the catalog writeCount */
+ /* changed since the last search). If 0, the rest */
+ /* of the record is invalid, start from beginning. */
+ u_int32_t nextNode; /* node number to resume search */
+ u_int32_t nextRecord; /* record number to resume search */
+ u_int32_t recordsFound; /* number of leaf records seen so far */
+};
+typedef struct CatPosition CatPosition;
+
+
+/*
+ BTScanState - This structure is used to keep track of the current state
+ of a BTree scan. It contains both the dynamic state information (like
+ the current node number and record number) and information that is static
+ for the duration of a scan (such as buffer pointers).
+
+ NOTE: recordNum may equal or exceed the number of records in the node
+ number nodeNum. If so, then the next attempt to get a record will move
+ to a new node number.
+*/
+struct BTScanState
+{
+ // The following fields are set up once at initialization time.
+ // They are not changed during a scan.
+ u_int32_t bufferSize;
+ struct buf * bufferPtr;
+ BTreeControlBlock * btcb;
+
+ // The following fields are the dynamic state of the current scan.
+ u_int32_t nodeNum; // zero is first node
+ u_int32_t recordNum; // zero is first record
+ BTNodeDescriptor * currentNodePtr; // points to current node within buffer
+ u_int32_t nodesLeftInBuffer; // number of valid nodes still in the buffer
+ u_int32_t recordsFound; // number of leaf records seen so far
+ struct timeval startTime; // time we started catalog search
+};
+typedef struct BTScanState BTScanState;
+
+
+/* *********************** PROTOTYPES *********************** */
+
+int BTScanInitialize( const FCB * btreeFile,
+ u_int32_t startingNode,
+ u_int32_t startingRecord,
+ u_int32_t recordsFound,
+ u_int32_t bufferSize,
+ BTScanState * scanState );
+
+int BTScanNextRecord( BTScanState * scanState,
+ Boolean avoidIO,
+ void * * key,
+ void * * data,
+ u_int32_t * dataSize );
+
+int BTScanTerminate( BTScanState * scanState,
+ u_int32_t * startingNode,
+ u_int32_t * startingRecord,
+ u_int32_t * recordsFound );
+
+#endif /* !_BTREESCANNER_H_ */
*mp = (struct mbuf *)0;
} else {
m->m_nextpkt = 0;
- ml = m;
- m = m->m_next;
+ if (ml != 0)
+ ml->m_next = m;
+ ml = m;
+ so->so_rcv.sb_mb = m = m->m_next;
+ ml->m_next = 0;
}
if (m)
m->m_nextpkt = nextrecord;
break;
if (ml) {
- so->so_rcv.sb_mb = ml->m_next;
- ml->m_next = (struct mbuf *)0;
m_freem_list(free_list);
}
error = sbwait(&so->so_rcv);
}
}
if (ml) {
- so->so_rcv.sb_mb = ml->m_next;
- ml->m_next = (struct mbuf *)0;
m_freem_list(free_list);
}
int s;
sMax = flag ? DDP_SOCKET_LAST-46 : DDP_SOCKET_LAST-6;
- sMin = DDP_SOCKET_1st_DYNAMIC-64;
+ sMin = DDP_SOCKET_1st_DYNAMIC;
ATDISABLE(s, adspall_lock);
for (inputC=255, sVal=sMax; sVal >= sMin; sVal--) {
} /* atp_unpack_bdsp */
#define ATP_SOCKET_LAST (DDP_SOCKET_LAST-6)
-#define ATP_SOCKET_FIRST (DDP_SOCKET_1st_DYNAMIC-64)
+#define ATP_SOCKET_FIRST (DDP_SOCKET_1st_DYNAMIC)
static unsigned int sNext = 0;
int atp_bind(gref, sVal, flag)
}
else {
#endif /* INET6 */
- /*
- * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
- * in_broadcast() should never return true on a received
- * packet with M_BCAST not set.
- */
- if (m->m_flags & (M_BCAST|M_MCAST) ||
- IN_MULTICAST(ntohl(ip->ip_dst.s_addr)))
+ /*
+ * RFC1122 4.2.3.10, p. 104: discard bcast/mcast SYN
+ * in_broadcast() should never return true on a received
+ * packet with M_BCAST not set.
+ *
+ * Packets with a multicast source address should also
+ * be discarded.
+ */
+ if (m->m_flags & (M_BCAST|M_MCAST))
+ goto drop;
+ if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
+ IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
+ ip->ip_src.s_addr == htonl(INADDR_BROADCAST) ||
+ in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))
goto drop;
MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME,
M_NOWAIT);
goto drop; /* anycast check is done at the top */
} else
#endif /* INET6 */
- if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)))
+ if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||
+ IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||
+ ip->ip_src.s_addr == htonl(INADDR_BROADCAST) ||
+ in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))
goto drop;
#if TCPDEBUG
if (tp == 0 || (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) {
+++ /dev/null
-/*
- * Copyright (c) 1999 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@
- */
-
-/* Sym8xxClient.m created by russb2 on Sat 30-May-1998 */
-
-#include "Sym8xxController.h"
-
-extern pmap_t kernel_pmap;
-
-
-/*-----------------------------------------------------------------------------*
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::executeCommand( IOSCSIParallelCommand *scsiCommand )
-{
- SRB *srb = NULL;
- SCSICDBInfo scsiCDB;
- SCSITargetLun targetLun;
- Nexus *nexus;
- Nexus *nexusPhys;
- UInt32 len;
- bool isWrite;
-
- srb = (SRB *) scsiCommand->getCommandData();
- bzero( srb, sizeof(SRB) );
-
- srb->srbPhys = (SRB *) pmap_extract( kernel_pmap, (vm_offset_t) srb );
- srb->scsiCommand = scsiCommand;
-
- scsiCommand->getCDB( &scsiCDB );
- scsiCommand->getTargetLun( &targetLun );
-
- nexus = &srb->nexus;
- nexusPhys = &srb->srbPhys->nexus;
-
- srb->target = targetLun.target;
- srb->lun = targetLun.lun;
- srb->srbCDBFlags = scsiCDB.cdbFlags;
-
- /*
- * Setup the Nexus struct. This part of the SRB is read/written both by the
- * script and the driver.
- */
- nexus->targetParms.target = srb->target;
-
-// printf( "SCSI(Symbios8xx): executeCommand: T/L = %d:%d Cmd = %08x CmdType = %d\n\r",
-// targetLun.target, targetLun.lun, (int)scsiCommand, scsiCommand->getCmdType() );
-
- switch ( scsiCommand->getCmdType() )
- {
- case kSCSICommandAbort:
- case kSCSICommandAbortAll:
- case kSCSICommandDeviceReset:
- Sym8xxAbortCommand( scsiCommand );
- return;
-
- default:
- ;
- }
-
- /*
- * Set client data buffer pointers in the SRB
- */
- scsiCommand->getPointers( &srb->xferDesc, &srb->xferCount, &isWrite );
-
- srb->directionMask = (isWrite) ? 0x00000000 :0x01000000;
-
- nexus->cdb.ppData = OSSwapHostToLittleInt32((UInt32)&nexusPhys->cdbData);
-
- len = scsiCDB.cdbLength;
-
- nexus->cdb.length = OSSwapHostToLittleInt32( len );
- nexus->cdbData = scsiCDB.cdb;
-
- Sym8xxCalcMsgs( scsiCommand );
-
- /*
- * Setup initial data transfer list (SGList)
- */
- nexus->ppSGList = (SGEntry *)OSSwapHostToLittleInt32((UInt32)&nexusPhys->sgListData[2]);
- Sym8xxUpdateSGList( srb );
-
- Sym8xxStartSRB( srb );
-}
-
-
-/*-----------------------------------------------------------------------------*
- * This routine queues an SRB to reset the SCSI Bus
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::resetCommand( IOSCSIParallelCommand *scsiCommand )
-{
- SRB *srb;
-
-// printf( "SCSI(Symbios8xx): resetCommand\n\r" );
-
- srb = (SRB *) scsiCommand->getCommandData();
- bzero( srb, sizeof(SRB) );
-
- srb->srbPhys = (SRB *) pmap_extract( kernel_pmap, (vm_offset_t) srb );
- srb->scsiCommand = scsiCommand;
-
- Sym8xxSCSIBusReset( srb );
-}
-
-/*-----------------------------------------------------------------------------*
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::cancelCommand( IOSCSIParallelCommand *scsiCommand )
-{
- IOSCSIParallelCommand *origCommand;
- SRB *srb;
- SCSITargetLun targetLun;
- SCSIResults scsiResults;
-
- origCommand = scsiCommand->getOriginalCmd();
- srb = (SRB *)origCommand->getCommandData();
-
- switch ( origCommand->getCmdType() )
- {
- case kSCSICommandAbort:
- case kSCSICommandAbortAll:
- case kSCSICommandDeviceReset:
- if ( abortSRB == srb )
- {
- SCRIPT_VAR(R_ld_AbortBdr_mailbox) = 0;
- abortSRB = 0;
-
- origCommand->complete();
- }
- break;
-
- default:
-
- if ( adapter->nexusPtrsVirt[srb->nexus.tag] == &srb->nexus )
- {
- adapter->nexusPtrsVirt[srb->nexus.tag] = (Nexus *) -1;
- adapter->nexusPtrsPhys[srb->nexus.tag] = (Nexus *) -1;
-
- origCommand->complete();
- }
- else
- {
- origCommand->getTargetLun( &targetLun );
- origCommand->complete();
-
- IOLog( "SCSI(Symbios8xx): Aborted SRB not found - T/L = %d:%d\n\r", targetLun.target, targetLun.lun );
- }
- }
-
- bzero( &scsiResults, sizeof(scsiResults) );
- scsiCommand->setResults( &scsiResults );
- scsiCommand->complete();
-}
-
-/*-----------------------------------------------------------------------------*
- *
- *
- *
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxAbortCommand( IOSCSIParallelCommand *scsiCommand )
-{
- SRB *srb;
- SCSICDBInfo scsiCDB;
- SCSITargetLun targetLun;
-
-
- scsiCommand->getTargetLun( &targetLun );
-
- switch ( scsiCommand->getCmdType() )
- {
- case kSCSICommandAbort:
- srb = (SRB *)scsiCommand->getOriginalCmd()->getCommandData();
- Sym8xxCancelMailBox( &srb->srbPhys->nexus );
- break;
-
- case kSCSICommandAbortAll:
- Sym8xxCancelMailBox( targetLun.target, targetLun.lun, false );
- break;
-
- case kSCSICommandDeviceReset:
- Sym8xxCancelMailBox( targetLun.target, (UInt32) -1, false );
- break;
-
- default:
- ;
- }
-
- if ( abortSRB )
- {
- abortReqPending = true;
-
- rescheduleCommand( scsiCommand );
- disableCommands();
- return;
- }
-
- scsiCommand->getCDB( &scsiCDB );
-
- srb = (SRB *) scsiCommand->getCommandData();
-
- srb->nexus.msgData[0] = srb->lun | ((srb->srbCDBFlags & kCDBFlagsNoDisconnect ) ? 0x80 : 0xC0);
-
- if ( scsiCDB.cdbTagMsg != 0 )
- {
- srb->nexus.tag = scsiCDB.cdbTag + 128;
- srb->nexus.msgData[1] = srb->nexus.tag;
- }
- else
- {
- srb->nexus.tag = ((UInt32)srb->target << 3) | srb->lun;
- srb->nexus.msgData[1] = 0;
- }
- srb->tag = srb->nexus.tag;
-
- srb->nexus.msgData[2] = scsiCDB.cdbAbortMsg;
-
- Sym8xxAbortBdr( srb );
-}
-
-
-/*-----------------------------------------------------------------------------*
- * This routine creates SCSI messages to send during the initial connection
- * to the target. It is called during client request processing and also by
- * the I/O thread when a request sense operation is required.
- *
- * Outbound messages are setup in the MsgOut buffer in the Nexus structure of
- * the SRB.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxCalcMsgs( IOSCSIParallelCommand *scsiCommand )
-{
- SRB *srb;
- Nexus *nexus;
- Nexus *nexusPhys;
- UInt32 msgIndex;
- SCSICDBInfo scsiCDB;
- SCSITargetParms targetParms;
- UInt32 i;
- UInt32 tw;
-
-
- srb = (SRB *)scsiCommand->getCommandData();
- nexus = &srb->nexus;
- nexusPhys = &srb->srbPhys->nexus;
-
- scsiCommand->getCDB( &scsiCDB );
-
- /*
- * Setup Identify message
- */
- msgIndex = 0;
- nexus->msg.ppData = OSSwapHostToLittleInt32((UInt32)&nexusPhys->msgData);
- nexus->msgData[msgIndex++] = srb->lun | (( scsiCDB.cdbFlags & kCDBFlagsNoDisconnect ) ? 0x80 : 0xC0);
-
- /*
- * Allocate tag for request.
- *
- * For non-tagged requests a pseudo-tag is created consisting of target*16+lun. For tagged
- * requests a tag in the range 128-255 is allocated.
- *
- * If a pseudo-tag is inuse for a non-tagged command or there are no tags available for
- * a tagged request, then the command is blocked until a tag becomes available.
- *
- * Note: If we are being called during request sense processing (srbState != ksrbStateCDBDone)
- * then a tag has already been allocated to the request.
- */
- if ( scsiCDB.cdbTagMsg != 0 )
- {
- nexus->msgData[msgIndex++] = scsiCDB.cdbTagMsg;
- nexus->msgData[msgIndex++] = srb->tag = srb->nexus.tag = scsiCDB.cdbTag + 128;
- }
- else
- {
- srb->tag = srb->nexus.tag = ((UInt32)srb->target << 3) | srb->lun;
- }
- /*
- * Setup to negotiate for Wide (16-bit) data transfers
- *
- * Note: There is no provision to negotiate back to narrow transfers although
- * SCSI does support this.
- */
-
- scsiCommand->getDevice(kIOSCSIParallelDevice)->getTargetParms( &targetParms );
-
- if ( scsiCDB.cdbFlags & (kCDBFlagsNegotiateWDTR | kCDBFlagsNegotiateSDTR) )
- {
- negotiateWDTRComplete = negotiateSDTRComplete = false;
- }
-
- if ( scsiCDB.cdbFlags & kCDBFlagsNegotiateWDTR )
- {
- nexus->msgData[msgIndex++] = kSCSIMsgExtended;
- nexus->msgData[msgIndex++] = 2;
- nexus->msgData[msgIndex++] = kSCSIMsgWideDataXferReq;
-
- for ( tw = targetParms.transferWidth, i = (UInt32)-1;
- tw;
- tw >>= 1, i++ )
- ;
-
- nexus->msgData[msgIndex++] = i;
- }
-
- /*
- * Setup to negotiate for Synchronous data transfers.
- *
- * Note: We can negotiate back to async based on the flags in the command.
- */
-
- if ( scsiCDB.cdbFlags & kCDBFlagsNegotiateSDTR )
- {
- nexus->msgData[msgIndex++] = kSCSIMsgExtended;
- nexus->msgData[msgIndex++] = 3;
- nexus->msgData[msgIndex++] = kSCSIMsgSyncXferReq;
- if ( targetParms.transferOffset != 0 )
- {
- nexus->msgData[msgIndex++] = targetParms.transferPeriodpS / 4000;
- nexus->msgData[msgIndex++] = targetParms.transferOffset;
- }
- else
- {
- nexus->msgData[msgIndex++] = 0;
- nexus->msgData[msgIndex++] = 0;
- }
-
- }
-
- /*
- * If we are negotiating for both Sync and Wide data transfers, we setup both messages
- * in the Nexus msgOut buffer. However, after each message the script needs to wait for
- * a reply message from the target. In this case, we set the msgOut length to include
- * bytes upto the end of the Wide message. When we get the reply from the target, the
- * routine handling the WDTR will setup the Nexus pointers/counts to send the remaining
- * message bytes. See Sym8xxExecute.m(Sym8xxNegotiateWDTR).
- */
- srb->srbMsgLength = msgIndex;
-
- if ((scsiCDB.cdbFlags & (kCDBFlagsNegotiateWDTR | kCDBFlagsNegotiateSDTR))
- == (kCDBFlagsNegotiateWDTR | kCDBFlagsNegotiateSDTR))
- {
- msgIndex -= 5;
- }
-
- nexus->msg.length = OSSwapHostToLittleInt32( msgIndex );
-
- srb->srbCDBFlags = scsiCDB.cdbFlags;
-}
-
-/*-----------------------------------------------------------------------------*
- * This routine sets up the data transfer SG list for the client's buffer in the
- * Nexus structure.
- *
- * The SGList actually consists of script instructions. The script will branch
- * to the SGList when the target enters data transfer phase. When the SGList completes
- * it will either execute a script INT instruction if there are more segments of the
- * user buffer that need to be transferred or will execute a script RETURN instruction
- * to return to the script.
- *
- * The first two slots in the SGList are reserved for partial data transfers. See
- * Sym8xxExecute.m(Sym8xxAdjustDataPtrs).
- *
- *-----------------------------------------------------------------------------*/
-
-
-/*-----------------------------------------------------------------------------*
- * Build SG list based on an IOMemoryDescriptor object.
- *
- *-----------------------------------------------------------------------------*/
-bool Sym8xxSCSIController::Sym8xxUpdateSGList( SRB *srb )
-{
- IOPhysicalSegment range;
- UInt32 actRanges;
- UInt32 offset;
- UInt32 bytesLeft;
- UInt32 i;
- IOReturn rc = true;
-
- offset = srb->xferOffset;
- bytesLeft = srb->xferCount - srb->xferOffset;
-
- if ( bytesLeft == 0 ) return rc;
-
- i = 2;
-
- while ( (bytesLeft > 0) && (i < MAX_SGLIST_ENTRIES-1))
- {
- actRanges = memoryCursor->getPhysicalSegments( srb->xferDesc,
- offset,
- &range,
- 1 );
-
- if ( actRanges != 1 )
- {
- rc = false;
- break;
- }
-
- /*
- * Note: The script instruction(s) to transfer data to/from the scsi bus
- * have the same format as a typical SGList with the transfer length
- * as the first word and the physical transfer address as the second.
- * The data transfer direction is specified by a bit or'd into the
- * high byte of the SG entry's length field.
- */
- srb->nexus.sgListData[i].physAddr = OSSwapHostToLittleInt32( (UInt32)range.location );
- srb->nexus.sgListData[i].length = OSSwapHostToLittleInt32( range.length | srb->directionMask );
-
- bytesLeft -= range.length;
- offset += range.length;
- i++;
- }
-
- if ( !bytesLeft )
- {
- srb->nexus.sgListData[i].length = OSSwapHostToLittleInt32( 0x90080000 );
- srb->nexus.sgListData[i].physAddr = OSSwapHostToLittleInt32( 0x00000000 );
- }
- else
- {
- srb->nexus.sgListData[i].length = OSSwapHostToLittleInt32( 0x98080000 );
- srb->nexus.sgListData[i].physAddr = OSSwapHostToLittleInt32( A_sglist_complete );
- }
-
- srb->xferOffsetPrev = srb->xferOffset;
- srb->xferOffset = offset;
-
- return rc;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 1999 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@
- */
-
-/* Sym8xxController.h created by russb2 on Sat 30-May-1998 */
-
-#include <IOKit/IOMemoryCursor.h>
-#include <IOKit/pci/IOPCIDevice.h>
-#include <libkern/OSByteOrder.h>
-
-#include <IOKit/scsi/IOSCSIParallelInterface.h>
-
-#include "Sym8xxRegs.h"
-#include "Sym8xxInterface.h"
-#include "Sym8xxSRB.h"
-
-#include "Sym8xxScript.h"
-
-#define offsetof(type, field) ((int)&((type *)0)->field)
-
-class Sym8xxSCSIController : public IOSCSIParallelController
-{
- OSDeclareDefaultStructors( Sym8xxSCSIController )
-
-private:
-
- AdapterInterface *adapter;
- AdapterInterface *adapterPhys;
-
- UInt32 nexusArrayVirt[MAX_SCSI_TAG];
-
- IOBigMemoryCursor *memoryCursor;
-
- IOPCIDevice *provider;
-
- IOInterruptEventSource *interruptEvent;
-
- IOMemoryMap *ioMapRegs;
- IOMemoryMap *ioMapRam;
-
- UInt8 mailBoxIndex;
-
- UInt32 initiatorID;
-
- UInt8 istatReg;
- UInt8 dstatReg;
- u_int16_t sistReg;
-
- UInt32 scriptRestartAddr;
-
- UInt32 srbSeqNum;
- UInt32 resetSeqNum;
-
- SRB *resetSRB;
- SRB *abortSRB;
- SRB *abortCurrentSRB;
- bool abortReqPending;
- bool initialReset;
-
- bool negotiateWDTRComplete;
- bool negotiateSDTRComplete;
-
- UInt32 transferPeriod;
- UInt32 transferOffset;
- UInt32 transferWidth;
-
- UInt32 chipId;
- UInt32 chipClockRate;
-
- volatile UInt8 *chipBaseAddr;
- UInt8 *chipBaseAddrPhys;
-
- volatile UInt8 *chipRamAddr;
- UInt8 *chipRamAddrPhys;
-
-public:
- bool configure( IOService *forProvider, SCSIControllerInfo *controllerInfo );
- void executeCommand( IOSCSIParallelCommand *scsiCommand );
- void cancelCommand( IOSCSIParallelCommand *scsiCommand );
- void resetCommand( IOSCSIParallelCommand *scsiCommand );
-
-private:
- bool Sym8xxInit();
- bool Sym8xxInitPCI();
- bool Sym8xxInitVars();
- bool Sym8xxInitScript();
- void Sym8xxLoadScript( UInt32 *scriptPgm, UInt32 scriptWords );
- bool Sym8xxInitChip();
-
- void Sym8xxCalcMsgs( IOSCSIParallelCommand *scsiCommand );
- void Sym8xxAbortCommand( IOSCSIParallelCommand *scsiCommand );
-
- bool Sym8xxUpdateSGList( SRB *srb );
- bool Sym8xxUpdateSGListVirt( SRB *srb );
- bool Sym8xxUpdateSGListDesc( SRB *srb );
-
- void Sym8xxStartSRB( SRB *srb );
- void Sym8xxSignalScript( SRB *srb );
- void interruptOccurred( IOInterruptEventSource *ies, int intCount );
- void Sym8xxProcessIODone();
- void Sym8xxCompleteSRB( SRB *srb );
- void Sym8xxProcessInterrupt();
- void Sym8xxAdjustDataPtrs( SRB *srb, Nexus *nexus );
- UInt32 Sym8xxCheckFifo( SRB *srb, UInt32 *pfifoCnt );
- void Sym8xxUpdateXferOffset( SRB *srb );
- void Sym8xxProcessNoNexus();
- void Sym8xxAbortCurrent( SRB *srb );
- void Sym8xxClearFifo();
- void Sym8xxNegotiateSDTR( SRB *srb, Nexus *nexus );
- void Sym8xxNegotiateWDTR( SRB *srb, Nexus *nexus );
- void Sym8xxSendMsgReject( SRB *srb );
- void Sym8xxSCSIBusReset(SRB *srb );
- void Sym8xxProcessSCSIBusReset();
- void Sym8xxCheckRequestSense( SRB *srb );
- void Sym8xxAbortBdr( SRB *srb );
- bool Sym8xxCancelMailBox( Nexus *nexusCancel );
- void Sym8xxCancelMailBox( UInt32 target, UInt32 lun, bool fReschedule );
-
- void Sym8xxAbortScript();
-
- UInt32 Sym8xxReadRegs( volatile UInt8 *chipRegs, UInt32 regOffset, UInt32 regSize );
- void Sym8xxWriteRegs( volatile UInt8 *chipRegs, UInt32 regOffset, UInt32 regSize, UInt32 regValue );
-
-};
-
+++ /dev/null
-/*
- * Copyright (c) 1999 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@
- */
-
-/* Sym8xxExecute.m created by russb2 on Sat 30-May-1998 */
-
-#include "Sym8xxController.h"
-
-extern "C"
-{
- unsigned int ml_phys_read( vm_offset_t paddr );
-};
-
-#if 0
-static UInt32 dropInt = 0;
-#endif
-
-void Sym8xxSCSIController::Sym8xxStartSRB( SRB *srb )
-{
-
- srb->nexus.targetParms.scntl3Reg = adapter->targetClocks[srb->target].scntl3Reg;
- srb->nexus.targetParms.sxferReg = adapter->targetClocks[srb->target].sxferReg;
-
- adapter->nexusPtrsVirt[srb->nexus.tag] = &srb->nexus;
- adapter->nexusPtrsPhys[srb->nexus.tag] = (Nexus *)OSSwapHostToLittleInt32( (UInt32)&srb->srbPhys->nexus );
- adapter->schedMailBox[mailBoxIndex++] = (Nexus *)OSSwapHostToLittleInt32 ( (UInt32)&srb->srbPhys->nexus );
-
- Sym8xxSignalScript( srb );
-}
-
-
-/*-----------------------------------------------------------------------------*
- * Interrupts from the Symbios chipset are dispatched here at task time under the
- * IOThread's context.
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::interruptOccurred( IOInterruptEventSource *ies, int intCount )
-{
- do
- {
- /*
- * The chipset's ISTAT reg gives us the general interrupting condiditions,
- * with DSTAT and SIST providing more detailed information.
- */
- istatReg = Sym8xxReadRegs( chipBaseAddr, ISTAT, ISTAT_SIZE );
-
- /* The INTF bit in ISTAT indicates that the script is signalling the driver
- * that its IODone mailbox is full and that we should process a completed
- * request. The script continues to run after posting this interrupt unlike
- * other chipset interrupts which require the driver to restart the script
- * engine.
- */
- if ( istatReg & INTF )
- {
- Sym8xxWriteRegs( chipBaseAddr, ISTAT, ISTAT_SIZE, istatReg );
-#if 0
- if ( dropInt++ > 100 )
- {
- dropInt = 0;
- SCRIPT_VAR(R_ld_IOdone_mailbox) = 0;
- continue;
- }
-#endif
- Sym8xxProcessIODone();
- }
-
- /*
- * Handle remaining interrupting conditions
- */
- if ( istatReg & (SIP | DIP) )
- {
- Sym8xxProcessInterrupt();
- }
- }
- while ( istatReg & (SIP | DIP | INTF) );
-
- getWorkLoop()->enableAllInterrupts();
-
-}
-
-/*-----------------------------------------------------------------------------*
- * Process a request posted in the script's IODone mailbox.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxProcessIODone()
-{
- SRB *srb;
- Nexus *nexus;
- IODoneMailBox *pMailBox;
-
-
- /*
- * The IODone mailbox contains an index into our Nexus pointer tables.
- *
- * The Nexus struct is part of the SRB so we can get our SRB address
- * by subtracting the offset of the Nexus struct in the SRB.
- */
- pMailBox = (IODoneMailBox *)&SCRIPT_VAR(R_ld_IOdone_mailbox);
- nexus = adapter->nexusPtrsVirt[pMailBox->nexus];
- srb = (SRB *)((UInt32)nexus - offsetof(SRB, nexus));
-
- srb->srbSCSIStatus = pMailBox->status;
-
- if ( srb->srbSCSIStatus == kSCSIStatusCheckCondition )
- {
- Sym8xxCheckRequestSense( srb );
- }
-
- Sym8xxUpdateXferOffset( srb );
-
- /*
- * Clear the completed Nexus pointer from our tables and clear the
- * IODone mailbox.
- */
- adapter->nexusPtrsVirt[pMailBox->nexus] = (Nexus *) -1;
- adapter->nexusPtrsPhys[pMailBox->nexus] = (Nexus *) -1;
- SCRIPT_VAR(R_ld_IOdone_mailbox) = 0;
-
- /*
- * Wake up the client's thread to do post-processing
- */
- Sym8xxCompleteSRB( srb );
-
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_select_phase];
-}
-/*-----------------------------------------------------------------------------*
- *
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxCompleteSRB( SRB *srb )
-{
- IOSCSIParallelCommand *scsiCommand;
- SCSIResults scsiResults;
- SCSINegotiationResults negotiationResult, *negResult;
-
-
- scsiCommand = srb->scsiCommand;
-
- bzero( &scsiResults, sizeof(scsiResults) );
-
- scsiResults.adapterStatus = srb->srbAdapterStatus;
- scsiResults.returnCode = srb->srbReturnCode;
-
-
- if ( srb == abortSRB )
- {
- abortSRB = 0;
- if ( abortReqPending == true )
- {
- abortReqPending = false;
- enableCommands();
- }
- }
- else
- {
- scsiResults.bytesTransferred = srb->xferDone;
- scsiResults.scsiStatus = srb->srbSCSIStatus;
- }
-
- negResult = 0;
-
- if ( (srb->srbCDBFlags & kCDBFlagsNegotiateSDTR) || (srb->srbCDBFlags & kCDBFlagsNegotiateWDTR) )
- {
- bzero( &negotiationResult, sizeof(struct SCSINegotiationResults) );
-
- if ( ((srb->srbCDBFlags & kCDBFlagsNegotiateSDTR) && srb->negotiateSDTRComplete == false) ||
- ((srb->srbCDBFlags & kCDBFlagsNegotiateWDTR) && srb->negotiateWDTRComplete == false) )
- {
- negotiationResult.returnCode = kIOReturnIOError;
- }
-
- negotiationResult.transferPeriodpS = transferPeriod;
- negotiationResult.transferOffset = transferOffset;
- negotiationResult.transferWidth = transferWidth;
- negotiationResult.transferOptions = 0;
-
- negResult = &negotiationResult;
- }
-
- scsiCommand->setResults( &scsiResults, negResult );
- scsiCommand->complete();
-}
-
-/*-----------------------------------------------------------------------------*
- * General script interrupt processing
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxProcessInterrupt()
-{
- SRB *srb = NULL;
- Nexus *nexus = NULL;
- UInt32 nexusIndex;
- UInt32 scriptPhase;
- UInt32 fifoCnt = 0;
- UInt32 dspsReg = 0;
- UInt32 dspReg = 0;
-
-
- /*
- * Read DSTAT/SIST regs to determine why the script stopped.
- */
- dstatReg = Sym8xxReadRegs( chipBaseAddr, DSTAT, DSTAT_SIZE );
- IODelay(5);
- sistReg = Sym8xxReadRegs( chipBaseAddr, SIST, SIST_SIZE );
-
-// printf( "SCSI(Symbios8xx): SIST = %04x DSTAT = %02x\n\r", sistReg, dstatReg );
-
- /*
- * This Script var tells us what the script thinks it was doing when the interrupt occurred.
- */
- scriptPhase = OSSwapHostToLittleInt32( SCRIPT_VAR(R_ld_phase_flag) );
-
- /*
- * SCSI Bus reset detected
- *
- * Clean up the carnage.
- * Note: This may be either an adapter or target initiated reset.
- */
- if ( sistReg & RSTI )
- {
- Sym8xxProcessSCSIBusReset();
- return;
- }
-
- /*
- * Calculate our current SRB/Nexus.
- *
- * Read a script var to determine the index of the nexus it was processing
- * when the interrupt occurred. The script will invalidate the index if there
- * is no target currently connected or the script cannot determine which target
- * has reconnected.
- */
- nexusIndex = OSSwapHostToLittleInt32(SCRIPT_VAR(R_ld_nexus_index));
- if ( nexusIndex >= MAX_SCSI_TAG )
- {
- Sym8xxProcessNoNexus();
- return;
- }
- nexus = adapter->nexusPtrsVirt[nexusIndex];
- if ( nexus == (Nexus *) -1 )
- {
- Sym8xxProcessNoNexus();
- return;
- }
- srb = (SRB *)((UInt32)nexus - offsetof(SRB, nexus));
-
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_phase_handler];
-
- /*
- * Parity and SCSI Gross Errors.
- *
- * Abort the current connection. The abort completion will trigger
- * clean-up of the current SRB/Nexus.
- */
- if ( sistReg & PAR )
- {
- srb->srbAdapterStatus = kSCSIAdapterStatusParityError;
- Sym8xxAbortCurrent( srb );
- }
-
- else if ( sistReg & SGE )
- {
- srb->srbAdapterStatus = kSCSIAdapterStatusProtocolError;
- Sym8xxAbortCurrent( srb );
- }
-
- /*
- * Unexpected disconnect.
- *
- * If we were currently trying to abort this connection then mark the abort
- * as completed. For all cases clean-up and wake-up the client thread.
- */
- else if ( sistReg & UDC )
- {
- if ( srb->srbAdapterStatus == kSCSIAdapterStatusSuccess )
- {
- srb->srbAdapterStatus = kSCSIAdapterStatusProtocolError;
- }
- adapter->nexusPtrsVirt[nexusIndex] = (Nexus *) -1;
- adapter->nexusPtrsPhys[nexusIndex] = (Nexus *) -1;
-
- if ( scriptPhase == A_kphase_ABORT_CURRENT )
- {
- abortCurrentSRB = NULL;
- }
-
- Sym8xxCompleteSRB( srb );
-
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_select_phase];
- }
-
- /*
- * Phase Mis-match
- *
- * If we are in MsgOut phase then calculate how much of the message we sent. For
- * now, however, we dont handle the target rejecting messages, so the request is aborted.
- *
- * If we are in DataIn/DataOut phase. We update the SRB/Nexus with our current data
- * pointers.
- */
- else if ( sistReg & MA )
- {
- if ( scriptPhase == A_kphase_MSG_OUT )
- {
- srb->srbMsgResid = Sym8xxCheckFifo( srb, &fifoCnt );
- nexus->msg.ppData = OSSwapHostToLittleInt32( OSSwapHostToLittleInt32(nexus->msg.ppData)
- + OSSwapHostToLittleInt32(nexus->msg.length)
- - srb->srbMsgResid );
- nexus->msg.length = OSSwapHostToLittleInt32( srb->srbMsgResid );
-
- Sym8xxAbortCurrent( srb );
- }
- else if ( (scriptPhase == A_kphase_DATA_OUT) || (scriptPhase == A_kphase_DATA_IN) )
- {
- Sym8xxAdjustDataPtrs( srb, nexus );
- }
- else
- {
- IOLog("SCSI(Symbios8xx): Unexpected phase mismatch - scriptPhase = %08x\n\r", (int)scriptPhase);
- Sym8xxAbortCurrent( srb );
- }
-
- Sym8xxClearFifo();
- }
-
- /*
- * Selection Timeout.
- *
- * Clean-up the current request.
- */
- else if ( sistReg & STO )
- {
- srb->srbAdapterStatus = kSCSIAdapterStatusSelectionTimeout;
-
- adapter->nexusPtrsVirt[nexusIndex] = (Nexus *) -1;
- adapter->nexusPtrsPhys[nexusIndex] = (Nexus *) -1;
- SCRIPT_VAR(R_ld_IOdone_mailbox) = 0;
-
- Sym8xxCompleteSRB( srb );
-
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_select_phase];
- }
-
- /*
- * Handle script initiated interrupts
- */
- else if ( dstatReg & SIR )
- {
- dspsReg = Sym8xxReadRegs( chipBaseAddr, DSPS, DSPS_SIZE );
-
-// printf( "SCSI(Symbios8xx): DSPS = %08x\n\r", dspsReg );
-
- switch ( dspsReg )
- {
- /*
- * Non-zero SCSI status
- *
- * Send request sense CDB or complete request depending on SCSI status value
- */
- case A_status_error:
- Sym8xxProcessIODone();
- break;
-
- /*
- * Received SDTR/WDTR message from target.
- *
- * Prepare reply message if we requested negotiation. Otherwise reject
- * target initiated negotiation.
- */
- case A_negotiateSDTR:
- Sym8xxNegotiateSDTR( srb, nexus );
- break;
-
- case A_negotiateWDTR:
- Sym8xxNegotiateWDTR( srb, nexus );
- break;
-
- /*
- * Partial SG List completed.
- *
- * Refresh the list from the remaining addresses to be transfered and set the
- * script engine to branch into the list.
- */
- case A_sglist_complete:
- Sym8xxUpdateSGList( srb );
- scriptRestartAddr = (UInt32)&srb->srbPhys->nexus.sgListData[2];
- break;
-
- /*
- * Completed abort request
- *
- * Clean-up the aborted request.
- */
- case A_abort_current:
- adapter->nexusPtrsVirt[nexusIndex] = (Nexus *) -1;
- adapter->nexusPtrsPhys[nexusIndex] = (Nexus *) -1;
-
- abortCurrentSRB = NULL;
-
- Sym8xxCompleteSRB( srb );
-
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_select_phase];
- break;
-
- /*
- * Script detected protocol errors
- *
- * Abort the current request.
- */
- case A_unknown_phase:
- srb->srbAdapterStatus = kSCSIAdapterStatusProtocolError;
- Sym8xxAbortCurrent( srb );
- break;
-
- case A_unknown_msg_reject:
- case A_unexpected_msg:
- case A_unexpected_ext_msg:
- srb->srbAdapterStatus = kSCSIAdapterStatusMsgReject;
- Sym8xxAbortCurrent( srb );
- break;
-
- default:
- IOLog( "SCSI(Symbios8xx): Unknown Script Int = %08x\n\r", (int)dspsReg );
- Sym8xxAbortCurrent( srb );
- }
- }
-
- /*
- * Illegal script instruction.
- *
- * We're toast! Abort the current request and hope for the best!
- */
- else if ( dstatReg & IID )
- {
- dspReg = Sym8xxReadRegs( chipBaseAddr, DSP, DSP_SIZE );
-
- IOLog("SCSI(Symbios8xx): Illegal script instruction - dsp = %08x srb=%08x\n\r", (int)dspReg, (int)srb );
-
- Sym8xxAbortCurrent( srb );
- }
-
- if ( scriptRestartAddr )
- {
- Sym8xxWriteRegs( chipBaseAddr, DSP, DSP_SIZE, scriptRestartAddr );
- }
-}
-
-
-/*-----------------------------------------------------------------------------*
- * Current Data Pointer calculations
- *
- * To do data transfers the driver generates a list of script instructions
- * in system storage to deliver data to the requested physical addresses. The
- * script branches to the list when the target enters data transfer phase.
- *
- * When the target changes phase during a data transfer, data is left trapped
- * inside the various script engine registers. This routine determines how much
- * data was not actually transfered to/from the target and generates a new
- * S/G List entry for the partial transfer and a branch back into the original
- * S/G list. These script instructions are stored in two reserved slots at the
- * top of the original S/G List.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxAdjustDataPtrs( SRB *srb, Nexus *nexus )
-{
- UInt32 i;
- UInt32 sgResid;
- UInt32 fifoCnt;
- UInt32 dspReg;
- UInt32 sgDone;
- UInt8 scntl2Reg;
- Nexus *nexusPhys;
-
- /*
- * Determine SG element residual
- *
- * This routine returns how much of the current S/G List element the
- * script was processing remains to be sent/received. All the information
- * required to do this is stored in the script engine's registers.
- */
- sgResid = Sym8xxCheckFifo( srb, &fifoCnt );
-
- /*
- * Determine which script instruction in our SGList we were executing when
- * the target changed phase.
- *
- * The script engine's dspReg tells us where the script thinks it was. Based
- * on the physical address of our current SRB/Nexus we can calculate
- * an index into our S/G List.
- */
- dspReg = Sym8xxReadRegs( chipBaseAddr, DSP, DSP_SIZE );
-
- i = ((dspReg - (UInt32)srb->srbPhys->nexus.sgListData) / sizeof(SGEntry)) - 1;
-
- if ( i > MAX_SGLIST_ENTRIES-1 )
- {
- IOLog("SCSI(Symbios8xx): Bad sgListIndex\n\r");
- Sym8xxAbortCurrent( srb );
- return;
- }
-
- /*
- * Wide/odd-byte transfers.
- *
- * When dealing with Wide data transfers, if a S/G List ends with an odd-transfer count, then a
- * valid received data byte is left in the script engine's SWIDE register. The least painful way
- * to recover this byte is to construct a small script thunk to transfer one additional byte. The
- * script will automatically draw this byte from the SWIDE register rather than the SCSI bus.
- * The script thunk then branches back to script's PhaseHandler entrypoint.
- *
- */
- nexusPhys = &srb->srbPhys->nexus;
-
- scntl2Reg = Sym8xxReadRegs( chipBaseAddr, SCNTL2, SCNTL2_SIZE );
- if ( scntl2Reg & WSR )
- {
- adapter->xferSWideInst[0] = OSSwapHostToLittleInt32( srb->directionMask | 1 );
- adapter->xferSWideInst[1] = nexus->sgListData[i].physAddr;
- adapter->xferSWideInst[2] = OSSwapHostToLittleInt32( 0x80080000 );
- adapter->xferSWideInst[3] = OSSwapHostToLittleInt32( (UInt32)&chipRamAddrPhys[Ent_phase_handler] );
-
- scriptRestartAddr = (UInt32) adapterPhys->xferSWideInst;
-
- /*
- * Note: There is an assumption here that the sgResid count will be > 1. It appears
- * that the script engine does not generate a phase-mismatch interrupt until
- * we attempt to move > 1 byte from the SCSI bus and the only byte available is
- * in SWIDE.
- */
- sgResid--;
- }
-
- /*
- * Calculate partial S/G List instruction and branch
- *
- * Fill in slots 0/1 of the SGList based on the SGList index (i) and SGList residual count
- * (sgResid) calculated above.
- *
- */
- sgDone = (OSSwapHostToLittleInt32( nexus->sgListData[i].length ) & 0x00ffffff) - sgResid;
-
- nexus->sgListData[0].length = OSSwapHostToLittleInt32( sgResid | srb->directionMask );
- nexus->sgListData[0].physAddr = OSSwapHostToLittleInt32( OSSwapHostToLittleInt32(nexus->sgListData[i].physAddr) + sgDone );
- /*
- * If a previously calculated SGList 0 entry was interrupted again, we dont need to calculate
- * a new branch address since the previous one is still valid.
- */
- if ( i != 0 )
- {
- nexus->sgListData[1].length = OSSwapHostToLittleInt32( 0x80080000 );
- nexus->sgListData[1].physAddr = OSSwapHostToLittleInt32( (UInt32)&nexusPhys->sgListData[i+1] );
- nexus->sgNextIndex = i + 1;
- }
- nexus->ppSGList = (SGEntry *)OSSwapHostToLittleInt32( (UInt32) &nexusPhys->sgListData[0] );
-
- /*
- * The script sets this Nexus variable to non-zero each time it calls the driver generated
- * S/G list. This allows the driver's completion routines to differentiate between a successful
- * transfer vs no data transfer at all.
- */
- nexus->dataXferCalled = 0;
-
- return;
-}
-
-/*-----------------------------------------------------------------------------*
- * Determine SG element residual
- *
- * This routine returns how much of the current S/G List element the
- * script was processing remains to be sent/received. All the information
- * required to do this is stored in the script engine's registers.
- *
- *-----------------------------------------------------------------------------*/
-UInt32 Sym8xxSCSIController::Sym8xxCheckFifo( SRB *srb, UInt32 *pfifoCnt )
-{
- bool fSCSISend;
- bool fXferSync;
- UInt32 scriptPhase = 0;
- UInt32 dbcReg = 0;
- UInt32 dfifoReg = 0;
- UInt32 ctest5Reg = 0;
- UInt8 sstat0Reg = 0;
- UInt8 sstat1Reg = 0;
- UInt8 sstat2Reg = 0;
- UInt32 fifoCnt = 0;
- UInt32 sgResid = 0;
-
- scriptPhase = OSSwapHostToLittleInt32( SCRIPT_VAR(R_ld_phase_flag) );
-
- fSCSISend = (scriptPhase == A_kphase_DATA_OUT) || (scriptPhase == A_kphase_MSG_OUT);
-
- fXferSync = ((scriptPhase == A_kphase_DATA_OUT) || (scriptPhase == A_kphase_DATA_IN))
- && (srb->nexus.targetParms.sxferReg & 0x1F);
-
- dbcReg = Sym8xxReadRegs( chipBaseAddr, DBC, DBC_SIZE ) & 0x00ffffff;
-
- if ( !(dstatReg & DFE) )
- {
- ctest5Reg = Sym8xxReadRegs( chipBaseAddr, CTEST5, CTEST5_SIZE );
- dfifoReg = Sym8xxReadRegs( chipBaseAddr, DFIFO, DFIFO_SIZE );
-
- if ( ctest5Reg & DFS )
- {
- fifoCnt = ((((ctest5Reg & 0x03) << 8) | dfifoReg) - dbcReg) & 0x3ff;
- }
- else
- {
- fifoCnt = (dfifoReg - dbcReg) & 0x7f;
- }
- }
-
- sstat0Reg = Sym8xxReadRegs( chipBaseAddr, SSTAT0, SSTAT0_SIZE );
- sstat2Reg = Sym8xxReadRegs( chipBaseAddr, SSTAT2, SSTAT2_SIZE );
-
- if ( fSCSISend )
- {
- fifoCnt += (sstat0Reg & OLF ) ? 1 : 0;
- fifoCnt += (sstat2Reg & OLF1) ? 1 : 0;
-
- if ( fXferSync )
- {
- fifoCnt += (sstat0Reg & ORF ) ? 1 : 0;
- fifoCnt += (sstat2Reg & ORF1) ? 1 : 0;
- }
- }
- else
- {
- if ( fXferSync )
- {
- sstat1Reg = Sym8xxReadRegs( chipBaseAddr, SSTAT0, SSTAT0_SIZE );
- fifoCnt += (sstat1Reg >> 4) | (sstat2Reg & FF4);
- }
- else
- {
- fifoCnt += (sstat0Reg & ILF ) ? 1 : 0;
- fifoCnt += (sstat2Reg & ILF1) ? 1 : 0;
- }
- }
-
- sgResid = dbcReg + fifoCnt;
- *pfifoCnt = fifoCnt;
-
- return sgResid;
-}
-
-/*-----------------------------------------------------------------------------*
- * Calculate transfer counts.
- *
- * This routine updates srb->xferDone with the amount of data transferred
- * by the last S/G List executed.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxUpdateXferOffset( SRB *srb )
-{
- UInt32 i;
- UInt32 xferOffset;
-
- /*
- * srb->xferOffset contains the client buffer offset INCLUDING the range
- * covered by the current SGList.
- */
- xferOffset = srb->xferOffset;
-
- /*
- * If script did not complete the current transfer list then we need to determine
- * how much of the list was completed.
- */
- if ( srb->nexus.dataXferCalled == 0 )
- {
- /*
- * srb->xferOffsetPrev contains the client buffer offset EXCLUDING the
- * range covered by the current SGList.
- */
- xferOffset = srb->xferOffsetPrev;
-
- /*
- * Calculate bytes transferred for partially completed list.
- *
- * To calculate the amount of this list completed, we sum the residual amount
- * in SGList Slot 0 and the completed list elements 2 to sgNextIndex-1.
- */
- if ( srb->nexus.sgNextIndex != 0 )
- {
- xferOffset += OSSwapHostToLittleInt32( srb->nexus.sgListData[srb->nexus.sgNextIndex-1].length )
- - OSSwapHostToLittleInt32( srb->nexus.sgListData[0].length );
-
- for ( i=2; i < srb->nexus.sgNextIndex-1; i++ )
- {
- xferOffset += OSSwapHostToLittleInt32( srb->nexus.sgListData[i].length ) & 0x00ffffff;
- }
- }
- }
-
- /*
- * The script leaves the result of any Ignore Wide Residual message received from the target
- * during the transfer.
- */
- xferOffset -= srb->nexus.wideResidCount;
-
-
-#if 0
- {
- UInt32 resid = srb->xferOffset - xferOffset;
- if ( resid )
- {
- IOLog( "SCSI(Symbios8xx): Incomplete transfer - Req Count = %08x Act Count = %08x - srb = %08x\n\r",
- srb->xferCount, xferOffset, (UInt32)srb );
- }
- }
-#endif
-
- srb->xferDone = xferOffset;
-}
-
-/*-----------------------------------------------------------------------------*
- * No SRB/Nexus Processing.
- *
- * In some cases (mainly Aborts) not having a SRB/Nexus is normal. In other
- * cases it indicates a problem such a reconnection from a target that we
- * have no record of.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxProcessNoNexus()
-{
- UInt32 dspsReg;
- UInt32 dspReg = 0;
- UInt32 scriptPhase = (UInt32)-1 ;
-
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_select_phase];
-
- dspsReg = Sym8xxReadRegs( chipBaseAddr, DSPS, DSPS_SIZE );
-
- scriptPhase = OSSwapHostToLittleInt32( SCRIPT_VAR(R_ld_phase_flag) );
-
- /*
- * If we were trying to abort or disconnect a target and the bus
- * is now free we consider the abort to have completed.
- */
- if ( sistReg & UDC )
- {
- if ( (scriptPhase == A_kphase_ABORT_MAILBOX) && abortSRB )
- {
- Sym8xxCompleteSRB( abortSRB );
- SCRIPT_VAR(R_ld_AbortBdr_mailbox) = 0;
- }
- else if ( scriptPhase == A_kphase_ABORT_CURRENT )
- {
- abortCurrentSRB = NULL;
- }
- }
- /*
- * If we were trying to connect to a target to send it an abort message, and
- * we timed out, we consider the abort as completed.
- *
- * Note: In this case the target may be hung, but at least its not on the bus.
- */
- else if ( sistReg & STO )
- {
- if ( (scriptPhase == A_kphase_ABORT_MAILBOX) && abortSRB )
- {
- Sym8xxCompleteSRB( abortSRB );
- SCRIPT_VAR(R_ld_AbortBdr_mailbox) = 0;
- }
- }
-
- /*
- * If the script died, without a vaild nexusIndex, we abort anything that is currently
- * connected and hope for the best!
- */
- else if ( dstatReg & IID )
- {
- dspReg = Sym8xxReadRegs( chipBaseAddr, DSP, DSP_SIZE );
- IOLog("SCSI(Symbios8xx): Illegal script instruction - dsp = %08x srb=0\n\r", (int)dspReg );
- Sym8xxAbortCurrent( (SRB *)-1 );
- }
-
- /*
- * Script signaled conditions
- */
- else if ( dstatReg & SIR )
- {
- switch ( dspsReg )
- {
- case A_abort_current:
- abortCurrentSRB = NULL;
- break;
-
- case A_abort_mailbox:
- Sym8xxCompleteSRB( abortSRB );
- SCRIPT_VAR(R_ld_AbortBdr_mailbox) = 0;
- break;
-
- default:
- Sym8xxAbortCurrent( (SRB *)-1 );
- }
- }
- else
- {
- Sym8xxAbortCurrent( (SRB *)-1 );
- }
-
- if ( scriptRestartAddr )
- {
- Sym8xxWriteRegs( chipBaseAddr, DSP, DSP_SIZE, scriptRestartAddr );
- }
-}
-
-
-/*-----------------------------------------------------------------------------*
- * Abort currently connected target.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxAbortCurrent( SRB *srb )
-{
- if ( abortCurrentSRB )
- {
- if ( abortCurrentSRB != srb )
- {
- IOLog("SCSI(Symbios8xx): Multiple abort immediate SRBs - resetting\n\r");
- Sym8xxSCSIBusReset( (SRB *)0 );
- }
- return;
- }
-
- abortCurrentSRB = srb;
-
- if ( srb != (SRB *)-1 )
- {
- if ( srb->srbAdapterStatus == kSCSIAdapterStatusSuccess )
- {
- srb->srbAdapterStatus = kSCSIAdapterStatusProtocolError;
- }
- }
-
- /*
- * Issue abort or abort tag depending on whether the is a tagged request
- */
- SCRIPT_VAR(R_ld_AbortCode) = OSSwapHostToLittleInt32( ((srb != (SRB *)-1) && (srb->nexus.tag >= MIN_SCSI_TAG)) ? 0x0d : 0x06 );
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_issueAbort_BDR];
-
- Sym8xxClearFifo();
-}
-
-/*-----------------------------------------------------------------------------*
- * This routine clears the script engine's SCSI and DMA fifos.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxClearFifo()
-{
- UInt8 ctest3Reg;
- UInt8 stest2Reg;
- UInt8 stest3Reg;
-
- stest2Reg = Sym8xxReadRegs( chipBaseAddr, STEST2, STEST2_SIZE );
- if ( stest2Reg & ROF )
- {
- Sym8xxWriteRegs( chipBaseAddr, STEST2, STEST2_SIZE, stest2Reg );
- }
-
- ctest3Reg = Sym8xxReadRegs( chipBaseAddr, CTEST3, CTEST3_SIZE );
- ctest3Reg |= CLF;
- Sym8xxWriteRegs( chipBaseAddr, CTEST3, CTEST3_SIZE, ctest3Reg );
-
- stest3Reg = Sym8xxReadRegs( chipBaseAddr, STEST3, STEST3_SIZE );
- stest3Reg |= CSF;
- Sym8xxWriteRegs( chipBaseAddr,STEST3, STEST3_SIZE, stest3Reg );
-
- do
- {
- ctest3Reg = Sym8xxReadRegs( chipBaseAddr, CTEST3, CTEST3_SIZE );
- stest2Reg = Sym8xxReadRegs( chipBaseAddr, STEST3, STEST3_SIZE );
- stest3Reg = Sym8xxReadRegs( chipBaseAddr, STEST3, STEST3_SIZE );
- }
- while( (ctest3Reg & CLF) || (stest3Reg & CSF) || (stest2Reg & ROF) );
-}
-
-/*-----------------------------------------------------------------------------*
- * This routine processes the target's response to our SDTR message.
- *
- * We calculate the values for the script engine's timing registers
- * for synchronous registers, and update our tables indicating that
- * requested data transfer mode is in-effect.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxNegotiateSDTR( SRB *srb, Nexus *nexus )
-{
- UInt32 x;
- UInt8 *pMsg;
- UInt32 syncPeriod;
-
- /*
- * If we were not negotiating, the send MsgReject to targets negotiation
- * attempt.
- */
- if ( !(srb->srbCDBFlags & kCDBFlagsNegotiateSDTR) )
- {
- Sym8xxSendMsgReject( srb );
- return;
- }
-
- /*
- * Get pointer to negotiation message received from target.
- */
- pMsg = (UInt8 *) &SCRIPT_VAR(R_ld_message);
-
- /*
- * The target's SDTR response contains the (transfer period / 4).
- *
- * We set our sync clock divisor to 1, 2, or 4 giving us a clock rates
- * of:
- * 80Mhz (Period = 12.5ns),
- * 40Mhz (Period = 25.0ns)
- * 20Mhz (Period = 50.0ns)
- *
- * This is further divided by the value in the sxfer reg to give us the final sync clock rate.
- *
- * The requested sync period is scaled up by 1000 and the clock periods are scaled up by 10
- * giving a result scaled up by 100. This is rounded-up and converted to sxfer reg values.
- */
- if ( pMsg[4] == 0 )
- {
- nexus->targetParms.scntl3Reg &= 0x0f;
- nexus->targetParms.sxferReg = 0x00;
- }
- else
- {
- syncPeriod = (UInt32)pMsg[3] << 2;
- if ( syncPeriod < 100 )
- {
- nexus->targetParms.scntl3Reg |= SCNTL3_INIT_875_ULTRA;
- x = (syncPeriod * 1000) / 125;
- }
- else if ( syncPeriod < 200 )
- {
- nexus->targetParms.scntl3Reg |= SCNTL3_INIT_875_FAST;
- x = (syncPeriod * 1000) / 250;
- }
- else
- {
- nexus->targetParms.scntl3Reg |= SCNTL3_INIT_875_SLOW;
- x = (syncPeriod * 1000) / 500;
- }
-
- if ( x % 100 ) x += 100;
-
- /*
- * sxferReg Bits: 5-0 - Transfer offset
- * 7-6 - Sync Clock Divisor (0 = sync clock / 4)
- */
- nexus->targetParms.sxferReg = ((x/100 - 4) << 5) | pMsg[4];
-
- transferPeriod = syncPeriod * 1000;
- transferOffset = pMsg[4];
-
- srb->negotiateSDTRComplete = true;
- }
-
- /*
- * Update our per-target tables and set-up the hardware regs for this request.
- *
- * On reconnection attempts, the script will use our per-target tables to set-up
- * the scntl3 and sxfer registers in the script engine.
- */
- adapter->targetClocks[srb->target].sxferReg = nexus->targetParms.sxferReg;
- adapter->targetClocks[srb->target].scntl3Reg = nexus->targetParms.scntl3Reg;
-
- Sym8xxWriteRegs( chipBaseAddr, SCNTL3, SCNTL3_SIZE, nexus->targetParms.scntl3Reg );
- Sym8xxWriteRegs( chipBaseAddr, SXFER, SXFER_SIZE, nexus->targetParms.sxferReg );
-
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_clearACK];
-}
-
-/*-----------------------------------------------------------------------------*
- * This routine processes the target's response to our WDTR message.
- *
- * In addition, if there is a pending SDTR message, this routine sends it
- * to the target.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxNegotiateWDTR( SRB *srb, Nexus *nexus )
-{
- UInt8 *pMsg;
- UInt32 msgBytesSent;
- UInt32 msgBytesLeft;
-
- /*
- * If we were not negotiating, the send MsgReject to targets negotiation
- * attempt.
- */
- if ( !(srb->srbCDBFlags & kCDBFlagsNegotiateWDTR) )
- {
- Sym8xxSendMsgReject( srb );
- return;
- }
-
- /*
- * Set Wide (16-bit) vs Narrow (8-bit) data transfer mode based on target's response.
- */
- pMsg = (UInt8 *) &SCRIPT_VAR(R_ld_message);
-
- if ( pMsg[3] == 1 )
- {
- nexus->targetParms.scntl3Reg |= EWS;
- transferWidth = 2;
- }
- else
- {
- nexus->targetParms.scntl3Reg &= ~EWS;
- transferWidth = 1;
- }
-
- /*
- * Update our per-target tables and set-up the hardware regs for this request.
- *
- * On reconnection attempts, the script will use our per-target tables to set-up
- * the scntl3 and sxfer registers in the script engine.
- */
-
- adapter->targetClocks[srb->target].scntl3Reg = nexus->targetParms.scntl3Reg;
- Sym8xxWriteRegs( chipBaseAddr, SCNTL3, SCNTL3_SIZE, nexus->targetParms.scntl3Reg );
-
- srb->negotiateWDTRComplete = true;
-
- /*
- * If there any pending messages left for the target, send them now,
- */
- msgBytesSent = OSSwapHostToLittleInt32( nexus->msg.length );
- msgBytesLeft = srb->srbMsgLength - msgBytesSent;
- if ( msgBytesLeft )
- {
- nexus->msg.length = OSSwapHostToLittleInt32( msgBytesLeft );
- nexus->msg.ppData = OSSwapHostToLittleInt32( OSSwapHostToLittleInt32( nexus->msg.ppData ) + msgBytesSent );
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_issueMessageOut];
- }
-
- /*
- * Otherwise, tell the script we're done with MsgOut phase.
- */
- else
- {
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_clearACK];
- }
-}
-
-/*-----------------------------------------------------------------------------*
- * Reject message received from target.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxSendMsgReject( SRB *srb )
-{
- srb->nexus.msg.ppData = OSSwapHostToLittleInt32((UInt32)&srb->srbPhys->nexus.msgData);
- srb->nexus.msg.length = OSSwapHostToLittleInt32(0x01);
- srb->nexus.msgData[0] = 0x07;
-
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_issueMessageOut];
-}
-
-
-/*-----------------------------------------------------------------------------*
- * This routine initiates a SCSI Bus Reset.
- *
- * This may be an internally generated request as part of error recovery or
- * a client's bus reset request.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxSCSIBusReset( SRB *srb )
-{
- if ( srb )
- {
- if ( resetSRB )
- {
- srb->srbReturnCode = kIOReturnBusy;
- Sym8xxCompleteSRB( srb );
- return;
- }
- resetSRB = srb;
- }
-
- Sym8xxAbortScript();
-
- Sym8xxWriteRegs( chipBaseAddr, SCNTL1, SCNTL1_SIZE, SCNTL1_SCSI_RST );
- IODelay( 100 );
- Sym8xxWriteRegs( chipBaseAddr, SCNTL1, SCNTL1_SIZE, SCNTL1_INIT );
-}
-
-/*-----------------------------------------------------------------------------*
- * This routine handles a SCSI Bus Reset interrupt.
- *
- * The SCSI Bus reset may be generated by a target on the bus, internally from
- * the driver's error recovery or from a client request.
- *
- * Once the reset is detected we establish a settle period where new client requests
- * are blocked in the client thread. In addition we flush all currently executing
- * scsi requests back to the client.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxProcessSCSIBusReset()
-{
- UInt32 i;
-
- Sym8xxClearFifo();
-
- /*
- * We clear the script's request mailboxes. Any work in the script mailboxes is
- * already in the NexusPtr tables so we have already have handled the SRB/Nexus
- * cleanup.
- */
- for ( i=0; i < MAX_SCHED_MAILBOXES; i++ )
- {
- adapter->schedMailBox[i] = 0;
- }
-
- SCRIPT_VAR(R_ld_AbortBdr_mailbox) = 0;
- SCRIPT_VAR(R_ld_IOdone_mailbox) = 0;
- SCRIPT_VAR(R_ld_counter) = 0;
- mailBoxIndex = 0;
-
-
- /*
- * Reset the data transfer mode/clocks in our per-target tables back to Async/Narrow 8-bit
- */
- for ( i=0; i < MAX_SCSI_TARGETS; i++ )
- {
- adapter->targetClocks[i].scntl3Reg = SCNTL3_INIT_875;
- adapter->targetClocks[i].sxferReg = 0;
- }
-
- scriptRestartAddr = (UInt32) &chipRamAddrPhys[Ent_select_phase];
- Sym8xxWriteRegs( chipBaseAddr, DSP, DSP_SIZE, scriptRestartAddr );
-
- if ( resetSRB )
- {
- resetSRB->srbReturnCode = kIOReturnBusy;
- Sym8xxCompleteSRB( resetSRB );
- resetSRB = 0;
- }
- else if ( initialReset == true )
- {
- initialReset = false;
- }
- else
- {
- resetOccurred();
- }
-}
-
-/*-----------------------------------------------------------------------------*
- * This routine sets the SIGP bit in the script engine's ISTAT
- * register. This signals the script to wake-up for a WAIT for
- * reselection instruction. The script will then check the mailboxes
- * for work to do.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxSignalScript( SRB *srb )
-{
- Sym8xxWriteRegs( chipBaseAddr, ISTAT, ISTAT_SIZE, SIGP );
-}
-
-/*-----------------------------------------------------------------------------*
- *
- *
- *
- *
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxCheckRequestSense( SRB *srb )
-{
- IOSCSIParallelCommand *scsiCommand;
- IOMemoryDescriptor *reqSenseDesc;
-
- scsiCommand = srb->scsiCommand;
-
- scsiCommand->getPointers( &reqSenseDesc, 0, 0, true );
-
- if ( reqSenseDesc != 0 )
- {
- Sym8xxCancelMailBox( srb->target, srb->lun, true );
- }
-}
-
-/*-----------------------------------------------------------------------------*
- * This routine does a mailbox abort.
- *
- * This type of abort is used for targets not currently connected to the SCSI Bus.
- *
- * The script will select the target and send a tag (if required) followed by the
- * appropriate abort message (abort/abort-tag)
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxAbortBdr( SRB *srb )
-{
- IOAbortBdrMailBox abortMailBox;
-
- abortSRB = srb;
-
- /*
- * Setup a script variable containing the abort information.
- */
- abortMailBox.identify = srb->nexus.msgData[0];
- abortMailBox.tag = srb->nexus.msgData[1];
- abortMailBox.message = srb->nexus.msgData[2];
- abortMailBox.scsi_id = srb->target;
-
- SCRIPT_VAR(R_ld_AbortBdr_mailbox) = *(UInt32 *) &abortMailBox;
-
- Sym8xxSignalScript( srb );
-}
-
-/*-----------------------------------------------------------------------------*
- *
- *
- *
- *
- *-----------------------------------------------------------------------------*/
-bool Sym8xxSCSIController::Sym8xxCancelMailBox( Nexus *nexusCancel )
-{
- Nexus *nexusPhys;
- UInt32 i;
-
- nexusPhys = (Nexus *)OSSwapHostToLittleInt32( (UInt32)nexusCancel );
- for ( i=0; i < MAX_SCHED_MAILBOXES; i++ )
- {
- if ( nexusPhys == adapter->schedMailBox[i] )
- {
- adapter->schedMailBox[i] = (Nexus *)OSSwapHostToLittleInt32( kMailBoxCancel );
- return true;
- }
- }
- return false;
-}
-
-
-/*-----------------------------------------------------------------------------*
- *
- *
- *
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxCancelMailBox( UInt32 target, UInt32 lun, bool fReschedule )
-{
- UInt32 tag;
- UInt32 tagPos;
- UInt32 tagShift;
-
- UInt32 i;
-
- SRB *srb;
- Nexus *nexus;
- Nexus *nexusPhys;
-
- tagPos = offsetof(Nexus, tag) & 0x03;
- tagShift = 24 - (tagPos << 3);
-
- for ( i=0; i < MAX_SCHED_MAILBOXES; i++ )
- {
- nexusPhys = (Nexus *)OSSwapHostToLittleInt32( (UInt32)adapter->schedMailBox[i] );
- if ( (nexusPhys != (Nexus *)kMailBoxEmpty) && (nexusPhys != (Nexus *)kMailBoxCancel) )
- {
- /*
- * Read the 'tag' byte given Nexus physical address from the mailBox.
- * Look-up the virtual address of the corresponding Nexus struct.
- */
- tag = ml_phys_read((UInt32)&nexusPhys->tag - tagPos);
- tag = (tag >> tagShift) & 0xff;
-
- nexus = adapter->nexusPtrsVirt[tag];
- if ( nexus == (Nexus *)-1 )
- {
- continue;
- }
-
- /*
- * If the SCSI target of the mailbox entry matches the abort SRB target,
- * then we may have a winner.
- */
- srb = (SRB *)((UInt32)nexus - offsetof(SRB, nexus));
-
- if ( srb->target == target )
- {
- /*
- * For a device reset, we cancel all requests for that target regardless of lun.
- * For an abort all, we must match on both target and lun
- */
- if ( (lun == (UInt32)-1) || (srb->lun == lun) )
- {
- adapter->schedMailBox[i] = (Nexus *)OSSwapHostToLittleInt32( kMailBoxCancel );
-
- if ( fReschedule == true )
- {
- rescheduleCommand( srb->scsiCommand );
- }
- }
- }
- }
- }
-}
-
-/*-----------------------------------------------------------------------------*
- * This routine is used to shutdown the script engine in an orderly fashion.
- *
- * Normally the script engine automatically stops when an interrupt is generated. However,
- * in the case of timeouts we need to change the script engine's dsp reg (instruction pointer).
- * to issue an abort.
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxAbortScript()
-{
- mach_timespec_t currentTime;
- mach_timespec_t startTime;
-
- getWorkLoop()->disableAllInterrupts();
-
- /*
- * We set the ABRT bit in ISTAT and spin until the script engine acknowledges the
- * abort or we timeout.
- */
- Sym8xxWriteRegs( chipBaseAddr, ISTAT, ISTAT_SIZE, ABRT );
-
- IOGetTime( &startTime );
-
- do
- {
- IOGetTime( ¤tTime );
- SUB_MACH_TIMESPEC( ¤tTime, &startTime );
-
- istatReg = Sym8xxReadRegs( chipBaseAddr, ISTAT, ISTAT_SIZE );
-
- if ( istatReg & SIP )
- {
- Sym8xxReadRegs( chipBaseAddr, SIST, SIST_SIZE );
- continue;
- }
-
- if ( istatReg & DIP )
- {
- Sym8xxWriteRegs( chipBaseAddr, ISTAT, ISTAT_SIZE, 0x00 );
- Sym8xxReadRegs( chipBaseAddr, DSTAT, DSTAT_SIZE );
- break;
- }
- }
- while ( currentTime.tv_nsec < (kAbortScriptTimeoutMS * 1000 * 1000) );
-
- istatReg = SIGP;
- Sym8xxWriteRegs( chipBaseAddr, ISTAT, ISTAT_SIZE, istatReg );
-
- getWorkLoop()->enableAllInterrupts();
-
- if ( currentTime.tv_nsec >= (kAbortScriptTimeoutMS * 1000 * 1000) )
- {
- IOLog( "SCSI(Symbios8xx): Abort script failed - resetting bus\n\r" );
- }
-
- }
-
-
+++ /dev/null
-/*
- * Copyright (c) 1999 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@
- */
-
-/* Sym8xxInit.m created by russb2 on Sat 30-May-1998 */
-
-/*-----------------------------------------------------------------------------*
- * This module contains initialization routines for the driver.
- *
- * Driver initialization consists of:
- *
- * - Doing PCI bus initialization for the script engine PCI device.
- * - Setting up shared communication areas in system memory between the script
- * and the driver.
- * - Copying the script program into the script engine on-board ram, applying
- * script relocation fixups as required.
- * - Setting the initial register values for the script engine.
- * - Setting up driver related storage and interfacing with driverKit.
- *
- *-----------------------------------------------------------------------------*/
-
-/*
- * This define causes Sym8xxScript.h to include the script instructions and
- * relocation tables. Normally without this define we only will get #define
- * values for interfacing with the script.
- */
-#define INCL_SCRIPT_TEXT
-
-#include "Sym8xxController.h"
-
-#define super IOSCSIParallelController
-
-OSDefineMetaClassAndStructors( Sym8xxSCSIController, IOSCSIParallelController ) ;
-
-/*-----------------------------------------------------------------------------*
- * This structure contains most of the inital register settings for
- * the script engine. See Sym8xxRegs.h for the actual initialization
- * values.
- *
- *-----------------------------------------------------------------------------*/
-typedef struct ChipInitRegs
-{
- UInt32 regNum;
- UInt32 regSize;
- UInt32 regValue;
-
-} ChipInitRegs;
-
-static ChipInitRegs Sym8xxInitRegs[] =
-{
- { SCNTL0, SCNTL0_SIZE, SCNTL0_INIT },
- { SCNTL1, SCNTL1_SIZE, SCNTL1_INIT },
- { SCNTL2, SCNTL2_SIZE, SCNTL2_INIT },
- { SCNTL3, SCNTL3_SIZE, SCNTL3_INIT_875 },
- { SXFER, SXFER_SIZE, SXFER_INIT },
- { SDID, SDID_SIZE, SDID_INIT },
- { GPREG, GPREG_SIZE, GPREG_INIT },
- { SFBR, SFBR_SIZE, SFBR_INIT },
- { SOCL, SOCL_SIZE, SOCL_INIT },
- { DSA, DSA_SIZE, DSA_INIT },
- { ISTAT, ISTAT_SIZE, ISTAT_INIT },
- { TEMP, TEMP_SIZE, TEMP_INIT },
- { CTEST0, CTEST0_SIZE, CTEST0_INIT },
- { CTEST3, CTEST3_SIZE, CTEST3_INIT_A },
- { CTEST4, CTEST4_SIZE, CTEST4_INIT },
- { CTEST5, CTEST5_SIZE, CTEST5_INIT_A_revB},
- { DBC, DBC_SIZE, DBC_INIT },
- { DCMD, DCMD_SIZE, DCMD_INIT },
- { DNAD, DNAD_SIZE, DNAD_INIT },
- { DSPS, DSPS_SIZE, DSPS_INIT },
- { SCRATCHA, SCRATCHA_SIZE, SCRATCHA_INIT },
- { DMODE, DMODE_SIZE, DMODE_INIT_A },
- { DIEN, DIEN_SIZE, DIEN_INIT },
- { DWT, DWT_SIZE, DWT_INIT },
- { DCNTL, DCNTL_SIZE, DCNTL_INIT_A },
- { SIEN, SIEN_SIZE, SIEN_INIT },
- { SLPAR, SLPAR_SIZE, SLPAR_INIT },
- { MACNTL, MACNTL_SIZE, MACNTL_INIT },
- { GPCNTL, GPCNTL_SIZE, GPCNTL_INIT },
- { STIME0, STIME0_SIZE, STIME0_INIT },
- { STIME1, STIME1_SIZE, STIME1_INIT },
- { RESPID0, RESPID0_SIZE, RESPID0_INIT },
- { RESPID1, RESPID1_SIZE, RESPID1_INIT },
- { STEST2, STEST2_SIZE, STEST2_INIT },
- { STEST3, STEST3_SIZE, STEST3_INIT },
- { SODL, SODL_SIZE, SODL_INIT },
- { SCRATCHB, SCRATCHB_SIZE, SCRATCHB_INIT }
-};
-
-/*-----------------------------------------------------------------------------*
- *
- *
- *-----------------------------------------------------------------------------*/
-bool Sym8xxSCSIController::configure( IOService *forProvider, SCSIControllerInfo *controllerInfo )
-{
- provider = (IOPCIDevice *)forProvider;
-
- if ( Sym8xxInit() == false )
- {
- return false;
- }
-
- initialReset = true;
-
- Sym8xxSCSIBusReset( 0 );
- IOSleep(3000);
-
- controllerInfo->initiatorId = 7;
-
- controllerInfo->maxTargetsSupported = 16;
- controllerInfo->maxLunsSupported = 8;
-
- controllerInfo->minTransferPeriodpS = (chipId == kChipIdSym875) ? 50000 : 0;
- controllerInfo->maxTransferOffset = (chipId == kChipIdSym875) ? 16 : 0;
- controllerInfo->maxTransferWidth = 2;
-
- controllerInfo->maxCommandsPerController = 0;
- controllerInfo->maxCommandsPerTarget = 0;
- controllerInfo->maxCommandsPerLun = 0;
-
- controllerInfo->tagAllocationMethod = kTagAllocationPerController;
- controllerInfo->maxTags = 128;
-
- controllerInfo->commandPrivateDataSize = sizeof( SRB );
- controllerInfo->targetPrivateDataSize = 0;
- controllerInfo->lunPrivateDataSize = 0;
-
- controllerInfo->disableCancelCommands = false;
-
- return true;
-}
-
-
-/*-----------------------------------------------------------------------------*
- * Script Initialization
- *
- *-----------------------------------------------------------------------------*/
-bool Sym8xxSCSIController::Sym8xxInit()
-{
- /*
- * Perform PCI related initialization
- */
- if ( Sym8xxInitPCI() == false )
- {
- return false;
- }
-
- /*
- * Allocate/initialize driver resources
- */
- if ( Sym8xxInitVars() == false )
- {
- return false;
- }
-
- /*
- * Initialize the script engine registers
- */
- if ( Sym8xxInitChip() == false )
- {
- return false;
- }
-
- /*
- * Apply fixups to script and copy script to script engine's on-board ram
- */
- if ( Sym8xxInitScript() == false )
- {
- return false;
- }
-
- getWorkLoop()->enableAllInterrupts();
-
- /*
- * Start script execution
- */
- Sym8xxWriteRegs( chipBaseAddr, DSP, DSP_SIZE, (UInt32) &chipRamAddrPhys[Ent_select_phase] );
-
- return true;
-}
-
-/*-----------------------------------------------------------------------------*
- * Script engine PCI initialization
- *
- * This routine determines the chip version/revision, enables the chip address
- * ranges and allocates a virtual mapping to the script engine's registers and
- * on-board ram.
- *-----------------------------------------------------------------------------*/
-bool Sym8xxSCSIController::Sym8xxInitPCI()
-{
- unsigned long pciReg0, pciReg8;
- UInt32 chipRev;
- UInt32 n;
- UInt32 ramReg;
- OSString *matchEntry;
-
-
- /*
- * Determine the number of memory ranges for the PCI device.
- *
- * The hardware implementation may or may not have a ROM present
- * accounting for the difference in the number of ranges.
- */
- n = provider->getDeviceMemoryCount();
- if ( !( n == 3 || n == 4 ) )
- {
- return false;
- }
-
- /*
- * Determine the hardware version. Check the deviceID and
- * RevID in the PCI config regs.
- */
- pciReg0 = provider->configRead32( 0x00 );
- pciReg8 = provider->configRead32( 0x08 );
-
- chipId = pciReg0 >> 16;
- chipRev = pciReg8 & 0xff;
-
-// IOLog( "SCSI(Symbios8xx): Chip Id = %04x Chip rev = %02x\n\r", chipId, chipRev );
-
-
- ioMapRegs = provider->mapDeviceMemoryWithRegister( 0x14 );
- if ( ioMapRegs == 0 )
- {
- return false;
- }
-
- switch ( chipId )
- {
- case kChipIdSym875:
- ramReg = 0x18;
- break;
-
- case kChipIdSym895:
- case kChipIdSym896:
- case kChipIdSym1010:
- ramReg = 0x1C;
- break;
-
- default:
- ramReg = 0x1C;
- }
-
- ioMapRam = provider->mapDeviceMemoryWithRegister( ramReg );
- if ( ioMapRam == 0 )
- {
- return false;
- }
-
- /*
- * Assume 80Mhz external clock rate for motherboard 875 implementations
- * and 40Mhz for others.
- */
- matchEntry = OSDynamicCast( OSString, getProperty( gIONameMatchedKey ) );
- if ( matchEntry == 0 )
- {
- IOLog("SCSI(Sym8xx): Cannot obtain matching property.\n");
- return false;
- }
-
- if ( matchEntry->isEqualTo( "apple53C8xx" ) == true )
- {
- chipClockRate = CLK_80MHz;
- }
- else
- {
- chipClockRate = CLK_40MHz;
- }
-
- /*
- * BUS MASTER, MEM I/O Space, MEM WR & INV
- */
- provider->configWrite32( 0x04, 0x16 );
-
- /*
- * set Latency to Max , cache 32
- */
- provider->configWrite32( 0x0C, 0x2008 );
-
- /*
- * get chip register block mapped into pci memory
- */
- chipBaseAddr = (UInt8 *)ioMapRegs->getVirtualAddress();
- chipBaseAddrPhys = (UInt8 *)ioMapRegs->getPhysicalAddress();
-
-// kprintf( "SCSI(Symbios8xx): Chip Base addr = %08x(p) %08x(v)\n\r",
-// (UInt32)chipBaseAddrPhys, (UInt32)chipBaseAddr );
-
- chipRamAddr = (UInt8 *)ioMapRam->getVirtualAddress();
- chipRamAddrPhys = (UInt8 *)ioMapRam->getPhysicalAddress();
-
-// kprintf( "SCSI(Symbios8xx): Chip Ram addr = %08x(p) %08x(v)\n\r",
-// (UInt32)chipRamAddrPhys, (UInt32)chipRamAddr );
-
- /*
- * Attach interrupt
- */
- interruptEvent = IOInterruptEventSource::interruptEventSource(
- (OSObject *) this,
- (IOInterruptEventAction) &Sym8xxSCSIController::interruptOccurred,
- (IOService *) provider,
- (int) 0 );
-
- if ( interruptEvent == NULL )
- {
- return false;
- }
-
- getWorkLoop()->addEventSource( interruptEvent );
-
- interruptEvent->enable();
-
- /*
- *
- */
- memoryCursor = IOBigMemoryCursor::withSpecification( 16*1024*1024, 0xffffffff );
- if ( memoryCursor == NULL )
- {
- return false;
- }
-
-
-
- return true;
-}
-
-/*-----------------------------------------------------------------------------*
- * This routine allocates/initializes shared memory for communication between
- * the script and the driver. In addition other driver resources semaphores,
- * queues are initialized here.
- *
- *-----------------------------------------------------------------------------*/
-bool Sym8xxSCSIController::Sym8xxInitVars()
-{
- UInt32 i;
-
- adapter = (AdapterInterface *)IOMallocContiguous( page_size, page_size, (IOPhysicalAddress *)&adapterPhys );
- if ( adapter == 0 )
- {
- return false;
- }
- bzero( adapter, page_size );
-
- /*
- * We keep two copies of the Nexus pointer array. One contains physical addresses and
- * is located in the script/driver shared storage. The other copy holds the corresponding
- * virtual addresses to the active Nexus structures and is located in the drivers instance
- * data.
- * Both tables can be accessed through indirect pointers in the script/driver communication
- * area. This is the preferred method to access these arrays.
- */
- adapter->nexusPtrsVirt = (Nexus **)nexusArrayVirt;
- adapter->nexusPtrsPhys = (Nexus **)adapter->nexusArrayPhys;
-
- for (i=0; i < MAX_SCSI_TAG; i ++ )
- {
- adapter->nexusPtrsVirt[i] = (Nexus *) -1;
- adapter->nexusPtrsPhys[i] = (Nexus *) -1;
- }
-
- /*
- * The script/driver communication area also contains a 16-entry table clock
- * settings for each target.
- */
- for (i=0; i < MAX_SCSI_TARGETS; i++ )
- {
- adapter->targetClocks[i].scntl3Reg = SCNTL3_INIT_875;
- }
-
-
- return true;
-}
-
-
-/*-----------------------------------------------------------------------------*
- * This routine makes a temporary copy of the script program, applies script fixups,
- * initializes the script local data table at the top of the script image, and
- * copies the modified script image to the script engine's on-board ram.
- *
- *-----------------------------------------------------------------------------*/
-bool Sym8xxSCSIController::Sym8xxInitScript()
-{
- UInt32 i;
- UInt32 scriptPgm[sizeof(BSC_SCRIPT)/sizeof(UInt32)];
-
- /*
- * Make a copy of the script
- */
- bcopy( BSC_SCRIPT, scriptPgm, sizeof(scriptPgm) );
- bzero( scriptPgm, R_ld_size );
-
- /*
- * Apply fixups to the script copy
- */
- for ( i=0; i < sizeof(Rel_Patches)/sizeof(UInt32); i++ )
- {
- scriptPgm[Rel_Patches[i]] += (UInt32)chipRamAddrPhys;
- }
- for ( i=0; i < sizeof(LABELPATCHES)/sizeof(UInt32); i++ )
- {
- scriptPgm[LABELPATCHES[i]] += (UInt32)chipRamAddrPhys;
- }
-
- /*
- * Initialize the script working variables with pointers to the script/driver
- * communications area.
- */
- scriptPgm[R_ld_sched_mlbx_base_adr >> 2] = (UInt32)&adapterPhys->schedMailBox;
- scriptPgm[R_ld_nexus_array_base >> 2] = (UInt32)&adapterPhys->nexusArrayPhys;
- scriptPgm[R_ld_device_table_base_adr >> 2] = (UInt32)&adapterPhys->targetClocks;
-
- /*
- * Load the script image into the script engine's on-board ram.
- */
- Sym8xxLoadScript( (UInt32 *)scriptPgm, sizeof(scriptPgm)/sizeof(UInt32) );
-
- return true;
-}
-
-
-/*-----------------------------------------------------------------------------*
- * This routine transfers the script program image into the script engine's
- * on-board ram
- *
- *-----------------------------------------------------------------------------*/
-void Sym8xxSCSIController::Sym8xxLoadScript( UInt32 *scriptPgm, UInt32 scriptWords )
-{
- UInt32 i;
- volatile UInt32 *ramPtr = (volatile UInt32 *)chipRamAddr;
-
- for ( i = 0; i < scriptWords; i++ )
- {
- ramPtr[i] = OSSwapHostToLittleInt32(scriptPgm[i]);
- }
-}
-
-/*-----------------------------------------------------------------------------*
- * This routine initializes the script engine's register block.
- *
- *-----------------------------------------------------------------------------*/
-bool Sym8xxSCSIController::Sym8xxInitChip()
-{
- UInt32 i;
-
- /*
- * Reset the script engine
- */
- Sym8xxWriteRegs( chipBaseAddr, ISTAT, ISTAT_SIZE, RST );
- IODelay( 25 );
- Sym8xxWriteRegs( chipBaseAddr, ISTAT, ISTAT_SIZE, ISTAT_INIT );
-
- /*
- * Load our canned register values into the script engine
- */
- for ( i = 0; i < sizeof(Sym8xxInitRegs)/sizeof(ChipInitRegs); i++ )
- {
- Sym8xxWriteRegs( chipBaseAddr, Sym8xxInitRegs[i].regNum, Sym8xxInitRegs[i].regSize, Sym8xxInitRegs[i].regValue );
- IODelay( 10 );
- }
-
- /*
- * For hardware implementations that have a 40Mhz SCLK input, we enable the chip's on-board
- * clock doubler to bring the clock rate upto 80Mhz which is required for Ultra-SCSI timings.
- */
- if ( chipClockRate == CLK_40MHz )
- {
- /*
- * Clock doubler setup for 875 (rev 3 and above).
- */
- /* set clock doubler enabler bit */
- Sym8xxWriteRegs( chipBaseAddr, STEST1, STEST1_SIZE, STEST1_INIT | DBLEN);
- IODelay(30);
- /* halt scsi clock */
- Sym8xxWriteRegs( chipBaseAddr, STEST3, STEST3_SIZE, STEST3_INIT | HSC );
- IODelay(10);
- Sym8xxWriteRegs( chipBaseAddr, SCNTL3, SCNTL3_SIZE, SCNTL3_INIT_875);
- IODelay(10);
- /* set clock doubler select bit */
- Sym8xxWriteRegs( chipBaseAddr, STEST1, STEST1_SIZE, STEST1_INIT | DBLEN | DBLSEL);
- IODelay(10);
- /* clear hold on scsi clock */
- Sym8xxWriteRegs( chipBaseAddr, STEST3, STEST3_SIZE, STEST3_INIT);
- }
-
- /*
- * Set our host-adapter ID in the script engine's registers
- */
- initiatorID = kHostAdapterSCSIId;
-
- if ( initiatorID > 7 )
- {
- Sym8xxWriteRegs( chipBaseAddr, RESPID1, RESPID1_SIZE, 1 << (initiatorID-8));
- }
- else
- {
- Sym8xxWriteRegs( chipBaseAddr, RESPID0, RESPID0_SIZE, 1 << initiatorID);
- }
-
- Sym8xxWriteRegs( chipBaseAddr, SCID, SCID_SIZE, SCID_INIT | initiatorID );
-
- return true;
-}
-
-
+++ /dev/null
-/*
- * Copyright (c) 1999 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@
- */
-
-/* Sym8xxInterface.h created by russb2 on Sat 30-May-1998 */
-
-/*
- * This file contains shared data structures between the script and the driver
- *
- */
-
-#define MAX_SCSI_TARGETS 16
-#define MAX_SCSI_LUNS 8
-#define MAX_SCSI_TAG 256
-#define MIN_SCSI_TAG 128
-
-#define kHostAdapterSCSIId 7
-
-#define MAX_SCHED_MAILBOXES 256
-#define kMailBoxEmpty 0
-#define kMailBoxCancel 1
-
-#define kSCSITimerIntervalMS 250
-#define kReqSenseTimeoutMS 3000
-#define kAbortTimeoutMS 3000
-#define kResetQuiesceDelayMS 3000
-#define kAbortScriptTimeoutMS 50
-
-/*
- * NEXUS DATA Structure
- *
- * The Nexus structure contains per-request information for the script/driver
- * to execute a SCSI request.
- */
-
-typedef struct SGEntry
-{
- UInt32 length;
- UInt32 physAddr;
-} SGEntry;
-
-/*
- * Note: There are (3) SG List entries reserved for use by the driver,
- * i.e SG Entries 0-1 and the last entry in the list.
- */
-#define MAX_SGLIST_ENTRIES (64+3)
-
-/*
- * This part of the Nexus structure contains the script engine clock registers to
- * be used for this request. This information is also contained in the per-target
- * table (AdapterInterface->targetClocks).
- */
-typedef struct NexusParms
-{
- UInt8 reserved_1;
- UInt8 sxferReg;
- UInt8 target;
- UInt8 scntl3Reg;
-} NexusParms;
-
-/*
- * Pointers in the Nexus to our CDB/MsgOut data are in this format.
- */
-typedef struct NexusData
-{
- UInt32 length;
- UInt32 ppData;
-} NexusData;
-
-typedef struct Nexus Nexus;
-struct Nexus
-{
- NexusParms targetParms;
-
- SGEntry *ppSGList;
-
- NexusData msg;
- NexusData cdb;
-
- UInt32 currentDataPtr;
- UInt32 savedDataPtr;
-
- UInt8 tag;
- UInt8 dataXferCalled;
- UInt8 wideResidCount;
- UInt8 reserved_1[1];
-
- /*
- * Data buffers for nexus
- */
- UInt8 cdbData[16];
- UInt8 msgData[16];
- UInt32 sgNextIndex;
- SGEntry sgListData[MAX_SGLIST_ENTRIES];
-
-};
-
-/*
- * Abort Bdr Mailbox
- *
- * The mailbox is used to send an Abort or Bus Device Reset to a device
- * This mailbox is 4 bytes long, and all the necessary information are
- * contained in this mailbox (No nexus Data associated)
- */
-typedef struct IOAbortBdrMailBox
-{
- UInt8 identify; /* Identify msg (0xC0) if Abort A0 */
- UInt8 tag; /* Tag Message or Zero A1 */
- UInt8 scsi_id; /* SCSI id of the target of the request A2 */
- UInt8 message; /* Abort(0x06) or Bdr(0x0C) or AbortTag (0x0D) A3 */
-} IOAbortBdrMailBox;
-
-/*
- * IODone mailbox
- *
- * This mailbox is used to signal the completion of an I/O to the driver.
- */
-
-typedef struct IODoneMailBox
-{
- UInt8 nexus; /* Nexus of the completed I/O */
- UInt8 status; /* Status of the completed I/O */
- UInt8 zero;
- UInt8 semaphore; /* If set, these contents are valid */
-} IODoneMailBox;
-
-/*
- * Adapter Interface
- *
- * This structure contains the shared data between the script and
- * the driver. The script's local variable table is updated to point to the
- * physical addresses of the data in this control block.
- */
-
-typedef struct TargetClocks
-{
- UInt8 reserved_1;
- UInt8 sxferReg;
- UInt8 reserved_2;
- UInt8 scntl3Reg;
-} TargetClocks;
-
-typedef struct AdapterInterface
-{
- Nexus **nexusPtrsVirt;
- Nexus **nexusPtrsPhys;
-
- Nexus *nexusArrayPhys[MAX_SCSI_TAG]; /* Active SRBs or -1 */
- Nexus *schedMailBox[MAX_SCHED_MAILBOXES]; /* New SRBs */
- TargetClocks targetClocks[MAX_SCSI_TARGETS];
-
- UInt32 xferSWideInst[4];
-
-} AdapterInterface;
-
-#define SCRIPT_VAR(x) ( *(UInt32 *)(chipRamAddr+(x)) )
+++ /dev/null
-/*
- * Copyright (c) 1999 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@
- */
-
-/* Sym8xxMisc.m created by russb2 on Sat 30-May-1998 */
-
-#include "Sym8xxController.h"
-
-/*
- * Miscellaneous IO worker routines
- */
-
-UInt32 Sym8xxSCSIController::Sym8xxReadRegs( volatile UInt8 *chipRegs, UInt32 regOffset, UInt32 regSize )
-{
- if ( regSize == 1 )
- {
- return chipRegs[regOffset];
- }
- if ( regSize == 2 )
- {
- return OSSwapHostToLittleInt16( *(volatile u_int16_t *)&chipRegs[regOffset] );
- }
- else if (regSize == 4 )
- {
- return OSSwapHostToLittleInt32( *(volatile UInt32 *)&chipRegs[regOffset] );
- }
- else
- {
- kprintf("SCSI(SymBios875): Sym8xxReadRegs incorrect regSize\n\r" );
- return 0;
- }
-}
-
-void Sym8xxSCSIController::Sym8xxWriteRegs( volatile UInt8 *chipRegs, UInt32 regOffset, UInt32 regSize, UInt32 regValue )
-{
- if ( regSize == 1 )
- {
- chipRegs[regOffset] = regValue;
- }
- else if ( regSize == 2 )
- {
- volatile u_int16_t *p = (volatile u_int16_t *)&chipRegs[regOffset];
- *p = OSSwapHostToLittleInt16( regValue );
- }
- else if ( regSize == 4 )
- {
- volatile UInt32 *p = (volatile UInt32 *)&chipRegs[regOffset];
- *p = OSSwapHostToLittleInt32( regValue );
- }
- else
- {
- kprintf("SCSI(SymBios875): Sym8xxWriteRegs incorrect regSize\n\r" );
- }
- eieio();
-}
+++ /dev/null
-/*
- * Copyright (c) 1999 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 (c) 1998 Apple Computer Inc.
- *
- * Symbios8xx Controller.
- *
- */
-
-/* SymBios 8xx register addressing definitions */
-
-#define SCNTL0_SIZE 0x01
-#define SCNTL0 0x00000000
-#define SCNTL0_INIT 0xCA /* Scsi control 0 */
- /* ARB1 1 */
- /* ARB0 1 : Full arbitration */
- /* START 0 : Start sequence */
- /* WATN 0 : Select with ATN */
- /* EPC 1 : enable SCSI bus parity checking */
- /* RES */
- /* AAP 1 : Assert ATN on SCSI parity error */
- /* TRG 0 : Target mode. 720 is Initiator */
-
-#define SCNTL1_SIZE 0x01
-#define SCNTL1 0x00000001
-#define SCNTL1_INIT 0x00 /* Scsi control 1 */
- /* EXC 0 : Extra clock cycle data setup (Sdtr) */
- /* ADB 0 : Assert SCSI data bus */
- /* DHP 0 : Target only Disable halt parity error */
- /* CON 0 : 820 connected to SCSI bus */
- /* RST 0 : Assert SCSI RST signal */
- /* AESP 0 : Force bad parity */
- /* IARB 0 : Immediate arbitration */
- /* SST 0 : Start SCSI transfer */
-
-#define SCNTL1_SCSI_RST 0x08 /* force scsi reset in scntl1 reg */
-
-#define SCNTL2_SIZE 0x01
-#define SCNTL2 0x00000002
-#define SCNTL2_INIT 0x00 /* Scsi control 2 */
- #define SDU 0x80 /* SDU 0 : SCSI Disconnect Unexpected */
- #define CHM 0x40 /* CHM 0 : Chained mode */
- #define SLPMD 0x40 /* SLPMD 0 : SLPAR Mode Bit */
- #define SLPHBEN 0x40 /* SLPHBEN : SLPAR High Byte Enable */
- #define WSS 0x08 /* WSS 0 : Wide Scsi Send */
- #define VUE0 0x40 /* VUE0 : Vendor Uniq Enhancements Bit 0 */
- #define VUE1 0x40 /* VUE1 : Vendor Uniq Enhancements Bit 1 */
- #define WSR 0x01 /* WSR 0 : Wide Scsi Receive */
-
-#define SCNTL3_SIZE 0x01
-#define SCNTL3 0x00000003
-#define SCNTL3_INIT 0x03 /* Scsi control 3 for 40Mhz sys clock */
-#define SCNTL3_INIT_875 0x05 /* Scsi control 3 for 80Mhz sys clock */
-#define SCNTL3_INIT_875_ULTRA 0x95 /* Scsi control 3 for 80Mhz sys clock */
-#define SCNTL3_INIT_875_FAST 0x35 /* Scsi control 3 for 80Mhz sys clock */
-#define SCNTL3_INIT_875_SLOW 0x55 /* Scsi control 3 for 80Mhz sys clock */
- /* RES */
- #define SCF 0x70 /* SCF 0 : Sync clock conversion factor 0-2 */
- #define EWS 0x08 /* EWS 0 : Enable Wide SCSI (wdtr) */
- #define CCF 0x07 /* CCF 0 : Async clock conversion factor 0-2 */
-
-#define SCID_SIZE 0x01
-#define SCID 0x00000004
-#define SCID_INIT 0x40 /* Scsi chip Id */
- /* RES */
- /* RRE 1 : Enable response to reselection */
- /* SRE 0 : Disable response to selection */
- /* RES */
- /* ID3 0 */
- /* ID2 0 */
- /* ID1 0 */
- /* ID0 0 : Encoded 53825 chip SCSI Id */
-
-#define SXFER_SIZE 0x01
-#define SXFER 0x00000005
-#define SXFER_INIT 0x00 /* Scsi Transfer */
- /* TP2 0 */
- /* TP1 0 */
- /* TP0 0 : Scsi sync Transfer Period (4)(Sdtr) */
- /* RES */
- /* MO3 0 */
- /* MO2 0 */
- /* MO1 0 */
- /* MO0 0 : Max Scsi Sync ReqAck offset (async) (Sdtr) */
-
-#define SDID_SIZE 0x01
-#define SDID 0x00000006
-#define SDID_INIT 0x00 /* Scsi destination Id */
- /* RES */
- /* RES */
- /* RES */
- /* RES */
- /* ID3 0 */
- /* ID2 0 */
- /* ID1 0 */
- /* ID0 0 : Encoded destination Scsi Id */
-
-#define GPREG_SIZE 0x01
-#define GPREG 0x00000007
-#define GPREG_INIT 0x00 /* Read/write general purpose */
-#define GPIO3 0x08 /* GPIO bit 3 */
- /* RES */
- /* RES */
- /* RES */
- /* GPO 0 : General purpose output */
- /* GPI3 0 */
- /* GPI2 0 */
- /* GPI1 0 */
- /* GPI0 0 : General purpose inputs */
-
-#define SFBR_SIZE 0x01
-#define SFBR 0x00000008
-#define SFBR_INIT 0x00
- /* SCSI First Byte Received */
-
-#define SOCL_SIZE 0x01
-#define SOCL 0x00000009
-#define SOCL_INIT 0x00
- #define SREQ 0x80 /* REQ 0 : Assert SCSI REQ signal */
- #define SACK 0x40 /* ACK 0 : ACK */
- #define SBSY 0x20 /* BSY 0 : BSY */
- #define SSEL 0x10 /* SEL 0 : SEL */
- #define SATN 0x08 /* ATN 0 : ATN */
- #define SMSG 0x04 /* MSG 0 : MSG */
- #define SC_D 0x02 /* C/D 0 : C/D */
- #define SI_O 0x01 /* I/O 0 : I/O */
-
-#define SSID_SIZE 0x01
-#define SSID 0x0000000A /* Read Only */
- /* VAL Scsi Valid Bit */
- /* RES */
- /* RES */
- /* RES */
- /* ID3 */
- /* ID2 */
- /* ID1 */
- /* ID0 Encoded Destination Scsi Id */
-
-#define SBCL_SIZE 0x01
-#define SBCL 0x0000000B /* Scsi Bus Control Lines Read only */
- /* REQ */
- /* ACK */
- /* BSY */
- /* SEL */
- /* ATN */
- /* MSG */
- /* C/D */
- /* I/O */
-
-#define DSTAT_SIZE 0x01
-#define DSTAT 0x0000000C /* DMA status Read only */
- #define DFE 0x80 /* DSTAT DMA FIFO Empty */
- #define MDPE 0x40 /* Master Data Parity Error */
- #define BF 0x20 /* Bus Fault */
- #define DABRT 0x10 /* Abort occurred */
- #define SSI 0x08 /* Script Step Interrupt */
- #define SIR 0x04 /* Script Interrupt Inst Received */
-#ifdef notdef
- #define WTD 0x02 /* was watchdog timer, now reserved */
-#endif /* notdef */
- #define IID 0x01 /* Illegal Instruction Detected */
-
-#define SSTAT0_SIZE 0x01
-#define SSTAT0 0x0000000D /* SCSI status zero Read only */
- #define ILF 0x80 /* ILF SIDL least significant byte full */
- #define ORF 0x40 /* ORF SODR least significant byte full */
- #define OLF 0x20 /* OLF SODL least significant byte full */
- #define AIP 0x10 /* AIP Arbitration in progress */
- #define LOA 0x08 /* LOA Lost arbitration */
- #define WOA 0x04 /* WOA Won arbitration */
- #define RSTB 0x02 /* RST Scsi reset signal */
- #define SDP0 0x01 /* SDP0 Scsi SDP0 parity signal */
-
-#define SSTAT1_SIZE 0x01
-#define SSTAT1 0x0000000E /* SCSI status one Read only */
- /* FF3-0 Bytes or word in the Scsi FIFO */
- /* SDP Latched Scsi parity */
- /* MSG Scsi phase status */
- /* C/D */
- /* I/O */
-
-#define SSTAT2_SIZE 0x01
-#define SSTAT2 0x0000000F /* Scsi status two Read only */
- #define ILF1 0x80 /* ILF1 SIDL most significant byte full */
- #define ORF1 0x40 /* ORF1 SODR " " " " */
- #define OLF1 0x20 /* OLF1 SODL " " " " */
- /* RES */
- #define SPL1 0x08 /* SPL1 Latched Scsi parity for SIDL15-8 */
- #define FF4 0x04 /* FIFO Flags Bit 4 */
- #define LDSC 0x02 /* LDSC Last disconnect */
- #define SDP1 0x01 /* SDP1 Scsi SDP1 Signal */
-
-#define DSA_SIZE 0x04
-#define DSA 0x00000010
-#define DSA_INIT 0x00000000 /* Data structure address */
-
-#define ISTAT_SIZE 0x01
-#define ISTAT 0x00000014
-#define ISTAT_INIT 0x00 /* Interrupt Status */
- #define ABRT 0x80 /* Abort Operation */
- #define RST 0x40 /* Software reset */
- #define SIGP 0x20 /* Signal process */
- #define SEM 0x10 /* Semaphore */
- #define ISTAT_CON 0X08 /* Connected to target. */
- #define INTF 0x04 /* Interrupt on the fly */
- #define SIP 0x02 /* SCSI Interrupt Pending */
- #define DIP 0x01 /* DMA Interrupt Pending */
-
-#define CTEST0_SIZE 0x01
-#define CTEST0 0x00000018
-#define CTEST0_INIT 0x00 /* Chip test zero (now general purpose, rph) */
-
-#define CTEST1_SIZE 0x01
-#define CTEST1 0x00000019 /* Chip test one Read only */
- /* FMT3-0 0 : Byte empty in DMA FIFO */
- /* FFL3-0 0 : Byte full in DMA FIFO */
-
-#define CTEST2_SIZE 0x01
-#define CTEST2 0x0000001A /* Chip test two Read only */
- /* DDIR Data transfer direction (1 : Scsi bus -> host) */
- /* SIGP Signal process (Clear SIGP ISTAT when read) */
- /* CIO (read-only, indicates chip configured as I/O space) */
- /* CM (read-only, indicates configured as memory space) */
- /* RES */
- /* TEOP Scsi true end of process */
- /* DREQ Data request status */
- /* DACK Data acknowledge status */
-
-#define CTEST3_SIZE 0x01
-#define CTEST3 0x0000001B
-#define CTEST3_INIT 0x04 /* Chip test three */
-#define CTEST3_INIT_A 0x05 /* Chip test three for 'A' part */
-
- #define VERS 0xf0 /* V3-0 0 : Chip revision level */
- #define FLF 0x08 /* FLF 0 : Flush DMA Fifo */
- #define CLF 0x04 /* CLF 1 : Clear DMA FIFO */
- #define FM 0x02 /* FM 0 : Fetch pin mode */
- #define WRIE 0x01 /* WRIE 1 : Write and Invalidate Enable, for 825A only!!! */
-
-#define TEMP_SIZE 0x04
-#define TEMP 0x0000001C
-#define TEMP_INIT 0x00000000 /* Tempory stack */
-
-#define DFIFO_SIZE 0x01
-#define DFIFO 0x00000020
-#define DFIFO_INIT 0x00 /* DMA FIFO */
- /* upper bit used for 825 'A' part when using large fifo */
- /* BO6-0 0: Byte offset counter */
-
-#define CTEST4_SIZE 0x01
-#define CTEST4 0x00000021 /* Chip test four */
-// #define CTEST4_INIT 0x80 /* Chip test four DISABLE BURST!! */
-#define CTEST4_INIT 0x00 /* Chip test four */
- /* BDIS 0 : set for Burst Disable, reset allows burst on data moves */
- /* ZMOD High impedance mode */
- /* ZSD Scsi high impedance mode */
- /* SRTM Shadow register test mode */
-/* NOT for bandit!!!! yes for NEW rev of Dumbarton LATER on, not initial!!! */
- /* MPEE 0 : Master Parity Error Enable Do we want this set???? rph */
- /* FBL2-0 Fifo byte control */
-
-#define CTEST5_SIZE 0x01
-#define CTEST5 0x00000022
-#define CTEST5_INIT 0x00 /* Chip test five */
-#define CTEST5_INIT_A 0x00 /* Chip test five 'A' part, upper burst OFF */
-#define CTEST5_INIT_A_revB 0x24 /* Chip test five 'A' part, upper burst OFF
- * also Enable 536 byte fifo */
- #define ADCK 0x80 /* ADCK 0 : Clock address incrementor */
- #define BBCK 0x40 /* BBCK 0 : Clock byte counter */
- #define DFS 0x20 /* DFS 0 : fifo size - 0=88 1=536 bytes */
- #define MASR 0x10 /* MASR 0 : Master control for set reset pulses */
- #define DDIR 0x08 /* DDIR 0 : DMA direction */
- #define BL2 0x04 /* BL2 0 : see DMODE bits 6,7 */
- #define BO89 0x03 /* BO89 0 : upper bits of DFIFO count */
-
-#define CTEST6_SIZE 0x01
-#define CTEST6 0x00000023
-#define CTEST6_INIT 0x00 /* chip test six */
- /* 7-0 0 : DMA Fifo */
-
-#define DBC_SIZE 0x04
-#define DBC 0x00000024
-#define DBC_INIT 0x000000 /* DMA Byte Counter */
-
-#define DCMD_SIZE 0x01
-#define DCMD 0x00000027
-#define DCMD_INIT 0x00 /* DMA command */
-
-#define DNAD_SIZE 0x04
-#define DNAD 0x00000028
-#define DNAD_INIT 0x00000000 /* DMA Next Data Address */
-
-#define DSP_SIZE 0x04
-#define DSP 0x0000002C
-#define DSP_INIT 0x00000000 /* DMA script pointer */
-
-#define DSPS_SIZE 0x04
-#define DSPS 0x00000030
-#define DSPS_INIT 0x00000000 /* DMA SCRIPTS Pointer Save */
-
-#define SCRATCHA_SIZE 0x04
-#define SCRATCHA 0x00000034
-#define SCRATCHA0 0x00000034
-#define SCRATCHA1 0x00000035
-#define SCRATCHA2 0x00000036
-#define SCRATCHA3 0x00000037
-#define SCRATCHA_INIT 0x04030201 /* general purpose register */
-
-#define DMODE_SIZE 0x01
-#define DMODE 0x00000038
-/* 825 bug!!!!! 8 is max!!!!!!! rph 8-23-94
- */
-#define DMODE_INIT 0x82 /* DMA mode 8 burst xfers + instruc fetch */
-#define DMODE_INIT_A 0x0A /* DMA mode 32 burst xfers + instruc fetch */
- /* BL1 1 : Burst length, burst size is '8' transfers (4 bytes per) */
- /* BL0 0 : Burst length */
- /* SIOM 0 : Source I/O-Memory Enable (Memory space is default) */
- /* DIOM 0 : Destination I/O-Memory Enable (Memory space is default) */
- /* ER 1 : Enable Read Line Command, set for 825'A' part */
- /* ERM 0 : */
- /* BOF 1 : Burst Op Code Fetch Enable, only for 825!!! rph */
- /* MAN 0 : Manual start mode (leave 0 for auto-start with DSP write */
-
-#define DIEN_SIZE 0x01
-#define DIEN 0x00000039
-#define DIEN_INIT 0x7D /* No mask on DMA interrupt */
- /* RES */
- /* MDPE 1 : Master Data Parity Error */
- /* BF 1 : Bus fault */
- /* ABRT 1 : Aborted */
- /* SSI 1 : Script step interrupt */
- /* SIR 1 : Script interrupt instruction received */
- /* RES */
- /* IID 1 : Illegal instruction detected */
-
-#define DWT_SIZE 0x01
-#define DWT 0x0000003A
-#define DWT_INIT 0xD0 /* DMA watchdog timer to 0xD0*32*BCLK ns*/
-
-#define DCNTL_SIZE 0x01
-#define DCNTL 0x0000003B
-#define DCNTL_INIT 0x01 /* DMA Control register */
-#define DCNTL_INIT_A 0xA1 /* DMA Control register, 'A' part */
- /* CLE 7: Cache Line Size Enable for 'A' part */
- /* PFF 6: pre-fetch flush bit for 'A' part */
- /* PFEN 5: pre-fetch Enable bit for 'A' part */
- /* RES */
- /* RES */
-#define SSM 0x10 /* 0 : Single step mode */
- /* IRQM 0 : HW driver type for IRQ pin, default is open drain, ask HW rph*/
-#define STD 0x04 /* 0 : start DMA operation */
- /* IRQ 1: IRQ disable for 'A' part */
- /* COM 1 : No Compatibility 700 */
-
-#define ADDER_SIZE 0x04
-#define ADDER 0x0000003C /* Adder sum output Read only */
-
-#define SIEN_SIZE 0x02
-#define SIEN 0x00000040
-#define SIEN_INIT_RST_OFF 0x048D /* SCSI Interrupt enable SIEN0-1 rph */
-#define SIEN_INIT 0x048F /* SCSI Interrupt enable SIEN0-1 rph */
-/* SIEN0 */
- /* M/A 1 : Scsi phase mismatch */
- /* CMP 0 : Function complete */
- /* SEL 0 : Selected */
- /* RSL 0 : Reselected */
- /* SGE 1 : Scsi Gross error */
- /* UDC 1 : Unexpected disconnect */
- /* RST 1 : Scsi Reset condition */
- /* PAR 1 : Scsi Parity error */
-
- /* RES */
- /* RES */
- /* RES */
- /* RES */
- /* RES */
- /* STO 1 : (Re)Selection timeout */
- /* GEM 0 : General purpose timeout*/
- /* HTH 0 : Handshake timeout */
-
-#define SIST_SIZE 0x02
-#define SIST 0x00000042 /* Scsi interrupt status Read only */
- /* idem SIEN reg */
- #define STO 0x0400
- #define GEN 0x0200
- #define HTH 0x0100
-
- #define MA 0x0080
- #define CMP 0x0040
- #define SEL 0x0020
- #define RSL 0x0010
- #define SGE 0x0008
- #define UDC 0x0004
- #define RSTI 0x0002
- #define PAR 0x0001
-
-#define SLPAR_SIZE 0x01
-#define SLPAR 0x00000044
-#define SLPAR_INIT 0x00 /* SCSI longitudinal parity */
-
-#define SWIDE_SIZE 0x01
-#define SWIDE 0x00000045 /* Scsi wide residue data Read only */
-
-#define MACNTL_SIZE 0x01
-#define MACNTL 0x00000046
-#define MACNTL_INIT 0x00 /* memory access control */
- /* TYP3-0 : Chip Type (read-only) */
- /* DataWr 0 : Data write Far memory */
- /* DataRd 0 : Data read far memory */
- /* Pointer to script fetch 0 : far memory */
- /* Script fetch 0 : far memory */
-
-#define GPCNTL_SIZE 0x01
-#define GPCNTL 0x00000047
-#define GPCNTL_INIT 0x0F /* General purpose control Cf appendum ?? */
-// #define GPCNTL_INIT 0xCF /* General purpose control Cf appendum ?? */
- /* ME : 0 Master Enable */
- /* FE : 0 Fetch Enable */
- /* RES */
- /* GPI/O_en4 : 0 GPREG input or output */
- /* GPI/O_en3 : 1 */
- /* GPI/O_en2 : 1 */
- /* GPI/O_en1 : 1 */
- /* GPI/O_en0 : 1 */
-
-#define STIME0_SIZE 0x01
-#define STIME0 0x00000048
-#define STIME0_INIT 0x0C /* Scsi timer register 0 */
- /* HTH3 */
- /* HTH2 */
- /* HTH1 0 */
- /* HTH0 0 : Handshake timer period (disabled) */
- /* SEL3 1 */
- /* SEL2 1 */
- /* SEL1 0 */
- /* SEL0 0 : Selection timeout period (204.8ms) */
-
-#define STIME1_SIZE 0x01
-#define STIME1 0x00000049
-#define STIME1_INIT 0x00 /* Scsi timer register one */
- /* RES */
- /* RES */
- /* RES */
- /* RES */
- /* GEN3 0 */
- /* GEN2 0 */
- /* GEN1 0 */
- /* GEN0 0 : General purpose timer period (disabled) */
-
-#define RESPID0_SIZE 0x01
-#define RESPID0 0x0000004A
-#define RESPID0_INIT 0x00 /* Response Id zero */
- /* ID7 - ID0 */
-
-#define RESPID1_SIZE 0x01
-#define RESPID1 0x0000004B
-#define RESPID1_INIT 0x00 /* Response ID one */
- /* ID15 - ID8 */
-
-#define STEST0_SIZE 0x01
-#define STEST0 0x0000004C /* Scsi test register zero Read only */
- /* RES */
- /* RES */
- /* RES */
- /* RES */
- /* SLT Selection response Logic test */
- /* ART Arbitration priority encoder test */
- /* SOZ Scsi synchronous offset zero */
- /* SOM Scsi synchronous offset maximum */
-
-#define STEST1_SIZE 0x01
-#define STEST1 0x0000004D /* Scsi test register one Read/Write */
-#define STEST1_INIT 0x00
- #define SCLK 0x80 /* SCLK 0 : 1 = Use PCI Clock 0 = Use SCLK input */
- #define SISIO 0x40 /* SISIO 0 : SCSI Isolation Mode */
- /* 0 : */
- /* 0 : */
- #define DBLEN 0x08 /* DBLEN 0 : SCLK Doubler Enable */
- #define DBLSEL 0x04 /* DBLSEL 0 : SCLK Doubler Select */
- /* 0 : */
- /* 0 : */
-
-#define STEST2_SIZE 0x01
-#define STEST2 0x0000004E
-#define STEST2_INIT 0x00 /* Scsi Test register two */
-#define STEST2_DIFF_INIT 0x20 /* Scsi Test register two */
- #define SCE 0x80 /* SCE 0 : Scsi control enable */
- #define ROF 0x40 /* ROF 0 : Reset Scsi offset */
- #define DIF 0x20 /* DIF 0/1 : SCSI differential mode, set if we detect differential card */
- #define SLB 0x10 /* SLB 0 : Scsi loopback mode */
- #define SZM 0x08 /* SZM 0 : SCSI high impedance mode */
- #define AWS 0x04 /* AWS 0 : Always wide SCSI */
- #define EXT 0x02 /* EXT 0 : Extend REQ/ACK filtering NEVER want SET for 'fast'!!! */
- #define LOW 0x01 /* LOW 0 : Scsi low level mode */
-
-#define STEST3_SIZE 0x01
-#define STEST3 0x0000004F
-#define STEST3_INIT 0x92 /* Scsi test register 3 */
- #define EAN 0x80 /* EAN 1 : Enable active negation */
- #define STR 0x40 /* STR 0 : Scsi FIFO test read */
- #define HSC 0x20 /* HSC 0 : Halt Scsi Clock */
- #define DSI 0x10 /* DSI 1 : Disable single initiator response */
- /* RES */
- #define TTM 0x04 /* TTM 0 : Timer test mode */
- #define CSF 0x02 /* CSF 1 : Clear SCSI FIFO */
- #define STW 0x01 /* STW 0 : SCSI FIFO test write */
-
-#define SSIDL_SIZE 0x02
-#define SSIDL 0x00000050 /* SCSI input data latch Read only */
-
-#define SODL_SIZE 0x02
-#define SODL 0x00000054
-#define SODL_INIT 0x0000 /* SCSI Output Data Latch */
-
-#define SBDL_SIZE 0x02
-#define SBDL 0x00000058 /* SCSI bus data line Read only */
-
-#define SCRATCHB_SIZE 0x04
-#define SCRATCHB 0x0000005C
-#define SCRATCHB0 0x0000005C
-#define SCRATCHB1 0x0000005D
-#define SCRATCHB2 0x0000005E
-#define SCRATCHB3 0x0000005F
-#define SCRATCHB_INIT 0x00000000 /* general purpose register */
-
-/* ************************* */
-
-/* Miscellaneous defines */
-#define CLK_40MHz 40
-#define CLK_80MHz 80
-#define kResetRecoveryTimeMS 5000
-
-#define kChipIdSym875 0x000f
-#define kChipIdSym895 0x000c
-#define kChipIdSym896 0x000b
-#define kChipIdSym1010 0x0020
+++ /dev/null
-/*
- * Copyright (c) 1999 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@
- */
-
-/* Sym8xxSRB.h created by russb2 on Sat 30-May-1998 */
-
-/*
- * The SRB is the main per-request data structure used by the driver.
- *
- * It contains an embedded Nexus structure which is used as a per-request
- * communication area between the script and the driver.
- */
-
-typedef struct SRB SRB;
-
-struct SRB
-{
- SRB *srbPhys;
-
- IOSCSIParallelCommand *scsiCommand;
-
- UInt32 srbCDBFlags;
-
- IOReturn srbReturnCode;
- SCSIAdapterStatus srbAdapterStatus;
- UInt8 srbSCSIStatus;
-
- UInt8 srbMsgResid;
- UInt8 srbMsgLength;
-
- UInt8 target;
- UInt8 lun;
- UInt8 tag;
-
- UInt8 negotiateSDTRComplete;
- UInt8 negotiateWDTRComplete;
-
- UInt32 directionMask;
-
- IOMemoryDescriptor *xferDesc;
- UInt32 xferOffset;
- UInt32 xferOffsetPrev;
- UInt32 xferCount;
- UInt32 xferDone;
-
- Nexus nexus;
-
-};
-
+++ /dev/null
-/*
- * Copyright (c) 1999 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@
- */
-
-typedef unsigned long ULONG;
-
-#ifdef INCL_SCRIPT_TEXT
-
-ULONG BSC_SCRIPT[] = {
- 0x80000000L, 0x00000000L,
- 0x80000000L, 0x00000000L,
- 0x80000000L, 0x00000000L,
- 0x80000000L, 0x00000000L,
- 0x80000000L, 0x00000000L,
- 0x80000000L, 0x00000000L,
- 0x80000000L, 0x00000000L,
- 0x80000000L, 0x00000000L,
- 0x80000000L, 0x00000000L,
- 0x80000000L, 0x0000004CL,
- 0x80000000L, 0x0000000FL,
- 0xE1340004L, 0x00000028L,
- 0x60000400L, 0x00000000L,
- 0x79340000L, 0x00000000L,
- 0x79350000L, 0x00000000L,
- 0x79340000L, 0x00000000L,
- 0x79350000L, 0x00000000L,
- 0xE0340004L, 0x0000009CL,
- 0xE1100004L, 0x00000024L,
- 0xF1100004L, 0x00000000L,
- 0x72100000L, 0x00000000L,
- 0x980C00FFL, 0x00000008L,
- 0xE0100004L, 0x0000002CL,
- 0x90080000L, 0x00000000L,
- 0xE15C0004L, 0x00000020L,
- 0x60000400L, 0x00000000L,
- 0x795C0000L, 0x00000000L,
- 0x795C0000L, 0x00000000L,
- 0xE05C0004L, 0x000000F4L,
- 0xE1100004L, 0x00000034L,
- 0xF15C0004L, 0x00000000L,
- 0x725D0000L, 0x00000000L,
- 0x6A050000L, 0x00000000L,
- 0x725F0000L, 0x00000000L,
- 0x6A030000L, 0x00000000L,
- 0x90080000L, 0x00000000L,
- 0x7A1A0000L, 0x00000000L,
- 0xE1340004L, 0x00000010L,
- 0x72340000L, 0x00000000L,
- 0x80840000L, 0x000005F0L,
- 0xE1340004L, 0x0000000CL,
- 0x60000400L, 0x00000000L,
- 0x79340000L, 0x00000000L,
- 0x79350000L, 0x00000000L,
- 0x79340000L, 0x00000000L,
- 0x79350000L, 0x00000000L,
- 0xE0340004L, 0x0000018CL,
- 0xE0340004L, 0x0000025CL,
- 0xE1100004L, 0x00000018L,
- 0xF1100004L, 0x00000000L,
- 0xE0100004L, 0x0000002CL,
- 0xE1340004L, 0x0000002CL,
- 0x72340000L, 0x00000000L,
- 0x808C0001L, 0x00000098L,
- 0x72B50000L, 0x00000000L,
- 0x72B60000L, 0x00000000L,
- 0x72B70000L, 0x00000000L,
- 0x808C0000L, 0x00000458L,
- 0x785C0800L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0xE15C0004L, 0x00000004L,
- 0xF15C0001L, 0x00000020L,
- 0xE05C0004L, 0x00000028L,
- 0xE1100004L, 0x0000002CL,
- 0xF15E0001L, 0x00000002L,
- 0x725E0000L, 0x00000000L,
- 0x6A5C0000L, 0x00000000L,
- 0xE05C0001L, 0x00000020L,
- 0x88880000L, 0xFFFFFE98L,
- 0xE1100004L, 0x0000002CL,
- 0xF05D0001L, 0x00000001L,
- 0xF05F0001L, 0x00000003L,
- 0x47000000L, 0x000003D0L,
- 0xE1340004L, 0x00000004L,
- 0xE1100004L, 0x00000018L,
- 0xF0340004L, 0x00000000L,
- 0xE15C0001L, 0x0000000CL,
- 0x7E5C0100L, 0x00000000L,
- 0xE05C0001L, 0x0000000CL,
- 0xE15C0001L, 0x0000002CL,
- 0x725C0000L, 0x00000000L,
- 0x808C0001L, 0xFFFFFE90L,
- 0xE1100004L, 0x0000002CL,
- 0x828B0000L, 0x00000088L,
- 0x808A0000L, 0x000000A8L,
- 0x868A0000L, 0x00000020L,
- 0x818A0000L, 0x000000E0L,
- 0x838A0000L, 0x00000108L,
- 0x878A0000L, 0x00000120L,
- 0x98080000L, 0x00000000L,
- 0x785C0600L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x1E000000L, 0x00000008L,
- 0x80880000L, 0xFFFFFFA0L,
- 0x58000008L, 0x00000000L,
- 0x60000040L, 0x00000000L,
- 0x868B0000L, 0xFFFFFFC8L,
- 0x87820000L, 0xFFFFFF80L,
- 0x0F000001L, 0x00000039L,
- 0x60000040L, 0x00000000L,
- 0x80880000L, 0xFFFFFFC8L,
- 0x785C0200L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x60000008L, 0x00000000L,
- 0x1A000000L, 0x00000010L,
- 0x80880000L, 0xFFFFFF40L,
- 0x785C0000L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x88880000L, 0x00000008L,
- 0x80880000L, 0xFFFFFF20L,
- 0xF1340004L, 0x00000004L,
- 0xE0340004L, 0x00000394L,
- 0x7835FF00L, 0x00000000L,
- 0xF0350001L, 0x00000021L,
- 0x80080000L, 0x00000333L,
- 0x785C0100L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x88880000L, 0xFFFFFFC0L,
- 0x81830000L, 0xFFFFFED8L,
- 0x01000001L, 0x00000008L,
- 0x80880000L, 0xFFFFFFE8L,
- 0x785C0300L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x0B000001L, 0x00000008L,
- 0x80880000L, 0xFFFFFEA8L,
- 0x785C0700L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x0F000001L, 0x00000040L,
- 0x808C0000L, 0x000000C0L,
- 0x808C0002L, 0x000001A8L,
- 0x808C0004L, 0x00000148L,
- 0x808C0023L, 0x00000038L,
- 0x808C0003L, 0x000001B0L,
- 0x808C0001L, 0x00000058L,
- 0x808C0007L, 0x00000008L,
- 0x98080000L, 0x00000002L,
- 0x98080000L, 0x0000000CL,
- 0x60000040L, 0x00000000L,
- 0x80880000L, 0xFFFFFE38L,
- 0x60000040L, 0x00000000L,
- 0x0F000001L, 0x00000041L,
- 0x6A5E0000L, 0x00000000L,
- 0xF05E0001L, 0x00000022L,
- 0x60000040L, 0x00000000L,
- 0x80880000L, 0xFFFFFE08L,
- 0x60000040L, 0x00000000L,
- 0x0F000001L, 0x00000041L,
- 0x60000040L, 0x00000000L,
- 0x0F000001L, 0x00000042L,
- 0x60000040L, 0x00000000L,
- 0x808C0001L, 0x00000140L,
- 0x808C0003L, 0x00000148L,
- 0x98080000L, 0x00000003L,
- 0x785C0C00L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x7C027F00L, 0x00000000L,
- 0x60000040L, 0x00000000L,
- 0x48000000L, 0x00000000L,
- 0xE1340004L, 0x00000014L,
- 0x72370000L, 0x00000000L,
- 0x80840000L, 0xFFFFFFE8L,
- 0xE1340001L, 0x00000028L,
- 0xE15C0001L, 0x00000008L,
- 0x725C0000L, 0x00000000L,
- 0x6A350000L, 0x00000000L,
- 0x78360000L, 0x00000000L,
- 0x7837FF00L, 0x00000000L,
- 0xE0340004L, 0x00000014L,
- 0x72350000L, 0x00000000L,
- 0x981CC100L, 0x000000FFL,
- 0x808CC100L, 0xFFFFFBC8L,
- 0x98080000L, 0x00000001L,
- 0xE15C0001L, 0x00000030L,
- 0x725C0000L, 0x00000000L,
- 0x808C0009L, 0x00000010L,
- 0x785C0D00L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x785FFF00L, 0x00000000L,
- 0xE05F0001L, 0x0000002BL,
- 0x7C027F00L, 0x00000000L,
- 0x60000040L, 0x00000000L,
- 0x48000000L, 0x00000000L,
- 0x80880000L, 0xFFFFFB68L,
- 0x785C0E00L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x60000040L, 0x00000000L,
- 0x80880000L, 0xFFFFFCB8L,
- 0x785C0F00L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x60000040L, 0x00000000L,
- 0x80880000L, 0xFFFFFC98L,
- 0x0F000002L, 0x00000043L,
- 0x98080000L, 0x0000000DL,
- 0x0F000001L, 0x00000043L,
- 0x98080000L, 0x0000000EL,
- 0x7C00DF00L, 0x00000000L,
- 0x7A1A0000L, 0x00000000L,
- 0x785C0900L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x785FFF00L, 0x00000000L,
- 0xE05F0001L, 0x0000002BL,
- 0x54000000L, 0xFFFFFAD0L,
- 0x720A0000L, 0x00000000L,
- 0x980C7F00L, 0x00000007L,
- 0x6C5C0F00L, 0x00000000L,
- 0xE05C0001L, 0x00000020L,
- 0x88880000L, 0xFFFFFA48L,
- 0x9F030000L, 0x00000005L,
- 0x0F000001L, 0x00000040L,
- 0x60000040L, 0x00000000L,
- 0x878B0000L, 0x00000048L,
- 0x6C340700L, 0x00000000L,
- 0xE15C0001L, 0x00000020L,
- 0x60000400L, 0x00000000L,
- 0x715C0000L, 0x00000000L,
- 0x695C0000L, 0x00000000L,
- 0x715C0000L, 0x00000000L,
- 0x7AB40000L, 0x00000000L,
- 0xE0340001L, 0x00000028L,
- 0x80880000L, 0x00000030L,
- 0x0F000001L, 0x00000040L,
- 0x808C0004L, 0xFFFFFE70L,
- 0x60000040L, 0x00000000L,
- 0x80840020L, 0xFFFFFB90L,
- 0x0F000001L, 0x00000028L,
- 0x60000040L, 0x00000000L,
- 0x785F0000L, 0x00000000L,
- 0xE05F0001L, 0x0000002BL,
- 0x88880000L, 0xFFFFF930L,
- 0x80880000L, 0xFFFFFB60L,
- 0x785C0B00L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x785FFF00L, 0x00000000L,
- 0xE05F0001L, 0x0000002BL,
- 0xE15E0001L, 0x00000012L,
- 0xE05E0001L, 0x00000762L,
- 0x45000000L, 0xFFFFFEB0L,
- 0x72350000L, 0x00000000L,
- 0x80840000L, 0x00000038L,
- 0x72370000L, 0x00000000L,
- 0x6A350000L, 0x00000000L,
- 0xE0340002L, 0x00000038L,
- 0x78020000L, 0x00000000L,
- 0x0E000002L, 0x00000038L,
- 0x48000000L, 0x00000000L,
- 0x98080000L, 0x00000009L,
- 0x72350000L, 0x00000000L,
- 0x6A360000L, 0x00000000L,
- 0x78352000L, 0x00000000L,
- 0xE0340004L, 0x00000038L,
- 0x78020000L, 0x00000000L,
- 0x0E000004L, 0x00000038L,
- 0x48000000L, 0x00000000L,
- 0x98080000L, 0x00000009L,
- 0x785C0A00L, 0x00000000L,
- 0xE05C0001L, 0x00000030L,
- 0x74140800L, 0x00000000L,
- 0x980C0000L, 0x0000000AL,
- 0x58000008L, 0x00000000L,
- 0xE1100004L, 0x0000002CL,
- 0x60000040L, 0x00000000L,
- 0x868B0000L, 0x000000A8L,
- 0x838A0000L, 0x00000030L,
- 0x878A0000L, 0x00000038L,
- 0x818A0000L, 0x00000040L,
- 0x7834AD00L, 0x00000000L,
- 0x808A0000L, 0x00000040L,
- 0x828A0000L, 0x00000058L,
- 0x98080000L, 0x00000000L,
- 0x0B000001L, 0x00000038L,
- 0x80880000L, 0xFFFFFFA8L,
- 0x0F000001L, 0x00000038L,
- 0x80880000L, 0xFFFFFF98L,
- 0x09000001L, 0x00000038L,
- 0x80880000L, 0xFFFFFF88L,
- 0x7B347300L, 0x00000000L,
- 0xE0340001L, 0x00000038L,
- 0x08000001L, 0x00000038L,
- 0x80880000L, 0xFFFFFF68L,
- 0x78340000L, 0x00000000L,
- 0xE0340001L, 0x00000038L,
- 0x0A000001L, 0x00000038L,
- 0x80880000L, 0xFFFFFF48L,
- 0x78020000L, 0x00000000L,
- 0x0E000001L, 0x00000000L,
- 0xE1340004L, 0x00000004L,
- 0xE0340004L, 0x00000000L,
- 0x48000000L, 0x00000000L,
- 0x98080000L, 0x0000000AL
-
-};
-
-#endif /* INCL_SCRIPT_TEXT */
-
-#define Rel_Count 76
-
-#ifdef INCL_SCRIPT_TEXT
-
-ULONG Rel_Patches[Rel_Count] = {
- 0x0000013DL,
- 0x0000014FL,
- 0x0000004BL,
- 0x000001D5L,
- 0x00000051L,
- 0x00000099L,
- 0x0000009DL,
- 0x0000003BL,
- 0x000000FFL,
- 0x00000119L,
- 0x00000125L,
- 0x00000129L,
- 0x0000017FL,
- 0x00000183L,
- 0x000001A1L,
- 0x000001B9L,
- 0x0000002DL,
- 0x00000065L,
- 0x00000067L,
- 0x0000007FL,
- 0x0000008BL,
- 0x0000009FL,
- 0x000000A5L,
- 0x00000207L,
- 0x00000025L,
- 0x00000017L,
- 0x0000007DL,
- 0x00000143L,
- 0x00000165L,
- 0x00000191L,
- 0x000001B5L,
- 0x000001C1L,
- 0x000001C7L,
- 0x000001D3L,
- 0x00000077L,
- 0x000000B7L,
- 0x000000CDL,
- 0x000000D7L,
- 0x000000E9L,
- 0x000000F5L,
- 0x000000FDL,
- 0x00000135L,
- 0x00000159L,
- 0x00000161L,
- 0x00000171L,
- 0x00000179L,
- 0x0000018DL,
- 0x000001CFL,
- 0x000001FFL,
- 0x00000061L,
- 0x00000095L,
- 0x000000C5L,
- 0x000001E3L,
- 0x000001E7L,
- 0x000001F3L,
- 0x000001F7L,
- 0x0000021BL,
- 0x0000021FL,
- 0x00000223L,
- 0x00000229L,
- 0x0000022BL,
- 0x00000231L,
- 0x00000233L,
- 0x00000031L,
- 0x00000087L,
- 0x0000019BL,
- 0x000001A9L,
- 0x00000013L,
- 0x000000EFL,
- 0x000000F7L,
- 0x00000145L,
- 0x00000079L,
- 0x00000093L,
- 0x0000023BL,
- 0x00000239L,
- 0x0000023DL
-};
-
-#endif /* INCL_SCRIPT_TEXT */
-
-#define R_ld_AbortCode 0x00000000L
-#define R_ld_zeroes 0x00000004L
-#define R_ld_status 0x00000008L
-#define R_ld_counter 0x0000000CL
-#define R_ld_AbortBdr_mailbox 0x00000010L
-#define R_ld_IOdone_mailbox 0x00000014L
-#define R_ld_sched_mlbx_base_adr 0x00000018L
-#define R_ld_scsi_id 0x00000020L
-#define R_ld_nexus_array_base 0x00000024L
-#define R_ld_nexus_index 0x00000028L
-#define R_ld_nexus 0x0000002CL
-#define R_ld_phase_flag 0x00000030L
-#define R_ld_device_table_base_adr 0x00000034L
-#define R_ld_scratch 0x00000038L
-#define R_ld_message 0x00000040L
-#define R_ld_size 0x0000004CL
-#define A_kphase_DATA_OUT 0x00000000L
-#define A_unknown_phase 0x00000000L
-#define A_TLQ_SCSI_ID 0x00000000L
-#define A_kphase_DATA_IN 0x00000001L
-#define A_status_error 0x00000001L
-#define A_unexpected_msg 0x00000002L
-#define A_kphase_COMMAND 0x00000002L
-#define A_kphase_STATUS 0x00000003L
-#define A_unexpected_ext_msg 0x00000003L
-#define A_TLQ_xferAdr 0x00000004L
-#define A_no_msgin_after_reselect 0x00000005L
-#define A_kphase_MSG_OUT 0x00000006L
-#define A_kphase_MSG_IN 0x00000007L
-#define A_unknown_reselect 0x00000007L
-#define A_kphase_SELECT 0x00000008L
-#define A_unallocated_nexus 0x00000008L
-#define A_TLQ_MSGOp 0x00000008L
-#define A_kphase_RESELECT 0x00000009L
-#define A_abort_mailbox 0x00000009L
-#define A_abort_current 0x0000000AL
-#define A_kphase_ABORT_CURRENT 0x0000000AL
-#define A_kphase_ABORT_MAILBOX 0x0000000BL
-#define A_kphase_CMD_COMPLETE 0x0000000CL
-#define A_unknown_msg_reject 0x0000000CL
-#define A_kphase_DISCONNECT 0x0000000DL
-#define A_negotiateSDTR 0x0000000DL
-#define A_negotiateWDTR 0x0000000EL
-#define A_kphase_saveDataPointer 0x0000000EL
-#define A_sglist_complete 0x0000000FL
-#define A_kphase_restoreDataPointer 0x0000000FL
-#define A_TLQ_CDBp 0x00000010L
-#define A_TLQ_index 0x00000020L
-#define A_TLQ_xferStarted 0x00000021L
-#define A_TLQ_IWR 0x00000022L
-#define Ent_clearACK 0x00000448L
-#define Ent_issueAbort_BDR 0x000007F0L
-#define Ent_issueMessageOut 0x000002F0L
-#define Ent_phase_handler 0x00000290L
-#define Ent_select_phase 0x00000120L
-
-#ifdef INCL_SCRIPT_TEXT
-
-ULONG LABELPATCHES[] = {
- 0x00000023L,
- 0x00000039L,
- 0x0000005DL,
- 0x0000005FL,
- 0x000000DFL,
- 0x000001D7L
-};
-
-#endif /* INCL_SCRIPT_TEXT */
+++ /dev/null
- 1
- 2 ; Copyright (c) 1997-1999 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 ; File Ownership:
- 23 ;
- 24 ; DRI: Mike Johnson
- 25 ;
- 26 ; Other Contact: Russ Berkoff
- 27 ;
- 28 ; Technology: SCSI
- 29 ;
- 30 ; Writers:
- 31 ;
- 32 ; (MLJ) Mike Johnson
- 33 ; (RRA) Rick Auricchio
- 34
- 35
- 36 ; NCR Errata Listing 125 Item 1 : Clear the SCNTL0 start bit
- 37 ; when jump to reselect during select (try_reselect)
- 38 ;
- 39 ; NCR Errata Listing 117 Item 4 : Bad parity if odd bytes during
- 40 ; wide transfer. Only for DATA OUT in Initiator mode.
- 41 ; (Confirm by Manfred Eierle 3rd June 93 not during DATA IN)
- 42
- 43 ARCH 825A ;specifically for 825a and 875 (new instructions)
- 44
- 45
- 46 ;*****************************************************************
- 47 ;
- 48 ; Phase codes - These values represent which action is being handled
- 49 ;
- 50 ;*****************************************************************
- 51
- 52 ABSOLUTE kphase_DATA_OUT = 0x00
- 53 ABSOLUTE kphase_DATA_IN = 0x01
- 54 ABSOLUTE kphase_COMMAND = 0x02
- 55 ABSOLUTE kphase_STATUS = 0x03
- 56 ABSOLUTE kphase_MSG_OUT = 0x06
- 57 ABSOLUTE kphase_MSG_IN = 0x07
- 58 ABSOLUTE kphase_SELECT = 0x08
- 59 ABSOLUTE kphase_RESELECT = 0x09
- 60 ABSOLUTE kphase_ABORT_CURRENT = 0x0A
- 61 ABSOLUTE kphase_ABORT_MAILBOX = 0x0B
- 62 ABSOLUTE kphase_CMD_COMPLETE = 0x0C
- 63 ABSOLUTE kphase_DISCONNECT = 0x0D
- 64 ABSOLUTE kphase_saveDataPointer = 0x0E ; ??? driver work to be done
- 65 ABSOLUTE kphase_restoreDataPointer = 0x0F ; ??? driver work to be done
- 66
- 67
- 68 ;*****************************************************************
- 69 ; interrupt codes
- 70 ;*****************************************************************
- 71
- 72 ABSOLUTE unknown_phase = 0x00 ; A spurious phase on SCSI Bus
- 73 ABSOLUTE status_error = 0x01 ; IO completes, but with status error
- 74 ABSOLUTE unexpected_msg = 0x02 ; An 'unknown' message is in ld_message var
- 75 ABSOLUTE unexpected_ext_msg = 0x03 ; An 'unknown' extended message in ld_message
- 76 ABSOLUTE wide_32_not_supported = 0x04 ; The device wants 32 bits data phase
- 77 ABSOLUTE no_msgin_after_reselect = 0x05 ; No message-in after reselection
- 78 ABSOLUTE reqack_too_large = 0x06 ; The device answer ReqAck offset is greater than 8
- 79 ABSOLUTE unknown_reselect = 0x07 ; The valid bit in SFBR reg not set
- 80 ABSOLUTE unallocated_nexus = 0x08 ; nexus index -> 0xFFFFFFFF
- 81 ABSOLUTE abort_mailbox = 0x09 ; Abort/BDR mailbox completed
- 82 ABSOLUTE abort_current = 0x0A ; Abort/BDR current op completed
- 83 ABSOLUTE unknown_message_out = 0x0B ; Unknown phase before message out
- 84 ABSOLUTE unknown_msg_reject = 0x0C ; Unknown message reject
- 85 ABSOLUTE negotiateSDTR = 0x0D ; Sync negotiation rx'd
- 86 ABSOLUTE negotiateWDTR = 0x0E ; Wide negotiation rx'd
- 87 ABSOLUTE sglist_complete = 0x0F ; SGList complete
- 88
- 89
- 90 ;*****************************************************************
- 91 ;
- 92 ; Data structure for T/L/Q Nexus:
- 93 ;
- 94 ;*****************************************************************
- 95
- 96 ABSOLUTE TLQ_SCSI_ID = 0 ; 4 SCSI ID et al for SELECT instruction
- 97 ABSOLUTE TLQ_xferAdr = 4 ; 4 Physical address of CHMOV instructions
- 98 ABSOLUTE TLQ_MSGOp = 8 ; 8 Byte count, data adr -> TLQ_MSGO
- 99 ABSOLUTE TLQ_CDBp = 16 ; 8 Byte count, data adr -> TLQ_CDB
- 100 ABSOLUTE TLQ_CDP = 24 ; 4 Current Data Pointer
- 101 ABSOLUTE TLQ_SDP = 28 ; 4 Saved Data Pointer
- 102 ABSOLUTE TLQ_index = 32 ; 1 index into nexus array
- 103 ABSOLUTE TLQ_xferStarted= 33 ; 1 transfer started flag
- 104 ABSOLUTE TLQ_IWR = 34 ; 1 flag to Ignore Wide Residue
- 105 ABSOLUTE TLQ_pad = 35 ; 1 pad byte
- 106
- 107
- 108 ;*****************************************************************
- 109 ;
- 110 ; ENTRY declarations - Declare entry points for driver
- 111 ;
- 112 ;*****************************************************************
- 113
- 114 ENTRY select_phase
- 115 ENTRY phase_handler
- 116 ENTRY issueMessageOut ; for negotiation and Reject messages
- 117 ENTRY issueAbort_BDR ; to immediately Abort or Bus-Device-Reset
- 118 ENTRY clearACK ; MsgIn done - clr ACK, jump to phase handler
- 119
- 120
- 121 ;*****************************************************************
- 122 ;
- 123 ; Define local data structure at start of SCRIPTS.
- 124 ; This structure is allocated by the following nops.
- 125 ;
- 126 ;*****************************************************************
- 127 ;
- 128
- 129 RELATIVE local_data \
- 130 00000000: ld_AbortCode = 4{??}\ ; 1 byte code to Abort or BDR
- 131 00000004: ld_zeroes = 4{??}\ ; 4 bytes of 0 to clear registers
- 132 00000008: ld_status = 4{??}\ ; Status byte from target
- 133 0000000C: ld_counter = 4{??}\ ; index into mailbox array
- 134 00000010: ld_AbortBdr_mailbox = 4{??}\ ; Abort/BusDeviceReset mailbox
- 135 00000014: ld_IOdone_mailbox = 4{??}\ ; [ nexus 0 0 semaphore ]
- 136 00000018: ld_sched_mlbx_base_adr = 4{??}\ ; base addr of mailbox array
- 137 0000001C: ld_mailboxp = 4{??}\ ; address of current mailbox
- 138 00000020: ld_scsi_id = 4{??}\ ; ptr to current mailbox
- 139 00000024: ld_nexus_array_base = 4{??}\ ; base address of Nexus pointers
- 140 00000028: ld_nexus_index = 4{??}\ ; index to Nexus pointer
- 141 0000002C: ld_nexus = 4{??}\ ; address of Nexus
- 142 00000030: ld_phase_flag = 4{??}\ ; for debugging
- 143 00000034: ld_device_table_base_adr = 4{??}\ ; device configuration table
- 144 00000038: ld_scratch = 4{??}\ ; scratch memory
- 145 0000003C: ld_unused = 4{??}\ ; unused
- 146 00000040: ld_message = 4{??}\ ; buffer for MsgIn bytes
- 147 00000044: ld_message4 = 4{??}\ ; buffer continuation
- 148 00000048: ld_pad = 4{??}\ ; padding
- 149 0000004C: ld_size = 4{??} ; size of this structure
- 150
- 151
- 152 00000000: PROC BSC_SCRIPT:
- 153
- 154 ; *** These NOPs must be at address 0. ***
- 155 ; *** This is reserved space for the structure "local_data". ***
- 156 ; *** The driver inits this area to zero. ***
- 157
- 158 00000000: 80000000 00000000 nop 0 ; ld_AbortCode, ld_zeroes
- 159 00000008: 80000000 00000000 nop 0 ; ld_status, ld_counter
- 160
- 161 00000010: 80000000 00000000 nop 0 ; ld_AbortBdr_mailbox, ld_IOdone_mailbox
- 162 00000018: 80000000 00000000 nop 0 ; ld_sched_mlbx_base_adr, ld_mailboxp
- 163
- 164 00000020: 80000000 00000000 nop 0 ; ld_scsi_id, ld_nexus_array_base
- 165 00000028: 80000000 00000000 nop 0 ; ld_nexus_index, ld_nexus
- 166
- 167 00000030: 80000000 00000000 nop 0 ; ld_phase_flag, ld_device_table_base_adr
- 168 00000038: 80000000 00000000 nop 0 ; ld_scratch, ld_unused
- 169
- 170 00000040: 80000000 00000000 nop 0 ; ld_message, ld_message4
- 171 00000048: 80000000 0000004C nop ld_size ; ld_pad, ld_size (Use ld_size or lose it)
- 172
- 173 00000050: 80000000 0000000F nop sglist_complete ; use sglist_complete or lose it from gen'd output file
- 174
- 175 ;****************************************************************************
- 176 ;
- 177 ; findNexusFromIndex - load DSA with pointer to Nexus given a Nexus index:
- 178 ;
- 179 ;****************************************************************************
- 180
- 181 00000058: findNexusFromIndex:
- 182
- 183 00000058: E1340004 00000028 load SCRATCHA0, 4, ld_nexus_index ; load index and leading zeroes
- 184 00000060: 60000400 00000000 clear CARRY
- 185 00000068: 79340000 00000000 move SCRATCHA0 SHL 0 to SCRATCHA0 ; double the index
- 186 00000070: 79350000 00000000 move SCRATCHA1 SHL 0 to SCRATCHA1
- 187 00000078: 79340000 00000000 move SCRATCHA0 SHL 0 to SCRATCHA0 ; double again
- 188 00000080: 79350000 00000000 move SCRATCHA1 SHL 0 to SCRATCHA1 ; A0 now has index to 4-byte address
- 189 00000088: E0340004 0000009C store SCRATCHA0, 4, patchArrayOffset+4 ; *** patch the code
- 190
- 191 00000090: E1100004 00000024 load DSA0, 4, ld_nexus_array_base ; load base address of array of Nexus pointers
- 192 00000098: patchArrayOffset:
- 193 00000098: F1100004 00000000 load DSA0, 4, DSAREL( 0 ) ; *** patched offset. Load pointer.
- 194
- 195 000000A0: 72100000 00000000 move DSA0 to SFBR ; Ensure pointer is not 0xFFFFFFFF
- 196 000000A8: 980C00FF 00000008 int unallocated_nexus, if 0xFF ; Interrupt if NFG
- 197
- 198 000000B0: E0100004 0000002C store DSA0, 4, ld_nexus ; Store the Nexus pointer
- 199 000000B8: 90080000 00000000 return ; end findNexusFromIndex
- 200
- 201
- 202 ;****************************************************************************
- 203 ;
- 204 ; initContext - Initialize the registers for Sync and Wide using
- 205 ; values stored in the device configuration table.
- 206 ; Return with values in SCRATCHB for Select code.
- 207 ;
- 208 ;****************************************************************************
- 209
- 210 000000C0: initContext:
- 211
- 212 000000C0: E15C0004 00000020 load SCRATCHB0, 4, ld_scsi_id ; load 4-bit SCSI ID and zeroes
- 213 000000C8: 60000400 00000000 clear CARRY
- 214 000000D0: 795C0000 00000000 move SCRATCHB0 SHL SCRATCHB0 ; * 2
- 215 000000D8: 795C0000 00000000 move SCRATCHB0 SHL SCRATCHB0 ; * 2 -> UInt32 index
- 216 000000E0: E05C0004 000000F4 store SCRATCHB0, 4, patchGetDevConfigOffset+4 ; *** Patch load code
- 217
- 218 000000E8: E1100004 00000034 load DSA0, 4, ld_device_table_base_adr ; load base physical addr of tables
- 219
- 220 000000F0: patchGetDevConfigOffset:
- 221 000000F0: F15C0004 00000000 load SCRATCHB0, 4, DSAREL( 0 ) ; *** Patched table offset ***
- 222
- 223 ; SCRATCHB0 = 0
- 224 ; SCRATCHB1 = TP,MO (SXFER bits7-5 bits3-0)
- 225 ; SCRATCHB2 = 0 (position for SCSI ID)
- 226 ; SCRATCHB3 = SCCF,EWS (SCNTL3 bits6-4 bit 3)
- 227
- 228 000000F8: 725D0000 00000000 move SCRATCHB1 to SFBR ; init SXFER from B1
- 229 00000100: 6A050000 00000000 move SFBR to SXFER
- 230 ; Init SCNTL3 from B3
- 231 00000108: 725F0000 00000000 move SCRATCHB3 to SFBR
- 232 00000110: 6A030000 00000000 move SFBR to SCNTL3
- 233 00000118: 90080000 00000000 return ; return with SCRATCHB intact.
- 234
- 235
- 236 ;*****************************************************************
- 237 ;
- 238 ; Select_phase:
- 239 ; Clear the SIGP bit.
- 240 ; Check if any Abort/BusDeviceReset request waiting.
- 241 ; Nexus is found in the list of 256 mailboxes.
- 242 ; If current mailbox is empty, jump to reselect_phase.
- 243 ; SCRIPTS tries to select device.
- 244 ; If select fails due to reselect, jump to reselect_phase
- 245 ; Select Timeout handled by driver.
- 246 ; If select succeeds, clear the mailbox entry
- 247 ; and increment the mailbox counter.
- 248 ; Jump to the phase_handler (hopefully for MSG_OUT)
- 249 ;
- 250 ;*****************************************************************
- 251
- 252 00000120: select_phase:
- 253
- 254 00000120: 7A1A0000 00000000 move CTEST2 | 0x00 to CTEST2 ; Clear SIGP bit from ISTAT reg
- 255
- 256 ; Check abort mailbox:
- 257
- 258 00000128: E1340004 00000010 load SCRATCHA0, 4, ld_AbortBdr_mailbox ; Get AbortBdr mailbox
- 259 ; The Identify byte in byte 0 is also the semaphore
- 260 ; A0 = Identify byte (0xC0 + LUN N.B. Disconnect allowed)
- 261 ; A1 = Tag, if any
- 262 ; A2 = SCSI ID
- 263 ; A3 = Abort code Abort=0x06; Abort Tag=0D; Bus Device Reset=0x0C
- 264 00000130: 72340000 00000000 move SCRATCHA0 to SFBR ; test the semaphore/Identify
- 265 00000138: 80840000 000005F0 jump rel( AbortMailbox ), if not 0 ; jump if aborting
- 266
- 267
- 268 ; Get the next IO nexus in the mailboxes circular list.
- 269 ; Calculate current mailbox address as so:
- 270 ; counter byte index * 4 to get mailbox index
- 271 ; add base physical address of mailboxes giving current mailbox address
- 272
- 273 00000140: E1340004 0000000C load SCRATCHA0, 4, ld_counter ; get 1-byte mailbox counter & 0s
- 274 00000148: 60000400 00000000 clear CARRY
- 275 00000150: 79340000 00000000 move SCRATCHA0 SHL 0 to SCRATCHA0 ; double it
- 276 00000158: 79350000 00000000 move SCRATCHA1 SHL 0 to SCRATCHA1
- 277 00000160: 79340000 00000000 move SCRATCHA0 SHL 0 to SCRATCHA0 ; double it again
- 278 00000168: 79350000 00000000 move SCRATCHA1 SHL 0 to SCRATCHA1 ; now have a UInt32 index
- 279 00000170: E0340004 0000018C store SCRATCHA0, 4, fetchMailbox+4 ; *** patch the load DSA instruction
- 280 00000178: E0340004 0000025C store SCRATCHA0, 4, clear_mailbox+4 ; *** patch the store DSA instruction
- 281
- 282 00000180: E1100004 00000018 load DSA0, 4, ld_sched_mlbx_base_adr ; load base physical address of mailboxes
- 283
- 284 00000188: fetchMailbox:
- 285 00000188: F1100004 00000000 load DSA0, 4, DSAREL( 0 ) ; *** Patched offset. Load Nexus address
- 286 00000190: E0100004 0000002C store DSA0, 4, ld_nexus ; save pointer to current Nexus
- 287 00000198: E1340004 0000002C load SCRATCHA0, 4, ld_nexus ; copy to A0
- 288
- 289 000001A0: 72340000 00000000 move SCRATCHA0 to SFBR ;
- 290 000001A8: 808C0001 00000098 jump rel( next_mailbox ), if 1 ; if low-byte == 0x01 then cancelled mailbox
- 291
- 292 000001B0: 72B50000 00000000 move SCRATCHA1 | SFBR to SFBR ; if non-zero, have implicit semaphore
- 293 000001B8: 72B60000 00000000 move SCRATCHA2 | SFBR to SFBR
- 294 000001C0: 72B70000 00000000 move SCRATCHA3 | SFBR to SFBR
- 295 000001C8: 808C0000 00000458 jump rel( reselect_phase ), if 0 ; go to reselect_phase if empty
- 296
- 297 ;*****************************************************************
- 298 ;
- 299 ; Something in mailbox: we have work to do
- 300 ;
- 301 ;*****************************************************************
- 302
- 303 000001D0: 785C0800 00000000 move kphase_SELECT to SCRATCHB0 ; set phase indicator
- 304 000001D8: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 305
- 306 000001E0: E15C0004 00000004 load SCRATCHB0, 4, ld_zeroes ; clr the invalid-nexus-index flag
- 307 000001E8: F15C0001 00000020 load SCRATCHB0, 1, DSAREL( TLQ_index ) ; get index byte from nexus
- 308 000001F0: E05C0004 00000028 store SCRATCHB0, 4, ld_nexus_index ; save it in local data
- 309
- 310 000001F8: E1100004 0000002C load DSA0, 4, ld_nexus ; restore DSA register
- 311 00000200: F15E0001 00000002 load SCRATCHB2, 1, DSAREL( TLQ_SCSI_ID+2 ) ; get Target's SCSI ID
- 312 00000208: 725E0000 00000000 move SCRATCHB2 to SFBR
- 313 00000210: 6A5C0000 00000000 move SFBR to SCRATCHB0 ; position it
- 314 00000218: E05C0001 00000020 store SCRATCHB0, 1, ld_scsi_id ; save it
- 315 00000220: 88880000 FFFFFE98 call rel( initContext ) ; setup Sync/Wide regs in SCRATCHB
- 316 00000228: E1100004 0000002C load DSA0, 4, ld_nexus ; restore DSA register
- 317 00000230: F05D0001 00000001 store SCRATCHB1, 1, DSAREL( TLQ_SCSI_ID+1 ) ; SXFER
- 318 00000238: F05F0001 00000003 store SCRATCHB3, 1, DSAREL( TLQ_SCSI_ID+3 ) ; SCNTL3
- 319
- 320 ;********************** select the device ********************************
- 321 00000240: 47000000 000003D0 SELECT ATN from TLQ_SCSI_ID, rel( try_reselect ) ; ************************
- 322 ;*************************************************************************
- 323
- 324 ; looking good - clear the mailbox:
- 325
- 326 00000248: next_mailbox:
- 327 00000248: E1340004 00000004 load SCRATCHA0, 4, ld_zeroes ; zero out scratch register A
- 328 00000250: E1100004 00000018 load DSA0, 4, ld_sched_mlbx_base_adr ; load base physical address of mailboxes
- 329 00000258: clear_mailbox:
- 330 00000258: F0340004 00000000 store SCRATCHA0, 4, DSAREL( 0 ) ; *** Patched offset. Zero the mailbox
- 331
- 332 ; Update the index to the mailbox circular list:
- 333 00000260: E15C0001 0000000C load SCRATCHB0, 1, ld_counter ; get counter (mailbox index)
- 334 00000268: 7E5C0100 00000000 move SCRATCHB0 + 1 to SCRATCHB0 ; add 1
- 335 00000270: E05C0001 0000000C store SCRATCHB0, 1, ld_counter ; put it back
- 336
- 337 00000278: E15C0001 0000002C load SCRATCHB0, 1, ld_nexus ; if low-byte == 0x01 then cancelled mailbox
- 338 00000280: 725C0000 00000000 move SCRATCHB0 to SFBR
- 339 00000288: 808C0001 FFFFFE90 jump rel( select_phase ), if 1
- 340
- 341 ; *** FALL THROUGH TO phase_handler ***
- 342
- 343
- 344 ;*****************************************************************
- 345 ;
- 346 ; Phase_handler
- 347 ; The phase handler script is a dispatcher function of SCSI phase
- 348 ;
- 349 ;*****************************************************************
- 350
- 351 00000290: phase_handler:
- 352 00000290: E1100004 0000002C load DSA0, 4, ld_nexus ; reload DSA
- 353 00000298: 828B0000 00000088 jump rel( command_phase ), when CMD ; wait for REQ
- 354 000002A0: 808A0000 000000A8 jump rel( data_out_phase ), if DATA_OUT ; already latched REQ signal
- 355 000002A8: 868A0000 00000020 jump rel( message_out_phase ), if MSG_OUT
- 356 000002B0: 818A0000 000000E0 jump rel( data_in_phase ), if DATA_IN
- 357 000002B8: 838A0000 00000108 jump rel( status_phase ), if STATUS
- 358 000002C0: 878A0000 00000120 jump rel( message_in_phase ), if MSG_IN
- 359 000002C8: 98080000 00000000 int unknown_phase
- 360
- 361
- 362 ;*****************************************************************
- 363 ;
- 364 ; Message-Out phase
- 365 ;
- 366 ;*****************************************************************
- 367
- 368 000002D0: message_out_phase:
- 369 000002D0: 785C0600 00000000 move kphase_MSG_OUT to SCRATCHB0 ; Set phase indicator
- 370 000002D8: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 371
- 372 000002E0: 1E000000 00000008 move from TLQ_MSGOp, when MSG_OUT ; put out the message(s)
- 373 000002E8: 80880000 FFFFFFA0 jump rel( phase_handler )
- 374
- 375
- 376 ; issueMessageOut - Driver entry point for Sync/Wide negotiation and
- 377 ; to issue message Reject:
- 378
- 379 000002F0: issueMessageOut:
- 380 000002F0: 58000008 00000000 set ATN ; tell Target we have something to say
- 381 000002F8: 60000040 00000000 clear ACK
- 382 00000300: 868B0000 FFFFFFC8 jump rel( message_out_phase ), when MSG_OUT ; wait for REQ. Jump if msg-out phase.
- 383 00000308: 87820000 FFFFFF80 jump rel( phase_handler ), if not MSG_IN ; jump if weird phase
- 384 00000310: 0F000001 00000039 move 1, ld_scratch+1, when MSG_IN ; dump the msg byte
- 385 00000318: 60000040 00000000 clear ACK ; accept Target's last msg-in byte
- 386 00000320: 80880000 FFFFFFC8 jump rel( issueMessageOut )
- 387
- 388
- 389 ;*****************************************************************
- 390 ;
- 391 ; Command phase
- 392 ;
- 393 ;*****************************************************************
- 394
- 395 00000328: command_phase:
- 396 00000328: 785C0200 00000000 move kphase_COMMAND to SCRATCHB0 ; Set phase indicator
- 397 00000330: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 398
- 399 00000338: 60000008 00000000 clear ATN ; In case we missed the sending nego
- 400 00000340: 1A000000 00000010 move FROM TLQ_CDBp, when CMD ; issue the CDB
- 401 00000348: 80880000 FFFFFF40 jump rel( phase_handler )
- 402
- 403
- 404 ;*****************************************************************
- 405 ;
- 406 ; Data_out_phase
- 407 ;
- 408 ;*****************************************************************
- 409
- 410 00000350: data_out_phase:
- 411 00000350: 785C0000 00000000 move kphase_DATA_OUT to SCRATCHB0 ; Set phase indicator
- 412 00000358: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 413
- 414 00000360: 88880000 00000008 call rel( driverXfer ) ; call driver-built CHMOV instructions
- 415 00000368: 80880000 FFFFFF20 jump rel( phase_handler ) ; if all data xfer'd, get next phase
- 416
- 417 00000370: driverXfer: ; get here from data-in code also
- 418 00000370: F1340004 00000004 load SCRATCHA0, 4, DSAREL( TLQ_xferAdr )
- 419 00000378: E0340004 00000394 store SCRATCHA0, 4, doItPatch+4 ; *** patch the JUMP address
- 420 00000380: 7835FF00 00000000 move 0xFF to SCRATCHA1
- 421 00000388: F0350001 00000021 store SCRATCHA1, 1, DSAREL( TLQ_xferStarted )
- 422
- 423 00000390: doItPatch:
- 424 00000390: 80080000 00000333 jump 0x0333 ; *** patched address
- 425
- 426
- 427
- 428 ;*****************************************************************
- 429 ;
- 430 ; Data_in_phase
- 431 ; 875 sets ATN if bad parity detected.
- 432 ; Use of CHMOV instructions assures that we properly handle
- 433 ; a leftover wide byte in the SWIDE or SODL register, depending
- 434 ; on the data direction. This can happen in either of two conditions:
- 435 ; 1. The Target disconnects at an odd boundary. This is
- 436 ; extremely unlikely with disk devices.
- 437 ; 2. The client passes either an odd buffer address or
- 438 ; an odd transfer count. When the Target disconnects (at
- 439 ; an even boundary, we end up with the extra wide
- 440 ; byte in SWIDE or SODL. MacOS does this with VM on.
- 441 ;
- 442 ;*****************************************************************
- 443
- 444 00000398: data_in_phase:
- 445 00000398: 785C0100 00000000 move kphase_DATA_IN to SCRATCHB0 ; Set phase indicator
- 446 000003A0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 447
- 448 000003A8: 88880000 FFFFFFC0 call rel( driverXfer ) ; call driver-built CHMOV instructions
- 449
- 450 ; The driver gets interrupted if a phase mismatch occurs as when
- 451 ; the Target goes MSG-IN with a Disconnect.
- 452 ; The driver codes either a RETURN if the Scatter/Gather list is complete or
- 453 ; an INT if more Scatter/Gather elements need to be generated.
- 454 ; On the Macintosh, client programs expect extra incoming data to be dumped.
- 455 ; For example, during boot the ROM reads 512 bytes from a 2K-byte-sector CD.
- 456
- 457 000003B0: bucket_loop:
- 458 000003B0: 81830000 FFFFFED8 jump rel( phase_handler ), when not DATA_IN ; wait for phase, exit if changed
- 459 000003B8: 01000001 00000008 CHMOV 1, ld_status, when DATA_IN ; eat a byte
- 460 000003C0: 80880000 FFFFFFE8 jump rel( bucket_loop ); ; keep dumping bytes
- 461
- 462
- 463 ;*****************************************************************
- 464 ;
- 465 ; Status phase
- 466 ;
- 467 ;*****************************************************************
- 468
- 469 000003C8: status_phase:
- 470 000003C8: 785C0300 00000000 move kphase_STATUS to SCRATCHB0 ; Set phase indicator
- 471 000003D0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 472
- 473 000003D8: 0B000001 00000008 move 1, ld_status, when STATUS ; Read Status byte from bus
- 474 000003E0: 80880000 FFFFFEA8 jump rel( phase_handler )
- 475
- 476
- 477 ;*****************************************************************
- 478 ;
- 479 ; Message-In phase
- 480 ;
- 481 ;*****************************************************************
- 482
- 483 000003E8: message_in_phase:
- 484 000003E8: 785C0700 00000000 move kphase_MSG_IN to SCRATCHB0 ; Set phase indicator
- 485 000003F0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 486
- 487 000003F8: 0F000001 00000040 move 1, ld_message, when MSG_IN ; Read byte from bus
- 488
- 489 00000400: 808C0000 000000C0 jump rel( cmdComplete ), if 0x00 ; Command Complete
- 490 00000408: 808C0002 000001A8 jump rel( saveDataPointer ), if 0x02 ; Save Data Pointer
- 491 00000410: 808C0004 00000148 jump rel( disconnect_msg ), if 0x04 ; Disconnect
- 492 00000418: 808C0023 00000038 jump rel( ignoreWideResidue ), if 0x23 ; Ignore Wide Residue
- 493 00000420: 808C0003 000001B0 jump rel( restoreDataPointer ), if 0x03 ; Restore Data Pointer
- 494 00000428: 808C0001 00000058 jump rel( extended_msg ), if 0x01 ; Extended message
- 495 00000430: 808C0007 00000008 jump rel( msg_reject ), if 0x07 ; Message Reject
- 496 ; Identify, if 0x80-FF ; Identify + LUN
- 497 ; simple_queue_tag, if 0x20 ; Simple Queue Tag
- 498 ; initiate_recovery, if 0x0F ; Initiate Recovery
- 499 ; linked_cde_complete, if 0x0A/0x0B
- 500 00000438: 98080000 00000002 int unexpected_msg ; unknown
- 501
- 502 00000440: msg_reject:
- 503 00000440: 98080000 0000000C int unknown_msg_reject
- 504
- 505 00000448: clearACK: ; ENTRY point to end negotiation
- 506 00000448: 60000040 00000000 clear ACK
- 507 00000450: 80880000 FFFFFE38 jump rel( phase_handler )
- 508
- 509
- 510
- 511 ;*****************************************************************
- 512 ;
- 513 ; Ignore Wide Residue
- 514 ;
- 515 ;*****************************************************************
- 516
- 517 00000458: ignoreWideResidue: ; this is a two byte message so snag the 2nd byte here
- 518 00000458: 60000040 00000000 clear ACK
- 519 00000460: 0F000001 00000041 move 1, ld_message+1, when MSG_IN ; save residue count
- 520 00000468: 6A5E0000 00000000 move SFBR to SCRATCHB2 ; byte is still in SFBR. Position it.
- 521 00000470: F05E0001 00000022 store SCRATCHB2, 1, DSAREL( TLQ_IWR ) ; Store residue count in Nexus for driver.
- 522 00000478: 60000040 00000000 clear ACK
- 523 00000480: 80880000 FFFFFE08 jump rel( phase_handler )
- 524
- 525
- 526 ;*****************************************************************
- 527 ;
- 528 ; Extended message
- 529 ; Accept Wide and Synchronous Data Transfer messages
- 530 ;
- 531 ;*****************************************************************
- 532
- 533 00000488: extended_msg:
- 534 00000488: 60000040 00000000 clear ACK
- 535 00000490: 0F000001 00000041 move 1, ld_message+1, when MSG_IN ; read msg length byte from bus
- 536 00000498: 60000040 00000000 clear ACK
- 537 000004A0: 0F000001 00000042 move 1, ld_message+2, when MSG_IN ; read ext msg code from bus
- 538 000004A8: 60000040 00000000 clear ACK
- 539 ; extended_identify, IF 0x02
- 540 ; modify_data_pointer, if 0x00
- 541 000004B0: 808C0001 00000140 jump rel( sdtr ), if 0x01 ; jump if SDTR, sync negotiation msg
- 542 000004B8: 808C0003 00000148 jump rel( wdtr ), if 0x03 ; jump if WDTR, wide negotiation msg
- 543 000004C0: 98080000 00000003 int unexpected_ext_msg ; let driver deal with unknown
- 544
- 545
- 546 ;*****************************************************************
- 547 ;
- 548 ; Command complete
- 549 ; The Command-Complete message is sent to indicate that the
- 550 ; IO operation has completed and valid status has been sent.
- 551 ; The Target should then disconnect.
- 552 ; SCRIPTS must spin until the IOdone mailbox is empty.
- 553 ; Then it sets the IOdone mailbox with the current Nexus.
- 554 ; The status message is analyzed.
- 555 ; If status is good, INTF the driver and jump to select_phase.
- 556 ; If status is NG, save it in the NEXUS and INT the driver.
- 557 ;
- 558 ;*****************************************************************
- 559
- 560 000004C8: cmdComplete:
- 561 000004C8: 785C0C00 00000000 move kphase_CMD_COMPLETE to SCRATCHB0 ; Set phase indicator
- 562 000004D0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 563
- 564 000004D8: 7C027F00 00000000 move SCNTL2 & 0X7F to SCNTL2 ; Clr SDU: SCSI Disconnect Unexpected
- 565 000004E0: 60000040 00000000 clear ACK
- 566 000004E8: 48000000 00000000 WAIT DISCONNECT
- 567
- 568 000004F0: testMbxLp: ; loop until IOdone mailbox empty
- 569 000004F0: E1340004 00000014 load SCRATCHA0, 4, ld_IOdone_mailbox
- 570 000004F8: 72370000 00000000 move SCRATCHA3 to SFBR ; A3 = semaphore
- 571 00000500: 80840000 FFFFFFE8 jump rel( testMbxLp ), if not 0
- 572
- 573 ; Fill in the IOdone mailbox with the following:
- 574 ; A0 = index to Nexus
- 575 ; A1 = Status
- 576 ; A2 = 0
- 577 ; A3 = semaphore (FF = set)
- 578 00000508: E1340001 00000028 load SCRATCHA0, 1, ld_nexus_index ; A0 = index to Nexus
- 579 00000510: E15C0001 00000008 load SCRATCHB0, 1, ld_status
- 580 00000518: 725C0000 00000000 move SCRATCHB0 to SFBR
- 581 00000520: 6A350000 00000000 move SFBR to SCRATCHA1 ; A1 = Status
- 582 00000528: 78360000 00000000 move 0x00 to SCRATCHA2 ; A2 = 0
- 583 00000530: 7837FF00 00000000 move 0xFF to SCRATCHA3 ; A3 = semaphore IOdone mailbox
- 584 00000538: E0340004 00000014 store SCRATCHA0, 4, ld_IOdone_mailbox
- 585
- 586 00000540: 72350000 00000000 move SCRATCHA1 to SFBR ; Test the Status of this IO
- 587 ; SFBR = status msg
- 588 ; Test status - If good, Interrupt on the fly and jump to select phase
- 589 00000548: 981CC100 000000FF intfly 0xFF, if 0 and mask 0xC1 ; mask off reserved bits
- 590 00000550: 808CC100 FFFFFBC8 jump rel( select_phase ), if 0 and mask 0xC1
- 591 00000558: 98080000 00000001 int status_error ; Status err. Interrupt driver & stop
- 592
- 593
- 594 ;*****************************************************************
- 595 ;
- 596 ; Disconnect
- 597 ; The 8xx Accepts the disconnection and jumps to the select_phase
- 598 ; to check for another IO
- 599 ;
- 600 ;*****************************************************************
- 601
- 602 00000560: disconnect_msg:
- 603 00000560: E15C0001 00000030 load SCRATCHB0, 1, ld_phase_flag
- 604 00000568: 725C0000 00000000 move SCRATCHB0 to SFBR
- 605 ; If we got here from reselect just bailout since ld_nexus is
- 606 ; not setup and the code using it is not needed anyway (no data xfer)
- 607 00000570: 808C0009 00000010 jump rel( bailout ), if kphase_RESELECT
- 608
- 609 00000578: 785C0D00 00000000 move kphase_DISCONNECT to SCRATCHB0
- 610 00000580: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 611
- 612 00000588: bailout:
- 613 00000588: 785FFF00 00000000 move 0xFF to SCRATCHB3 ; invalidate nexus index for driver
- 614 00000590: E05F0001 0000002B store SCRATCHB3, 1, ld_nexus_index+3
- 615 00000598: 7C027F00 00000000 move SCNTL2 & 0x7F to SCNTL2 ; Clr SDU: SCSI Disconnect Unexpected
- 616 000005A0: 60000040 00000000 clear ACK
- 617 000005A8: 48000000 00000000 WAIT DISCONNECT ; wait for bus-free
- 618 000005B0: 80880000 FFFFFB68 jump rel( select_phase ) ; go see if more to do
- 619
- 620
- 621 ;******************************************************************
- 622 ;
- 623 ; ??? mlj - saveDataPointer and restoreDataPointer are incorrect.
- 624 ; ??? They basically do nothing.
- 625 ; Save Data Pointer
- 626 ;
- 627 ;*****************************************************************
- 628
- 629 000005B8: saveDataPointer:
- 630 000005B8: 785C0E00 00000000 move kphase_saveDataPointer to SCRATCHB0
- 631 000005C0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 632 000005C8: 60000040 00000000 clear ACK
- 633 000005D0: 80880000 FFFFFCB8 jump rel( phase_handler )
- 634
- 635
- 636 ;******************************************************************
- 637 ;
- 638 ; ??? mlj - saveDataPointer and restoreDataPointer are incorrect.
- 639 ; ??? They basically do nothing.
- 640 ; Restore Data Pointer
- 641 ; The local values still blocks, still bytes and data address
- 642 ; must be loaded from the corresponding NEXUS data set.
- 643 ; This message should followed an IDE (parity error)
- 644 ;
- 645 ;*****************************************************************
- 646
- 647 000005D8: restoreDataPointer:
- 648 000005D8: 785C0F00 00000000 move kphase_restoreDataPointer to SCRATCHB0
- 649 000005E0: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 650 000005E8: 60000040 00000000 clear ACK
- 651 000005F0: 80880000 FFFFFC98 jump rel( phase_handler )
- 652
- 653
- 654 ;*****************************************************************
- 655 ;
- 656 ; Synchronous data transfer request or response
- 657 ;
- 658 ;*****************************************************************
- 659 000005F8: sdtr:
- 660 000005F8: 0F000002 00000043 move 2, ld_message+3, when MSG_IN ; Read period & offset from bus
- 661 00000600: 98080000 0000000D int negotiateSDTR
- 662
- 663
- 664 ;***************************************************************************
- 665 ;
- 666 ; Wide Data Transfer request or response
- 667 ;
- 668 ;***************************************************************************
- 669 00000608: wdtr:
- 670 00000608: 0F000001 00000043 move 1, ld_message+3, when MSG_IN ; get Transfer Width Exponent fm bus
- 671 00000610: 98080000 0000000E int negotiateWDTR
- 672
- 673
- 674 ;*****************************************************************
- 675 ;
- 676 ; Reselect phase
- 677 ; The chip waits here either for a Reselection from a Target or
- 678 ; a SIGP from the driver indicating something in the mailbox.
- 679 ; If reselected, the script uses the Nexus value which is either
- 680 ; a Tag or a SCSI ID/LUN combo to lookup the Nexus.
- 681 ; Then init the SXFER and SCNTL3 registers from the device config table.
- 682 ;
- 683 ;*****************************************************************
- 684
- 685 00000618: try_reselect: ; Select failed - probably reselecting
- 686 ; Cf NCR Errata Listing 117 Item 1:
- 687 00000618: 7C00DF00 00000000 move SCNTL0 & 0xDF to SCNTL0 ; clr Start bit
- 688 00000620: 7A1A0000 00000000 move CTEST2 | 0x00 to CTEST2 ; Clear SIGP bit from ISTAT reg
- 689
- 690 00000628: reselect_phase:
- 691 00000628: 785C0900 00000000 move kphase_RESELECT to SCRATCHB0 ; Set phase indicator
- 692 00000630: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 693
- 694 00000638: 785FFF00 00000000 move 0xFF to SCRATCHB3 ; invalidate nexus index for driver
- 695 00000640: E05F0001 0000002B store SCRATCHB3, 1, ld_nexus_index+3
- 696
- 697 ; wait here for reselect from a Target
- 698 ; or SIGP from the driver
- 699
- 700 00000648: 54000000 FFFFFAD0 WAIT RESELECT REL( select_phase ) ; jump if SIGP
- 701
- 702 ; Reselected:
- 703
- 704 00000650: 720A0000 00000000 move SSID to SFBR ; SSID = [ Valxxx Scsi_id ]
- 705 00000658: 980C7F00 00000007 int unknown_reselect, if 0 and mask 0x7F; Interrupt if VAL bit not set
- 706 00000660: 6C5C0F00 00000000 move SFBR & 0x0F to SCRATCHB0 ; B0 = Target ID
- 707 00000668: E05C0001 00000020 store SCRATCHB0, 1, ld_scsi_id ; save it
- 708
- 709 00000670: 88880000 FFFFFA48 call rel( initContext ) ; setup sync regs here
- 710
- 711 00000678: 9F030000 00000005 int no_msgin_after_reselect, when not MSG_IN
- 712
- 713 00000680: 0F000001 00000040 move 1, ld_message, when MSG_IN ; Read Identify byte from bus
- 714
- 715 ; if another REQ is asserted, a SimpleQueueTag message should be next
- 716
- 717 00000688: 60000040 00000000 clear ACK ; notify Target: msg byte rx'd
- 718 00000690: 878B0000 00000048 jump rel( getNextMsg ), when MSG_IN ; jump if SimpleQueueTag coming
- 719
- 720 ; untagged operation:
- 721
- 722 00000698: 6C340700 00000000 move SFBR & 0x07 to SCRATCHA0 ; isolate LUN from Identify byte
- 723
- 724 000006A0: E15C0001 00000020 load SCRATCHB0, 1, ld_scsi_id ; B0 = Target ID
- 725 000006A8: 60000400 00000000 clear CARRY
- 726 000006B0: 715C0000 00000000 move SCRATCHB0 SHL SFBR ; shift left #1
- 727 000006B8: 695C0000 00000000 move SFBR SHL SCRATCHB0 ; shift left #2
- 728 000006C0: 715C0000 00000000 move SCRATCHB0 SHL SFBR ; shift left #3
- 729 000006C8: 7AB40000 00000000 move SCRATCHA0 | SFBR to SCRATCHA0 ; form Nexus index = 0b0TTTTLLL
- 730
- 731 000006D0: E0340001 00000028 store SCRATCHA0, 1, ld_nexus_index ; store as index to Nexus
- 732 000006D8: 80880000 00000030 jump rel( haveNexusIndex )
- 733
- 734 ; should be tagged operation:
- 735
- 736 000006E0: getNextMsg:
- 737 000006E0: 0F000001 00000040 move 1, ld_message, when MSG_IN ; read message byte from bus
- 738 000006E8: 808C0004 FFFFFE70 jump rel( disconnect_msg ), if 0x04 ; if Disconnect, oh well.
- 739 000006F0: 60000040 00000000 clear ACK
- 740 000006F8: 80840020 FFFFFB90 jump rel( phase_handler ), if not 0x20; Branch if not Queue tag code
- 741 ; get the Queue Tag and save as the nexus index
- 742 00000700: 0F000001 00000028 move 1, ld_nexus_index, when MSG_IN ; Nexus index <- Tag from bus
- 743 00000708: 60000040 00000000 clear ACK ; acknowledge it
- 744
- 745 00000710: haveNexusIndex:
- 746 00000710: 785F0000 00000000 move 0x00 to SCRATCHB3 ; clear invalid-nexus-index flag
- 747 00000718: E05F0001 0000002B store SCRATCHB3, 1, ld_nexus_index+3
- 748 00000720: 88880000 FFFFF930 call rel( findNexusFromIndex ) ; set DSA <- Nexus pointer
- 749 00000728: 80880000 FFFFFB60 jump rel( phase_handler ) ; start handling phases.
- 750
- 751
- 752 ;*****************************************************************
- 753 ;
- 754 ; AbortMailbox - Abort (or BusDeviceReset) the mailbox entry.
- 755 ; This is a queued operation - not an immediate
- 756 ; operation as is issueAbort_BDR.
- 757 ; The Abort message clears all IO processes for the
- 758 ; selecting Initiator on the specified LUN.
- 759 ;
- 760 ; The Bus Device Reset message clears all IO processes for
- 761 ; all Initiators on all LUNs of selected Target.
- 762 ; It forces a hard reset condition to the selected SCSI device.
- 763 ;
- 764 ; A0 = Identify byte (0xC0 + LUN N.B. Disconnect allowed)
- 765 ; A1 = Tag, if any
- 766 ; A2 = SCSI ID
- 767 ; A3 = Abort code Abort=0x06; Abort Tag=0D; Bus Device Reset=0x0C
- 768 ;
- 769 ; Mailbox not cleared by SCRIPTS so that driver can find SCSI ID when done
- 770 ; N.B.: Device is Async and Narrow after BDR!!!
- 771 ; Driver must set the device config table values accordingly.
- 772 ;*****************************************************************
- 773
- 774 00000730: AbortMailbox:
- 775 00000730: 785C0B00 00000000 move kphase_ABORT_MAILBOX to SCRATCHB0 ; Set phase code
- 776 00000738: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 777
- 778 00000740: 785FFF00 00000000 move 0xFF to SCRATCHB3 ; invalidate nexus index for driver
- 779 00000748: E05F0001 0000002B store SCRATCHB3, 1, ld_nexus_index+3
- 780
- 781 00000750: E15E0001 00000012 load SCRATCHB2, 1, ld_AbortBdr_mailbox+2 ; get SCSI ID
- 782 00000758: E05E0001 00000762 store SCRATCHB2, 1, AbortSelect+2 ; *** Patch the Select/ATN instruction
- 783
- 784 00000760: AbortSelect:
- 785 00000760: 45000000 FFFFFEB0 SELECT ATN 0, REL( try_reselect ) ; *** Patched SCSI ID
- 786
- 787 00000768: 72350000 00000000 move SCRATCHA1 to SFBR ; check for Tag
- 788 00000770: 80840000 00000038 jump rel( taggedAbort ) if not 0x00 ; jump if tagged abort
- 789
- 790 ; untagged Abort or BusDeviceReset:
- 791
- 792 00000778: 72370000 00000000 move SCRATCHA3 to SFBR ; position the abort code
- 793 00000780: 6A350000 00000000 move SFBR to SCRATCHA1
- 794 00000788: E0340002 00000038 store SCRATCHA0, 2, ld_scratch ; Store Identify and Abort msgs
- 795 00000790: 78020000 00000000 move 0x00 to SCNTL2 ; Clr SDU SCSI Disconnect Unexpected
- 796 00000798: 0E000002 00000038 move 2, ld_scratch , when MSG_OUT ; emit Identify and Abort messages
- 797 000007A0: 48000000 00000000 WAIT DISCONNECT
- 798 000007A8: 98080000 00000009 int abort_mailbox
- 799
- 800 ; AbortTag:
- 801
- 802 000007B0: taggedAbort:
- 803 000007B0: 72350000 00000000 move SCRATCHA1 to SFBR ; position the Tag
- 804 000007B8: 6A360000 00000000 move SFBR to SCRATCHA2
- 805 000007C0: 78352000 00000000 move 0x20 to SCRATCHA1 ; gen SimpleQueueTag code
- 806 000007C8: E0340004 00000038 store SCRATCHA0, 4, ld_scratch ; store Identify, SQT, Tag, AbortTag
- 807 000007D0: 78020000 00000000 move 0x00 to SCNTL2 ; Clr SDU SCSI Disconnect Unexpected
- 808 000007D8: 0E000004 00000038 move 4, ld_scratch, when MSG_OUT ; emit all 4 bytes
- 809 000007E0: 48000000 00000000 WAIT DISCONNECT
- 810 000007E8: 98080000 00000009 int abort_mailbox
- 811
- 812
- 813 ;*****************************************************************
- 814 ;
- 815 ; issueAbort_BDR - Abort (or BusDeviceReset) the current operation.
- 816 ; This is an immediate operation - not a queued operation
- 817 ; as is AbortMailbox.
- 818 ; The Abort message clears all IO processes for the
- 819 ; selecting Initiator on the specified LUN.
- 820 ;
- 821 ; The Bus Device Reset message clears all IO processes for
- 822 ; all Initiators on all LUNs of selected Target.
- 823 ; It forces a hard reset condition to the selected SCSI device.
- 824 ;
- 825 ;*****************************************************************
- 826
- 827 000007F0: issueAbort_BDR:
- 828 000007F0: 785C0A00 00000000 move kphase_ABORT_CURRENT to SCRATCHB0 ; Set phase code
- 829 000007F8: E05C0001 00000030 store SCRATCHB0, 1, ld_phase_flag
- 830
- 831 00000800: 74140800 00000000 move ISTAT & 0x08 to SFBR ; see if Target connected to bus
- 832 00000808: 980C0000 0000000A int abort_current, if 0 ; interrupt driver if not connected
- 833
- 834 00000810: 58000008 00000000 SET ATN ; get Target's attention
- 835 00000818: E1100004 0000002C load DSA0, 4, ld_nexus ; load pointer to Nexus
- 836
- 837 00000820: bucketLoop:
- 838 00000820: 60000040 00000000 clear ACK
- 839 00000828: 868B0000 000000A8 jump rel( sendAbortBDR ), when MSG_OUT ; wait for REQ. Jump if OK.
- 840
- 841 00000830: 838A0000 00000030 jump rel( BucketInStatus ), if STATUS ; bit bucket in
- 842 00000838: 878A0000 00000038 jump rel( BucketInMsg ), if MSG_IN ; bit bucket in
- 843 00000840: 818A0000 00000040 jump rel( BucketInData ), if DATA_IN ; bit bucket in
- 844
- 845 00000848: 7834AD00 00000000 move 0xAD to SCRATCHA0
- 846 00000850: 808A0000 00000040 jump rel( BucketOutData ), if DATA_OUT ; bit bucket out
- 847 00000858: 828A0000 00000058 jump rel( BucketOutCmd ), if CMD ; bit bucket out
- 848 00000860: 98080000 00000000 int unknown_phase ; back to driver for harsher measures
- 849
- 850
- 851 00000868: BucketInStatus:
- 852 00000868: 0B000001 00000038 move 1, ld_scratch, when STATUS ; eat the Status byte
- 853 00000870: 80880000 FFFFFFA8 jump rel( bucketLoop ); ; keep bit-bucketing bytes
- 854
- 855 00000878: BucketInMsg:
- 856 00000878: 0F000001 00000038 move 1, ld_scratch, when MSG_IN ; eat a message byte
- 857 00000880: 80880000 FFFFFF98 jump rel( bucketLoop ); ; keep bit-bucketing bytes
- 858
- 859 00000888: BucketInData:
- 860 00000888: 09000001 00000038 move 1, ld_scratch, when DATA_IN ; eat a data byte
- 861 00000890: 80880000 FFFFFF88 jump rel( bucketLoop ); ; keep bit-bucketing bytes
- 862
- 863 00000898: BucketOutData:
- 864 00000898: 7B347300 00000000 move SCRATCHA0 xor 0x73 to SCRATCHA0 ; gen 0xDEAD ...
- 865 000008A0: E0340001 00000038 store SCRATCHA0, 1, ld_scratch
- 866 000008A8: 08000001 00000038 move 1, ld_scratch, when DATA_OUT ; pad a byte out
- 867 000008B0: 80880000 FFFFFF68 jump rel( bucketLoop ); ; keep bit-bucketing bytes
- 868
- 869 000008B8: BucketOutCmd:
- 870 000008B8: 78340000 00000000 move 0x00 to SCRATCHA0 ; load Null, TestUnitReady, whatever
- 871 000008C0: E0340001 00000038 store SCRATCHA0, 1, ld_scratch
- 872 000008C8: 0A000001 00000038 move 1, ld_scratch, when CMD ; pad a byte out
- 873 000008D0: 80880000 FFFFFF48 jump rel( bucketLoop ); ; keep bit-bucketing bytes
- 874
- 875
- 876 000008D8: sendAbortBDR:
- 877 000008D8: 78020000 00000000 move 0x00 to SCNTL2 ; Clr SDU SCSI Disconnect Unexpected
- 878 000008E0: 0E000001 00000000 move 1, ld_AbortCode, when MSG_OUT ; Send Abort(06) or BDR(0C) message
- 879 000008E8: E1340004 00000004 load SCRATCHA0, 4, ld_zeroes ; load 0's
- 880 000008F0: E0340004 00000000 store SCRATCHA0, 4, ld_AbortCode ; clear the Abort code
- 881 000008F8: 48000000 00000000 WAIT DISCONNECT
- 882 00000900: 98080000 0000000A int abort_current ; went BusFree - tell Driver
-
---SYMBOL---------------------------VALUE------TYPE-------
-abort_current 0000000A ABSOLUTE
-abort_mailbox 00000009 ABSOLUTE
-kphase_ABORT_MAILBOX 0000000B ABSOLUTE
-kphase_ABORT_CURRENT 0000000A ABSOLUTE
-kphase_CMD_COMPLETE 0000000C ABSOLUTE
-kphase_COMMAND 00000002 ABSOLUTE
-kphase_DATA_IN 00000001 ABSOLUTE
-kphase_DATA_OUT 00000000 ABSOLUTE
-kphase_DISCONNECT 0000000D ABSOLUTE
-kphase_MSG_IN 00000007 ABSOLUTE
-kphase_MSG_OUT 00000006 ABSOLUTE
-kphase_RESELECT 00000009 ABSOLUTE
-kphase_SELECT 00000008 ABSOLUTE
-kphase_STATUS 00000003 ABSOLUTE
-kphase_restoreDataPointer 0000000F ABSOLUTE
-kphase_saveDataPointer 0000000E ABSOLUTE
-negotiateWDTR 0000000E ABSOLUTE
-negotiateSDTR 0000000D ABSOLUTE
-no_msgin_after_reselect 00000005 ABSOLUTE
-reqack_too_large 00000006 ABSOLUTE
-sglist_complete 0000000F ABSOLUTE
-status_error 00000001 ABSOLUTE
-TLQ_CDP 00000018 ABSOLUTE
-TLQ_CDBp 00000010 ABSOLUTE
-TLQ_IWR 00000022 ABSOLUTE
-TLQ_MSGOp 00000008 ABSOLUTE
-TLQ_SDP 0000001C ABSOLUTE
-TLQ_index 00000020 ABSOLUTE
-TLQ_pad 00000023 ABSOLUTE
-TLQ_xferAdr 00000004 ABSOLUTE
-TLQ_SCSI_ID 00000000 ABSOLUTE
-TLQ_xferStarted 00000021 ABSOLUTE
-unallocated_nexus 00000008 ABSOLUTE
-unexpected_ext_msg 00000003 ABSOLUTE
-unexpected_msg 00000002 ABSOLUTE
-unknown_message_out 0000000B ABSOLUTE
-unknown_msg_reject 0000000C ABSOLUTE
-unknown_phase 00000000 ABSOLUTE
-unknown_reselect 00000007 ABSOLUTE
-wide_32_not_supported 00000004 ABSOLUTE
-BSC_SCRIPT 00000000 CODE SEGMENT
-SCRIPT 00000000 CODE SEGMENT
-local_data 00000000 DATA SEGMENT
-clearACK 00000448 ENTRY
-issueAbort_BDR 000007F0 ENTRY
-issueMessageOut 000002F0 ENTRY
-phase_handler 00000290 ENTRY
-select_phase 00000120 ENTRY
-AbortSelect 00000760 LABEL
-AbortMailbox 00000730 LABEL
-BucketInData 00000888 LABEL
-BucketInMsg 00000878 LABEL
-BucketInStatus 00000868 LABEL
-BucketOutCmd 000008B8 LABEL
-BucketOutData 00000898 LABEL
-bucketLoop 00000820 LABEL
-bailout 00000588 LABEL
-bucket_loop 000003B0 LABEL
-clear_mailbox 00000258 LABEL
-cmdComplete 000004C8 LABEL
-command_phase 00000328 LABEL
-data_in_phase 00000398 LABEL
-data_out_phase 00000350 LABEL
-disconnect_msg 00000560 LABEL
-doItPatch 00000390 LABEL
-driverXfer 00000370 LABEL
-extended_msg 00000488 LABEL
-fetchMailbox 00000188 LABEL
-findNexusFromIndex 00000058 LABEL
-getNextMsg 000006E0 LABEL
-haveNexusIndex 00000710 LABEL
-ignoreWideResidue 00000458 LABEL
-initContext 000000C0 LABEL
-message_in_phase 000003E8 LABEL
-message_out_phase 000002D0 LABEL
-msg_reject 00000440 LABEL
-next_mailbox 00000248 LABEL
-patchGetDevConfigOffset 000000F0 LABEL
-patchArrayOffset 00000098 LABEL
-reselect_phase 00000628 LABEL
-restoreDataPointer 000005D8 LABEL
-sdtr 000005F8 LABEL
-saveDataPointer 000005B8 LABEL
-sendAbortBDR 000008D8 LABEL
-status_phase 000003C8 LABEL
-taggedAbort 000007B0 LABEL
-testMbxLp 000004F0 LABEL
-try_reselect 00000618 LABEL
-wdtr 00000608 LABEL
-ld_IOdone_mailbox 00000014 RELATIVE.
-ld_AbortBdr_mailbox 00000010 RELATIVE.
-ld_counter 0000000C RELATIVE.
-ld_device_table_base_adr 00000034 RELATIVE.
-ld_mailboxp 0000001C RELATIVE.
-ld_message 00000040 RELATIVE.
-ld_message4 00000044 RELATIVE.
-ld_nexus 0000002C RELATIVE.
-ld_nexus_array_base 00000024 RELATIVE.
-ld_nexus_index 00000028 RELATIVE.
-ld_pad 00000048 RELATIVE.
-ld_phase_flag 00000030 RELATIVE.
-ld_sched_mlbx_base_adr 00000018 RELATIVE.
-ld_scratch 00000038 RELATIVE.
-ld_scsi_id 00000020 RELATIVE.
-ld_size 0000004C RELATIVE.
-ld_status 00000008 RELATIVE.
-ld_unused 0000003C RELATIVE.
-ld_zeroes 00000004 RELATIVE.
-ld_AbortCode 00000000 RELATIVE.
\ No newline at end of file
+++ /dev/null
-
-; Copyright (c) 1997-1999 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@
-;
-; File Ownership:
-;
-; DRI: Mike Johnson
-;
-; Other Contact: Russ Berkoff
-;
-; Technology: SCSI
-;
-; Writers:
-;
-; (MLJ) Mike Johnson
-; (RRA) Rick Auricchio
-
-
-; NCR Errata Listing 125 Item 1 : Clear the SCNTL0 start bit
-; when jump to reselect during select (try_reselect)
-;
-; NCR Errata Listing 117 Item 4 : Bad parity if odd bytes during
-; wide transfer. Only for DATA OUT in Initiator mode.
-; (Confirm by Manfred Eierle 3rd June 93 not during DATA IN)
-
- ARCH 825A ;specifically for 825a and 875 (new instructions)
-
-
- ;*****************************************************************
- ;
- ; Phase codes - These values represent which action is being handled
- ;
- ;*****************************************************************
-
- ABSOLUTE kphase_DATA_OUT = 0x00
- ABSOLUTE kphase_DATA_IN = 0x01
- ABSOLUTE kphase_COMMAND = 0x02
- ABSOLUTE kphase_STATUS = 0x03
- ABSOLUTE kphase_MSG_OUT = 0x06
- ABSOLUTE kphase_MSG_IN = 0x07
- ABSOLUTE kphase_SELECT = 0x08
- ABSOLUTE kphase_RESELECT = 0x09
- ABSOLUTE kphase_ABORT_CURRENT = 0x0A
- ABSOLUTE kphase_ABORT_MAILBOX = 0x0B
- ABSOLUTE kphase_CMD_COMPLETE = 0x0C
- ABSOLUTE kphase_DISCONNECT = 0x0D
- ABSOLUTE kphase_saveDataPointer = 0x0E ; ??? driver work to be done
- ABSOLUTE kphase_restoreDataPointer = 0x0F ; ??? driver work to be done
-
-
- ;*****************************************************************
- ; interrupt codes
- ;*****************************************************************
-
- ABSOLUTE unknown_phase = 0x00 ; A spurious phase on SCSI Bus
- ABSOLUTE status_error = 0x01 ; IO completes, but with status error
- ABSOLUTE unexpected_msg = 0x02 ; An 'unknown' message is in ld_message var
- ABSOLUTE unexpected_ext_msg = 0x03 ; An 'unknown' extended message in ld_message
- ABSOLUTE wide_32_not_supported = 0x04 ; The device wants 32 bits data phase
- ABSOLUTE no_msgin_after_reselect = 0x05 ; No message-in after reselection
- ABSOLUTE reqack_too_large = 0x06 ; The device answer ReqAck offset is greater than 8
- ABSOLUTE unknown_reselect = 0x07 ; The valid bit in SFBR reg not set
- ABSOLUTE unallocated_nexus = 0x08 ; nexus index -> 0xFFFFFFFF
- ABSOLUTE abort_mailbox = 0x09 ; Abort/BDR mailbox completed
- ABSOLUTE abort_current = 0x0A ; Abort/BDR current op completed
- ABSOLUTE unknown_message_out = 0x0B ; Unknown phase before message out
- ABSOLUTE unknown_msg_reject = 0x0C ; Unknown message reject
- ABSOLUTE negotiateSDTR = 0x0D ; Sync negotiation rx'd
- ABSOLUTE negotiateWDTR = 0x0E ; Wide negotiation rx'd
- ABSOLUTE sglist_complete = 0x0F ; SGList complete
-
-
- ;*****************************************************************
- ;
- ; Data structure for T/L/Q Nexus:
- ;
- ;*****************************************************************
-
- ABSOLUTE TLQ_SCSI_ID = 0 ; 4 SCSI ID et al for SELECT instruction
- ABSOLUTE TLQ_xferAdr = 4 ; 4 Physical address of CHMOV instructions
- ABSOLUTE TLQ_MSGOp = 8 ; 8 Byte count, data adr -> TLQ_MSGO
- ABSOLUTE TLQ_CDBp = 16 ; 8 Byte count, data adr -> TLQ_CDB
- ABSOLUTE TLQ_CDP = 24 ; 4 Current Data Pointer
- ABSOLUTE TLQ_SDP = 28 ; 4 Saved Data Pointer
- ABSOLUTE TLQ_index = 32 ; 1 index into nexus array
- ABSOLUTE TLQ_xferStarted= 33 ; 1 transfer started flag
- ABSOLUTE TLQ_IWR = 34 ; 1 flag to Ignore Wide Residue
- ABSOLUTE TLQ_pad = 35 ; 1 pad byte
-
-
- ;*****************************************************************
- ;
- ; ENTRY declarations - Declare entry points for driver
- ;
- ;*****************************************************************
-
- ENTRY select_phase
- ENTRY phase_handler
- ENTRY issueMessageOut ; for negotiation and Reject messages
- ENTRY issueAbort_BDR ; to immediately Abort or Bus-Device-Reset
- ENTRY clearACK ; MsgIn done - clr ACK, jump to phase handler
-
-
- ;*****************************************************************
- ;
- ; Define local data structure at start of SCRIPTS.
- ; This structure is allocated by the following nops.
- ;
- ;*****************************************************************
- ;
-
- RELATIVE local_data \
- ld_AbortCode = 4{??}\ ; 1 byte code to Abort or BDR
- ld_zeroes = 4{??}\ ; 4 bytes of 0 to clear registers
- ld_status = 4{??}\ ; Status byte from target
- ld_counter = 4{??}\ ; index into mailbox array
- ld_AbortBdr_mailbox = 4{??}\ ; Abort/BusDeviceReset mailbox
- ld_IOdone_mailbox = 4{??}\ ; [ nexus 0 0 semaphore ]
- ld_sched_mlbx_base_adr = 4{??}\ ; base addr of mailbox array
- ld_mailboxp = 4{??}\ ; address of current mailbox
- ld_scsi_id = 4{??}\ ; ptr to current mailbox
- ld_nexus_array_base = 4{??}\ ; base address of Nexus pointers
- ld_nexus_index = 4{??}\ ; index to Nexus pointer
- ld_nexus = 4{??}\ ; address of Nexus
- ld_phase_flag = 4{??}\ ; for debugging
- ld_device_table_base_adr = 4{??}\ ; device configuration table
- ld_scratch = 4{??}\ ; scratch memory
- ld_unused = 4{??}\ ; unused
- ld_message = 4{??}\ ; buffer for MsgIn bytes
- ld_message4 = 4{??}\ ; buffer continuation
- ld_pad = 4{??}\ ; padding
- ld_size = 4{??} ; size of this structure
-
-
-PROC BSC_SCRIPT:
-
- ; *** These NOPs must be at address 0. ***
- ; *** This is reserved space for the structure "local_data". ***
- ; *** The driver inits this area to zero. ***
-
- nop 0 ; ld_AbortCode, ld_zeroes
- nop 0 ; ld_status, ld_counter
-
- nop 0 ; ld_AbortBdr_mailbox, ld_IOdone_mailbox
- nop 0 ; ld_sched_mlbx_base_adr, ld_mailboxp
-
- nop 0 ; ld_scsi_id, ld_nexus_array_base
- nop 0 ; ld_nexus_index, ld_nexus
-
- nop 0 ; ld_phase_flag, ld_device_table_base_adr
- nop 0 ; ld_scratch, ld_unused
-
- nop 0 ; ld_message, ld_message4
- nop ld_size ; ld_pad, ld_size (Use ld_size or lose it)
-
- nop sglist_complete ; use sglist_complete or lose it from gen'd output file
-
- ;****************************************************************************
- ;
- ; findNexusFromIndex - load DSA with pointer to Nexus given a Nexus index:
- ;
- ;****************************************************************************
-
-findNexusFromIndex:
-
- load SCRATCHA0, 4, ld_nexus_index ; load index and leading zeroes
- clear CARRY
- move SCRATCHA0 SHL 0 to SCRATCHA0 ; double the index
- move SCRATCHA1 SHL 0 to SCRATCHA1
- move SCRATCHA0 SHL 0 to SCRATCHA0 ; double again
- move SCRATCHA1 SHL 0 to SCRATCHA1 ; A0 now has index to 4-byte address
- store SCRATCHA0, 4, patchArrayOffset+4 ; *** patch the code
-
- load DSA0, 4, ld_nexus_array_base ; load base address of array of Nexus pointers
-patchArrayOffset:
- load DSA0, 4, DSAREL( 0 ) ; *** patched offset. Load pointer.
-
- move DSA0 to SFBR ; Ensure pointer is not 0xFFFFFFFF
- int unallocated_nexus, if 0xFF ; Interrupt if NFG
-
- store DSA0, 4, ld_nexus ; Store the Nexus pointer
- return ; end findNexusFromIndex
-
-
- ;****************************************************************************
- ;
- ; initContext - Initialize the registers for Sync and Wide using
- ; values stored in the device configuration table.
- ; Return with values in SCRATCHB for Select code.
- ;
- ;****************************************************************************
-
-initContext:
-
- load SCRATCHB0, 4, ld_scsi_id ; load 4-bit SCSI ID and zeroes
- clear CARRY
- move SCRATCHB0 SHL SCRATCHB0 ; * 2
- move SCRATCHB0 SHL SCRATCHB0 ; * 2 -> UInt32 index
- store SCRATCHB0, 4, patchGetDevConfigOffset+4 ; *** Patch load code
-
- load DSA0, 4, ld_device_table_base_adr ; load base physical addr of tables
-
-patchGetDevConfigOffset:
- load SCRATCHB0, 4, DSAREL( 0 ) ; *** Patched table offset ***
-
- ; SCRATCHB0 = 0
- ; SCRATCHB1 = TP,MO (SXFER bits7-5 bits3-0)
- ; SCRATCHB2 = 0 (position for SCSI ID)
- ; SCRATCHB3 = SCCF,EWS (SCNTL3 bits6-4 bit 3)
-
- move SCRATCHB1 to SFBR ; init SXFER from B1
- move SFBR to SXFER
- ; Init SCNTL3 from B3
- move SCRATCHB3 to SFBR
- move SFBR to SCNTL3
- return ; return with SCRATCHB intact.
-
-
- ;*****************************************************************
- ;
- ; Select_phase:
- ; Clear the SIGP bit.
- ; Check if any Abort/BusDeviceReset request waiting.
- ; Nexus is found in the list of 256 mailboxes.
- ; If current mailbox is empty, jump to reselect_phase.
- ; SCRIPTS tries to select device.
- ; If select fails due to reselect, jump to reselect_phase
- ; Select Timeout handled by driver.
- ; If select succeeds, clear the mailbox entry
- ; and increment the mailbox counter.
- ; Jump to the phase_handler (hopefully for MSG_OUT)
- ;
- ;*****************************************************************
-
-select_phase:
-
- move CTEST2 | 0x00 to CTEST2 ; Clear SIGP bit from ISTAT reg
-
- ; Check abort mailbox:
-
- load SCRATCHA0, 4, ld_AbortBdr_mailbox ; Get AbortBdr mailbox
- ; The Identify byte in byte 0 is also the semaphore
- ; A0 = Identify byte (0xC0 + LUN N.B. Disconnect allowed)
- ; A1 = Tag, if any
- ; A2 = SCSI ID
- ; A3 = Abort code Abort=0x06; Abort Tag=0D; Bus Device Reset=0x0C
- move SCRATCHA0 to SFBR ; test the semaphore/Identify
- jump rel( AbortMailbox ), if not 0 ; jump if aborting
-
-
- ; Get the next IO nexus in the mailboxes circular list.
- ; Calculate current mailbox address as so:
- ; counter byte index * 4 to get mailbox index
- ; add base physical address of mailboxes giving current mailbox address
-
- load SCRATCHA0, 4, ld_counter ; get 1-byte mailbox counter & 0s
- clear CARRY
- move SCRATCHA0 SHL 0 to SCRATCHA0 ; double it
- move SCRATCHA1 SHL 0 to SCRATCHA1
- move SCRATCHA0 SHL 0 to SCRATCHA0 ; double it again
- move SCRATCHA1 SHL 0 to SCRATCHA1 ; now have a UInt32 index
- store SCRATCHA0, 4, fetchMailbox+4 ; *** patch the load DSA instruction
- store SCRATCHA0, 4, clear_mailbox+4 ; *** patch the store DSA instruction
-
- load DSA0, 4, ld_sched_mlbx_base_adr ; load base physical address of mailboxes
-
-fetchMailbox:
- load DSA0, 4, DSAREL( 0 ) ; *** Patched offset. Load Nexus address
- store DSA0, 4, ld_nexus ; save pointer to current Nexus
- load SCRATCHA0, 4, ld_nexus ; copy to A0
-
- move SCRATCHA0 to SFBR ;
- jump rel( next_mailbox ), if 1 ; if low-byte == 0x01 then cancelled mailbox
-
- move SCRATCHA1 | SFBR to SFBR ; if non-zero, have implicit semaphore
- move SCRATCHA2 | SFBR to SFBR
- move SCRATCHA3 | SFBR to SFBR
- jump rel( reselect_phase ), if 0 ; go to reselect_phase if empty
-
- ;*****************************************************************
- ;
- ; Something in mailbox: we have work to do
- ;
- ;*****************************************************************
-
- move kphase_SELECT to SCRATCHB0 ; set phase indicator
- store SCRATCHB0, 1, ld_phase_flag
-
- load SCRATCHB0, 4, ld_zeroes ; clr the invalid-nexus-index flag
- load SCRATCHB0, 1, DSAREL( TLQ_index ) ; get index byte from nexus
- store SCRATCHB0, 4, ld_nexus_index ; save it in local data
-
- load DSA0, 4, ld_nexus ; restore DSA register
- load SCRATCHB2, 1, DSAREL( TLQ_SCSI_ID+2 ) ; get Target's SCSI ID
- move SCRATCHB2 to SFBR
- move SFBR to SCRATCHB0 ; position it
- store SCRATCHB0, 1, ld_scsi_id ; save it
- call rel( initContext ) ; setup Sync/Wide regs in SCRATCHB
- load DSA0, 4, ld_nexus ; restore DSA register
- store SCRATCHB1, 1, DSAREL( TLQ_SCSI_ID+1 ) ; SXFER
- store SCRATCHB3, 1, DSAREL( TLQ_SCSI_ID+3 ) ; SCNTL3
-
- ;********************** select the device ********************************
- SELECT ATN from TLQ_SCSI_ID, rel( try_reselect ) ; ************************
- ;*************************************************************************
-
- ; looking good - clear the mailbox:
-
-next_mailbox:
- load SCRATCHA0, 4, ld_zeroes ; zero out scratch register A
- load DSA0, 4, ld_sched_mlbx_base_adr ; load base physical address of mailboxes
-clear_mailbox:
- store SCRATCHA0, 4, DSAREL( 0 ) ; *** Patched offset. Zero the mailbox
-
- ; Update the index to the mailbox circular list:
- load SCRATCHB0, 1, ld_counter ; get counter (mailbox index)
- move SCRATCHB0 + 1 to SCRATCHB0 ; add 1
- store SCRATCHB0, 1, ld_counter ; put it back
-
- load SCRATCHB0, 1, ld_nexus ; if low-byte == 0x01 then cancelled mailbox
- move SCRATCHB0 to SFBR
- jump rel( select_phase ), if 1
-
-; *** FALL THROUGH TO phase_handler ***
-
-
- ;*****************************************************************
- ;
- ; Phase_handler
- ; The phase handler script is a dispatcher function of SCSI phase
- ;
- ;*****************************************************************
-
-phase_handler:
- load DSA0, 4, ld_nexus ; reload DSA
- jump rel( command_phase ), when CMD ; wait for REQ
- jump rel( data_out_phase ), if DATA_OUT ; already latched REQ signal
- jump rel( message_out_phase ), if MSG_OUT
- jump rel( data_in_phase ), if DATA_IN
- jump rel( status_phase ), if STATUS
- jump rel( message_in_phase ), if MSG_IN
- int unknown_phase
-
-
- ;*****************************************************************
- ;
- ; Message-Out phase
- ;
- ;*****************************************************************
-
-message_out_phase:
- move kphase_MSG_OUT to SCRATCHB0 ; Set phase indicator
- store SCRATCHB0, 1, ld_phase_flag
-
- move from TLQ_MSGOp, when MSG_OUT ; put out the message(s)
- jump rel( phase_handler )
-
-
- ; issueMessageOut - Driver entry point for Sync/Wide negotiation and
- ; to issue message Reject:
-
-issueMessageOut:
- set ATN ; tell Target we have something to say
- clear ACK
- jump rel( message_out_phase ), when MSG_OUT ; wait for REQ. Jump if msg-out phase.
- jump rel( phase_handler ), if not MSG_IN ; jump if weird phase
- move 1, ld_scratch+1, when MSG_IN ; dump the msg byte
- clear ACK ; accept Target's last msg-in byte
- jump rel( issueMessageOut )
-
-
- ;*****************************************************************
- ;
- ; Command phase
- ;
- ;*****************************************************************
-
-command_phase:
- move kphase_COMMAND to SCRATCHB0 ; Set phase indicator
- store SCRATCHB0, 1, ld_phase_flag
-
- clear ATN ; In case we missed the sending nego
- move FROM TLQ_CDBp, when CMD ; issue the CDB
- jump rel( phase_handler )
-
-
- ;*****************************************************************
- ;
- ; Data_out_phase
- ;
- ;*****************************************************************
-
-data_out_phase:
- move kphase_DATA_OUT to SCRATCHB0 ; Set phase indicator
- store SCRATCHB0, 1, ld_phase_flag
-
- call rel( driverXfer ) ; call driver-built CHMOV instructions
- jump rel( phase_handler ) ; if all data xfer'd, get next phase
-
-driverXfer: ; get here from data-in code also
- load SCRATCHA0, 4, DSAREL( TLQ_xferAdr )
- store SCRATCHA0, 4, doItPatch+4 ; *** patch the JUMP address
- move 0xFF to SCRATCHA1
- store SCRATCHA1, 1, DSAREL( TLQ_xferStarted )
-
-doItPatch:
- jump 0x0333 ; *** patched address
-
-
-
- ;*****************************************************************
- ;
- ; Data_in_phase
- ; 875 sets ATN if bad parity detected.
- ; Use of CHMOV instructions assures that we properly handle
- ; a leftover wide byte in the SWIDE or SODL register, depending
- ; on the data direction. This can happen in either of two conditions:
- ; 1. The Target disconnects at an odd boundary. This is
- ; extremely unlikely with disk devices.
- ; 2. The client passes either an odd buffer address or
- ; an odd transfer count. When the Target disconnects (at
- ; an even boundary, we end up with the extra wide
- ; byte in SWIDE or SODL. MacOS does this with VM on.
- ;
- ;*****************************************************************
-
-data_in_phase:
- move kphase_DATA_IN to SCRATCHB0 ; Set phase indicator
- store SCRATCHB0, 1, ld_phase_flag
-
- call rel( driverXfer ) ; call driver-built CHMOV instructions
-
- ; The driver gets interrupted if a phase mismatch occurs as when
- ; the Target goes MSG-IN with a Disconnect.
- ; The driver codes either a RETURN if the Scatter/Gather list is complete or
- ; an INT if more Scatter/Gather elements need to be generated.
- ; On the Macintosh, client programs expect extra incoming data to be dumped.
- ; For example, during boot the ROM reads 512 bytes from a 2K-byte-sector CD.
-
-bucket_loop:
- jump rel( phase_handler ), when not DATA_IN ; wait for phase, exit if changed
- CHMOV 1, ld_status, when DATA_IN ; eat a byte
- jump rel( bucket_loop ); ; keep dumping bytes
-
-
- ;*****************************************************************
- ;
- ; Status phase
- ;
- ;*****************************************************************
-
-status_phase:
- move kphase_STATUS to SCRATCHB0 ; Set phase indicator
- store SCRATCHB0, 1, ld_phase_flag
-
- move 1, ld_status, when STATUS ; Read Status byte from bus
- jump rel( phase_handler )
-
-
- ;*****************************************************************
- ;
- ; Message-In phase
- ;
- ;*****************************************************************
-
-message_in_phase:
- move kphase_MSG_IN to SCRATCHB0 ; Set phase indicator
- store SCRATCHB0, 1, ld_phase_flag
-
- move 1, ld_message, when MSG_IN ; Read byte from bus
-
- jump rel( cmdComplete ), if 0x00 ; Command Complete
- jump rel( saveDataPointer ), if 0x02 ; Save Data Pointer
- jump rel( disconnect_msg ), if 0x04 ; Disconnect
- jump rel( ignoreWideResidue ), if 0x23 ; Ignore Wide Residue
- jump rel( restoreDataPointer ), if 0x03 ; Restore Data Pointer
- jump rel( extended_msg ), if 0x01 ; Extended message
- jump rel( msg_reject ), if 0x07 ; Message Reject
- ; Identify, if 0x80-FF ; Identify + LUN
- ; simple_queue_tag, if 0x20 ; Simple Queue Tag
- ; initiate_recovery, if 0x0F ; Initiate Recovery
- ; linked_cde_complete, if 0x0A/0x0B
- int unexpected_msg ; unknown
-
-msg_reject:
- int unknown_msg_reject
-
-clearACK: ; ENTRY point to end negotiation
- clear ACK
- jump rel( phase_handler )
-
-
-
- ;*****************************************************************
- ;
- ; Ignore Wide Residue
- ;
- ;*****************************************************************
-
-ignoreWideResidue: ; this is a two byte message so snag the 2nd byte here
- clear ACK
- move 1, ld_message+1, when MSG_IN ; save residue count
- move SFBR to SCRATCHB2 ; byte is still in SFBR. Position it.
- store SCRATCHB2, 1, DSAREL( TLQ_IWR ) ; Store residue count in Nexus for driver.
- clear ACK
- jump rel( phase_handler )
-
-
- ;*****************************************************************
- ;
- ; Extended message
- ; Accept Wide and Synchronous Data Transfer messages
- ;
- ;*****************************************************************
-
-extended_msg:
- clear ACK
- move 1, ld_message+1, when MSG_IN ; read msg length byte from bus
- clear ACK
- move 1, ld_message+2, when MSG_IN ; read ext msg code from bus
- clear ACK
- ; extended_identify, IF 0x02
- ; modify_data_pointer, if 0x00
- jump rel( sdtr ), if 0x01 ; jump if SDTR, sync negotiation msg
- jump rel( wdtr ), if 0x03 ; jump if WDTR, wide negotiation msg
- int unexpected_ext_msg ; let driver deal with unknown
-
-
- ;*****************************************************************
- ;
- ; Command complete
- ; The Command-Complete message is sent to indicate that the
- ; IO operation has completed and valid status has been sent.
- ; The Target should then disconnect.
- ; SCRIPTS must spin until the IOdone mailbox is empty.
- ; Then it sets the IOdone mailbox with the current Nexus.
- ; The status message is analyzed.
- ; If status is good, INTF the driver and jump to select_phase.
- ; If status is NG, save it in the NEXUS and INT the driver.
- ;
- ;*****************************************************************
-
-cmdComplete:
- move kphase_CMD_COMPLETE to SCRATCHB0 ; Set phase indicator
- store SCRATCHB0, 1, ld_phase_flag
-
- move SCNTL2 & 0X7F to SCNTL2 ; Clr SDU: SCSI Disconnect Unexpected
- clear ACK
- WAIT DISCONNECT
-
-testMbxLp: ; loop until IOdone mailbox empty
- load SCRATCHA0, 4, ld_IOdone_mailbox
- move SCRATCHA3 to SFBR ; A3 = semaphore
- jump rel( testMbxLp ), if not 0
-
- ; Fill in the IOdone mailbox with the following:
- ; A0 = index to Nexus
- ; A1 = Status
- ; A2 = 0
- ; A3 = semaphore (FF = set)
- load SCRATCHA0, 1, ld_nexus_index ; A0 = index to Nexus
- load SCRATCHB0, 1, ld_status
- move SCRATCHB0 to SFBR
- move SFBR to SCRATCHA1 ; A1 = Status
- move 0x00 to SCRATCHA2 ; A2 = 0
- move 0xFF to SCRATCHA3 ; A3 = semaphore IOdone mailbox
- store SCRATCHA0, 4, ld_IOdone_mailbox
-
- move SCRATCHA1 to SFBR ; Test the Status of this IO
- ; SFBR = status msg
- ; Test status - If good, Interrupt on the fly and jump to select phase
- intfly 0xFF, if 0 and mask 0xC1 ; mask off reserved bits
- jump rel( select_phase ), if 0 and mask 0xC1
- int status_error ; Status err. Interrupt driver & stop
-
-
- ;*****************************************************************
- ;
- ; Disconnect
- ; The 8xx Accepts the disconnection and jumps to the select_phase
- ; to check for another IO
- ;
- ;*****************************************************************
-
-disconnect_msg:
- load SCRATCHB0, 1, ld_phase_flag
- move SCRATCHB0 to SFBR
- ; If we got here from reselect just bailout since ld_nexus is
- ; not setup and the code using it is not needed anyway (no data xfer)
- jump rel( bailout ), if kphase_RESELECT
-
- move kphase_DISCONNECT to SCRATCHB0
- store SCRATCHB0, 1, ld_phase_flag
-
-bailout:
- move 0xFF to SCRATCHB3 ; invalidate nexus index for driver
- store SCRATCHB3, 1, ld_nexus_index+3
- move SCNTL2 & 0x7F to SCNTL2 ; Clr SDU: SCSI Disconnect Unexpected
- clear ACK
- WAIT DISCONNECT ; wait for bus-free
- jump rel( select_phase ) ; go see if more to do
-
-
- ;******************************************************************
- ;
- ; ??? mlj - saveDataPointer and restoreDataPointer are incorrect.
- ; ??? They basically do nothing.
- ; Save Data Pointer
- ;
- ;*****************************************************************
-
-saveDataPointer:
- move kphase_saveDataPointer to SCRATCHB0
- store SCRATCHB0, 1, ld_phase_flag
- clear ACK
- jump rel( phase_handler )
-
-
- ;******************************************************************
- ;
- ; ??? mlj - saveDataPointer and restoreDataPointer are incorrect.
- ; ??? They basically do nothing.
- ; Restore Data Pointer
- ; The local values still blocks, still bytes and data address
- ; must be loaded from the corresponding NEXUS data set.
- ; This message should followed an IDE (parity error)
- ;
- ;*****************************************************************
-
-restoreDataPointer:
- move kphase_restoreDataPointer to SCRATCHB0
- store SCRATCHB0, 1, ld_phase_flag
- clear ACK
- jump rel( phase_handler )
-
-
- ;*****************************************************************
- ;
- ; Synchronous data transfer request or response
- ;
- ;*****************************************************************
-sdtr:
- move 2, ld_message+3, when MSG_IN ; Read period & offset from bus
- int negotiateSDTR
-
-
- ;***************************************************************************
- ;
- ; Wide Data Transfer request or response
- ;
- ;***************************************************************************
-wdtr:
- move 1, ld_message+3, when MSG_IN ; get Transfer Width Exponent fm bus
- int negotiateWDTR
-
-
- ;*****************************************************************
- ;
- ; Reselect phase
- ; The chip waits here either for a Reselection from a Target or
- ; a SIGP from the driver indicating something in the mailbox.
- ; If reselected, the script uses the Nexus value which is either
- ; a Tag or a SCSI ID/LUN combo to lookup the Nexus.
- ; Then init the SXFER and SCNTL3 registers from the device config table.
- ;
- ;*****************************************************************
-
-try_reselect: ; Select failed - probably reselecting
- ; Cf NCR Errata Listing 117 Item 1:
- move SCNTL0 & 0xDF to SCNTL0 ; clr Start bit
- move CTEST2 | 0x00 to CTEST2 ; Clear SIGP bit from ISTAT reg
-
-reselect_phase:
- move kphase_RESELECT to SCRATCHB0 ; Set phase indicator
- store SCRATCHB0, 1, ld_phase_flag
-
- move 0xFF to SCRATCHB3 ; invalidate nexus index for driver
- store SCRATCHB3, 1, ld_nexus_index+3
-
- ; wait here for reselect from a Target
- ; or SIGP from the driver
-
- WAIT RESELECT REL( select_phase ) ; jump if SIGP
-
- ; Reselected:
-
- move SSID to SFBR ; SSID = [ Valxxx Scsi_id ]
- int unknown_reselect, if 0 and mask 0x7F; Interrupt if VAL bit not set
- move SFBR & 0x0F to SCRATCHB0 ; B0 = Target ID
- store SCRATCHB0, 1, ld_scsi_id ; save it
-
- call rel( initContext ) ; setup sync regs here
-
- int no_msgin_after_reselect, when not MSG_IN
-
- move 1, ld_message, when MSG_IN ; Read Identify byte from bus
-
- ; if another REQ is asserted, a SimpleQueueTag message should be next
-
- clear ACK ; notify Target: msg byte rx'd
- jump rel( getNextMsg ), when MSG_IN ; jump if SimpleQueueTag coming
-
- ; untagged operation:
-
- move SFBR & 0x07 to SCRATCHA0 ; isolate LUN from Identify byte
-
- load SCRATCHB0, 1, ld_scsi_id ; B0 = Target ID
- clear CARRY
- move SCRATCHB0 SHL SFBR ; shift left #1
- move SFBR SHL SCRATCHB0 ; shift left #2
- move SCRATCHB0 SHL SFBR ; shift left #3
- move SCRATCHA0 | SFBR to SCRATCHA0 ; form Nexus index = 0b0TTTTLLL
-
- store SCRATCHA0, 1, ld_nexus_index ; store as index to Nexus
- jump rel( haveNexusIndex )
-
- ; should be tagged operation:
-
-getNextMsg:
- move 1, ld_message, when MSG_IN ; read message byte from bus
- jump rel( disconnect_msg ), if 0x04 ; if Disconnect, oh well.
- clear ACK
- jump rel( phase_handler ), if not 0x20; Branch if not Queue tag code
- ; get the Queue Tag and save as the nexus index
- move 1, ld_nexus_index, when MSG_IN ; Nexus index <- Tag from bus
- clear ACK ; acknowledge it
-
-haveNexusIndex:
- move 0x00 to SCRATCHB3 ; clear invalid-nexus-index flag
- store SCRATCHB3, 1, ld_nexus_index+3
- call rel( findNexusFromIndex ) ; set DSA <- Nexus pointer
- jump rel( phase_handler ) ; start handling phases.
-
-
- ;*****************************************************************
- ;
- ; AbortMailbox - Abort (or BusDeviceReset) the mailbox entry.
- ; This is a queued operation - not an immediate
- ; operation as is issueAbort_BDR.
- ; The Abort message clears all IO processes for the
- ; selecting Initiator on the specified LUN.
- ;
- ; The Bus Device Reset message clears all IO processes for
- ; all Initiators on all LUNs of selected Target.
- ; It forces a hard reset condition to the selected SCSI device.
- ;
- ; A0 = Identify byte (0xC0 + LUN N.B. Disconnect allowed)
- ; A1 = Tag, if any
- ; A2 = SCSI ID
- ; A3 = Abort code Abort=0x06; Abort Tag=0D; Bus Device Reset=0x0C
- ;
- ; Mailbox not cleared by SCRIPTS so that driver can find SCSI ID when done
- ; N.B.: Device is Async and Narrow after BDR!!!
- ; Driver must set the device config table values accordingly.
- ;*****************************************************************
-
-AbortMailbox:
- move kphase_ABORT_MAILBOX to SCRATCHB0 ; Set phase code
- store SCRATCHB0, 1, ld_phase_flag
-
- move 0xFF to SCRATCHB3 ; invalidate nexus index for driver
- store SCRATCHB3, 1, ld_nexus_index+3
-
- load SCRATCHB2, 1, ld_AbortBdr_mailbox+2 ; get SCSI ID
- store SCRATCHB2, 1, AbortSelect+2 ; *** Patch the Select/ATN instruction
-
-AbortSelect:
- SELECT ATN 0, REL( try_reselect ) ; *** Patched SCSI ID
-
- move SCRATCHA1 to SFBR ; check for Tag
- jump rel( taggedAbort ) if not 0x00 ; jump if tagged abort
-
- ; untagged Abort or BusDeviceReset:
-
- move SCRATCHA3 to SFBR ; position the abort code
- move SFBR to SCRATCHA1
- store SCRATCHA0, 2, ld_scratch ; Store Identify and Abort msgs
- move 0x00 to SCNTL2 ; Clr SDU SCSI Disconnect Unexpected
- move 2, ld_scratch , when MSG_OUT ; emit Identify and Abort messages
- WAIT DISCONNECT
- int abort_mailbox
-
- ; AbortTag:
-
-taggedAbort:
- move SCRATCHA1 to SFBR ; position the Tag
- move SFBR to SCRATCHA2
- move 0x20 to SCRATCHA1 ; gen SimpleQueueTag code
- store SCRATCHA0, 4, ld_scratch ; store Identify, SQT, Tag, AbortTag
- move 0x00 to SCNTL2 ; Clr SDU SCSI Disconnect Unexpected
- move 4, ld_scratch, when MSG_OUT ; emit all 4 bytes
- WAIT DISCONNECT
- int abort_mailbox
-
-
- ;*****************************************************************
- ;
- ; issueAbort_BDR - Abort (or BusDeviceReset) the current operation.
- ; This is an immediate operation - not a queued operation
- ; as is AbortMailbox.
- ; The Abort message clears all IO processes for the
- ; selecting Initiator on the specified LUN.
- ;
- ; The Bus Device Reset message clears all IO processes for
- ; all Initiators on all LUNs of selected Target.
- ; It forces a hard reset condition to the selected SCSI device.
- ;
- ;*****************************************************************
-
-issueAbort_BDR:
- move kphase_ABORT_CURRENT to SCRATCHB0 ; Set phase code
- store SCRATCHB0, 1, ld_phase_flag
-
- move ISTAT & 0x08 to SFBR ; see if Target connected to bus
- int abort_current, if 0 ; interrupt driver if not connected
-
- SET ATN ; get Target's attention
- load DSA0, 4, ld_nexus ; load pointer to Nexus
-
-bucketLoop:
- clear ACK
- jump rel( sendAbortBDR ), when MSG_OUT ; wait for REQ. Jump if OK.
-
- jump rel( BucketInStatus ), if STATUS ; bit bucket in
- jump rel( BucketInMsg ), if MSG_IN ; bit bucket in
- jump rel( BucketInData ), if DATA_IN ; bit bucket in
-
- move 0xAD to SCRATCHA0
- jump rel( BucketOutData ), if DATA_OUT ; bit bucket out
- jump rel( BucketOutCmd ), if CMD ; bit bucket out
- int unknown_phase ; back to driver for harsher measures
-
-
-BucketInStatus:
- move 1, ld_scratch, when STATUS ; eat the Status byte
- jump rel( bucketLoop ); ; keep bit-bucketing bytes
-
-BucketInMsg:
- move 1, ld_scratch, when MSG_IN ; eat a message byte
- jump rel( bucketLoop ); ; keep bit-bucketing bytes
-
-BucketInData:
- move 1, ld_scratch, when DATA_IN ; eat a data byte
- jump rel( bucketLoop ); ; keep bit-bucketing bytes
-
-BucketOutData:
- move SCRATCHA0 xor 0x73 to SCRATCHA0 ; gen 0xDEAD ...
- store SCRATCHA0, 1, ld_scratch
- move 1, ld_scratch, when DATA_OUT ; pad a byte out
- jump rel( bucketLoop ); ; keep bit-bucketing bytes
-
-BucketOutCmd:
- move 0x00 to SCRATCHA0 ; load Null, TestUnitReady, whatever
- store SCRATCHA0, 1, ld_scratch
- move 1, ld_scratch, when CMD ; pad a byte out
- jump rel( bucketLoop ); ; keep bit-bucketing bytes
-
-
-sendAbortBDR:
- move 0x00 to SCNTL2 ; Clr SDU SCSI Disconnect Unexpected
- move 1, ld_AbortCode, when MSG_OUT ; Send Abort(06) or BDR(0C) message
- load SCRATCHA0, 4, ld_zeroes ; load 0's
- store SCRATCHA0, 4, ld_AbortCode ; clear the Abort code
- WAIT DISCONNECT
- int abort_current ; went BusFree - tell Driver
tpCur = &target->targetParmsCurrent;
- if ( tpCur->transferWidth != 1 )
+ if ( tpCur->transferWidth > 1 )
{
reqSenseCmd->scsiCmd.cdbFlags |= kCDBFlagsNegotiateWDTR;
if (tpCur->transferOptions & kSCSITransferOptionPPR) {
long vectorNumber;
IOInterruptVector *vector;
OSData *vectorData;
- IOInterruptState interruptState;;
+ IOInterruptState interruptState;
interruptSources = nub->_interruptSources;
vectorData = interruptSources[source].vectorData;
vectorNumber = *(long *)vectorData->getBytesNoCopy();
vector = &vectors[vectorNumber];
- if (vector->interruptDisabledSoft) {
- interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
- vector->interruptDisabledSoft = 0;
- vectorsEnabled++;
+ interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
+ if (!vector->interruptDisabledSoft) {
IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
-
- if (controllerDisabled && (vectorsEnabled == vectorsRegistered)) {
- controllerDisabled = 0;
- provider->enableInterrupt(0);
- }
+ return kIOReturnSuccess;
+ }
+
+ vector->interruptDisabledSoft = 0;
+ vectorsEnabled++;
+ IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
+
+ if (controllerDisabled && (vectorsEnabled == vectorsRegistered)) {
+ controllerDisabled = 0;
+ provider->enableInterrupt(0);
}
return kIOReturnSuccess;
long vectorNumber;
IOInterruptVector *vector;
OSData *vectorData;
- IOInterruptState interruptState;;
+ IOInterruptState interruptState;
interruptSources = nub->_interruptSources;
vectorData = interruptSources[source].vectorData;
vectorNumber = *(long *)vectorData->getBytesNoCopy();
vector = &vectors[vectorNumber];
+ interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
if (!vector->interruptDisabledSoft) {
- interruptState = IOSimpleLockLockDisableInterrupt(controllerLock);
vector->interruptDisabledSoft = 1;
#if __ppc__
sync();
isync();
#endif
vectorsEnabled--;
- IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
}
+ IOSimpleLockUnlockEnableInterrupt(controllerLock, interruptState);
if (!getPlatform()->atInterruptLevel()) {
while (vector->interruptActive);
*/
const char * gIOKernelKmods =
"{
- 'com.apple.kernel' = '5.3';
- 'com.apple.kernel.bsd' = '5.3';
- 'com.apple.kernel.iokit' = '5.3';
- 'com.apple.kernel.libkern' = '5.3';
- 'com.apple.kernel.mach' = '5.3';
+ 'com.apple.kernel' = '5.4';
+ 'com.apple.kernel.bsd' = '5.4';
+ 'com.apple.kernel.iokit' = '5.4';
+ 'com.apple.kernel.libkern' = '5.4';
+ 'com.apple.kernel.mach' = '5.4';
'com.apple.iokit.IOADBFamily' = '1.1';
'com.apple.iokit.IOSystemManagementFamily' = '1.1';
}";
iokit/Drivers/platform/drvAppleGrandCentral/GrandCentral.cpp optional disabled-iokitcpp
iokit/Drivers/platform/drvAppleOHare/OHare.cpp optional iokitcpp
-# Symbios 8xx SCSI Driver
-#iokit/Drivers/scsi/drvSymbios8xx/Sym8xxClient.cpp optional iokitcpp
-#iokit/Drivers/scsi/drvSymbios8xx/Sym8xxExecute.cpp optional iokitcpp
-#iokit/Drivers/scsi/drvSymbios8xx/Sym8xxInit.cpp optional iokitcpp
-#iokit/Drivers/scsi/drvSymbios8xx/Sym8xxMisc.cpp optional iokitcpp
# ATA driver
#iokit/Drivers/ata/drvAppleUltra66ATA/AppleUltra66ATA.cpp optional iokitcpp