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

📄 aic7880lib.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    {	    /* standard fast SCSI mode */	     	    	    if (period <= 100)		{		period    = AIC_7880_PERIOD_100;		*pXferRate = 0x00;		}	    else if ((period > 100) && (period <= 125))		{		period = AIC_7880_PERIOD_125;		*pXferRate = 0x10;		}	    else if ((period > 125) && (period <= 150))		{		period = AIC_7880_PERIOD_150;		*pXferRate = 0x20;		}	    else if ((period > 150) && (period <= 175))		{		period = AIC_7880_PERIOD_175;		*pXferRate = 0x30;		}	    	    else if ((period > 175) && (period <= 200))		{		period = AIC_7880_PERIOD_200;		*pXferRate = 0x40;		}	    else if ((period > 200) && (period <= 225))		{		period = AIC_7880_PERIOD_225;		*pXferRate = 0x50;		}	    	    else if ((period > 225) && (period <= 250))		{		period = AIC_7880_PERIOD_250;		*pXferRate = 0x60;		}	    	    else if (period > 250)		{		period = AIC_7880_PERIOD_275;		*pXferRate = 0x70;		}	    }	/* adjust the synchronous offset to fit the allowable range */	    	if (offset < AIC_7880_MIN_REQ_ACK_OFFSET)	    offset = AIC_7880_MIN_REQ_ACK_OFFSET;		else if (offset > AIC_7880_MAX_REQ_ACK_OFFSET)	    offset = AIC_7880_MAX_REQ_ACK_OFFSET;		}    SCSI_DEBUG_MSG ("aic7880XferParamsCvt: converted to: "		    "offset = %d, period = %d\n",  		     offset, period, 0,0, 0, 0);        *pOffset   = offset;    *pPeriod   = period;    }/********************************************************************************* aic7880XferParamsSet - set transfer parameters** Set the transfer parameters specific to a thread.** Transfer period is specified in SCSI units (multiples of 4 ns).  An offset* of zero specifies asynchronous transfer.** RETURNS: OK or ERROR.*/LOCAL STATUS aic7880XferParamsSet    (    SCSI_CTRL * pScsiCtrl,		/* ptr to controller info */    UINT8       offset,			/* max REQ/ACK offset     */    UINT8       period			/* min transfer period    */    )    {    AIC_7880_THREAD * pThread = (AIC_7880_THREAD *) pScsiCtrl->pThread;    return (aic7880ThreadParamsSet (pThread, offset, period));    }/********************************************************************************* aic7880ThreadParamsSet - 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 or ERROR if it failed negotiation.*/LOCAL STATUS aic7880ThreadParamsSet    (    AIC_7880_THREAD * pThread,	    	/* thread to be affected  */    UINT8            offset,		/* max REQ/ACK offset     */    UINT8            period		/* min transfer period    */    )    {    SCSI_THREAD   * pScsiThread  = (SCSI_THREAD *) pThread;    SIOP          * pSiop        = (SIOP *) pScsiThread->pScsiCtrl;    cfp_struct    * pCfpStruct;    sp_struct     * pScb;    UINT8           xferRate;    UINT8           devBusId;    STATUS          status;    pScb = pThread->pScb;    devBusId = (pScb->SP_Tarlun >> 4) & 0x0f;    pCfpStruct = pSiop->aic7880CfpStruct;        aic7880XferParamsCvt (pSiop, &offset, &period, &xferRate);    offset = (offset - 1) << 1;    offset &= SOFS;    pCfpStruct->Cf_ScsiOption [devBusId] &= 0x80;    pCfpStruct->Cf_ScsiOption [devBusId] |= (xferRate | offset | SYNC_MODE);    pCfpStruct->CFP_SuppressNego = 0;    if ((status = (PH_Special (FORCE_RENEGOTIATE, pCfpStruct, pScb))) != OK)	{	SCSI_DEBUG_MSG ("aic7880ThreadParamsSet: Sync Negotiation Failed.\n",			 0, 0, 0, 0, 0, 0);	return (ERROR);	}    return (OK);    }/********************************************************************************* aic7880WideXferParamsSet - set wide transfer parameters** Assume valid parameters and set the AIC 7880's thread parameters to the* appropriate values.** RETURNS: OK or ERROR if it failed wide negotiation.*/LOCAL STATUS aic7880WideXferParamsSet    (    SCSI_CTRL * pScsiCtrl,		/* ptr to controller info */    UINT8       xferWidth               /* wide data transfer width */    )    {    AIC_7880_THREAD * pThread = (AIC_7880_THREAD *) pScsiCtrl->pThread;    SCSI_THREAD   * pScsiThread  = (SCSI_THREAD *) pThread;    SIOP          * pSiop        = (SIOP *) pScsiThread->pScsiCtrl;    cfp_struct    * pCfpStruct;    sp_struct     * pScb;    UINT8           devBusId;    STATUS          status;    pScb = pThread->pScb;    devBusId = (pScb->SP_Tarlun >> 4) & 0x0f;    pCfpStruct = pSiop->aic7880CfpStruct;    if (xferWidth != SCSI_WIDE_XFER_SIZE_NARROW)	{	pCfpStruct->Cf_ScsiOption [devBusId] |= WIDE_MODE;	SCSI_DEBUG_MSG ("aic7880WideXferParamsSet: %x %x\n", devBusId, 			pCfpStruct->Cf_ScsiOption [devBusId], 0, 0, 0, 0);		pCfpStruct->CFP_SuppressNego = 0;		if ((status = (PH_Special (FORCE_RENEGOTIATE, pCfpStruct, pScb))) != OK)	    {	    SCSI_DEBUG_MSG ("aic7880WideParamsSet: Wide Negotiation Failed.\n",			    0, 0, 0, 0, 0, 0);	    return (ERROR);	    }   	}    else	pCfpStruct->Cf_ScsiOption [devBusId] = NARROW_MODE;        return (OK);    }/********************************************************************************* aic7880EnableFast20 - enable double speed SCSI data transfers** This routine enables double speed SCSI data transfers for the SCSI host* adapter. This allows the host adapter to transfer data upto 20 MB/s for* an 8 bit device and upto 40 MB/s for a 16 bit device.** RETURNS: N/A*/VOID aic7880EnableFast20    (    SCSI_CTRL * pScsiCtrl,  /* ptr to SCSI controller */    BOOL        enable      /* enable = 1 / disable = 0 */    )    {    SIOP        * pSiop  = (SIOP *) pScsiCtrl;    cfp_struct  * configPtr = pSiop->aic7880CfpStruct;    if (enable)	configPtr->CFP_EnableFast20 = 1;    else	configPtr->CFP_EnableFast20 = 0;    }/********************************************************************************* aic7880dFifoThresholdSet - set the data FIFO threshold.** This routine specifies to the AIC-7880 host adapter how to manage its* data FIFO. Below is a description of the threshold  values for SCSI* reads and writes.** SCSI READS* .iP* 0 Xfer data from FIFO as soon as it is available.* .iP* 1 Xfer data from FIFO as soon as the FIFO is half full.* .iP* 2 Xfer data from FIFO as soon as the FIFO is 75%  full.* .iP* 3 Xfer data from FIFO as soon as the FIFO is 100% full.** SCSI WRITES* .iP* 0 Xfer data as soon as there is room in the FIFO.* .iP* 1 Xfer data to FIFO as soon as it is 50% empty. * .iP* 2 Xfer data to FIFO as soon as it is 75% empty.* .iP* 3 Xfer data to FIFO as soon as the FIFO is empty.** RETURNS: OK or ERROR if the threshold value is not within the valid range.*/STATUS aic7880dFifoThresholdSet     (    SCSI_CTRL * pScsiCtrl,   /* ptr to SCSI controller */    UBYTE       threshHold   /* data FIFO threshold value */    )    {    SIOP        * pSiop  = (SIOP *) pScsiCtrl;    cfp_struct  * configPtr = pSiop->aic7880CfpStruct;    if (threshHold > 3)	return (ERROR);    configPtr->Cf_Threshold = threshHold;    return (OK);    }/********************************************************************************* aic7880ThreadAbort - 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. Otherwise the* thread is active on the controller. Invoke the PH_Special routine with the * Abort SCB opcode passing in the address of the SCB to be aborted. The HIM * reacts as follows:** If the SCB has not become active, the status is set to aborted and* it is  returned. If the SCB has already completed, it returns completion * status. If the SCB is active and connected, the abort is issued and the SCB* is returned with an aborted status. If the target fails to transition to* the Message out or Bus Free phase, a SCSI Reset is issued. If the SCB is* active but disconnected, the HIM selects the target and issues an abort * message. If the target does not respond correctly to the selection and* abort sequence a SCSI Bus Reset is issued. If the HIM does not find a * valid SCB at the specified address, the abort command is simply ignored.** RETURNS: TRUE if the thread is being aborted by this driver (i.e. it is* currently active on the controller) else FALSE.*/LOCAL BOOL aic7880ThreadAbort    (    SIOP            * pSiop,      /* ptr to controller info */    AIC_7880_THREAD * pThread     /* ptr to SCSI controller thread */    )    {    SCSI_CTRL   * pScsiCtrl   = (SCSI_CTRL *)   pSiop;    SCSI_THREAD * pScsiThread = (SCSI_THREAD *) pThread;    sp_struct   * pScb = pThread->pScb;    cfp_struct  * configPtr = pSiop->aic7880CfpStruct;        SCSI_DEBUG_MSG ("aic7880ThreadAbort: 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:            return (FALSE);            break;	default:	    PH_Special (ABORT_SCB, configPtr, pScb);	    aic7880ThreadStateSet (pThread, SCSI_THREAD_ABORTING);	    break;	}    return (TRUE);    }/********************************************************************************* aic7880GetNumOfBuses - perform a PCI bus scan** This routine provides a callback mechanism from the HIM to the OSM* It allows the OSM to scan the PCI bus, before the HIM is allowed * to perform the bus scan.** RETURNS: 0x55555555 if the OSM is not able to conduct its own bus scan*/DWORD aic7880GetNumOfBuses ()    {    return (0x55555555);    }/********************************************************************************* aic7880ReadConfig  - read from PCI config space** This routine provides a callback mechanism from the HIM to the OSM.* The purpose of this routine is to allow the OSM to do its own Read* access of the PCI configuration space. If the OSM cannot successfully* complete the Read access, the OSM returns 0x55555555. If this happens* the HIM attempts to conduct the configuration space Read access.** RETURNS: value read or 0x55555555, if the OSM is not able to conduct * read access to the PCI configuration space.*/DWORD aic7880ReadConfig     (    cfp_struct * configPtr, /* ptr to cf_struct */    UBYTE        busNo,     /* PCI bus number */    UBYTE        devNo,     /* PCI device number */    UBYTE        regNo      /* register */    )    {    int          funcNo = 0;    DWORD        regVal;    if ((pciConfigInLong  (busNo, devNo, funcNo, (int) regNo,			   &regVal)) != OK)        {        logMsg ("aic7880ReadConfig: PCI read failed\n",                 0, 0, 0, 0, 0, 0);	return (0x55555555);        }    else	return (regVal);    }/********************************************************************************* aic7880WriteConfig - read to PCI config space** This routine provides a callback mechanism from the HIM to the OSM.* The purpose of this routine is to allow the OSM to do its own write* access of the PCI configuration space. If the OSM cannot successfully* complete the write access, the OSM returns 0x55555555. If this happens* the HIM attempts to conduct the configuration space write access.** RETURNS: OK or 0x55555555, if the OSM is not able to conduct write access * to the PCI configuration space.*/DWORD aic7880WriteConfig     (    cfp_struct * config_ptr,  /* ptr to cf_struct */    UBYTE        busNo,       /* PCI bus number */    UBYTE        devNo,       /* PCI device number */    UBYTE        regNo,       /* register */    DWORD        regVal       /* register value */    )    {    int funcNo = 0;    if ((pciConfigOutLong  (busNo, devNo, funcNo, (int) regNo,			    regVal)) != OK)        {        logMsg ("aic7880WriteConfig: PCI read failed\n",                 0, 0, 0, 0, 0, 0);	return (0x55555555);        }    else	return (OK);    }

⌨️ 快捷键说明

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