summaryrefslogtreecommitdiffstats
path: root/lib/libscsi
diff options
context:
space:
mode:
authordufault <dufault@FreeBSD.org>1995-01-26 23:48:41 +0000
committerdufault <dufault@FreeBSD.org>1995-01-26 23:48:41 +0000
commita6910ddd5a86b337149ad2e18a21e2cd00e566ff (patch)
treebc7b6889a5c4c453f1fcd0f2e37050776d36b6f1 /lib/libscsi
parent34ecc54a2cac749f9eee4139f62595ecb4097992 (diff)
downloadFreeBSD-src-a6910ddd5a86b337149ad2e18a21e2cd00e566ff.zip
FreeBSD-src-a6910ddd5a86b337149ad2e18a21e2cd00e566ff.tar.gz
Clean up handling of unspecified names. Clarify man page.
Diffstat (limited to 'lib/libscsi')
-rw-r--r--lib/libscsi/scsi.3103
-rw-r--r--lib/libscsi/scsi.c105
2 files changed, 111 insertions, 97 deletions
diff --git a/lib/libscsi/scsi.3 b/lib/libscsi/scsi.3
index e6d0275..bf7163a 100644
--- a/lib/libscsi/scsi.3
+++ b/lib/libscsi/scsi.3
@@ -82,14 +82,18 @@ 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
+Look at the
+.Xr scsi 8
+command before using the library directly - simple programs are
+best implemented as scripts using that facility.
+.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"
+not all devices accept the SCIOCCOMAND ioctl. It is accepted by the
+control device for tape drives, partition D for disk drives, partition C
+for CD ROM drives, and any "unknown" device.
+The "super scsi"
.Xr ssc 4
-device also accepts it.
+device also accepts the ioctl.
.Pp
Most of the SCSI library functions build up and manipulate the
.Ar scsireq
@@ -115,7 +119,6 @@ typedef struct scsireq {
} scsireq_t;
.Ed
.Pp
-The function
.Fn scsireq_new
allocates a new
.Ar scsireq
@@ -166,30 +169,34 @@ indicates a data in phase (a transfer into the user buffer at
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.
+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.
-The optional name is the final part of a field specifier and
-is in curly braces. A valid example is:
+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
-.Fr "v:b1 {PS} 0:b1 {Reserved} v:b6 {Page Code}"
+.Fr "{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.
+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
+then a single byte value
is copied to the next unused byte of the CDB.
When the letter
.Fr v
@@ -203,17 +210,17 @@ followed by a field width specifier (e.g.,
.Fr 3:b4 ,
.Fr 3:i3 ,
.FR v:i3 )
-is used to specify a field of a given bit or byte width.
+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. A decimal number or the letter
+bits or bytes of the CDB.
+.Pp
+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
+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 the byte fills completely or when an
+the CDB is started whenever a byte fills completely or when an
.Fr i
field is encountered.
.Pp
@@ -223,49 +230,50 @@ 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
+For the
+.Fr 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.
+.Pp
The decoding is similar to
the command specifier processing of
-.Fn scsireq_build,
+.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
+The stdarg list should be pointers to integers instead of integer
values.
-.Pp
-In addition, a seek field type and a suppression field modifier are added.
+A seek field type and a suppression modifier are added.
The
.Fr *
-suppression modifier to a field (e.g.,
+suppression modifier (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.
+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
-A seek field type
+The seek field type
.Fr s
-is provided. This ``seeks'' to an absolute position in the data (
+permits you to skip over data.
+This seeks to an absolute position (
.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
+in the data, based on whether or not the presence of the '+' sign.
+The seek value can be specified as
.Fr v
- and the next integer value will be taken from the arg list
-and used as the seek value.
+and the next integer value from the argument list will be
+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.
+decodes an arbitrary data buffer using the method
+described above in
+.Fn scsireq_decode .
.Pp
.Fn scsireq_encode
encodes the data phase section of the structure. The encoding is
@@ -286,10 +294,6 @@ or not, and so on.
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.
@@ -311,11 +315,12 @@ and
return the same pointer as the one passed in.
.Pp
The functions
-.Fn scsireq_buff_decode ,
+.Fn scsireq_buff_decode and
.Fn scsireq_decode
-and
+return the number of assignments performed.
+.Pp
.Fn scsireq_encode
-return the number of fields processed.
+returns the number of fields processed.
.Pp
The function
.Fn scsireq_enter
diff --git a/lib/libscsi/scsi.c b/lib/libscsi/scsi.c
index 4d563e2..e597bb4 100644
--- a/lib/libscsi/scsi.c
+++ b/lib/libscsi/scsi.c
@@ -30,7 +30,7 @@
* 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: scsi.c,v 1.1.1.1 1995/01/24 12:10:11 dufault Exp $
+ * $Id: scsi.c,v 1.2 1995/01/25 00:33:50 dufault Exp $
*/
#include <stdlib.h>
#include <stdio.h>
@@ -132,20 +132,11 @@ scsireq_t *scsireq_new(void)
*
*/
-#define ARG_PUT(ARG) \
-do \
-{ \
- if (arg_put) \
- (*arg_put)(puthook, letter, (void *)((long)(ARG)), 1, field_name); \
- else \
- *(va_arg(ap, int *)) = (ARG); \
-} while (0)
-
static int do_buff_decode(u_char *databuf, size_t len,
void (*arg_put)(void *, int , void *, int, char *), void *puthook,
char *fmt, va_list ap)
{
- int decoded = 0;
+ int assigned = 0;
int width;
int suppress;
int plus;
@@ -156,19 +147,46 @@ char *fmt, va_list ap)
char letter;
char field_name[80];
+# define ARG_PUT(ARG) \
+ do \
+ { \
+ if (!suppress) \
+ { \
+ if (arg_put) \
+ (*arg_put)(puthook, letter, \
+ (void *)((long)(ARG)), 1, field_name); \
+ else \
+ *(va_arg(ap, int *)) = (ARG); \
+ assigned++; \
+ } \
+ field_name[0] = 0; \
+ suppress = 0; \
+ } while (0)
+
u_char bits = 0; /* For bit fields */
int shift = 0; /* Bits already shifted out */
suppress = 0;
+ field_name[0] = 0;
while (!done)
{
switch(letter = *fmt)
{
- case ' ':
+ case ' ': /* White space */
case '\t':
+ case '\r':
+ case '\n':
+ case '\f':
fmt++;
break;
+ case '#': /* Comment */
+ while (*fmt && (*fmt != '\n'))
+ fmt++;
+ if (fmt)
+ fmt++; /* Skip '\n' */
+ break;
+
case '*': /* Suppress assignment */
fmt++;
suppress = 1;
@@ -185,7 +203,8 @@ char *fmt, va_list ap)
fmt++;
}
- fmt++; /* Skip '}' */
+ if (fmt)
+ fmt++; /* Skip '}' */
field_name[i] = 0;
}
break;
@@ -209,10 +228,7 @@ char *fmt, va_list ap)
shift, bits, value, width, mask[width]);
#endif
- if (!suppress)
- ARG_PUT(value);
- else
- suppress = 0;
+ ARG_PUT(value);
shift -= width;
}
@@ -226,43 +242,31 @@ char *fmt, va_list ap)
switch(width)
{
case 1:
- if (!suppress)
- ARG_PUT(*databuf);
- else
- suppress = 0;
+ ARG_PUT(*databuf);
databuf++;
break;
case 2:
- if (!suppress)
- ARG_PUT(
- (*databuf) << 8 |
- *(databuf + 1));
- else
- suppress = 0;
+ ARG_PUT(
+ (*databuf) << 8 |
+ *(databuf + 1));
databuf += 2;
break;
case 3:
- if (!suppress)
- ARG_PUT(
- (*databuf) << 16 |
- (*(databuf + 1)) << 8 |
- *(databuf + 2));
- else
- suppress = 0;
+ ARG_PUT(
+ (*databuf) << 16 |
+ (*(databuf + 1)) << 8 |
+ *(databuf + 2));
databuf += 3;
break;
case 4:
- if (!suppress)
- ARG_PUT(
- (*databuf) << 24 |
- (*(databuf + 1)) << 16 |
- (*(databuf + 2)) << 8 |
- *(databuf + 3));
- else
- suppress = 0;
+ ARG_PUT(
+ (*databuf) << 24 |
+ (*(databuf + 1)) << 16 |
+ (*(databuf + 2)) << 8 |
+ *(databuf + 3));
databuf += 4;
break;
@@ -279,7 +283,6 @@ char *fmt, va_list ap)
width = strtol(fmt, &fmt, 10);
if (!suppress)
{
-
if (arg_put)
(*arg_put)(puthook, letter, databuf, width, field_name);
else
@@ -295,11 +298,11 @@ char *fmt, va_list ap)
*p = 0;
}
}
+ assigned++;
}
- else
- suppress = 0;
databuf += width;
- decoded++;
+ field_name[0] = 0;
+ suppress = 0;
break;
case 's': /* Seek */
@@ -330,7 +333,6 @@ char *fmt, va_list ap)
else
databuf = base + width; /* Absolute seek */
- decoded++;
break;
case 0:
@@ -343,7 +345,7 @@ char *fmt, va_list ap)
}
}
- return decoded;
+ return assigned;
}
int scsireq_decode(scsireq_t *scsireq, char *fmt, ...)
@@ -438,6 +440,13 @@ char *fmt, int *width_p, int *value_p, char *name, int n_name, int *error_p)
state = DONE;
else if (isspace(*p))
p++;
+ else if (*p == '#')
+ {
+ while (*p && *p != '\n')
+ p++;
+ if (p)
+ p++;
+ }
else if (*p == '{')
{
int i = 0;
OpenPOWER on IntegriCloud