Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ sa(4S) — OS/MP 4.1A3

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

scsi(4S)

sd(4S)

st(4S)

SA(4S)  —  DEVICES AND NETWORK INTERFACES

NAME

sa − user level SCSI access driver

SYNOPSIS

#include <dev/saio.h>

DESCRIPTION

The sa device driver provides a mechanism for the user to access the SCSI bus without having to go to the trouble of writing a kernel device driver.  The driver is intended for use in quickly interfacing non-standard (application specific) SCSI devices to a Solbourne machine.  The remainder of this section discusses the use of this interface. 

The driver supports only three operations: open, close, and ioctl.  Each minor device number represents an exclusive use channel of communication to the SCSI bus.  An open of a channel is not specific to any SCSI target/lun and will always succeed if the channel is not already inuse (given appropriate permissions on the special file).  The channel will remain open until it is closed (or the process which opened it exits). 

An open channel supports two ioctls: one to bind the channel to the specified SCSI device, and one to issue a SCSI command to the device.  The definitions of these ioctl operations are in <dev/saio.h>:

/∗
 ∗ Copyright 1988 Solbourne Computer, Inc.
 ∗ All rights reserved.
 ∗/
 #ifndef _SAIO_
#define _SAIO_
 #include <sys/ioccom.h>
#include <dev/scsi.h>
 /∗
 ∗ Structures and definitions for scsi user io control commands
 ∗/
 /∗
 ∗ Structures used as data by ioctl calls.
 ∗/
 /∗
 ∗ Used to bind an unit to a scsi target
 ∗/
#define    SA_IO_BIND    _IOW(u, 0, struct sa_bind)    /∗ Bind to device ∗/
struct sa_bind {
    u_char    sa_bind_target;     /∗ scsi target id to bind ∗/
    u_char    sa_bind_lun;        /∗ lun of target to bind ∗/
    int       sa_bind_flags;
#define    SA_BIND_FLAGS_SILENT   0x01    /∗ no error messages ∗/
#define    SA_BIND_FLAGS_DISCON   0x02    /∗ allow disconnect ∗/
#define    SA_BIND_FLAGS_SYNCH    0x04    /∗ allow synchronous ∗/
#define    SA_BIND_FLAGS_PARITY   0x08    /∗ allow parity ∗/
#define    SA_BIND_FLAGS_NON_MUX  0x10    /∗ non-multiplexed device ∗/
#define    SA_BIND_FLAGS_MSG_CC   0x20    /∗ only supports cmd complete ∗/
    int    sa_bind_blksize;
};
 /∗
 ∗ Used for commands
 ∗/
#define    SA_IO_CMD    _IOWR(u, 1, struct sa_cmd)    /∗ issue cmd ∗/
struct sa_cmd {
    union scsi_cdb  ∗sa_cmd_cdb;        /∗ scsi command block ∗/
    caddr_t         sa_cmd_bufaddr;     /∗ user’s buffer address ∗/
    u_int           sa_cmd_buflen;      /∗ size of user’s buffer ∗/
    short           sa_cmd_ctlb_flags;  /∗ command flags for ∗/
                        /∗ non-standard commands. ∗/
                        /∗ see scsi.h ctlb_flags...∗/
    short           sa_cmd_timeout;     /∗ time for completion ∗/
    int             sa_cmd_error_class; /∗ see scsi_var.h ∗/
    int             sa_cmd_error_code;  /∗ host adaptor specific ∗/
    union scsi_scb  ∗sa_cmd_scb;        /∗ execution status ∗/
};
#endif !_SAIO_
};

EXAMPLE

The following example will print out the current devices plugged into the SCSI bus. 

#include    <sys/types.h>
#include    <dev/saio.h>
 struct sa_bind   sa_bind;
struct sa_cmd    sa_cmd;
struct scsi_inq  scsi_inq;
union scsi_cdb   scsi_cdb;
union scsi_scb   scsi_scb;
 main()
{
    int fd, target;
     if ((fd = open("/dev/sa0", 2)) < 0) {
        perror("failed open");
        exit(1);
    }
     for (target = 0 ; target < 7 ; target++) {
        sa_bind.sa_bind_target = target;
        sa_bind.sa_bind_lun = 0;
        sa_bind.sa_bind_flags =
            SA_BIND_FLAGS_DISCON | SA_BIND_FLAGS_PARITY;
        if (ioctl(fd, SA_IO_BIND, &sa_bind) < 0) {
            perror("failed bind");
            exit(1);
        }
         SET_CDB_0(scsi_cdb, SC_INQUIRY, 0, 0, sizeof(struct scsi_inq));
        sa_cmd.sa_cmd_cdb = &scsi_cdb;
        sa_cmd.sa_cmd_bufaddr = (caddr_t) &scsi_inq;
        sa_cmd.sa_cmd_buflen = sizeof(struct scsi_inq);
        sa_cmd.sa_cmd_timeout = 60;
        sa_cmd.sa_cmd_scb = &scsi_scb;
        if (ioctl(fd, SA_IO_CMD, &sa_cmd) < 0) {
            perror("failed cmd");
            exit(1);
        }
        printf("target %d lun 0: ", target);
        if (sa_cmd.sa_cmd_error_class || sa_cmd.sa_cmd_error_code)
            printf("ERROR_CLASS %d, ERROR_CODE %d0,
                sa_cmd.sa_cmd_error_class,
                sa_cmd.sa_cmd_error_code);
        else
            printf("%s0, scsi_inq.inq_vendor);
    }
    exit(0);
}

SEE ALSO

scsi(4S), sd(4S), st(4S)

Solbourne Computer, Inc.  —  13 December 1989

Typewritten Software • bear@typewritten.org • Edmonds, WA 98026