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

📄 scsictrllib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
    switch (pEvent->type)	{	case SCSI_EVENT_CONNECTED:    	    scsiCtrlThreadConnect (pThread, pEvent);	    break;	case SCSI_EVENT_DISCONNECTED:    	    scsiCtrlThreadDisconnect (pThread, pEvent);	    break;	case SCSI_EVENT_SELECTED:	case SCSI_EVENT_RESELECTED:    	    scsiCtrlThreadSelect (pThread, pEvent);	    break;	case SCSI_EVENT_XFER_REQUEST:    	    scsiCtrlThreadInfoXfer (pThread, pEvent);	    break;	case SCSI_EVENT_TIMEOUT:    	    scsiCtrlThreadFail (pThread, S_scsiLib_SELECT_TIMEOUT);	    break;        case SCSI_EVENT_PARITY_ERR:	    errnoSet (S_scsiLib_HARDWARE_ERROR);    	    scsiCtrlThreadFail (pThread, S_scsiLib_HARDWARE_ERROR);	    break;	case SCSI_EVENT_BUS_RESET:	    /* SCSI manager handles this */	    scsiCtrlThreadStateSet (pThread, SCSI_THREAD_INACTIVE);	    break;	default:	    logMsg ("scsiCtrlThreadEvent: invalid event type (%d)\n",		    pEvent->type, 0, 0, 0, 0, 0);	    break;	}    switch (pThread->state)	{	case SCSI_THREAD_ESTABLISHED:	    /* assert ATN if there is a pending message out */	    if (pScsiCtrl->msgOutState == SCSI_MSG_OUT_PENDING)	    	{	    	if ((*pScsiCtrl->scsiBusControl) (pScsiCtrl,					      	  SCSI_BUS_ASSERT_ATN) != OK)		    {		    SCSI_ERROR_MSG ("scsiCtrlEvent: failed to assert ATN.\n",				    0, 0, 0, 0, 0, 0);		    scsiCtrlThreadFail (pThread, errno);		    }		}	    break;	default:	    break;	}    }    /********************************************************************************* scsiCtrlThreadConnect - thread connection event processing routine** Set transfer parameters for the newly connected thread.  Set the thread* state to ESTABLISHED if the whole identification message has been sent,* otherwise set its state to IDENTIFICATION OUT.** RETURNS: N/A*/LOCAL void scsiCtrlThreadConnect    (    SCSI_THREAD * pThread,    SCSI_EVENT *  pEvent    )    {    SCSI_PHYS_DEV * pScsiPhysDev = pThread->pScsiPhysDev;    SCSI_TARGET *   pScsiTarget  = pThread->pScsiTarget;        if (pThread->state != SCSI_THREAD_CONNECTING)	{	logMsg ("scsiCtrlThreadConnect: thread 0x%08x: invalid state (%d)\n",		(int) pThread, pThread->state, 0, 0, 0, 0);	return;	}    SCSI_DEBUG_MSG ("scsi: connected to target %d, phys dev = 0x%08x\n",		    pScsiTarget->scsiDevBusId, (int)pScsiPhysDev, 0, 0, 0, 0);    pThread->nBytesIdent = pEvent->nBytesIdent;    if (scsiCtrlXferParamsSet (pThread) != OK)	{        scsiCtrlThreadFail (pThread, errno);	return;	}    if (pThread->nBytesIdent < pThread->identMsgLength)	{    	scsiCtrlThreadStateSet (pThread, SCSI_THREAD_IDENT_OUT);	}    else	{	scsiCtrlThreadStateSet (pThread, SCSI_THREAD_ESTABLISHED);	}    }/********************************************************************************* scsiCtrlThreadDisconnect - thread disconnect event processing routine** There are basically three cases:**   1)	after a DISCONNECT message has been received: disconnect the thread**   2)	after a COMMAND COMPLETE message has been received, or an ABORT*   	message has been sent, complete the thread normally**   3)	otherwise, fail the thread with an "unexpected disconnection" error** RETURNS: N/A*/LOCAL void scsiCtrlThreadDisconnect    (    SCSI_THREAD * pThread,    SCSI_EVENT *  pEvent    )    {    if (pThread->pScsiCtrl->msgOutState == SCSI_MSG_OUT_PENDING)	{	SCSI_DEBUG_MSG ("scsiCtrlThreadDisconnect: thread 0x%08x: "			"message out not sent (ignored).\n",			(int) pThread, 0, 0, 0, 0, 0);	}    switch (pThread->state)	{	case SCSI_THREAD_WAIT_DISCONNECT:    	    scsiMgrThreadEvent (pThread, SCSI_THREAD_EVENT_DISCONNECTED);    	    scsiCtrlThreadStateSet (pThread, SCSI_THREAD_DISCONNECTED);	    break;	case SCSI_THREAD_WAIT_COMPLETE:	    scsiCtrlThreadComplete (pThread);	    break;	case SCSI_THREAD_WAIT_ABORT:	    scsiCtrlThreadComplete (pThread);	    break;	default:	    SCSI_ERROR_MSG ("scsiCtrlThreadDisconnect: thread 0x%08x: "			    "unexpected disconnection\n",			    (int) pThread, 0, 0, 0, 0, 0);	    scsiCtrlThreadFail (pThread, S_scsiLib_DISCONNECTED);	    break;	}    }    /********************************************************************************* scsiCtrlThreadSelect - thread selection event processing routine** Forward the event to the proper handler depending on the role played by* the thread.** RETURNS: N/A*/LOCAL void scsiCtrlThreadSelect    (    SCSI_THREAD * pThread,    SCSI_EVENT *  pEvent    )    {    switch (pThread->state)	{	case SCSI_THREAD_CONNECTING:	    scsiCtrlThreadDefer (pThread);	    break;	case SCSI_THREAD_INACTIVE:	    scsiCtrlIdentInCommence (pThread, pEvent);	    break;	default:	    logMsg ("scsiCtrlThreadConnect: thread 0x%08x: "		    "invalid state (%d)\n",		    (int) pThread, pThread->state, 0, 0, 0, 0);	    break;	}    }/********************************************************************************* scsiCtrlThreadInfoXfer - thread info transfer request event processing** Forward the event to the proper handler depending on the thread's current* state.** RETURNS: N/A*/LOCAL void scsiCtrlThreadInfoXfer    (    SCSI_THREAD * pThread,    SCSI_EVENT *  pEvent    )    {    switch (pThread->state)	{	case SCSI_THREAD_IDENT_OUT:	    scsiCtrlIdentOutXfer (pThread, pEvent);	    break;	case SCSI_THREAD_IDENT_IN:	    scsiCtrlIdentInXfer (pThread, pEvent);	    break;	case SCSI_THREAD_ABORTING:	    scsiCtrlAbortXfer (pThread, pEvent);	    break;	    	default:	    scsiCtrlNormalXfer (pThread, pEvent);	    break;	}    }    /********************************************************************************* scsiCtrlIdentOutXfer - process info. xfer request during identification out** Check that a message out transfer is being requested: fail the thread if* not.  Transfer the remainder of the identification message, including a* queue tag message if applicable.  Set the thread state to ESTABLISHED.** This code assumes that the target cannot request a new info transfer phase* until it has read the entire identification sequence (either 1 or 3 bytes).* (This seems to be required by the SCSI standard.)** RETURNS: N/A*/LOCAL void scsiCtrlIdentOutXfer    (    SCSI_THREAD * pThread,    SCSI_EVENT *  pEvent    )    {    SCSI_CTRL * pScsiCtrl = pThread->pScsiCtrl;    int         nBytes;    int         maxBytes;    /*     *	Check for logical errors     */    if (pThread->state != SCSI_THREAD_IDENT_OUT)	{	logMsg ("scsiCtrlIdentOutXfer: invalid state (%d)\n",		pThread->state, 0, 0, 0, 0, 0);	return;	}        if ((maxBytes = pThread->identMsgLength - pThread->nBytesIdent) == 0)	{	logMsg ("scsiCtrlIdentOutXfer: no identification message!\n",		0, 0, 0, 0, 0, 0);	return;	}        if (pEvent->phase != SCSI_MSG_OUT_PHASE)	{	SCSI_ERROR_MSG ("scsiCtrlIdentOutXfer: unexpected phase (%d) "			"requested during identification out\n",		        pEvent->phase, 0, 0, 0, 0, 0);	scsiCtrlThreadFail (pThread, S_scsiLib_INVALID_PHASE);        return;	}    /*     *	Transfer the whole remaining identification sequence (in one go)     */    nBytes = (*pScsiCtrl->scsiInfoXfer) (pScsiCtrl,				         SCSI_MSG_OUT_PHASE,                                         pThread->identMsg + pThread->nBytesIdent,				         maxBytes);    pThread->nBytesIdent += nBytes;    if (nBytes != maxBytes)        {	/*	 *  The target has most likely requested a new phase.  The only	 *  legitimate reason for this is to reject a queue tag message if	 *  it does not support queueing - this should be dealt with by the	 *  normal message reject mechanism.  (The thread should be treated	 *  as if it were untagged.)	 *	 *  Hence, we continue and set the thread established anyway.	 */        SCSI_DEBUG_MSG ("scsiCtrlIdentOutXfer: identification incomplete - "			"%d of %d bytes sent\n",			pThread->nBytesIdent, pThread->identMsgLength,    	    	    	0, 0, 0, 0);	        }    scsiCtrlThreadStateSet (pThread, SCSI_THREAD_ESTABLISHED);    }    /********************************************************************************* scsiCtrlIdentInCommence - commence incoming identification** Copy the identification message read by the driver into the thread's buffer.* Parse the identification message so far (see "scsiCtrlIdentInContinue()").* Acknowledge the last message-in byte read (if any).** RETURNS: N/A*/LOCAL void scsiCtrlIdentInCommence    (    SCSI_THREAD * pThread,    SCSI_EVENT *  pEvent    )    {    bcopy ((char *)pEvent->identMsg, (char *)pThread->identMsg,	   pEvent->nBytesIdent);    pThread->nBytesIdent = pEvent->nBytesIdent;    scsiCtrlIdentInContinue (pThread);    if (pThread->nBytesIdent > 0)	{	scsiCtrlMsgInAck (pThread->pScsiCtrl);	}    }    /********************************************************************************* scsiCtrlIdentInXfer - process info. xfer during incoming identification.** Check that a message in transfer is being requested; if not, fail the* thread (even though, at this stage, it's not a client thread).  Transfer* the message byte in, then parse the message so far.  Acknowledge the* message in byte.** RETURNS: N/A*/LOCAL void scsiCtrlIdentInXfer    (    SCSI_THREAD * pThread,    SCSI_EVENT *  pEvent    )    {    SCSI_CTRL * pScsiCtrl = pThread->pScsiCtrl;        if (pThread->state != SCSI_THREAD_IDENT_IN)	{	logMsg ("scsiCtrlIdentInXfer: invalid state (%d)\n",		pThread->state, 0, 0, 0, 0, 0);	return;	}        if (pEvent->phase != SCSI_MSG_IN_PHASE)	{	SCSI_ERROR_MSG ("scsiCtrlIdentInXfer: unexpected phase (%d) "			"requested during identification in\n",		        pEvent->phase, 0, 0, 0, 0, 0);	scsiCtrlThreadFail (pThread, 0);        return;	}    if ((*pScsiCtrl->scsiInfoXfer) (pScsiCtrl,				    SCSI_MSG_IN_PHASE,                                    pThread->identMsg + pThread->nBytesIdent,				    1) != 1)        {        SCSI_ERROR_MSG ("scsiCtrlIdentInXfer: message in transfer failed\n",			0, 0, 0, 0, 0, 0);		scsiCtrlThreadFail (pThread, 0);        return;        }    ++pThread->nBytesIdent;    scsiCtrlIdentInContinue (pThread);    scsiCtrlMsgInAck (pScsiCtrl);    }    /********************************************************************************* scsiCtrlIdentInContinue - continue incoming identification** Parse the message built up so far.  If it is not yet complete, do nothing.* If the message is complete, attempt to reconnect the thread it identifies,* and deactivate this thread (the identification thread is no longer active).* Otherwise (identification has failed), abort the identification sequence.** RETURNS: N/A*/LOCAL void scsiCtrlIdentInContinue    (    SCSI_THREAD * pThread    )    {    SCSI_THREAD * pNewThread;    SCSI_CTRL   * pScsiCtrl  = pThread->pScsiCtrl;    SCSI_IDENT_STATUS status;    SCSI_THREAD_STATE state;

⌨️ 快捷键说明

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