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

📄 sym895lib.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            if (((pSiop->pCurThread->sxfer) & SYM895_SXFER_OFF_MASK) != 0)                {                if (SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT0) &                                       SYM895_SSTAT0_OLF)                    tmpCount++;                if (SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT2) &                                       SYM895_SSTAT2_OLF1)                    tmpCount++;                }			            /* Finally, add this to "remCount" to get the complete count */            remCount += tmpCount;            break;        case PHASE_DATA_IN	:        case PHASE_MSG_IN	:        case PHASE_STATUS	:            /* These are input phases check for data in input registers */				            /* The following for asynchronous transfers */            if (((pSiop->pCurThread->sxfer) & SYM895_SXFER_OFF_MASK) == 0)                {                if (SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT0) &                                       SYM895_SSTAT0_ILF)                    tmpCount++;                if (SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT2) &                                       SYM895_SSTAT2_ILF1)                    tmpCount++;                }            else                {				/*                  * For Sync. transfers add the total count, the number of bytes		 * in the sync FIFO.	 	 */				tmpCount += (((SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT1) &                                                  0xf0)>>4) |                             (SYM895_REG8_READ (pSiop, SYM895_OFF_SSTAT2) &                                                 0x10));                }                break;        default     :			            SCSI_MSG ("sym895RemainderGet: Invalid Phase %d\n", phase,                       0, 0, 0, 0, 0);			        }    /* Clear FiFos */    SYM895_REG8_WRITE (pSiop, SYM895_OFF_CTEST3,	                       SYM895_REG8_READ (pSiop,SYM895_OFF_CTEST3)|                        SYM895_CTEST3_CLF);		    return (remCount);	    }		/********************************************************************************* sym895Event - SCSI Controller event processing routine** Parse the event type and act accordingly.  Controller-level events are* handled within this function, and the event is then passed to the current* thread (if any) for thread-level processing.** Note the special case when (re)selection occurs: if there is a current* thread when the event occurs, it receives the event (and is assumed to* defer itself) before the identification thread is made current.  The* event is then forwarded to the identification thread.** RETURNS N/A*/LOCAL void sym895Event    (    SIOP *         pSiop,    SYM895_EVENT * pEvent    )    {    SCSI_CTRL  *    pScsiCtrl  = (SCSI_CTRL *)  pSiop;    SCSI_EVENT *    pScsiEvent = &pEvent->scsiEvent;    SYM895_THREAD * pThread    = (SYM895_THREAD *) pScsiCtrl->pThread;     SYM895_SCSI_DEBUG_MSG ("sym895Event:received event %d (thread = 0x%08x)\n",                           pScsiEvent->type, (int) pThread, 0, 0, 0, 0);    /*	Do controller-level event processing */    switch (pScsiEvent->type)        {        case SYM895_SELECTED:        case SYM895_RESELECTED:            /*             * Forward event to current thread, if any (it should defer)             * then install a reserved thread for identification purposes.             */    	    if (pThread != 0)                sym895ThreadEvent (pThread, pEvent);    	    pScsiCtrl->peerBusId = pScsiEvent->busId;    	    pScsiCtrl->pThread = pScsiCtrl->pIdentThread;	                pScsiCtrl->pThread->role = (pScsiEvent->type == SCSI_EVENT_SELECTED)		    	    	     ? SCSI_ROLE_IDENT_TARG :                                       SCSI_ROLE_IDENT_INIT;            pThread = (SYM895_THREAD *) pScsiCtrl->pThread;            scsiMgrCtrlEvent (pScsiCtrl, SCSI_EVENT_CONNECTED);            break;        case SYM895_DISCONNECTED:        case SYM895_CMD_COMPLETE:        case SYM895_UNEXPECTED_DISCON:        case SYM895_SCSI_TIMEOUT:            pScsiCtrl->peerBusId = NONE;    	    pScsiCtrl->pThread   = 0;            scsiMgrCtrlEvent (pScsiCtrl, SCSI_EVENT_DISCONNECTED);               break;        case SYM895_SCSI_BUS_RESET:	            pScsiCtrl->peerBusId = NONE;            pScsiCtrl->pThread   = 0;            scsiMgrBusReset (pScsiCtrl);            break;	        default:            /*             * Any other event type is assumed to be thread-specific.             * The thread event handler will report an error if it's             * not a valid type.             */            if (pThread == 0)                {                SCSI_MSG ("sym895Event invalid event type (%d)\n",                          pScsiEvent->type, 0, 0, 0, 0, 0);                }            break;        }    /* If there's a thread on the controller, forward the event to it */	    if (pThread != 0)        sym895ThreadEvent (pThread, pEvent);    }    /******************************************************************************** sym895ThreadInit - initialize a client thread structure** Initialize the fixed data for a thread (i.e., independent of the command).* Called once when a thread structure is first created.** RETURNS OK, or ERROR if an error occurs** NOMANUAL*/LOCAL STATUS sym895ThreadInit    (    SIOP *          pSiop,    SYM895_THREAD * pThread    )    {        if (scsiThreadInit (&pThread->scsiThread) != OK)        return (ERROR);	    pThread->pShMem = pSiop->pClientShMem;    pThread->scntl3 = pSiop->clkDiv;	    return (OK);    }/******************************************************************************** sym895IdentThreadInit - initialize an identification thread structure** Set up pointers and counts for all buffers other than messages.  Also set* transfer parameters for asynchronous mode, and update the shared memory* area to match this thread.** NOTE:* The pointers/counts set here are normally never used by the identification* thread; however, when an identification thread is aborted, it's possible* that the target will attempt to transfer one or more non-message bytes* before requesting the abort message out.  To handle this, the thread's* pointers and counts all specify a dummy buffer.  There is no re-entrancy* problem here because we do not care what data is transferred.  This might* be handled more elegantly if there were a special script entry to abort* an identification thread.** RETURNS: OK, or ERROR if an error occurs** NOMANUAL*/LOCAL STATUS sym895IdentThreadInit    (    SYM895_THREAD * pThread    )    {    SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread;    SIOP *        pSiop       = (SIOP *) pScsiThread->pScsiCtrl;    static UINT8  dummy;        /*     *	Initialise Pointers and counts in thread     */    pScsiThread->cmdLength         = 1;    pScsiThread->cmdAddress        = &dummy;    pScsiThread->dataLength        = 1;    pScsiThread->dataAddress       = &dummy;    pScsiThread->activeDataLength  = 1;    pScsiThread->activeDataAddress = &dummy;    pScsiThread->savedDataLength   = 1;    pScsiThread->savedDataAddress  = &dummy;    pScsiThread->statusLength      = 1;    pScsiThread->statusAddress     = &dummy;    pScsiThread->identMsgLength    = 1;        /*     *	Initialise SIOP register context in thread     */    pThread->nHostFlags   = 0;    pThread->msgOutStatus = SCSI_MSG_OUT_NONE;    pThread->msgInStatus  = SCSI_MSG_IN_NONE;    pThread->sxfer = SYM895_ASYNC_SXFER;    /*     * The value set in scntl3 for the ident message is chosen based on the.     * following reasons ...     * 1. Ident message is Async by default. So the bits SCFx donot matter now.     * 2. The target can be an Ultra SCSI or just FAST SCSI, so can't     *    enable those ULTRA bits now, effectively ruling out the possibility     *	  of using 160/80 MHz SCSI Clocks for ident message.     * 3. We chose to hardcode the value of 50 Mhz into scntl3 for ident      *    message. After negotiation, these values will suitably be changed.     */    pThread->scntl3 = SYM895_3750MHZ_ASYNC_DIV;  /* Hard Code */    /* pThread->scntl3 = pSiop->clkDiv; */    /* Initialise shared memory area */    pThread->pShMem = pSiop->pIdentShMem;        sym895SharedMemInit (pSiop, pThread->pShMem);    sym895ThreadUpdate (pThread);        return (OK);    }/******************************************************************************** sym895SharedMemInit - initialize the fields in a shared memory area** Initialise pointers and counts for all message transfers.  These are* always directed to buffers provided by the SCSI_CTRL structure.** RETURNS: N/A** NOMANUAL*/LOCAL void sym895SharedMemInit    (    SIOP *          pSiop,    SYM895_SHARED * pShMem    )    {    /*     * Note: All the values being set in the shared memory need to be     * 32 bit byte swapped. Actual swapping takes place when, when memory     * is big endian (since the SYM895 is a little endian PCI device.      * Otherwise, if memory is little endian then the byte swapping      * does not do anything. The "endianness" is configurable at compile     * time.     *     * Similarly, a PCI offset is added to all addresses so that the     * SYM895 PCI chip can get to memory. This value is also configurable     * at compile time.     */    pShMem->identIn.size = SYM895_SWAP_32 (1);    pShMem->identIn.addr = (UINT8 *)SYM895_SWAP_32 (SYM895_VIRT_TO_PHYS                                                    (pSiop->scsiCtrl.identBuf));    pShMem->msgOut.size = SYM895_SWAP_32 (0);	/* set dynamically */    pShMem->msgOut.addr = (UINT8 *)SYM895_SWAP_32 (SYM895_VIRT_TO_PHYS                                                   (pSiop->scsiCtrl.msgOutBuf));        pShMem->msgIn.size  = SYM895_SWAP_32 (1);    pShMem->msgIn.addr  = (UINT8 *)SYM895_SWAP_32 (SYM895_VIRT_TO_PHYS                                                   (pSiop->scsiCtrl.msgInBuf));    pShMem->msgInSecond.size = SYM895_SWAP_32 (1);    pShMem->msgInSecond.addr = (UINT8 *)SYM895_SWAP_32 (SYM895_VIRT_TO_PHYS                                                      (pSiop->scsiCtrl.msgInBuf)                                                     + (UINT) 1);    pShMem->msgInRest.size = SYM895_SWAP_32 (0);  /* set dynamically */    pShMem->msgInRest.addr = (UINT8 *)SYM895_SWAP_32 (SYM895_VIRT_TO_PHYS                                                     (pSiop->scsiCtrl.msgInBuf)                                                      + (UINT) 2);    }/******************************************************************************** sym895ThreadActivate - 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 "sym895Activate()").** Set the thread's state to ESTABLISHED.* Do not wait for the script to be activated.  Completion of the script will* be signalled by an event which is handled by "sym895Event()".** RETURNS OK or ERROR** NOMANUAL*/LOCAL STATUS sym895ThreadActivate    (    SIOP *          pSiop,		/* pointer to SIOP structure */    SYM895_THREAD * pThread		/* pointer to thread structure */    )    {    SCSI_CTRL *   pScsiCtrl   = (SCSI_CTRL *) pSiop;    SCSI_THREAD * pScsiThread = &pThread->scsiThread;    SCSI_TARGET * pScsiTarget = pScsiThread->pScsiTarget;        SYM895_SCSI_DEBUG_MSG ("sym895ThreadActivate: thread 0x%08x activating\n",              (int) pThread, 0, 0, 0, 0, 0);    /* Ensure buffers used by the thread are coherent with system cache */    scsiCacheSynchronize (pScsiThread, SCSI_CACHE_PRE_COMMAND);    /* Reset controller state variables set sync xfer parameters */

⌨️ 快捷键说明

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