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

📄 aic7880lib.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        cmdStatus = pScb->SP_Stat;    switch (cmdStatus) 	{	case AIC_7880_CMD_COMPLETE:	    pScsiEvent.type = AIC_7880_CMD_COMPLETE;            break;	            case AIC_7880_CMD_COMP_WITH_ERROR:	    haStatus = pScb->SP_HaStat;	    switch (haStatus)		{		case AIC_7880_NO_STATUS:		    SCSI_DEBUG_MSG ("No Status\n", 0, 0, 0, 0, 0, 0);		    pScsiEvent.type = AIC_7880_CMD_COMPLETE;		    break;		case AIC_7880_CMD_ABORT:		case AIC_7880_CMD_ABORT_BY_HA:		    SCSI_DEBUG_MSG ("SCSI Command Abort\n", 0,0,0,0,0,0);		    pScsiEvent.type = AIC_7880_CMD_COMPLETE;		    break;		case AIC_7880_UNEXPECTED_BUS_FREE:		    SCSI_DEBUG_MSG ("Unexpected Bus Free\n", 0,0,0,0,0,0);		    pScsiEvent.type = AIC_7880_SCSI_BUS_RESET;		    break;					case AIC_7880_PHASE_MISMATCH:		    SCSI_DEBUG_MSG ("Phase Mismatch occured\n", 0,0,0,0,0,0);		    pScsiEvent.type = AIC_7880_SCSI_BUS_RESET;		    break;		case AIC_7880_HA_HW_ERROR:		    SCSI_DEBUG_MSG ("Host Adapter H/W error\n", 0,0,0,0,0,0);		    pScsiEvent.type = AIC_7880_SCSI_BUS_RESET;		    break;			  		case AIC_7880_BUS_RESET:		case AIC_7880_BUS_RESET_OTHER_DEV:		    SCSI_DEBUG_MSG ("SCSI Bus Reset\n", 0,0,0,0,0,0);		    pScsiEvent.type = AIC_7880_SCSI_BUS_RESET;		    break;		case AIC_7880_SELECT_TIMEOUT:		    SCSI_DEBUG_MSG ("Device Selction Timeout\n", 0,0,0,0,0,0);		    pScsiEvent.type = AIC_7880_SELECT_TIMEOUT;		    break;		case AIC_7880_REQ_SENSE_FAILED:		    SCSI_DEBUG_MSG ("Request Sense Failed\n",0,0,0,0,0,0);		    notify = FALSE;		    break;		default:		    SCSI_DEBUG_MSG ("aic7880Intr: unexpt'd host adap'r intr\n",				   0,0,0,0,0,0);		    break;		}	    break;	    	default:	    notify = FALSE;            SCSI_DEBUG_MSG ("aic7880ScbCompleted: unexpected interupt\n", 			    0, 0, 0, 0, 0, 0);             break;         }    if (notify)	{	aic7880Event (pSiop, &pScsiEvent);	semGive (pScsiCtrl->actionSem);	}        /* restore the current H/W thread */    pScsiCtrl->pThread = pSavedThread;    }/********************************************************************************* aic7880Event - AIC 788 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 completed* thread for thread-level processing. The SCSI Controllers state variables* are set to indicate if the controller is connected or disconnected. When* a thread is activated the Controllers state is set to CONNECTED and when* the thread has completed execution or if a SCSI Bus Reset has occured the* Controllers state is set to DISCONNECTED.** RETURNS: N/A*/LOCAL VOID aic7880Event    (    SIOP       * pSiop,         /* ptr to controller info */    SCSI_EVENT * pScsiEvent     /* ptr to SCSI EVENT      */    )    {    SCSI_CTRL       * pScsiCtrl  = (SCSI_CTRL *)  pSiop;    AIC_7880_THREAD * pThread    = (AIC_7880_THREAD *) pScsiCtrl->pThread;    SCSI_DEBUG_MSG ("aic7880Event: received event %d (thread = 0x%08x)\n",                     pScsiEvent->type, (int) pThread, 0, 0, 0, 0);    switch (pScsiEvent->type)	{	case AIC_7880_CMD_COMPLETE:	case AIC_7880_SELECT_TIMEOUT:            pScsiCtrl->peerBusId = NONE;            pScsiCtrl->pThread   = 0;            scsiMgrCtrlEvent (pScsiCtrl, SCSI_EVENT_DISCONNECTED);            break;        case AIC_7880_SCSI_BUS_RESET:            pScsiCtrl->peerBusId = NONE;            pScsiCtrl->pThread   = 0;            scsiMgrBusReset (pScsiCtrl);            break;	            default:	    logMsg ("aic7880Event: invalid event type.\n", 0, 0, 0, 0, 0, 0);            break;	}    /* If there's a thread on the controller, forward the event to it */    if (pThread != 0)        aic7880ThreadEvent (pThread, pScsiEvent);    }/********************************************************************************* aic7880ThreadEvent - AIC 7880 thread event processing routine** Forward the event to the proper handler for the thread's current role.** RETURNS: N/A*/LOCAL VOID aic7880ThreadEvent    (    AIC_7880_THREAD * pThread,    /* ptr to aci7880 thread info */    SCSI_EVENT      * pScsiEvent  /* ptr to SCSI EVENT */    )    {    SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread;    switch (pScsiThread->role)        {        case SCSI_ROLE_INITIATOR:            aic7880InitEvent (pThread, pScsiEvent);            break;        default:            logMsg ("aic7880ThreadEvent: thread 0x%08x: invalid role (%d)\n",                    (int) pThread, pScsiThread->role, 0, 0, 0, 0);            break;	}    }/********************************************************************************* aic7880InitEvent - AIC 7880 initiator thread event processing routine** Parse the event type and handle it accordingly.  This may result in state* changes for the thread, state variables being updated, etc.** RETURNS: N/A*/LOCAL VOID aic7880InitEvent    (    AIC_7880_THREAD * pThread,    /* ptr to aci7880 thread info */    SCSI_EVENT      * pScsiEvent  /* ptr to SCSI EVENT */    )    {    switch (pScsiEvent->type)	{        case AIC_7880_CMD_COMPLETE:            aic7880ThreadComplete (pThread);            break;	case AIC_7880_SELECT_TIMEOUT:            SCSI_ERROR_MSG ("aic7880InitEvent: thread 0x%08x: timeout.\n",                            (int) pThread, 0, 0, 0, 0, 0);	    	    aic7880ThreadFail (pThread, S_scsiLib_SELECT_TIMEOUT);	    break;        default:            logMsg ("aic7880InitEvent: invalid event type (%d)\n",                     pScsiEvent->type, 0, 0, 0, 0, 0);            break;	}    }/********************************************************************************* aic7880DummyHandler - used by scsi2Lib.c to do special handling ** This routine is used by scsiMgrLib.c and scsi2Lib.c to perform certain* functions specific to the AIC-7880 driver. Wide / Synchronous transfer* negotiations and thread activation are handled differently by scsi2Lib for * this driver.** RETURNS N/A*/LOCAL VOID aic7880DummyHandler    (    )    {    }/********************************************************************************* aic7880ThreadComplete - successfully complete execution of a client thread** Set the thread status and errno appropriately, depending on whether or* not the thread has been aborted.  Set the thread inactive, and notify* the SCSI manager of the completion.** RETURNS: N/A*/LOCAL VOID aic7880ThreadComplete    (    AIC_7880_THREAD * pThread    /* ptr to aci7880 thread info */    )    {    SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread;    if (pScsiThread->state == SCSI_THREAD_ABORTING)        {        pScsiThread->status = ERROR;        pScsiThread->errNum = S_scsiLib_ABORTED;        }    else        {        pScsiThread->status = OK;        pScsiThread->errNum = 0;        }    aic7880ThreadStateSet (pThread, SCSI_THREAD_INACTIVE);    scsiCacheSynchronize (pScsiThread, SCSI_CACHE_POST_COMMAND);    scsiMgrThreadEvent (pScsiThread, SCSI_THREAD_EVENT_COMPLETED);    }/********************************************************************************* aic7880ThreadFail - complete execution of a thread, with error status** Set the thread's status and errno according to the type of error.  Set* the thread's state to INACTIVE, and notify the SCSI manager of the* completion event.** RETURNS: N/A*/LOCAL VOID aic7880ThreadFail    (    AIC_7880_THREAD * pThread,   /* ptr to aci7880 thread info */    int               errNum     /* error number */    )    {    SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread;    SCSI_DEBUG_MSG ("aic7880ThreadFail: thread 0x%08x failed (errno = %d)\n",                    (int) pThread, errNum, 0, 0, 0, 0);    pScsiThread->status = ERROR;    if (pScsiThread->state == SCSI_THREAD_ABORTING)        pScsiThread->errNum = S_scsiLib_ABORTED;    else        pScsiThread->errNum = errNum;    aic7880ThreadStateSet (pThread, SCSI_THREAD_INACTIVE);    scsiMgrThreadEvent (pScsiThread, SCSI_THREAD_EVENT_COMPLETED);    }/********************************************************************************* aic7880ScsiBusControl - low-level SCSI bus control operations** Currently supports only the SCSI_BUS_RESET operation. After a SCSI Bus* Reset has occured the transfer parameters are re negotiated when a* new SCSI thread begins execution.** RETURNS: OK, or ERROR if an invalid operation is requested.*/LOCAL STATUS aic7880ScsiBusControl    (    SIOP * pSiop,           /* ptr to controller info                   */    int    operation        /* bitmask for operation(s) to be performed */    )    {    SCSI_CTRL       * pScsiCtrl  = (SCSI_CTRL *)  pSiop;    cfp_struct      * configPtr;    int               status;    int               i;    if ((operation & ~SCSI_BUS_RESET) != 0)        return (ERROR);        configPtr = pSiop->aic7880CfpStruct;    if (operation & SCSI_BUS_RESET)        if ((status = PH_Special (HARD_HA_RESET, configPtr, NULL))	    != OK)	    return (ERROR);    for (i = 0; i < configPtr->Cf_MaxTargets; i++)	configPtr->Cf_ScsiOption [i] = 0;        scsiMgrBusReset (pScsiCtrl);    return (OK);    }/********************************************************************************* aic7880XferParamsQuery - get synchronous transfer parameters** Query the AIC 7880 and see if it is capable of handling the specified* transfer parameters. If the AIC 7880 does not support the specified * period and offset this routine returns the offset and period values* the AIC 7880 is capable of handling.** RETURNS: OK*/LOCAL STATUS aic7880XferParamsQuery    (    SCSI_CTRL * pScsiCtrl,               /* ptr to controller info       */    UINT8     * pOffset,                 /* max REQ/ACK offset  [in/out] */    UINT8     * pPeriod                  /* min transfer period [in/out] */    )    {    UINT8 unused;        (VOID) aic7880XferParamsCvt ((SIOP *) pScsiCtrl, pOffset, pPeriod,				 &unused);    return (OK);    }/********************************************************************************* aic7880XferParamsCvt - convert transfer period from SCSI to AIC 7880 units.** Given a "suggested" REQ/ACK offset and transfer period (in SCSI units of* 4 ns), return the nearest offset and transfer period the AIC 7880 is* capable of using.** An offset of zero specifies asynchronous transfer, in which case the period* is irrelevant.  Otherwise, the offset specified is used if it lies within* the permissible range allowed by the AIC 7880.** The transfer period is normally rounded towards longer periods if the AIC* 7880 is not capable of using the exact specified value.** RETURNS: N/A.** NOMANUAL*/LOCAL VOID aic7880XferParamsCvt    (    FAST SIOP  * pSiop,            /* ptr to controller info            */    FAST UINT8 * pOffset,          /* REQ/ACK offset                    */    FAST UINT8 * pPeriod,          /* xfer period, SCSI units (x 4 ns)  */    FAST UINT8 * pXferRate         /* corresponding Sync Xfer Reg value */    )    {    cfp_struct * configPtr = pSiop->aic7880CfpStruct;    UINT  offset  = (UINT) * pOffset;    UINT  period  = (UINT) * pPeriod;    /* asynchronous xfer requested */    if (offset == SCSI_SYNC_XFER_ASYNC_OFFSET)        period = 0;    else        {        SCSI_DEBUG_MSG ("aic7880XferParamsCvt: requested: "			"offset = %d, period = %d\n",			 offset, period, 0, 0, 0, 0);		/* convert to nano seconds */	period *= 4;		if (configPtr->CFP_EnableFast20)	    {	    if (period <= 50)		{		period = AIC_7880_DBLSPD_50;		*pXferRate = 0x00;		}	    else if ((period > 50) && (period <= 64))		{		period = AIC_7880_DBLSPD_64;		*pXferRate = 0x10;		}	    else if (period > 65)		{		period = AIC_7880_DBLSPD_75;		*pXferRate = 0x20;		}	    }		else

⌨️ 快捷键说明

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