add sg_safte utility
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@108 6180dd3e-e324-4e3e-922d-17de1ae2f315
diff --git a/COVERAGE b/COVERAGE
index e38aa2a..e472ef9 100644
--- a/COVERAGE
+++ b/COVERAGE
@@ -34,7 +34,7 @@
READ(10) sg_dd, sgm_dd, sgp_dd, sg_read
READ(12) sg_dd, sgm_dd, sgp_dd, sg_read
READ(16) sg_dd, sgm_dd, sgp_dd, sg_read
-READ BUFFER sg_rbuf, sg_test_rwbuf, sg_read_buffer
+READ BUFFER sg_rbuf, sg_test_rwbuf, sg_read_buffer, sg_safte, ++
READ CAPACITY(10) sg_readcap, sg_dd, sgm_dd, sgp_dd, sg_format, ++
READ CAPACITY(16) sg_readcap, sg_dd, sgm_dd, sgp_dd, sg_format, ++
READ DEFECT(10) sginfo, sg_reassign('-g'), ++
@@ -61,7 +61,7 @@
WRITE(10) sg_dd, sgm_dd, sgp_dd
WRITE(12) sg_dd, sgm_dd, sgp_dd
WRITE(16) sg_dd, sgm_dd, sgp_dd
-WRITE BUFFER sg_test_rwbuf, sg_write_buffer
+WRITE BUFFER sg_test_rwbuf, sg_write_buffer, ++
WRITE LONG (10) sg_write_long, ++
WRITE LONG (16) sg_write_long, ++
@@ -87,4 +87,4 @@
Doug Gilbert
-31st August 2007
+29th September 2007
diff --git a/CREDITS b/CREDITS
index f401635..b2ccffb 100644
--- a/CREDITS
+++ b/CREDITS
@@ -29,6 +29,10 @@
Grant Grundler <grundler at parisc-linux dot org> co-author of blk512-linux
that has become sg_format [20050201]
+Hannes Reinecke <hare at suse dot de>
+ contributed sg_rdac, (and the corresponding VPD entry to
+ sg_vpd_vendor), sg_stpg and sg_safte [20070927]
+
Hayashi Naoyuki <titan at culzean dot org>
port to Tru64 [20060127]
@@ -36,7 +40,7 @@
programs for the original sg driver
Ingo van Lil <inguin at gmx dot de>
- contributed sg_raw [20070331]
+ contributed sg_raw [20070331]
James Bottomley <jejb at parisc-linux dot org> co-author of blk512-linux
that has become sg_format [20050201]
@@ -69,7 +73,7 @@
Saeed Bishara contributed sg_write_long
Thomas Kolbe <tkolbe at partnersdata dot com>
- Solaris port help and testing [20070503]
+ Solaris port help and testing [20070503]
Tim Hunt <tim at timhunt dot net> increased number of (sd and sg) devices
that sginfo could detect.
@@ -82,4 +86,4 @@
Doug Gilbert
-16th July 2007
+27th September 2007
diff --git a/ChangeLog b/ChangeLog
index ea91a7f..072d4a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,8 +2,9 @@
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for sg3_utils-1.25 [20070926]
+Changelog for sg3_utils-1.25 [20070929]
- sg_stpg: new utility to Set Target Port Groups
+ - sg_safte: new utility to query SAF-TE processor (SES like)
- sg_cmds_extra: add sg_ll_set_tgt_prt_grp()
- sg_sat_set_features: new utility (actually copied from examples
directory); renamed examples version: sg__sat_set_features
diff --git a/README b/README
index 97e4b9c..06286c7 100644
--- a/README
+++ b/README
@@ -152,7 +152,7 @@
sg_format, sg_ident, sg_inq, sg_logs, sg_luns, sg_map, sg_map26,
sg_modes, sg_opcodes, sg_persist, sg_prevent, sg_raw, sg_rbuf, sg_rdac,
sg_read, sg_readcap, sg_read_buffer, sg_read_long, sg_reassign,
- sg_request, sg_reset, sg_rmsn, sg_rtpg, sg_sat_identify,
+ sg_request, sg_reset, sg_rmsn, sg_rtpg, sg_safte, sg_sat_identify,
sg_sat_set_features, sg_scan, sg_senddiag, sg_ses, sg_start, sg_stpg,
sg_sync, sg_test_rwbuff, sg_turs, sg_verify, sg_vpd, sg_write_buffer,
sg_write_long, sg_wr_mode
@@ -286,7 +286,7 @@
The more recent utilities that use "getopt_long" only are:
- sg_format sg_get_config sg_ident sg_luns sg_map26 sg_persist
sg_prevent sg_raw sg_read_buffer sg_read_long sg_reassign sg_requests
- sg_rmsn sg_rtpg sg_sat_identify sg_sat_set_features
+ sg_rmsn sg_rtpg sg_sat_identify sg_safte sg_sat_set_features
sg_sat_set_features sg_scan(w) sg_ses sg_stpg sg_sync sg_test_rwbuf
sg_verify sg_vpd sg_write_buffer sg_write_long sg_wr_mode
@@ -327,4 +327,4 @@
Doug Gilbert
-26th September 2007
+29th September 2007
diff --git a/README.freebsd b/README.freebsd
index b880ae0..dbe9ba0 100644
--- a/README.freebsd
+++ b/README.freebsd
@@ -27,7 +27,9 @@
sg_requests
sg_rmsn
sg_rtpg
+ sg_safte
sg_sat_identify
+ sg_sat_set_features
sg_senddiag
sg_ses
sg_start
@@ -82,4 +84,4 @@
Doug Gilbert
-31st August 2007
+29th September 2007
diff --git a/README.solaris b/README.solaris
index d229653..b94eee4 100644
--- a/README.solaris
+++ b/README.solaris
@@ -27,7 +27,9 @@
sg_requests
sg_rmsn
sg_rtpg
+ sg_safte
sg_sat_identify
+ sg_sat_set_features
sg_senddiag
sg_ses
sg_start
@@ -76,4 +78,4 @@
Doug Gilbert
-31st August 2007
+29th September 2007
diff --git a/README.tru64 b/README.tru64
index fb7023f..3c6db4b 100644
--- a/README.tru64
+++ b/README.tru64
@@ -27,7 +27,9 @@
sg_requests
sg_rmsn
sg_rtpg
+ sg_safte
sg_sat_identify
+ sg_sat_set_features
sg_senddiag
sg_ses
sg_start
@@ -81,4 +83,4 @@
Doug Gilbert
-31st August 2007
+29th September 2007
diff --git a/README.win32 b/README.win32
index 4a9b489..f806bc6 100644
--- a/README.win32
+++ b/README.win32
@@ -38,7 +38,9 @@
sg_requests
sg_rmsn
sg_rtpg
+ sg_safte
sg_sat_identify
+ sg_sat_set_features
sg_scan [this is Windows specific]
sg_senddiag
sg_ses
@@ -130,4 +132,4 @@
Doug Gilbert
-31st August 2007
+29th September 2007
diff --git a/debian/changelog b/debian/changelog
index d9c258f..f6dbed9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@
* New upstream version
- -- Doug Gilbert <[email protected]> Wed, 26 Sep 2007 23:00:00 -0400
+ -- Doug Gilbert <[email protected]> Sat, 29 Sep 2007 01:00:00 -0400
sg3-utils (1.24-1) unstable; urgency=low
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 91f67d4..284ec50 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -14,7 +14,7 @@
sgm_dd.8 sg_modes.8 sg_opcodes.8 sgp_dd.8 sg_persist.8 \
sg_prevent.8 sg_raw.8 sg_rbuf.8 sg_rdac.8 sg_read.8 sg_readcap.8 \
sg_read_buffer.8 sg_read_long.8 sg_reassign.8 sg_requests.8 \
- sg_reset.8 sg_rmsn.8 sg_rtpg.8 sg_sat_identify.8 \
+ sg_reset.8 sg_rmsn.8 sg_rtpg.8 sg_safte.8 sg_sat_identify.8 \
sg_sat_set_features.8 sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 \
sg_stpg.8 sg_sync.8 sg_test_rwbuf.8 sg_turs.8 sg_verify.8 sg_vpd.8 \
sg_write_buffer.8 sg_write_long.8 sg_wr_mode.8
@@ -31,8 +31,8 @@
sg_modes.8 sg_opcodes.8 sg_persist.8 \
sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 sg_read_buffer.8 \
sg_read_long.8 sg_reassign.8 sg_requests.8 sg_rmsn.8 \
- sg_rtpg.8 sg_sat_identify.8 sg_sat_set_features.8 sg_scan.8 \
- sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
+ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_set_features.8 \
+ sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
sg_turs.8 sg_verify.8 sg_vpd.8 sg_write_buffer.8 sg_write_long.8 \
sg_wr_mode.8
@@ -48,8 +48,8 @@
sg_modes.8 sg_opcodes.8 sg_persist.8 \
sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 sg_read_buffer.8 \
sg_read_long.8 sg_reassign.8 sg_requests.8 sg_rmsn.8 \
- sg_rtpg.8 sg_sat_identify.8 sg_sat_set_features.8 sg_scan.8 \
- sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
+ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_set_features.8 \
+ sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
sg_turs.8 sg_verify.8 sg_vpd.8 sg_write_buffer.8 sg_write_long.8 \
sg_wr_mode.8
@@ -65,7 +65,7 @@
sg_modes.8 sg_opcodes.8 sg_persist.8 \
sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 sg_read_buffer.8 \
sg_read_long.8 sg_reassign.8 sg_requests.8 sg_rmsn.8 \
- sg_rtpg.8 sg_sat_identify.8 sg_sat_set_features.8 \
+ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_set_features.8 \
sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
sg_turs.8 sg_verify.8 sg_vpd.8 sg_write_buffer.8 sg_write_long.8 \
sg_wr_mode.8
@@ -82,7 +82,7 @@
sg_modes.8 sg_opcodes.8 sg_persist.8 \
sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 sg_read_buffer.8 \
sg_read_long.8 sg_reassign.8 sg_requests.8 sg_rmsn.8 \
- sg_rtpg.8 sg_sat_identify.8 sg_sat_set_features.8 \
+ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_set_features.8 \
sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
sg_turs.8 sg_verify.8 sg_vpd.8 sg_write_buffer.8 sg_write_long.8 \
sg_wr_mode.8
@@ -99,7 +99,7 @@
sg_modes.8 sg_opcodes.8 sg_persist.8 \
sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 sg_read_buffer.8 \
sg_read_long.8 sg_reassign.8 sg_requests.8 sg_rmsn.8 \
- sg_rtpg.8 sg_sat_identify.8 sg_sat_set_features.8 \
+ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_set_features.8 \
sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
sg_turs.8 sg_verify.8 sg_vpd.8 sg_write_buffer.8 sg_write_long.8 \
sg_wr_mode.8
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 75786cb..3b424b6 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -162,7 +162,7 @@
@OS_FREEBSD_TRUE@ sg_modes.8 sg_opcodes.8 sg_persist.8 \
@OS_FREEBSD_TRUE@ sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 sg_read_buffer.8 \
@OS_FREEBSD_TRUE@ sg_read_long.8 sg_reassign.8 sg_requests.8 sg_rmsn.8 \
-@OS_FREEBSD_TRUE@ sg_rtpg.8 sg_sat_identify.8 sg_sat_set_features.8 \
+@OS_FREEBSD_TRUE@ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_set_features.8 \
@OS_FREEBSD_TRUE@ sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
@OS_FREEBSD_TRUE@ sg_turs.8 sg_verify.8 sg_vpd.8 sg_write_buffer.8 sg_write_long.8 \
@OS_FREEBSD_TRUE@ sg_wr_mode.8
@@ -180,7 +180,7 @@
@OS_LINUX_TRUE@ sgm_dd.8 sg_modes.8 sg_opcodes.8 sgp_dd.8 sg_persist.8 \
@OS_LINUX_TRUE@ sg_prevent.8 sg_raw.8 sg_rbuf.8 sg_rdac.8 sg_read.8 sg_readcap.8 \
@OS_LINUX_TRUE@ sg_read_buffer.8 sg_read_long.8 sg_reassign.8 sg_requests.8 \
-@OS_LINUX_TRUE@ sg_reset.8 sg_rmsn.8 sg_rtpg.8 sg_sat_identify.8 \
+@OS_LINUX_TRUE@ sg_reset.8 sg_rmsn.8 sg_rtpg.8 sg_safte.8 sg_sat_identify.8 \
@OS_LINUX_TRUE@ sg_sat_set_features.8 sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 \
@OS_LINUX_TRUE@ sg_stpg.8 sg_sync.8 sg_test_rwbuf.8 sg_turs.8 sg_verify.8 sg_vpd.8 \
@OS_LINUX_TRUE@ sg_write_buffer.8 sg_write_long.8 sg_wr_mode.8
@@ -192,7 +192,7 @@
@OS_OSF_TRUE@ sg_modes.8 sg_opcodes.8 sg_persist.8 \
@OS_OSF_TRUE@ sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 sg_read_buffer.8 \
@OS_OSF_TRUE@ sg_read_long.8 sg_reassign.8 sg_requests.8 sg_rmsn.8 \
-@OS_OSF_TRUE@ sg_rtpg.8 sg_sat_identify.8 sg_sat_set_features.8 \
+@OS_OSF_TRUE@ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_set_features.8 \
@OS_OSF_TRUE@ sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
@OS_OSF_TRUE@ sg_turs.8 sg_verify.8 sg_vpd.8 sg_write_buffer.8 sg_write_long.8 \
@OS_OSF_TRUE@ sg_wr_mode.8
@@ -204,7 +204,7 @@
@OS_SOLARIS_TRUE@ sg_modes.8 sg_opcodes.8 sg_persist.8 \
@OS_SOLARIS_TRUE@ sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 sg_read_buffer.8 \
@OS_SOLARIS_TRUE@ sg_read_long.8 sg_reassign.8 sg_requests.8 sg_rmsn.8 \
-@OS_SOLARIS_TRUE@ sg_rtpg.8 sg_sat_identify.8 sg_sat_set_features.8 \
+@OS_SOLARIS_TRUE@ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_set_features.8 \
@OS_SOLARIS_TRUE@ sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
@OS_SOLARIS_TRUE@ sg_turs.8 sg_verify.8 sg_vpd.8 sg_write_buffer.8 sg_write_long.8 \
@OS_SOLARIS_TRUE@ sg_wr_mode.8
@@ -216,8 +216,8 @@
@OS_WIN32_CYGWIN_TRUE@ sg_modes.8 sg_opcodes.8 sg_persist.8 \
@OS_WIN32_CYGWIN_TRUE@ sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 sg_read_buffer.8 \
@OS_WIN32_CYGWIN_TRUE@ sg_read_long.8 sg_reassign.8 sg_requests.8 sg_rmsn.8 \
-@OS_WIN32_CYGWIN_TRUE@ sg_rtpg.8 sg_sat_identify.8 sg_sat_set_features.8 sg_scan.8 \
-@OS_WIN32_CYGWIN_TRUE@ sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
+@OS_WIN32_CYGWIN_TRUE@ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_set_features.8 \
+@OS_WIN32_CYGWIN_TRUE@ sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
@OS_WIN32_CYGWIN_TRUE@ sg_turs.8 sg_verify.8 sg_vpd.8 sg_write_buffer.8 sg_write_long.8 \
@OS_WIN32_CYGWIN_TRUE@ sg_wr_mode.8
@@ -228,8 +228,8 @@
@OS_WIN32_MINGW_TRUE@ sg_modes.8 sg_opcodes.8 sg_persist.8 \
@OS_WIN32_MINGW_TRUE@ sg_prevent.8 sg_raw.8 sg_rdac.8 sg_readcap.8 sg_read_buffer.8 \
@OS_WIN32_MINGW_TRUE@ sg_read_long.8 sg_reassign.8 sg_requests.8 sg_rmsn.8 \
-@OS_WIN32_MINGW_TRUE@ sg_rtpg.8 sg_sat_identify.8 sg_sat_set_features.8 sg_scan.8 \
-@OS_WIN32_MINGW_TRUE@ sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
+@OS_WIN32_MINGW_TRUE@ sg_rtpg.8 sg_safte.8 sg_sat_identify.8 sg_sat_set_features.8 \
+@OS_WIN32_MINGW_TRUE@ sg_scan.8 sg_senddiag.8 sg_ses.8 sg_start.8 sg_stpg.8 sg_sync.8 \
@OS_WIN32_MINGW_TRUE@ sg_turs.8 sg_verify.8 sg_vpd.8 sg_write_buffer.8 sg_write_long.8 \
@OS_WIN32_MINGW_TRUE@ sg_wr_mode.8
diff --git a/doc/sg_safte.8 b/doc/sg_safte.8
new file mode 100644
index 0000000..f71f0e0
--- /dev/null
+++ b/doc/sg_safte.8
@@ -0,0 +1,118 @@
+.TH SG_SAFTE "8" "September 2007" "sg3_utils\-1.25" SG3_UTILS
+.SH NAME
+sg_safte \- Fetch status from a SCSI Accessed Fault\-Tolerant Enclosure
+(SAF\-TE) device
+.SH SYNOPSIS
+.B sg_safte
+[\fI\-\-config\fR] [\fI\-\-devstatus\fR] [\fI\-\-encstatus\fR]
+[\fI\-\-flags\fR] [\fI\-\-help\fR] [\fI\-\-insertions\fR]
+[\fI\-\-usage\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR] \fIDEVICE\fR
+.SH DESCRIPTION
+.\" Add any additional description here
+.PP
+Fetches enclosure status (via a SCSI READ BUFFER command).
+The \fIDEVICE\fR should be a SAF\-TE device which may be a storage
+array controller (INQUIRY peripheral device type 0xc) or a generic
+processor device (INQUIRY peripheral device type 0x3).
+.PP
+If no options are given (only the \fIDEVICE\fR argument) then the
+overall enclosure status as reported by the option
+.I
+\-\-config
+.R
+is reported.
+.SH OPTIONS
+Arguments to long options are mandatory for short options as well.
+.TP
+\fB\-c\fR, \fB\-\-config\fR
+will issues a
+.I
+Read Enclosure Configuration
+.R
+(READ BUFFER ID 0) cdb to the device, which returns a list of the
+enclosure hardware resources.
+.TP
+\fB\-d\fR, \fB\-\-devstatus\fR
+will issue a
+.I
+Read Device Slot Status
+.R
+(READ BUFFER ID 4) cdb to the device, which returns information about
+the current state of each drive or slot.
+.TP
+\fB\-s\fR, \fB\-\-encstatus\fR
+will issue a
+.I
+Read Enclosure Status
+.R
+(READ BUFFER ID 1) cdb to the device, which returns the operational
+state of the components.
+.TP
+\fB\-f\fR, \fB\-\-flags\fR
+will issue a
+.I
+Read Global Flags
+.R
+(READ BUFFER ID 5) cdb to the device, which read the most recent state
+of the global flags of the RAID processor device.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+output the usage message then exit.
+.TP
+\fB\-i\fR, \fB\-\-insertions\fR
+will issue a
+.I
+Read Device Insertions
+.R
+(READ BUFFER ID 3) cdb to the device, which returns information about
+the number of times devices have been inserted whilst the RAID system
+was powered on.
+.TP
+\fB\-u\fR, \fB\-\-usage\fR
+will issue a
+.I
+Read Usage Statistics
+.R
+(READ BUFFER ID 2) cdb to the device, which returns the information on
+total usage time and number of power\-on cycles of the RAID device.
+.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
+The implementation is based on the intermediate review document eg as
+found at
+.PP
+http://www.intel.com/design/servers/ipmi/saf\-te.htm
+.PP
+As the specification was never finalized this document serves as the
+de\-facto standard.
+.PP
+A similar functionality is provided by the SPC\-4 SCSI Enclosure
+Services devices (Peripheral device type 0xd), which can be queried
+with the sg_ses utility.
+.SH EXAMPLES
+To view the configuration:
+.PP
+ sg_safte /dev/sg1
+.PP
+To view the device slot status:
+.PP
+ sg_safte \-\-devstatus /dev/sg1
+.PP
+.SH EXIT STATUS
+The exit status of sg_ses is 0 when it is successful. Otherwise see
+the sg3_utils(8) man page.
+.SH AUTHORS
+Written by Hannes Reinecke and Douglas Gilbert.
+.SH "REPORTING BUGS"
+Report bugs to <dgilbert at interlog dot com>.
+.SH COPYRIGHT
+Copyright \(co 2004\-2007 Hannes Reinecke and 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_inq, sg_ses (in sg3_utils package)
diff --git a/sg3_utils.spec b/sg3_utils.spec
index 184ccc8..c3e72a9 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,8 +79,8 @@
%{_libdir}/*.la
%changelog
-* Wed Sep 26 2007 - dgilbert at interlog dot com
-- add sg_sat_set_features, sg_stpg; sg_dd oflag=sparse,null
+* Sat Sep 29 2007 - dgilbert at interlog dot com
+- add sg_sat_set_features, sg_stpg, sg_safte; sg_dd oflag=sparse,null
* sg3_utils-1.25
* Mon May 07 2007 - dgilbert at interlog dot com
diff --git a/src/Makefile.am b/src/Makefile.am
index 4edf7c2..0726b16 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,10 +13,10 @@
sgm_dd sg_modes sg_opcodes sgp_dd sg_persist \
sg_prevent sg_raw sg_rbuf sg_rdac sg_read sg_readcap \
sg_read_buffer sg_read_long sg_reassign sg_requests \
- sg_reset sg_rmsn sg_rtpg sg_sat_identify sg_sat_set_features \
- sg_scan sg_senddiag sg_ses sg_start sg_stpg sg_sync sg_test_rwbuf \
- sg_turs sg_verify sg_vpd sg_write_buffer sg_write_long \
- sg_wr_mode
+ sg_reset sg_rmsn sg_rtpg sg_safte sg_sat_identify \
+ sg_sat_set_features sg_scan sg_senddiag sg_ses sg_start sg_stpg \
+ sg_sync sg_test_rwbuf sg_turs sg_verify sg_vpd sg_write_buffer \
+ sg_write_long sg_wr_mode
endif
@@ -29,7 +29,7 @@
sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap \
sg_read_buffer sg_read_long sg_reassign sg_requests sg_rmsn \
- sg_rtpg sg_sat_identify sg_sat_set_features sg_scan \
+ sg_rtpg sg_safte sg_sat_identify sg_sat_set_features sg_scan \
sg_senddiag sg_ses sg_start sg_stpg sg_sync \
sg_turs sg_verify sg_vpd sg_write_buffer sg_write_long \
sg_wr_mode
@@ -45,7 +45,7 @@
sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap \
sg_read_buffer sg_read_long sg_reassign sg_requests sg_rmsn \
- sg_rtpg sg_sat_identify sg_sat_set_features sg_scan \
+ sg_rtpg sg_safte sg_sat_identify sg_sat_set_features sg_scan \
sg_senddiag sg_ses sg_start sg_stpg sg_sync \
sg_turs sg_verify sg_vpd sg_write_buffer sg_write_long \
sg_wr_mode
@@ -61,7 +61,7 @@
sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap \
sg_read_buffer sg_read_long sg_reassign sg_requests sg_rmsn \
- sg_rtpg sg_sat_identify sg_sat_set_features \
+ sg_rtpg sg_safte sg_sat_identify sg_sat_set_features \
sg_senddiag sg_ses sg_start sg_stpg sg_sync \
sg_turs sg_verify sg_vpd sg_write_buffer sg_write_long \
sg_wr_mode
@@ -77,7 +77,7 @@
sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap \
sg_read_buffer sg_read_long sg_reassign sg_requests sg_rmsn \
- sg_rtpg sg_sat_identify sg_sat_set_features \
+ sg_rtpg sg_safte sg_sat_identify sg_sat_set_features \
sg_senddiag sg_ses sg_start sg_stpg sg_sync \
sg_turs sg_verify sg_vpd sg_write_buffer sg_write_long \
sg_wr_mode
@@ -93,7 +93,7 @@
sg_modes sg_opcodes sg_persist \
sg_prevent sg_raw sg_rdac sg_readcap \
sg_read_buffer sg_read_long sg_reassign sg_requests sg_rmsn \
- sg_rtpg sg_sat_identify sg_sat_set_features \
+ sg_rtpg sg_safte sg_sat_identify sg_sat_set_features \
sg_senddiag sg_ses sg_start sg_stpg sg_sync \
sg_turs sg_verify sg_vpd sg_write_buffer sg_write_long \
sg_wr_mode
@@ -191,6 +191,9 @@
sg_rtpg_SOURCES = sg_rtpg.c
sg_rtpg_LDADD = ../lib/libsgutils.la @os_libs@
+sg_safte_SOURCES = sg_safte.c
+sg_safte_LDADD = ../lib/libsgutils.la @os_libs@
+
sg_sat_identify_SOURCES = sg_sat_identify.c
sg_sat_identify_LDADD = ../lib/libsgutils.la @os_libs@
diff --git a/src/Makefile.in b/src/Makefile.in
index 9a4d091..dfadda5 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -51,6 +51,7 @@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_requests$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_rmsn$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_rtpg$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_safte$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_sat_set_features$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_scan$(EXEEXT) \
@@ -84,6 +85,7 @@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_requests$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_rmsn$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_rtpg$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_safte$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_sat_set_features$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_scan$(EXEEXT) \
@@ -117,6 +119,7 @@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_requests$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_rmsn$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_rtpg$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_safte$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_sat_set_features$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_senddiag$(EXEEXT) \
@@ -149,6 +152,7 @@
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_requests$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_rmsn$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_rtpg$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_safte$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_sat_set_features$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_senddiag$(EXEEXT) \
@@ -191,6 +195,7 @@
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_reset$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_rmsn$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_rtpg$(EXEEXT) \
+@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_safte$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_sat_set_features$(EXEEXT) \
@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_scan$(EXEEXT) \
@@ -216,7 +221,7 @@
@OS_FREEBSD_TRUE@ sg_read_buffer$(EXEEXT) sg_read_long$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_reassign$(EXEEXT) sg_requests$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_rmsn$(EXEEXT) sg_rtpg$(EXEEXT) \
-@OS_FREEBSD_TRUE@ sg_sat_identify$(EXEEXT) \
+@OS_FREEBSD_TRUE@ sg_safte$(EXEEXT) sg_sat_identify$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_sat_set_features$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_senddiag$(EXEEXT) sg_ses$(EXEEXT) \
@OS_FREEBSD_TRUE@ sg_start$(EXEEXT) sg_stpg$(EXEEXT) \
@@ -314,6 +319,9 @@
am_sg_rtpg_OBJECTS = sg_rtpg.$(OBJEXT)
sg_rtpg_OBJECTS = $(am_sg_rtpg_OBJECTS)
sg_rtpg_DEPENDENCIES = ../lib/libsgutils.la
+am_sg_safte_OBJECTS = sg_safte.$(OBJEXT)
+sg_safte_OBJECTS = $(am_sg_safte_OBJECTS)
+sg_safte_DEPENDENCIES = ../lib/libsgutils.la
am_sg_sat_identify_OBJECTS = sg_sat_identify.$(OBJEXT)
sg_sat_identify_OBJECTS = $(am_sg_sat_identify_OBJECTS)
sg_sat_identify_DEPENDENCIES = ../lib/libsgutils.la
@@ -391,14 +399,14 @@
$(sg_read_buffer_SOURCES) $(sg_read_long_SOURCES) \
$(sg_readcap_SOURCES) $(sg_reassign_SOURCES) \
$(sg_requests_SOURCES) $(sg_reset_SOURCES) $(sg_rmsn_SOURCES) \
- $(sg_rtpg_SOURCES) $(sg_sat_identify_SOURCES) \
- $(sg_sat_set_features_SOURCES) $(sg_scan_SOURCES) \
- $(sg_senddiag_SOURCES) $(sg_ses_SOURCES) $(sg_start_SOURCES) \
- $(sg_stpg_SOURCES) $(sg_sync_SOURCES) $(sg_test_rwbuf_SOURCES) \
- $(sg_turs_SOURCES) $(sg_verify_SOURCES) $(sg_vpd_SOURCES) \
- $(sg_wr_mode_SOURCES) $(sg_write_buffer_SOURCES) \
- $(sg_write_long_SOURCES) $(sginfo_SOURCES) $(sgm_dd_SOURCES) \
- $(sgp_dd_SOURCES)
+ $(sg_rtpg_SOURCES) $(sg_safte_SOURCES) \
+ $(sg_sat_identify_SOURCES) $(sg_sat_set_features_SOURCES) \
+ $(sg_scan_SOURCES) $(sg_senddiag_SOURCES) $(sg_ses_SOURCES) \
+ $(sg_start_SOURCES) $(sg_stpg_SOURCES) $(sg_sync_SOURCES) \
+ $(sg_test_rwbuf_SOURCES) $(sg_turs_SOURCES) \
+ $(sg_verify_SOURCES) $(sg_vpd_SOURCES) $(sg_wr_mode_SOURCES) \
+ $(sg_write_buffer_SOURCES) $(sg_write_long_SOURCES) \
+ $(sginfo_SOURCES) $(sgm_dd_SOURCES) $(sgp_dd_SOURCES)
DIST_SOURCES = $(sg_dd_SOURCES) $(sg_emc_trespass_SOURCES) \
$(sg_format_SOURCES) $(sg_get_config_SOURCES) \
$(sg_ident_SOURCES) $(sg_inq_SOURCES) $(sg_logs_SOURCES) \
@@ -409,14 +417,14 @@
$(sg_read_buffer_SOURCES) $(sg_read_long_SOURCES) \
$(sg_readcap_SOURCES) $(sg_reassign_SOURCES) \
$(sg_requests_SOURCES) $(sg_reset_SOURCES) $(sg_rmsn_SOURCES) \
- $(sg_rtpg_SOURCES) $(sg_sat_identify_SOURCES) \
- $(sg_sat_set_features_SOURCES) $(sg_scan_SOURCES) \
- $(sg_senddiag_SOURCES) $(sg_ses_SOURCES) $(sg_start_SOURCES) \
- $(sg_stpg_SOURCES) $(sg_sync_SOURCES) $(sg_test_rwbuf_SOURCES) \
- $(sg_turs_SOURCES) $(sg_verify_SOURCES) $(sg_vpd_SOURCES) \
- $(sg_wr_mode_SOURCES) $(sg_write_buffer_SOURCES) \
- $(sg_write_long_SOURCES) $(sginfo_SOURCES) $(sgm_dd_SOURCES) \
- $(sgp_dd_SOURCES)
+ $(sg_rtpg_SOURCES) $(sg_safte_SOURCES) \
+ $(sg_sat_identify_SOURCES) $(sg_sat_set_features_SOURCES) \
+ $(sg_scan_SOURCES) $(sg_senddiag_SOURCES) $(sg_ses_SOURCES) \
+ $(sg_start_SOURCES) $(sg_stpg_SOURCES) $(sg_sync_SOURCES) \
+ $(sg_test_rwbuf_SOURCES) $(sg_turs_SOURCES) \
+ $(sg_verify_SOURCES) $(sg_vpd_SOURCES) $(sg_wr_mode_SOURCES) \
+ $(sg_write_buffer_SOURCES) $(sg_write_long_SOURCES) \
+ $(sginfo_SOURCES) $(sgm_dd_SOURCES) $(sgp_dd_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -588,6 +596,8 @@
sg_rmsn_LDADD = ../lib/libsgutils.la @os_libs@
sg_rtpg_SOURCES = sg_rtpg.c
sg_rtpg_LDADD = ../lib/libsgutils.la @os_libs@
+sg_safte_SOURCES = sg_safte.c
+sg_safte_LDADD = ../lib/libsgutils.la @os_libs@
sg_sat_identify_SOURCES = sg_sat_identify.c
sg_sat_identify_LDADD = ../lib/libsgutils.la @os_libs@
sg_sat_set_features_SOURCES = sg_sat_set_features.c
@@ -757,6 +767,9 @@
sg_rtpg$(EXEEXT): $(sg_rtpg_OBJECTS) $(sg_rtpg_DEPENDENCIES)
@rm -f sg_rtpg$(EXEEXT)
$(LINK) $(sg_rtpg_OBJECTS) $(sg_rtpg_LDADD) $(LIBS)
+sg_safte$(EXEEXT): $(sg_safte_OBJECTS) $(sg_safte_DEPENDENCIES)
+ @rm -f sg_safte$(EXEEXT)
+ $(LINK) $(sg_safte_OBJECTS) $(sg_safte_LDADD) $(LIBS)
sg_sat_identify$(EXEEXT): $(sg_sat_identify_OBJECTS) $(sg_sat_identify_DEPENDENCIES)
@rm -f sg_sat_identify$(EXEEXT)
$(LINK) $(sg_sat_identify_OBJECTS) $(sg_sat_identify_LDADD) $(LIBS)
@@ -845,6 +858,7 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_reset.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_rmsn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_rtpg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_safte.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_sat_identify.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_sat_set_features.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_scan.Po@am__quote@
diff --git a/src/sg_safte.c b/src/sg_safte.c
new file mode 100644
index 0000000..941ed4f
--- /dev/null
+++ b/src/sg_safte.c
@@ -0,0 +1,654 @@
+/*
+ * Copyright (c) 2004-2007 Hannes Reinecke and Douglas Gilbert.
+ * 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.
+ *
+ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <getopt.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "sg_lib.h"
+#include "sg_cmds_basic.h"
+#include "sg_cmds_extra.h"
+
+/* A utility program for the Linux OS SCSI subsystem.
+ *
+ * This program accesses a processor device which operates according
+ * to the 'SCSI Accessed Fault-Tolerant Enclosures' (SAF-TE) spec.
+ */
+
+static char * version_str = "0.21 20070929";
+
+
+#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define DEF_TIMEOUT 60000 /* 60,000 millisecs == 60 seconds */
+#define EBUFF_SZ 256
+
+#define RB_MODE_DESC 3
+#define RWB_MODE_DATA 2
+#define RWB_MODE_VENDOR 1
+#define RB_DESC_LEN 4
+
+#define SAFTE_CFG_FLAG_DOORLOCK 1
+#define SAFTE_CFG_FLAG_ALARM 2
+#define SAFTE_CFG_FLAG_CELSIUS 3
+
+struct safte_cfg_t {
+ int fans;
+ int psupplies;
+ int slots;
+ int temps;
+ int thermostats;
+ int vendor_specific;
+ int flags;
+};
+
+struct safte_cfg_t safte_cfg;
+
+static int peri_type = 0; /* ugly but not easy to pass to alpha compare */
+static unsigned int buf_capacity = 64;
+
+/* Buffer ID 0x0: Read Enclosure Configuration (mandatory) */
+static int read_safte_configuration (int sg_fd, unsigned char *rb_buff,
+ unsigned int rb_len, int verbose)
+{
+ int res;
+
+ if (rb_len < buf_capacity) {
+ fprintf(stderr,"SCSI BUFFER size too small (%d/%d bytes)\n",
+ rb_len, buf_capacity);
+ return SG_LIB_CAT_ILLEGAL_REQ;
+ }
+
+ res = sg_ll_read_buffer(sg_fd, RWB_MODE_VENDOR, 0, 0,
+ rb_buff, rb_len, 1, verbose);
+ if (res && res != SG_LIB_CAT_RECOVERED)
+ return res;
+
+ safte_cfg.fans = rb_buff[0];
+ safte_cfg.psupplies = rb_buff[1];
+ safte_cfg.slots = rb_buff[2];
+ safte_cfg.temps = rb_buff[4];
+ if (rb_buff[3])
+ safte_cfg.flags |= SAFTE_CFG_FLAG_DOORLOCK;
+ if (rb_buff[5])
+ safte_cfg.flags |= SAFTE_CFG_FLAG_ALARM;
+ if (rb_buff[6] & 0x80)
+ safte_cfg.flags |= SAFTE_CFG_FLAG_CELSIUS;
+
+ safte_cfg.thermostats = rb_buff[6] & 0x0f;
+ safte_cfg.vendor_specific = rb_buff[63];
+
+ return 0;
+}
+
+static int print_safte_configuration (void)
+{
+ printf("Enclosure Configuration:\n");
+ printf("\tNumber of Fans: %d\n", safte_cfg.fans);
+ printf("\tNumber of Power Supplies: %d\n", safte_cfg.psupplies);
+ printf("\tNumber of Device Slots: %d\n", safte_cfg.slots);
+ printf("\tNumber of Temperature Sensors: %d\n", safte_cfg.temps);
+ printf("\tNumber of Thermostats: %d\n", safte_cfg.thermostats);
+ printf("\tVendor unique bytes: %d\n", safte_cfg.vendor_specific);
+
+ return 0;
+}
+
+/* Buffer ID 0x01: Read Enclosure Status (mandatory) */
+static int do_safte_encl_status (int sg_fd, int verbose)
+{
+ int res, i, offset;
+ unsigned int rb_len;
+ unsigned char *rb_buff;
+
+ rb_len = safte_cfg.fans + safte_cfg.psupplies + safte_cfg.slots +
+ safte_cfg.temps + 5 + safte_cfg.vendor_specific;
+ rb_buff = (unsigned char *)malloc(rb_len);
+
+
+ res = sg_ll_read_buffer(sg_fd, RWB_MODE_VENDOR, 1, 0,
+ rb_buff, rb_len, 0, verbose);
+ if (res && res != SG_LIB_CAT_RECOVERED)
+ return res;
+
+ printf("Enclosure Status:\n");
+ offset = 0;
+ for (i = 0; i < safte_cfg.fans; i++) {
+ printf("\tFan %d status: ", i);
+ switch(rb_buff[i]) {
+ case 0:
+ printf("operational\n");
+ break;
+ case 1:
+ printf("malfunctioning\n");
+ break;
+ case 2:
+ printf("not installed\n");
+ break;
+ case 80:
+ printf("not reportable\n");
+ break;
+ default:
+ printf("unknown\n");
+ break;
+ }
+ }
+
+ offset += safte_cfg.fans;
+ for (i = 0; i < safte_cfg.psupplies; i++) {
+ printf("\tPower supply %d status: ", i);
+ switch(rb_buff[i + offset]) {
+ case 0:
+ printf("operational / on\n");
+ break;
+ case 1:
+ printf("operational / off\n");
+ break;
+ case 0x10:
+ printf("malfunctioning / on\n");
+ break;
+ case 0x11:
+ printf("malfunctioning / off\n");
+ break;
+ case 0x20:
+ printf("not present\n");
+ break;
+ case 0x21:
+ printf("present\n");
+ break;
+ case 0x80:
+ printf("not reportable\n");
+ break;
+ default:
+ printf("unknown\n");
+ break;
+ }
+ }
+
+ offset += safte_cfg.psupplies;
+ for (i = 0; i < safte_cfg.slots; i++) {
+ printf("\tDevice Slot %d: SCSI ID %d\n", i, rb_buff[i + offset]);
+ }
+
+ offset += safte_cfg.slots;
+ if (safte_cfg.flags & SAFTE_CFG_FLAG_DOORLOCK) {
+ switch(rb_buff[offset]) {
+ case 0x0:
+ printf("\tDoor lock status: locked\n");
+ break;
+ case 0x01:
+ printf("\tDoor lock status: unlocked\n");
+ break;
+ case 0x80:
+ printf("\tDoor lock status: not reportable\n");
+ break;
+ }
+ } else {
+ printf("\tDoor lock status: not installed\n");
+ }
+
+ offset++;
+ if (!(safte_cfg.flags & SAFTE_CFG_FLAG_ALARM)) {
+ printf("\tSpeaker status: not installed\n");
+ } else {
+ switch(rb_buff[offset]) {
+ case 0x0:
+ printf("\tSpeaker status: off\n");
+ break;
+ case 0x01:
+ printf("\tSpeaker status: on\n");
+ break;
+ }
+ }
+
+ offset++;
+ for (i = 0; i < safte_cfg.temps; i++) {
+ int temp = 0;
+
+ if (!(safte_cfg.flags & SAFTE_CFG_FLAG_CELSIUS))
+ temp -= 10;
+
+ printf("\tTemperature sensor %d: %d deg %c\n", i, rb_buff[i + offset],
+ safte_cfg.flags & SAFTE_CFG_FLAG_CELSIUS?'C':'F');
+ }
+
+ offset += safte_cfg.temps;
+ if (safte_cfg.thermostats) {
+ if (rb_buff[offset] & 0x80) {
+ printf("\tEnclosure Temperature alert status: abnormal\n");
+ } else {
+ printf("\tEnclosure Temperature alert status: normal\n");
+ }
+ }
+ return 0;
+}
+
+/* Buffer ID 0x02: Read Usage Statistics (optional) */
+static int do_safte_usage_statistics (int sg_fd, int verbose)
+{
+ int res;
+ unsigned int rb_len;
+ unsigned char *rb_buff;
+ unsigned long minutes;
+
+ rb_len = 16 + safte_cfg.vendor_specific;
+ rb_buff = (unsigned char *)malloc(rb_len);
+
+ res = sg_ll_read_buffer(sg_fd, RWB_MODE_VENDOR, 2, 0,
+ rb_buff, rb_len, 0, verbose);
+ if (res) {
+ if (res == SG_LIB_CAT_ILLEGAL_REQ) {
+ printf("Usage Statistics:\n\tNot implemented\n");
+ return 0;
+ }
+ if (res != SG_LIB_CAT_RECOVERED) {
+ free(rb_buff);
+ return res;
+ }
+ }
+
+ printf("Usage Statistics:\n");
+ minutes = (rb_buff[0] << 24) + (rb_buff[1] << 16) +
+ (rb_buff[2] << 8) + rb_buff[3];
+ printf("\tPower on Minutes: %ld\n", minutes);
+ minutes = (rb_buff[4] << 24) + (rb_buff[5] << 16) +
+ (rb_buff[6] << 8) + rb_buff[7];
+ printf("\tPower on Cycles: %ld\n", minutes);
+
+ free(rb_buff);
+ return 0;
+}
+
+/* Buffer ID 0x03: Read Device Insertions (optional) */
+static int do_safte_slot_insertions (int sg_fd, int verbose)
+{
+ int res, i;
+ unsigned int rb_len;
+ unsigned char *rb_buff, slot_status;
+
+ rb_len = safte_cfg.slots * 2;
+ rb_buff = (unsigned char *)malloc(rb_len);
+
+ res = sg_ll_read_buffer(sg_fd, RWB_MODE_VENDOR, 3, 0,
+ rb_buff, rb_len, 0, verbose);
+ if (res ) {
+ if (res == SG_LIB_CAT_ILLEGAL_REQ) {
+ printf("Slot insertions:\n\tNot implemented\n");
+ return 0;
+ }
+ if (res != SG_LIB_CAT_RECOVERED) {
+ free(rb_buff);
+ return res;
+ }
+ }
+
+ printf("Slot insertions:\n");
+ for (i = 0; i < safte_cfg.slots; i++) {
+ slot_status = (rb_buff[i * 2] << 8) + rb_buff[i * 2];
+ printf("\tSlot %d: %d insertions", i, slot_status);
+ }
+ free(rb_buff);
+ return 0;
+}
+
+/* Buffer ID 0x04: Read Device Slot Status (mandatory) */
+static int do_safte_slot_status (int sg_fd, int verbose)
+{
+ int res, i;
+ unsigned int rb_len;
+ unsigned char *rb_buff, slot_status;
+
+ rb_len = safte_cfg.slots * 4;
+ rb_buff = (unsigned char *)malloc(rb_len);
+
+ res = sg_ll_read_buffer(sg_fd, RWB_MODE_VENDOR, 4, 0,
+ rb_buff, rb_len, 0, verbose);
+ if (res && res != SG_LIB_CAT_RECOVERED) {
+ free(rb_buff);
+ return res;
+ }
+
+ printf("Slot status:\n");
+ for (i = 0; i < safte_cfg.slots; i++) {
+ slot_status = rb_buff[i * 4 + 3];
+ printf("\tSlot %d: ", i);
+ if (slot_status & 0x7) {
+ if (slot_status & 0x1)
+ printf("inserted ");
+ if (slot_status & 0x2)
+ printf("ready ");
+ if (slot_status & 0x4)
+ printf("activated ");
+ printf("\n");
+ } else {
+ printf("empty\n");
+ }
+ }
+ free(rb_buff);
+ return 0;
+}
+
+/* Buffer ID 0x05: Read Global Flags (optional) */
+static int do_safte_global_flags (int sg_fd, int verbose)
+{
+ int res;
+ unsigned int rb_len;
+ unsigned char *rb_buff;
+
+ rb_len = 16;
+ rb_buff = (unsigned char *)malloc(rb_len);
+
+ res = sg_ll_read_buffer(sg_fd, RWB_MODE_VENDOR, 5, 0,
+ rb_buff, rb_len, 0, verbose);
+ if (res ) {
+ if (res == SG_LIB_CAT_ILLEGAL_REQ) {
+ printf("Global Flags:\n\tNot implemented\n");
+ return 0;
+ }
+ if (res != SG_LIB_CAT_RECOVERED) {
+ free(rb_buff);
+ return res;
+ }
+ }
+
+ printf("Global Flags:\n");
+ printf("\tAudible Alarm Control: %s\n",
+ rb_buff[0] & 0x1?"on":"off");
+ printf("\tGlobal Failure Indicator: %s\n",
+ rb_buff[0] & 0x2?"on":"off");
+ printf("\tGlobal Warning Indicator: %s\n",
+ rb_buff[0] & 0x4?"on":"off");
+ printf("\tEnclosure Power: %s\n",
+ rb_buff[0] & 0x8?"on":"off");
+ printf("\tCooling Failure: %s\n",
+ rb_buff[0] & 0x10?"yes":"no");
+ printf("\tPower Failure: %s\n",
+ rb_buff[0] & 0x20?"yes":"no");
+ printf("\tDrive Failure: %s\n",
+ rb_buff[0] & 0x40?"yes":"no");
+ printf("\tDrive Warning: %s\n",
+ rb_buff[0] & 0x80?"yes":"no");
+ printf("\tArray Failure: %s\n",
+ rb_buff[1] & 0x1?"yes":"no");
+ printf("\tArray Warning: %s\n",
+ rb_buff[0] & 0x2?"yes":"no");
+ printf("\tEnclosre Lock: %s\n",
+ rb_buff[0] & 0x4?"on":"off");
+ printf("\tEnclosre Identify: %s\n",
+ rb_buff[0] & 0x8?"on":"off");
+
+ free(rb_buff);
+ return 0;
+}
+
+static void usage()
+{
+ fprintf(stderr,
+ "Usage: sg_safte [--config] [--devstatus] [--encstatus] "
+ "[--flags] [--help]\n"
+ " [--insertions] [--usage] [--verbose] "
+ "[--version] DEVICE\n"
+ " where:\n"
+ " --config|-c output enclosure configuration\n"
+ " --devstatus|-d output device slot status\n"
+ " --encstatus|-s output enclosure status\n"
+ " --flags|-f output global flags\n"
+ " --help|-h output command usage message then "
+ "exit\n"
+ " --insertions|-i output insertion statistics\n"
+ " --usage|-u output usage statistics\n"
+ " --verbose|-v increase verbosity\n"
+ " --version|-v output version then exit\n\n"
+ "Queries a SAF-TE processor device\n");
+}
+
+static struct option long_options[] = {
+ {"config", 0, 0, 'c'},
+ {"devstatus", 0, 0, 'd'},
+ {"encstatus", 0, 0, 's'},
+ {"flags", 0, 0, 'f'},
+ {"help", 0, 0, 'h'},
+ {"insertions", 0, 0, 'i'},
+ {"usage", 0, 0, 'u'},
+ {"verbose", 0, 0, 'v'},
+ {"version", 0, 0, 'V'},
+ {0, 0, 0, 0},
+};
+
+int main(int argc, char * argv[])
+{
+ int sg_fd, c, res = SG_LIB_CAT_OTHER;
+ const char * device_name = NULL;
+ char ebuff[EBUFF_SZ];
+ unsigned char *rb_buff;
+ int do_config = 0;
+ int do_status = 0;
+ int do_slots = 0;
+ int do_flags = 0;
+ int do_usage = 0;
+ int verbose = 0;
+ int do_insertions = 0;
+ const char * cp;
+ char buff[48];
+ struct sg_simple_inquiry_resp inq_resp;
+ const char op_name[] = "READ BUFFER";
+
+ while (1) {
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "cdfhisuvV?", long_options,
+ &option_index);
+
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'c':
+ do_config = 1;
+ break;
+ case 'd':
+ do_slots = 1;
+ break;
+ case 'f':
+ do_flags = 1;
+ break;
+ case 'h':
+ case '?':
+ usage();
+ return 0;
+ case 'i':
+ do_insertions = 1;
+ break;
+ case 's':
+ do_status = 1;
+ break;
+ case 'u':
+ do_usage = 1;
+ break;
+ case 'v':
+ ++verbose;
+ break;
+ case 'V':
+ fprintf(stderr, "Version string: %s\n", version_str);
+ exit(0);
+ default:
+ fprintf(stderr, "unrecognised option code 0x%x ??\n", c);
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+ if (optind < argc) {
+ if (NULL == device_name) {
+ device_name = argv[optind];
+ ++optind;
+ }
+ if (optind < argc) {
+ for (; optind < argc; ++optind)
+ fprintf(stderr, "Unexpected extra argument: %s\n",
+ argv[optind]);
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+
+ if (NULL == device_name) {
+ fprintf(stderr, "missing device name!\n");
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+
+ if ((sg_fd = sg_cmds_open_device(device_name, 0 /* rw */, verbose)) < 0) {
+ snprintf(ebuff, EBUFF_SZ, "sg_safte: error opening file: %s (ro)",
+ device_name);
+ perror(ebuff);
+ return SG_LIB_FILE_ERROR;
+ }
+
+ if (0 == sg_simple_inquiry(sg_fd, &inq_resp, 1, verbose)) {
+ printf(" %.8s %.16s %.4s\n", inq_resp.vendor, inq_resp.product,
+ inq_resp.revision);
+ peri_type = inq_resp.peripheral_type;
+ cp = sg_get_pdt_str(peri_type, sizeof(buff), buff);
+ if (strlen(cp) > 0)
+ printf(" Peripheral device type: %s\n", cp);
+ else
+ printf(" Peripheral device type: 0x%x\n", peri_type);
+ } else {
+ printf("sg_safte: %s doesn't respond to a SCSI INQUIRY\n", device_name);
+ return SG_LIB_CAT_OTHER;
+ }
+
+ rb_buff = (unsigned char *)malloc(buf_capacity);
+ if (!rb_buff)
+ goto err_out;
+
+ memset(rb_buff, 0, buf_capacity);
+
+ res = read_safte_configuration(sg_fd, rb_buff, buf_capacity, verbose);
+ switch (res) {
+ case 0:
+ case SG_LIB_CAT_RECOVERED:
+ break;
+ default:
+ goto err_out;
+ }
+
+ if (do_config)
+ print_safte_configuration();
+
+ if (do_status) {
+ res = do_safte_encl_status(sg_fd, verbose);
+ switch (res) {
+ case 0:
+ case SG_LIB_CAT_RECOVERED:
+ break;
+ default:
+ goto err_out;
+ }
+ }
+
+ if (do_usage) {
+ res = do_safte_usage_statistics(sg_fd, verbose);
+ switch (res) {
+ case 0:
+ case SG_LIB_CAT_RECOVERED:
+ break;
+ default:
+ goto err_out;
+ }
+ }
+
+ if (do_insertions) {
+ res = do_safte_slot_insertions(sg_fd, verbose);
+ switch (res) {
+ case 0:
+ case SG_LIB_CAT_RECOVERED:
+ break;
+ default:
+ goto err_out;
+ }
+ }
+
+ if (do_slots) {
+ res = do_safte_slot_status(sg_fd, verbose);
+ switch (res) {
+ case 0:
+ case SG_LIB_CAT_RECOVERED:
+ break;
+ default:
+ goto err_out;
+ }
+ }
+
+ if (do_flags) {
+ res = do_safte_global_flags(sg_fd, verbose);
+ switch (res) {
+ case 0:
+ case SG_LIB_CAT_RECOVERED:
+ break;
+ default:
+ goto err_out;
+ }
+ }
+ res = 0;
+
+err_out:
+ switch (res) {
+ case 0:
+ case SG_LIB_CAT_RECOVERED:
+ break;
+ case SG_LIB_CAT_ABORTED_COMMAND:
+ fprintf(stderr, "%s: aborted command\n", op_name);
+ break;
+ case SG_LIB_CAT_NOT_READY:
+ fprintf(stderr, "%s: device not ready\n", op_name);
+ break;
+ case SG_LIB_CAT_UNIT_ATTENTION:
+ fprintf(stderr, "%s: unit attention\n", op_name);
+ break;
+ case SG_LIB_CAT_INVALID_OP:
+ fprintf(stderr, "%s: operation not supported\n", op_name);
+ break;
+ case SG_LIB_CAT_ILLEGAL_REQ:
+ fprintf(stderr, "%s: bad field in cdb\n", op_name);
+ break;
+ default:
+ fprintf(stderr, "%s failed\n", op_name);
+ break;
+ }
+
+ res = sg_cmds_close_device(sg_fd);
+ return res;
+}