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

📄 wd33c93lib2.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* wd33c93Lib2.c - WD33C93 SCSI-Bus Interface Controller library (SCSI-2) *//* Copyright 1984-1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02h,03mar99,dat  added init of wideXfer to FALSE. SPR 2408902h,11jan99,aeg  added semTerminate () in wd33c93CtrlCreateScsi2 ().02g,29oct96,dgp  doc: editing for newly published SCSI libraries02f,06may96,jds  and more doc tweaks...02e,01may96,jds  yet more doc tweaks...02d,13nov95,jds  more doc tweaks02c,20sep95,jdi  doc tweaks.02b,20jul95,jds  changed wd33c93Intr to sbicIntr to keep it consistent with		 previous incarnations of this driver. Integrated into 		 vxWorks5.203a,16mar95,ihw  major modifications to work with generic SCSI thread manager02g,14jan94,ihw  ANSI-fied and generally smartened up to v5.1 standard02f,19jul92,ihw  improved support for disconnect/reconnect02e,17jul92,ihw  added sync. points in sbicBytes{In,Out}()02d,01jul92,ihw  modifications to support synchronous transfer02c,04oct91,ihw  fixed problem with reselection (interrupt lock-out)02b,19jun91,ihw  extensive modifications for disconnect/reconnect support02a,06jun91,ihw  modifications for multiple-initiator support01e,02oct90,jcc  UTINY became UINT8; changes in sem{Give, Take}() calls 		 since SEM_ID's became SEMAPHORE's in various structures;		 malloc() became calloc() in wd33c93CtrlCreate(); miscellaneous.01d,21sep90,jcc  misc. cleanup for 5.0 release.01c,10aug90,dnw  added forward declarations for VOID functions.01b,18jul90,jcc  made semTake() calls 5.0 compatible; clean-up.01a,28feb90,jcc  written*//*DESCRIPTIONThis library contains part of the I/O driver for the Western Digital WD33C93 family of SCSI-2 Bus Interface Controllers (SBIC).  It is designed to work with scsi2Lib. The driver routines in this library depend on theSCSI-2 ANSI specification; for general driver routines and for overall SBICdocumentation, see wd33c93Lib.USER-CALLABLE ROUTINESMost of the routines in this driver are accessible only through the I/Osystem.  The only exception in this portion of the driver iswd33c93CtrlCreateScsi2(), which creates a controller structure.INCLUDE FILESwd33c93.h, wd33c93_2.hSEE ALSO: scsiLib, scsi2Lib, wd33c93Lib, .pG "I/O System"*/#include "vxWorks.h"#define WD33C93_2_LOCAL_FUNCS#include "drv/scsi/wd33c93_2.h"#undef WD33C93_2_LOCAL_FUNCS#include "errnoLib.h"#include "intLib.h"#include "logLib.h"#include "msgQLib.h"#include "semLib.h"#include "stdio.h"#include "stdlib.h"#include "tickLib.h"#define WD_33C93_MAX_BYTES_PER_XFER  ((UINT) 0xffffff)typedef WD_33C93_SCSI_CTRL SBIC;/* globals */int wd33c93XferDoneSemOptions  = SEM_Q_PRIORITY;char *wd33c93ScsiTaskName      = SCSI_DEF_TASK_NAME;int   wd33c93ScsiTaskOptions   = SCSI_DEF_TASK_OPTIONS;int   wd33c93ScsiTaskPriority  = SCSI_DEF_TASK_PRIORITY;int   wd33c93ScsiTaskStackSize = SCSI_DEF_TASK_STACK_SIZE;IMPORT SCSI_CTRL *pSysScsiCtrl;/* forward declarations */LOCAL STATUS sbicDevSelect (SCSI_CTRL *pScsiCtrl, int devBusId,			    UINT selTimeOut, UINT8 *msgBuf, UINT msgLen);LOCAL STATUS sbicBusControl (SCSI_CTRL *pScsiCtrl, int operation);LOCAL STATUS sbicXferParamsQuery (SCSI_CTRL *pScsiCtrl, UINT8 *pOffset,    	    	    	    	                        UINT8 *pPeriod);LOCAL STATUS sbicXferParamsSet (SCSI_CTRL *pScsiCtrl, UINT8 offset,				                      UINT8 period);LOCAL int sbicInfoXfer (SCSI_CTRL *pScsiCtrl, int phase, UINT8 *pBuf, UINT bufLength);LOCAL void sbicSelTimeOutCvt (SBIC *pSbic, UINT timeOutInUsec,    	    	    	      UINT *pTimeOutSetting);LOCAL BOOL   sbicXferParamsCvt (SBIC  *pSbic, UINT8 *pOffset, UINT8 *pPeriod,				UINT8 *pXferParams);LOCAL STATUS sbicXferCountSet (SBIC *pSbic, UINT count);LOCAL void sbicXferCountGet (SBIC *pSbic, UINT *pCount);LOCAL void sbicCommand (SBIC *pSbic, UINT8 cmdCode);LOCAL void sbicHwInit (SBIC *pSbic);LOCAL void sbicPostResetInit (SBIC *pSbic);LOCAL void sbicRegRead (SBIC *pSbic, UINT8 regAdrs, int  *pDatum);LOCAL void sbicRegWrite (SBIC *pSbic, UINT8 regAdrs, UINT8 datum);LOCAL void sbicIntr (SBIC *);WD_33C93_SCSI_CTRL *wd33c93CtrlCreateScsi2 ( FAST UINT8 *sbicBaseAdrs, 		       int regOffset, UINT clkPeriod, FUNCPTR sysScsiBusReset,		       int sysScsiResetArg, UINT sysScsiDmaMaxBytes,		       FUNCPTR sysScsiDmaStart, FUNCPTR sysScsiDmaAbort,		       int sysScsiDmaArg);LOCAL STATUS wd33c93CtrlInit (FAST SBIC *pSbic, FAST int scsiCtrlBusId,		              FAST UINT defaultSelTimeOut);LOCAL STATUS wd33c93Show ( FAST SCSI_CTRL *pScsiCtrl);/********************************************************************************* wd33c93Scsi2IfInit - initialize the SCSI-2 interface to wd33c93** NOMANUAL*/void wd33c93Scsi2IfInit ()    {    /* create table */    wd33c93IfTblInit ();    /* initialize table */    pWd33c93IfTbl->sbicCommand       = (FUNCPTR) sbicCommand;    pWd33c93IfTbl->sbicIntr          = (FUNCPTR) sbicIntr;    pWd33c93IfTbl->sbicRegRead       = (FUNCPTR) sbicRegRead;    pWd33c93IfTbl->sbicRegWrite      = (FUNCPTR) sbicRegWrite;    pWd33c93IfTbl->sbicXferCountGet  = (FUNCPTR) sbicXferCountGet;    pWd33c93IfTbl->sbicXferCountSet  = (FUNCPTR) sbicXferCountSet;    pWd33c93IfTbl->wd33c93CtrlInit   = (FUNCPTR) wd33c93CtrlInit;    pWd33c93IfTbl->wd33c93Show       = (FUNCPTR) wd33c93Show;    }/********************************************************************************* wd33c93CtrlCreateScsi2 - create and partially initialize an SBIC structure** This routine creates an SBIC data structure and must be called before using* an SBIC chip.  It must be called exactly once for a specified SBIC.* Since it allocates memory for a structure needed by all routines in* wd33c93Lib2, it must be called before any other routines in the library.* After calling this routine, at least one call to wd33c93CtrlInit() must* be made before any SCSI transaction is initiated using the SBIC.** NOTE: Only the non-multiplexed processor interface is supported.** A detailed description of the input parameters follows:* .iP `sbicBaseAdrs'* the address at which the CPU would access the lowest * (AUX STATUS) register of the SBIC.* .iP `regOffset'* the address offset (bytes) to access consecutive registers.* (This must be a power of 2, for example, 1, 2, 4, etc.)* .iP `clkPeriod'* the period in nanoseconds of the signal to SBIC CLK input.* .iP "`sysScsiBusReset' and `sysScsiResetArg'"* the board-specific routine to pulse the SCSI bus RST signal.* The specified argument is passed to this routine when it is called.* It may be used to identify the SCSI bus to be reset, if there is a* choice.  The interface to this routine is of the form:* .CS*     void xxBusReset *         (*         int arg;  	    	      /@ call-back argument @/ *         )* .CE* .iP "`sysScsiDmaMaxBytes', `sysScsiDmaStart', `sysScsiDmaAbort', and `sysScsiDmaArg'"* board-specific routines to handle DMA transfers to and from the SBIC;* if the maximum DMA byte count is zero, programmed I/O is used.* Otherwise, non-NULL function pointers to DMA start and abort routines* must be provided.* The specified argument is passed to these routines when they are* called; it may be used to identify the DMA channel to use, for example.* Note that DMA is implemented only during SCSI data in/out phases.* The interface to these DMA routines must be of the form:* .CS*     STATUS xxDmaStart *         (*         int arg;  	    	      /@ call-back argument           @/*         UINT8 *pBuffer;             /@ ptr to the data buffer       @/*         UINT bufLength;             /@ number of bytes to xfer      @/*   	  int direction;    	      /@ 0 = SCSI->mem, 1 = mem->SCSI @/*         )**     STATUS xxDmaAbort*         (*         int arg;  	    	      /@ call-back argument @/*         )* .CE** RETURNS: A pointer to the SBIC structure, or NULL if memory is * insufficient or the parameters are invalid.*/WD_33C93_SCSI_CTRL *wd33c93CtrlCreateScsi2    (    FAST UINT8 *sbicBaseAdrs,	     /* base address of the SBIC              */    int         regOffset,	     /* address offset between SBIC registers */    UINT        clkPeriod,	     /* period of the SBIC clock (nsec)       */    FUNCPTR     sysScsiBusReset,     /* function to reset SCSI bus            */    int         sysScsiResetArg,     /* argument to pass to above function    */    UINT        sysScsiDmaMaxBytes,  /* maximum byte count using DMA          */    FUNCPTR     sysScsiDmaStart,     /* function to start SCSI DMA transfer   */    FUNCPTR     sysScsiDmaAbort,     /* function to abort SCSI DMA transfer   */    int         sysScsiDmaArg	     /* argument to pass to above functions   */    )    {    FAST SBIC *pSbic;		/* ptr to SBIC info */    /* verify input parameters */    if ((regOffset == 0) || (clkPeriod == 0))	return ((SBIC *) NULL);        if ((sysScsiDmaMaxBytes != 0) &&	((sysScsiDmaStart == NULL) || (sysScsiDmaAbort == NULL)))	return ((SBIC *) NULL);        /* calloc the controller info structure; return NULL if unable */    if ((pSbic = (SBIC *) calloc (1, sizeof (SBIC))) == NULL)        return ((SBIC *) NULL);    /*     *  Set up sizes of event and thread structures.  Must be done before     *	calling "scsiCtrlInit()".     *     *	Since this controller uses standard event and thread structures,     *	it could simply leave these values set to 0 (i.e., use default).     */    pSbic->scsiCtrl.eventSize  = sizeof (SCSI_EVENT);    pSbic->scsiCtrl.threadSize = sizeof (SCSI_THREAD);        /* leave transact, event and thread management routines as default */    /* fill in driver-specific routines for scsiLib interface */    pSbic->scsiCtrl.scsiDevSelect       = sbicDevSelect;    pSbic->scsiCtrl.scsiInfoXfer        = sbicInfoXfer;    pSbic->scsiCtrl.scsiBusControl      = sbicBusControl;    pSbic->scsiCtrl.scsiXferParamsQuery = sbicXferParamsQuery;    pSbic->scsiCtrl.scsiXferParamsSet   = (FUNCPTR)sbicXferParamsSet;    pSbic->scsiCtrl.wideXfer		= FALSE;    pSbic->scsiCtrl.scsiWideXferParamsQuery = NULL;    pSbic->scsiCtrl.scsiWideXferParamsSet   = NULL;    /* fill in driver-specific variables for scsiLib interface */    if ((sysScsiDmaMaxBytes != 0) &&	(sysScsiDmaMaxBytes <= WD_33C93_MAX_BYTES_PER_XFER))	pSbic->scsiCtrl.maxBytesPerXfer = sysScsiDmaMaxBytes;    else	pSbic->scsiCtrl.maxBytesPerXfer = WD_33C93_MAX_BYTES_PER_XFER;    /* fill in generic SCSI info for this controller */    scsiCtrlInit (&pSbic->scsiCtrl);    /* initialize SBIC info transfer synchronisation semaphore */    if (semBInit (&pSbic->xferDoneSem, wd33c93XferDoneSemOptions, SEM_EMPTY)	         == ERROR)	{	SCSI_MSG ("wd33c93CtrlCreate: semBInit of xferDoneSem failed\n",		  0, 0, 0, 0, 0, 0);	(void) free ((char *) pSbic);	return ((WD_33C93_SCSI_CTRL *) NULL);	}					      /* initialise state variables */    pSbic->state       = SBIC_STATE_IDLE;    pSbic->initPending = FALSE;    pSbic->xferPending = FALSE;        /* fill in SBIC specific data for this controller */    pSbic->clkPeriod   = clkPeriod;    pSbic->pAdrsReg    = sbicBaseAdrs;    pSbic->pAuxStatReg = sbicBaseAdrs;    pSbic->pRegFile    = sbicBaseAdrs + regOffset;    /* fill in board-specific SCSI bus reset and DMA xfer routines */    pSbic->sysScsiDmaStart = sysScsiDmaStart;    pSbic->sysScsiDmaAbort = sysScsiDmaAbort;    pSbic->sysScsiDmaArg   = sysScsiDmaArg;    pSbic->sysScsiBusReset = sysScsiBusReset;    pSbic->sysScsiResetArg = sysScsiResetArg;        /* spawn SCSI manager - use generic code from "scsiLib.c" */    pSbic->scsiCtrl.scsiMgrId = taskSpawn (wd33c93ScsiTaskName,		       	    	           wd33c93ScsiTaskPriority,		       	    	           wd33c93ScsiTaskOptions,		       	    	           wd33c93ScsiTaskStackSize,		       	    	           (FUNCPTR) scsiMgr,		       	    	           (int) pSbic,					   0, 0, 0, 0, 0, 0, 0, 0, 0);    if (pSbic->scsiCtrl.scsiMgrId == ERROR)	{	SCSI_MSG ("wd33c93CtrlCreate: can't spawn SCSI manager task\n",		  0, 0, 0, 0, 0, 0);	semTerminate (&pSbic->xferDoneSem);	free ((char *) pSbic);	return ((SBIC *) NULL);	}    return (pSbic);    }/********************************************************************************* wd33c93CtrlInit - initialize user specifiable fields in an SBIC structure** After an SBIC structure is created with wd33c93CtrlCreate(2), but* before using the SBIC, it must be initialized by calling this routine.* It may be called more than once if desired.  However, it should only be* called while there is no activity on the SCSI interface.** A detailed description of the input parameters follows:* * .iP `pSbic'* pointer to the WD_33C93_SCSI_CTRL structure created with wd33c93CtrlCreate(2).* * .iP `scsiCtrlBusId'* the SCSI bus ID of the SBIC; somewhat arbitrary, seven (7),* or highest priority, is conventional.  Must be in range 0 - 7.* * .iP `defaultSelTimeOut'* the timeout (in microsec) for selecting a SCSI device* attached to this controller; called default since the* timeout may be specified per device.* The recommended value zero (0)* specifies SCSI_DEF_SELECT_TIMEOUT (250 millisec).* Values over the maximum timeout period specify the maximum,* which is approximately 2 seconds (depending on SBIC clock* period).  See also Western Digital documentation.** RETURNS: OK, or ERROR if out-of-range parameter(s).*/LOCAL STATUS wd33c93CtrlInit    (    FAST SBIC *pSbic,		/* ptr to SBIC info */    FAST int  scsiCtrlBusId,	/* SCSI bus ID of this SBIC */    FAST UINT defaultSelTimeOut /* default dev. select timeout (microsec) */    )    {    /* verify scsiCtrlBusId and enter legal value in SBIC structure */    if (scsiCtrlBusId < SCSI_MIN_BUS_ID || scsiCtrlBusId > SCSI_MAX_BUS_ID)	return (ERROR);    else	pSbic->scsiCtrl.scsiCtrlBusId = scsiCtrlBusId;    if (defaultSelTimeOut == 0)	pSbic->defSelTimeOut = SCSI_DEF_SELECT_TIMEOUT;    else	pSbic->defSelTimeOut = defaultSelTimeOut;    sbicHwInit (pSbic); 	/* initialize the SBIC hardware */    return (OK);    }/********************************************************************************* sbicDevSelect - attempt to select a SCSI device** Initiate selection of the specified SCSI target, asserting ATN if there is* an identification message to be sent.  Return immediately; do not wait for* the selection to complete.  (This will be notified by an asynchronous* message posted in the controller's event queue).** There is a race condition inherent in SCSI between the synchronous* activation of a thread (i.e., execution of this routine) and asynchronous* activation of a thread as a result of selection or reselection.  The SCSI* manager is designed to take account of this, and assumes that either the* new thread has been successfully activated or a (re)selection has taken* place, as determined by the next event it receives.  In the case when* (re)selection occurs, the current activation request is deferred and* retried later.** Therefore, a SELECT command is issued only if the controller is currently* IDLE (waiting for (re)selection or a host command).  If the controller is* CONNECTED, (re)selection is assumed to have already occurred.  Note that* this is not an error condition; there is no way for the caller to reliably* distinguish the two cases, because even if the thread appears to have been* activated it may yet be "pre-empted" by (re)selection.** The controller should never be in SELECT_PENDING state.  If it is, the* SCSI manager has tried to activate multiple concurrent threads on the* controller, which indicates a major (software) disaster.** NOTE: Interrupt locking is required to ensure that the correct action* is taken once the controller state has been checked.** RETURNS: OK, or ERROR if the controller is in an invalid state (this* indicates a major software failure).*/LOCAL STATUS sbicDevSelect    (    SCSI_CTRL *pScsiCtrl,	/* ptr to SCSI controller info     */    int        devBusId,	/* SCSI bus ID of device to select */    UINT       selTimeOut,	/* select t-o period (usec)        */    UINT8     *msgBuf,		/* ptr to identification message   */    UINT       msgLen	    	/* maximum number of message bytes */    )    {    FAST SBIC *pSbic;		/* ptr to SBIC info             */    int        lockKey;		/* saved interrupt lock key     */    UINT8      selectCmd;   	/* actual SELECT command to use */    STATUS     status;

⌨️ 快捷键说明

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