📄 scsilib.c
字号:
/* scsiLib.c - Small Computer System Interface (SCSI) library *//* Copyright 1989-1995 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01h,09jul97,dgp doc: correct fonts per SPR 785301g,29oct96,dgp doc: editing for newly published SCSI libraries01f,01may96,jds doc tweaks01e,13nov95,jds minor documentation tweaks01d,08nov95,jds main description modification01c,20sep95,jdi doc tweaks.01b,11feb95,jdi doc: fixed style for global variable pSysScsiCtrl.01a,24aug94,jds Written. Interface and documentation remain the same. However, routines moved to different SCSI1 or SCSI2 libraries.*//*DESCRIPTIONThe purpose of this library is to switch SCSI function calls (the common SCSI-1 and SCSI-2 calls listed above) to either scsi1Lib or scsi2Lib, depending upon the SCSI configuration in the Board Support Package (BSP).The normal usage is to configure SCSI-2. However, SCSI-1 is configuredwhen device incompatibilities exist. VxWorks can be configured with either SCSI-1 or SCSI-2, but not both SCSI-1 and SCSI-2 simultaneously.For more information about SCSI-1 functionality, refer to scsi1Lib. For more information about SCSI-2, refer to scsi2Lib.INCLUDE FILESscsiLib.h, scsi1Lib.h, scsi2Lib.hSEE ALSO: dosFsLib, rt11FsLib, rawFsLib, scsi1Lib, scsi2Lib,.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 "sysLib.h"#include "scsiLib.h"/* globals */BOOL scsiErrors; /* enable SCSI error messages */BOOL scsiDebug; /* enable task level debug messages */BOOL scsiIntsDebug; /* enable int level debug messages */SCSI_FUNC_TBL * pScsiIfTbl; /* pointer to scsiLib interface table */ /* select timeout to use when creating a SCSI_PHYS_DEV */UINT32 scsiSelectTimeout = SCSI_DEF_SELECT_TIMEOUT;int blkDevListMutexOptions = SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE;int scsiCtrlMutexOptions = SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE;int scsiCtrlSemOptions = SEM_Q_FIFO;int scsiPhysDevMutexOptions = SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE;int scsiPhysDevSemOptions = SEM_Q_FIFO;SCSI_CTRL * pSysScsiCtrl; /* ptr to default SCSI_CTRL struct *//******************************************************************************** scsiCtrlInit - 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*/STATUS scsiCtrlInit ( SCSI_CTRL *pScsiCtrl /* ptr to SCSI_CTRL struct to initialize */ ) { if (pScsiIfTbl->scsiCtrlInit != NULL) return ((STATUS) (pScsiIfTbl->scsiCtrlInit) (pScsiCtrl)); else return (ERROR); }/******************************************************************************** scsiPhysDevDelete - delete a SCSI physical-device structure** This routine deletes a specified SCSI physical-device structure.** RETURNS: OK, or ERROR if `pScsiPhysDev' is NULL or SCSI_BLK_DEVs have* been created on the device.*/STATUS scsiPhysDevDelete ( SCSI_PHYS_DEV *pScsiPhysDev /* ptr to SCSI physical device info */ ) { if (pScsiIfTbl->scsiPhysDevDelete != NULL) return ((STATUS) (pScsiIfTbl->scsiPhysDevDelete) (pScsiPhysDev)); else return (ERROR); }/********************************************************************************* scsiPhysDevCreate - create a SCSI physical device structure** This routine enables access to a SCSI device and must be the first routine* invoked. It must be called once for each physical device on the SCSI bus.** If <reqSenseLength> is NULL (0), one or more REQUEST_SENSE* commands are issued to the device to determine the number of bytes of* sense data it typically returns. Note that if the device returns variable* amounts of sense data depending on its state, you must consult the device* manual to determine the maximum amount of sense data that can be* returned.** If <devType> is NONE (-1), an INQUIRY command is issued to* determine the device type; as an added benefit, it acquires the device's* make and model number. The scsiShow() routine displays this information.* Common values of <devType> can be found in scsiLib.h or in the SCSI* specification.** If <numBlocks> or <blockSize> are specified as NULL (0), a READ_CAPACITY* command is issued to determine those values. This occurs* only for device types that support READ_CAPACITY.** RETURNS: A pointer to the created SCSI_PHYS_DEV structure, or NULL if the* routine is unable to create the physical-device structure.*/SCSI_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 */ ) { if (pScsiIfTbl->scsiPhysDevCreate != NULL) return ((SCSI_PHYS_DEV *) (pScsiIfTbl->scsiPhysDevCreate) (pScsiCtrl, devBusId, devLUN, reqSenseLength, devType, removable, numBlocks, blockSize)); else return (NULL); }/********************************************************************************* scsiPhysDevIdGet - return a pointer to a SCSI_PHYS_DEV structure** This routine returns a pointer to the SCSI_PHYS_DEV structure of the SCSI* physical device located at a specified bus ID (<devBusId>) and logical* unit number (<devLUN>) and attached to a specified SCSI controller* (<pScsiCtrl>).** RETURNS: A pointer to the specified SCSI_PHYS_DEV structure, or NULL if the* structure does not exist.*/SCSI_PHYS_DEV * scsiPhysDevIdGet ( SCSI_CTRL * pScsiCtrl, /* ptr to SCSI controller info */ int devBusId, /* device's SCSI bus ID */ int devLUN /* device's logical unit number */ ) { if (pScsiIfTbl->scsiPhysDevIdGet != NULL) return ((SCSI_PHYS_DEV *) (pScsiIfTbl->scsiPhysDevIdGet) (pScsiCtrl, devBusId, devLUN)); else return (NULL); }/********************************************************************************* scsiAutoConfig - configure all devices connected to a SCSI controller** This routine cycles through all valid SCSI bus IDs and logical unit* numbers (LUNs), attempting a scsiPhysDevCreate() with default parameters* on each. All devices which support the INQUIRY command are* configured. The scsiShow() routine can be used to find the system table* of SCSI physical devices attached to a specified SCSI controller. In* addition, scsiPhysDevIdGet() can be used programmatically to get a* pointer to the SCSI_PHYS_DEV structure associated with the device at a* specified SCSI bus ID and LUN.** RETURNS: OK, or ERROR if <pScsiCtrl> and the global variable `pSysScsiCtrl'* are both NULL.*/STATUS scsiAutoConfig ( SCSI_CTRL *pScsiCtrl /* ptr to SCSI controller info */ ) { if (pScsiIfTbl->scsiAutoConfig != NULL) return ((STATUS) (pScsiIfTbl->scsiAutoConfig) (pScsiCtrl)); else return (ERROR); }/********************************************************************************* scsiShow - list the physical devices attached to a SCSI controller** This routine displays the SCSI bus ID, logical unit number (LUN), vendor ID,* product ID, firmware revision (rev.), device type, number of blocks,* block size in bytes, and a pointer to the associated SCSI_PHYS_DEV* structure for each physical SCSI device known to be attached to a specified* SCSI controller.** NOTE:* If <pScsiCtrl> is NULL, the value of the global variable `pSysScsiCtrl'* is used, unless it is also NULL.** RETURNS: OK, or ERROR if both <pScsiCtrl> and `pSysScsiCtrl' are NULL.*/STATUS scsiShow ( SCSI_CTRL *pScsiCtrl /* ptr to SCSI controller info */ ) { if (pScsiIfTbl->scsiShow != NULL) return ((STATUS) (pScsiIfTbl->scsiShow) (pScsiCtrl)); else return (ERROR); }/********************************************************************************* scsiBlkDevCreate - define a logical partition on a SCSI block device** This routine creates and initializes a BLK_DEV structure, which* describes a logical partition on a SCSI physical-block device. A logical* partition is an array of contiguously addressed blocks; it can be completely* described by the number of blocks and the address of the first block in* the partition. In normal configurations partitions do not overlap, although* such a condition is not an error.** NOTE:* If <numBlocks> is 0, the rest of device is used.** RETURNS: A pointer to the created BLK_DEV, or NULL if parameters exceed* physical device boundaries, if the physical device is not a block device, or* if memory is insufficient for the structures.*/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 */ ) { if (pScsiIfTbl->scsiBlkDevCreate != NULL) return ((BLK_DEV *) (pScsiIfTbl->scsiBlkDevCreate) (pScsiPhysDev, numBlocks, blockOffset)); else return (NULL); }/********************************************************************************* scsiBlkDevInit - initialize fields in a SCSI logical partition** This routine specifies the disk-geometry parameters required by certain* file systems (for example, dosFs). It is called after a SCSI_BLK_DEV* structure is created with scsiBlkDevCreate(), but before calling a file system* initialization routine. It is generally required only for removable-media* devices.** RETURNS: N/A*/void scsiBlkDevInit ( SCSI_BLK_DEV * pScsiBlkDev, /* ptr to SCSI block dev. struct */ int blksPerTrack,/* blocks per track */ int nHeads /* number of heads */ ) { if (pScsiIfTbl->scsiBlkDevInit != NULL) (pScsiIfTbl->scsiBlkDevInit) (pScsiBlkDev, blksPerTrack, nHeads); }/********************************************************************************* scsiBlkDevShow - show the BLK_DEV structures on a specified physical device** This routine displays all of the BLK_DEV structures created on a specified* physical device. This routine is called by scsiShow() but may also be* invoked directly, usually from the shell.** RETURNS: N/A** SEE ALSO: scsiShow()*/void scsiBlkDevShow ( SCSI_PHYS_DEV * pScsiPhysDev /* ptr to SCSI physical device info */ ) { if (pScsiIfTbl->scsiBlkDevShow != NULL) (pScsiIfTbl->scsiBlkDevShow) (pScsiPhysDev); }/********************************************************************************* scsiBusReset - pulse the reset signal on the SCSI bus** This routine calls a controller-specific routine to reset a specified* controller's SCSI bus. If no controller is specified (<pScsiCtrl> is 0),* the value in the global variable `pSysScsiCtrl' is used.** RETURNS: OK, or ERROR if there is no controller or controller-specific* routine.*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -