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

📄 ncr810lib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
		/* 825/875 Extensions */		if ((pSiop->devType == NCR825_DEVICE_ID) ||		    (pSiop->devType == NCR875_DEVICE_ID))		    {		    if (NCR810_IN_BYTE(pSiop->pSstat2) & SSTAT2_FF4)			countFifo |= 0x1f;		    }		tmpCount += countFifo;		}			    /* Check wide SCSI on 825/875 */	    if ((pSiop->devType == NCR825_DEVICE_ID) ||		(pSiop->devType == NCR875_DEVICE_ID))		{		if (NCR810_IN_BYTE(pSiop->pScntl2) & SCNTL2_WSR)		    tmpCount++;		}	    remCount += tmpCount;    	    break;        case PHASE_DATA_OUT:        case PHASE_MSG_OUT:	case PHASE_COMMAND:	    /* Asynch/Synchronous write */	    if (NCR810_IN_BYTE(pSiop->pSstat0) & SSTAT0_OLF)		tmpCount++;	    if ((pSiop->devType == NCR825_DEVICE_ID) ||		(pSiop->devType == NCR875_DEVICE_ID))		{		if (NCR810_IN_BYTE(pSiop->pSstat2) & SSTAT2_OLF)		    tmpCount++;		}			    if (syncMode)		{		/* Synchronous write */		if (NCR810_IN_BYTE(pSiop->pSstat0) & SSTAT0_ORF)		    tmpCount++;		/* 825/875 Extensions */		if ((pSiop->devType == NCR825_DEVICE_ID) ||		    (pSiop->devType == NCR875_DEVICE_ID))		    {		    if (NCR810_IN_BYTE(pSiop->pSstat2) & SSTAT2_ORF)			tmpCount++;		    } /* 825/875 */		}	   	    remCount += tmpCount;	    break;            default:            logMsg ("ncr810RemainderGet: invalid phase.\n", 0, 0, 0, 0, 0, 0);	    break;        }    /* Add in any deep fifo adjustments; this is zero for 88-byte fifos */    remCount += tmpCountWord;    /* Clear data FIFOs */    NCR810_OUT_BYTE(pSiop->pCtest3, NCR810_IN_BYTE(pSiop->pCtest3) |		    CTEST3_CLF);    return (remCount);    }/******************************************************************************** ncr810EventTypeGet - parse SCSI and DMA status registers at interrupt time** NOTE*   Only status bits which have corresponding interrupts enabled are checked !** RETURNS: an interrupt (event) type code** NOMANUAL*/LOCAL int ncr810EventTypeGet    (    SIOP * pSiop    )    {    UINT8 istat;    UINT8 dmaStatus;    UINT8 sist0;    UINT8 sist1;    int key;    /*     *	Read interrupt status registers     *     *	Note: reading the interrupt status register as a long word     *  causes the status register to read as NULL. This should not     *  be the case, however, the workaround is to read the status     *  registers as 8 bit registers and insert 12 SCLK delays     *  in between successive reads, as explained in the data manual.     */    dmaStatus = 0;    istat = sist0 = sist1 = 0;    /*     * Interrupts need to be locked in interrupt context while the status     * registers are being read so that there is no contention between     * a synchronous thread and a bus initiated thread (reselect)     */    key = intLock ();     CACHE_PIPE_FLUSH ();    istat = NCR810_IN_BYTE(pSiop->pIstat);     if ((istat & (ISTAT_SIP | ISTAT_DIP)) != 0)         {	if (istat & ISTAT_ABRT)	    NCR810_OUT_BYTE(pSiop->pIstat, 0x00);	if ((istat & ISTAT_SIP) && (istat & ISTAT_DIP))	    {	    SCSI_INT_DEBUG_MSG ("Both SIP and DIP occurred simultaneously\n",	                     0,0,0,0,0,0);	    }        CACHE_PIPE_FLUSH ();	dmaStatus  = NCR810_IN_BYTE(pSiop->pDstat);        CACHE_PIPE_FLUSH ();        ncr810Delay ();        sist0 = NCR810_IN_BYTE(pSiop->pSist0);        CACHE_PIPE_FLUSH ();        ncr810Delay ();        sist1 = NCR810_IN_BYTE(pSiop->pSist1);	intUnlock (key);        }    else	{        intUnlock (key);	return (ERROR);	}    SCSI_INT_DEBUG_MSG ("ncr810EventTypeGet:"			"Interrupt status istat = 0x%02x, "			"SCSI status0 = 0x%02x, "			"SCSI status1 = 0x%02x"			"DMA status = 0x%02x\n",		    	istat, sist0, sist1, dmaStatus, 0, 0);    /*     *	Check for fatal errors (first !)     */    if  (sist0 & B_SGE)        {	logMsg ("ncr810: SCSI bus gross error.\n", 0, 0, 0, 0, 0, 0);	return (NCR810_FATAL_ERROR);        }    if  (sist0 & B_PAR)        {	logMsg ("ncr810: parity error.\n", 0, 0, 0, 0, 0, 0);	return (NCR810_FATAL_ERROR);        }    if (dmaStatus & B_IID)        {	logMsg ("ncr810: illegal instruction (DSP = 0x%08x).\n",		NCR810_IN_32(pSiop->pDsp), 0, 0, 0, 0, 0);	return (NCR810_FATAL_ERROR);        }    if (dmaStatus & B_BF)        {	logMsg ("ncr810: bus fault (DSPS = 0x%08x) DBC = (0x%08x).\n",		NCR810_IN_32(pSiop->pDsps), 		NCR810_IN_32(pSiop->pDbc) & 0xffffff, 0, 0, 0, 0);	return (NCR810_FATAL_ERROR);        }    /*     *	No fatal errors; try the rest (NB order of tests is important !)     */    if  (sist0 & B_RST)        {	SCSI_INT_DEBUG_MSG ("ncr810EventTypeGet: SCSI bus reset.\n",			    0, 0, 0, 0, 0, 0);	NCR810_OUT_BYTE(pSiop->pCtest3, NCR810_IN_BYTE(pSiop->pCtest3) |			CTEST3_CLF);	/* clear FIFOs */		return (NCR810_SCSI_BUS_RESET);        }    if  (sist0 & B_UDC)        {	SCSI_INT_DEBUG_MSG ("ncr810EventTypeGet: unexpected disconnection.\n",			    0, 0, 0, 0, 0, 0);	/* clear FIFOs */	NCR810_OUT_BYTE(pSiop->pCtest3, NCR810_IN_BYTE(pSiop->pCtest3) |			CTEST3_CLF);		return (NCR810_UNEXPECTED_DISCON);        }    if (sist1 & B_STO)	{    	SCSI_INT_DEBUG_MSG ("ncr810EventTypeGet: SCSI bus timeout.\n",			    0, 0, 0, 0, 0, 0);	/* clear FIFOs */	NCR810_OUT_BYTE(pSiop->pCtest3, NCR810_IN_BYTE(pSiop->pCtest3) |			CTEST3_CLF);		return (NCR810_SCSI_TIMEOUT);	}    if (sist1 & B_HTH)	{    	SCSI_INT_DEBUG_MSG ("ncr810EventTypeGet: SCSI handshake timeout.\n",			    0, 0, 0, 0, 0, 0);	/* clear FIFOs */	NCR810_OUT_BYTE(pSiop->pCtest3, NCR810_IN_BYTE(pSiop->pCtest3) |			CTEST3_CLF);		return (NCR810_HANDSHAKE_TIMEOUT);	}    if (sist0 & B_MA)        {	/*	 *  The "phase mismatch" interrupt is used to indicate assertion of	 *  ATN in target mode.  This interrupt should have been disabled	 *  by the script when in target mode, because the current code does	 *  not know how to handle it.	 */	if (NCR810_IN_BYTE(pSiop->pScntl0) & SCNTL0_TRG)	    {	    if (NCR810_IN_BYTE(pSiop->pSien0) & B_MA)		{		logMsg ("ncr810EventTypeGet: enabled ATN interrupt!\n",			0, 0, 0, 0, 0, 0);		return (NCR810_FATAL_ERROR);		}	    }	else	    {	    SCSI_INT_DEBUG_MSG ("ncr810EventTypeGet: phase mismatch.\n",			    0, 0, 0, 0, 0, 0);	    return (NCR810_PHASE_MISMATCH);	    }        }    if (dmaStatus & B_ABT)        {	SCSI_INT_DEBUG_MSG ("ncr810EventTypeGet: script aborted.\n",		    	    0, 0, 0, 0, 0, 0);	return (NCR810_SCRIPT_ABORTED);        }    if (dmaStatus & B_SIR)	{	SCSI_INT_DEBUG_MSG ("ncr810EventTypeGet: script completed.\n",			    0, 0, 0, 0, 0, 0);	return ( NCR810_IN_32(pSiop->pDsps) );        }    if (dmaStatus & B_SSI)	{	SCSI_INT_DEBUG_MSG ("ncr810EventTypeGet: single-step.\n",			    0, 0, 0, 0, 0, 0);	return (NCR810_SINGLE_STEP);	}    /*     *	No (expected) reason for the interrupt !     */    logMsg ("ncr810EventTypeGet: spurious interrupt !\n", 0, 0, 0, 0, 0, 0);    logMsg ("\tistat: (0x%x) dstat: (0x%x)\n", istat, dmaStatus, 0, 0, 0, 0);     logMsg ("\tsist0: (0x%x) sist1: (0x%x)\n", sist0, sist1, 0, 0, 0, 0);        return (NCR810_FATAL_ERROR);    }/********************************************************************************* ncr810ThreadActivate - activate a SCSI connection for an initiator thread** Set whatever thread/controller state variables need to be set.  Ensure that* all buffers used by the thread are coherent with the contents of the* system caches (if any).** Set transfer parameters for the thread based on what its target device* last negotiated.** Update the thread context (including shared memory area) and note that* there is a new client script to be activated (see "ncr810Activate()").** Set the thread's state to ESTABLISHED.  This is strictly a bit premature,* but there is no distinction as far as this driver is concerned between a* thread which is connecting and one which has connected (i.e., the script* just runs to completion and we have to examine its exit status to determine* how far through the process the thread got).** Do not wait for the script to be activated.  Completion of the script will* be signalled by an event which is handled by "ncr810Event()".** RETURNS: OK or ERROR** NOMANUAL*/LOCAL STATUS ncr810ThreadActivate    (    SIOP *          pSiop,		/* ptr to controller info */    NCR810_THREAD * pThread		/* ptr to thread info     */    )    {    SCSI_CTRL *   pScsiCtrl   = (SCSI_CTRL *)   pSiop;    SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread;    SCSI_TARGET * pScsiTarget = pScsiThread->pScsiTarget;        SCSI_DEBUG_MSG ("ncr810ThreadActivate: thread 0x%08x: activating\n",		    (int) pThread, 0, 0, 0, 0, 0);    scsiCacheSynchronize (pScsiThread, SCSI_CACHE_PRE_COMMAND);    /*     *	Reset controller state variables: set sync xfer parameters     */    pScsiCtrl->msgOutState = SCSI_MSG_OUT_NONE;    pScsiCtrl->msgInState  = SCSI_MSG_IN_NONE;        /*     * A wide transfer is initiated before a synchronous transfer. However,     * when a wide transfer has been done the next activation causes the     * synchronous transfer to be activated. Another possible but more     * complicated way to implement this would be to have both wide and     * synchronous negotiations in the same activation or thread i.e.     * the same SCSI transaction.     */    scsiWideXferNegotiate (pScsiCtrl, pScsiTarget, WIDE_XFER_NEW_THREAD);    scsiSyncXferNegotiate (pScsiCtrl, pScsiTarget, SYNC_XFER_NEW_THREAD);    if (ncr810ThreadParamsSet (pThread, pScsiTarget->xferOffset,			     	        pScsiTarget->xferPeriod) != OK)	{	SCSI_ERROR_MSG ("ncr810ThreadActivate: failed to set thread params.\n",			0, 0, 0, 0, 0, 0);	return (ERROR);	}    /*     *  Concatenate the ident message with a pending 'normal' message out,     *  if possible.  This allows the script to send the first message out     *  within the same MSG OUT phase as the IDENTIFY message - needed on     *  some target systems (e.g. DG Clariion RAID) to avoid the message     *  being rejected(!).     */    pSiop->identMsgLength = 0;    bcopy (pScsiThread->identMsg,           pSiop->identMsg,           pScsiThread->identMsgLength);    pSiop->identMsgLength += pScsiThread->identMsgLength;    if (pScsiCtrl->msgOutState == SCSI_MSG_OUT_PENDING)        {        bcopy (pScsiCtrl->msgOutBuf,               pSiop->identMsg + pSiop->identMsgLength,               pScsiCtrl->msgOutLength);        pSiop->identMsgLength += pScsiCtrl->msgOutLength;        }    /*     *	Update thread context; activate the thread     */    ncr810ThreadUpdate (pThread);        if (ncr810Activate (pSiop, pThread) != OK)	{	SCSI_ERROR_MSG ("ncr810ThreadActivate: failed to activate thread.\n",		        0, 0, 0, 0, 0, 0);	return (ERROR);	}    pScsiCtrl->pThread = pScsiThread;    ncr810ThreadStateSet (pThread, SCSI_THREAD_ESTABLISHED);        return (OK);    }/*******************************************************************************

⌨️ 快捷键说明

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