📄 wd33c93lib1.c
字号:
/* wd33c93Lib1.c - WD33C93 SCSI-Bus Interface Controller library (SCSI-1) *//* Copyright 1989-1995 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01w,06may96,jds yet more doc tweaks01v,01may96,jds more doc cleanup01u,03feb95,rhp documentation cleanup01t,10oct93,jds fixed for SCSI1 and SCSI2 compatability01s,24feb93,jdi documentation cleanup.01r,19feb93,ccc removed bypass of DMA routine if DMA is included.01q,26sep92,ccc changed sbicShow() to wd33c93Show() and added example.01p,24sep92,ccc fixed timeout in sbicBusPhaseGet().01o,20jul92,gae fixed parameters to logMsg().01n,18jul92,smb Changed errno.h to errnoLib.h.01m,12jul92,ccc added reset of SCSI bus if timed out (bus hung).01l,04jun92,ccc added timeout to semTake()s.01k,26may92,rrr the tree shuffle -changed includes to have absolute path from h/01j,20apr92,ccc fixed warnings.01i,07oct91,rrr some forward decls01h,04oct91,rrr passed through the ansification filter -changed functions to ansi style -changed includes to have absolute path from h/ -changed VOID to void -changed copyright notice01g,05apr91,jdi documentation -- removed header parens and x-ref numbers; doc review by jcc.01f,01feb91,jaa documentation.01e,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 theWestern Digital WD33C93 and WD33C93A SCSI-Bus Interface Controllers(SBIC). The driver routines in this library depend on the SCSI-1 version of the SCSI standard; for driver routines that do not dependon SCSI-1 or SCSI-2, and for overall SBIC driver documentation, seewd33c93Lib.USER-CALLABLE ROUTINESMost of the routines in this driver are accessible only through theI/O system. The only exception in this portion of the driver iswd33c93CtrlCreate(), which creates a controller structure.INCLUDE FILESwd33c93.h, wd33c93_1.hSEE ALSO: scsiLib, scsi1Lib, wd33c93Lib*/#include "vxWorks.h"#define WD33C93_1_LOCAL_FUNCS#include "drv/scsi/wd33c93_1.h"#undef WD33C93_1_LOCAL_FUNCS#include "memLib.h"#include "logLib.h"#include "scsiLib.h"#include "stdlib.h"#include "errnoLib.h"#include "stdio.h"#include "sysLib.h"#define WD_33C93_MAX_BYTES_PER_XFER ((UINT) 0xffffff)typedef WD_33C93_SCSI_CTRL SBIC;/* imported functions */IMPORT STATUS scsiTransact ();IMPORT STATUS scsiCtrlInit ();/* forward static functions */LOCAL STATUS sbicDevSelect (SCSI_PHYS_DEV *, SCSI_TRANSACTION *);LOCAL STATUS sbicMsgInAck (SCSI_CTRL *, BOOL);LOCAL STATUS sbicBytesOut (SCSI_PHYS_DEV *, char *, int, int);LOCAL STATUS sbicBytesIn (SCSI_PHYS_DEV *, char *, int, int);LOCAL STATUS sbicBusPhaseGet (SCSI_CTRL *, int, int *);LOCAL void sbicSelTimeOutCvt (SCSI_CTRL *, UINT, UINT *);LOCAL void sbicScsiBusReset (SBIC *);LOCAL void sbicHwInit (SBIC *);WD_33C93_SCSI_CTRL *wd33c93CtrlCreate (FAST UINT8 *, int, UINT, int, FUNCPTR, FUNCPTR, FUNCPTR);LOCAL STATUS wd33c93CtrlInit (FAST SBIC *, FAST int, FAST UINT, int);LOCAL STATUS sbicXferCountSet (FAST SBIC *, FAST UINT);LOCAL void sbicXferCountGet (FAST SBIC *, FAST int *);LOCAL void sbicCommand (SBIC *, UINT8);LOCAL void sbicIntr (SBIC *);LOCAL void sbicRegRead (SBIC *, UINT8, int *);LOCAL void sbicRegWrite (SBIC *, UINT8, UINT8);LOCAL STATUS wd33c93Show (FAST SCSI_CTRL *);/********************************************************************************* wd33c93Scsi1IfInit - initialize the SCSI-2 interface to wd33c93** NOMANUAL*/void wd33c93Scsi1IfInit () { /* 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; }/********************************************************************************* wd33c93CtrlCreate - create and partially initialize a WD33C93 SBIC structure** This routine creates an SBIC data structure and must be called before using* an SBIC chip. It should be called once and only once for a specified SBIC. * Since it allocates memory for a structure needed by all routines in* wd33c93Lib, it must be called before any other routines in the library.* After calling this routine, at least one call to wd33c93CtrlInit() should* be made before any SCSI transaction is initiated using the SBIC.** Note that only the non-multiplexed processor interface is supported.** The input parameters are as follows:* .iP <sbicBaseAdrs> 4* the address where the CPU accesses the lowest register of* the SBIC.* .iP <regOffset>* the address offset (in 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 clock input used only for* select command timeouts.* .iP <devType>* a constant corresponding to the type (part number) of this controller; * possible options are enumerated in wd33c93.h under the heading "SBIC * device type."* .iP <sbicScsiReset>* a board-specific routine to assert the RST line on the SCSI bus, which causes* all connected devices to return to a known quiescent state.* .iP "<spcDmaBytesIn> and <spcDmaBytesOut>"* board-specific routines to handle DMA input and output. * If these are NULL (0), SBIC program transfer mode is used.* DMA is implemented only during SCSI data in/out phases.* The interface to these DMA routines must be of the form:* .CS* STATUS xxDmaBytes{In, Out}* (* SCSI_PHYS_DEV *pScsiPhysDev, /@ ptr to phys dev info @/* UINT8 *pBuffer, /@ ptr to the data buffer @/* int bufLength /@ number of bytes to xfer @/* )* .CE** RETURNS: A pointer to the SBIC control structure,* or NULL if memory is insufficient or parameters are invalid.** SEE ALSO: wd33c93.h*/WD_33C93_SCSI_CTRL *wd33c93CtrlCreate ( FAST UINT8 *sbicBaseAdrs, /* base address of SBIC */ int regOffset, /* addr offset between consecutive regs. */ UINT clkPeriod, /* period of controller clock (nsec) */ int devType, /* SBIC device type */ FUNCPTR sbicScsiReset, /* SCSI bus reset function */ FUNCPTR sbicDmaBytesIn, /* SCSI DMA input function */ FUNCPTR sbicDmaBytesOut /* SCSI DMA output function */ ) { FAST SBIC *pSbic; /* ptr to SBIC info */ /* initialize the driver function table */ wd33c93Scsi1IfInit (); /* verify input parameters */ if (regOffset == 0) return ((SBIC *) NULL); /* calloc the controller info structure; return NULL if unable */ if ((pSbic = (SBIC *) calloc (1, sizeof (SBIC))) == NULL) return ((SBIC *) NULL); /* fill in generic SCSI info for this controller */ scsiCtrlInit (&pSbic->scsiCtrl); /* fill in SBIC specific data for this controller */ pSbic->pAdrsReg = sbicBaseAdrs; pSbic->pAuxStatReg = sbicBaseAdrs; pSbic->pRegFile = sbicBaseAdrs + regOffset; pSbic->devType = devType; pSbic->scsiCtrl.clkPeriod = clkPeriod; pSbic->scsiCtrl.maxBytesPerXfer = WD_33C93_MAX_BYTES_PER_XFER; /* fill in board-specific SCSI bus reset routine */ pSbic->scsiCtrl.scsiBusReset = sbicScsiBusReset; /* fill in driver-specific routines for scsiLib interface */ pSbic->scsiCtrl.scsiTransact = scsiTransact; pSbic->scsiCtrl.scsiDevSelect = sbicDevSelect; pSbic->scsiCtrl.scsiBytesIn = sbicBytesIn; pSbic->scsiCtrl.scsiBytesOut = sbicBytesOut; pSbic->scsiCtrl.scsiDmaBytesIn = sbicDmaBytesIn; pSbic->scsiCtrl.scsiDmaBytesOut = sbicDmaBytesOut; pSbic->scsiCtrl.scsiBusPhaseGet = sbicBusPhaseGet; pSbic->scsiCtrl.scsiMsgInAck = sbicMsgInAck; pSbic->scsiCtrl.scsiSelTimeOutCvt = sbicSelTimeOutCvt; pSbic->sbicScsiReset = sbicScsiReset; return (pSbic); }/********************************************************************************* wd33c93CtrlInit - initialize the user-specified fields in a WD33C93 SBIC structure** This routine initializes an SBIC structure, after the structure is created* with wd33c93CtrlCreate(). This structure must be initialized before the SBIC* can be used. It may be called more than once; however, it should* be called only while there is no activity on the SCSI interface.** Before returning, this routine pulses RST (reset) on the SCSI bus, thus* resetting all attached devices.** The input parameters are as follows:* .iP <pSbic> 4* a pointer to the WD_33C93_SCSI_CTRL structure created with* wd33c93CtrlCreate().* .iP <scsiCtrlBusId>* the SCSI bus ID of the SBIC, in the range 0 - 7. The ID is somewhat * arbitrary; the value 7, or highest priority, is conventional.* .iP <defaultSelTimeOut>* the timeout, in microseconds, for selecting a SCSI device attached to this* controller. This value is used as a default if no timeout is specified in* scsiPhysDevCreate(). The recommended value zero (0) specifies* SCSI_DEF_SELECT_TIMEOUT (250 millisec). The maximum timeout possible is* approximately 2 seconds. Values exceeding this revert to the* maximum. For more information about chip timeouts, see the manuals* .I "Western Digital WD33C92/93 SCSI-Bus Interface Controller,"* .I "Western Digital WD33C92A/93A SCSI-Bus Interface Controller."* .iP <scsiPriority>* the priority to which a task is set when performing a SCSI* transaction. Valid priorities are 0 to 255. Alternatively, the value -1 * specifies that the priority should not be altered during SCSI transactions.** RETURNS: OK, or ERROR if a parameter is out of range.** SEE ALSO: scsiPhysDevCreate(),* .I "Western Digital WD33C92/93 SCSI-Bus Interface Controller,"* .I "Western Digital WD33C92A/93A SCSI-Bus Interface Controller"*/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) */ int scsiPriority /* priority of task when doing SCSI I/O */ ) { UINT tempSelTimeOut; /* temp. value of select timeout (no units) */ /* verify scsiCtrlBusId and enter legal value in SBIC structure */ SCSI_DEBUG_MSG ("scsiCtrlBusId = %d\n", scsiCtrlBusId, 0, 0, 0, 0, 0); if (scsiCtrlBusId < SCSI_MIN_BUS_ID || scsiCtrlBusId > SCSI_MAX_BUS_ID) return (ERROR); pSbic->scsiCtrl.scsiCtrlBusId = scsiCtrlBusId; if (scsiPriority < NONE || scsiPriority > 0xff) return (ERROR); pSbic->scsiCtrl.scsiPriority = scsiPriority; /* verify defaultSelTimeOut, convert it from usec to SBIC register values, * and enter value in SBIC structure */ sbicSelTimeOutCvt (&pSbic->scsiCtrl, defaultSelTimeOut, &tempSelTimeOut); pSbic->defaultSelTimeOut = (UINT8) tempSelTimeOut; /* disconnect not supported for now */ pSbic->scsiCtrl.disconnect = (TBOOL) FALSE; sbicHwInit (pSbic); /* initialize the SBIC hardware */ return (OK); }/********************************************************************************* sbicDevSelect - attempt to select a SCSI device** This routine is intended to be called from scsiLib, not directly.** RETURNS: OK if the device was successfully selected, otherwise ERROR.*/LOCAL STATUS sbicDevSelect ( FAST SCSI_PHYS_DEV *pScsiPhysDev, /* ptr to SCSI physical device info */ SCSI_TRANSACTION *pScsiXaction /* ptr to SCSI transaction info */ ) { FAST SBIC *pSbic; /* ptr to SBIC info */ int sbicBusId; /* SCSI bus ID of the SBIC */ UINT8 identMsg; /* for construction of the IDENTIFY message */ STATUS status; /* placeholder for status */ int scsiPhase; /* SCSI bus phase following the select */ pSbic = (SBIC *) pScsiPhysDev->pScsiCtrl; sbicRegRead (pSbic, SBIC_REG_OWN_ID, &sbicBusId);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -