📄 scsi2lib.c
字号:
STATUS myScsiCommand ( SCSI_PHYS_DEV * pScsiPhysDev, /@ ptr to SCSI physical device @/ char * buffer, /@ ptr to data buffer @/ int bufLength, /@ length of buffer in bytes @/ int someParam /@ param. specifiable in cmd block @/ ) { SCSI_COMMAND myScsiCmdBlock; /@ SCSI command byte array @/ SCSI_TRANSACTION myScsiXaction; /@ info on a SCSI transaction @/ /@ fill in fields of SCSI_COMMAND structure @/ myScsiCmdBlock [0] = MY_COMMAND_OPCODE; /@ the required opcode @/ . myScsiCmdBlock [X] = (UINT8) someParam; /@ for example @/ . myScsiCmdBlock [N-1] = MY_CONTROL_BYTE; /@ typically == 0 @/ /@ fill in fields of SCSI_TRANSACTION structure @/ myScsiXaction.cmdAddress = myScsiCmdBlock; myScsiXaction.cmdLength = <# of valid bytes in myScsiCmdBlock>; myScsiXaction.dataAddress = (UINT8 *) buffer; myScsiXaction.dataDirection = <O_RDONLY (0) or O_WRONLY (1)>; myScsiXaction.dataLength = bufLength; myScsiXaction.addLengthByte = 0; /@ no longer used @/ myScsiXaction.cmdTimeout = <timeout in usec>; myScsiXaction.tagType = SCSI_TAG_{DEFAULT,UNTAGGED, SIMPLE,ORDERED,HEAD_OF_Q}; myScsiXaction.priority = [ 0 (highest) to 255 (lowest) ]; if (scsiIoctl (pScsiPhysDev, FIOSCSICOMMAND, &myScsiXaction) == OK) return (OK); else /@ optionally perform retry or other action based on value of * myScsiXaction.statusByte @/ return (ERROR); }.CEINCLUDE FILESscsiLib.h, scsi2Lib.hSEE ALSO: dosFsLib, rt11FsLib, rawFsLib, tapeFsLib, scsiLib, scsiCommonLib,scsiDirectLib, scsiSeqLib, scsiMgrLib, scsiCtrlLib,.I "American National Standard for Information Systems - Small Computer" .I "System Interface (SCSI-2), ANSI X3T9,".pG "I/O System, Local File Systems"*/#define INCLUDE_SCSI2#include "vxWorks.h"#include "ioLib.h"#include "intLib.h"#include "ctype.h"#include "cacheLib.h"#include "stdlib.h"#include "errnoLib.h"#include "taskLib.h"#include "lstLib.h"#include "logLib.h"#include "msgQLib.h"#include "string.h"#include "stdio.h"#include "sysLib.h"#include "scsiLib.h"#include "wdLib.h"/* globals */extern int scsiPhysDevMutexOptions;IMPORT BOOL scsiErrors; /* enable SCSI error messages */IMPORT BOOL scsiDebug; /* enable task level debug messages */IMPORT BOOL scsiIntsDebug; /* enable int level debug messages */int scsiCtrlMutexSemOptions = SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE;int scsiMaxNumThreads = SCSI_DEF_MAX_THREADS;int scsiAllocNumThreads = SCSI_DEF_ALLOC_THREADS;UINT scsiMinTimeout = SCSI_DEF_MIN_TIMEOUT;UINT scsiMaxTimeout = SCSI_DEF_MAX_TIMEOUT;int scsiCacheFlushThreshold = SCSI_DEF_CACHE_FLUSH_THRESHOLD;UINT scsiTestUnitRdyTrys = 5; /* Times to retry scsiTestUnitReady() */IMPORT SCSI_CTRL * pSysScsiCtrl; /* ptr to default SCSI_CTRL struct */VOID scsiTargetReset (SCSI_CTRL * pScsiCtrl, UINT busId);VOID scsiThreadListShow (LIST * pList);VOID scsiThreadListIdShow (LIST * pList);/* forward static functions *//* Backward compatability functions localised */LOCAL STATUS scsi2CtrlInit (SCSI_CTRL *);LOCAL SCSI_PHYS_DEV * scsi2PhysDevIdGet (SCSI_CTRL *, int, int);LOCAL STATUS scsi2PhysDevDelete (FAST SCSI_PHYS_DEV *);LOCAL SCSI_PHYS_DEV * scsi2PhysDevCreate (SCSI_CTRL *, int, int, int, int, BOOL, int, int);LOCAL STATUS scsi2AutoConfig (SCSI_CTRL *);LOCAL STATUS scsi2Show (FAST SCSI_CTRL *);LOCAL STATUS scsi2BusReset (SCSI_CTRL *);LOCAL STATUS scsi2CmdBuild (SCSI_COMMAND, int *, UINT8, int, BOOL, int, int, UINT8);LOCAL STATUS scsi2Transact (SCSI_PHYS_DEV *, SCSI_TRANSACTION *);LOCAL STATUS scsi2Ioctl (SCSI_PHYS_DEV *, int, int);LOCAL char * scsi2PhaseNameGet (int);/* Miscellaneous support routines */LOCAL void scsiTargetInit (SCSI_CTRL * pScsiCtrl, UINT busId);LOCAL BOOL strIsPrintable (char *pString);LOCAL UINT scsiTimeoutCvt (UINT uSecs);LOCAL SCSI_PRIORITY scsiPriorityCvt (UINT priority);LOCAL SCSI_THREAD * scsiThreadCreate (SCSI_PHYS_DEV * pScsiPhysDev, SCSI_TRANSACTION * pScsiXaction);LOCAL void scsiThreadDelete (SCSI_THREAD * pThread);LOCAL SCSI_THREAD * scsiThreadAllocate (SCSI_CTRL * pScsiCtrl);LOCAL void scsiThreadDeallocate (SCSI_CTRL * pScsiCtrl, SCSI_THREAD * pThread);LOCAL char * scsiThreadArrayCreate (SCSI_CTRL * pScsiCtrl, int nThreads);LOCAL STATUS scsiThreadExecute (SCSI_THREAD * pThread);LOCAL STATUS scsiCommand (SCSI_PHYS_DEV * pScsiPhysDev, SCSI_TRANSACTION * pScsiXaction);LOCAL void chkMedChangeAndWP (int addSenseCode, SCSI_PHYS_DEV * pScsiPhysDev);/* Imported functions from other scsi*Lib modules */IMPORT void scsiDirectLibTblInit ();IMPORT void scsiCommonLibTblInit ();/********************************************************************************* scsi2IfInit - initialize the SCSI-2 interface to scsiLib** This routine initializes the SCSI-2 function interface by adding all the * routines in scsi2Lib plus those in scsiDirectLib and scsiCommonLib. It is* invoked by usrConfig.c if the macro INCLUDE_SCSI2 is defined in* config.h. The calling interface remains the same between SCSI-1 and SCSI-2;* this routine simply sets the calling interface function pointers to * the SCSI-2 functions.** RETURNS: N/A*/void scsi2IfInit () { /* Allocate memory for the interface table */ pScsiIfTbl = (SCSI_FUNC_TBL *) calloc (1,sizeof (SCSI_FUNC_TBL)); if (pScsiIfTbl == NULL) return; /* Initialisation of functions in this module */ pScsiIfTbl->scsiCtrlInit = (FUNCPTR) scsi2CtrlInit; pScsiIfTbl->scsiPhaseNameGet = (FUNCPTR) scsi2PhaseNameGet; pScsiIfTbl->scsiPhysDevCreate = (FUNCPTR) scsi2PhysDevCreate; pScsiIfTbl->scsiPhysDevDelete = (FUNCPTR) scsi2PhysDevDelete; pScsiIfTbl->scsiPhysDevIdGet = (FUNCPTR) scsi2PhysDevIdGet; pScsiIfTbl->scsiAutoConfig = (FUNCPTR) scsi2AutoConfig; pScsiIfTbl->scsiShow = (FUNCPTR) scsi2Show; pScsiIfTbl->scsiBusReset = (FUNCPTR) scsi2BusReset; pScsiIfTbl->scsiCmdBuild = (FUNCPTR) scsi2CmdBuild; pScsiIfTbl->scsiTransact = (FUNCPTR) scsi2Transact; pScsiIfTbl->scsiIoctl = (FUNCPTR) scsi2Ioctl; /* Initialisation of functions in other modules */ scsiDirectLibTblInit (); scsiCommonLibTblInit (); }/********************************************************************************* scsi2CtrlInit - initialize generic fields of a SCSI_CTRL structure** This routine should be called by the SCSI controller libraries' xxCtrlCreate* routines, which are responsible for initializing any fields not herein* initialized. It is NOT intended to be called directly by a user.** NOTE* As a matter of good practice, the SCSI_CTRL structure should be* calloc()'ed by the xxCtrlCreate() routine, so that all fields are* initially zero. If this is done, some of the work of this routine will be* redundant.** Many of the fields in the SCSI_CTRL structure are used to set up virtual* functions and configuration data for the controller drivers. If these* fields are left set to zero, default values are used. These values assume* that a bus-level controller driver is used in conjunction with the* generic thread-level driver in this source file (see "scsiCtrlxxx()").** INTERNAL* This function is really initialising too many things and should probably* be broken into several functions such as: scsiMgrInit, scsiCtrlInit (i.e.* the "generic" controller), and an overall initialisation function that* can be called by a driver create routine, as the current routine is.** RETURNS: OK, or ERROR if a semaphore creation fails.** NOMANUAL*/LOCAL STATUS scsi2CtrlInit ( SCSI_CTRL * pScsiCtrl /* ptr to SCSI_CTRL struct to initialize */ ) { int ix; /* loop index */ /* * Initialize virtual functions and configuration info. * * If the driver has left the default value (0), set to the values * for the generic thread-level driver. */ /* structure sizes */ if (pScsiCtrl->eventSize == 0) pScsiCtrl->eventSize = sizeof (SCSI_EVENT); if (pScsiCtrl->threadSize == 0) pScsiCtrl->threadSize = sizeof (SCSI_THREAD); /* virtual functions bus-level driver */ if (pScsiCtrl->scsiTransact == 0) pScsiCtrl->scsiTransact = scsiTransact; if (pScsiCtrl->scsiEventProc == 0) pScsiCtrl->scsiEventProc = scsiCtrlEvent; if (pScsiCtrl->scsiThreadInit == 0) pScsiCtrl->scsiThreadInit = scsiCtrlThreadInit; if (pScsiCtrl->scsiThreadActivate == 0) pScsiCtrl->scsiThreadActivate = scsiCtrlThreadActivate; if (pScsiCtrl->scsiThreadAbort == 0) pScsiCtrl->scsiThreadAbort = scsiCtrlThreadAbort; /* create controller mutual exclusion semaphore */ if ((pScsiCtrl->mutexSem = semMCreate (scsiCtrlMutexSemOptions)) == NULL) { printErr ("scsiCtrlInit: semMCreate of mutexSem failed.\n"); goto failed; } /* create sync semaphore for controller events and client requests */ if ((pScsiCtrl->actionSem = semBCreate (scsiMgrActionSemOptions, SEM_EMPTY)) == NULL) { printErr ("scsiCtrlInit: semBCreate of actionSem failed.\n"); goto failed; } /* create ring buffers for controller events and client requests */ if ((pScsiCtrl->eventQ = rngCreate (scsiMgrEventQSize * pScsiCtrl->eventSize)) == NULL) { printErr ("scsiCtrlInit: rngCreate of eventQ failed\n"); goto failed; } if ((pScsiCtrl->timeoutQ = rngCreate (scsiMgrTimeoutQSize * sizeof (SCSI_TIMEOUT))) == NULL) { printErr ("scsiCtrlInit: rngCreate of timeoutQ failed\n"); goto failed; } if ((pScsiCtrl->requestQ = rngCreate (scsiMgrRequestQSize * sizeof (SCSI_REQUEST))) == NULL) { printErr ("scsiCtrlInit: rngCreate of requestQ failed\n"); goto failed; } if ((pScsiCtrl->replyQ = rngCreate (scsiMgrReplyQSize * sizeof (SCSI_REPLY))) == NULL) { printErr ("scsiCtrlInit: rngCreate of replyQ failed\n"); goto failed; } /* create thread used for incoming identification */ if ((pScsiCtrl->pIdentThread = scsiCtrlIdentThreadCreate (pScsiCtrl)) == 0) { printErr ("scsiCtrlInit: can't create identification thread.\n"); goto failed; } /* initialize the list of free threads */ lstInit (&pScsiCtrl->freeThreads); /* initialize support for disconnect and sync. xfer to yes */ /* (may be reset by driver) */ pScsiCtrl->disconnect = TRUE; pScsiCtrl->syncXfer = TRUE; /* * The default behaviour is assumed to be to disallow wide transfers. * However, this default can be modified by the controller driver and * must be tested first. */ if (pScsiCtrl->wideXfer != TRUE) pScsiCtrl->wideXfer = FALSE; /* initialise controller state variables */ pScsiCtrl->active = FALSE; pScsiCtrl->nThreads = 0; pScsiCtrl->pThread = 0; pScsiCtrl->nextDev = 0; pScsiCtrl->msgInState = SCSI_MSG_IN_NONE; pScsiCtrl->msgOutState = SCSI_MSG_OUT_NONE; /* initialize array of target information */ for (ix = 0; ix < SCSI_MAX_TARGETS; ix++) { pScsiCtrl->targetArr [ix].scsiDevBusId = ix; scsiTargetInit (pScsiCtrl, ix); } /* initialize array of ptrs to SCSI_PHYS_DEV structures to NULL */ for (ix = 0; ix < SCSI_MAX_PHYS_DEVS; ix++) { pScsiCtrl->physDevArr [ix] = (SCSI_PHYS_DEV *) NULL; } /* by default hardware snooping is disabled */ pScsiCtrl->cacheSnooping = FALSE; return (OK);failed: if (pScsiCtrl->mutexSem != 0) (void) semDelete (pScsiCtrl->mutexSem); if (pScsiCtrl->actionSem != 0) (void) semDelete (pScsiCtrl->actionSem); if (pScsiCtrl->eventQ != 0) (void) rngDelete (pScsiCtrl->eventQ);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -