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

📄 scsictrllib.c

📁 the vxworks system kernel souce packeg.there may be something you need .
💻 C
📖 第 1 页 / 共 4 页
字号:
    status = scsiIdentMsgParse (pScsiCtrl, pThread->identMsg,			       	    	   pThread->nBytesIdent,			       	    	  &pThread->pScsiPhysDev,			       	    	  &pThread->tagNumber);    switch (status)	{	case SCSI_IDENT_INCOMPLETE:	    state = SCSI_THREAD_IDENT_IN;	    break;	case SCSI_IDENT_COMPLETE:	    scsiMgrThreadEvent (pThread, SCSI_THREAD_EVENT_RECONNECTED);	    if ((pNewThread = scsiMgrPhysDevActiveThreadFind (						pThread->pScsiPhysDev,						pThread->tagNumber)) == 0)		{		state = SCSI_THREAD_IDENT_ABORTING;		}	    else		{	    	scsiCtrlThreadReconnect (pNewThread);	    	state = SCSI_THREAD_INACTIVE;		}	    break;	case SCSI_IDENT_FAILED:	    state = SCSI_THREAD_IDENT_ABORTING;	    break;	default:	    logMsg ("scsiCtrlIdentInContinue: invalid ident status (%d)\n",    	    	    status, 0, 0, 0, 0, 0);	    state = SCSI_THREAD_INACTIVE;	    break;	}    if (state == SCSI_THREAD_IDENT_ABORTING)	scsiCtrlThreadAbort (pScsiCtrl, pThread);    scsiCtrlThreadStateSet (pThread, state);    }    /********************************************************************************* scsiCtrlThreadReconnect - reconnect a thread** Restore the SCSI pointers for the thread (this really should be in a more* generic section of code - perhaps part of the SCSI manager's thread event* procesing ?).  Set the controller's transfer parameters for the newly * connected thread.  Set the thread's state to ESTABLISHED.** RETURNS: N/A*/LOCAL void scsiCtrlThreadReconnect    (    SCSI_THREAD * pThread    )    {    SCSI_CTRL * pScsiCtrl = pThread->pScsiCtrl;        SCSI_DEBUG_MSG ("scsiCtrlThreadReconnect: reconnecting thread 0x%08x\n",		    (int) pThread, 0, 0, 0, 0, 0);    pScsiCtrl->pThread = pThread;    /*     *  Reset controller state variables for the new thread     */    pScsiCtrl->msgOutState = SCSI_MSG_OUT_NONE;    pScsiCtrl->msgInState  = SCSI_MSG_IN_NONE;    /* Implied RESTORE POINTERS action: see "scsiMsgInComplete ()" */    pThread->activeDataAddress = pThread->savedDataAddress;    pThread->activeDataLength  = pThread->savedDataLength;    if (scsiCtrlXferParamsSet (pThread) != OK)	{	SCSI_ERROR_MSG ("scsiCtrlThreadReconnect: failed to set xfer params.\n",			0, 0, 0, 0, 0, 0);	scsiCtrlThreadFail (pThread, errno);	return;	}    scsiCtrlThreadStateSet (pThread, SCSI_THREAD_ESTABLISHED);    }/********************************************************************************* scsiCtrlNormalXfer - initiator info transfer request event processing** Check for phase changes during message-in and message-out transfers,* handling them accordingly (neither is necessarily an error condition).* Call the appropriate handler routine for the message transfer phase* requested by the target.** RETURNS: N/A*/LOCAL void scsiCtrlNormalXfer    (    SCSI_THREAD * pThread,    SCSI_EVENT *  pEvent    )    {    STATUS status;    SCSI_CTRL * pScsiCtrl = pThread->pScsiCtrl;    int         phase     = pEvent->phase;    switch (pThread->state)	{	case SCSI_THREAD_ESTABLISHED:	case SCSI_THREAD_WAIT_COMPLETE:	case SCSI_THREAD_WAIT_DISCONNECT:	case SCSI_THREAD_WAIT_ABORT:	    break;	default:	    logMsg ("scsiCtrlNormalXfer: thread 0x%08x: invalid state (%d)\n",		    (int) pThread, pThread->state, 0, 0, 0, 0);	    return;	}        SCSI_DEBUG_MSG ("scsiCtrlNormalXfer: thread 0x%08x: "		    "target requesting %s phase\n",		    (int) pThread, (int) scsiPhaseNameGet (phase),		    0, 0, 0, 0);	    /*     *	Check for phase change during message in handling: this probably     *	results from our having asserted ATN in order to send a message out.     *	This would occur if we reject a partially read incoming message.     *     *	Reset the message-in state in this case.     */    if (phase != SCSI_MSG_IN_PHASE)	{    	switch (pScsiCtrl->msgInState)	    {	    case SCSI_MSG_IN_NONE:	    	break;	    default:            	SCSI_DEBUG_MSG ("scsiCtrlNormalXfer: phase change "				"during msg in\n",			    	0, 0, 0, 0, 0, 0);	    	pScsiCtrl->msgInState = SCSI_MSG_IN_NONE;	    break;	    }	}	    /*     *	Check for phase change during (immediately after) message out.     *     *	If this happens while there is a pending message out, there are     *	two possibilities.  Either the target has not yet noticed our ATN     *	(i.e., no message data has yet been transferred) or it has changed     *	phase in mid-transfer (probably to reject the message we're sending).     *	In either case, the message state is left pending so that it will be     *	(re-)sent or rejected as appropriate.     *     *	If it happens just after a message out has been sent, it means the     *	target has accepted the message.  In this case the message out state     *	is reset, and the message out completion routine is called.     */    if (phase != SCSI_MSG_OUT_PHASE)	{    	switch (pScsiCtrl->msgOutState)	    {	    case SCSI_MSG_OUT_NONE:	    case SCSI_MSG_OUT_PENDING:	    	break;	    case SCSI_MSG_OUT_SENT:	    	pScsiCtrl->msgOutState = SCSI_MSG_OUT_NONE;	    	(void) scsiMsgOutComplete (pScsiCtrl, pThread);	    	break;            default:	        break;	    }	}	        /*     *	Perform information transfer requested by target     */    switch (phase)	{	case SCSI_DATA_OUT_PHASE:	    status = scsiCtrlDataOutAction (pScsiCtrl, pThread);	    break;	    	case SCSI_DATA_IN_PHASE:	    status = scsiCtrlDataInAction (pScsiCtrl, pThread);	    break;	    	case SCSI_COMMAND_PHASE:	    status = scsiCtrlCommandAction (pScsiCtrl, pThread);	    break;	    	case SCSI_STATUS_PHASE:	    status = scsiCtrlStatusAction (pScsiCtrl, pThread);	    break;	    	case SCSI_MSG_OUT_PHASE:	    status = scsiCtrlMsgOutAction (pScsiCtrl, pThread);	    break;	    	case SCSI_MSG_IN_PHASE:	    status = scsiCtrlMsgInAction (pScsiCtrl, pThread);	    break;	    	default:	    SCSI_ERROR_MSG ("scsiCtrlNormalXfer: invalid phase (%d)\n",		      	    phase, 0, 0, 0, 0, 0);	    scsiCtrlThreadFail (pThread, S_scsiLib_INVALID_PHASE);	    return;	}    if (status != OK)        {        SCSI_ERROR_MSG ("scsiCtrlNormalXfer: transfer failed\n",			0, 0, 0, 0, 0, 0);	scsiCtrlThreadFail (pThread, errno);        }    }    /********************************************************************************* scsiCtrlAbortXfer - process info. xfer request for an aborting thread** Check that the phase requested is message out.  Transfer the single-byte* message out.  Set the thread's state to indicate that it's waiting for the* target to disconnect after an abort message.** RETURNS: N/A*/LOCAL void scsiCtrlAbortXfer    (    SCSI_THREAD * pThread,    SCSI_EVENT *  pEvent    )    {    SCSI_CTRL * pScsiCtrl = pThread->pScsiCtrl;        if (pThread->state != SCSI_THREAD_ABORTING)	{	logMsg ("scsiCtrlAbortXfer: invalid state (%d)\n",		pThread->state, 0, 0, 0, 0, 0);	return;	}        if (pEvent->phase != SCSI_MSG_OUT_PHASE)	{	SCSI_ERROR_MSG ("scsiCtrlAbortXfer: unexpected phase (%d) "			"requested during thread abort\n",		        pEvent->phase, 0, 0, 0, 0, 0);        return;	}    if ((*pScsiCtrl->scsiInfoXfer) (pScsiCtrl,				    SCSI_MSG_OUT_PHASE,                                    pScsiCtrl->msgOutBuf,				    1) != 1)        {        SCSI_ERROR_MSG ("scsiCtrlAbortXfer: message out transfer failed\n",			0, 0, 0, 0, 0, 0);        return;        }    scsiCtrlThreadStateSet (pThread, SCSI_THREAD_WAIT_ABORT);    }    /******************************************************************************** scsiCtrlDataOutAction - handle DATA OUT information transfer phase** Transfer out the remaining data count or the maximum possible for the* controller, whichever is the smaller.  Update the active data pointer* and count to reflect the number of bytes transferred - this may be fewer* than requested, e.g. if the target requests a different phase.** RETURNS: OK, or ERROR if transfer fails.*/LOCAL STATUS scsiCtrlDataOutAction    (    SCSI_CTRL   *pScsiCtrl,		/* ptr to SCSI controller info */    SCSI_THREAD *pThread		/* ptr to thread info */    )    {    UINT xferCount;			/* number of bytes transferred */    UINT maxBytes;			/* max number of bytes to send */    maxBytes = min (pThread->activeDataLength, pScsiCtrl->maxBytesPerXfer);        xferCount = (*pScsiCtrl->scsiInfoXfer) (pScsiCtrl,					    SCSI_DATA_OUT_PHASE,                                            pThread->activeDataAddress,                                            maxBytes);    if (xferCount == ERROR)    	return (ERROR);    pThread->activeDataAddress += xferCount;    pThread->activeDataLength  -= xferCount;    return (OK);    }/******************************************************************************** scsiCtrlDataInAction - handle DATA IN information transfer phase** Transfer in the remaining data count or the maximum possible for the* controller, whichever is the smaller.  Update the active data pointer* and count to reflect the number of bytes transferred - this may be fewer* than requested, e.g. if the target requests a different phase.** NOTE: the "additional length byte" handling done in previous versions of* the SCSI library is unnecessary when disconnect/reconnect is supported.** SCSI requires the target to honour the initiator's maximum allocation* length, so there can never be more incoming data than was requested.* Conversely, if the target has less data to send than the initiator* expects, it will simply terminate the DATA IN transfer phase early.** Unfortunately the currently defined SCSI transaction interface does not* allow the client task to find out how many data bytes were actually* received in either case.* * RETURNS: OK, or ERROR if transfer fails.*/LOCAL STATUS scsiCtrlDataInAction    (    SCSI_CTRL   *pScsiCtrl,		/* ptr to SCSI controller info */    SCSI_THREAD *pThread		/* ptr to thread info */    )    {    UINT xferCount;			/* number of bytes transferred */    UINT maxBytes;			/* max number of bytes to recv */    maxBytes = min (pThread->activeDataLength, pScsiCtrl->maxBytesPerXfer);        xferCount = (*pScsiCtrl->scsiInfoXfer) (pScsiCtrl,					    SCSI_DATA_IN_PHASE,                                            pThread->activeDataAddress,                                            maxBytes);    if (xferCount == ERROR)    	return (ERROR);    pThread->activeDataAddress += xferCount;    pThread->activeDataLength  -= xferCount;    return (OK);    }/******************************************************************************** scsiCtrlCommandAction - handle COMMAND information transfer phase** Note: it is assumed that a command transfer must be completed fully, i.e.* the target cannot disconnect.  It is also assumed that the length of a* command transfer never exceeds the maximum byte count the controller can* handle.** RETURNS: OK, or ERROR if transfer fails.*/LOCAL STATUS scsiCtrlCommandAction    (    SCSI_CTRL   *pScsiCtrl,		/* ptr to SCSI controller info */    SCSI_THREAD *pThread		/* ptr to thread info */    )    {    UINT xferCount;			/* number of bytes transferred */    xferCount = (*pScsiCtrl->scsiInfoXfer) (pScsiCtrl,					    SCSI_COMMAND_PHASE,                                            pThread->cmdAddress,                                            pThread->cmdLength);    return ((xferCount == pThread->cmdLength) ? OK : ERROR);    }/******************************************************************************** scsiCtrlStatusAction - handle STATUS information transfer phase** Note: it is assumed that a status transfer must be completed fully, i.e.* the target cannot disconnect.  It is also assumed that the length of a* status transfer never exceeds the maximum byte count the controller can* handle.** RETURNS: OK, or ERROR if transfer fails.*/LOCAL STATUS scsiCtrlStatusAction    (    SCSI_CTRL   *pScsiCtrl,		/* ptr to SCSI controller info */    SCSI_THREAD *pThread		/* ptr to thread info */    )    {    UINT xferCount;			/* number of bytes transferred */    xferCount = (*pScsiCtrl->scsiInfoXfer) (pScsiCtrl,					    SCSI_STATUS_PHASE,                                            pThread->statusAddress,                                            pThread->statusLength);

⌨️ 快捷键说明

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