📄 ncr710lib.c
字号:
/* ncr710Lib.c - NCR 53C710 SCSI I/O Processor (SIOP) library (SCSI-1) *//* Copyright 1989-1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02v,11jan99,aeg added semTerminate () in ncr710StepEnable1 () when disabling.02u,26aug98,sut renamed ncr710StepEnable into ncr710StepEnable1 ; in ncr710CtrlCreate added support to use ncr710StepEnable1 as the ncr710StepEnable see also ncr710CommLib.c02t,24aug98,sut renamed ncr710SingleStep into ncr710SingleStep1 ; in ncr710CtrlCreate added support to use ncr710SingleStep1 as the ncr710SingleStep see also ncr710CommLib.c02s,12sep97,dds SPR # 4831: changing clock frequency value has no effect on the DCNTL register.02r,03may96,jds and more doc tweaks...02q,01may96,jds yet more doc tweaks...02p,08nov95,jds more doc tweaks.02o,13feb95,jdi doc tweak.02n,07nov94,jds incorporated Carl's patch for cache coherency (spr 2210)02m,23feb93,jdi documentation cleanup.02l,10feb93,ccc fixed cache problem and null pointers (spr 1995).02k,26sep92,ccc doc changes.02j,18aug92,ccc fixed warnings.02i,31jul92,dnw Changed to new cacheLib. Added requirement that dma cache be write coherent and removed corresponding flushes.02h,20jul92,eve Move debug macros from ncr710.h.02g,20jul92,eve Added cache support for 5.1. 02f,18jul92,smb Changed errno.h to errnoLib.h.02e,13jul92,eve Make a single exit process both for OK and ERROR in ncr710ScsiPhase() and create ncr710CheckStatRegs().02d,11jul92,eve Suppress ncr710CmdBuild() since scsiCmdBuild() is public in scsiLib.c.Suppress ncr710Relocation() routine.02c,02jul92,eve start ANSI modifications.02b,21apr92,eve Add disconnect capability.02a,03mar92,eve Add the process for new bit in the ncr710HwRegister() and suppress access to the EA bit in the other routines. 01n,20feb92,eve Change the clock frequency parameter by a value like xxns * 100 in ncr710CtrlCreate().01m,12jan91,eve Add support for sync transfer capability.01l,10dec91,eve Correct bug in ncr710ScsiPhase() regarding the Bus fault Wtd timeout and illegal instruction.01k,29nov91,eve Change semTake timeout in ncr710StartPhase().01j,29nov91,eve Correct use of pDevToSelect,suppress initialisation devSync semaphore in ncr710HwInit().01i,07nov91,eve Perform a select with attention in ncr710ScsiPhase() if useIdentify is set.01h,01nov91,ccc Documentation changes, changed modification numbers.01g,01nov91,eve Suppress pccchip2 include01f,27oct91,eve Suppress regOffset argument in ncr710CtlrCreate(), the chip need to be connected to all of the address bus (31-0).01e,27oct91,eve Add ncr710SetHwRegister() routine.01d,25oct91,eve Allocate dynamicly ncrCtlShare data structure keep only a pointer in SIOP info.01c,24oct91,eve Change clockPeriod by a frequency value in ncr710CtrlCreate().01b,24oct91,eve Try to cleaning up documentation.01a,23oct91,eve Created. *//*DESCRIPTIONThis is the I/O driver for the NCR 53C710 SCSI I/O Processor (SIOP).It is designed to work with scsi1Lib. It also runs inconjunction with a script program for the NCR 53C710 chip.This script uses the NCR 53C710 DMA function for data transfers.This driver supports cache functions through cacheLib.USER-CALLABLE ROUTINESMost of the routines in this driver are accessible only through the I/Osystem. Three routines, however, must be called directly: ncr710CtrlCreate()to create a controller structure, and ncr710CtrlInit() to initialize it.The NCR 53C710 hardware registers need to be configured according tothe hardware implementation. If the default configuration is not proper,the routine ncr710SetHwRegister() should be used to properly configurethe registers.INTERNALThis driver supports the connect/disconnect capability. But this feature is invalidated in the driver code in ncr710CtrlInit() :.CS /@ disconnect is supported for now,but this feature is not included @ in this revision. @/ pSiop->scsiCtrl.disconnect = FALSE; /@ TRUE to support disconnect @/; .CE To validate the disconnect, this field must be set to TRUE (and recompile)and the field <pScsiPhysDev->useIdentify> must be also set to TRUE.It also support the synchronous message. The new scsiSyncTarget() routine in the scsiLib could be use to set up a synchronous protocol between the targetand the initiator.There are debug variables to trace events in the driver.<scsiDebug> scsiLib debug variable, trace event in scsiLib, ncr710ScsiPhase(),and ncr710ScsiTransact().<scsiIntsDebug> prints interrupt informations.<ncr710LogErr> print out error case and dump the ncr710 register contents.<ncr710Debug> Print out informations during the SCSI transaction. INCLUDE FILESncr710.h, ncr710_1.h, ncr710Script.h, ncr710Script1.hSEE ALSO: scsiLib, scsi1Lib, cacheLib,.I "NCR 53C710 SCSI I/O Processor Programming Guide,".pG "I/O System"*/#include "vxWorks.h"#include "memLib.h"#include "ctype.h"#include "stdlib.h"#include "string.h"#include "stdio.h"#include "logLib.h"#include "semLib.h"#include "ioLib.h"#include "errnoLib.h"#include "cacheLib.h"#include "taskLib.h"#include "drv/scsi/ncr710.h"#include "drv/timer/timerDev.h"/* defines */typedef NCR_710_SCSI_CTRL SIOP;#define SIOP_MAX_XFER_LENGTH ((UINT) (0x00ffffff)) /* max data xfer length *//* Time out used in the semtake in the driver. Because this is a global value * that not a good way to handle a time out for a scsi command. This should * be done in the scsiLib for each command running and processed by the * driver during the devSync semTake(). */ #define DEF_TIMEOUT 0x1000000/* ncr710 debug level */ #define NCR710_MSG \ printErr#define NCR710_DEBUG_MSG \ if (ncr710Debug) \ NCR710_MSG /* screen log error at task level */#define LOG_ERR\ if (ncr710LogErr == 1)\ printErr #define LOG_ERR_CTXT \ if (ncr710LogErr == 1) ncr710Show((SCSI_CTRL *)pSiop) /* ncr710 debug phase mismatch level */#define NCR710_MM_MSG\ logMsg #define NCR710_MISMATCH_MSG\ if (ncr710MmatchLog == 1)\ NCR710_MM_MSG/* External */IMPORT BOOL scsiDebug;IMPORT BOOL scsiIntsDebug;IMPORT UINT relocation; /* relocation table information */IMPORT UINT selWithAtn_idx; /* index for the first entry point */IMPORT UINT waitSelect; /* Idle script entry point */IMPORT UINT selWithAtn; /* First scsi Script routine atn set */IMPORT UINT selWithoutAtn; /* First scsi Script routine ,no atn */IMPORT UINT ackMsg1; /* retry entry Script routine for extended msg */ /* before a data phase */IMPORT UINT ackMsg3; /* retry entry Script routine msg after data */ /* phase */IMPORT UINT checkPhData; /* Entry Script routine to ack a message */ /* after a data phase and look for the next */ /* phase. */IMPORT UINT ackAtnMsg; /* Entry Script routine to send a msg out */ IMPORT UINT endAbort; /* Entry Script when a msg out as reset */ /* device is send */ IMPORT UINT asortPh; /* Entry script to sort phase before data */ /* phase */IMPORT UINT checkNewCmd; /* Entry point to start a new cmd at intr lvl */ IMPORT UINT *script_ptr[]; /* table of all entry in the script */IMPORT VOIDFUNCPTR ncr710SingleStepRtn; /* Single step routine */IMPORT VOIDFUNCPTR ncr710StepEnableRtn; /* Single step routine *//* This part allow to log some information at interrupt level. That a * conditionnal compile feature. This is useful to keep track of * disconnect/reconnect operation at interrupt level. * A show routine, ncr710LogShow() print and increment the <pLogMemShow> * pointer. */#if FALSE /* FALSE to disable interrupt log memory trace * at the compile time. *//* To enable interrupt log memory capability at the compile time. Allocated * memory with a malloc (size set by LOG_SIZE_MEM) and assign this return * value to <pNcr710Deb>, and pLogMemCount, set ncr710LogMem to 1, and * ncr710LogCount to 0 .*/#define NCR710_INT_LOG_MEM#endif /* TRUE/FALSE */ #ifdef NCR710_INT_LOG_MEM /* Interrupt trace enabled */ #define LOG_SIZE_MEM 0x10000 /* Memory log size */int ncr710LogMem = 0; /* enable/disable memory log at the run time */UINT *pNcr710Deb; /* pointer to the beginning of log memory */ /* array */UINT *pLogMemShow; /* internal pointer for incremental show of */ /* log memory */int ncr710LogCount = 0; /* memory log fifo counter *//* macro to write memory log element */#define LOG_MEM(s) \ *(pNcr710Deb + ncr710LogCount)= s; \ ncr710LogCount++; \ if (ncr710LogCount >= (LOG_SIZE_MEM /4))\ ncr710LogCount = 0;#define LOG_MEM_INTR\ if (ncr710LogMem == 1) \ { \ LOG_MEM((UINT)ncr710CountIntr) \ LOG_MEM((UINT)ncr710LogCount) \ LOG_MEM(*pSiop->pDsps) \ LOG_MEM((UINT)(*pSiop->pScratch3)) \ LOG_MEM((UINT)pSiop->pNcrCtl) \ LOG_MEM((UINT)pSiop->pNcrCtlCmd) \ LOG_MEM((UINT)pScsiPhysDev) \ LOG_MEM((UINT)pSiop->pNcrCtl->pScsiPhysDev) \ LOG_MEM((UINT)pSiop->pNcrCtl->pData) \ LOG_MEM(pSiop->pNcrCtl->dataCount) \ LOG_MEM((UINT)pSiop->commandRequest) \ LOG_MEM((UINT)(*pSiop->pScratch0)) \ LOG_MEM((UINT)(*pSiop->pSbcl)) \ LOG_MEM((UINT)(*pSiop->pSdid)) \ LOG_MEM((UINT)(*pSiop->pIstat)) \ LOG_MEM((UINT)(0x99999999)) \ }#endif /* NCR710_INT_LOG_MEM *//* variables */ TBOOL siopSStep; /* Global state of single step script */ /* execution */int ncr710CountIntr = 0; /* Global interrupt counter *//* Debug variables use by the debug macros */int ncr710Debug = 0; /* <1> enable debug msg */int ncr710MmatchLog = 0; /* <1> enable mismatch screen log (int lvl) */int ncr710LogErr = 0; /* <1> enable print task level screen error * log (task lvl). *//* default timeout value use in semTake (devSyncSem.. */int ncr710TimeOut = DEF_TIMEOUT; /* forward declarations */LOCAL void ncr710SelTimeOutCvt (SCSI_CTRL *pScsiCtrl,UINT timeOutInUsec, UINT *pTimeOutSetting);LOCAL void ncr710ScsiBusReset (SIOP *pSiop);LOCAL STATUS ncr710ScsiTransact(SCSI_PHYS_DEV *pScsiPhysDev, SCSI_TRANSACTION *pScsiXaction);LOCAL STATUS ncr710ScsiPhase(SCSI_PHYS_DEV *pScsiPhysDev, SCSI_TRANSACTION *pScsiXaction);STATUS ncr710SetHwRegister (SIOP *pSiop, NCR710_HW_REGS *pHwRegs);LOCAL void ncr710HwInit (SIOP *pSiop);LOCAL STATUS ncr710SyncMsgConvert (SCSI_PHYS_DEV *pScsiPhysDev, UINT8 *pMsgIn, int *pSyncVal, int *pOffsetVal); LOCAL UINT *ncr710RejectRecv (SIOP *pSiop, SCSI_PHYS_DEV *pScsiPhysDev, NCR_CTL *pNcrCtl);LOCAL UINT *ncr710ExtMsgRecv (SIOP *pSiop, SCSI_PHYS_DEV *pScsiPhysDev, NCR_CTL *pNcrCtl, UINT8 *msgIn);LOCAL UINT *ncr710PhaseMismatch (SIOP *pSiop, SCSI_PHYS_DEV *pScsiPhysDev, NCR_CTL *pNcrCtl, UINT phaseRequested);LOCAL STATUS ncr710BuildMsgOut (SCSI_PHYS_DEV *pScsiPhysDev);LOCAL STATUS ncr710FirstStartPhase (SIOP *pSiop, NCR_CTL *pNcrCtl, SCSI_PHYS_DEV *pScsiPhysDev, int timeOut); LOCAL STATUS ncr710StartPhase (SIOP *pSiop, NCR_CTL *pNcrCtl, UINT *scriptAddress, int timeOut); LOCAL void ncr710StartScript (SIOP *pSiop, NCR_CTL *pNcrCtl, SCSI_PHYS_DEV *pScsiPhysDev, UINT *scriptEntry);LOCAL STATUS ncr710CheckStatRegs (SIOP *pSiop, SCSI_PHYS_DEV *pScsiPhysDev, UINT *localStart);LOCAL void ncr710FlushCache (SIOP *pSiop, NCR_CTL *pNcrCtl);LOCAL void ncr710SingleStep1 (SIOP* pSiop);LOCAL void ncr710StepEnable1 (SIOP* pSiop, BOOL boolValue);/********************************************************************************* ncr710CtrlCreate - create a control structure for an NCR 53C710 SIOP** This routine creates an SIOP data structure and must be called before* using an SIOP chip. It should be called once and only once for a * specified SIOP. Since it allocates memory for a structure needed by all* routines in ncr710Lib, it must be called before any other routines in the* library. After calling this routine, ncr710CtrlInit() should be called* at least once before any SCSI transactions are initiated using the SIOP.** A detailed description of the input parameters follows:* .iP <baseAdrs> 4* the address at which the CPU accesses the lowest * register of the SIOP.* .iP <freqValue>* the value at the SIOP SCSI clock input. This is used to determine * the clock period for the SCSI core of the chip and the synchronous* divider value for synchronous transfer.* It is important to have the right timing on the SCSI bus.* The <freqValue> parameter is defined as the SCSI clock input value, in * nanoseconds, multiplied by 100. Several <freqValue> constants are * defined in ncr710.h as follows:* .CS* NCR710_1667MHZ 5998 /@ 16.67Mhz chip @/* NCR710_20MHZ 5000 /@ 20Mhz chip @/* NCR710_25MHZ 4000 /@ 25Mhz chip @/* NCR710_3750MHZ 2666 /@ 37.50Mhz chip @/* NCR710_40MHZ 2500 /@ 40Mhz chip @/* NCR710_50MHZ 2000 /@ 50Mhz chip @/* NCR710_66MHZ 1515 /@ 66Mhz chip @/* NCR710_6666MHZ 1500 /@ 66.66Mhz chip @/* .CE** RETURNS: A pointer to the NCR_710_SCSI_CTRL structure, or NULL if memory * is insufficient or parameters are invalid. */NCR_710_SCSI_CTRL *ncr710CtrlCreate ( UINT8 *baseAdrs, /* base address of the SIOP */ UINT freqValue /* clock controller period (nsec*100) */ ) { FAST SIOP *pSiop; /* ptr to SIOP info */ FAST NCR_CTL_CTXT *pNcrCtxt; /* ptr to SIOP context */ /* local dependant hardware registers values */ static NCR710_HW_REGS hwRegs = DEFAULT_710_HW_REGS; /* SingleStep routine selection */ ncr710SingleStepRtn = ncr710SingleStep1; ncr710StepEnableRtn = ncr710StepEnable1; /* verify parameters */ if (baseAdrs == ((UINT8 *) NULL)) return ((SIOP *) NULL); if ((freqValue > NCR710_1667MHZ) || (freqValue < NCR710_6666MHZ)) return ((SIOP *) NULL); /* check that dma buffers are write coherent */ if (!CACHE_DMA_IS_WRITE_COHERENT () || !CACHE_DMA_IS_READ_COHERENT ()) { printf ("\nshared memory not cache coherent\n"); return ((SIOP *) NULL); } /* calloc the controller info structure; return ERROR if unable */ pSiop = (SIOP *) cacheDmaMalloc (sizeof (SIOP)); if (pSiop == (SIOP *) NULL) return ((SIOP *) NULL); bzero ((char *) pSiop, sizeof (SIOP));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -