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

📄 templatescsi2.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    else	{	templateScriptStart (pSiop, pSiop->pIdentThread,			   TEMPLATE_SCRIPT_WAIT);		pSiop->state = TEMPLATE_STATE_PASSIVE;	}    pSiop->cmdPending = FALSE;    SCSI_INT_DEBUG_MSG ("templateIntr: state %d -> %d\n",			oldState, pSiop->state, 0, 0, 0, 0);    /* Send the event to the SCSI manager to be processed. */    if (notify)    	scsiMgrEventNotify ((SCSI_CTRL *) pSiop, pScsiEvent, sizeof (event));    }/********************************************************************************* templateEvent - 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.** RETURNS: N/A*/LOCAL void templateEvent    (    SIOP *         pSiop,    TEMPLATE_EVENT * pEvent    )    {    SCSI_CTRL  *    pScsiCtrl  = (SCSI_CTRL *)  pSiop;    SCSI_EVENT *    pScsiEvent = &pEvent->scsiEvent;    TEMPLATE_THREAD * pThread    = (TEMPLATE_THREAD *) pScsiCtrl->pThread;     SCSI_DEBUG_MSG ("templateEvent: received event %d (thread = 0x%08x)\n",		    pScsiEvent->type, (int) pThread, 0, 0, 0, 0);    /*	Do controller-level event processing */    switch (pScsiEvent->type)	{	case SCSI_EVENT_SELECTED:	case SCSI_EVENT_RESELECTED:	    /*	     *	Forward event to current thread, if any (it should defer)	     *	then install a reserved thread for identification purposes.	     */    	    if (pThread != 0)	    	templateThreadEvent (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 = (TEMPLATE_THREAD *) pScsiCtrl->pThread;	    scsiMgrCtrlEvent (pScsiCtrl, SCSI_EVENT_CONNECTED);	    break;	case SCSI_EVENT_DISCONNECTED:	case TEMPLATE_SCSI_COMPLETE:	case TEMPLATE_UNEXPECTED_DISCON:	case TEMPLATE_SCSI_TIMEOUT:    	    pScsiCtrl->peerBusId = NONE;    	    pScsiCtrl->pThread   = 0;	    scsiMgrCtrlEvent (pScsiCtrl, SCSI_EVENT_DISCONNECTED);	    	    break;	case SCSI_EVENT_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)		{	    	logMsg ("templateEvent: 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)	templateThreadEvent (pThread, pEvent);    }    /********************************************************************************* templateThreadInit - 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*/LOCAL STATUS templateThreadInit    (    SIOP *          pSiop,    TEMPLATE_THREAD * pThread    )    {    scsiThreadInit (&pThread->scsiThread);    /* TODO - device specific thread initialization */    return (OK);    }/********************************************************************************* templateThreadActivate - 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 "templateActivate()").** 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 "templateEvent()".** RETURNS: OK or ERROR*/LOCAL STATUS templateThreadActivate    (    SIOP *          pSiop,		/* ptr to controller info */    TEMPLATE_THREAD * pThread		/* ptr to thread info     */    )    {    SCSI_CTRL *   pScsiCtrl   = (SCSI_CTRL *)   pSiop;    SCSI_THREAD * pScsiThread = &pThread->scsiThread;    SCSI_TARGET * pScsiTarget = pScsiThread->pScsiTarget;        SCSI_DEBUG_MSG ("templateThreadActivate: 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 (templateThreadParamsSet (pThread, pScsiTarget->xferOffset,			     	        pScsiTarget->xferPeriod) != OK)	{	SCSI_ERROR_MSG ("templateThreadActivate: failed to set thread " \			"params.\n", 0, 0, 0, 0, 0, 0);	return (ERROR);	}    /* Update thread context; activate the thread */    templateThreadUpdate (pThread);        if (templateActivate (pSiop, pThread) != OK)	{	SCSI_ERROR_MSG ("templateThreadActivate: failed to activate thread.\n",		        0, 0, 0, 0, 0, 0);	return (ERROR);	}    pScsiCtrl->pThread = pScsiThread;    templateThreadStateSet (pThread, SCSI_THREAD_ESTABLISHED);        return (OK);    }/********************************************************************************* templateThreadAbort - abort a thread** If the thread is not currently connected, do nothing and return FALSE to* indicate that the SCSI manager should abort the thread.** RETURNS: TRUE if the thread is being aborted by this driver (i.e. it is* currently active on the controller, else FALSE.*/LOCAL BOOL templateThreadAbort    (    SIOP *          pSiop,		/* ptr to controller info */    TEMPLATE_THREAD * pThread		/* ptr to thread info     */    )    {    BOOL          tagged;    SCSI_CTRL *   pScsiCtrl   = (SCSI_CTRL *)   pSiop;    SCSI_THREAD * pScsiThread = &pThread->scsiThread;    SCSI_DEBUG_MSG ("templateThreadAbort: thread 0x%08x (state = %d) "		    "aborting\n", (int)pThread, pScsiThread->state, 0, 0, 0, 0);    if (pScsiThread != pScsiCtrl->pThread)	return (FALSE);        switch (pScsiThread->state)	{	case SCSI_THREAD_INACTIVE:	case SCSI_THREAD_WAITING:	case SCSI_THREAD_DISCONNECTED:	    return (FALSE);	    break;	default:	    /*	     *	Build an ABORT (or ABORT TAG) message.  When this has been	     *	sent, the target should disconnect.  Mark the thread aborted	     *	and continue until disconnection.	     */	    tagged = (pScsiThread->tagNumber != NONE);	    pScsiCtrl->msgOutBuf[0] = tagged ? SCSI_MSG_ABORT_TAG		    	    	    	     : SCSI_MSG_ABORT;	    pScsiCtrl->msgOutLength = 1;	    pScsiCtrl->msgOutState  = SCSI_MSG_OUT_PENDING;	    templateAbort (pSiop);    	    templateThreadStateSet (pThread, SCSI_THREAD_ABORTING);	    break;	}    return (TRUE);    }/********************************************************************************* templateScsiBusControl - miscellaneous low-level SCSI bus control operations** Currently supports only the SCSI_BUS_RESET operation; other operations are* not used explicitly by the driver because they are carried out automatically* by the script program.** NOTE: after the SCSI bus has been reset, we expect the device* to create a TEMPLATE_BUS_RESET event to be sent to the SCSI manager.* See "templateIntr()".** RETURNS: OK, or ERROR if an invalid operation is requested.** NOMANUAL*/LOCAL STATUS templateScsiBusControl    (    SIOP * pSiop,   	    /* ptr to controller info                   */    int    operation	    /* bitmask for operation(s) to be performed */    )    {    if (operation & SCSI_BUS_RESET)	{	/* TODO - assert & deassert the RST line */	return OK;	}    return ERROR; /* unknown operation */    }/********************************************************************************* templateXferParamsQuery - get synchronous transfer parameters** Updates the synchronous transfer parameters suggested in the call to match* the TEMPLATE SCSI Controller's capabilities.  Transfer period is in SCSI units* (multiples * of 4 ns).** RETURNS: OK*/LOCAL STATUS templateXferParamsQuery    (    SCSI_CTRL *pScsiCtrl,		/* ptr to controller info       */    UINT8     *pOffset,			/* max REQ/ACK offset  [in/out] */    UINT8     *pPeriod			/* min transfer period [in/out] */    )    {    /* TODO - alter the offset and period variables to acceptable values */    return (OK);    }    /********************************************************************************* templateXferParamsSet - set transfer parameters** Validate the requested parameters, convert to the TEMPLATE SCSI Controller's * native format and save in the current thread for later use (the chip's* registers are not actually set until the next script activation for this * thread).** Transfer period is specified in SCSI units (multiples of 4 ns).  An offset* of zero specifies asynchronous transfer.** RETURNS: OK if transfer parameters are OK, else ERROR.*/LOCAL STATUS templateXferParamsSet    (    SCSI_CTRL *pScsiCtrl,		/* ptr to controller info */    UINT8      offset,			/* max REQ/ACK offset     */    UINT8      period			/* min transfer period    */    )    {    return (templateThreadParamsSet ((TEMPLATE_THREAD*)pScsiCtrl->pThread,				    offset, period));    }/********************************************************************************* templateWideXferParamsQuery - get wide data transfer parameters** Updates the wide data transfer parameters suggested in the call to match* the TEMPLATE SCSI Controller's capabilities.  Transfer width is in the units * of the WIDE DATA TRANSFER message's transfer width exponent field. This is* an 8 bit field where 0 represents a narrow transfer of 8 bits, 1 represents* a wide transfer of 16 bits and 2 represents a wide transfer of 32 bits.** RETURNS: OK*/LOCAL STATUS templateWideXferParamsQuery    (    SCSI_CTRL *pScsiCtrl,		/* ptr to controller info       */    UINT8     *xferWidth		/* suggested transfer width     */    )    {    if (*xferWidth > TEMPLATE_MAX_XFER_WIDTH)	*xferWidth = TEMPLATE_MAX_XFER_WIDTH;        templateWideXferParamsSet (pScsiCtrl, *xferWidth);    return (OK);    }/********************************************************************************* templateWideXferParamsSet - set wide transfer parameters** Assume valid parameters and set the TEMPLATE's thread parameters to the* appropriate values. The actual registers are not written yet, but will* be written from the thread values when it is activated.** Transfer width is specified in SCSI transfer width exponent units. ** RETURNS: OK */LOCAL STATUS templateWideXferParamsSet    (    SCSI_CTRL *pScsiCtrl,		/* ptr to controller info */    UINT8      xferWidth 		/* wide data transfer width */    )    {    /* TODO - update thread to enable/disable wide data xfers */    return OK;    }/********************************************************************************* templateThreadParamsSet - set various parameters for a thread** Parameters include transfer offset and period, as well as the ID of the* target device.  All of these end up as encoded values stored either in* the thread's register context or its associated shared memory area.** Transfer period is specified in SCSI units (multiples of 4 ns).  An offset* of zero specifies asynchronous transfer.** RETURNS: OK if parameters are OK, else ERROR.** NOMANUAL*/LOCAL STATUS templateThreadParamsSet    (    TEMPLATE_THREAD * pThread,	    	/* thread to be affected  */    UINT8           offset,		/* max REQ/ACK offset     */    UINT8           period		/* min transfer period    */    )    {    /* TODO - setup synch/asynch control bits */    /* TODO - setup wide control bits */    /* TODO - update device control registers if needed */    return (OK);    }/******************************************************************************** templateEventTypeGet - parse status registers at interrupt time** This routine examines the device state to determine what type of event* is pending.  If none is pending then a fatal error code is returned.** RETURNS: Returns an interrupt (event) type code or TEMPLATE_FATAL_ERROR.*/LOCAL int templateEventTypeGet    (    SIOP * pSiop    )    {    int key;    /*     * We should 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 ();     /* TODO - Read and save device status registers */    intUnlock (key);    SCSI_INT_DEBUG_MSG ("templateEventTypeGet: \n", 0, 0, 0, 0, 0, 0);    if (0) /* TODO - check for fatal error */	return TEMPLATE_ABORT;    /* TODO - try the rest (NB order of tests can be important !) */    if  (0) /* TODO - check for SCSI Bus reset */        {

⌨️ 快捷键说明

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