xref: /aosp_15_r20/external/sg3_utils/README.details (revision 44704f698541f6367e81f991ef8bb54ccbf3fc18)
1                      README.details for sg3_utils
2                      ============================
3Introduction
4============
5This package contains low level command line utilities for devices that use
6the SCSI command set. Originally the SCSI command set was associated
7exclusively with the SCSI Parallel Interface (SPI) transport. SPI has now
8almost been completely replaced by the Serial Attached SCSI (SAS) transport
9which also accepts the SCSI command set. Additionally many other storage
10related transports use the SCSI command set (amongst others); examples are
11ATAPI devices (CD/DVDs and tapes), USB mass storage devices (including those
12using the newer UAS[P]), Fibre Channel disks, IEEE 1394 storage devices (SBP
13protocol), iSCSI, FCoE and SOP devices. Even NVMe which has its own command
14set accepts SCSI commands in some contexts; one example is for enclosure
15management where NVME-MI has SES Send and SES Receive commands. SES refers
16to the SCSI Enclosure Services command set.
17
18This package originally targeted the Linux SCSI subsystem. Since most
19operating systems contain a SCSI command pass-through mechanism, many
20utilities within this package have been ported. This README mainly
21concentrates on Linux: see the README.freebsd file for the FreeBSD port,
22README.solaris for the Solaris port, the README.tru64 file for the Tru64
23(OSF) port and README.win32 for the Windows ports (of which there are two
24variants).
25
26Most utilities within the sg3_utils package work at the SCSI command level.
27For example the sg_inq utility issues a SCSI INQUIRY command and decodes the
28response. The COVERAGE file has a table containing a row for each SCSI
29command issued by this package; to the right of each row is the utility
30(sometimes more than one) that issue that SCSI command. The COVERAGE file
31has a second table for ATA commands usage.
32
33Some utilities interface at a slightly higher level, for example: sg_dd,
34sgm_dd and sgp_dd. These are closely related to the Unix dd command and
35typically issue a sequence of SCSI READ and WRITE commands to copy data.
36These utilities are relatively tightly bound to Linux and are not ported to
37other Operating Systems. A new utility called ddpt (in a package of the same
38name) is more generic while still allowing a copy to be done in terms of
39SCSI READ and WRITE commands. ddpt has been ported to other OSes.
40
41License
42=======
43All utilities and libraries have either a "2 clause" BSD license or are
44"GPL-2ed". The "2 clause" BSD license is taken from the FreeBSD project but
45drops the last paragraph that directly refers to the "FreeBSD project".
46That BSD license was updated from the "3 clause" to the newer "2 clause"
47version on 20180119. To save space various source code files refer to a
48file called "BSD_LICENSE" in the main, src and lib directories. The author's
49intention is that users may incorporate all or part of the code in their work
50as they please. Attribution is encouraged. Please check the code as other
51contributors (apart from the author) may also have copyright notices. For a
52list of contributors see the CREDITS file.
53
54
55Description
56===========
57A web site supporting the sg3_utils package can be found at
58https://sg.danny.cz/sg/sg3_utils.html . That page has a table of released
59versions for download. The most recent release or beta of sg3_utils may
60be found on this page: https://sg.danny.cz/sg in the News section.
61
62The predecessor to this package was called sg_utils. It is described in
63https://sg.danny.cz/sg/uu_index.html and old versions can be downloaded
64from the Downloads section of https://sg.danny.cz/sg .
65
66In the Linux 2.4 kernel series these utilities need to use the SCSI generic
67(sg) driver to access SCSI devices. The name of this package (i.e. sg3_utils)
68refers to version 3 of the SCSI generic (sg) driver which was introduced at
69the beginning of the 2.4 Linux kernel series. Significantly this added a new
70SCSI command interface structure (i.e. struct sg_io_hdr) that is more
71flexible than the older "sg_header" structure found in the sg driver in the
722.2 and earlier Linux kernel series. The sg_io_hdr structure is also more
73flexible than the awkward (and limiting) interface to the
74SCSI_IOCTL_SEND_COMMAND ioctl supported by the Linux SCSI mid level. The
75version 3 sg driver also added the SG_IO ioctl that is synchronous (i.e. it
76issues the requested SCSI command and waits for the response (or a timeout)
77before the ioctl returns to the user space program that invoked it). The
78SG_IO ioctl is now supported in other parts of the Linux kernel in the 2.6
79series.
80
81In sg3_utils version 1.27 support has been added for the Linux bsg driver
82which use the sg version 4 interface. There seems no point in renaming
83this package sg4_utils. The existing utilities just silently support either.
84Currently the source build must be able to see the /usr/include/linux/bsg.h
85file. Then at run time the /proc/devices pseudo file needs to have an entry
86for the bsg driver (appeared around lk 2.6.28). With this in place each
87utility at run time checks the device it has been given and if it is a char
88device whose major number matches the bsg entry in /proc/devices then the
89sg v4 interface is used. Otherwise the sg v3 interface is used.
90
91Utilities that wish to use the asynchronous SCSI command interface (i.e. via
92a write() read() sequence) or issue special "commands" (e.g. bus and device
93resets) still need to use the Linux sg driver. Note that various
94drivers (e.g. cdrom/sr) have different open() flag and permissions policies
95that the user may need to take into account.
96
97If users have problems or questions about them please contact the author.
98Documentation for the Linux sg device driver can be found at:
99https://sg.danny.cz/sg/p/sg_v3_ho.html . This is written in DocBook and the
100original xml can be found in the same directory with the ".xml" extension.
101Postscript and pdf renderings are also in that directory. Older documentation
102for the sg version 3 driver can be found at:
103https://sg.danny.cz/sg/p/scsi_generic_v3.txt .
104
105To save the repetition of common code (e.g. SCSI error processing) and
106reduce the size of the executable files, a shared library called
107libsgutils<num>.so (its Linux name) is created during the build process.
108That library is built from the contents of the include and lib
109subdirectories. The header files in the include subdirectory can be seen
110as the API of libsgutils and are commented with that in mind. The SCSI
111pass-through code for the supported operating systems is found in the lib
112subdirectory with names like sg_pt_linux.c and sg_pt_win32.c .
113
114Various distributions (of Linux mainly) distribute sg3_utils as 3
115installable packages. One is a package containing the shared library
116discussed above (e.g. libsgutils2-2_1.33-0.1_i386.deb). A second package
117contains the utilities (e.g. sg3-utils_1.33-0.1_i386.deb) and depends on the
118first package). Finally there is an optional package that contains header
119files and a static library (e.g. libsgutils2-dev_1.33-0.1_i386.deb). This
120final package is only needed to build other packages (e.g. sdparm) that
121wish to use the sg3_utils shared library.
122
123All the utilities in the src subdirectory have "man" pages that are
124placed in the doc subdirectory. There is also a sg3_utils (8) man page that
125summarizes common facilities including exit statuses. Additional
126information (including each utility's version number) can be found towards
127the top of each ".c" file corresponding to the utility name.
128
129The sg driver in Linux can be seen as having 3 distinct versions:
130
131   v1   lk < 2.2.6     sg_header based relatively unchanged since 1992
132   v2   lk >= 2.2.6    enhanced sg_header interface structure [1999/4/16]
133   v3   lk >= 2.4      additional sg_io_hdr interface structure [2001/1/4]
134   v3   lk >= 2.6      same interface as found in lk 2.4 [2.6.0: 2003/12/18]
135
136and the bsg driver supports the sg v4 interface and was added around
137lk 2.6.28 . This package is targeted at "v3" and "v4". Another package called
138"sg_utils" is targeted at "v2" and to a lesser extent "v1". The "sg_utils"
139package has a subset of the utilities found in this package.
140
141In Linux some sg driver ioctls (notably SG_IO) are defined for many block
142devices in lk 2.6 series. In practice this means all SCSI block devices,
143ATAPI block devices (mainly CD, DVD and BD optical devices) but _not_ ATA
144disks, depending on which kernel configuration options, can be accessed by
145the utilities in this package. SATA disks that use the libata kernel library
146(or some other SCSI to ATA Translation (SAT) Layer (SATL)) accept SCSI
147commands and thus are supported. Support for the SG_IO as been added to the
148scsi tape driver (st) in lk 2.6.6 .
149
150In the src directory the bulk of the utilities are written in relatively
151clean POSIX compliant C code with Linux specific system calls and structures
152removed and placed in Linux specific files in the lib directory. A small
153number of utilities in the src directory do contain Linux specific logic
154and are not ported to other OSes (e.g. sg_dd). One utility, sg_scan, has
155two separate implementations, one for Linux (sg_scan_linux.c) and one for
156Windows (sg_scan_win32.c). The src-lib directory split approach allows
157FreeBSD, Solaris, Tru64 and Windows specific code to be isolated to a few
158files in the lib directory whose interfaces match those of the Linux
159specific code.
160
161Darwin is not supported because the Apple folks do not want to give their
162users a pass-through SCSI interface. The author has read about creative
163hackers using a VM containing a real OS to circumvent the Apple restriction.
164
165C standard is C11
166==================
167The C code in this package is written for portability rather than speed.
168It assumes a level of C99 compliance (the C standard prior to C11) and
169favours POSIX system and library calls over OS specific calls.
170
171The C code is written in a C++ friendly way and is checked from time to
172time that it compiles clean with C++. To accommodate C++ certain C99
173constructs such as designated initializers cannot be used. To build
174with C++, C++11 (i.e. the C++ standard from 2011) or later is required.
175Finding a common C and C++ syntax for zeroing stack variables (including
176aggregates) may need to wait until C23 allows this syntax:
177   struct example_t ex1 {};
178which C++ introduced in C++11.  In the meantime the SG_C_CPP_ZERO_INIT
179define (hack) does this.
180
181The author has not seriously attempted to build this code on MSVC (aka
182Visual Studio). There are a few roadblocks (that may be overcome in the
183future) that include MSVC being basically a C++ compiler, not a C/C++
184compiler. For some reason MSVC only claims C89 compliance (i.e. the first
185C standard from 1989). MSVC 2013 and 2015 are moving closer to C99
186compliance and may be sufficient to compile this package. Another problem
187is the assumption of the availability of basic Unix system calls such as
188open(). Nearly 20 years ago Microsoft indicated (promised ?) that it
189would move in the direction of POSIX compliance, but very little ever
190happened. "Talk is cheap, there should be a tax on it."
191
192Building
193========
194This package is designed to be built with the usual:
195    "./configure ; make ; make install"
196sequence. In some situations that may need to be prefixed by a call to
197the "./autogen.sh" script which invokes autoconf and automake. That in turn
198may require packages containing those utilities to be installed. The
199libtool utility is also required. Naturally a C compiler is required
200and due to the vagaries of libtool a C++ compiler also.
201
202The "./configure" takes many command line options with the defaults
203being usually sufficient to start with. One quirk is that the location
204of the installation is under the /usr/local directory. So the sg_inq
205utility will be installed at /usr/local/bin/sg_inq . This is controlled
206by the "--prefix=<directory>" option which defaults to
207"--prefix=/usr/local". As an example to install the executables in /usr/bin
208and disable the creation of the shared library (libsgutils<num>.so) this
209invocation could be used: "./configure --prefix=/usr --disable-shared".
210To reduce the size of an executable as well try this:
211"./configure --prefix=/usr --disable-shared --disable-scsistrings".
212Also --disable-shared will produce (relatively) "static" executables in
213the src directory that are easier to debug. And
214"./configure --enable-debug" will compile with more debug type options,
215including more compiler checks and defining "DEBUG" within the src and
216lib source files. Most utilities in the src directory set '-vv' (i.e.
217equivalent to calling "--verbose" twice) when "DEBUG" is set.
218
219In Linux there are package build files for "rpm" based and for "deb" based
220systems. The 'sg3_utils.spec' file in the main directory can be used like
221this: 'rpmbuild -ba sg3_utils.spec' in a rpmbuild tree SPECS directory.
222To cross build or make a more widely distributable package then the --target
223option may be useful: 'rpmbuild --target=i386 -ba sg3_utils.spec' or
224'rpmbuild --target=x86_64 -ba sg3_utils.spec' . The sg3_utils.spec file
225in the main directory targets Red Hat systems, an alternative "spec" file
226for Suse systems has been placed under the 'suse' directory.
227
228The 'build_debian.sh' script should build several "deb" packages and place
229them in the parent directory. In debian based systems doing
230a 'apt-get install build-essential' is one way to get most of build
231environment needed if it has not already been loaded. There are now some
232problems with this script and the superseded Debian 4.0 ("etch"). See
233debian/README.debian4 for a workaround. Amongst other things debian
234builds are sensitive to the value in the debian/compat file. If it
235contains "7" then it works on lenny and gives warning on squeeze (but
236fails on the earlier etch).
237
238Warning
239=======
240Many devices use SCSI command sets over transport protocols not normally
241associated with SCSI (as defined at https://www.t10.org ). Some of these
242devices react poorly (e.g. lock up) when sent SCSI commands that they don't
243support. Even sending a supported SCSI command with a field set to an
244unexpected value can cause problems. [The author is talking about billions
245of USB devices with horrible SCSI implementations.]
246
247For example, all "SCSI" devices must support the INQUIRY command which the
248SCSI-2 standard says should request a 36 byte response. However later SCSI
249standards (e.g. SPC-2) have increased that length but some SCSI devices lock
250up when they receive a request for anything other than a 36 byte response.
251
252Any well implemented "SCSI" device should react sensibly when a utility in
253sg3_utils sends a SCSI command that it doesn't support. Unfortunately this
254cannot be guaranteed.
255
256Prior to lk 2.6.29 USB mass storage limited sense data to 18 bytes which
257caused problems for certain types of descriptor based sense data. An
258example of this is the SCSI ATA PASS-THROUGH command with the CK_COND bit
259set.
260
261
262Utilities
263=========
264Here is list in alphabetical order of utilities found in the 'src'
265subdirectory of the sg3_utils package:
266    sginfo, sg_bt_ctl, sg_compare_and_write, sg_copy_results, sgm_dd, sgp_dd,
267    sg_dd, sg_decode_sense, sg_emc_trespass, sg_format, sg_get_config,
268    sg_get_elem_status, sg_get_lba_status, sg_ident, sg_inq, sg_logs,
269    sg_luns, sg_map, sg_map26, sg_modes, sg_opcodes, sg_persist, sg_prevent,
270    sg_raw, sg_rbuf, sg_rdac, sg_read, sg_read_attr, sg_readcap,
271    sg_read_block_limits, sg_read_buffer, sg_read_long, sg_reassign,
272    sg_referrals, sg_rem_rest_elem, sg_rep_density, sg_rep_pip, sg_rep_zones,
273    sg_request, sg_reset, sg_rmsn, sg_rtpg, sg_safte, sg_sanitize,
274    sg_sat_identify, sg_sat_phy_event, sg_sat_read_gplog, sg_sat_set_features,
275    sg_scan, sg_seek, sg_senddiag, sg_ses, sg_ses_microcode, sg_start,
276    sg_stpg, sg_stream_ctl, sg_sync, sg_test_rwbuff, sg_timestamp, sg_turs,
277    sg_unmap, sg_verify, sg_vpd, sg_write_buffer, sg_write_long,
278    sg_write_same, sg_write_verify, sg_write_x, sg_wr_mode, sg_xcopy, sg_zone,
279    sg_z_act_query
280
281Each of the above utilities depends on header files found in the 'include'
282subdirectory and library code found in the 'lib' subdirectory. Associated
283man pages are found in the 'doc' subdirectory. Additional programs found
284in the 'archive', 'examples' and 'utils' subdirectories in not build by the
285top level build infrastructure. Linux binary distributions of the sg3_utils
286package (e.g. "rpm" and debian packages) typically contain the shared
287library, the utilities found in the 'src' subdirectory, their associated man
288pages and some documentation files (e.g. README, INSTALL, CREDITS, COPYING
289and COVERAGE). See the INSTALL file for generic instructions about building
290with autotools (e.g. ./configure ).
291
292Man pages can be read (without building and installing the package) by
293going to the 'doc' subdirectory and executing something like this:
294 $ man ./sg_dd.8
295
296To see which SCSI commands (and ATA commands) are used by these utilities
297refer to the COVERAGE file.
298
299Here is a list in alphabetical order of utilities found in the 'examples'
300subdirectory:
301  - sg_excl, scsi_inquiry, sg_sat_chk_power, sg__sat_identify,
302    sg__sat_phy_event, sg__sat_set_features, sg_sat_smart_rd_data,
303    sg_simple1, sg_simple2, sg_simple3, sg_simple4, sg_simple5,
304    sg_simple16
305
306Also in that subdirectory is a script to test sg_persist, an example data
307file for sg_persist (called "transport_ids.txt") and an example data file for
308sg_reassign (called "reassign_addr.txt"). There are several scripts
309for 'sg_senddiag -pf -raw=-' that will put some SAS disk phys into
310a "compliant jitter tolerance pattern" (CJTPAT).
311
312The 'testing' subdirectory contains source and a Makefiles to test
313kernel pass-through and associated drivers, mainly for Linux. There is
314both C code (with the extension ".c") and C++ code (with the extension
315".cpp"). There is a "Makefile" to build the C + C++ code. The Makefile
316depends on some object files from the "lib" subdirectory. So a sequence
317like this may be required prior to invoking make: "cd <top_of_package> ;
318./configure ; cd lib ; make ; cd ../testing".
319
320Here is a list in alphabetical order of utilities found in the 'testing'
321subdirectory:
322  - bsg_queue_tst, sgh_dd (C++), sg_iovec_tst, sg_queue_tst, sg_sense_tst,
323    sg_tst_async (C++), sg_tst_context (C++), sg_tst_excl (C++),
324    sg_tst_excl2 (C++), sg_tst_excl3 (C++)
325
326The 'utils' subdirectory contains source and a Makefile to build "hxascdmp"
327which accepts binary data from stdin (or a file on the command line) and
328outputs an ASCII-HEX and ASCII representation of it. It is similar to the
329Unix od command. There is also code to sg_chk_asc.c which checks a given
330text file (typically a copy of https://www.t10.org/lists/asc-num.txt ) and
331checks it against the asc/ascq text strings held in sg_lib_data.c .
332
333The 'doc' subdirectory contains a README file containing the urls of
334various related documents.
335
336The 'scripts' subdirectory contains some Bourne (bash) shell scripts that
337rely on utilities in the main directory. One script uses the sdparm utility.
338These scripts are described in the scripts/README file and have usage
339messages.
340
341
342Notes for utilities without man pages
343=====================================
344These utils are found in the 'examples' subdirectory.
345
346The "scsi_inquiry" program shows the use of the SCSI_IOCTL_SEND_COMMAND
347ioctl to send a SCSI INQUIRY command. That ioctl() is supported by the
348SCSI sub system mid level and so is common to all sd, sr, st and sg devices.
349That ioctl is deprecated in the lk 2.6 series. This program has been placed
350in the "examples" subdirectory.
351
352"sg_simple1" and "sg_simple2" are example programs demonstrating calls
353to the SCSI INQUIRY and TEST UNIT READY commands. They only differ in their
354error processing: sg_simple1 uses sg_lib.[hc] for error processing while
355sg_simple2 does its own more primitive checks.
356
357"sg_simple3" tests out user space scatter gather added to the version 3
358sg driver.
359
360"sg_simple4" shows the INQUIRY command using mmap-ed IO to obtain its
361response buffer.
362
363"sg_simple5" also sends and INQUIRY and TEST UNIT READY commands. It
364uses the generic pass through mechanism based on sg_pt.h . It will
365currently build in Linux and FreeBSD (with "make -f Makefile.freebsd").
366It has extensive error checking code.
367
368"sg_simple16" attempts to send a 16 byte SCSI command, READ_16, to the
369scsi device. This is only supported for lk >= 2.4.15 and for adapter
370drivers that indicate that they have 16 byte CDB capability (otherwise
371DID_ABORT will appear in the host_status).
372
373"sg_sat_chk_power" attempts to push an ATA CHECK POWER MODE command
374through the SAT-defined ATA PASS_THROUGH (16) SCSI command. That
375ATA command needs to read the "FIS" registers after the command is
376completed which involves using the ATA Status Return (sense data)
377descriptor (as defined in SAT).
378
379"sg_sat_smart_rd_data" attempts to push an ATA SMART/READ DATA command
380through the SAT-defined ATA PASS_THROUGH (16) SCSI command. If
381successful, the 256 word (512 byte) response is output.
382
383"sg_tst_excl" and "sg_tst_excl2" use multiple threads to bombard the
384given device with O_EXCL open flags, so only one should succeed at a
385time. While holding O_EXCL control a thread attempts a double increment
386on an integer in the given LBA. If the integer starts even (after the
387first read) then it should remain even if the O_EXCL flag is doing its job.
388The "sg_tst_excl" variant uses the Linux SG_IO v3 interface while the
389"sg_tst_excl2" uses the more generic sg_pt infrastructure.
390
391"sg_tst_excl3" is a variant of "sg_tst_excl2". "sg_tst_excl3" only does
392the double increment from the first thread, each time using O_EXCL on
393open. The remaining threads check the value is even, each time doing
394an open without the O_EXCL flag.
395
396"bsg_queue_tst" sends an INQUIRY command via the Linux SG_IO v4 interface
397which is used by the bsg driver. So it will take device names like
398"/dev/bsg/6:0:0:0". It tests if sending repeated INQUIRYs with
399the BSG_FLAG_Q_AT_HEAD or BSG_FLAG_Q_AT_TAIL flag makes any difference.
400
401"sg_tst_async" is a test harness for the Linux sg driver. It is multi
402threaded, submitting either TEST UNIT READY, READ(16) or WRITE(16) SCSI
403commands asynchronously. Each thread opens a file descriptor and submits
404those commands up to the queue limit (sg driver has a per file descriptor
405queue limit of 16). Multiple threads doing the same thing act as a
406multiplier to that queue limit.
407
408
409NVME Support
410============
411Firstly the author has no intention of extending this package to contain
412general purpose NVMe utilities. That leaves the areas where SCSI overlaps
413with NVMe. There was a SCSI to NVMe Translation Layer (SNTL) driver in the
414Linux kernel based on a white paper from NVM Express. Intel has withdrawn
415that driver and T10 (SCSI) and NVM Express have made no further attempts
416to standardize a SNTL. Given the SCSI to ATA Translation Layer (SATL) which
417is standardized by T10, it is pretty clear what a SNTL should do.
418
419The NVMe Management Interface (NVME-MI) committee have decided to use SES-3
420standard from T10 via the newly added SES Send and SES Receive MI commands.
421So the sg_ses utility and this package's library have been extended to use
422these commands when a NVMe device (typically a disk enclosure) is detected.
423This has been tested by a disk vendor who is happy with the results. Other
424user reports are welcome as the author does not have equipment to test
425this.
426
427Other utilities in this package that use the SES Send and Receive commands,
428or the SNTL in the library are sg_senddiag, sg_inq, sg_raw and sg_readcap.
429
430
431Command line processing
432=======================
433These utilities can be divided into 3 groups when their handling of command
434line arguments is considered:
435  - ad hoc, typically in a short form only, sometimes longer (e.g.
436    "sg_logs -pcb /dev/sdc")
437  - inspired by the dd Unix command (e.g. sg_dd, sgm_dd, sgp_dd, sg_read)
438  - recent utilities use "getopt_long" (see "man getopt_long")
439    type command lines. These have short form (starting with "-")
440    and corresponding longer form (starting with "--") options.
441
442The older utilities that use ad hoc options, in alphabetical order:
443  - sg_emc_trespass, sginfo(1/2), sg_inq, sg_logs, sg_map, sg_modes,
444    sg_opcodes, sg_rbuf, sg_rdac, sg_readcap, sg_reset, sg_scan (Linux),
445    sg_senddiag, sg_start, sg_test_rwbuf, sg_turs
446In sg3_utils version 1.23 the following utilities from this group were
447converted to have a dual getopt_long/ad_hoc interface, defaulting to
448the getop_long interface:
449  - sg_inq, sg_logs, sg_modes, sg_opcodes, sg_rbuf, sg_readcap,
450    sg_senddiag, sg_start, sg_turs
451These can be switched back to the older (backward compatible) ad hoc
452interface by defining the SG3_UTILS_OLD_OPTS environment variable
453or using '-O' as the first command line option.
454
455The more recent utilities that use "getopt_long" only are:
456  - sg_bt_ctl, sg_compare_and_write, sg_decode_sense, sg_format,
457    sg_get_config, sg_get_lba_status, sg_ident, sg_luns, sg_map26,
458    sg_persist, sg_prevent, sg_raw, sg_read_attr, sg_read_block_limits,
459    sg_read_buffer, sg_read_long, sg_reassign, sg_referrals, sg_rep_pip,
460    sg_rep_zones, sg_requests, sg_rmsn, sg_rtpg, sg_safte, sg_sanitize,
461    sg_sat_identify, sg_sat_phy_event, sg_sat_read_gplog,
462    sg_sat_set_features, sg_scan(w), sg_seek, sg_ses, sg_ses_microcode,
463    sg_stpg, sg_stream_ctl, sg_sync, sg_test_rwbuf, sg_timestamp, sg_unmap,
464    sg_verify, sg_vpd, sg_write_buffer, sg_write_long, sg_write_same,
465    sg_write_verify, sg_write_x, sg_wr_mode, sg_zone, sg_z_act_query
466
467
468Dangerous code
469==============
470This C code snippet:
471    unsigned char uc = 0x80;
472    uint64_t ull;
473    ull = (uc << 24);
474Somewhat surprisingly sets ull to:
475    ull: 0xffffffff80000000
476This result is due to the 'unary conversion' of uc to a (32 bit signed)
477'int' before the shift. The resultant type from the shift is also an int
478and it has its top bit set so there is sign extension when it is assigned
479into a 64 bit unsigned integer. Making sure there is no conversion to 'int'
480solves the problem. In this case if uc is declared as unsigned int the
481result will be as expected (i.e. 0x80000000).
482
483
484Bypassing the somewhat dangerous shift operators
485================================================
486The shift operators in C are "<<" and ">>". They can be dangerous (as shown
487in the above section) or tedious and hence error prone to use. However they
488are often needed to cope with the translation of integers on the host OS to
489the corresponding representation within a SCSI command or parameter data
490moved to or from a SCSI device. The Logical Block Address (LBA) is a good
491example; it is either 32 or 64 bits long typically (i.e. 4 or 8 bytes
492respectively). The host machine representation may be big or little endian
493and may prefer or require alignment to a particular memory address boundary
494(e.g. module 4 (or in 'C' code: "(lba % 4) == 0")). For SCSI commands and
495the parameter data moved to or from a SCSI device, the integer
496representation is big endian and it is unaligned.
497
498Recent versions of this package have replaced the explicit use of the C
499shift operators with a group of functions modelled on those found in the
500Linux kernel. These functions contain either "get_unaligned" or
501"put_unaligned" in their names and are found in the asm/unaligned.h
502header. This package contains the sg_unaligned.h header that implements
503a similar set of functions. The current implementation favours correctness
504over speed. The functions in the package use a "sg_" prefix but otherwise
505use the same function name as the Linux kernel for the same action.
506
507An example of the change made to a snippet of sg_write_buffer.c may
508clarify this change. The old code was:
509
510   wbufCmdBlk[3] = (unsigned char)((buffer_offset >> 16) & 0xff);
511   wbufCmdBlk[4] = (unsigned char)((buffer_offset >> 8) & 0xff);
512   wbufCmdBlk[5] = (unsigned char)(buffer_offset & 0xff);
513
514and it has been replaced by:
515
516   sg_put_unaligned_be24(buffer_offset, wbufCmdBlk + 3);
517
518The Linux kernel only supplies "unaligned" functions for 16, 32 and 64
519bit quantities. SCSI commands also have cases of 24 and 48 bit numbers
520so sg_unaligned.h contains support for those plus a variant where the
521byte length is passed as an argument.
522
523The unaligned functions are inlined for speed (at the possible expense of
524space) and now have specializations depending whether the host is big or
525(more likely) little endian. These functions can be broken down to a
526memcpy() and optionally a byte-swap for 16, 32 and 64 bit operations.
527The memcpy() takes care of alignment while the byte-swap (bswap_16(),
528bswap_32() and bswap_64() ) addresses integer endianness. If the host is
529little endian and a little endian variant of the unaligned functions is
530requested, then no byte-swap is required. These specializations can be
531"compiled out" with this configure option: './configure
532--disable-fast-lebe' in which case the classic "C shifting" technique is
533used to implement all the unaligned functions.
534
535Associated with the above change, fixed length integer types seem a better
536fit for SCSI command and parameter integers than the traditional integer
537types in the C language. Fixed length integer types were standardized in
538C99 and require the inclusion of <stdint.h>. For example this means for
539an integer that will represent a 64 bit LBA, to favour using "uint64_t"
540over the "unsigned long long" type. Also "unsigned char" has mostly been
541replaced by "uint8_t" as the 8 bit (unsigned) byte type; "char" is still
542used for ASCII text.
543
544
545Coding Style
546============
547Everyone has their own C/C++ coding style and the author is no different.
548In terms of the GNU indent command:
549     indent -i4 -il0 -nut -br -npcs -ncs -ce
550is pretty close. That is similar to the Linux kernel coding style but
551with 4 space indentations and no tabs.
552
553
554Other SCSI and storage tools
555============================
556See https://sg.danny.cz/sg/tools.html
557
558
559Douglas Gilbert		[email protected]
56026th August 2022
561