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

📄 aic7880lib.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    pScsiCtrl->scsiEventProc       = (VOIDFUNCPTR) aic7880Event;    pScsiCtrl->scsiTransact        = (FUNCPTR)     scsiTransact;    pScsiCtrl->scsiThreadInit      = (FUNCPTR)     aic7880ThreadInit;    pScsiCtrl->scsiThreadAbort     = (FUNCPTR)     aic7880ThreadAbort;    pScsiCtrl->scsiThreadActivate  = (FUNCPTR)     aic7880ThreadActivate;    pScsiCtrl->scsiBusControl      = (FUNCPTR)     aic7880ScsiBusControl;    pScsiCtrl->scsiSpecialHandler  = (FUNCPTR)     aic7880DummyHandler;    pScsiCtrl->scsiXferParamsQuery = (FUNCPTR)     aic7880XferParamsQuery;    pScsiCtrl->scsiXferParamsSet   = (FUNCPTR)     aic7880XferParamsSet;    pScsiCtrl->scsiWideXferParamsSet   = (FUNCPTR) aic7880WideXferParamsSet;    /* SCSI Host Adapter supports 16 bit wide bus */    pScsiCtrl->wideXfer = TRUE;    /* fill in the generic SCSI info for this controller */    scsiCtrlInit (&aic7880Ctrl->scsiCtrl);     pScsiCtrl->scsiMgrId = taskSpawn (aic7880ScsiTaskName,                                      aic7880ScsiTaskPriority,                                      aic7880ScsiTaskOptions,                                      aic7880ScsiTaskStackSize,                                      (FUNCPTR) scsiMgr,                                      (int) aic7880Ctrl,				      0, 0, 0, 0, 0, 0, 0, 0, 0);     return (aic7880Ctrl);    }/********************************************************************************* aic7880ThreadInit - initialize a client thread structure** Initialize the fixed data for a thread. Memory for the SCB (SCSI Command* Block) structure within the thread is allocated and initialized. Memory* for the scatter / gather  list structure is also allocated in this routine.* This routine is called once when a thread structure is first created. Memory* for a thread structure is allocated in function scsiThreadArrayCreate in * scsi2Lib.c** RETURNS: OK, or ERROR if memory is unavailable.*/LOCAL STATUS aic7880ThreadInit    (    SIOP            * pSiop,   /* ptr to aic7880 Controller struct */    AIC_7880_THREAD * pThread  /* ptr to an aic7880 thread structure */    )    {    sp_struct * pScb;    SEG_PTR   * segPtr;    int nBytes;    if (scsiThreadInit (&pThread->scsiThread) != OK)        return (ERROR);    /* allocate a SCSI Command Block structure */    if ((pScb = (sp_struct *) KMEM_ALLOC(sizeof (sp_struct))) == NULL)        {        SCSI_DEBUG_MSG ("Could not allocate memory for sp_struct\n",		       0, 0, 0, 0, 0, 0);        return (ERROR);        }    nBytes = sizeof (sp_struct);    bzero ((char *) pScb, nBytes);    /* driver can determine which SCSI thread belongs to the SCB */     pScb->pThread = pThread;    /* allocate memory for the scatter/gather list */    if ((segPtr = (SEG_PTR *) KMEM_ALLOC(sizeof (SEG_PTR))) == NULL)	{	SCSI_DEBUG_MSG ("Could not allocate memory for Scatter/Gather list\n",                       0, 0, 0, 0, 0, 0);        return (ERROR);        }    /* initialize the thread pointers to the SCB and the scatter/gather list */    pThread->pScb = pScb;    pThread->segPtr = segPtr;    return (OK);    }/********************************************************************************* aic7880ThreadActivate - activate a SCSI connection for an initiator thread** This routine activates the client thread after updating the contents of the* SCB with information needed to execute a SCSI transaction. Cache Coherency* is ensured prior to thread execution. Sync/Wide Xfer parameters are * re-negotiated if neccessary prior to the activation of each thread. * After the SCSI thread has been activated the state of the thread is set to * reflect the current status.** RETURNS: OK or ERROR if unable to activate thread.*/LOCAL STATUS aic7880ThreadActivate    (    SIOP            * pSiop,            /* ptr to controller info */    AIC_7880_THREAD * pThread           /* ptr to thread info     */    )    {    SCSI_CTRL   * pScsiCtrl   = (SCSI_CTRL *)   pSiop;    SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread;    SCSI_TARGET * pScsiTarget  = pScsiThread->pScsiTarget;    SCSI_DEBUG_MSG ("aic7880ThreadActivate: thread 0x%08x: activating\n",                    (int) pThread, 0, 0, 0, 0, 0);    scsiCacheSynchronize (pScsiThread, SCSI_CACHE_PRE_COMMAND);    aic7880ThreadUpdate (pSiop, pThread);    /*      * set the thread pointer in the generic SCSI Controller to      * point to the thread being activated.     */    pScsiCtrl->pThread = pScsiThread;    pSiop->pHwThread   = pThread;    scsiWideXferNegotiate (pScsiCtrl, pScsiTarget, WIDE_XFER_NEW_THREAD);    scsiSyncXferNegotiate (pScsiCtrl, pScsiTarget, SYNC_XFER_NEW_THREAD);     aic7880Activate (pThread);    aic7880ThreadStateSet (pThread, SCSI_THREAD_ESTABLISHED);    return (OK);    }/********************************************************************************* aic7880ThreadUpdate - update the thread structure for a current SCSI command** This routine fills up the SCB (SCSI Command Block) with the information * needed by the Sequencer to execute a SCSI transaction.** RETURNS: N/A*/LOCAL VOID aic7880ThreadUpdate     (    SIOP            * pSiop,     /* ptr to controller info */    AIC_7880_THREAD * pThread    /* thread info */    )    {    SCSI_THREAD   * pScsiThread  = (SCSI_THREAD *) pThread;    SCSI_PHYS_DEV * pScsiPhysDev = pScsiThread->pScsiPhysDev;    SCSI_TARGET   * pScsiTarget  = pScsiThread->pScsiTarget;    UINT            busId        = pScsiTarget->scsiDevBusId;    UINT            devLun       = pScsiPhysDev->scsiDevLUN;    sp_struct * pScb;   /* pointer to the SCSI Command Block */    pScb = pThread->pScb;     /*     * fill in the Scatter/Gather list Segment pointer with      * the address of the first byte to be transferred and     * the length of the data to be transferred during the     * data phase of the SCSI command.     */    pThread->segPtr->dataPtr = \	AIC_7880_VIRT_TO_PHYS(pScsiThread->dataAddress);    pThread->segPtr->dataLen = pScsiThread->dataLength;    /*      * virtual pointer to the config data structure associated     * with the AIC 7880 to which the SCB is loaded.     */        pScb->Sp_config.ConfigPtr = (struct cfp *) \	AIC_7880_VIRT_TO_PHYS(pSiop->aic7880CfpStruct);    /* internal SCB Access SCSI command */    pScb->Sp_control.Cmd = EXEC_SCB;     pScb->SP_Next     = 0;    pScb->SP_ResCnt   = 0;    pScb->SP_HaStat   = 0;    pScb->SP_TargStat = 0;    /* disable automatic Req Sense */    pScb->Sp_control.AutoSense = 0;    /* do not report underrun as an error */    pScb->Sp_control.NoUnderrun = 1;    /*     * indicate the specific target/Logical unit for which     * the SCB is to be executed.     */    pScb->SP_Tarlun = (busId << 4) | devLun;    /*      * enable or disable disconnects and command queue      * tagging. Also set the appropriate tag type      */    if ((pScsiThread->tagType == SCSI_TAG_SIMPLE) ||	(pScsiThread->tagType == SCSI_TAG_ORDERED) ||	(pScsiThread->tagType == SCSI_TAG_HEAD_OF_Q))	{	if (pScsiThread->tagType == SCSI_TAG_SIMPLE)	    pScb->SP_TagType = SIMPLE_QUEUE_TAG;	else if (pScsiThread->tagType == SCSI_TAG_ORDERED)	    pScb->SP_TagType = ORDERED_QUEUE_TAG;	else if (pScsiThread->tagType == SCSI_TAG_HEAD_OF_Q)	    pScb->SP_TagType = HEAD_OF_QUEUE_TAG;	pScb->SP_TagEnable = 1;	if (pScsiTarget->disconnect)	    pScb->SP_DisEnable = 1;	else	    pScb->SP_DisEnable = 0;	}    else	{	pScb->SP_TagEnable = 0;        pScb->SP_DisEnable = 0;	}    /*      * A value of 1 indicates that the data to be transferred from     * host memory is contiguous. In VxWorks since there is a one      * to one correspondence between virtual and physical memory and     * this field is set to one for all data transfers.     */    if (pScsiThread->dataLength)	pScb->SP_SegCnt = 1;    else	pScb->SP_SegCnt = 0;    /*      * This field indicates to the sequencer whether the data to be     * transferred to or from host memory is contiguous. This bit     * should be set to one if the SegCnt field is greater than one     */    if (pScb->SP_SegCnt > 1)	pScb->SP_RejectMDP = 1;    else	pScb->SP_RejectMDP = 0;    pScb->SP_SegPtr = \	AIC_7880_VIRT_TO_PHYS(pThread->segPtr);    /* fill in the command descriptor block */    bcopy (pScsiThread->cmdAddress, pScb->Sp_CDB, pScsiThread->cmdLength);    /*      * set the command length and the command pointer fields to      * point to the appropriate SCSI command.     */    pScb->SP_CDBLen = (DWORD) pScsiThread->cmdLength;    pScb->SP_CDBPtr = AIC_7880_VIRT_TO_PHYS(pScb->Sp_CDB);    }/******************************************************************************** aic7880Activate - activate an SCB corresponding to a new thread** This routine activates the SCB corresponding to the new thread and then * calls the HIM function PH_ScbSend with a pointer to the SCB. If the HIM is * busy the SCB is queued for later execution, otherwise it begins execution* of the SCB immediately.** RETURNS: N/A*/LOCAL VOID aic7880Activate    (    AIC_7880_THREAD * pThread  /* ptr to thread info */    )    {    sp_struct * pScb;   /* pointer to the SCSI Command Block */    pScb = pThread->pScb;    /* send the thread for execution to the Sequencer */    PH_ScbSend (pScb);    }/******************************************************************************** aic7880ThreadStateSet - set the state of a thread** This routine sets the state of the current thread. The SCSI Thread* maintains only four states for this driver SCSI_THREAD_WAITING, * SCSI_THREAD_ESTABLISHED, SCSI_THREAD_INACTIVE and SCSI_THREAD_ABORTING. * Disconnects / Reconnects are handled by the Sequencer.** RETURNS: N/A*/LOCAL VOID aic7880ThreadStateSet    (    AIC_7880_THREAD   *  pThread,          /* ptr to thread info */    SCSI_THREAD_STATE    state             /* thread state */    )    {    SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread;    SCSI_DEBUG_MSG ("aic78800ThreadStateSet: thread 0x%08x: %d -> %d\n",                    (int) pThread, pScsiThread->state, state, 0, 0, 0);    pScsiThread->state = state;    }/********************************************************************************* aic7880Intr - interrupt service routine for the SIOP** This routine is invoked when an aic7880 Host Adapter interrupt occurs.* Although most interrupts are due to a Command Completed interrupt, the* Sequencer code could also interrupt the host to handle abnormal SCSI phases* and errors. This routine calls the HIM "PH_IntHandler" routine with the * cfp_struct pointer associated with appropriate AIC-7880 passed in. The HIM* handles the interrupt and returns with a status. The function then issues* an EOI if the returned status from "PH_IntHandler" indicates that it handled* the interrupt. In case of shared IRQ's the returned status may indicate that* no interupt was handled for this host adapter.** RETURNS: N/A.** NOMANUAL*/VOID aic7880Intr     (    SIOP * pSiop    /* ptr to controller info */    )    {    cfp_struct      * pCfpStruct;    UBYTE             intrStatus;    pCfpStruct = pSiop->aic7880CfpStruct;    intrStatus = PH_IntHandler (pCfpStruct);    intrStatus &= INTMASK;    /* send  EOI (End of Interrupt) signal. */     if (intrStatus)	SCSI_DEBUG_MSG ("aic7880Intr pSiop = 0x%lx\n",(int) pSiop, 			0, 0, 0, 0, 0);    }    /********************************************************************************* aic7880ScbCompleted - successfully completed execution of a client thread** This routine is called from within the context of the ISR. The HIM calls* this routine passing in the pointer of the of the completed SCB. This* routine sets the thread status, handles the completed SCB and returns* program control back to the HIM which then returns from the PH_IntHandler * routine.** This routine could be called more than once from the same PH_IntHandler* call. Each call to this routine indicates the completion of an SCB. For* each SCB completed, this routine sets the event type and calls the * appropriate AIC-7880 event handler routines which sets the SCSI Controller,* SCSI Physical Device and SCSI Thread, state variables appropriately.* This routine also handles synchronization with the SCSI Manager so that* the next runnable thread can be scheduled for execution.** RETURNS: N/A**/VOID aic7880ScbCompleted     (    sp_struct * pScb  /* ptr to completed SCSI Command Block */    )    {    AIC_7880_THREAD * pThread = pScb->pThread;    SCSI_THREAD     * pScsiThread = (SCSI_THREAD *) pThread;    SCSI_THREAD     * pSavedThread;    SCSI_CTRL       * pScsiCtrl = pScsiThread->pScsiCtrl;    SIOP            * pSiop = (SIOP *) pScsiCtrl;    SCSI_EVENT        pScsiEvent;    BOOL              notify    = TRUE;    DWORD             cmdStatus;         /* SCB command status */    DWORD             haStatus;          /* host adapter status */    /* update the status of the SCSI thread */    pScsiThread->status = (STATUS) pScb->SP_TargStat;    *pScsiThread->statusAddress = pScsiThread->status;    /* save the current H/W thread that may have been activated */        pSavedThread = (SCSI_THREAD *) pSiop->pHwThread;    /*      * set the generic SCSI C0ntrollers thread to point to the     * thread that has just compeleted execution.      */    pScsiCtrl->pThread = pScsiThread;        /* check the SCB command status */

⌨️ 快捷键说明

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