aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2018-01-28 06:50:39 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2018-01-28 06:50:39 +0000
commit3a7e1666843ba386946f65d8ea89fe4ddf9ed9bf (patch)
treeec2d3a035ff39e5f5786460ac09f31df45d5469f /doc
parent6293187a432dd0bbf85961a897755bd0260f28ad (diff)
downloadsg3_utils-3a7e1666843ba386946f65d8ea89fe4ddf9ed9bf.tar.gz
add sg_seek and sg_stream_ctl utilities; properly identify vendor-specific sense; documentation cleanup
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@747 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'doc')
-rw-r--r--doc/Makefile.am11
-rw-r--r--doc/Makefile.in13
-rw-r--r--doc/sg3_utils.844
-rw-r--r--doc/sg_compare_and_write.88
-rw-r--r--doc/sg_seek.8135
-rw-r--r--doc/sg_ses.813
-rw-r--r--doc/sg_stream_ctl.8117
-rw-r--r--doc/sg_write_x.82
8 files changed, 321 insertions, 22 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am
index b1ffa079..9a1816eb 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -9,11 +9,11 @@ man_MANS = \
sg_read_long.8 sg_readcap.8 sg_reassign.8 sg_referrals.8 \
sg_rep_zones.8 sg_requests.8 sg_reset_wp.8 sg_rmsn.8 sg_rtpg.8 \
sg_safte.8 sg_sanitize.8 sg_sat_identify.8 sg_sat_phy_event.8 \
- sg_sat_read_gplog.8 sg_sat_set_features.8 sg_senddiag.8 sg_ses.8 \
- sg_ses_microcode.8 sg_start.8 sg_stpg.8 sg_sync.8 sg_timestamp.8 \
- sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 sg_wr_mode.8 \
- sg_write_buffer.8 sg_write_long.8 sg_write_same.8 sg_write_verify.8 \
- sg_write_x.8 sg_zone.8
+ sg_sat_read_gplog.8 sg_sat_set_features.8 sg_seek.8 sg_senddiag.8 \
+ sg_ses.8 sg_ses_microcode.8 sg_start.8 sg_stpg.8 sg_stream_ctl.8 \
+ sg_sync.8 sg_timestamp.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
+ sg_wr_mode.8 sg_write_buffer.8 sg_write_long.8 sg_write_same.8 \
+ sg_write_verify.8 sg_write_x.8 sg_zone.8
CLEANFILES =
if OS_LINUX
@@ -26,7 +26,6 @@ sg_scan.8: sg_scan.8.linux
cp -p $< $@
endif
-
if OS_WIN32_MINGW
man_MANS += sg_scan.8
CLEANFILES += sg_scan.8
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 0419857a..514ab45a 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -221,6 +221,7 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_LIB = @PTHREAD_LIB@
RANLIB = @RANLIB@
+RT_LIB = @RT_LIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
@@ -289,12 +290,12 @@ man_MANS = scsi_mandat.8 scsi_readcap.8 scsi_ready.8 scsi_satl.8 \
sg_readcap.8 sg_reassign.8 sg_referrals.8 sg_rep_zones.8 \
sg_requests.8 sg_reset_wp.8 sg_rmsn.8 sg_rtpg.8 sg_safte.8 \
sg_sanitize.8 sg_sat_identify.8 sg_sat_phy_event.8 \
- sg_sat_read_gplog.8 sg_sat_set_features.8 sg_senddiag.8 \
- sg_ses.8 sg_ses_microcode.8 sg_start.8 sg_stpg.8 sg_sync.8 \
- sg_timestamp.8 sg_turs.8 sg_unmap.8 sg_verify.8 sg_vpd.8 \
- sg_wr_mode.8 sg_write_buffer.8 sg_write_long.8 sg_write_same.8 \
- sg_write_verify.8 sg_write_x.8 sg_zone.8 $(am__append_1) \
- $(am__append_3) $(am__append_5)
+ sg_sat_read_gplog.8 sg_sat_set_features.8 sg_seek.8 \
+ sg_senddiag.8 sg_ses.8 sg_ses_microcode.8 sg_start.8 sg_stpg.8 \
+ sg_stream_ctl.8 sg_sync.8 sg_timestamp.8 sg_turs.8 sg_unmap.8 \
+ sg_verify.8 sg_vpd.8 sg_wr_mode.8 sg_write_buffer.8 \
+ sg_write_long.8 sg_write_same.8 sg_write_verify.8 sg_write_x.8 \
+ sg_zone.8 $(am__append_1) $(am__append_3) $(am__append_5)
CLEANFILES = $(am__append_2) $(am__append_4) $(am__append_6)
all: all-am
diff --git a/doc/sg3_utils.8 b/doc/sg3_utils.8
index 7238303b..1da5de46 100644
--- a/doc/sg3_utils.8
+++ b/doc/sg3_utils.8
@@ -32,7 +32,7 @@ A good overview of various SCSI standards can be seen in
http://www.t10.org/scsi\-3.htm with the SCSI command sets in the upper part
of the diagram. The highest level (i.e. most abstract) document is the SCSI
Architecture Model (SAM) with SAM\-5 being the most recent standard (ANSI
-INCITS 447-2008) although SAM\-5 should be released soon. SCSI commands in
+INCITS 447\-2008) although SAM\-5 should be released soon. SCSI commands in
common with all device types can be found in SPC of which SPC\-5 is the
latest major version. Block device specific commands (e.g. as used by disks)
are in SBC, those for tape drives in SSC and those for CD/DVD/BD drives in
@@ -199,6 +199,44 @@ the 'format' command" advice works but seems a very dangerous way to list
devices. [It does prompt again before doing any damage.] 'devfsadm \-Cv'
cleans out the clutter in the /dev/rdsk directory, only leaving what
is "live". The "cfgadm \-v" command looks promising.
+.SH NVME SUPPORT
+NVMe (or NVM Express) is a relatively new storage transport and command
+set. The level of abstraction of the NVMe command set is somewhat lower
+the SCSI command sets, closer to the level of abstraction of ATA (and SATA)
+command sets. NVMe claims to be designed with flash and modern "solid
+state" storage in mind, something unheard of when SCSI was originally
+developed in the 1980s.
+.PP
+The SCSI command sets' advantage is the length of time they have been in
+place and the existing tools (like these) to support it. Plus SCSI command
+sets level of abstraction is both and advantage and disadvantage. Recently
+the NVME\-MI (Management Interface) designers decide to use the SCSI
+Enclosure Services (SES\-3) standard "as is" with the addition of two
+tunnelling NVME\-MI commands: SES Send and SES Receive. This means after the
+OS interface differences are taken into account, the sg_ses, sg_ses_microcode
+and sg_senddiag utilities can be used on a NVMe device that supports a newer
+version of NVME\-MI.
+.PP
+The NVME\-MI SES Send and SES Receive commands correspond to the SCSI
+SEND DIAGNOSTIC and RECEIVE DIAGNOSTIC RESULTS commands respectively.
+There are however a few other commands that need to be translated, the
+most important of which is the SCSI INQUIRY command to the NVMe Identify
+controller/namespace. Version 1.43 of these utilities contain a small
+SNTL (SCSI to NVMe Translation Layer) to take care of these details.
+.PP
+As a side effect of this "juggling" if the sg_inq utility is used (without
+the \-\-page= option) on a NVMe \fIDEVICE\fR then the actual NVMe
+Identifier (controller and possibly namespace) responses are decoded and
+output. However if 'sg_inq \-\-page=sinq <device>' is given for the
+same \fIDEVICE\fR then parts of the NVMe Identify controller and namespace
+response are translated to a SCSI standard INQUIRY response which is then
+decoded and output.
+.PP
+Apart from the special case with the sg_inq, all other utilities in the
+package assume they are talking to a SCSI device and decode any response
+accordingly. One easy way for users to see the underlying device is a
+NVMe device is the standard INQUIRY response Vendor Identification field
+of "NVMe " (an 8 character long string with 4 spaces to the right).
.SH EXIT STATUS
To aid scripts that call these utilities, the exit status is set to indicate
success (0) or failure (1 or more). Note that some of the lower values
@@ -321,7 +359,7 @@ Work in this area is currently experimental.
.TP
.B 49
low level driver reports a residual count (i.e. number of bytes actually
-received by HBA is 'requested_bytes - residual_count') that is high enough
+received by HBA is 'requested_bytes \- residual_count') that is high enough
to indicate that no useful processing can be done on that response.
.TP
.B 50 + <os_error_number>
@@ -334,7 +372,7 @@ package reports 50+ENOMEM when it can't allocate memory, not necessarily
from an OS system call. In recent versions of Linux the file showing the
mapping between symbolic constants (e.g. ENOMEM) and the corresponding
integer is in the kernel source code file:
-include/uapi/asm-generic/errno-base.h
+include/uapi/asm\-generic/errno\-base.h
.TP
.B 97
a SCSI command response failed sanity checks.
diff --git a/doc/sg_compare_and_write.8 b/doc/sg_compare_and_write.8
index e476153f..9329f6e1 100644
--- a/doc/sg_compare_and_write.8
+++ b/doc/sg_compare_and_write.8
@@ -1,10 +1,10 @@
-.TH "COMPARE AND WRITE" "8" "October 2017" "sg3_utils\-1.43" SG3_UTILS
+.TH "COMPARE AND WRITE" "8" "January 2018" "sg3_utils\-1.43" SG3_UTILS
.SH NAME
sg_compare_and_write \- send the SCSI COMPARE AND WRITE command
.SH SYNOPSIS
.B sg_compare_and_write
[\fI\-\-dpo\fR] [\fI\-\-fua\fR] [\fI\-\-fua_nv\fR] [\fI\-\-help\fR]
-[\fI\-\-group=GN\fR] \fI\-\-in=IF\fR [\fI\-\-inw=WF\fR] \fI\-\-lba=LBA\fR
+[\fI\-\-grpnum=GN\fR] \fI\-\-in=IF\fR [\fI\-\-inw=WF\fR] \fI\-\-lba=LBA\fR
[\fI\-\-num=NUM\fR] [\fI\-\-quiet\fR] [\fI\-\-timeout=TO\fR]
[\fI\-\-verbose\fR] [\fI\-\-version\fR] [\fI\-\-wrprotect=WP\fR]
[\fI\-\-xferlen=LEN\fR] \fIDEVICE\fR
@@ -67,7 +67,7 @@ Set the FUA bit in the COMPARE AND WRITE CDB
Set the FUA_NV bit in the COMPARE AND WRITE CDB. This bit was removed in
SBC\-3 revision 35d and its position marked as "reserved".
.TP
-\fB\-g\fR, \fB\-\-group\fR=\fIGN\fR
+\fB\-g\fR, \fB\-\-grpnum\fR=\fIGN\fR
where \fIGN\fR is the value to be placed in the group number field in the
COMPARE AND WRITE CDB.
.TP
@@ -144,7 +144,7 @@ Eric Seppanen.
.SH "REPORTING BUGS"
Report bugs to shahar.salzman@kaminario.com or dgilbert@interlog.com
.SH COPYRIGHT
-Copyright \(co 2012\-2017 Kaminario Technologies LTD
+Copyright \(co 2012\-2018 Kaminario Technologies LTD
.br
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
diff --git a/doc/sg_seek.8 b/doc/sg_seek.8
new file mode 100644
index 00000000..c550788b
--- /dev/null
+++ b/doc/sg_seek.8
@@ -0,0 +1,135 @@
+.TH SG_SEEK "8" "January 2018" "sg3_utils\-1.43" SG3_UTILS
+.SH NAME
+sg_seek \- send SCSI SEEK, PRE-FETCH(10) or PRE-FETCH(16) command
+.SH SYNOPSIS
+.B sg_seek
+[\fI\-\-10\fR] [\fI\-\-count=NC\fR] [\fI\-\-grpnum=GN\fR] [\fI\-\-help\fR]
+[\fI\-\-immed\fR] [\fI\-\-lba=LBA\fR] [\fI\-\-num\-blocks=NUM\fR]
+[\fI\-\-pre\-fetch\fR] [\fI\-\-readonly\fR] [\fI\-\-skip=SB\fR]
+[\fI\-\-time\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR]
+[\fI\-\-wrap\-offset=WO\fR] \fIDEVICE\fR
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+Sends a SCSI SEEK(10), PRE\-FETCH(10) or PRE\-FETCH(16) command to the
+\fIDEVICE\fR. The SEEK command has been obsolete since SBC\-2 (2005) but
+still is supported on some hard disks and even some SSDs (solid state
+disks). The PRE\-FETCH command can be viewed as SEEK's modern replacement.
+Instead of talking about moving the disk heads to the track containing
+the sort after LBA, it talks about bringing the sort after LBA (and a
+given number of blocks) into the disk's cache. Also the PRE\-FETCH commands
+have an IMMED field.
+.PP
+The PRE\-FETCH commands can report "real" errors but usually they will report
+one of two "good" statuses. To do this they return the rarely used CONDITION
+MET status. If the number of blocks does actually fit in the cache (when
+IMMED=0) or there is enough room in the cache when the command arrives (when
+IMMED=1) then a CONDITION MET status is returned. If the requested number of
+blocks did not fit (IMMED=0) or would not fit (IMMED=1) then status GOOD
+is returned. So if a disk has a large cache and PRE\-FETCH is used sparingly
+then the command is more likely to return CONDITION MET than GOOD. This
+presents some SCSI sub-systems with problems as due to its rareness they
+mishandle CONDITION MET and treat it as an error.
+.SH OPTIONS
+Arguments to long options are mandatory for short options as well.
+.TP
+\fB\-T\fR, \fB\-\-10\fR
+use a 10 byte cdb command, either SEEK(10) or PRE\-FETCH(10) command. In
+the absence of the \fI\-\-pre\-fetch\fR option, the SEEK(10) command is
+used. If the \fI\-\-pre\-fetch\fR option is given without this option
+then a PRE\-FETCH(16) command is used.
+.TP
+\fB\-c\fR, \fB\-\-count\fR=\fINC\fR
+\fINC\fR is the number of commands (one of SEEK(10), PRE\-FETCH(10) or
+PRE\-FETCH(16)) that will be executed. The default value is 1. If an error
+occurs it is noted and the program continues until \fINC\fR is exhausted.
+If \fINC\fR is 0 then options are checked and the \fIDEVICE\fR is opened
+but no commands are sent.
+.TP
+\fB\-g\fR, \fB\-\-grpnum\fR=\fIGN\fR
+\fIGN\fR is the group number, a value between 0 and 63 (in hex: 0x3f). The
+default value is 0. This option is ignored if the selected command is
+SEEK(10).
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+output the usage message then exit.
+.TP
+\fB\-i\fR, \fB\-\-immed\fR
+this option only applies to PRE\-FETCH(10) and PRE\-FETCH(16), setting
+the IMMED bit. Without this option, the \fIDEVICE\fR returns after it has
+completed transferring all, or part of, the requested blocks into the
+cache. If this option is given the \fIDEVICE\fR returns after it has done
+sanity checks on the cdb (e.g. making sure the \fILBA\fR is greater than
+the number of available blocks) and before it does the transfer into the
+cache.
+.br
+Note that even when this option is given, the return status from the
+PRE\-FETCH commands is still either CONDITION MET status (if the cache seems
+to have enough free space for the transfer) or a GOOD status (if the cache
+does not seem to have enough free space).
+.TP
+\fB\-l\fR, \fB\-\-lba\fR=\fILBA\fR
+\fILBA\fR is the starting logical block address that is placed in the
+command descriptor block (cdb) of the selected command. Note that the
+\fILBA\fR field in SEEK(10) and PRE\-FETCH(10) is a 32 bit quantity,
+while with PRE\-FETCH(16) it is a 64 bit quantity. The default value is
+0 .
+.TP
+\fB\-n\fR, \fB\-\-num\-blocks\fR=\fINUM\fR
+\fINUM\fR is the number of blocks, starting at and including \fILBA\fR,
+to place in the \fIDEVICE\fR's cache. The SEEK(10) command does not use
+the \fINUM\fR value. For PRE\-FETCH(10) \fINUM\fR is a 16 bit quantity,
+while for PRE\-FETCH(16) it is a 32 bit quantity. The default value is
+1 . If \fINUM\fR is 0 then the \fIDEVICE\fR will attempt to transfer all
+blocks from the given \fILBA\fR to the end of the medium.
+.TP
+\fB\-p\fR, \fB\-\-pre\-fetch\fR
+this option selects either PRE\-FETCH(10) or PRE\-FETCH(16) commands. With
+the \fI\-\-10\fR also given, the PRE\-FETCH(10) command is selected; without
+that option PRE\-FETCH(16) is selected. The default (in the absence of this
+and other 'selecting' options) the SEEK(10) command is selected.
+.TP
+\fB\-r\fR, \fB\-\-readonly\fR
+this option sets a 'read\-only' flag when the underlying operating system
+opens the given \fIDEVICE\fR. This may not work since operating systems can
+not easily determine whether a pass\-through is a logical read or write
+operation so they take a risk averse stance and require read\-write type
+\fIDEVICE\fR opens irrespective of what is performed by the pass\-through.
+.TP
+\fB\-s\fR, \fB\-\-skip\fR=\fISB\fR
+\fISB\fR is the number of logical block addresses to skip, between repeated
+commands when \fINC\fR is greater than 1. The default value of \fISB\fR is
+1 . \fISB\fR may be set to 0 so that all \fINC\fR PRE\-FETCH commands use
+the same \fILBA\fR.
+.TP
+\fB\-t\fR, \fB\-\-time\fR
+if given the elapsed time to execute \fINC\fR commands is recorded. This is
+printed out before this utility exits. If \fINC\fR is greater than 1 then
+the the "per command" time is also printed.
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+increase the level of verbosity, (i.e. debug output).
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+print the version string and then exit.
+.TP
+\fB\-w\fR, \fB\-\-wrap\-offset\fR=\fIWO\fR
+\fIWO\fR is the number of blocks, relative to \fILBA\fR, that when exceeded,
+set the next command's logical block address back to \fILBA\fR. Whether
+this "reset-to-LBA" action occurs depends on the values \fINC\fR and \fISB\fR.
+.SH NOTES
+As of Linux kernel 4.15 the CONDITION MET status is logged as an error.
+.SH EXIT STATUS
+The exit status of sg_stream_ctl is 0 when it is successful. Otherwise see
+the sg3_utils(8) man page.
+.SH AUTHORS
+Written by Douglas Gilbert.
+.SH "REPORTING BUGS"
+Report bugs to <dgilbert at interlog dot com>.
+.SH COPYRIGHT
+Copyright \(co 2018 Douglas Gilbert
+.br
+This software is distributed under a FreeBSD license. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+.SH "SEE ALSO"
+.B sg_vpd(sg3_utils); sdparm(sdparm)
diff --git a/doc/sg_ses.8 b/doc/sg_ses.8
index 56234047..f941c908 100644
--- a/doc/sg_ses.8
+++ b/doc/sg_ses.8
@@ -351,7 +351,7 @@ pages follow the same pattern as the Enclosure Status page.
.PP
The numeric index corresponding to the overall element is "\-1". If the
Configuration page indicates a particular element type has "n" elements
-and n is greater than 0 then its indexes range from 0 to n-\1 .
+and n is greater than 0 then its indexes range from 0 to n\-1 .
.PP
The Additional Element Status page is a bit more complicated. It has
entries for "Number of possible elements" of certain Element types. It
@@ -382,7 +382,7 @@ individual index then the option is equivalent to \fI\-\-index=0,II\fR. When
\fI\-\-index=A,\-1\fR.
.PP
Wherever an individual index is applicable, it can be replaced by an
-individual index range. It has the form: <first_ii>-<last_ii>. For
+individual index range. It has the form: <first_ii>\-<last_ii>. For
example: '3\-5' will select individual indexes 3, 4 and 5 .
.PP
To cope with vendor specific Element types (which should be in the range 128
@@ -506,6 +506,15 @@ Subenclosure Identifier (\fISEID\fR) are written to the Subenclosure Nickname
Control page.
.PP
There is an example of changing a nickname in the EXAMPLES section below.
+.SH NVME ENCLOSURES
+Support has been added to sg_ses (actually, its underlying library) for
+NVMe (also known as NVM Express) Enclosures. It can be considered
+experimental in sg3_utils package version 1.43 and sg_ses version 2.31 .
+.PP
+This support is based on a decision by NVME-MI (Management Interface)
+developers to support the SES\-3 standard. This was done using the newly
+added SES Send and SES Receive commands that tunnel diagnostic page
+contents as used by SES.
.SH NOTES
This utility can be used to fetch arbitrary (i.e. non SES) diagnostic
pages (using the SCSI READ DIAGNOSTIC command). To this end the
diff --git a/doc/sg_stream_ctl.8 b/doc/sg_stream_ctl.8
new file mode 100644
index 00000000..6be07f65
--- /dev/null
+++ b/doc/sg_stream_ctl.8
@@ -0,0 +1,117 @@
+.TH SG_STREAM_CTL "8" "January 2018" "sg3_utils\-1.43" SG3_UTILS
+.SH NAME
+sg_stream_ctl \- send SCSI STREAM CONTROL or GET STREAM STATUS command
+.SH SYNOPSIS
+.B sg_stream_ctl
+[\fI\-\-brief\fR] [\fI\-\-close\fR] [\fI\-\-ctl=CTL\fR] [\fI\-\-get\fR]
+[\fI\-\-help\fR] [\fI\-\-id=SID\fR] [\fI\-\-maxlen=LEN\fR] [\fI\-\-open\fR]
+[\fI\-\-readonly\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR] \fIDEVICE\fR
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+Sends a SCSI STREAM CONTROL or GET STREAM STATUS command to the \fIDEVICE\fR.
+These commands, together with WRITE STREAM(16 and 32) and several fields in
+the Block Limits Extension VPD page [0xb7] support the streams concept.
+The stream commands were added in SBC\-4 draft 8 (September 2015).
+.PP
+Both STREAM CONTROL and GET STREAM STATUS command expect data from the
+\fIDEVICE\fR (referred to as 'data\-in'). In the case of STREAM CONTROL
+only the 'open' STR_CTL<\-\-0x1 actually needs the data\-in as it contains
+the "Assigned stream id" if the open was successful. The assigned stream
+id should be used by subsequent WRITE STREAM commands and ultimately
+by the STREAM CONTROL close (STR_CTL<\-\-0x2). Valid stream ids are between
+1 and 65535 inclusive.
+.SH OPTIONS
+Arguments to long options are mandatory for short options as well.
+.TP
+\fB\-b\fR, \fB\-\-brief\fR
+this option reduces the output of the GET STREAM STATUS command to just
+one number (in decimal) per line sent to stdout. Those numbers are the
+currently open stream ids. If an error occurs then \-1 is sent to stdout
+and error related messages are sent to stderr. The default is to print more
+words (and fields) from the GET STREAM STATUS response.
+.TP
+\fB\-c\fR, \fB\-\-close\fR
+selects the STREAM CONTROL command and sets STR_CTL<\-\-0x2 (i.e. 'close').
+The \fI\-\-id=SID\fR option should also be given because it defaults to 0
+which is not a valid stream id.
+.TP
+\fB\-C\fR, \fB\-\-ctl\fR=\fICTL\fR
+\fICTL\fR is the value placed in the STR_CTL field of the STREAM CONTROL
+command (cdb). It is a two bit field so has 4 variants: 0 and 3 are reserved;
+1 opens are new stream and 2 closes the given stream id. '\-\-ctl=1' is
+equivalent to '\-\-open' while '\-\-ctl=2' is equivalent to '\-\-close'.
+.TP
+\fB\-g\fR, \fB\-\-get\fR
+selects the GET STREAM STATUS command. If the \fI\-\-id=SID\fR option is
+also given the the response starts lists open stream ids from and including
+\fISID\fR. If the \fI\-\-id=SID\fR option is not given (or \fISID\fR is 0)
+then all open stream id will be returned in the response (data\-in) as long
+as the allocation length (defaults to 248 bytes which can be overridden by
+the \fI\-\-maxlen=LEN\fR option) is long enough. This is the default action
+of this utility (i.e. GET STREAM STATUS command) if no "selecting" options
+are given.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+output the usage message then exit.
+.TP
+\fB\-i\fR, \fB\-\-id\fR=\fISID\fR
+\fISID\fR is a stream id, a value between 1 and 65535. It is used by STREAM
+CONTROL (close) to identify the stream to close. It is used by the GET
+STREAM STATUS command as the starting stream id (from and including); so
+stream ids that are less than \fISID\fR will not appear in the response.
+.TP
+\fB\-m\fR, \fB\-\-maxlen\fR=\fILEN\fR
+\fILEN\fR is the maximum length the response can be. It becomes the
+ALLOCATION LENGTH field in both commands. The default (in the absence of
+this option) is 8 bytes for STREAM CONTROL and 248 bytes for GET STREAM
+STATUS.
+.TP
+\fB\-o\fR, \fB\-\-open\fR
+selects the STREAM CONTROL command and sets STR_CTL<\-\-0x1 (i.e. 'open').
+If the \fI\-\-id=SID\fR option is given then it is ignored. The user should
+observe the response as the "Assigned stream id" is printed on stdout if
+the open is successful, if not '\-1' is sent to stdout and error messages are
+sent to stderr. If the \fI\-\-brief\fR option is also given then the only
+thing sent to stdout is a number of the assigned stream id (1 to
+65535 inclusive) or '\-1' if there is an error.
+.TP
+\fB\-r\fR, \fB\-\-readonly\fR
+this option sets a 'read\-only' flag when the underlying operating system
+opens the given \fIDEVICE\fR. This may not work since operating systems can
+not easily determine whether a pass\-through command is a logical read or
+write operation on the media (or its metadata) so they take a risk averse
+stance and require read\-write type permissions on the \fIDEVICE\fR open
+irrespective of what is performed by the pass\-through.
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+increase the level of verbosity, (i.e. debug output).
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+print the version string and then exit.
+.SH NOTES
+There are no special read commands for streams. This implies that "normal"
+READs (6, 10, 12, 16 or 32) can be used. Note that when a stream is closed,
+all resources associated with that stream id are removed, apart from the
+data in the written LBAs. To make sure the reading back data is not delayed
+too much by error recovery (in the presence of media errors) the user may
+set the RECOVERY TIME LIMIT field (units for non\-zero values: milliseconds)
+in the 'Read\-write error recovery' mode page. This can be done with the
+sdparm utility.
+.PP
+The SCSI WRITE STREAM (16 and 32) commands can be found in the sg_write_x
+utility in this package.
+.SH EXIT STATUS
+The exit status of sg_stream_ctl is 0 when it is successful. Otherwise see
+the sg3_utils(8) man page.
+.SH AUTHORS
+Written by Douglas Gilbert.
+.SH "REPORTING BUGS"
+Report bugs to <dgilbert at interlog dot com>.
+.SH COPYRIGHT
+Copyright \(co 2018 Douglas Gilbert
+.br
+This software is distributed under a FreeBSD license. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+.SH "SEE ALSO"
+.B sg_vpd,sg_write_x(sg3_utils); sdparm(sdparm)
diff --git a/doc/sg_write_x.8 b/doc/sg_write_x.8
index 9d965a5f..25bde0d9 100644
--- a/doc/sg_write_x.8
+++ b/doc/sg_write_x.8
@@ -585,4 +585,4 @@ Copyright \(co 2017 Douglas Gilbert
This software is distributed under a FreeBSD license. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.SH "SEE ALSO"
-.B sg_readcap,sg_vpd,sg_write_same(sg3_utils)
+.B sg_readcap,sg_vpd,sg_write_same,sg_stream_ctl(sg3_utils)