aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2007-09-29 13:51:35 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2007-09-29 13:51:35 +0000
commit084021ad040f99cd63d06d1da64e6a5848bba2a2 (patch)
treefb85a991b74d7ed65acae39ccc6a373bc78a1eae
parent7d27a2728146c647e4a048a02603485bf7afb5b0 (diff)
downloadsg3_utils-084021ad040f99cd63d06d1da64e6a5848bba2a2.tar.gz
add sg_safte utility
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@108 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--COVERAGE6
-rw-r--r--CREDITS10
-rw-r--r--ChangeLog3
-rw-r--r--README6
-rw-r--r--README.freebsd4
-rw-r--r--README.solaris4
-rw-r--r--README.tru644
-rw-r--r--README.win324
-rw-r--r--debian/changelog2
-rw-r--r--doc/Makefile.am16
-rw-r--r--doc/Makefile.in16
-rw-r--r--doc/sg_safte.8118
-rw-r--r--sg3_utils.spec4
-rw-r--r--src/Makefile.am21
-rw-r--r--src/Makefile.in48
-rw-r--r--src/sg_safte.c654
16 files changed, 861 insertions, 59 deletions
diff --git a/COVERAGE b/COVERAGE
index e38aa2a9..e472ef93 100644
--- a/COVERAGE
+++ b/COVERAGE
@@ -34,7 +34,7 @@ READ(6) sg_dd, sgm_dd, sgp_dd, sg_read
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(6) sg_dd, sgm_dd, sgp_dd
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 @@ SMART READ DATA examples/sg_sat_smart_rd_data
Doug Gilbert
-31st August 2007
+29th September 2007
diff --git a/CREDITS b/CREDITS
index f401635e..b2ccffbb 100644
--- a/CREDITS
+++ b/CREDITS
@@ -29,6 +29,10 @@ F. Jansen: additions to sg_scan
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 @@ Heiko Eissfeldt <heiko at colossus dot escape dot de> sg based example
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 @@ Peter Allworth <linsol at zeta dot org dot au> original dd clone design used
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 @@ Trent Piepho <xyzzy at speakeasy dot org> print out some "sense key specific"
Doug Gilbert
-16th July 2007
+27th September 2007
diff --git a/ChangeLog b/ChangeLog
index ea91a7f5..072d4a57 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,8 +2,9 @@ Each utility has its own version number, date of last change and
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 97e4b9cd..06286c74 100644
--- a/README
+++ b/README
@@ -152,7 +152,7 @@ subdirectory of the sg3_utils package:
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 @@ or using '-O' as the first command line option.
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 @@ See http://www.torque.net/sg/tools.html
Doug Gilbert
-26th September 2007
+29th September 2007
diff --git a/README.freebsd b/README.freebsd
index b880ae04..dbe9ba06 100644
--- a/README.freebsd
+++ b/README.freebsd
@@ -27,7 +27,9 @@ Here is a list of utilities that have been ported:
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 @@ See the FreeBSD section in the INSTALL file for install directions.
Doug Gilbert
-31st August 2007
+29th September 2007
diff --git a/README.solaris b/README.solaris
index d2296539..b94eee49 100644
--- a/README.solaris
+++ b/README.solaris
@@ -27,7 +27,9 @@ Here is a list of utilities that have been ported:
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 @@ See the Solaris section in the INSTALL file for install directions.
Doug Gilbert
-31st August 2007
+29th September 2007
diff --git a/README.tru64 b/README.tru64
index fb7023f8..3c6db4b3 100644
--- a/README.tru64
+++ b/README.tru64
@@ -27,7 +27,9 @@ Here is a list of utilities that have been ported:
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 @@ subdirectory. Currently only the Tru64 port uses it.
Doug Gilbert
-31st August 2007
+29th September 2007
diff --git a/README.win32 b/README.win32
index 4a9b489b..f806bc6d 100644
--- a/README.win32
+++ b/README.win32
@@ -38,7 +38,9 @@ Here is a list of utilities that have been ported:
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 @@ See the INSTALL file for more details.
Doug Gilbert
-31st August 2007
+29th September 2007
diff --git a/debian/changelog b/debian/changelog
index d9c258f8..f6dbed9b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.25-0.1) unstable; urgency=low
* New upstream version
- -- Doug Gilbert <dgilbert@interlog.com> Wed, 26 Sep 2007 23:00:00 -0400
+ -- Doug Gilbert <dgilbert@interlog.com> 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 91f67d45..284ec50b 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -14,7 +14,7 @@ man_MANS = \
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 @@ man_MANS = \
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 @@ man_MANS = \
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 @@ man_MANS = \
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 @@ man_MANS = \
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 @@ man_MANS = \
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 75786cbf..3b424b63 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -162,7 +162,7 @@ top_srcdir = @top_srcdir@
@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 @@ top_srcdir = @top_srcdir@
@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 @@ top_srcdir = @top_srcdir@
@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 @@ top_srcdir = @top_srcdir@
@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 @@ top_srcdir = @top_srcdir@
@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 @@ top_srcdir = @top_srcdir@
@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 00000000..f71f0e06
--- /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 184ccc89..c3e72a9b 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,8 +79,8 @@ fi
%{_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 4edf7c22..0726b165 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,10 +13,10 @@ bin_PROGRAMS = \
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 @@ bin_PROGRAMS = \
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 @@ bin_PROGRAMS = \
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 @@ bin_PROGRAMS = \
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 @@ bin_PROGRAMS = \
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 @@ bin_PROGRAMS = \
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_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@
diff --git a/src/Makefile.in b/src/Makefile.in
index 9a4d0918..dfadda54 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -51,6 +51,7 @@ host_triplet = @host@
@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 @@ host_triplet = @host@
@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 @@ host_triplet = @host@
@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 @@ host_triplet = @host@
@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 @@ host_triplet = @host@
@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 @@ host_triplet = @host@
@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 @@ sg_rmsn_DEPENDENCIES = ../lib/libsgutils.la
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 @@ SOURCES = $(sg_dd_SOURCES) $(sg_emc_trespass_SOURCES) \
$(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 @@ DIST_SOURCES = $(sg_dd_SOURCES) $(sg_emc_trespass_SOURCES) \
$(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_SOURCES = sg_rmsn.c
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_rmsn$(EXEEXT): $(sg_rmsn_OBJECTS) $(sg_rmsn_DEPENDENCIES)
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 @@ distclean-compile:
@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 00000000..941ed4f4
--- /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;
+}