diff options
author | ken <ken@FreeBSD.org> | 1998-10-14 06:20:36 +0000 |
---|---|---|
committer | ken <ken@FreeBSD.org> | 1998-10-14 06:20:36 +0000 |
commit | 995f10982005f3549e7f40ad95e12bd69088584c (patch) | |
tree | 68796d3196198135f372fb8884b341683f8b736b /lib/libcam | |
parent | 0966fead52f01db69f761858f479fce0d844d215 (diff) | |
download | FreeBSD-src-995f10982005f3549e7f40ad95e12bd69088584c.zip FreeBSD-src-995f10982005f3549e7f40ad95e12bd69088584c.tar.gz |
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.
Diffstat (limited to 'lib/libcam')
-rw-r--r-- | lib/libcam/Makefile | 58 | ||||
-rw-r--r-- | lib/libcam/cam.3 | 416 | ||||
-rw-r--r-- | lib/libcam/cam_cdbparse.3 | 542 |
3 files changed, 983 insertions, 33 deletions
diff --git a/lib/libcam/Makefile b/lib/libcam/Makefile index 0bccbdc..5b395e4 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 0000000..1f3e0e4 --- /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 0000000..4887aa3 --- /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. |