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

📄 ncr710lib2.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    ncr710IdentThreadInit ((NCR710_THREAD *) pScsiCtrl->pIdentThread);    /* spawn SCSI manager - use generic code from "scsiLib.c" */    pScsiCtrl->scsiMgrId = taskSpawn (ncr710ScsiTaskName,		       	    	      ncr710ScsiTaskPriority,		       	    	      ncr710ScsiTaskOptions,		       	    	      ncr710ScsiTaskStackSize,		       	    	      (FUNCPTR) scsiMgr,		       	    	      (int) pSiop, 0, 0, 0, 0, 0, 0, 0, 0, 0);    if (pScsiCtrl->scsiMgrId == ERROR)	{	SCSI_MSG ("ncr710CtrlCreateScsi2: can't spawn SCSI manager task\n",		  0, 0, 0, 0, 0, 0);	goto failed;	}    return (pSiop);failed:    if (pSiop->singleStepSem != NULL)	(void) semDelete (pSiop->singleStepSem);    (void) cacheDmaFree ((char *) pSiop);        return (NULL);    }/********************************************************************************* ncr710CtrlInitScsi2 - initialize a control structure for the NCR 53C710 SIOP** This routine initializes an SIOP structure after the structure is created* with ncr710CtrlCreateScsi2().  This structure must be initialized before the* SIOP can be used.  It may be called more than once if needed;  however,* it must only be called while there is no activity on the SCSI interface.** A detailed description of the input parameters follows:* .iP <pSiop>* a pointer to the NCR_710_SCSI_CTRL structure created with* ncr710CtrlCreateScsi2().* .iP <scsiCtrlBusId>* the SCSI bus ID of the SIOP.  Its value is somewhat arbitrary:  seven (7),* or highest priority, is conventional.  The value must be in the range 0 - 7.* .iP <scsiPriority>* this parameter is ignored.  All SCSI I/O is now done in the context of* the SCSI manager task; if necessary, the priority of the manager task may be* changed using taskPrioritySet() or by setting the value of the global* variable `ncr710ScsiTaskPriority' before calling ncr710CtrlCreateScsi2().* .LP** RETURNS: OK, or ERROR if the parameters are out of range.** SEE ALSO: ncr710CtrlCreateScsi2()*/STATUS ncr710CtrlInitScsi2    (    FAST NCR_710_SCSI_CTRL *pSiop,  /* ptr to SIOP struct */    int scsiCtrlBusId,		    /* SCSI bus ID of this SIOP */    int scsiPriority		    /* task priority when doing SCSI I/O */    )    {    SCSI_CTRL * pScsiCtrl = (SCSI_CTRL *) pSiop;    /*     *	Validate parameters     */    if (pSiop == (SIOP *)NULL)	return (ERROR);    /*     *	Validate and set bus ID     */    if (scsiCtrlBusId < SCSI_MIN_BUS_ID || scsiCtrlBusId > SCSI_MAX_BUS_ID)	return (ERROR);        pScsiCtrl->scsiCtrlBusId = scsiCtrlBusId;    /*     *	Initialise the SIOP     */    ncr710HwInit (pSiop);    ncr710ScriptStart (pSiop,		       (NCR710_THREAD *) pScsiCtrl->pIdentThread,		       NCR710_SCRIPT_WAIT);    pSiop->state = NCR710_STATE_PASSIVE;    return (OK);    }/********************************************************************************* ncr710HwInit - initialize the SIOP chip to a known state** This routine puts the SIOP into a known quiescent state.  Because the value* of some registers depend upon the hardware implementation of the chip you * may have to use ncr710SetHwRegister() to adjust them.** This routine does not touch the bits in registers that are set by * the ncr710SetHwRegister() routine.** See the NCR 53C710 Data Manual for fuller details of the registers* programmed by this routine.** SEE ALSO *	ncr710SetHwRegister()** NOMANUAL*/LOCAL void ncr710HwInit    (    FAST SIOP *pSiop			/* ptr to an SIOP info structure */    )    {    UINT clkPeriod;    /*     *	Software reset the SIOP     */    *pSiop->pIstat = B_SOFTRST;    *pSiop->pIstat = 0;    /*     *	Initialise hardware-dependent registers     */    ncr710SetHwRegisterScsi2 (pSiop, &pSiop->hwRegs);    /*     *	DMA mode, control and watchdog timer registers     *     *	Use manual start and NCR 53C700 compatibility mode.     *	Set clock conversion factor (the clkPeriod has been checked in     *	"ncr710CtrlCreate()") and save async clock period for use by     *	"ncr710XferParamsCvt()".  Disable the watchdog timer.     */    *pSiop->pDwt    = 0;    *pSiop->pDmode |= B_MAN;    *pSiop->pDcntl |= B_COM;    clkPeriod = pSiop->clkPeriod;        if (clkPeriod >= NCR710_25MHZ)   	    	    /* 16.67 - 25.00 MHz */    	{        *pSiop->pDcntl |= NCR710_16MHZ_DIV;	pSiop->asyncClkPeriod = clkPeriod;    	}    else if (clkPeriod >= NCR710_3750MHZ)    	    /* 25.01 - 37.50 MHz */    	{        *pSiop->pDcntl |= NCR710_25MHZ_DIV;	pSiop->asyncClkPeriod = clkPeriod * 3 / 2;    	}    else if (clkPeriod >= NCR710_50MHZ) 	    /* 37.51 - 50.00 MHz */    	{        *pSiop->pDcntl |= NCR710_50MHZ_DIV;	pSiop->asyncClkPeriod = clkPeriod * 2;    	}    else /* (clkPeriod >= NCR710_6666MHZ) */ 	    /* 50.01 - 66.67 MHz */    	{        *pSiop->pDcntl |= NCR710_66MHZ_DIV;	pSiop->asyncClkPeriod = clkPeriod * 3;    	}    /*     *	SCSI control registers     *     *	If disconnect/reconnect is enabled, use full arbitration.     *	Always generate parity; check for parity if required to do so.     *	Set slow cable mode if specified.     */    *pSiop->pScntl0 = B_EPG;    *pSiop->pScntl1 = 0;    if (pSiop->scsiCtrl.disconnect) 	{        *pSiop->pScntl0 |= (B_ARB1 | B_ARB0);	*pSiop->pScntl1 |= B_ESR;	}    if (pSiop->parityCheckEnbl)	*pSiop->pScntl0 |= B_EPC;         if (pSiop->slowCableMode)	*pSiop->pScntl1 |= B_EXC;    /*     *	Chip test registers     *     *	Enable active negation (needed for fast SCSI)     */    *pSiop->pCtest0 = B_EAN;    /*     *	Set own SCSI bus ID (checked in "ncr710CtrlInit()")     */    *pSiop->pScid = (1 << pSiop->scsiCtrl.scsiCtrlBusId);    /*     *	Enable relevant SCSI and DMA interrupts (see "ncr710EventTypeGet()")     *     *	Note: in target mode the phase mismatch interrupt (B_MA) is used to     *	signal assertion of ATN.  Currently we cannot handle this either in     *	this library or in the script.  Therefore, the script automatically     *	disables this interrupt in target mode and enables it (for phase     *	mismatch) in initiator mode.  Also see "ncr710EventTypeGet()".     */    *pSiop->pSien = (B_STO | B_SGE | B_UDC | B_RSTE | B_PAR);     *pSiop->pDien = (B_BF | B_ABT | B_SIR | B_WTD | B_IID);    }/********************************************************************************* ncr710SetHwRegisterScsi2 - set hardware-dependent registers for the NCR 53C710** This routine sets up the registers used in the hardware* implementation of the chip.  Typically, this routine is called by * the sysScsiInit() routine from the BSP.  ** The input parameters are as follows:* .iP <pSiop> 4* a pointer to the NCR_710_SCSI_CTRL structure created with* ncr710CtrlCreateScsi2().* .iP <pHwRegs>* a pointer to a NCR710_HW_REGS structure that is filled with the logical* values 0 or 1 for each bit of each register described below.** This routine includes only the bit registers that can be used to modify * the behavior of the chip. The default configuration used during * ncr710CtlrCreateScsi2() and ncr710CrtlInitScsi2() is * {0,0,0,0,1,0,0,0,0,0,0,0,0,1,0}.**.CS*    typedef struct*        {*        int ctest4Bit7;   /@ Host bus multiplex mode @/*        int ctest7Bit7;   /@ Disable/enable burst cache capability @/*        int ctest7Bit6;   /@ Snoop control bit1 @/*        int ctest7Bit5;   /@ Snoop control bit0 @/*        int ctest7Bit1;   /@ invert tt1 pin (sync bus host mode only)@/*        int ctest7Bit0;   /@ enable differential scsi bus capability@/*        int ctest8Bit0;   /@ Set snoop pins mode @/*        int dmodeBit7;    /@ Burst Length transfer bit 1 @/*        int dmodeBit6;    /@ Burst Length transfer bit 0 @/*        int dmodeBit5;    /@ Function code bit FC2 @/*        int dmodeBit4;    /@ Function code bit FC1 @/*        int dmodeBit3;    /@ Program data bit (FC0) @/*        int dmodeBit1;    /@ user  programmable transfer type @/*        int dcntlBit5;    /@ Enable Ack pin @/*        int dcntlBit1;    /@ Enable fast arbitration on host port @/*        } NCR710_HW_REGS;**.CE* For a more detailed explanation of the register bits, refer to the* .I "NCR 53C710 SCSI I/O Processor Programming Guide."** NOTE* Because this routine writes to the chip registers you cannot use it* if there is any SCSI bus activity.** RETURNS: OK, or ERROR if any input parameter is NULL.** SEE ALSO: ncr710CtrlCreateScsi2(), * .I "NCR 53C710 SCSI I/O Processor Programming Guide"*/STATUS ncr710SetHwRegisterScsi2    (    FAST SIOP	   *pSiop,	/* pointer to SIOP info */    NCR710_HW_REGS *pHwRegs     /* pointer to a NCR710_HW_REGS info */    )    {    /* check input parameters */    if ((pSiop == NULL) || (pHwRegs == NULL))	return (ERROR);    /* fill the SIOP structure with new parameters */    bcopy ((char *)pHwRegs, (char *) &pSiop->hwRegs, sizeof(NCR710_HW_REGS));    /* Set each bit register to the new value */        /* This bit must be set first else the chip will not anwser to a slave      * access in some hardware implementations.     */    ((pHwRegs->dcntlBit5)  ? (*pSiop->pDcntl   =  B_EA)			   : (*pSiop->pDcntl   =  0));    ((pHwRegs->ctest4Bit7) ? (*pSiop->pCtest4 |=  B_MUX)			   : (*pSiop->pCtest4 &= ~B_MUX));    ((pHwRegs->ctest7Bit7) ? (*pSiop->pCtest7 |=  B_CDIS)			   : (*pSiop->pCtest7 &= ~B_CDIS));    ((pHwRegs->ctest7Bit6) ? (*pSiop->pCtest7 |=  B_SC1)			   : (*pSiop->pCtest7 &= ~B_SC1));    ((pHwRegs->ctest7Bit5) ? (*pSiop->pCtest7 |=  B_SC0)			   : (*pSiop->pCtest7 &= ~B_SC0));    ((pHwRegs->ctest7Bit1) ? (*pSiop->pCtest7 |=  B_TT1)			   : (*pSiop->pCtest7 &= ~B_TT1));    ((pHwRegs->ctest7Bit0) ? (*pSiop->pCtest7 |=  B_DIFF) 			   : (*pSiop->pCtest7 &= ~B_DIFF));    ((pHwRegs->ctest8Bit0) ? (*pSiop->pCtest8 |=  B_SM)			   : (*pSiop->pCtest8 &= ~B_SM));    ((pHwRegs->dmodeBit7)  ? (*pSiop->pDmode  |=  B_BL1)			   : (*pSiop->pDmode  &= ~B_BL1));    ((pHwRegs->dmodeBit6)  ? (*pSiop->pDmode  |=  B_BL0)			   : (*pSiop->pDmode  &= ~B_BL0));    ((pHwRegs->dmodeBit5)  ? (*pSiop->pDmode  |=  B_FC2)			   : (*pSiop->pDmode  &= ~B_FC2));    ((pHwRegs->dmodeBit4)  ? (*pSiop->pDmode  |=  B_FC1)			   : (*pSiop->pDmode  &= ~B_FC1));    ((pHwRegs->dmodeBit3)  ? (*pSiop->pDmode  |=  B_PD)			   : (*pSiop->pDmode  &= ~B_PD));    ((pHwRegs->dmodeBit1)  ? (*pSiop->pDmode  |=  B_U0TT0)			   : (*pSiop->pDmode  &= ~B_U0TT0));    ((pHwRegs->dcntlBit1)  ? (*pSiop->pDcntl  |=  B_FA)			   : (*pSiop->pDcntl  &= ~B_FA));    return (OK);    }/********************************************************************************* ncr710ScsiBusControl - miscellaneous low-level SCSI bus control operations** Currently supports only the SCSI_BUS_RESET operation; other operations are* not used explicitly by the driver because they are carried out automatically* by the script program.** NOTE: after the SCSI bus has been reset, the SIOP generates an interrupt* which causes an NCR710_BUS_RESET event to be sent to the SCSI manager.* See "ncr710Intr()".** RETURNS: OK, or ERROR if an invalid operation is requested.** NOMANUAL*/LOCAL STATUS ncr710ScsiBusControl    (    SIOP * pSiop,   	    /* ptr to controller info                   */    int    operation	    /* bitmask for operation(s) to be performed */    )    {    if ((operation & ~SCSI_BUS_RESET) != 0)	return (ERROR);	    if (operation & SCSI_BUS_RESET)	ncr710ScsiBusReset (pSiop);    return (OK);    }/********************************************************************************* ncr710ScsiBusReset - assert the RST line on the SCSI bus ** Issue a SCSI Bus Reset command to the NCR 710. This should put all devices* on the SCSI bus in an initial quiescent state.** The bus reset will generate an interrupt which is handled by the normal* ISR (see "ncr710Intr()").** RETURNS: N/A** NOMANUAL*/LOCAL void ncr710ScsiBusReset    (    FAST SIOP *pSiop	/* ptr to SIOP info */    )    {    *pSiop->pScntl1 |=  B_RST;    taskDelay (2);			/* pause for at least 250 us */    *pSiop->pScntl1 &= ~B_RST;    }/********************************************************************************* ncr710IntrScsi2 - interrupt service routine for the SIOP** Find the event type corresponding to this interrupt, and carry out any* actions which must be done before the SIOP is re-started.  Determine* whether or not the SIOP is connected to the bus (depending on the event* type - see note below).  If not, start a client script if possible or* else just make the SIOP wait for something else to happen.** Notify the SCSI manager of a controller event.** NOTE:* The "connected" Boolean tells whether there is a SCSI thread in progress* which must be continued before any other SCSI activity can occur.  In* principle, it might seem that reading the appropriate bit in the SIOP's* SCNTL1 register would be better than inferring the value from the interrupt* code.** However, the SCNTL1 register may change between the time the script* completes (generates the interrupt) and the time it is read - for example,* if the SIOP is reselected immediately after generating a DISCONNECTED* interrupt.** Because the action taken by the ISR depends critically on what will happen* in software as a result of the current interrupt, and _not_ on the current* state of the SIOP hardware, if the hardware "connected" bit were used, the* above scenario would cause the ISR to fail to re-start a script when in* fact it should do.  The result would be that the SIOP would forever remain

⌨️ 快捷键说明

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