📄 ncr810lib.c
字号:
pSiop->pCtest2 = baseAdrs + OFF_CTEST2; pSiop->pCtest3 = baseAdrs + OFF_CTEST3; pSiop->pTemp = (UINT *) (baseAdrs + OFF_TEMP); pSiop->pDfifo = baseAdrs + OFF_DFIFO; pSiop->pCtest4 = baseAdrs + OFF_CTEST4; pSiop->pCtest5 = baseAdrs + OFF_CTEST5; pSiop->pCtest6 = baseAdrs + OFF_CTEST6; pSiop->pDbc = (UINT *) (baseAdrs + OFF_DBC); pSiop->pDcmd = baseAdrs + OFF_DCMD; pSiop->pDnad = (UINT *) (baseAdrs + OFF_DNAD); pSiop->pDsp = (UINT *) (baseAdrs + OFF_DSP); pSiop->pDsps = (UINT *) (baseAdrs + OFF_DSPS); pSiop->pScratcha0 = baseAdrs + OFF_SCRATCHA0; pSiop->pScratcha1 = baseAdrs + OFF_SCRATCHA1; pSiop->pScratcha2 = baseAdrs + OFF_SCRATCHA2; pSiop->pScratcha3 = baseAdrs + OFF_SCRATCHA3; pSiop->pDmode = baseAdrs + OFF_DMODE; pSiop->pDien = baseAdrs + OFF_DIEN; pSiop->pDwt = baseAdrs + OFF_DWT; pSiop->pDcntl = baseAdrs + OFF_DCNTL; pSiop->pAdder = (UINT *) (baseAdrs + OFF_ADDER); pSiop->pSien0 = baseAdrs + OFF_SIEN0; pSiop->pSien1 = baseAdrs + OFF_SIEN1; pSiop->pSist0 = baseAdrs + OFF_SIST0; pSiop->pSist1 = baseAdrs + OFF_SIST1; pSiop->pSlpar = baseAdrs + OFF_SLPAR; pSiop->pMacntl = baseAdrs + OFF_MACNTL; pSiop->pGpcntl = baseAdrs + OFF_GPCNTL; pSiop->pStime0 = baseAdrs + OFF_STIME0; pSiop->pStime1 = baseAdrs + OFF_STIME1; pSiop->pRespid = baseAdrs + OFF_RESPID; pSiop->pStest0 = baseAdrs + OFF_STEST0; pSiop->pStest1 = baseAdrs + OFF_STEST1; pSiop->pStest2 = baseAdrs + OFF_STEST2; pSiop->pStest3 = baseAdrs + OFF_STEST3; pSiop->pSidl = (UINT16 *) (baseAdrs + OFF_SIDL); pSiop->pSodl = (UINT16 *) (baseAdrs + OFF_SODL); pSiop->pSbdl = (UINT16 *) (baseAdrs + OFF_SBDL); pSiop->pScratchb = (UINT *) (baseAdrs + OFF_SCRATCHB); pSiop->devType = devType; pSiop->clkPeriod = clkPeriod; /* * Initialise hardware-dependent registers to default values. */ bcopy ((char *)&ncr810HwRegs, (char *)&pSiop->hwRegs, sizeof (NCR810_HW_REGS)); /* * Create synchronisation semaphore for single-step support */ if ((pSiop->singleStepSem = semBCreate(ncr810SingleStepSemOptions, SEM_EMPTY)) == NULL) { SCSI_MSG ("ncr810CtrlCreate: semBCreate of singleStepSem failed.\n" ,0, 0, 0, 0, 0, 0); goto failed; } /* * Initialise controller state variables */ pSiop->state = NCR810_STATE_IDLE; pSiop->cmdPending = FALSE; /* * Initialize fixed fields in client shared data area */ ncr810SharedMemInit (pSiop, pSiop->pClientShMem); /* * Identification thread has been created by the generic initialisation. * Initialise it for use with the NCR 53C810. */ ncr810IdentThreadInit ((NCR810_THREAD *) pScsiCtrl->pIdentThread); /* spawn SCSI manager - use generic code from "scsiLib.c" */ pScsiCtrl->scsiMgrId = taskSpawn (ncr810ScsiTaskName, ncr810ScsiTaskPriority, ncr810ScsiTaskOptions, ncr810ScsiTaskStackSize, (FUNCPTR) scsiMgr, (int) pSiop, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (pScsiCtrl->scsiMgrId == ERROR) { SCSI_MSG ("ncr810CtrlCreate: can't spawn SCSI manager task\n", 0, 0, 0, 0, 0, 0); goto failed; } return (pSiop);failed: if (pSiop->singleStepSem != NULL) (void) semDelete (pSiop->singleStepSem); (void) cacheDmaFree ((char *) pSiop); return (NULL); }/********************************************************************************* ncr810CtrlInit - initialize a control structure for the NCR 53C8xx SIOP** This routine initializes an SIOP structure, after the structure is created* with ncr810CtrlCreate(). This structure must be initialized before the* SIOP can be used. It may be called more than once if needed; however,* it must only be called while there is no activity on the SCSI interface.** A detailed description of the input parameters follows:* .iP <pSiop>* a pointer to the NCR_810_SCSI_CTRL structure created with* ncr810CtrlCreate().* .iP <scsiCtrlBusId>* the SCSI bus ID of the SIOP. Its value is somewhat arbitrary: seven (7),* or highest priority, is conventional. The value must be in the range 0 - 7.** RETURNS: OK, or ERROR if parameters are out of range.*/STATUS ncr810CtrlInit ( FAST NCR_810_SCSI_CTRL *pSiop, /* ptr to SIOP struct */ int scsiCtrlBusId /* SCSI bus ID of this SIOP */ ) { SCSI_CTRL * pScsiCtrl = (SCSI_CTRL *) pSiop; volatile int delay; /* * Validate parameters */ if (pSiop == (SIOP *)NULL) return (ERROR); /* * Validate and set bus ID */ if (scsiCtrlBusId < SCSI_MIN_BUS_ID || scsiCtrlBusId > SCSI_MAX_BUS_ID) return (ERROR); pScsiCtrl->scsiCtrlBusId = scsiCtrlBusId; /* * Initialise the SIOP */ ncr810HwInit (pSiop); delay = ncr810DelayCount; ncr810DelayCount *= 35; /* First delay must be longer */ ncr810ScriptStart (pSiop, (NCR810_THREAD *) pScsiCtrl->pIdentThread, NCR810_SCRIPT_WAIT); pSiop->state = NCR810_STATE_PASSIVE; ncr810DelayCount = delay; /* Restore original delay count */ return (OK); }/********************************************************************************* ncr810HwInit - initialize the SIOP chip to a known state** This routine puts the SIOP into a known quiescent state. Because the value* of some registers depend upon the hardware implementation of the chip you * may have to use ncr810SetHwRegister() to adjust them.** This routine does not touch the bits in registers that are set by * the ncr810SetHwRegister() routine.** See the NCR 53C810 Data Manual for fuller details of the registers* programmed by this routine.** SEE ALSO * ncr810SetHwRegister()** NOMANUAL*/LOCAL void ncr810HwInit ( FAST SIOP *pSiop /* ptr to an SIOP info structure */ ) { UINT clkPeriod; /* * Software reset the SIOP */ NCR810_OUT_BYTE(pSiop->pIstat, ISTAT_SOFTRST); taskDelay (2); NCR810_OUT_BYTE(pSiop->pIstat, 0); /* clear the software reset */ /* * Initialise hardware-dependent registers */ ncr810SetHwRegister (pSiop, &pSiop->hwRegs); /* * DMA mode, control and watchdog timer registers * * Use manual start and NCR 53C700 compatibility mode. * Set clock conversion factor (the clkPeriod has been checked in * "ncr810CtrlCreate()") and save async clock period for use by * "ncr810XferParamsCvt()". Disable the watchdog timer. * * Note: * Manual Start Mode. Setting this bit prevents automatic fetching and * execution of scripts when the DSP register is written. */ CACHE_PIPE_FLUSH(); NCR810_OUT_BYTE(pSiop->pDmode, NCR810_IN_BYTE(pSiop->pDmode) | DMODE_MAN); /* NCR 53C700 Compatability is turned off */ CACHE_PIPE_FLUSH(); NCR810_OUT_BYTE(pSiop->pDcntl, NCR810_IN_BYTE(pSiop->pDcntl) | DCNTL_COM); clkPeriod = pSiop->clkPeriod; if (clkPeriod >= NCR810_25MHZ) /* 16.67 - 25.00 MHz */ { /* set the async and sync period to be the same */ pSiop->clkDiv = NCR810_16MHZ_ASYNC_DIV; NCR810_OUT_BYTE(pSiop->pScntl3, NCR810_16MHZ_ASYNC_DIV); } else if (clkPeriod >= NCR810_3750MHZ) /* 25.01 - 37.50 MHz */ { /* set the async and sync period to be the same */ pSiop->clkDiv = NCR810_25MHZ_ASYNC_DIV; NCR810_OUT_BYTE(pSiop->pScntl3, NCR810_25MHZ_ASYNC_DIV); } else if (clkPeriod >= NCR810_50MHZ) /* 37.51 - 50.00 MHz */ { /* set the async and sync period to be the same */ pSiop->clkDiv = NCR810_50MHZ_ASYNC_DIV; NCR810_OUT_BYTE(pSiop->pScntl3, NCR810_50MHZ_ASYNC_DIV); } else /* (clkPeriod >= NCR810_6666MHZ) */ /* 50.01 - 66.67 MHz */ { /* set the async and sync period to be the same */ pSiop->clkDiv = NCR810_66MHZ_ASYNC_DIV; NCR810_OUT_BYTE(pSiop->pScntl3, NCR810_66MHZ_ASYNC_DIV); } /* * SCSI control registers * * If disconnect/reconnect is enabled, use full arbitration. * Always generate parity; check for parity if required to do so. * Set slow cable mode if specified. */ if (pSiop->scsiCtrl.disconnect) { CACHE_PIPE_FLUSH(); NCR810_OUT_BYTE(pSiop->pScntl0, NCR810_IN_BYTE(pSiop->pScntl0) | (SCNTL0_ARB1 | SCNTL0_ARB0)); /* full arbitration */ } /* Enable select with attention */ CACHE_PIPE_FLUSH(); NCR810_OUT_BYTE(pSiop->pScntl0, NCR810_IN_BYTE(pSiop->pScntl0) | SCNTL0_WATN);#if FALSE /* Parity not supported yet */ if (pSiop->parityCheckEnbl) { CACHE_PIPE_FLUSH(); NCR810_OUT_BYTE(pSiop->pScntl0, NCR810_IN_BYTE(pSiop->pScntl0) | B_EPC); /* Enable parity checking */ }#endif /* * Set own SCSI bus ID (checked in "ncr810CtrlInit()") */ CACHE_PIPE_FLUSH(); NCR810_OUT_BYTE(pSiop->pScid, NCR810_IN_BYTE(pSiop->pScid) | pSiop->scsiCtrl.scsiCtrlBusId); NCR810_OUT_BYTE(pSiop->pRespid, (1 << pSiop->scsiCtrl.scsiCtrlBusId)); /* Enable response to bus initiated selection and reselection */ CACHE_PIPE_FLUSH(); NCR810_OUT_BYTE(pSiop->pScid, NCR810_IN_BYTE(pSiop->pScid) | SCID_RRE | SCID_SRE); /* * Enable relevant SCSI and DMA interrupts (see "ncr810EventTypeGet()") * * Note: in target mode the phase mismatch interrupt (B_MA) is used to * signal assertion of ATN. Currently we cannot handle this either in * this library or in the script. Therefore, the script automatically * disables this interrupt in target mode and enables it (for phase * mismatch) in initiator mode. Also see "ncr810EventTypeGet()". */ NCR810_OUT_BYTE(pSiop->pSien0, (B_SGE | B_UDC | B_RST | B_PAR)); NCR810_OUT_BYTE(pSiop->pSien1, (B_STO | B_HTH)); NCR810_OUT_BYTE(pSiop->pDien, (B_BF | B_ABT | B_SIR | B_IID)); /* CTEST registers to set in order to get the right initialisation */ CACHE_PIPE_FLUSH(); NCR810_OUT_BYTE(pSiop->pCtest3, NCR810_IN_BYTE(pSiop->pCtest3) |CTEST3_CLF); }/********************************************************************************* ncr810SetHwRegister - set hardware-dependent registers for the NCR 53C8xx SIOP** This routine sets up the registers used in the hardware* implementation of the chip. Typically, this routine is called by * the sysScsiInit() routine from the BSP. ** The input parameters are as follows:* .iP <pSiop> 4* a pointer to the NCR_810_SCSI_CTRL structure created with* ncr810CtrlCreate().* .iP <pHwRegs>* a pointer to a NCR810_HW_REGS structure that is filled with the logical* values 0 or 1 for each bit of each register described below.** This routine includes only the bit registers that can be used to modify * the behavior of the chip. The default configuration used during * ncr810CtlrCreate() and ncr810CrtlInit() is {0,0,0,0,0,1,0,0,0,0,0}.**.CS* typedef struct* {* int stest1Bit7; /@ Disable external SCSI clock @/* int stest2Bit7; /@ SCSI control enable @/* int stest2Bit5; /@ Enable differential SCSI bus @/* int stest2Bit2; /@ Always WIDE SCSI @/* int stest2Bit1; /@ Extend SREQ/SACK filtering @/* int stest3Bit7; /@ TolerANT enable @/* int dmodeBit7; /@ Burst Length transfer bit 1 @/* int dmodeBit6; /@ Burst Length transfer bit 0 @/* int dmodeBit5; /@ Source I/O memory enable @/* int dmodeBit4; /@ Destination I/O memory enable@/* int scntl1Bit7; /@ Slow cable mode @/* } NCR810_HW_REGS;**.CE* For a more detailed explanation of the register bits, see the appropriate * NCR 53C8xx data manuals.** NOTE* Because this routine writes to the NCR 53C8xx chip registers, it cannot be* used when there is any SCSI bus activity.** RETURNS: OK, or ERROR if any input parameter is NULL ** SEE ALSO: ncr810.h, ncr810CtlrCreate()*/STATUS ncr810SetHwRegister ( FAST SIOP *pSiop, /* pointer to SIOP info */ NCR810_HW_REGS *pHwRegs /* pointer to a NCR810_HW_REGS info */ ) { /* check input parameters */ if ((pSiop == NULL) || (pHwRegs == NULL)) return (ERROR); /* fill the SIOP structure with new parameters */ bcopy ((char *)pHwRegs, (char *) &pSiop->hwRegs, sizeof(NCR810_HW_REGS)); /* Set each bit register to the new value */ ((pHwRegs->stest1Bit7) ? (NCR810_OUT_BYTE(pSiop->pStest1, NCR810_IN_BYTE(pSiop->pStest1) | STEST1_SCLK)) : (NCR810_OUT_BYTE(pSiop->pStest1, NCR810_IN_BYTE(pSiop->pStest1) & ~STEST1_SCLK))); ((pHwRegs->stest2Bit7) ? (NCR810_OUT_BYTE(pSiop->pStest2, NCR810_IN_BYTE(pSiop->pStest2) | STEST2_SCE)) : (NCR810_OUT_BYTE(pSiop->pStest2, NCR810_IN_BYTE(pSiop->pStest2) & ~STEST2_SCE))); /* NCR825 specific initialisation */ if ((pSiop->devType == NCR825_DEVICE_ID) || (pSiop->devType == NCR875_DEVICE_ID)) { CACHE_PIPE_FLUSH(); ((pHwRegs->stest2Bit5) ? (NCR810_OUT_BYTE(pSiop->pStest2, NCR810_IN_BYTE(pSiop->pStest2) | STEST2_DIF)) : (NCR810_OUT_BYTE(pSiop->pStest2, NCR810_IN_BYTE(pSiop->pStest2) & ~STEST2_DIF))); CACHE_PIPE_FLUSH(); ((pHwRegs->stest2Bit2) ? (NCR810_OUT_BYTE(pSiop->pStest2, NCR810_IN_BYTE(pSiop->pStest2) | STEST2_AWS)) : (NCR810_OUT_BYTE(pSiop->pStest2, NCR810_IN_BYTE(pSiop->pStest2) & ~STEST2_AWS))); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -