VxWorks Reference Manual : Libraries

scsi1Lib

NAME

scsi1Lib - Small Computer System Interface (SCSI) library (SCSI-1)

ROUTINES

DESCRIPTION

This library implements the Small Computer System Interface (SCSI) protocol in a controller-independent manner. It implements only the SCSI initiator function; the library does not support a VxWorks target acting as a SCSI target. Furthermore, in the current implementation, a VxWorks 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 the selection of a SCSI device by the initiator, the issuance of a SCSI command, and the sequence of data, status, and message phases necessary to perform the command. A transaction normally completes with a "Command Complete" message from the target, followed by disconnection from the SCSI bus. If the status from the target is "Check Condition," the transaction continues; the initiator issues a "Request Sense" command to gain more information on the exception condition reported.

Many of the subroutines in scsi1Lib facilitate the transaction of frequently used SCSI commands. Individual command fields are passed as arguments from which SCSI Command Descriptor Blocks are constructed, and fields of a SCSI_TRANSACTION structure are filled in appropriately. This structure, along with the SCSI_PHYS_DEV structure associated with the target SCSI device, is passed to the routine whose address is indicated by the scsiTransact field of the SCSI_CTRL structure associated with the relevant SCSI controller.

The function variable scsiTransact is set by the individual SCSI controller driver. For off-board SCSI controllers, this routine rearranges the fields of the SCSI_TRANSACTION structure into the appropriate structure for the specified hardware, which then carries out the transaction through firmware control. Drivers for an on-board SCSI-controller chip can use the scsiTransact( ) routine in scsiLib (which invokes 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 DEVICES

The scsi1Lib library supports use of SCSI peripherals conforming to the standards specified in Common Command Set (CCS) of the SCSI, Rev. 4.B. Most SCSI peripherals currently offered support CCS. While an attempt has been made to have scsi1Lib support non-CCS peripherals, not all commands or features of this library are guaranteed to work with them. For example, auto-configuration may be impossible with non-CCS devices, if they do not support the INQUIRY command.

Not all classes of SCSI devices are supported. However, the scsiLib library provides the capability to transact any SCSI command on any SCSI device through the FIOSCSICOMMAND function of the scsiIoctl( ) routine.

Only direct-access devices (disks) are supported by a file system. For other types of devices, additional, higher-level software is necessary to map user-level commands to SCSI transactions.

CONFIGURING SCSI CONTROLLERS

The routines to create and initialize a specific SCSI controller are particular to the controller and normally are found in its library module. The normal calling sequence is:

    xxCtrlCreate (...); /* parameters are controller specific */
    xxCtrlInit (...);   /* parameters are controller specific */
The conceptual difference between the two routines is that xxCtrlCreate( ) calloc's memory for the xx_SCSI_CTRL data structure and initializes information that is never expected to change (for example, clock rate). The remaining fields in the xx_SCSI_CTRL structure are initialized by xxCtrlInit( ) and any necessary registers are written on the SCSI controller to effect the desired initialization. This routine can be called multiple times, although this is rarely required. For example, the bus ID of the SCSI controller can be changed without rebooting the VxWorks system.

CONFIGURING PHYSICAL SCSI DEVICES

Before a device can be used, it must be "created," that is, declared. This is done with scsiPhysDevCreate( ) and can only be done after a SCSI_CTRL structure exists and has been properly initialized.

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 */
    )
Several of these parameters can be left unspecified, as follows:
reqSenseLength
If 0, issue a REQUEST_SENSE to determine a request sense length.

devType
If -1, issue an INQUIRY to determine the device type.

numBlocks, blockSize
If 0, issue a READ_CAPACITY to determine the number of blocks.

The above values are recommended, unless the device does not support the required commands, or other non-standard conditions prevail.

LOGICAL PARTITIONS ON BLOCK DEVICES

It is possible to have more than one logical partition on a SCSI block device. This capability is currently not supported for removable media devices. A partition is an array of contiguously addressed blocks with a specified starting block address and a specified number of blocks. The scsiBlkDevCreate( ) routine is called once for each block device partition. Under normal usage, logical partitions should not overlap.

SCSI_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 */
    )
Note that if numBlocks is 0, the rest of the device is used.

ATTACHING FILE SYSTEMS TO LOGICAL PARTITIONS

Files 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 more information, see the documentation in dosFsLib or rt11FsLib.

TRANSMITTING ARBITRARY COMMANDS TO SCSI DEVICES

The scsi1Lib library provides routines that implement many common SCSI commands. Still, there are situations that require commands that are not supported 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:

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.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);
    }

INCLUDE FILES

scsiLib.h, scsi1Lib.h

SEE ALSO

scsi1Lib, dosFsLib, rt11FsLib, < >American National Standards for Information Systems - Small Computer" < >System Interface (SCSI), ANSI X3.131-1986, " VxWorks Programmer's Guide: I/O System, Local File Systems