mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-27 05:21:08 +01:00
345 lines
11 KiB
Groff
345 lines
11 KiB
Groff
|
.\" Copyright (c) 1994 HD Associates (hd@world.std.com)
|
||
|
.\" All rights reserved.
|
||
|
.\"
|
||
|
.\" Redistribution and use in source and binary forms, with or without
|
||
|
.\" modification, are permitted provided that the following conditions
|
||
|
.\" are met:
|
||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||
|
.\" notice, this list of conditions and the following disclaimer.
|
||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||
|
.\" documentation and/or other materials provided with the distribution.
|
||
|
.\" 3. All advertising materials mentioning features or use of this software
|
||
|
.\" must display the following acknowledgement:
|
||
|
.\" This product includes software developed by HD Associates
|
||
|
.\" 4. Neither the name of the HD Associaates nor the names of its contributors
|
||
|
.\" may be used to endorse or promote products derived from this software
|
||
|
.\" without specific prior written permission.
|
||
|
.\"
|
||
|
.\" THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES``AS IS'' AND
|
||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE
|
||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
|
.\" SUCH DAMAGE.
|
||
|
.\"
|
||
|
.\"
|
||
|
.Dd November 20, 1994
|
||
|
.Dt SCSI 3
|
||
|
.Os
|
||
|
.Sh NAME
|
||
|
.Nm scsireq_buff_decode ,
|
||
|
.Nm scsireq_build ,
|
||
|
.Nm scsireq_decode ,
|
||
|
.Nm scsireq_encode
|
||
|
.Nm scsireq_enter
|
||
|
.Nm scsireq_new ,
|
||
|
.Nm scsireq_reset ,
|
||
|
.Nm SCSIREQ_ERROR ,
|
||
|
.Nm scsi_open
|
||
|
.Nm scsi_debug
|
||
|
.Nm scsi_debug_output
|
||
|
.Nd SCSI User library
|
||
|
.Sh SYNOPSIS
|
||
|
.Fd #include <sys/types.h>
|
||
|
.Fd #include <sys/scsiio.h>
|
||
|
.Fd #include <libscsi.h>
|
||
|
.Ft int
|
||
|
.Fn scsireq_buff_decode "u_char *ptr, size_t len, char *fmt, ..."
|
||
|
.Ft struct scsireq *
|
||
|
.Fn scsireq_build "struct scsireq *s, u_long len, caddr_t buf, u_long flags, char *fmt, ..."
|
||
|
.Ft int
|
||
|
.Fn scsireq_decode "struct scsireq *, char *fmt, ..."
|
||
|
.Ft int
|
||
|
.Fn scsireq_encode "struct scsireq *, char *fmt, ..."
|
||
|
.Ft int
|
||
|
.Fn scsireq_enter "int fid, struct scsireq *s"
|
||
|
.Ft struct scsireq *
|
||
|
.Fn scsireq_new void
|
||
|
.Ft struct scsireq *
|
||
|
.Fn scsireq_reset "struct scsireq *"
|
||
|
.Ft int
|
||
|
.Fn SCSIREQ_ERROR "struct scsireq *"
|
||
|
.Ft int
|
||
|
.Fn scsi_open "const char *path, int flags"
|
||
|
.Ft void
|
||
|
.Fn scsi_debug "FILE *f, int ret, struct scsireq *s"
|
||
|
.Ft FILE *
|
||
|
.Fn scsi_debug_output "char *s"
|
||
|
.Sh DESCRIPTION
|
||
|
These functions
|
||
|
use the SCIOCCOMMAND
|
||
|
.Xr ioctl 2
|
||
|
of the FreeBSD SCSI subsystem
|
||
|
to provide user level access to SCSI commands.
|
||
|
The programmer must know the SCSI CDB (Command Descriptor
|
||
|
Block) to perform the desired command. These functions assist in
|
||
|
building up the CDB, submitting it to the SCSI subsystem, and decoding
|
||
|
the result.
|
||
|
.Pp
|
||
|
To provide for security,
|
||
|
not all devices accept the SCIOCCOMAND ioctl. For tape
|
||
|
drives, only the control device accepts it. For disk drives, only
|
||
|
the RAWPART partition (partition d in 2.0) accepts it. Any device
|
||
|
that comes on line as an UNKNOWN device will accept the ioctl, and
|
||
|
the "super scsi"
|
||
|
.Xr ssc 4
|
||
|
device also accepts it.
|
||
|
.Pp
|
||
|
Most of the SCSI library functions build up and manipulate the
|
||
|
.Ar scsireq
|
||
|
structure found in the include file
|
||
|
.Aq Pa sys/scsiio.h :
|
||
|
.Bd -literal -offset indent
|
||
|
#define SENSEBUFLEN 48
|
||
|
.Pp
|
||
|
typedef struct scsireq {
|
||
|
u_long flags; /* info about the request status and type */
|
||
|
u_long timeout;
|
||
|
u_char cmd[16]; /* 12 is actually the max */
|
||
|
u_char cmdlen;
|
||
|
caddr_t databuf; /* address in user space of buffer */
|
||
|
u_long datalen; /* size of user buffer (request) */
|
||
|
u_long datalen_used; /* size of user buffer (used)*/
|
||
|
u_char sense[SENSEBUFLEN]; /* returned sense will be in here */
|
||
|
u_char senselen; /* sensedata request size (MAX of SENSEBUFLEN)*/
|
||
|
u_char senselen_used; /* return value only */
|
||
|
u_char status; /* what the scsi status was from the adapter */
|
||
|
u_char retsts; /* the return status for the command */
|
||
|
int error; /* error bits */
|
||
|
} scsireq_t;
|
||
|
.Ed
|
||
|
.Pp
|
||
|
The function
|
||
|
.Fn scsireq_new
|
||
|
allocates a new
|
||
|
.Ar scsireq
|
||
|
structure and returns a pointer to it or NULL if it can't allocate
|
||
|
memory.
|
||
|
.Pp
|
||
|
.Fn scsireq_reset
|
||
|
resets the structure to reasonable values and returns the same pointer passed
|
||
|
in to it.
|
||
|
It gracefully handles the NULL pointer passed in to it so that you can
|
||
|
unconditionally use
|
||
|
.Ar scsireq_new .
|
||
|
.Pp
|
||
|
.Fn scsireq_build
|
||
|
builds up a scsireq structure based on the information provided in
|
||
|
the variable argument list.
|
||
|
It gracefully handles a NULL pointer passed to it.
|
||
|
.Pp
|
||
|
.Fr len
|
||
|
is the length of the data phase; the data transfer direction is
|
||
|
determined by the
|
||
|
.Ar flags
|
||
|
argument.
|
||
|
.Pp
|
||
|
.Fr buf
|
||
|
is the data buffer used during the SCSI data phase. If it is NULL it
|
||
|
is allocated via malloc and
|
||
|
.Ar scsireq->databuf
|
||
|
is set to point to the newly allocated memory.
|
||
|
.Pp
|
||
|
.Fr flags
|
||
|
are the flags defined in
|
||
|
.Aq Pa sys/scsiio.h :
|
||
|
.Bd -literal -offset indent
|
||
|
/* bit defintions for flags */
|
||
|
#define SCCMD_READ 0x00000001
|
||
|
#define SCCMD_WRITE 0x00000002
|
||
|
#define SCCMD_IOV 0x00000004
|
||
|
#define SCCMD_ESCAPE 0x00000010
|
||
|
#define SCCMD_TARGET 0x00000020
|
||
|
.Ed
|
||
|
Only two of these flags are supported in this release of the software:
|
||
|
.Fr SCCMD_READ
|
||
|
indicates a data in phase (a transfer into the user buffer at
|
||
|
.Ar scsireg->databuf
|
||
|
), and
|
||
|
.Fr SCCMD_WRITE
|
||
|
indicates a data out phase (a transfer out of the user buffer).
|
||
|
.Pp
|
||
|
.Fr fmt
|
||
|
is an ASCII CDB format specifier used to build up the SCSI CDB.
|
||
|
This text string is made up of a list of field specifiers. Field
|
||
|
specifiers specify the value for each CDB field (including indicating
|
||
|
that the value be taken from the next argument in the
|
||
|
variable argument list), the width
|
||
|
of the field in bits or bytes, and an optional name.
|
||
|
The optional name is the final part of a field specifier and
|
||
|
is in curly braces. A valid example is:
|
||
|
.Bd -literal -offset indent
|
||
|
.Fr "v:b1 {PS} 0:b1 {Reserved} v:b6 {Page Code}"
|
||
|
.Ed
|
||
|
This field specifier has two one bit fields and one six bit field.
|
||
|
The second one bit field is the constant value 0 and the first
|
||
|
one bit field and the six bit field are taken from the variable
|
||
|
argument list.
|
||
|
Multi byte fields are swapped into the SCSI byte order in the
|
||
|
CDB and
|
||
|
white space is ignored.
|
||
|
.Pp
|
||
|
When the field is a hex value or the letter v, (e.g.,
|
||
|
.Fr "1A"
|
||
|
or
|
||
|
.Fr "v" )
|
||
|
a single byte value
|
||
|
is copied to the next unused byte of the CDB.
|
||
|
When the letter
|
||
|
.Fr v
|
||
|
is used the next integer argument is taken from the variable argument list
|
||
|
and that value used.
|
||
|
.Pp
|
||
|
A constant hex value followed by a field width specifier or the letter
|
||
|
.Fr v
|
||
|
followed by a field width specifier (e.g.,
|
||
|
.Fr 3:4 ,
|
||
|
.Fr 3:b4 ,
|
||
|
.Fr 3:i3 ,
|
||
|
.FR v:i3 )
|
||
|
is used to specify a field of a given bit or byte width.
|
||
|
Either the constant value or (for the V specifier) the next integer value from
|
||
|
the variable argument list is copied to the next unused
|
||
|
bits or bytes of the CDB. A decimal number or the letter
|
||
|
.Fr b
|
||
|
followed by a decimal
|
||
|
number as the field width indicates a bit field of that width.
|
||
|
These bit fields are packed as tightly as possible beginning with the
|
||
|
high bit (so that it reads the same as the SCSI spec), and a new byte of
|
||
|
the CDB is
|
||
|
started whenever the byte fills completely or when an
|
||
|
.Fr i
|
||
|
field is encountered.
|
||
|
.Pp
|
||
|
A field width specifier consisting of the letter
|
||
|
.Fr i
|
||
|
followed by either
|
||
|
1, 2, 3 or 4 indicates a 1, 2, 3 or 4 byte integral value that must
|
||
|
be swapped into SCSI byte order (MSB first).
|
||
|
.Pp
|
||
|
For the v field specifier
|
||
|
the next integer argument is taken from the variable argument
|
||
|
list and that value is used swapped into SCSI byte order.
|
||
|
.Pp
|
||
|
.Fn scsireq_decode
|
||
|
is used to decode information from the data in phase of the SCSI
|
||
|
transfer.
|
||
|
The decoding is similar to
|
||
|
the command specifier processing of
|
||
|
.Fn scsireq_build,
|
||
|
except that the data is extracted from the data pointed to by
|
||
|
.Fr scsireq->databuf.
|
||
|
The stdarg list must be pointers to integers instead of integer
|
||
|
values.
|
||
|
.Pp
|
||
|
In addition, a seek field type and a suppression field modifier are added.
|
||
|
The
|
||
|
.Fr *
|
||
|
suppression modifier to a field (e.g.,
|
||
|
.Fr *i3
|
||
|
or
|
||
|
.Fr *b4 )
|
||
|
suppresses the assignment from that field and can be used to skip
|
||
|
over bytes or bits in the data, without copying them to a dummy variable
|
||
|
in the arg list.
|
||
|
.Pp
|
||
|
A seek field type
|
||
|
.Fr s
|
||
|
is provided. This ``seeks'' to an absolute position in the data (
|
||
|
.Fr s3 )
|
||
|
or a relative position (
|
||
|
.Fr s+3 )
|
||
|
in the data, based on whether or not the seek value has a '+' sign.
|
||
|
The value can also be
|
||
|
.Fr v
|
||
|
and the next integer value will be taken from the arg list
|
||
|
and used as the seek value.
|
||
|
.Pp
|
||
|
.Fn scsireq_buff_decode
|
||
|
decodes an arbitrary data buffer identically to the method
|
||
|
used by the
|
||
|
.Fn scsireq_decode
|
||
|
function.
|
||
|
.Pp
|
||
|
.Fn scsireq_encode
|
||
|
encodes the data phase section of the structure. The encoding is
|
||
|
handled identically as the encoding of the CDB structure by
|
||
|
.Fn scsireq_build
|
||
|
.Pp
|
||
|
.Fn scsireq_enter
|
||
|
submits the built up structure for processing using
|
||
|
the SCIOCCOMMAND ioctl.
|
||
|
.Pp
|
||
|
.Fn SCSIREQ_ERROR
|
||
|
is a macro that determines if the result of the SCIOCCOMMAND ioctl may
|
||
|
have been
|
||
|
in error by examining the host adapter return code, whether sense was sent
|
||
|
or not, and so on.
|
||
|
.Pp
|
||
|
.Fn scsi_open
|
||
|
checks environment variables and initializes the library for
|
||
|
consistent library use and then calls the regular open system call.
|
||
|
.Pp
|
||
|
.Fn scsi_debug and
|
||
|
.Fn scsi_debug_output
|
||
|
are used for debugging.
|
||
|
.Pp
|
||
|
.Fn scsi_debug
|
||
|
prints the results of a scsireq_enter function to the specified stdio
|
||
|
stream.
|
||
|
.Pp
|
||
|
.Fn scsi_debug_output
|
||
|
requests that the results of all transactions be debugged to the
|
||
|
supplied file using
|
||
|
.Fn scsi_debug .
|
||
|
.Sh RETURN VALUES
|
||
|
The function
|
||
|
.Fn scsireq_new
|
||
|
returns a pointer to storage allocated from malloc, and therefore
|
||
|
potentially a NULL.
|
||
|
.Pp
|
||
|
The functions
|
||
|
.Fn scsireq_build
|
||
|
and
|
||
|
.Fn scsireq_reset
|
||
|
return the same pointer as the one passed in.
|
||
|
.Pp
|
||
|
The functions
|
||
|
.Fn scsireq_buff_decode ,
|
||
|
.Fn scsireq_decode
|
||
|
and
|
||
|
.Fn scsireq_encode
|
||
|
return the number of fields processed.
|
||
|
.Pp
|
||
|
The function
|
||
|
.Fn scsireq_enter
|
||
|
returns the result of the ioctl call.
|
||
|
.Sh SEE ALSO
|
||
|
.Xr scsi 8 ,
|
||
|
.Xr scsi 4
|
||
|
.Sh BUGS
|
||
|
This only works completely for the 1542C. The host adapter code
|
||
|
that sets up the residual amount of data transfer has to be added
|
||
|
to each individual adapter. This library is usable on the other
|
||
|
host adapters, however, the SCSI driver pretends that the proper
|
||
|
amount of data is always transferred. If you have an Adaptec 174x
|
||
|
and can hack contact dufault@hda.com and you can have the code to
|
||
|
calculate residual data for the 174x series to integrate and test.
|
||
|
.Sh HISTORY
|
||
|
Many systems have comparable interfaces to permit a user to construct a
|
||
|
SCSI command in user space.
|
||
|
.Pp
|
||
|
The data structure is almost identical to the SGI /dev/scsi data
|
||
|
structure. If anyone knows the name of the authors it should
|
||
|
go here; Peter Dufault first read about it in a 1989 Sun Expert magazine.
|
||
|
.Pp
|
||
|
Peter Dufault implemented a clone of SGI's interface in 386bsd that
|
||
|
led to this library and the related kernel ioctl.
|
||
|
If anyone needs that for compatability contact dufault@hda.com.
|