⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncr710lib.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* cacheDmaMalloc the data share info structure; return ERROR if unable */    pNcrCtxt = (NCR_CTL_CTXT *) cacheDmaMalloc (sizeof (NCR_CTL_CTXT));    if (pNcrCtxt == (NCR_CTL_CTXT *) NULL)	{	printErr("ncr710CtrlCreate :malloc NCR_CTL_CTXT context failed\n");	(void) cacheDmaFree ((char *) pSiop);        return((SIOP *) NULL);	}    bzero ((char *) pNcrCtxt, sizeof (NCR_CTL_CTXT));    /* fill in generic SCSI info for this controller */    scsiCtrlInit (&pSiop->scsiCtrl);    /* Init NcrCtxt pointer in siop structure */    pSiop->pNcrCtxt = pNcrCtxt;    /* fill in SIOP specific data for this controller */    pSiop->pSien     = baseAdrs + OFF_SIEN;    pSiop->pSdid     = baseAdrs + OFF_SDID;    pSiop->pScntl1   = baseAdrs + OFF_SCNTL1;    pSiop->pScntl0   = baseAdrs + OFF_SCNTL0;    pSiop->pSocl     = baseAdrs + OFF_SOCL;    pSiop->pSodl     = baseAdrs + OFF_SODL;    pSiop->pSxfer    = baseAdrs + OFF_SXFER;    pSiop->pScid     = baseAdrs + OFF_SCID;    pSiop->pSbcl     = baseAdrs + OFF_SBCL;    pSiop->pSbdl     = baseAdrs + OFF_SBDL;    pSiop->pSidl     = baseAdrs + OFF_SIDL;    pSiop->pSfbr     = baseAdrs + OFF_SFBR;    pSiop->pSstat2   = baseAdrs + OFF_SSTAT2;    pSiop->pSstat1   = baseAdrs + OFF_SSTAT1;    pSiop->pSstat0   = baseAdrs + OFF_SSTAT0;    pSiop->pDstat    = baseAdrs + OFF_DSTAT;    pSiop->pDsa      = (UINT *) (baseAdrs + OFF_DSA);    pSiop->pCtest3   = baseAdrs + OFF_CTEST3;    pSiop->pCtest2   = baseAdrs + OFF_CTEST2;    pSiop->pCtest1   = baseAdrs + OFF_CTEST1;    pSiop->pCtest0   = baseAdrs + OFF_CTEST0;    pSiop->pCtest7   = baseAdrs + OFF_CTEST7;    pSiop->pCtest6   = baseAdrs + OFF_CTEST6;    pSiop->pCtest5   = baseAdrs + OFF_CTEST5;    pSiop->pCtest4   = baseAdrs + OFF_CTEST4;    pSiop->pTemp     = (UINT *) (baseAdrs + (OFF_TEMP));    pSiop->pLcrc     = baseAdrs + OFF_LCRC;    pSiop->pCtest8   = baseAdrs + OFF_CTEST8;    pSiop->pIstat    = baseAdrs + OFF_ISTAT;    pSiop->pDfifo    = baseAdrs + OFF_DFIFO;    pSiop->pDcmd     =  baseAdrs + OFF_DCMD;    pSiop->pDbc      = (UINT *) (baseAdrs + (OFF_DBC));    pSiop->pDnad     = (UINT *) (baseAdrs + (OFF_DNAD));    pSiop->pDsp      = (UINT *) (baseAdrs + (OFF_DSP));    pSiop->pDsps     = (UINT *) (baseAdrs + (OFF_DSPS));    pSiop->pScratch0 = baseAdrs + OFF_SCRATCH0;    pSiop->pScratch1 = baseAdrs + OFF_SCRATCH1;    pSiop->pScratch2 = baseAdrs + OFF_SCRATCH2;    pSiop->pScratch3 = baseAdrs + OFF_SCRATCH3;    pSiop->pDcntl    = baseAdrs + OFF_DCNTL;    pSiop->pDwt      = baseAdrs + OFF_DWT;    pSiop->pDien     = baseAdrs + OFF_DIEN;    pSiop->pDmode    = baseAdrs + OFF_DMODE;    pSiop->pAdder    = (UINT *) (baseAdrs + (OFF_ADDER));    pSiop->scsiCtrl.clkPeriod = freqValue;    pSiop->scsiCtrl.maxBytesPerXfer = SIOP_MAX_XFER_LENGTH;    pSiop->scsiCtrl.scsiBusReset      = (VOIDFUNCPTR) ncr710ScsiBusReset;     pSiop->scsiCtrl.scsiTransact       = (FUNCPTR) ncr710ScsiTransact;    pSiop->scsiCtrl.scsiSyncMsgConvert = (FUNCPTR) ncr710SyncMsgConvert;    /* no longer needed with this kind of chip */    pSiop->scsiCtrl.scsiDevSelect      = NULL;    pSiop->scsiCtrl.scsiBytesIn        = NULL;    pSiop->scsiCtrl.scsiBytesOut       = NULL;    pSiop->scsiCtrl.scsiDmaBytesIn     = NULL;    pSiop->scsiCtrl.scsiDmaBytesOut    = NULL;    pSiop->scsiCtrl.scsiBusPhaseGet    = NULL;    pSiop->scsiCtrl.scsiMsgInAck       = NULL;    pSiop->scsiCtrl.scsiSetAtn         = NULL;    /* Fill the siop structure with the default value for        some hardware dependant registers */     bcopy ((char *)&hwRegs,(char *)&pSiop->hwRegs,sizeof (NCR710_HW_REGS));    /* Just here to avoid a bus error in scsiAutoConfig        the chip can't be programming for an another value (0 or 250ms) */    pSiop->scsiCtrl.scsiSelTimeOutCvt = (VOIDFUNCPTR)ncr710SelTimeOutCvt;	    pSiop->pDevToSelect = (SCSI_PHYS_DEV *) NULL;    /* create the mutex siop data semaphore */    pSiop->pMutexData = semBCreate(SEM_Q_FIFO,SEM_FULL);    if (pSiop->pMutexData == (SEM_ID)NULL)	{	(void) cacheDmaFree ((char *) pSiop);	(void) cacheDmaFree ((char *) pNcrCtxt);	return((SIOP *)NULL);        } #ifdef NCR710_INT_LOG_MEM    pNcr710Deb = (UINT *)malloc(LOG_SIZE_MEM);    pLogMemShow = pNcr710Deb;#endif    return (pSiop);    }/********************************************************************************* ncr710CtrlInit - initialize a control structure for an NCR 53C710 SIOP** This routine initializes an SIOP structure, after the structure is created* with ncr710CtrlCreate().  This structure must be initialized before the* SIOP can be used.  It may be called more than once;  however,* it should be called only while there is no activity on the SCSI interface.** Before returning, this routine pulses RST (reset) on the SCSI bus, thus* resetting all attached devices.** The input parameters are as follows:* .iP <pSiop> 4* a pointer to the NCR_710_SCSI_CTRL structure created with* ncr710CtrlCreate().* .iP <scsiCtrlBusId>* the SCSI bus ID of the SIOP, in the range 0 - 7.  The ID is somewhat * arbitrary; the value 7, or highest priority, is conventional.* .iP <scsiPriority>* the priority to which a task is set when performing a SCSI transaction.* Valid priorities are 0 to 255.  Alternatively, the value -1 specifies that * the priority should not be altered during SCSI transactions. ** RETURNS: OK, or ERROR if parameters are out of range.*/STATUS ncr710CtrlInit    (    FAST NCR_710_SCSI_CTRL *pSiop, /* ptr to SIOP struct */    FAST int scsiCtrlBusId,	   /* SCSI bus ID of this SIOP */    int scsiPriority		   /* priority of task when doing SCSI I/O */    )    {    int ix;    int jx;    NCR_CTL *pNcrCtl;    /* Check if pSiop not NULL */    if (pSiop == (SIOP *)NULL)	return (ERROR);    pNcrCtl = &pSiop->pNcrCtxt->ncrCtl[0][0];    pSiop->pNcrCtl = (NCR_CTL *) NULL;    /* verify scsiCtrlBusId and enter legal value in SIOP structure */    if (scsiCtrlBusId < SCSI_MIN_BUS_ID || scsiCtrlBusId > SCSI_MAX_BUS_ID)	return (ERROR);        pSiop->scsiCtrl.scsiCtrlBusId = (UINT8) scsiCtrlBusId;    /* translate id 0-7 in power of 2 (1000000 = 7).It's for saving time     * at interrupt level in a reconnection scheme.      */    pSiop->ctrlIdPow2 = (UINT8) (0x1 << pSiop->scsiCtrl.scsiCtrlBusId);    /* verify scsiPriority and enter legal value in SIOP structure */    if (scsiPriority < NONE || scsiPriority > 0xff)	return (ERROR);        pSiop->scsiCtrl.scsiPriority = scsiPriority;    /* disconnect is supported for now,but this feature is not included     * in this revision.     */    pSiop->scsiCtrl.disconnect = FALSE; /* TRUE to enable disconnect */    ncr710ScsiBusReset (pSiop);    /* initialize the SIOP hardware */    ncr710HwInit (pSiop);      /* Fill fixed values in the SIOP nexus */    for (ix = 0; ix<= SCSI_MAX_BUS_ID; ix++)	{	for (jx = 0; jx <= SCSI_MAX_LUN; jx++)	    {	    /* Init fixed count */ 	    pNcrCtl->msgInCount = 1;	    pNcrCtl->extMsgInCount = 4;	    pNcrCtl->statusCount = 1;            pNcrCtl->pIdentMsg = CACHE_DMA_VIRT_TO_PHYS (						 &pSiop->saveIdentMsg);            pNcrCtl->identCount = 1;            pNcrCtl++; 	    }	}    return (OK);    }/********************************************************************************* ncr710ScsiBusReset - assert the RST line on the SCSI bus ** Issue a SCSI Bus Reset command to the NCR 710.  This should put all devices* on the SCSI bus in an initial quiescent state.* This routine also clears the interrupt status by reading all status* registers.  Because the chip has an interrupt stack, it is necessary to* loop on the status registers to clear any pending interrupts.** RETURNS: N/A** NOMANUAL*/LOCAL void ncr710ScsiBusReset    (    FAST SIOP *pSiop	/* ptr to SIOP info */   )    {    UINT8 tempReg;    *pSiop->pScntl1 |= (UINT8) (B_RST);    taskDelay (2);    *pSiop->pScntl1 &= ~B_RST;       /* Check for interrupt pending after scsi reset */    tempReg = ((*pSiop->pIstat) & (B_DIP | B_SIP));    while  (tempReg != 0)        {        /* Read scsi Status interrupt */        tempReg = *pSiop->pSstat0; 	taskDelay (2);        tempReg = *pSiop->pDstat; 	taskDelay (2);	tempReg = ((*pSiop->pIstat) & (B_DIP | B_SIP));        }    }/********************************************************************************* ncr710Intr - interrupt service routine for the SIOP** This interrupt routine just performs a clear of interrupt * conditions and copies all of the interrupt status of the SIOP* (status registers and script instruction interrupt values). * A check of the interrupt issued is done at the task level in* ncr710ScsiPhase function except for a phase mismatch, a new command to * start, and a reconnect process.** RETURNS: N/A** NOMANUAL*/void ncr710Intr     (    SIOP *pSiop		/* ptr to SIOP info */    )    {    UINT8 tmpReg;    UINT8 phaseReqReg;    TBOOL scriptIntr;        /* used to detect true end in single step Mode */    UINT8 tmpLun;            /* used to extract lun from ident msgin */    UINT8 tmp;    SCSI_PHYS_DEV  *pScsiPhysDev;   /* Used when reconnected occur */    UINT *localStart;               /* Used to restart Script */    UINT intrRegs;	     /* local 32bit read of interrupt status */    ncr710CountIntr++;    /* Clear previous values */    pSiop->saveSstat0 = 0;    pSiop->saveDstat = 0;    pSiop->saveScriptIntrStat=0;    /* Update phase requested for this nexus */    phaseReqReg = *pSiop->pScratch0;    /* Read interrupt status registers with a long acces to avoid any      * potential timing problem. The ncr710 Data manuel specify that a      * 12BCLK period must be insert beetwen two 8bit read of SSTAT0     * and DSTAT.  This limitation does not exist for a 32bit access.     */    while ((tmpReg = (*pSiop->pIstat & (B_SIP | B_DIP))) != 0)        {#if _BYTE_ORDER==_BIG_ENDIAN        intrRegs = *((UINT *)pSiop->pSstat2);        pSiop->saveSstat0 |= (UINT8)((intrRegs >> 8) & 0x0FF);        pSiop->saveDstat  |= (UINT8)(intrRegs & 0x0FF);#else        intrRegs = *((UINT *)pSiop->pDstat);        pSiop->saveSstat0 |= (UINT8)((intrRegs >> 16) & 0x0FF);        pSiop->saveDstat  |= (UINT8)((intrRegs >> 24) & 0x0FF);#endif        }    /* check for Single Step interrupt */    if (pSiop->saveDstat & B_SSI)        SCSI_INT_DEBUG_MSG("Single Step interrupt\n", 0, 0, 0, 0, 0, 0);     if (pSiop->saveDstat & B_SIR)        {        scriptIntr = TRUE;        }    /* read the result value of int script instruction */    pSiop->saveScriptIntrStat = *pSiop->pDsps;    /* Process new command / disconnect / reconnected for exclusive      * access data part     */    switch (pSiop->saveScriptIntrStat)	{        	case NEW_COMMAND_PROCESS:            SCSI_INT_DEBUG_MSG("ncr710Intr:start new cmd \n", 0, 0, 0, 0, 0, 0);            /* Initialize global nexus pointer */            pSiop->pNcrCtl = pSiop->pNcrCtlCmd; #ifdef NCR710_INT_LOG_MEM	    LOG_MEM_INTR;#endif /* NCR710_INT_LOG_MEM */            /* Flush all data involve in a transaction. */            ncr710FlushCache(pSiop, pSiop->pNcrCtl);	    ncr710StartScript (pSiop,pSiop->pNcrCtl,			      (SCSI_PHYS_DEV *)pSiop->pNcrCtl->pScsiPhysDev,                              (UINT *)pSiop->pNcrCtl->scriptAddr);            return;        case RECONNECT_PROCESS:            SCSI_INT_DEBUG_MSG("ncr710Intr:reconnect\n", 0, 0, 0, 0, 0, 0);	    if ((pSiop->saveIdentMsg & SCSI_MSG_IDENTIFY) == 0)		{                /* It's a bogus reconnect continue */                logMsg ("ncr710Intr:bogus reselect msgIn = 0x%02x\n",		        pSiop->saveIdentMsg, 0, 0, 0, 0, 0);#ifdef NCR710_INT_LOG_MEM	    LOG_MEM_INTR;#endif /* NCR710_INT_LOG_MEM */                ncr710StartScript(pSiop,pSiop->pNcrCtl,				(SCSI_PHYS_DEV *)pSiop->pNcrCtl->pScsiPhysDev,				&ackMsg1);                return;                }            tmpLun = pSiop->saveIdentMsg & SCSI_MAX_LUN;            /* Get scsi Id : we 've got the power of 2 both for             *    own controller id and target id,xor first to get              *   the target id  10000100 (ctr = 7 ,target = 2). 	     */                         tmp = (pSiop->ctrlIdPow2) ^ (*pSiop->pScratch3);             /* extract number from power of 2 picture for indexing */            for (tmpReg=0;!(tmp & 0x1);tmpReg++)		tmp = (tmp >> 1);            /* Give devSyncSem for reconnected target by indexing ncrCtl 	     * device array.	     */            pScsiPhysDev =(SCSI_PHYS_DEV *)pSiop->pNcrCtxt->			  ncrCtl[tmpReg][tmpLun].pScsiPhysDev;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -