aboutsummaryrefslogtreecommitdiff
path: root/lib/libcam
diff options
context:
space:
mode:
authorKenneth D. Merry <ken@FreeBSD.org>1998-10-14 06:20:36 +0000
committerKenneth D. Merry <ken@FreeBSD.org>1998-10-14 06:20:36 +0000
commit01a4eb824cfe9aa183037de0ceea929db505f43c (patch)
tree29234c5a5c89b01137f2196fe55efa6fc54df4d2 /lib/libcam
parent2a26e9ea83050b053068c5f4b1af9a40bd36fd1b (diff)
downloadsrc-01a4eb824cfe9aa183037de0ceea929db505f43c.tar.gz
src-01a4eb824cfe9aa183037de0ceea929db505f43c.zip
Add man pages for many of the functions in the CAM library. This covers
most of the open/close routines, and the buffer/cdb parsing routines derived from the old scsi(3) library. The cam_cdbparse(3) man page borrows from the old scsi(3) man page, so the copyright and history section reflect that. The many scsi_* functions and other functions that are pulled in from the kernel aren't documented yet, but will be eventually.
Notes
Notes: svn path=/head/; revision=40337
Diffstat (limited to 'lib/libcam')
-rw-r--r--lib/libcam/Makefile58
-rw-r--r--lib/libcam/cam.3416
-rw-r--r--lib/libcam/cam_cdbparse.3542
3 files changed, 983 insertions, 33 deletions
diff --git a/lib/libcam/Makefile b/lib/libcam/Makefile
index 0bccbdce7fb6..5b395e49bc32 100644
--- a/lib/libcam/Makefile
+++ b/lib/libcam/Makefile
@@ -2,39 +2,31 @@
LIB= cam
SRCS= camlib.c scsi_cmdparse.c scsi_all.c scsi_sa.c cam.c
-# MAN3= cam.3
-
-# XXX KDM Need to write the man pages.
-# MLINKS+= cam.3 cam_open_device.3 \
-# cam.3 cam_close_device.3 \
-# cam.3 cam_getccb.3 \
-# cam.3 cam_freeccb.3 \
-# cam.3 cam_send_ccb.3 \
-# cam.3 cam_device_dup.3 \
-# cam.3 cam_device_copy.3 \
-# cam.3 scsi_read_write.3 \
-# cam.3 scsi_start_stop.3 \
-# cam.3 scsi_sense_desc.3 \
-# cam.3 scsi_op_desc.3 \
-# cam.3 scsi_cdb_string.3 \
-# cam.3 scsi_print_inquriy.3 \
-# cam.3 scsi_calc_syncsrate.3 \ # XXX
-# cam.3 scsi_test_unit_ready.3 \
-# cam.3 scsi_inquiry.3 \
-# cam.3 scsi_read_capacity.3 \
-# cam.3 scsi_prevent.3 \
-# cam.3 scsi_synchronize_cache.3 \
-# cam.3 scsi_sense_string.3 \
-# cam.3 scsi_sense_print.3 \
-# cam.3 scsi_inqurity_match.3 \ # XXX
-# cam.3 scsi_extract_sense.3 \
-# cam.3 scsi_ulto2b.3 \
-# cam.3 scsi_ulto3b.3 \
-# cam.3 scsi_ulto4b.3 \
-# cam.3 scsi_2btoul.3 \
-# cam.3 scsi_3btoul.3 \
-# cam.3 scsi_3btol.3 \
-# cam.3 scsi_4btoul.3
+MAN3= cam.3 cam_cdbparse.3
+
+
+MLINKS+=cam.3 cam_open_device.3 \
+ cam.3 cam_open_spec_device.3 \
+ cam.3 cam_open_btl.3 \
+ cam.3 cam_open_pass.3 \
+ cam.3 cam_close_device.3 \
+ cam.3 cam_close_spec_device.3 \
+ cam.3 cam_getccb.3 \
+ cam.3 cam_send_ccb.3 \
+ cam.3 cam_freeccb.3 \
+ cam.3 cam_path_string.3 \
+ cam.3 cam_device_dup.3 \
+ cam.3 cam_device_copy.3 \
+ cam.3 cam_get_device.3 \
+ cam_cdbparse.3 csio_build.3 \
+ cam_cdbparse.3 csio_build_visit.3 \
+ cam_cdbparse.3 csio_decode.3 \
+ cam_cdbparse.3 csio_decode_visit.3 \
+ cam_cdbparse.3 buff_decode.3 \
+ cam_cdbparse.3 buff_decode_visit.3 \
+ cam_cdbparse.3 csio_encode.3 \
+ cam_cdbparse.3 csio_encode_visit.3 \
+ cam_cdbparse.3 buff_encode_visit.3
beforeinstall:
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 ${.CURDIR}/camlib.h \
diff --git a/lib/libcam/cam.3 b/lib/libcam/cam.3
new file mode 100644
index 000000000000..1f3e0e417856
--- /dev/null
+++ b/lib/libcam/cam.3
@@ -0,0 +1,416 @@
+.\"
+.\" Copyright (c) 1998 Kenneth D. Merry.
+.\" 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. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR 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.
+.\"
+.\" $Id$
+.\"
+.Dd October 10, 1998
+.Os FreeBSD 3.0
+.Dt CAM 3
+.Sh NAME
+.Nm cam_open_device ,
+.Nm cam_open_spec_device ,
+.Nm cam_open_btl ,
+.Nm cam_open_pass ,
+.Nm cam_close_device ,
+.Nm cam_close_spec_device ,
+.Nm cam_getccb ,
+.Nm cam_send_ccb ,
+.Nm cam_freeccb ,
+.Nm cam_path_string ,
+.Nm cam_device_dup ,
+.Nm cam_device_copy ,
+.Nm cam_get_device
+.Nd CAM user library
+.Sh SYNOPSIS
+.Fd #include <camlib.h>
+.Ft struct cam_device *
+.Fo cam_open_device
+.Fa "const char *path"
+.Fa "int flags"
+.Fc
+.Ft struct cam_device *
+.Fo cam_open_spec_device
+.Fa "const char *dev_name"
+.Fa "int unit"
+.Fa "int flags"
+.Fa "struct cam_device *device"
+.Fc
+.Ft struct cam_device *
+.Fo cam_open_btl
+.Fa "path_id_t path_id"
+.Fa "target_id_t target_id"
+.Fa "lun_id_t target_lun"
+.Fa "int flags"
+.Fa "struct cam_device *device"
+.Fc
+.Ft struct cam_device *
+.Fo cam_open_pass
+.Fa "const char *path"
+.Fa "int flags"
+.Fa "struct cam_device *device"
+.Fc
+.Ft void
+.Fo cam_close_device
+.Fa "struct cam_device *dev"
+.Fc
+.Ft void
+.Fo cam_close_spec_device
+.Fa "struct cam_device *dev"
+.Fc
+.Ft union ccb *
+.Fo cam_getccb
+.Fa "struct cam_device *dev"
+.Fc
+.Ft int
+.Fo cam_send_ccb
+.Fa "struct cam_device *device"
+.Fa "union ccb *ccb"
+.Fc
+.Ft void
+.Fo cam_freeccb
+.Fa "union ccb *ccb"
+.Fc
+.Ft char *
+.Fo cam_path_string
+.Fa "struct cam_device *dev"
+.Fa "char *str"
+.Fa "int len"
+.Fc
+.Ft struct cam_device *
+.Fo cam_device_dup
+.Fa "struct cam_device *device"
+.Fc
+.Ft void
+.Fo cam_device_copy
+.Fa "struct cam_device *src"
+.Fa "struct cam_device *dst"
+.Fc
+.Ft int
+.Fo cam_get_device
+.Fa "const char *path"
+.Fa "char *dev_name"
+.Fa "int devnamelen"
+.Fa "int *unit"
+.Fc
+.Sh DESCRIPTION
+The CAM library consists of a number of functions designed to aid in
+programming with the CAM subsystem. This man page covers the basic set of
+library functions. More functions are documented in the man pages listed
+below.
+.Pp
+Many of the CAM library functions use the
+.Va cam_device
+structure:
+.Bd -literal
+struct cam_device {
+ char device_path[MAXPATHLEN+1];/*
+ * Pathname of the
+ * device given by the
+ * user. This may be
+ * null if the user
+ * states the device
+ * name and unit number
+ * separately.
+ */
+ char given_dev_name[DEV_IDLEN+1];/*
+ * Device name given by
+ * the user.
+ */
+ u_int32_t given_unit_number; /*
+ * Unit number given by
+ * the user.
+ */
+ char device_name[DEV_IDLEN+1];/*
+ * Name of the device,
+ * e.g. 'pass'
+ */
+ u_int32_t dev_unit_num; /* Unit number of the passthrough
+ * device associated with this
+ * particular device.
+ */
+
+ char sim_name[SIM_IDLEN+1];/*
+ * Controller name, e.g.'ahc'
+ */
+ u_int32_t sim_unit_number; /* Controller unit number */
+ u_int32_t bus_id; /* Controller bus number */
+ lun_id_t target_lun; /* Logical Unit Number */
+ target_id_t target_id; /* Target ID */
+ path_id_t path_id; /* System SCSI bus number */
+ u_int16_t pd_type; /* type of peripheral device */
+ struct scsi_inquiry_data inq_data; /* SCSI Inquiry data */
+ u_int8_t serial_num[252]; /* device serial number */
+ u_int8_t serial_num_len; /* length of the serial number */
+ u_int8_t sync_period; /* Negotiated sync period */
+ u_int8_t sync_offset; /* Negotiated sync offset */
+ u_int8_t bus_width; /* Negotiated bus width */
+ int fd; /* file descriptor for device */
+};
+.Ed
+.Pp
+.Fn cam_open_device
+takes as arguments a string describing the device it is to open, and
+.Ar flags
+suitable for passing to
+.Xr open 2 .
+The "path" passed in may actually be most any type of string that contains
+a device name and unit number to be opened. The string will be parsed by
+.Fn cam_get_device
+into a device name and unit number. Once the device name and unit number
+are determined, a lookup is performed to determine the passthrough device
+that corresponds to the given device.
+.Fn cam_open_device
+is rather simple to use, but it isn't really suitable for general use
+because its behavior isn't necessarily deterministic. Programmers writing
+new applications should make the extra effort to use one of the other open
+routines documented below.
+.Pp
+.Fn cam_open_spec_device
+opens the
+.Xr pass 4
+device that corresponds to the device name and unit number passed in. The
+.Ar flags
+should be flags suitable for passing to
+.Xr open 2 .
+The
+.Ar device
+argument is optional. The user may supply pre-allocated space for the
+.Va cam_device
+structure. If the
+.Ar device
+argument is
+.Va NULL ,
+.Fn cam_open_spec_device
+will allocate space for the
+.Va cam_device
+structure using
+.Xr malloc 3 .
+.Pp
+.Fn cam_open_btl
+is similar to
+.Fn cam_open_spec_device ,
+except that it takes a
+.Tn SCSI
+bus, target and logical unit instead of a device name and unit number as
+arguments. The
+.Va path_id
+argument is the CAM equivalent of a
+.Tn SCSI
+bus number. It represents the logical bus number in the system. The
+.Ar flags
+should be flags suitable for passing to
+.Xr open 2 .
+As with
+.Fn cam_open_spec_device ,
+the
+.Fa device
+argument is optional.
+.Pp
+.Fn cam_open_pass
+takes as an argument the
+.Fa path
+of a
+.Xr pass 4
+device to open. No translation or lookup is performed, so the path passed
+in must be that of a CAM
+.Xr pass 4
+device. The
+.Fa flags
+should be flags suitable for passing to
+.Xr open 2 .
+The
+.Fa device
+argument, as with
+.Fn cam_open_spec_device
+and
+.Fn cam_open_btl ,
+should be NULL if the user wants the CAM library to allocate space for the
+.Va cam_device
+structure.
+.Fn cam_close_device
+frees the
+.Va cam_device
+structure allocated by one of the above open() calls, and closes the file
+descriptor to the passthrough device. This routine should not be called if
+the user allocated space for the
+.Va cam_device
+structure. Instead, the user should call
+.Fn cam_close_spec_device .
+.Pp
+.Fn cam_close_spec_device
+merely closes the file descriptor opened in one of the open() routines
+described above. This function should be called when the
+.Va cam_device
+structure was allocated by the caller, rather than the CAM library.
+.Pp
+.Fn cam_getccb
+allocates a CCB (see
+.Xr ccb 4 )
+using
+.Xr malloc 3
+and sets fields in the CCB header using values from the
+.Va cam_device
+structure.
+.Pp
+.Fn cam_send_ccb
+sends the given
+.Va ccb
+to the
+.Fa device
+described in the
+.Va cam_device
+structure.
+.Pp
+.Fn cam_freeccb
+frees CCBs allocated by
+.Fn cam_getccb .
+.Pp
+.Fn cam_path_string
+takes as arguments a
+.Va cam_device
+structure, and a string with length
+.Fa len .
+It creates a colon-terminated printing prefix string similar to the ones
+used by the kernel. e.g.: "(cd0:ahc1:0:4:0): ".
+.Fn cam_path_string
+will place at most
+.Fa len Ns \-1
+characters into
+.Ar str .
+The
+.Ar len Ns 'th
+character will be the terminating
+.Ql \e0 .
+.Pp
+.Fn cam_device_dup
+operates in a fashion similar to
+.Xr strdup 3 .
+It allocates space for a
+.Va cam_device
+structure and copies the contents of the passed-in
+.Fa device
+structure to the newly allocated structure.
+.Pp
+.Fn cam_device_copy
+copies the
+.Fa src
+structure to
+.Fa dst .
+.Pp
+.Fn cam_get_device
+takes a
+.Fa path
+argument containing a string with a device name followed by a unit number.
+It then breaks the string down into a device name and unit number, and
+passes them back in
+.Fa dev_name
+and
+.Fa unit ,
+respectively.
+.Fn cam_get_device
+can handle strings of the following forms, at least:
+.Pp
+.Bl -tag -width 1234 -compact
+.It /dev/foo0a
+.It /dev/rfoo0a
+.It /dev/rfoo1s2c
+.It foo0
+.It foo0a
+.It rfoo0
+.It rfoo0a
+.It nrfoo0
+.El
+.Pp
+.Fn cam_get_device
+is provided as a convenience function for applications that need to provide
+functionality similar to
+.Fn cam_open_device .
+Programmers are encouraged to use more deterministic methods of obtaining
+device names and unit numbers if possible.
+.Sh RETURN VALUES
+.Fn cam_open_device ,
+.Fn cam_open_spec_device ,
+.Fn cam_open_btl ,
+and
+.Fn cam_open_pass
+return a pointer to a
+.Va cam_device
+structure, or NULL if there was an error.
+.Pp
+.Fn cam_getccb
+returns an allocated and partially initialized CCB, or NULL if allocation
+of the CCB failed.
+.Pp
+.Fn cam_send_ccb
+returns a value of -1 if an error occured, and
+.Va errno
+is set to indicate the error.
+.Pp
+.Fn cam_path_string
+returns a filled printing prefix string as a convenience. This is the same
+.Fa str
+that is passed into
+.Fn cam_path_string .
+.Pp
+.Fn cam_device_dup
+returns a copy of the
+.Va device
+passed in, or NULL if an error occurred.
+.Pp
+.Fn cam_get_device
+returns 0 for success, and -1 to indicate failure.
+.Pp
+If an error is returned from one of the base CAM library functions
+described here, the reason for the error is generally printed in the global
+string
+.Va cam_errbuf
+which is
+.Dv CAM_ERRBUF_SIZE
+characters long.
+.Sh SEE ALSO
+.Xr cam_cdbparse 3 ,
+.Xr pass 4 ,
+.Xr camcontrol 8 ,
+.Sh HISTORY
+The CAM library first appeared in
+.Fx 3.0 .
+.Sh AUTHORS
+.An Kenneth Merry Aq ken@FreeBSD.ORG
+.Sh BUGS
+.Fn cam_open_device
+doesn't check to see if the
+.Fa path
+passed in is a symlink to something. It also doesn't check to see if the
+.Fa path
+passed in is an actual
+.Xr pass 4
+device. The former would be rather easy to implement, but the latter would
+require a definitive way to identify a device node as a
+.Xr pass 4
+device.
+.Pp
+Some of the functions are possibly mis-named or poorly named.
diff --git a/lib/libcam/cam_cdbparse.3 b/lib/libcam/cam_cdbparse.3
new file mode 100644
index 000000000000..4887aa3923fd
--- /dev/null
+++ b/lib/libcam/cam_cdbparse.3
@@ -0,0 +1,542 @@
+.\"
+.\" Copyright (c) 1998 Kenneth D. Merry.
+.\" 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. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR 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.
+.\"
+.\" $Id$
+.\"
+.\" This man page borrows heavily from the old scsi(3) man page, which had
+.\" the following copyright:
+.\"
+.\" 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 Associates 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 October 13, 1998
+.Os FreeBSD 3.0
+.Dt CAM_CDBPARSE 3
+.Sh NAME
+.Nm csio_build ,
+.Nm csio_build_visit ,
+.Nm csio_decode ,
+.Nm csio_decode_visit ,
+.Nm buff_decode ,
+.Nm buff_decode_visit ,
+.Nm csio_encode ,
+.Nm csio_encode_visit ,
+.Nm buff_encode_visit
+.Nd CAM user library SCSI buffer parsing routines
+.Sh SYNOPSIS
+.Fd #include <camlib.h>
+.Ft int
+.Fo csio_build
+.Fa "struct ccb_scsiio *csio"
+.Fa "u_int8_t *data_ptr"
+.Fa "u_int32_t dxfer_len"
+.Fa "u_int32_t flags"
+.Fa "int retry_count"
+.Fa "int timeout"
+.Fa "char *cmd_spec"
+.Fa "..."
+.Fc
+.Ft int
+.Fo csio_build_visit
+.Fa "struct ccb_scsiio *csio"
+.Fa "u_int8_t *data_ptr"
+.Fa "u_int32_t dxfer_len"
+.Fa "u_int32_t flags"
+.Fa "int retry_count"
+.Fa "int timeout"
+.Fa "char *cmd_spec"
+.Fa "int (*arg_get)(void *hook, char *field_name)"
+.Fa "void *gethook"
+.Fc
+.Ft int
+.Fo csio_decode
+.Fa "struct ccb_scsiio *csio"
+.Fa "char *fmt"
+.Fa "..."
+.Fc
+.Ft int
+.Fo csio_decode_visit
+.Fa "struct ccb_scsiio *csio"
+.Fa "char *fmt"
+.Fa "void (*arg_put)(void *hook"
+.Fa "int letter"
+.Fa "void *val"
+.Fa "int count"
+.Fa "char *name)"
+.Fa "void *puthook"
+.Fc
+.Ft int
+.Fo buff_decode
+.Fa "u_int8_t *buff"
+.Fa "size_t len"
+.Fa "char *fmt"
+.Fa "..."
+.Fc
+.Ft int
+.Fo buff_decode_visit
+.Fa "u_int8_t *buff"
+.Fa "size_t len"
+.Fa "char *fmt"
+.Fa "void (*arg_put)(void *, int, void *, int, char *)"
+.Fa "void *puthook"
+.Fc
+.Ft int
+.Fo csio_encode
+.Fa "struct ccb_scsiio *csio"
+.Fa "char *fmt"
+.Fa "..."
+.Fc
+.Ft int
+.Fo csio_encode_visit
+.Fa "struct ccb_scsiio *csio"
+.Fa "char *fmt"
+.Fa "int (*arg_get)(void *hook, char *field_name)"
+.Fa "void *gethook"
+.Fc
+.Ft int
+.Fo buff_encode_visit
+.Fa "u_int8_t *buff"
+.Fa "size_t len"
+.Fa "char *fmt"
+.Fa "int (*arg_get)(void *hook, char *field_name)"
+.Fa "void *gethook"
+.Fc
+.Sh DESCRIPTION
+The CAM buffer/CDB encoding and decoding routines provide a relatively easy
+migration path for userland
+.Tn SCSI
+applications written with the similarly-named
+.Va scsireq_ Ns *
+functions from the old FreeBSD
+.Tn SCSI
+layer.
+.Pp
+These functions may be used in new applications, but users may find it
+easier to use the various SCSI CCB building functions included with the
+.Xr cam 3
+library. (e.g.
+.Fn cam_fill_csio ,
+.Fn scsi_start_stop ,
+and
+.Fn scsi_read_write )
+.Pp
+.Fn csio_build
+builds up a
+.Va ccb_scsiio
+structure based on the information provided in
+the variable argument list.
+It gracefully handles a NULL
+.Fa data_ptr
+argument passed to it.
+.Pp
+.Fa dxfer_len
+is the length of the data phase; the data transfer direction is
+determined by the
+.Fa flags
+argument.
+.Pp
+.Fa data_ptr
+is the data buffer used during the
+.Tn SCSI
+data phase. If no data is to be
+transferred for the
+.Tn SCSI
+command in question, this should be set to NULL. If there is data to
+transfer for the command, this buffer must be at least
+.Fa dxfer_len
+long.
+.Pp
+.Fa flags
+are the flags defined in
+.Aq Pa cam/cam_ccb.h :
+.Bd -literal
+/* Common CCB header */
+/* CAM CCB flags */
+typedef enum {
+ CAM_CDB_POINTER = 0x00000001,/* The CDB field is a pointer */
+ CAM_QUEUE_ENABLE = 0x00000002,/* SIM queue actions are enabled */
+ CAM_CDB_LINKED = 0x00000004,/* CCB contains a linked CDB */
+ CAM_SCATTER_VALID = 0x00000010,/* Scatter/gather list is valid */
+ CAM_DIS_AUTOSENSE = 0x00000020,/* Disable autosense feature */
+ CAM_DIR_RESV = 0x00000000,/* Data direction (00:reserved) */
+ CAM_DIR_IN = 0x00000040,/* Data direction (01:DATA IN) */
+ CAM_DIR_OUT = 0x00000080,/* Data direction (10:DATA OUT) */
+ CAM_DIR_NONE = 0x000000C0,/* Data direction (11:no data) */
+ CAM_DIR_MASK = 0x000000C0,/* Data direction Mask */
+ CAM_SOFT_RST_OP = 0x00000100,/* Use Soft reset alternative */
+ CAM_ENG_SYNC = 0x00000200,/* Flush resid bytes on complete */
+ CAM_DEV_QFRZDIS = 0x00000400,/* Disable DEV Q freezing */
+ CAM_DEV_QFREEZE = 0x00000800,/* Freeze DEV Q on execution */
+ CAM_HIGH_POWER = 0x00001000,/* Command takes a lot of power */
+ CAM_SENSE_PTR = 0x00002000,/* Sense data is a pointer */
+ CAM_SENSE_PHYS = 0x00004000,/* Sense pointer is physical addr*/
+ CAM_TAG_ACTION_VALID = 0x00008000,/* Use the tag action in this ccb*/
+ CAM_PASS_ERR_RECOVER = 0x00010000,/* Pass driver does err. recovery*/
+ CAM_DIS_DISCONNECT = 0x00020000,/* Disable disconnect */
+ CAM_SG_LIST_PHYS = 0x00040000,/* SG list has physical addrs. */
+ CAM_MSG_BUF_PHYS = 0x00080000,/* Message buffer ptr is physical*/
+ CAM_SNS_BUF_PHYS = 0x00100000,/* Autosense data ptr is physical*/
+ CAM_DATA_PHYS = 0x00200000,/* SG/Buffer data ptrs are phys. */
+ CAM_CDB_PHYS = 0x00400000,/* CDB poiner is physical */
+ CAM_ENG_SGLIST = 0x00800000,/* SG list is for the HBA engine */
+
+/* Phase cognizant mode flags */
+ CAM_DIS_AUTOSRP = 0x01000000,/* Diable autosave/restore ptrs */
+ CAM_DIS_AUTODISC = 0x02000000,/* Disable auto disconnect */
+ CAM_TGT_CCB_AVAIL = 0x04000000,/* Target CCB available */
+ CAM_TGT_PHASE_MODE = 0x08000000,/* The SIM runs in phase mode */
+ CAM_MSGB_VALID = 0x20000000,/* Message buffer valid */
+ CAM_STATUS_VALID = 0x40000000,/* Status buffer valid */
+ CAM_DATAB_VALID = 0x80000000,/* Data buffer valid */
+
+/* Host target Mode flags */
+ CAM_TERM_IO = 0x20000000,/* Terminate I/O Message sup. */
+ CAM_DISCONNECT = 0x40000000,/* Disconnects are mandatory */
+ CAM_SEND_STATUS = 0x80000000,/* Send status after data phase */
+} ccb_flags;
+.Ed
+.Pp
+Multiple flags should be ORed together. Any of the CCB flags may be used,
+although it is worth noting several important ones here:
+.Pp
+.Bl -tag -width CAM_PASS_ERR_RECOVER
+.It Dv CAM_DIR_IN
+This indicates that the operation in question is a read operation. i.e.,
+data is being read from the
+.Tn SCSI
+device to the user-supplied buffer.
+.It Dv CAM_DIR_OUT
+This indicates that the operation is a write operation. i.e. data is being
+written from the user-supplied buffer to the device.
+.It Dv CAM_DIR_NONE
+This indicates that there is no data to be transferred for this command.
+.It Dv CAM_DEV_QFRZDIS
+This flag disables device queue freezing as an error recovery mechanism.
+.It Dv CAM_PASS_ERR_RECOVER
+This flag tells the
+.Xr pass 4
+driver to enable error recovery. The default is to not perform error
+recovery, which means that the retry count won't be honored without this
+flag, among other things.
+.It Dv CAM_DATA_PHYS
+This indicates that the address contained in
+.Fa data_ptr
+is a physical address, not a virtual address.
+.El
+.Pp
+The
+.Fa retry_count
+tells the kernel how many times to retry the command in question. The
+retry count is ignored unless the
+.Xr pass 4
+driver is told to enable error recovery via the
+.Dv CAM_PASS_ERR_RECOVER
+flag.
+.Pp
+The
+.Fa timeout
+tells the kernel how long to wait for the given command to complete. If
+the timeout expires and the command hasn't completed, the CCB will be
+returned from the kernel with an appropriate error status.
+.Pp
+.Fa cmd_spec
+is a 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. White space is
+ignored, and the pound sign ('#') introduces a comment that ends at the
+end of the current line.
+.Pp
+The optional name is the first part of a field specifier and
+is in curly braces. The text in curly braces in this example are
+the names:
+.Bd -literal -offset indent
+.Fa "{PS} v:b1 {Reserved} 0:b1 {Page Code} v:b6 # Mode select page"
+.Ed
+.Pp
+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.,
+.Fa "1A"
+or
+.Fa "v" )
+then a single byte value
+is copied to the next unused byte of the CDB.
+When the letter
+.Fa 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
+.Fa v
+followed by a field width specifier (e.g.,
+.Fa 3:4 ,
+.Fa 3:b4 ,
+.Fa 3:i3 ,
+.FR v:i3 )
+specifies 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.
+.Pp
+A decimal number or the letter
+.Fa b
+followed by a decimal number field width indicates a bit field of that width.
+The 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 a byte fills completely or when an
+.Fa i
+field is encountered.
+.Pp
+A field width specifier consisting of the letter
+.Fa 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
+.Fa 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 csio_build_visit
+operates similarly to
+.Fn csio_build ,
+except that the values to substitute for variable arguments in
+.Fa cmd_spec
+are retrieved via the
+.Fn arg_get
+function passed in to
+.Fn csio_build_visit
+instead of via
+.Xr stdarg 3 .
+The
+.Fn arg_get
+function takes two arguments:
+.Bl -tag -width field_name
+.It Fa gethook
+is passed into the
+.Fn arg_get
+function at each invocation. This enables the
+.Fn arg_get
+function to keep some state in between calls without using global or static
+variables.
+.It Fa field_name
+is the field name supplied in
+.Fa fmt ,
+if any.
+.El
+.Pp
+.Fn csio_decode
+is used to decode information from the data in phase of the SCSI
+transfer.
+.Pp
+The decoding is similar to
+the command specifier processing of
+.Fn csio_build
+except that the data is extracted from the data pointed to by
+.Fa csio->data_ptr .
+The stdarg list should be pointers to integers instead of integer
+values.
+A seek field type and a suppression modifier are added.
+The
+.Fa *
+suppression modifier (e.g.,
+.Fa *i3
+or
+.Fa *b4 )
+suppresses assignment from the field and can be used to skip
+over bytes or bits in the data, without having to copy
+them to a dummy variable in the arg list.
+.Pp
+The seek field type
+.Fa s
+permits you to skip over data.
+This seeks to an absolute position (
+.Fa s3 )
+or a relative position (
+.Fa s+3 )
+in the data, based on whether or not the presence of the '+' sign.
+The seek value can be specified as
+.Fa v
+and the next integer value from the argument list will be
+used as the seek value.
+.Pp
+.Fn csio_decode_visit
+operates like
+.Fn csio_decode
+except that instead of placing the decoded contents of the buffer in
+varardic arguments, the decoded buffer contents are returned to the user
+via the
+.Fn arg_put
+function that is passed in.
+The
+.Fn arg_put
+function takes several arguments:
+.Bl -tag -width letter
+.It Fa hook
+The "hook" is a mechanism to allow the
+.Fn arg_put
+function to save state in between calls.
+.It Fa letter
+is the letter describing the format of the argument being passed into the
+function.
+.It Fa val
+is a void pointer to the value being passed into the function.
+.It Fa count
+is the number of arguments being passed into the
+.Fn arg_put
+function. At present this will only be set to 1.
+.It Fa name
+This is a text description of the field, if one was provided in the
+.Fa fmt .
+.El
+.Pp
+.Fn buff_decode
+decodes an arbitrary data buffer using the method
+described above for
+.Fn csio_decode .
+.Pp
+.Fn buff_decode_visit
+decodes an arbitrary data buffer using the method described above for
+.Fn csio_decode_visit .
+.Pp
+.Fn csio_encode
+encodes the
+.Fa data_ptr
+portion (not the CDB!) of a
+.Va ccb_scsiio
+structure, using the method described above for
+.Fn csio_build .
+.Pp
+.Fn csio_encode_visit
+encodes the
+.Fa data_ptr
+portion (not the CDB!) of a
+.Va ccb_scsiio
+structure, using the method described above for
+.Fn csio_build_visit .
+.Pp
+.Fn buff_encode_visit
+encodes an arbitrary data pointer, using the method described
+above for
+.Fn csio_build_visit .
+.Sh RETURN VALUES
+.Fn csio_build ,
+.Fn csio_build_visit ,
+.Fn csio_encode ,
+.Fn csio_encode_visit ,
+and
+.Fn buff_encode_visit
+return the number of fields processed.
+.Pp
+.Fn csio_decode ,
+.Fn csio_decode_visit ,
+.Fn buff_decode ,
+and
+.Fn buff_decode_visit
+return the number of assignments performed.
+.Sh SEE ALSO
+.Xr cam 3 ,
+.Xr pass 4 ,
+.Xr camcontrol 8
+.Sh HISTORY
+.Pp
+The CAM versions of these functions are based upon similar functions
+implemented for the old FreeBSD
+.Tn SCSI
+layer. The encoding/decoding functions in the old
+.Tn SCSI
+code were written by Peter Dufault.
+.Pp
+Many systems have comparable interfaces to permit a user to construct a
+SCSI command in user space.
+.Pp
+The old
+.Va scsireq
+data structure was 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
+The new CCB data structures are derived from the CAM-2 and CAM-3
+specifications.
+.Pp
+Peter Dufault implemented a clone of SGI's interface in 386bsd that
+led to the original FreeBSD
+.Tn SCSI
+library and the related kernel ioctl.
+If anyone needs that for compatibility contact dufault@hda.com.
+.Sh AUTHORS
+Kenneth Merry implemented the CAM versions of these encoding and decoding
+functions. This current work is based upon earlier work by Peter Dufault.
+.Sh BUGS
+There should probably be a function that encodes both the CDB and the data
+buffer portions of a
+.Tn SCSI
+CCB. I discovered this while implementing the arbitrary command execution
+code in
+.Xr camcontrol 8 ,
+but I haven't yet had time to implement such a function.
+.Pp
+Some of the CCB flag descriptions really don't belong here. Rather they
+belong in a generic CCB man page. Since that man page hasn't yet been
+written, the shorter descriptions here will have to suffice.