diff options
author | dufault <dufault@FreeBSD.org> | 1995-01-26 23:48:41 +0000 |
---|---|---|
committer | dufault <dufault@FreeBSD.org> | 1995-01-26 23:48:41 +0000 |
commit | a6910ddd5a86b337149ad2e18a21e2cd00e566ff (patch) | |
tree | bc7b6889a5c4c453f1fcd0f2e37050776d36b6f1 /lib/libscsi | |
parent | 34ecc54a2cac749f9eee4139f62595ecb4097992 (diff) | |
download | FreeBSD-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.3 | 103 | ||||
-rw-r--r-- | lib/libscsi/scsi.c | 105 |
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; |