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

📄 scsi1lib.c

📁 VxWorks操作系统内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* scsi1Lib.c - Small Computer System Interface (SCSI) library (SCSI-1) *//* Copyright 1989-1994 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02e,09jul97,dgp  doc: correct fonts per SPR 785302d,29oct96,dgp  doc: editing for newly published SCSI libraries02c,06may96,jds  and more doc fixes...02b,01may96,jds  yet more doc fixes...02a,13nov95,jds  more doc tweaks01z,08nov95,jds  doc tweaks01y,10oct94,jds  fixed for SCSI1 and SCSI2 backward compatability01x,28feb93,jdi  doc: changed comment in scsiWrtSecs() from "read" to "write".01w,27nov92,jdi  documentation cleanup, including SPR 1415.01v,15sep92,ccc  reworked select timeout, fixed extended message to work		 with new drive, documentation changes.01u,10aug92,ccc  added timeouts to scsiXaction for each scsi command.01t,28jul92,rrr  fixed decl of scsiSyncTarget01s,22jul92,gae  added correct number of parameters to logMsg().01r,20jul92,eve  Remove conditional INCLUDE_SYNC_SCSI compilation.01q,18jul92,smb  Changed errno.h to errnoLib.h.01p,13jul92,eve  added init of the current pScsiXaction in scsiPhaseSequence().01o,08jul92,eve  supplies a reqSense buffer if there is no user buffer 		 in scsiTransact routine.01n,03jul92,eve  added new sync feature with NOMANUAL01m,26may92,rrr  the tree shuffle01l,16dec91,gae  added includes for ANSI; added parameters to logMsg() calls.01k,19nov91,rrr  shut up some ansi warnings.01j,04oct91,rrr  passed through the ansification filter                  -changed functions to ansi style		  -changed READ, WRITE and UPDATE to O_RDONLY O_WRONLY and ...		  -changed VOID to void		  -changed copyright notice01i,13mar91,jcc  misc. clean-up and enhancements.01h,25oct90,jcc  lint.01g,18oct90,jcc  removed call to printErrno() in scsiAutoConfig().01f,02oct90,jcc  UTINY became UINT8; added scsiAutoConfig(), scsiPhysDevIdGet(),		 and scsiIoctl() option FIODISKFORMAT;		 changed all malloc()'s to calloc()'s in xxCreate() routines;		 made changes associated with SEM_ID's becoming SEMAPHORE's		 in created structures;		 enhanced scsiPhysDevCreate() to determine amount and type		 of REQUEST SENSE data returned by the device; miscellaneous.01e,10aug90,dnw  fixed warnings caused by changing scsiBusReset to VOIDFUNCPTR.01d,18jul90,jcc  made semTake() calls 5.0 compatible; clean-up.01c,08jun90,jcc  modified incoming message handling; generalized scsiTransact		 calls to a procedure variable to allow off-board SCSI		 controller drivers; documentation.01b,23mar90,jcc  lint.01a,05may89,jcc  written.*//*DESCRIPTIONThis library implements the Small Computer System Interface (SCSI)protocol in a controller-independent manner.  It implements only the SCSIinitiator function; the library does not support a VxWorks targetacting as a SCSI target.  Furthermore, in the current implementation, aVxWorks target is assumed to be the only initiator on the SCSI bus,although there may be multiple targets (SCSI peripherals) on the bus.The implementation is transaction based.  A transaction is defined as theselection of a SCSI device by the initiator, the issuance of a SCSI command,and the sequence of data, status, and message phases necessary to performthe command.  A transaction normally completes with a "Command Complete" message fromthe target, followed by disconnection from the SCSI bus.  Ifthe status from the target is "Check Condition," the transaction continues;the initiator issues a "Request Sense" command to gain more informationon the exception condition reported.Many of the subroutines in scsi1Lib facilitate the transaction offrequently used SCSI commands.  Individual command fields are passed asarguments from which SCSI Command Descriptor Blocks are constructed, andfields of a SCSI_TRANSACTION structure are filled in appropriately.  Thisstructure, along with the SCSI_PHYS_DEV structure associated with thetarget SCSI device, is passed to the routine whose address is indicated bythe 'scsiTransact' field of the SCSI_CTRL structure associated with therelevant SCSI controller.The function variable 'scsiTransact' is set by the individual SCSIcontroller driver.  For off-board SCSI controllers, thisroutine rearranges the fields of the SCSI_TRANSACTION structure intothe appropriate structure for the specified hardware, which then carries outthe transaction through firmware control.  Drivers for an on-boardSCSI-controller chip can use the scsiTransact() routine in scsiLib (whichinvokes the scsi1Transact() routine in scsi1Lib), as long as they provide the other functions specified in the SCSI_CTRL structure.Note that no disconnect/reconnect capability is currently supported.SUPPORTED SCSI DEVICESThe scsi1Lib library supports use of SCSI peripherals conforming to the standards specified in .I "Common Command Set (CCS) of the SCSI, Rev. 4.B."Most SCSI peripherals currently offered support CCS.  While an attempt has been madeto have scsi1Lib support non-CCS peripherals, not all commands or featuresof this library are guaranteed to work with them.  For example,auto-configuration may be impossible with non-CCS devices, if they do notsupport the INQUIRY command.Not all classes of SCSI devices are supported.  However, the scsiLib libraryprovides the capability to transact any SCSI command on any SCSI devicethrough the FIOSCSICOMMAND function of the scsiIoctl() routine.Only direct-access devices (disks) are supported by a file system.  Forother types of devices, additional, higher-level software is necessary tomap user-level commands to SCSI transactions.CONFIGURING SCSI CONTROLLERSThe routines to create and initialize a specific SCSI controller areparticular to the controller and normally are found in its librarymodule.  The normal calling sequence is:.ne 4.CS    xxCtrlCreate (...); /@ parameters are controller specific @/    xxCtrlInit (...);   /@ parameters are controller specific @/.CEThe conceptual difference between the two routines is that xxCtrlCreate()calloc's memory for the xx_SCSI_CTRL data structure and initializesinformation that is never expected to change (for example, clock rate).  Theremaining fields in the xx_SCSI_CTRL structure are initialized byxxCtrlInit() and any necessary registers are written on the SCSIcontroller to effect the desired initialization.  Thisroutine can be called multiple times, although this is rarely required.For example, the bus ID of the SCSIcontroller can be changed without rebooting the VxWorks system.CONFIGURING PHYSICAL SCSI DEVICESBefore a device can be used, it must be "created," that is, declared.This is done with scsiPhysDevCreate() and can only be done after aSCSI_CTRL structure exists and has been properly initialized..CSSCSI_PHYS_DEV *scsiPhysDevCreate    (    SCSI_CTRL * pScsiCtrl,/@ ptr to SCSI controller info @/    int  devBusId,        /@ device's SCSI bus ID @/    int  devLUN,          /@ device's logical unit number @/    int  reqSenseLength,  /@ length of REQUEST SENSE data dev returns @/    int  devType,         /@ type of SCSI device @/    BOOL removable,       /@ whether medium is removable @/    int  numBlocks,       /@ number of blocks on device @/    int  blockSize        /@ size of a block in bytes @/    ).CESeveral of these parameters can be left unspecified, as follows:.iP <reqSenseLength>If 0, issue a REQUEST_SENSE to determine a request sense length..iP <devType>If -1, issue an INQUIRY to determine the device type..iP "<numBlocks>, <blockSize>"If 0, issue a READ_CAPACITY to determine the number of blocks..LPThe above values are recommended, unless the device does not support therequired commands, or other non-standard conditions prevail.LOGICAL PARTITIONS ON BLOCK DEVICESIt is possible to have more than one logical partition on a SCSI blockdevice.  This capability is currently not supported for removable mediadevices.  A partition is an array of contiguously addressed blockswith a specified starting block address and a specified number of blocks.The scsiBlkDevCreate() routine is called once for each block devicepartition.  Under normal usage, logical partitions should not overlap..ne 8.CSSCSI_BLK_DEV *scsiBlkDevCreate    (    SCSI_PHYS_DEV *  pScsiPhysDev,  /@ ptr to SCSI physical device info @/    int              numBlocks,     /@ number of blocks in block device @/    int              blockOffset    /@ address of first block in volume @/    ).CENote that if <numBlocks> is 0, the rest of the device is used.ATTACHING FILE SYSTEMS TO LOGICAL PARTITIONSFiles cannot be read or written to a disk partition until a file system(such as dosFs or rt11Fs) has been initialized on the partition.  For moreinformation, see the documentation in dosFsLib or rt11FsLib.TRANSMITTING ARBITRARY COMMANDS TO SCSI DEVICESThe scsi1Lib library provides routines that implement many common SCSIcommands.  Still, there are situations that require commands that are notsupported by scsi1Lib (for example, writing software to control non-direct access devices).  Arbitrary commands are handled with the FIOSCSICOMMAND option to scsiIoctl().  The <arg> parameter for FIOSCSICOMMAND is a pointer to a valid SCSI_TRANSACTION structure.  Typically, a call to scsiIoctl() is written as a subroutine of the form:.CSSTATUS 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.cmdTimeout    = timeout in usec;    /@ if dataDirection is O_RDONLY, and the length of the input data is     * variable, the following parameter specifies the byte # (min == 0)     * of the input data which will specify the additional number of     * bytes available     @/    myScsiXaction.addLengthByte = X;    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, scsi1Lib.hSEE ALSO: dosFsLib, rt11FsLib,.I  "American National Standards for Information Systems - Small Computer" .I  "System Interface (SCSI), ANSI X3.131-1986,".pG "I/O System, Local File Systems"*/#include "vxWorks.h"#include "ioLib.h"#include "ctype.h"#include "stdlib.h"#include "errnoLib.h"#include "taskLib.h"#include "logLib.h"#include "string.h"#include "stdio.h"#include "scsiLib.h"/* forward static functions */LOCAL BOOL            strIsPrintable (char *);LOCAL STATUS          scsiDevSelect (SCSI_PHYS_DEV *, SCSI_TRANSACTION *);LOCAL STATUS          scsiStatusCheck (BLK_DEV *);LOCAL STATUS          scsiPhaseSequence (SCSI_PHYS_DEV *, SCSI_TRANSACTION *);LOCAL STATUS          scsiBlkDevIoctl (SCSI_BLK_DEV *, int, int);LOCAL STATUS          scsiSyncTarget (SCSI_PHYS_DEV *, int, int, 						       SCSI_SYNC_AGREEMENT *);LOCAL STATUS          scsi1CtrlInit (SCSI_CTRL *);LOCAL STATUS          scsi1TestUnitRdy (SCSI_PHYS_DEV *);LOCAL SCSI_PHYS_DEV * scsi1PhysDevIdGet (SCSI_CTRL *, int, int);LOCAL STATUS          scsi1ReqSense (SCSI_PHYS_DEV *, char *, int);LOCAL STATUS          scsi1Inquiry (SCSI_PHYS_DEV *, char *, int);LOCAL STATUS          scsi1ReadCapacity (SCSI_PHYS_DEV *, int *, int *);LOCAL STATUS          scsi1RdSecs (SCSI_BLK_DEV *, int, int, char *);LOCAL STATUS          scsi1WrtSecs (SCSI_BLK_DEV *, int, int, char *);LOCAL STATUS          scsi1PhysDevDelete (FAST SCSI_PHYS_DEV *);LOCAL SCSI_PHYS_DEV * scsi1PhysDevCreate (SCSI_CTRL *, int, int, int, int, BOOL,                                        int, int);LOCAL STATUS          scsi1AutoConfig (SCSI_CTRL *);LOCAL BLK_DEV *       scsi1BlkDevCreate (SCSI_PHYS_DEV *, int, int);LOCAL void            scsi1BlkDevInit (SCSI_BLK_DEV *, int, int);LOCAL void            scsi1BlkDevShow (SCSI_PHYS_DEV *);LOCAL STATUS          scsi1Show (FAST SCSI_CTRL *);LOCAL STATUS          scsi1BusReset (SCSI_CTRL *);LOCAL STATUS          scsi1CmdBuild (SCSI_COMMAND, int *, UINT8, int, BOOL, int,         							int, UINT8);LOCAL STATUS          scsi1Transact (SCSI_PHYS_DEV *, SCSI_TRANSACTION *);LOCAL STATUS          scsi1Ioctl (SCSI_PHYS_DEV *, int, int);LOCAL STATUS          scsi1FormatUnit (SCSI_PHYS_DEV *, BOOL, int, int, int, 								char *,int);LOCAL STATUS          scsi1ModeSelect (SCSI_PHYS_DEV *, int, int, char *, int);LOCAL STATUS          scsi1ModeSense (SCSI_PHYS_DEV *, int, int, char *, int);LOCAL char *          scsi1PhaseNameGet (int);SCSI_FUNC_TBL scsi1IfTbl =    {    (FUNCPTR) scsi1CtrlInit,    (FUNCPTR) scsi1BlkDevInit,    (FUNCPTR) scsi1BlkDevCreate,    (FUNCPTR) scsi1BlkDevShow,    (FUNCPTR) scsi1PhaseNameGet,    (FUNCPTR) scsi1PhysDevCreate,    (FUNCPTR) scsi1PhysDevDelete,    (FUNCPTR) scsi1PhysDevIdGet,    (FUNCPTR) scsi1AutoConfig,    (FUNCPTR) scsi1Show,    (FUNCPTR) scsi1BusReset,    (FUNCPTR) scsi1CmdBuild,    (FUNCPTR) scsi1Transact,    (FUNCPTR) scsi1Ioctl,    (FUNCPTR) scsi1FormatUnit,    (FUNCPTR) scsi1ModeSelect,    (FUNCPTR) scsi1ModeSense,    (FUNCPTR) scsi1ReadCapacity,    (FUNCPTR) scsi1RdSecs,    (FUNCPTR) scsi1WrtSecs,    (FUNCPTR) scsi1TestUnitRdy,    (FUNCPTR) scsi1Inquiry,    (FUNCPTR) scsi1ReqSense    };/********************************************************************************* scsi1IfInit - initialize the SCSI1 interface to scsiLib** NOMANUAL */void scsi1IfInit ()    {    pScsiIfTbl = &scsi1IfTbl;    pScsiIfTbl->scsiCtrlInit      = (FUNCPTR) scsi1CtrlInit;    pScsiIfTbl->scsiPhysDevDelete = (FUNCPTR) scsi1PhysDevDelete;    pScsiIfTbl->scsiPhysDevCreate = (FUNCPTR) scsi1PhysDevCreate;    pScsiIfTbl->scsiAutoConfig    = (FUNCPTR) scsi1AutoConfig;    pScsiIfTbl->scsiBlkDevCreate  = (FUNCPTR) scsi1BlkDevCreate;    pScsiIfTbl->scsiPhysDevIdGet  = (FUNCPTR) scsi1PhysDevIdGet;    pScsiIfTbl->scsiBlkDevInit    = (FUNCPTR) scsi1BlkDevInit;    pScsiIfTbl->scsiBlkDevShow    = (FUNCPTR) scsi1BlkDevShow;    pScsiIfTbl->scsiShow          = (FUNCPTR) scsi1Show;    pScsiIfTbl->scsiBusReset      = (FUNCPTR) scsi1BusReset;    pScsiIfTbl->scsiCmdBuild      = (FUNCPTR) scsi1CmdBuild;    pScsiIfTbl->scsiTransact      = (FUNCPTR) scsi1Transact;    pScsiIfTbl->scsiIoctl         = (FUNCPTR) scsi1Ioctl;    pScsiIfTbl->scsiFormatUnit    = (FUNCPTR) scsi1FormatUnit;    pScsiIfTbl->scsiModeSelect    = (FUNCPTR) scsi1ModeSelect;    pScsiIfTbl->scsiModeSense     = (FUNCPTR) scsi1ModeSense;    pScsiIfTbl->scsiPhaseNameGet  = (FUNCPTR) scsi1PhaseNameGet;    pScsiIfTbl->scsiReadCapacity  = (FUNCPTR) scsi1ReadCapacity;    pScsiIfTbl->scsiRdSecs        = (FUNCPTR) scsi1RdSecs;    pScsiIfTbl->scsiWrtSecs       = (FUNCPTR) scsi1WrtSecs;    pScsiIfTbl->scsiTestUnitRdy   = (FUNCPTR) scsi1TestUnitRdy;    pScsiIfTbl->scsiInquiry       = (FUNCPTR) scsi1Inquiry;    pScsiIfTbl->scsiReqSense      = (FUNCPTR) scsi1ReqSense;    }/********************************************************************************* scsi1CtrlInit - 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.** RETURNS: OK, or ERROR if a semaphore initialization fails.** NOMANUAL*/LOCAL STATUS scsi1CtrlInit    (    SCSI_CTRL *pScsiCtrl        /* ptr to SCSI_CTRL struct to initialize */    )    {

⌨️ 快捷键说明

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