diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2014-05-27 23:26:04 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2014-05-27 23:26:04 +0000 |
commit | 4d770f100b237146adc51e9f4bdd194e83252d50 (patch) | |
tree | fa2f096759f5d40aadd57d15e3798fb2a796b859 /src | |
parent | eebe59ce63d30da476a04e294a3c06ff5ae20aab (diff) | |
download | sg3_utils-4d770f100b237146adc51e9f4bdd194e83252d50.tar.gz |
new utils: sg_rep_zones+sg_reset_wp; new Linux udev scripts; sg_inq --export work; sg_logs lto5+6 work
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@584 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 99 | ||||
-rw-r--r-- | src/Makefile.in | 59 | ||||
-rw-r--r-- | src/sg_inq.c | 116 | ||||
-rw-r--r-- | src/sg_inq_data.c | 2 | ||||
-rw-r--r-- | src/sg_logs.c | 196 | ||||
-rw-r--r-- | src/sg_rep_zones.c | 451 | ||||
-rw-r--r-- | src/sg_reset_wp.c | 257 | ||||
-rw-r--r-- | src/sg_vpd.c | 10 |
8 files changed, 981 insertions, 209 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index b4f2eb7a..50b1fa3b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,11 +13,12 @@ bin_PROGRAMS = \ sg_ident sginfo sg_inq sg_logs sg_luns sg_map26 sg_map sgm_dd \ sg_modes sg_opcodes sgp_dd sg_persist sg_prevent sg_raw sg_rbuf \ sg_rdac sg_read sg_readcap sg_read_block_limits sg_read_buffer \ - sg_read_long sg_reassign sg_referrals sg_requests sg_reset sg_rmsn \ - sg_rtpg sg_safte sg_sanitize sg_sat_identify sg_sat_phy_event \ - sg_sat_set_features sg_scan sg_senddiag sg_ses sg_start sg_stpg \ - sg_sync sg_test_rwbuf sg_turs sg_unmap sg_verify sg_vpd \ - sg_write_buffer sg_write_long sg_write_same sg_wr_mode sg_xcopy + sg_read_long sg_reassign sg_referrals sg_rep_zones sg_requests \ + sg_reset sg_reset_wp sg_rmsn sg_rtpg sg_safte sg_sanitize \ + sg_sat_identify sg_sat_phy_event sg_sat_set_features sg_scan \ + sg_senddiag sg_ses sg_start sg_stpg sg_sync sg_test_rwbuf sg_turs \ + sg_unmap sg_verify sg_vpd sg_write_buffer sg_write_long \ + sg_write_same sg_wr_mode sg_xcopy distclean-local: rm -f sg_scan.c @@ -35,11 +36,11 @@ bin_PROGRAMS = \ sg_get_lba_status sg_ident sg_inq sg_logs sg_luns sg_modes \ sg_opcodes sg_persist sg_prevent sg_raw sg_rdac sg_readcap \ sg_read_block_limits sg_read_buffer sg_read_long sg_reassign \ - sg_referrals sg_requests sg_rmsn sg_rtpg sg_safte sg_sanitize \ - sg_sat_identify sg_sat_phy_event sg_sat_set_features sg_scan \ - sg_senddiag sg_ses sg_start sg_stpg sg_sync sg_turs sg_unmap \ - sg_verify sg_vpd sg_write_buffer sg_write_long sg_write_same \ - sg_wr_mode + sg_referrals sg_rep_zones sg_requests sg_reset_wp sg_rmsn \ + sg_rtpg sg_safte sg_sanitize sg_sat_identify sg_sat_phy_event \ + sg_sat_set_features sg_scan sg_senddiag sg_ses sg_start sg_stpg \ + sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \ + sg_write_long sg_write_same sg_wr_mode distclean-local: rm -f sg_scan.c @@ -53,15 +54,15 @@ endif if OS_WIN32_CYGWIN bin_PROGRAMS = \ - sg_compare_and_write \ - sg_decode_sense sg_format sg_get_config sg_get_lba_status sg_ident \ - sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \ - sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \ - sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \ - sg_rmsn sg_rtpg sg_safte sg_sanitize sg_sat_identify \ - sg_sat_phy_event sg_sat_set_features sg_scan sg_senddiag sg_ses \ - sg_start sg_stpg sg_sync sg_turs sg_unmap sg_verify sg_vpd \ - sg_write_buffer sg_write_long sg_write_same sg_wr_mode + sg_compare_and_write sg_decode_sense sg_format sg_get_config \ + sg_get_lba_status sg_ident sg_inq sg_logs sg_luns sg_modes \ + sg_opcodes sg_persist sg_prevent sg_raw sg_rdac sg_readcap \ + sg_read_block_limits sg_read_buffer sg_read_long sg_reassign \ + sg_referrals sg_rep_zones sg_requests sg_reset_wp sg_rmsn \ + sg_rtpg sg_safte sg_sanitize sg_sat_identify sg_sat_phy_event \ + sg_sat_set_features sg_scan sg_senddiag sg_ses sg_start sg_stpg \ + sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \ + sg_write_long sg_write_same sg_wr_mode distclean-local: rm -f sg_scan.c @@ -75,15 +76,15 @@ endif if OS_FREEBSD bin_PROGRAMS = \ - sg_compare_and_write \ - sg_decode_sense sg_format sg_get_config sg_get_lba_status sg_ident \ - sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \ - sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \ - sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \ - sg_rmsn sg_rtpg sg_safte sg_sanitize sg_sat_identify \ - sg_sat_phy_event sg_sat_set_features sg_senddiag sg_ses sg_start \ - sg_stpg sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \ - sg_write_long sg_write_same sg_wr_mode + sg_compare_and_write sg_decode_sense sg_format sg_get_config \ + sg_get_lba_status sg_ident sg_inq sg_logs sg_luns sg_modes \ + sg_opcodes sg_persist sg_prevent sg_raw sg_rdac sg_readcap + sg_read_block_limits sg_read_buffer sg_read_long sg_reassign \ + sg_referrals sg_rep_zones sg_requests sg_reset_wp sg_rmsn \ + sg_rtpg sg_safte sg_sanitize sg_sat_identify sg_sat_phy_event \ + sg_sat_set_features sg_senddiag sg_ses sg_start sg_stpg sg_sync \ + sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer sg_write_long \ + sg_write_same sg_wr_mode endif @@ -91,15 +92,15 @@ endif if OS_SOLARIS bin_PROGRAMS = \ - sg_compare_and_write \ - sg_decode_sense sg_format sg_get_config sg_get_lba_status sg_ident \ - sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \ - sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \ - sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \ - sg_rmsn sg_rtpg sg_safte sg_sanitize sg_sat_identify \ - sg_sat_phy_event sg_sat_set_features sg_senddiag sg_ses sg_start \ - sg_stpg sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \ - sg_write_long sg_write_same sg_wr_mode + sg_compare_and_write sg_decode_sense sg_format sg_get_config \ + sg_get_lba_status sg_ident sg_inq sg_logs sg_luns sg_modes \ + sg_opcodes sg_persist sg_prevent sg_raw sg_rdac sg_readcap \ + sg_read_block_limits sg_read_buffer sg_read_long sg_reassign \ + sg_referrals sg_rep_zones sg_requests sg_reset_wp sg_rmsn \ + sg_rtpg sg_safte sg_sanitize sg_sat_identify sg_sat_phy_event \ + sg_sat_set_features sg_senddiag sg_ses sg_start sg_stpg sg_sync \ + sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer sg_write_long \ + sg_write_same sg_wr_mode endif @@ -107,15 +108,15 @@ endif if OS_OSF bin_PROGRAMS = \ - sg_compare_and_write \ - sg_decode_sense sg_format sg_get_config sg_get_lba_status sg_ident \ - sg_inq sg_logs sg_luns sg_modes sg_opcodes sg_persist \ - sg_prevent sg_raw sg_rdac sg_readcap sg_read_block_limits \ - sg_read_buffer sg_read_long sg_reassign sg_referrals sg_requests \ - sg_rmsn sg_rtpg sg_safte sg_sanitize sg_sat_identify \ - sg_sat_phy_event sg_sat_set_features sg_senddiag sg_ses sg_start \ - sg_stpg sg_sync sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer \ - sg_write_long sg_write_same sg_wr_mode + sg_compare_and_write sg_decode_sense sg_format sg_get_config \ + sg_get_lba_status sg_ident sg_inq sg_logs sg_luns sg_modes \ + sg_opcodes sg_persist sg_prevent sg_raw sg_rdac sg_readcap \ + sg_read_block_limits sg_read_buffer sg_read_long sg_reassign \ + sg_referrals sg_rep_zones sg_requests sg_reset_wp sg_rmsn \ + sg_rtpg sg_safte sg_sanitize sg_sat_identify sg_sat_phy_event \ + sg_sat_set_features sg_senddiag sg_ses sg_start sg_stpg sg_sync \ + sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer sg_write_long \ + sg_write_same sg_wr_mode endif @@ -297,3 +298,9 @@ sg_copy_results_LDADD = ../lib/libsgutils2.la @os_libs@ sg_compare_and_write_SOURCES = sg_compare_and_write.c sg_compare_and_write_LDADD = ../lib/libsgutils2.la @os_libs@ + +sg_rep_zones_SOURCES = sg_rep_zones.c +sg_rep_zones_LDADD = ../lib/libsgutils2.la @os_libs@ + +sg_reset_wp_SOURCES = sg_reset_wp.c +sg_reset_wp_LDADD = ../lib/libsgutils2.la @os_libs@ diff --git a/src/Makefile.in b/src/Makefile.in index b7f3e00a..0c496526 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -99,7 +99,9 @@ host_triplet = @host@ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_read_long$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_reassign$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_referrals$(EXEEXT) \ +@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_FALSE@@OS_WIN32_MINGW_TRUE@ sg_rep_zones$(EXEEXT) \ @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_reset_wp$(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) \ @@ -142,7 +144,9 @@ host_triplet = @host@ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_read_long$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_reassign$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_referrals$(EXEEXT) \ +@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_FALSE@@OS_WIN32_CYGWIN_TRUE@ sg_rep_zones$(EXEEXT) \ @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_reset_wp$(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) \ @@ -185,7 +189,9 @@ host_triplet = @host@ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_read_long$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_reassign$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_referrals$(EXEEXT) \ +@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_FALSE@@OS_SOLARIS_TRUE@ sg_rep_zones$(EXEEXT) \ @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_reset_wp$(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) \ @@ -227,7 +233,9 @@ host_triplet = @host@ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_read_long$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_reassign$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_referrals$(EXEEXT) \ +@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_rep_zones$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_requests$(EXEEXT) \ +@OS_FREEBSD_FALSE@@OS_LINUX_FALSE@@OS_OSF_TRUE@ sg_reset_wp$(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) \ @@ -279,8 +287,10 @@ host_triplet = @host@ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_read_long$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_reassign$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_referrals$(EXEEXT) \ +@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_rep_zones$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_requests$(EXEEXT) \ @OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_reset$(EXEEXT) \ +@OS_FREEBSD_FALSE@@OS_LINUX_TRUE@ sg_reset_wp$(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) \ @@ -312,22 +322,7 @@ host_triplet = @host@ @OS_FREEBSD_TRUE@ sg_luns$(EXEEXT) sg_modes$(EXEEXT) \ @OS_FREEBSD_TRUE@ sg_opcodes$(EXEEXT) sg_persist$(EXEEXT) \ @OS_FREEBSD_TRUE@ sg_prevent$(EXEEXT) sg_raw$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_rdac$(EXEEXT) sg_readcap$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_read_block_limits$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_read_buffer$(EXEEXT) sg_read_long$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_reassign$(EXEEXT) sg_referrals$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_requests$(EXEEXT) sg_rmsn$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_rtpg$(EXEEXT) sg_safte$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_sanitize$(EXEEXT) sg_sat_identify$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_sat_phy_event$(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) \ -@OS_FREEBSD_TRUE@ sg_sync$(EXEEXT) sg_turs$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_unmap$(EXEEXT) sg_verify$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_vpd$(EXEEXT) sg_write_buffer$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_write_long$(EXEEXT) sg_write_same$(EXEEXT) \ -@OS_FREEBSD_TRUE@ sg_wr_mode$(EXEEXT) +@OS_FREEBSD_TRUE@ sg_rdac$(EXEEXT) sg_readcap$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -429,12 +424,18 @@ sg_reassign_DEPENDENCIES = ../lib/libsgutils2.la am_sg_referrals_OBJECTS = sg_referrals.$(OBJEXT) sg_referrals_OBJECTS = $(am_sg_referrals_OBJECTS) sg_referrals_DEPENDENCIES = ../lib/libsgutils2.la +am_sg_rep_zones_OBJECTS = sg_rep_zones.$(OBJEXT) +sg_rep_zones_OBJECTS = $(am_sg_rep_zones_OBJECTS) +sg_rep_zones_DEPENDENCIES = ../lib/libsgutils2.la am_sg_requests_OBJECTS = sg_requests.$(OBJEXT) sg_requests_OBJECTS = $(am_sg_requests_OBJECTS) sg_requests_DEPENDENCIES = ../lib/libsgutils2.la am_sg_reset_OBJECTS = sg_reset.$(OBJEXT) sg_reset_OBJECTS = $(am_sg_reset_OBJECTS) sg_reset_DEPENDENCIES = +am_sg_reset_wp_OBJECTS = sg_reset_wp.$(OBJEXT) +sg_reset_wp_OBJECTS = $(am_sg_reset_wp_OBJECTS) +sg_reset_wp_DEPENDENCIES = ../lib/libsgutils2.la am_sg_rmsn_OBJECTS = sg_rmsn.$(OBJEXT) sg_rmsn_OBJECTS = $(am_sg_rmsn_OBJECTS) sg_rmsn_DEPENDENCIES = ../lib/libsgutils2.la @@ -559,7 +560,8 @@ SOURCES = $(sg_compare_and_write_SOURCES) $(sg_copy_results_SOURCES) \ $(sg_read_block_limits_SOURCES) $(sg_read_buffer_SOURCES) \ $(sg_read_long_SOURCES) $(sg_readcap_SOURCES) \ $(sg_reassign_SOURCES) $(sg_referrals_SOURCES) \ - $(sg_requests_SOURCES) $(sg_reset_SOURCES) $(sg_rmsn_SOURCES) \ + $(sg_rep_zones_SOURCES) $(sg_requests_SOURCES) \ + $(sg_reset_SOURCES) $(sg_reset_wp_SOURCES) $(sg_rmsn_SOURCES) \ $(sg_rtpg_SOURCES) $(sg_safte_SOURCES) $(sg_sanitize_SOURCES) \ $(sg_sat_identify_SOURCES) $(sg_sat_phy_event_SOURCES) \ $(sg_sat_set_features_SOURCES) $(sg_scan_SOURCES) \ @@ -583,7 +585,8 @@ DIST_SOURCES = $(sg_compare_and_write_SOURCES) \ $(sg_read_block_limits_SOURCES) $(sg_read_buffer_SOURCES) \ $(sg_read_long_SOURCES) $(sg_readcap_SOURCES) \ $(sg_reassign_SOURCES) $(sg_referrals_SOURCES) \ - $(sg_requests_SOURCES) $(sg_reset_SOURCES) $(sg_rmsn_SOURCES) \ + $(sg_rep_zones_SOURCES) $(sg_requests_SOURCES) \ + $(sg_reset_SOURCES) $(sg_reset_wp_SOURCES) $(sg_rmsn_SOURCES) \ $(sg_rtpg_SOURCES) $(sg_safte_SOURCES) $(sg_sanitize_SOURCES) \ $(sg_sat_identify_SOURCES) $(sg_sat_phy_event_SOURCES) \ $(sg_sat_set_features_SOURCES) $(sg_scan_SOURCES) \ @@ -855,6 +858,10 @@ sg_copy_results_SOURCES = sg_copy_results.c sg_copy_results_LDADD = ../lib/libsgutils2.la @os_libs@ sg_compare_and_write_SOURCES = sg_compare_and_write.c sg_compare_and_write_LDADD = ../lib/libsgutils2.la @os_libs@ +sg_rep_zones_SOURCES = sg_rep_zones.c +sg_rep_zones_LDADD = ../lib/libsgutils2.la @os_libs@ +sg_reset_wp_SOURCES = sg_reset_wp.c +sg_reset_wp_LDADD = ../lib/libsgutils2.la @os_libs@ all: all-am .SUFFIXES: @@ -1051,6 +1058,10 @@ sg_referrals$(EXEEXT): $(sg_referrals_OBJECTS) $(sg_referrals_DEPENDENCIES) $(EX @rm -f sg_referrals$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sg_referrals_OBJECTS) $(sg_referrals_LDADD) $(LIBS) +sg_rep_zones$(EXEEXT): $(sg_rep_zones_OBJECTS) $(sg_rep_zones_DEPENDENCIES) $(EXTRA_sg_rep_zones_DEPENDENCIES) + @rm -f sg_rep_zones$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(sg_rep_zones_OBJECTS) $(sg_rep_zones_LDADD) $(LIBS) + sg_requests$(EXEEXT): $(sg_requests_OBJECTS) $(sg_requests_DEPENDENCIES) $(EXTRA_sg_requests_DEPENDENCIES) @rm -f sg_requests$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sg_requests_OBJECTS) $(sg_requests_LDADD) $(LIBS) @@ -1059,6 +1070,10 @@ sg_reset$(EXEEXT): $(sg_reset_OBJECTS) $(sg_reset_DEPENDENCIES) $(EXTRA_sg_reset @rm -f sg_reset$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sg_reset_OBJECTS) $(sg_reset_LDADD) $(LIBS) +sg_reset_wp$(EXEEXT): $(sg_reset_wp_OBJECTS) $(sg_reset_wp_DEPENDENCIES) $(EXTRA_sg_reset_wp_DEPENDENCIES) + @rm -f sg_reset_wp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(sg_reset_wp_OBJECTS) $(sg_reset_wp_LDADD) $(LIBS) + sg_rmsn$(EXEEXT): $(sg_rmsn_OBJECTS) $(sg_rmsn_DEPENDENCIES) $(EXTRA_sg_rmsn_DEPENDENCIES) @rm -f sg_rmsn$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sg_rmsn_OBJECTS) $(sg_rmsn_LDADD) $(LIBS) @@ -1198,8 +1213,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_readcap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_reassign.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_referrals.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_rep_zones.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_requests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_reset.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sg_reset_wp.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@ @@ -1480,6 +1497,12 @@ uninstall-am: uninstall-binPROGRAMS @OS_WIN32_CYGWIN_TRUE@sg_scan.c : sg_scan.c.win32 @OS_WIN32_CYGWIN_TRUE@ cp sg_scan.c.win32 sg_scan.c +@OS_FREEBSD_TRUE@ sg_read_block_limits sg_read_buffer sg_read_long sg_reassign \ +@OS_FREEBSD_TRUE@ sg_referrals sg_rep_zones sg_requests sg_reset_wp sg_rmsn \ +@OS_FREEBSD_TRUE@ sg_rtpg sg_safte sg_sanitize sg_sat_identify sg_sat_phy_event \ +@OS_FREEBSD_TRUE@ sg_sat_set_features sg_senddiag sg_ses sg_start sg_stpg sg_sync \ +@OS_FREEBSD_TRUE@ sg_turs sg_unmap sg_verify sg_vpd sg_write_buffer sg_write_long \ +@OS_FREEBSD_TRUE@ sg_write_same sg_wr_mode # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/sg_inq.c b/src/sg_inq.c index 642d75d5..3d83ba41 100644 --- a/src/sg_inq.c +++ b/src/sg_inq.c @@ -41,7 +41,7 @@ #include "sg_cmds_basic.h" #include "sg_pt.h" -static const char * version_str = "1.38 20140518"; /* SPC-4 rev 37 */ +static const char * version_str = "1.39 20140527"; /* SPC-4 rev 37 */ /* INQUIRY notes: * It is recommended that the initial allocation length given to a @@ -1765,7 +1765,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex) } static void -export_dev_ids(unsigned char * buff, int len) +export_dev_ids(unsigned char * buff, int len, int verbose) { int u, j, m, id_len, c_set, assoc, desig_type, i_len; int off, d_id, naa, k, p_id; @@ -1795,9 +1795,10 @@ export_dev_ids(unsigned char * buff, int len) i_len = ucp[3]; id_len = i_len + 4; if ((off + id_len) > len) { - pr2serr("Device Identification VPD page error: designator " - "length longer than\n remaining response length=%d\n", - (len - off)); + if (verbose) + pr2serr("Device Identification VPD page error: designator " + "length longer than\n remaining response " + "length=%d\n", (len - off)); return; } ip = ucp + 4; @@ -1817,7 +1818,8 @@ export_dev_ids(unsigned char * buff, int len) assoc_str = "TARGET"; break; default: - pr2serr(" Invalid association %d\n", assoc); + if (verbose) + pr2serr(" Invalid association %d\n", assoc); return; } switch (desig_type) { @@ -1837,6 +1839,10 @@ export_dev_ids(unsigned char * buff, int len) if ((2 == c_set) || (3 == c_set)) { k = encode_whitespaces(ip, i_len); printf("%.*s\n", k, ip); + if (!memcmp(ip, "ATA_", 4)) { + printf("SCSI_IDENT_%s_ATA=%.*s\n", assoc_str, + k - 4, ip + 4); + } } else { for (m = 0; m < i_len; ++m) printf("%02x", (unsigned int)ip[m]); @@ -1845,8 +1851,10 @@ export_dev_ids(unsigned char * buff, int len) break; case 2: /* EUI-64 based */ if (1 != c_set) { - pr2serr(" << expected binary code_set (1)>>\n"); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << expected binary code_set (1)>>\n"); + dStrHexErr((const char *)ip, i_len, 0); + } break; } printf("SCSI_IDENT_%s_EUI64=", assoc_str); @@ -1856,21 +1864,27 @@ export_dev_ids(unsigned char * buff, int len) break; case 3: /* NAA */ if (1 != c_set) { - pr2serr(" << expected binary code_set (1)>>\n"); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << expected binary code_set (1)>>\n"); + dStrHexErr((const char *)ip, i_len, 0); + } break; } naa = (ip[0] >> 4) & 0xff; if ((naa < 2) || (naa > 6) || (4 == naa)) { - pr2serr(" << unexpected naa [0x%x]>>\n", naa); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << unexpected naa [0x%x]>>\n", naa); + dStrHexErr((const char *)ip, i_len, 0); + } break; } if (6 != naa) { if (8 != i_len) { - pr2serr(" << unexpected NAA 2 identifier " - "length: 0x%x>>\n", i_len); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << unexpected NAA 2 identifier " + "length: 0x%x>>\n", i_len); + dStrHexErr((const char *)ip, i_len, 0); + } break; } printf("SCSI_IDENT_%s_NAA=", assoc_str); @@ -1879,9 +1893,11 @@ export_dev_ids(unsigned char * buff, int len) printf("\n"); } else { /* NAA IEEE Registered extended */ if (16 != i_len) { - pr2serr(" << unexpected NAA 6 identifier " - "length: 0x%x>>\n", i_len); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << unexpected NAA 6 identifier " + "length: 0x%x>>\n", i_len); + dStrHexErr((const char *)ip, i_len, 0); + } break; } printf("SCSI_IDENT_%s_NAA=", assoc_str); @@ -1892,9 +1908,11 @@ export_dev_ids(unsigned char * buff, int len) break; case 4: /* Relative target port */ if ((1 != c_set) || (1 != assoc) || (4 != i_len)) { - pr2serr(" << expected binary code_set, target " - "port association, length 4>>\n"); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << expected binary code_set, target " + "port association, length 4>>\n"); + dStrHexErr((const char *)ip, i_len, 0); + } break; } d_id = ((ip[2] << 8) | ip[3]); @@ -1902,9 +1920,11 @@ export_dev_ids(unsigned char * buff, int len) break; case 5: /* (primary) Target port group */ if ((1 != c_set) || (1 != assoc) || (4 != i_len)) { - pr2serr(" << expected binary code_set, target " - "port association, length 4>>\n"); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << expected binary code_set, target " + "port association, length 4>>\n"); + dStrHexErr((const char *)ip, i_len, 0); + } break; } d_id = ((ip[2] << 8) | ip[3]); @@ -1912,9 +1932,11 @@ export_dev_ids(unsigned char * buff, int len) break; case 6: /* Logical unit group */ if ((1 != c_set) || (0 != assoc) || (4 != i_len)) { - pr2serr(" << expected binary code_set, logical " - "unit association, length 4>>\n"); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << expected binary code_set, logical " + "unit association, length 4>>\n"); + dStrHexErr((const char *)ip, i_len, 0); + } break; } d_id = ((ip[2] << 8) | ip[3]); @@ -1922,9 +1944,11 @@ export_dev_ids(unsigned char * buff, int len) break; case 7: /* MD5 logical unit identifier */ if ((1 != c_set) || (0 != assoc)) { - pr2serr(" << expected binary code_set, logical " - "unit association>>\n"); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << expected binary code_set, logical " + "unit association>>\n"); + dStrHexErr((const char *)ip, i_len, 0); + } break; } printf("SCSI_IDENT_%s_MD5=", assoc_str); @@ -1932,8 +1956,10 @@ export_dev_ids(unsigned char * buff, int len) break; case 8: /* SCSI name string */ if (3 != c_set) { - pr2serr(" << expected UTF-8 code_set>>\n"); - dStrHexErr((const char *)ip, i_len, -1); + if (verbose) { + pr2serr(" << expected UTF-8 code_set>>\n"); + dStrHexErr((const char *)ip, i_len, -1); + } break; } printf("SCSI_IDENT_%s_NAME=%.*s\n", assoc_str, i_len, @@ -1942,9 +1968,11 @@ export_dev_ids(unsigned char * buff, int len) case 9: /* Protocol specific port identifier */ if (TPROTO_UAS == p_id) { if ((4 != i_len) || (1 != assoc)) { - pr2serr(" << UAS (USB) expected target " - "port association>>\n"); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << UAS (USB) expected target " + "port association>>\n"); + dStrHexErr((const char *)ip, i_len, 0); + } break; } printf("SCSI_IDENT_%s_UAS_DEVICE_ADDRESS=0x%x\n", assoc_str, @@ -1953,9 +1981,11 @@ export_dev_ids(unsigned char * buff, int len) ip[2]); } else if (TPROTO_SOP == p_id) { if ((4 != i_len) && (8 != i_len)) { /* spc4r36h confused */ - pr2serr(" << SOP (PCIe) descriptor " - "length=%d >>\n", i_len); - dStrHexErr((const char *)ip, i_len, 0); + if (verbose) { + pr2serr(" << SOP (PCIe) descriptor " + "length=%d >>\n", i_len); + dStrHexErr((const char *)ip, i_len, 0); + } break; } printf("SCSI_IDENT_%s_SOP_ROUTING_ID=0x%x\n", assoc_str, @@ -1966,12 +1996,14 @@ export_dev_ids(unsigned char * buff, int len) } break; default: /* reserved */ - pr2serr(" reserved designator=0x%x\n", desig_type); - dStrHexErr((const char *)ip, i_len, -1); + if (verbose) { + pr2serr(" reserved designator=0x%x\n", desig_type); + dStrHexErr((const char *)ip, i_len, -1); + } break; } } - if (-2 == u) + if (-2 == u && verbose) pr2serr("Device identification VPD page error: " "around offset=%d\n", off); } @@ -3233,7 +3265,7 @@ vpd_decode(int sg_fd, const struct opts_t * op, int inhex_len) else if (op->do_hex > 2) dStrHex((const char *)rp, len, -1); else if (op->do_export) - export_dev_ids(rp + 4, len - 4); + export_dev_ids(rp + 4, len - 4, op->do_verbose); else decode_id_vpd(rp, len, op->do_hex); break; diff --git a/src/sg_inq_data.c b/src/sg_inq_data.c index 2dc08a7f..77dea3a5 100644 --- a/src/sg_inq_data.c +++ b/src/sg_inq_data.c @@ -30,7 +30,7 @@ const char * sg_ansi_version_arr[] = "SPC-2", "SPC-3", "SPC-4", - "reserved [7h]", + "SPC-5", "ecma=1, [8h]", "ecma=1, [9h]", "ecma=1, [Ah]", diff --git a/src/sg_logs.c b/src/sg_logs.c index ee539116..81fd8e94 100644 --- a/src/sg_logs.c +++ b/src/sg_logs.c @@ -28,7 +28,7 @@ #include "sg_cmds_basic.h" #include "sg_pt.h" /* needed for scsi_pt_win32_direct() */ -static const char * version_str = "1.23 20140518"; /* spc4r37 + sbc4r01 */ +static const char * version_str = "1.24 20140523"; /* spc4r37 + sbc4r01 */ #define MX_ALLOC_LEN (0xfffc) #define SHORT_RESP_LEN 128 @@ -1018,11 +1018,11 @@ show_page_name(int pg_code, int subpg_code, if (0x15 == pg_code) { switch (inq_dat->peripheral_type) { case PDT_DISK: case PDT_WO: case PDT_OPTICAL: case PDT_RBC: - if (0 == subpg_code) { - printf("%sBackground scan results (sbc-3)\n", b); + if (0 == subpg_code) { /* introduced: SBC-3 */ + printf("%sBackground scan results\n", b); return; - } else if (1 == subpg_code) { - printf("%sPending defects (sbc-4)\n", b); + } else if (1 == subpg_code) { /* introduced: SBC-4 */ + printf("%sPending defects\n", b); return; } break; @@ -1041,21 +1041,21 @@ show_page_name(int pg_code, int subpg_code, /* disk (direct access) type devices */ { switch (pg_code) { - case FORMAT_STATUS_LPAGE: - printf("%sFormat status (sbc-2)\n", b); + case FORMAT_STATUS_LPAGE: /* introduced: SBC-2 */ + printf("%sFormat status\n", b); break; - case LB_PROV_LPAGE: /* 0xc */ - printf("%sLogical block provisioning (sbc-3)\n", b); + case LB_PROV_LPAGE: /* 0xc introduced: SBC-3 */ + printf("%sLogical block provisioning\n", b); break; /* case 0x15: has subpage in sbc4 */ - case SOLID_STATE_MEDIA_LPAGE: /* 0x11 */ - printf("%sSolid state media (sbc-3)\n", b); + case SOLID_STATE_MEDIA_LPAGE: /* 0x11 introduced: SBC-3 */ + printf("%sSolid state media\n", b); break; - case SAT_ATA_RESULTS_LPAGE: - printf("%sATA pass-through results (sat-2)\n", b); + case SAT_ATA_RESULTS_LPAGE: /* introduced: SAT-2 */ + printf("%sATA pass-through results (sat)\n", b); break; - case 0x17: - printf("%sNon-volatile cache (sbc-2)\n", b); + case 0x17: /* introduced: SBC-2 */ + printf("%sNon-volatile cache\n", b); break; case 0x30: printf("%sPerformance counters (Hitachi)\n", b); @@ -1076,72 +1076,75 @@ show_page_name(int pg_code, int subpg_code, /* tape (streaming) and printer (obsolete) devices */ { switch (pg_code) { - case 0xc: - printf("%sSequential access device (ssc-2)\n", b); + case 0xc: /* introduced: SSC-2 */ + printf("%sSequential access device\n", b); break; - case 0x11: - printf("%sDT Device status (ssc-3)\n", b); + case 0x11: /* introduced: SSC-3 */ + printf("%sDT Device status\n", b); break; - case 0x12: - printf("%sTape alert response (ssc-3)\n", b); + case 0x12: /* introduced: SSC-3 */ + printf("%sTape alert response\n", b); break; - case 0x13: - printf("%sRequested recovery (ssc-3)\n", b); + case 0x13: /* introduced: SSC-3 */ + printf("%sRequested recovery\n", b); break; - case 0x14: - printf("%sDevice statistics (ssc-3)\n", b); + case 0x14: /* introduced: SSC-3 */ + printf("%sDevice statistics\n", b); break; - case 0x16: - printf("%sTape diagnostic (ssc-3)\n", b); + case 0x16: /* introduced: SSC-3 */ + printf("%sTape diagnostic\n", b); break; - case 0x17: - printf("%sVolume statistics (ssc-4)\n", b); + case 0x17: /* introduced: SSC-4 */ + printf("%sVolume statistics\n", b); break; - case 0x1b: - printf("%sData compression (ssc-4)\n", b); + case 0x1b: /* introduced: SSC-4 */ + printf("%sData compression\n", b); break; - case 0x2d: - printf("%sCurrent service information (ssc-3)\n", b); + case 0x2d: /* introduced: SSC-3 */ + printf("%sCurrent service information\n", b); break; - case TAPE_ALERT_LPAGE: - printf("%sTapeAlert (ssc-2)\n", b); + case TAPE_ALERT_LPAGE: /* introduced: SSC-2 */ + printf("%sTapeAlert\n", b); break; case 0x30: - printf("%sTape usage (IBM specific)\n", b); + printf("%sTape usage (LTO-5 and 6 specific)\n", b); break; case 0x31: - printf("%sTape capacity (IBM specific)\n", b); + printf("%sTape capacity (LTO-5 and 6 specific)\n", b); break; case 0x32: - printf("%sData compression (IBM specific)\n", b); + printf("%sData compression (LTO-5 specific, LTO-6 use " + "0x1b)\n", b); break; - case 0x33: - printf("%sWrite errors (IBM specific)\n", b); + case 0x33: /* in LTO-6 this is 'Device Wellness' page */ + printf("%sWrite errors (LTO-5 specific)\n", b); break; - case 0x34: - printf("%sRead forward errors (IBM specific)\n", b); + case 0x34: /* in LTO-6 this is Performance data page */ + printf("%sRead forward errors (LTO-5 specific)\n", b); break; + /* case 0x35: in LTO-6 this is DT Device Error page */ case 0x37: - printf("%sPerformance characteristics (IBM specific)\n", b); + printf("%sPerformance characteristics (LTO-5 specific)\n", b); break; case 0x38: - printf("%sBlocks/bytes transferred (IBM specific)\n", b); + printf("%sBlocks/bytes transferred (LTO-5 specific)\n", b); break; case 0x39: - printf("%sHost port 0 interface errors (IBM specific)\n", b); + printf("%sHost port 0 interface errors (LTO-5 specific)\n", b); break; case 0x3a: - printf("%sDrive control verification (IBM specific)\n", b); + printf("%sDrive control verification (LTO-5 specific)\n", b); break; case 0x3b: - printf("%sHost port 1 interface errors (IBM specific)\n", b); + printf("%sHost port 1 interface errors (LTO-5 specific)\n", b); break; case 0x3c: - printf("%sDrive usage information (IBM specific)\n", b); + printf("%sDrive usage information (LTO-5 specific)\n", b); break; case 0x3d: - printf("%sSubsystem statistics (IBM specific)\n", b); + printf("%sSubsystem statistics (LTO-5 specific)\n", b); break; + /* case 0x3e: in LTO-6 this is Device Status page */ default: done = 0; break; @@ -1235,7 +1238,7 @@ get_pcb_str(int pcb, char * outp, int maxoutlen) outp[0] = '\0'; } -/* BUFF_OVER_UNDER_LPAGE [0x1] */ +/* BUFF_OVER_UNDER_LPAGE [0x1] introduced: SPC-2 */ static void show_buffer_under_over_run_page(unsigned char * resp, int len, const struct opts_t * op) @@ -1247,7 +1250,7 @@ show_buffer_under_over_run_page(unsigned char * resp, int len, char pcb_str[PCB_STR_LEN]; if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Buffer over-run/under-run page (spc-2) [0x1]\n"); + printf("Buffer over-run/under-run page [0x1]\n"); num = len - 4; ucp = &resp[0] + 4; while (num > 3) { @@ -1362,7 +1365,7 @@ skip: } /* WRITE_ERR_LPAGE; READ_ERR_LPAGE; READ_REV_ERR_LPAGE; VERIFY_ERR_LPAGE */ -/* [0x2, 0x3, 0x4, 0x5] */ +/* [0x2, 0x3, 0x4, 0x5] introduced: SPC-3 */ static void show_error_counter_page(unsigned char * resp, int len, const struct opts_t * op) @@ -1375,17 +1378,17 @@ show_error_counter_page(unsigned char * resp, int len, if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) { switch(pg_code) { case WRITE_ERR_LPAGE: - printf("Write error counter page (spc-3) [0x%x]\n", pg_code); + printf("Write error counter page [0x%x]\n", pg_code); break; case READ_ERR_LPAGE: - printf("Read error counter page (spc-3) [0x%x]\n", pg_code); + printf("Read error counter page [0x%x]\n", pg_code); break; case READ_REV_ERR_LPAGE: - printf("Read Reverse error counter page (spc-3) [0x%x]\n", + printf("Read Reverse error counter page [0x%x]\n", pg_code); break; case VERIFY_ERR_LPAGE: - printf("Verify error counter page (spc-3) [0x%x]\n", pg_code); + printf("Verify error counter page [0x%x]\n", pg_code); break; default: pr2serr("expecting error counter page, got page = 0x%x\n", @@ -1436,7 +1439,7 @@ skip: } } -/* NON_MEDIUM_LPAGE [0x6] */ +/* NON_MEDIUM_LPAGE [0x6] introduced: SPC-2 */ static void show_non_medium_error_page(unsigned char * resp, int len, const struct opts_t * op) @@ -1446,7 +1449,7 @@ show_non_medium_error_page(unsigned char * resp, int len, char pcb_str[PCB_STR_LEN]; if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Non-medium error page (spc-2) [0x6]\n"); + printf("Non-medium error page [0x6]\n"); num = len - 4; ucp = &resp[0] + 4; while (num > 3) { @@ -1489,7 +1492,7 @@ skip: } } -/* PCT_LPAGE [0x1a] */ +/* PCT_LPAGE [0x1a] introduced: SPC-4 */ static void show_power_condition_transitions_page(unsigned char * resp, int len, const struct opts_t * op) @@ -1499,7 +1502,7 @@ show_power_condition_transitions_page(unsigned char * resp, int len, char pcb_str[PCB_STR_LEN]; if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Power condition transitions page (spc-4) [0x1a]\n"); + printf("Power condition transitions page [0x1a]\n"); num = len - 4; ucp = &resp[0] + 4; while (num > 3) { @@ -1547,7 +1550,7 @@ skip: } } -/* Tape usage: Vendor specific (IBM): 0x30 */ +/* Tape usage: Vendor specific (LTO-5 and LTO-6): 0x30 */ static void show_tape_usage_log_page(unsigned char * resp, int len, const struct opts_t * op) @@ -1565,7 +1568,7 @@ show_tape_usage_log_page(unsigned char * resp, int len, return; } if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Tape usage page (IBM specific) [0x30]\n"); + printf("Tape usage page (LTO-5 and LTO-6 specific) [0x30]\n"); for (k = num; k > 0; k -= extra, ucp += extra) { pc = (ucp[0] << 8) + ucp[1]; pcb = ucp[2]; @@ -1827,7 +1830,7 @@ skip_para: } } -/* LAST_N_ERR_LPAGE [0x7] */ +/* LAST_N_ERR_LPAGE [0x7] introduced: SPC-2 */ static void show_last_n_error_page(unsigned char * resp, int len, const struct opts_t * op) @@ -1843,7 +1846,7 @@ show_last_n_error_page(unsigned char * resp, int len, return; } if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Last n error events page (spc-2) [0x7]\n"); + printf("Last n error events page [0x7]\n"); for (k = num; k > 0; k -= pl, ucp += pl) { if (k < 3) { printf("short Last n error events page\n"); @@ -1884,7 +1887,7 @@ show_last_n_error_page(unsigned char * resp, int len, } } -/* LAST_N_DEFERRED_LPAGE [0xb] */ +/* LAST_N_DEFERRED_LPAGE [0xb] introduced: SPC-2 */ static void show_last_n_deferred_error_page(unsigned char * resp, int len, const struct opts_t * op) @@ -1900,7 +1903,7 @@ show_last_n_deferred_error_page(unsigned char * resp, int len, return; } if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Last n deferred errors page (spc-2) [0xb]\n"); + printf("Last n deferred errors page [0xb]\n"); for (k = num; k > 0; k -= pl, ucp += pl) { if (k < 3) { printf("short Last n deferred errors page\n"); @@ -1949,7 +1952,7 @@ static const char * self_test_result[] = { "reserved", "self test in progress"}; -/* SELF_TEST_LPAGE [0x10] */ +/* SELF_TEST_LPAGE [0x10] introduced: SPC-3 */ static void show_self_test_page(unsigned char * resp, int len, const struct opts_t * op) { @@ -1967,7 +1970,7 @@ show_self_test_page(unsigned char * resp, int len, const struct opts_t * op) return; } if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Self-test results page (spc-3) [0x10]\n"); + printf("Self-test results page [0x10]\n"); for (k = 0, ucp = resp + 4; k < 20; ++k, ucp += 20 ) { pcb = ucp[2]; pl = ucp[3] + 4; @@ -2019,7 +2022,7 @@ show_self_test_page(unsigned char * resp, int len, const struct opts_t * op) } } -/* TEMPERATURE_LPAGE [0xd] */ +/* TEMPERATURE_LPAGE [0xd] introduced: SPC-3 */ static void show_temperature_page(unsigned char * resp, int len, const struct opts_t * op, int show_extra) @@ -2036,7 +2039,7 @@ show_temperature_page(unsigned char * resp, int len, } if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) { if (show_extra) - printf("Temperature page (spc-3) [0xd]\n"); + printf("Temperature page [0xd]\n"); } for (k = num; k > 0; k -= extra, ucp += extra) { if (k < 3) { @@ -2094,7 +2097,7 @@ show_temperature_page(unsigned char * resp, int len, } } -/* START_STOP_LPAGE [0xe] */ +/* START_STOP_LPAGE [0xe] introduced: SPC-3 */ static void show_start_stop_page(unsigned char * resp, int len, const struct opts_t * op) { @@ -2110,7 +2113,7 @@ show_start_stop_page(unsigned char * resp, int len, const struct opts_t * op) return; } if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Start-stop cycle counter page (spc-3) [0xe]\n"); + printf("Start-stop cycle counter page [0xe]\n"); for (k = num; k > 0; k -= extra, ucp += extra) { if (k < 3) { pr2serr("short Start-stop cycle counter page\n"); @@ -2208,7 +2211,7 @@ show_start_stop_page(unsigned char * resp, int len, const struct opts_t * op) } } -/* APP_CLIENT_LPAGE [0xf] */ +/* APP_CLIENT_LPAGE [0xf] introduced: SPC-3 */ static void show_app_client_page(unsigned char * resp, int len, const struct opts_t * op) { @@ -2223,7 +2226,7 @@ show_app_client_page(unsigned char * resp, int len, const struct opts_t * op) return; } if (op->do_verbose || ((op->do_raw == 0) && (op->do_hex == 0))) - printf("Application client page (spc-3) [0xf]\n"); + printf("Application client page [0xf]\n"); if (0 == op->filter_given) { if ((len > 128) && (0 == op->do_hex)) { dStrHex((const char *)resp, 64, 1); @@ -2263,7 +2266,7 @@ show_app_client_page(unsigned char * resp, int len, const struct opts_t * op) } } -/* IE_LPAGE [0x2f] */ +/* IE_LPAGE [0x2f] introduced: SPC-3 */ static void show_ie_page(unsigned char * resp, int len, const struct opts_t * op, int full) @@ -2281,7 +2284,7 @@ show_ie_page(unsigned char * resp, int len, const struct opts_t * op, } if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) { if (full) - printf("Informational Exceptions page (spc-3) [0x2f]\n"); + printf("Informational Exceptions page [0x2f]\n"); } for (k = num; k > 0; k -= extra, ucp += extra) { if (k < 3) { @@ -2736,7 +2739,7 @@ skip: } /* Returns 1 if processed page, 0 otherwise */ -/* STATS_LPAGE [0x19], subpages: 0x0 to 0x1f */ +/* STATS_LPAGE [0x19], subpages: 0x0 to 0x1f introduced: SPC-4 */ static int show_stats_perform_page(unsigned char * resp, int len, const struct opts_t * op) @@ -2760,10 +2763,9 @@ show_stats_perform_page(unsigned char * resp, int len, printf("log_subpage=0x%x\n", subpg_code); } else { if (0 == subpg_code) - printf("General Statistics and Performance (spc-4) " - "[0x19]\n"); + printf("General Statistics and Performance [0x19]\n"); else - printf("Group Statistics and Performance (%d) (spc-4) " + printf("Group Statistics and Performance (%d) " "[0x19,0x%x]\n", subpg_code, subpg_code); } } @@ -3100,7 +3102,7 @@ show_stats_perform_page(unsigned char * resp, int len, } /* Returns 1 if processed page, 0 otherwise */ -/* STATS_LPAGE [0x19], CACHE_STATS_SUBPG [0x20] */ +/* STATS_LPAGE [0x19], CACHE_STATS_SUBPG [0x20] introduced: SPC-4 */ static int show_cache_stats_page(unsigned char * resp, int len, const struct opts_t * op) @@ -3127,7 +3129,7 @@ show_cache_stats_page(unsigned char * resp, int len, if (subpg_code > 0) printf("log_subpage=0x%x\n", subpg_code); } else - printf("Cache memory statistics page (spc-4) [0x19,0x20]\n"); + printf("Cache memory statistics page [0x19,0x20]\n"); } for (k = num; k > 0; k -= extra, ucp += extra) { @@ -3249,7 +3251,7 @@ show_cache_stats_page(unsigned char * resp, int len, return 1; } -/* FORMAT_STATUS_LPAGE [0x8] */ +/* FORMAT_STATUS_LPAGE [0x8] introduced: SBC-2 */ static void show_format_status_page(unsigned char * resp, int len, const struct opts_t * op) @@ -3261,7 +3263,7 @@ show_format_status_page(unsigned char * resp, int len, char pcb_str[PCB_STR_LEN]; if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Format status page (sbc-2) [0x8]\n"); + printf("Format status page [0x8]\n"); num = len - 4; ucp = &resp[0] + 4; while (num > 3) { @@ -3335,7 +3337,7 @@ skip: } } -/* Non-volatile cache page [0x17] */ +/* Non-volatile cache page [0x17] introduced: SBC-2 */ static void show_non_volatile_cache_page(unsigned char * resp, int len, const struct opts_t * op) @@ -3345,7 +3347,7 @@ show_non_volatile_cache_page(unsigned char * resp, int len, char pcb_str[PCB_STR_LEN]; if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Non-volatile cache page (sbc-2) [0x17]\n"); + printf("Non-volatile cache page [0x17]\n"); num = len - 4; ucp = &resp[0] + 4; while (num > 3) { @@ -3423,7 +3425,7 @@ skip: } } -/* LB_PROV_LPAGE [0xc] */ +/* LB_PROV_LPAGE [0xc] introduced: SBC-3 */ static void show_lb_provisioning_page(unsigned char * resp, int len, const struct opts_t * op) @@ -3434,7 +3436,7 @@ show_lb_provisioning_page(unsigned char * resp, int len, char str[PCB_STR_LEN]; if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Logical block provisioning page (sbc-3) [0xc]\n"); + printf("Logical block provisioning page [0xc]\n"); num = len - 4; ucp = &resp[0] + 4; while (num > 3) { @@ -3513,7 +3515,7 @@ skip: } } -/* SOLID_STATE_MEDIA_LPAGE [0x11] */ +/* SOLID_STATE_MEDIA_LPAGE [0x11] introduced: SBC-3 */ static void show_solid_state_media_page(unsigned char * resp, int len, const struct opts_t * op) @@ -3523,7 +3525,7 @@ show_solid_state_media_page(unsigned char * resp, int len, char str[PCB_STR_LEN]; if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Solid state media page (sbc-3) [0x11]\n"); + printf("Solid state media page [0x11]\n"); num = len - 4; ucp = &resp[0] + 4; while (num > 3) { @@ -3799,7 +3801,7 @@ static const char * reassign_status[] = { "Logical block unsuccessfully reassigned by application client", /* 8 */ }; -/* Background scan results [0x15,0] for disk */ +/* Background scan results [0x15,0] for disk introduced: SBC-3 */ static void show_background_scan_results_page(unsigned char * resp, int len, const struct opts_t * op) @@ -3809,7 +3811,7 @@ show_background_scan_results_page(unsigned char * resp, int len, char str[PCB_STR_LEN]; if (op->do_verbose || ((0 == op->do_raw) && (0 == op->do_hex))) - printf("Background scan results page (sbc-3) [0x15]\n"); + printf("Background scan results page [0x15]\n"); num = len - 4; ucp = &resp[0] + 4; while (num > 3) { @@ -5033,8 +5035,8 @@ show_ascii_page(unsigned char * resp, int len, subpg_code = spf ? resp[1] : 0; if ((SUPP_PAGES_LPAGE != pg_code ) && (SUPP_SPGS_SUBPG == subpg_code)) { - printf("Supported subpages for log page=0x%x (spc-4) [0x%x, 0x%x]" - "\n", pg_code, pg_code, subpg_code); + printf("Supported subpages for log page=0x%x [0x%x, 0x%x]\n", + pg_code, pg_code, subpg_code); /* introduced: SPC-4 */ for (k = 0; k < num; k += 2) show_page_name((int)resp[4 + k], (int)resp[4 + k + 1], inq_dat); @@ -5043,13 +5045,13 @@ show_ascii_page(unsigned char * resp, int len, switch (pg_code) { case SUPP_PAGES_LPAGE: /* 0x0 */ if (spf) { - printf("Supported log pages and subpages (spc-4) [0x%x, 0x%x]:" - "\n", pg_code, subpg_code); + printf("Supported log pages and subpages [0x%x, 0x%x]:\n", + pg_code, subpg_code); /* introduced: SPC-4 */ for (k = 0; k < num; k += 2) show_page_name((int)resp[4 + k], (int)resp[4 + k + 1], inq_dat); } else { - printf("Supported log pages (spc-2) [0x0]:\n"); + printf("Supported log pages [0x0]:\n"); /* introduced: SPC-2 */ for (k = 0; k < num; ++k) show_page_name((int)resp[4 + k], 0, inq_dat); } diff --git a/src/sg_rep_zones.c b/src/sg_rep_zones.c new file mode 100644 index 00000000..99d4f5d3 --- /dev/null +++ b/src/sg_rep_zones.c @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2014 Douglas Gilbert. + * All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the BSD_LICENSE file. + */ + +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <ctype.h> +#include <getopt.h> +#define __STDC_FORMAT_MACROS 1 +#include <inttypes.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "sg_lib.h" +#include "sg_pt.h" +#include "sg_cmds_basic.h" + +/* A utility program originally written for the Linux OS SCSI subsystem. + * + * + * This program issues the SCSI REPORT ZONES command to the given SCSI device + * and decodes the response. + */ + +static const char * version_str = "1.01 20140527"; + +#define MAX_RZONES_BUFF_LEN (1024 * 1024) +#define DEF_RZONES_BUFF_LEN (1024 * 8) + +#define SERVICE_ACTION_IN_16_CMD 0x9e +#define SERVICE_ACTION_IN_16_CMDLEN 16 +#define REPORT_ZONES_SA 0x14 + +#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */ +#define DEF_PT_TIMEOUT 60 /* 60 seconds */ + + +static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"hex", no_argument, 0, 'H'}, + {"maxlen", required_argument, 0, 'm'}, + {"raw", no_argument, 0, 'r'}, + {"readonly", no_argument, 0, 'R'}, + {"report", required_argument, 0, 'o'}, + {"start", required_argument, 0, 's'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {0, 0, 0, 0}, +}; + + +#ifdef __GNUC__ +static int pr2serr(const char * fmt, ...) + __attribute__ ((format (printf, 1, 2))); +#else +static int pr2serr(const char * fmt, ...); +#endif + + +static int +pr2serr(const char * fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vfprintf(stderr, fmt, args); + va_end(args); + return n; +} + +static void +usage() +{ + pr2serr("Usage: " + "sg_rep_zones [--help] [--hex] [--maxlen=LEN] [--raw]\n" + " [--readonly] [--report=OPT] " + "[--start=LBA]\n" + " [--verbose] [--version] DEVICE\n"); + pr2serr(" where:\n" + " --help|-h print out usage message\n" + " --hex|-H output response in hexadecimal; used " + "twice\n" + " shows decoded values in hex\n" + " --maxlen=LEN|-m LEN max response length (allocation " + "length in cdb)\n" + " (def: 0 -> 8192 bytes)\n" + " --raw|-r output response in binary\n" + " --readonly|-R open DEVICE read-only (def: read-write)\n" + " --report=OPT|-o OP reporting option (def: 0)\n" + " --start=LBA|-s LBA report zones from the LBA (def: 0)\n" + " must be a zone starting LBA\n" + " --verbose|-v increase verbosity\n" + " --version|-V print version string and exit\n\n" + "Performs a SCSI REPORT ZONES command.\n"); +} + +/* Invokes a SCSI REPORT ZONES command (ZBC). Return of 0 -> success, + * various SG_LIB_CAT_* positive values or -1 -> other errors */ +static int +sg_ll_report_zones(int sg_fd, uint64_t zs_lba, int report_opts, void * resp, + int mx_resp_len, int * residp, int noisy, int verbose) +{ + int k, ret, res, sense_cat; + unsigned char rzCmdBlk[SERVICE_ACTION_IN_16_CMDLEN] = + {SERVICE_ACTION_IN_16_CMD, REPORT_ZONES_SA, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; + unsigned char sense_b[SENSE_BUFF_LEN]; + struct sg_pt_base * ptvp; + + if ((zs_lba >> 56) & 0xff) { + pr2serr("%s: zone start LBA too large\n", __func__); + return SG_LIB_CAT_MALFORMED; + } + /* a 7 byte field as zbc-r01a claims ?? */ + rzCmdBlk[3] = (zs_lba >> 48) & 0xff; + rzCmdBlk[4] = (zs_lba >> 40) & 0xff; + rzCmdBlk[5] = (zs_lba >> 32) & 0xff; + rzCmdBlk[6] = (zs_lba >> 24) & 0xff; + rzCmdBlk[7] = (zs_lba >> 16) & 0xff; + rzCmdBlk[8] = (zs_lba >> 8) & 0xff; + rzCmdBlk[9] = zs_lba & 0xff; + rzCmdBlk[10] = (mx_resp_len >> 24) & 0xff; + rzCmdBlk[11] = (mx_resp_len >> 16) & 0xff; + rzCmdBlk[12] = (mx_resp_len >> 8) & 0xff; + rzCmdBlk[13] = mx_resp_len & 0xff; + rzCmdBlk[14] = report_opts & 0xf; + if (verbose) { + pr2serr(" Report zones cdb: "); + for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k) + pr2serr("%02x ", rzCmdBlk[k]); + pr2serr("\n"); + } + + ptvp = construct_scsi_pt_obj(); + if (NULL == ptvp) { + pr2serr("Report zones: out of memory\n"); + return -1; + } + set_scsi_pt_cdb(ptvp, rzCmdBlk, sizeof(rzCmdBlk)); + set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); + set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len); + res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); + ret = sg_cmds_process_resp(ptvp, "report zones", res, mx_resp_len, + sense_b, noisy, verbose, &sense_cat); + if (-1 == ret) + ; + else if (-2 == ret) { + switch (sense_cat) { + case SG_LIB_CAT_RECOVERED: + case SG_LIB_CAT_NO_SENSE: + ret = 0; + break; + default: + ret = sense_cat; + break; + } + } else + ret = 0; + if (residp) + *residp = get_scsi_pt_resid(ptvp); + destruct_scsi_pt_obj(ptvp); + return ret; +} + +static void +dStrRaw(const char* str, int len) +{ + int k; + + for (k = 0 ; k < len; ++k) + printf("%c", str[k]); +} + +static const char * +zone_type_str(int zt, char * b, int blen, int vb) +{ + const char * cp; + + if (NULL == b) + return "zone_type_str: NULL ptr)"; + switch (zt) { + case 1: + cp = "Conventional"; + break; + case 2: + cp = "Sequential write required"; + break; + case 3: + cp = "Sequential write preferred"; + break; + default: + cp = NULL; + break; + } + if (cp) { + if (vb) + snprintf(b, blen, "%s [0x%x]", cp, zt); + else + snprintf(b, blen, "%s", cp); + } else + snprintf(b, blen, "Reserved [0x%x]", zt); + return b; +} + +static const char * +zone_condition_str(int zc, char * b, int blen, int vb) +{ + const char * cp; + + if (NULL == b) + return "zone_condition_str: NULL ptr)"; + switch (zc) { + case 1: + cp = "Empty"; + break; + case 2: + cp = "Open"; + break; + case 0xd: + cp = "Read only"; + break; + case 0xe: + cp = "Full"; + break; + case 0xf: + cp = "Offline"; + break; + default: + cp = NULL; + break; + } + if (cp) { + if (vb) + snprintf(b, blen, "%s [0x%x]", cp, zc); + else + snprintf(b, blen, "%s", cp); + } else + snprintf(b, blen, "Reserved [0x%x]", zc); + return b; +} + + +int +main(int argc, char * argv[]) +{ + int sg_fd, k, m, res, c, zl_len, len, zones, resid, rlen, zt, zc; + int do_hex = 0; + int maxlen = 0; + int do_raw = 0; + int o_readonly = 0; + int reporting_opt = 0; + int verbose = 0; + uint64_t st_lba = 0; + int64_t ll; + const char * device_name = NULL; + unsigned char * reportZonesBuff = NULL; + unsigned char * ucp; + int ret = 0; + char b[80]; + + while (1) { + int option_index = 0; + + c = getopt_long(argc, argv, "hHm:o:rRs:vV", long_options, + &option_index); + if (c == -1) + break; + + switch (c) { + case 'h': + case '?': + usage(); + return 0; + case 'H': + ++do_hex; + break; + case 'm': + maxlen = sg_get_num(optarg); + if ((maxlen < 0) || (maxlen > MAX_RZONES_BUFF_LEN)) { + pr2serr("argument to '--maxlen' should be %d or " + "less\n", MAX_RZONES_BUFF_LEN); + return SG_LIB_SYNTAX_ERROR; + } + break; + case 'o': + reporting_opt = sg_get_num(optarg); + if ((reporting_opt < 0) || (reporting_opt > 15)) { + pr2serr("bad argument to '--report=OPT', expect 0 to " + "15\n"); + return SG_LIB_SYNTAX_ERROR; + } + break; + case 'r': + ++do_raw; + break; + case 'R': + ++o_readonly; + break; + case 's': + ll = sg_get_llnum(optarg); + if (-1 == ll) { + fprintf(stderr, "bad argument to '--start=LBA'\n"); + return SG_LIB_SYNTAX_ERROR; + } + st_lba = (uint64_t)ll; + break; + case 'v': + ++verbose; + break; + case 'V': + pr2serr("version: %s\n", version_str); + return 0; + default: + pr2serr("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) + pr2serr("Unexpected extra argument: %s\n", + argv[optind]); + usage(); + return SG_LIB_SYNTAX_ERROR; + } + } + + if (NULL == device_name) { + pr2serr("missing device name!\n"); + usage(); + return SG_LIB_SYNTAX_ERROR; + } + + if (do_raw) { + if (sg_set_binary_mode(STDOUT_FILENO) < 0) { + perror("sg_set_binary_mode"); + return SG_LIB_FILE_ERROR; + } + } + + sg_fd = sg_cmds_open_device(device_name, o_readonly, verbose); + if (sg_fd < 0) { + pr2serr("open error: %s: %s\n", device_name, + safe_strerror(-sg_fd)); + return SG_LIB_FILE_ERROR; + } + + if (0 == maxlen) + maxlen = DEF_RZONES_BUFF_LEN; + reportZonesBuff = (unsigned char *)calloc(1, maxlen); + if (NULL == reportZonesBuff) { + pr2serr("unable to malloc %d bytes\n", maxlen); + return SG_LIB_CAT_OTHER; + } + + res = sg_ll_report_zones(sg_fd, st_lba, reporting_opt, reportZonesBuff, + maxlen, &resid, 1, verbose); + ret = res; + if (0 == res) { + rlen = maxlen - resid; + if (rlen < 4) { + pr2serr("Response length (%d) too short\n", rlen); + ret = SG_LIB_CAT_MALFORMED; + goto the_end; + } + zl_len = (reportZonesBuff[0] << 24) + (reportZonesBuff[1] << 16) + + (reportZonesBuff[2] << 8) + reportZonesBuff[3] + 64; + if (zl_len > rlen) { + if (verbose) + pr2serr("zl_len available is %d, response length is %d\n", + zl_len, rlen); + len = rlen; + } else + len = zl_len; + if (do_raw) { + dStrRaw((const char *)reportZonesBuff, len); + goto the_end; + } + if (do_hex && (2 != do_hex)) { + dStrHex((const char *)reportZonesBuff, len, + ((1 == do_hex) ? 1 : -1)); + goto the_end; + } + printf("Report zones response:\n"); + if (len < 64) { + pr2serr("Zone length [%d] too short (perhaps after truncation\n)", + len); + ret = SG_LIB_CAT_MALFORMED; + goto the_end; + } + printf(" Same=%d\n\n", reportZonesBuff[4] & 1); + zones = (len - 64) / 64; + for (k = 0, ucp = reportZonesBuff + 64; k < zones; ++k, ucp += 64) { + printf(" Zone descriptor: %d\n", k); + if (do_hex) { + dStrHex((const char *)ucp, len, -1); + continue; + } + zt = ucp[0] & 0xf; + zc = (ucp[1] >> 4) & 0xf; + printf(" Zone type: %s\n", zone_type_str(zt, b, sizeof(b), + verbose)); + printf(" Zone condition: %s\n", zone_condition_str(zc, b, + sizeof(b), verbose)); + printf(" Reset: %d\n", ucp[1] & 0x1); + printf(" Zone Length: 0x"); + for (m = 0; m < 8; ++m) + printf("%02x", ucp[8 + m]); + printf("\n Zone start LBA: 0x"); + for (m = 0; m < 8; ++m) + printf("%02x", ucp[64 + m]); + printf("\n Write pointer LBA: 0x"); + for (m = 0; m < 8; ++m) + printf("%02x", ucp[64 + m]); + printf("\n"); + } + if ((64 + (64 * zones)) < zl_len) + printf("\n>>> Beware: Zone list truncated, may need another " + "call\n"); + } else if (SG_LIB_CAT_INVALID_OP == res) + pr2serr("Report zones command not supported\n"); + else { + sg_get_category_sense_str(res, sizeof(b), b, verbose); + pr2serr("Report zones command: %s\n", b); + } + +the_end: + if (reportZonesBuff) + free(reportZonesBuff); + res = sg_cmds_close_device(sg_fd); + if (res < 0) { + pr2serr("close error: %s\n", safe_strerror(-res)); + if (0 == ret) + return SG_LIB_FILE_ERROR; + } + return (ret >= 0) ? ret : SG_LIB_CAT_OTHER; +} diff --git a/src/sg_reset_wp.c b/src/sg_reset_wp.c new file mode 100644 index 00000000..cdc1f5d4 --- /dev/null +++ b/src/sg_reset_wp.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2014 Douglas Gilbert. + * All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the BSD_LICENSE file. + */ + +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <ctype.h> +#include <getopt.h> +#define __STDC_FORMAT_MACROS 1 +#include <inttypes.h> + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "sg_lib.h" +#include "sg_pt.h" +#include "sg_cmds_basic.h" + +/* A utility program originally written for the Linux OS SCSI subsystem. + * + * + * This program issues the SCSI RESET WRITE POINTER command to the given SCSI + * device. + */ + +static const char * version_str = "1.00 20140527"; + +#define SERVICE_ACTION_OUT_16_CMD 0x9f +#define SERVICE_ACTION_OUT_16_CMDLEN 16 +#define RESET_WRITE_POINTER_SA 0x14 + +#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */ +#define DEF_PT_TIMEOUT 60 /* 60 seconds */ + + +static struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"reset-all", no_argument, 0, 'R'}, + {"reset_all", no_argument, 0, 'R'}, + {"verbose", no_argument, 0, 'v'}, + {"version", no_argument, 0, 'V'}, + {"zone", required_argument, 0, 'z'}, + {0, 0, 0, 0}, +}; + + +#ifdef __GNUC__ +static int pr2serr(const char * fmt, ...) + __attribute__ ((format (printf, 1, 2))); +#else +static int pr2serr(const char * fmt, ...); +#endif + + +static int +pr2serr(const char * fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vfprintf(stderr, fmt, args); + va_end(args); + return n; +} + +static void +usage() +{ + pr2serr("Usage: " + "sg_reset_wp [--help] [--reset-all] [--verbose] [--version]\n" + " [--zone=ID] DEVICE\n"); + pr2serr(" where:\n" + " --help|-h print out usage message\n" + " --reset-all|-R sets the RESET ALL flag in the cdb\n" + " --verbose|-v increase verbosity\n" + " --version|-V print version string and exit\n\n" + " --zone=ID|-z ID ID is the starting LBA of the zone " + "whose\n" + " write pointer is to be reset\n" + "Performs a SCSI RESET WRITE POINTER command. ID is decimal by " + "default,\nfor hex use a leading '0x' or a trailing 'h'. " + "Either the --zone=ID\nor --reset-all needs to be given.\n"); +} + +/* Invokes a SCSI RESET WRITE POINTER command (ZBC). Return of 0 -> success, + * various SG_LIB_CAT_* positive values or -1 -> other errors */ +static int +sg_ll_reset_write_pointer(int sg_fd, uint64_t zid, int reset_all, int noisy, + int verbose) +{ + int k, ret, res, sense_cat; + unsigned char rwpCmdBlk[SERVICE_ACTION_OUT_16_CMDLEN] = + {SERVICE_ACTION_OUT_16_CMD, RESET_WRITE_POINTER_SA, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + unsigned char sense_b[SENSE_BUFF_LEN]; + struct sg_pt_base * ptvp; + + if ((zid >> 56) & 0xff) { + pr2serr("%s: zone id (LBA) too large\n", __func__); + return SG_LIB_CAT_MALFORMED; + } + /* a 7 byte field as zbc-r01a claims ?? */ + rwpCmdBlk[3] = (zid >> 48) & 0xff; + rwpCmdBlk[4] = (zid >> 40) & 0xff; + rwpCmdBlk[5] = (zid >> 32) & 0xff; + rwpCmdBlk[6] = (zid >> 24) & 0xff; + rwpCmdBlk[7] = (zid >> 16) & 0xff; + rwpCmdBlk[8] = (zid >> 8) & 0xff; + rwpCmdBlk[9] = zid & 0xff; + if (reset_all) + rwpCmdBlk[14] = 0x1; + if (verbose) { + pr2serr(" Reset write pointer cdb: "); + for (k = 0; k < SERVICE_ACTION_OUT_16_CMDLEN; ++k) + pr2serr("%02x ", rwpCmdBlk[k]); + pr2serr("\n"); + } + + ptvp = construct_scsi_pt_obj(); + if (NULL == ptvp) { + pr2serr("Reset write pointer: out of memory\n"); + return -1; + } + set_scsi_pt_cdb(ptvp, rwpCmdBlk, sizeof(rwpCmdBlk)); + set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b)); + res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose); + ret = sg_cmds_process_resp(ptvp, "reset write pointer", res, 0, sense_b, + noisy, verbose, &sense_cat); + if (-1 == ret) + ; + else if (-2 == ret) { + switch (sense_cat) { + case SG_LIB_CAT_RECOVERED: + case SG_LIB_CAT_NO_SENSE: + ret = 0; + break; + default: + ret = sense_cat; + break; + } + } else + ret = 0; + destruct_scsi_pt_obj(ptvp); + return ret; +} + + +int +main(int argc, char * argv[]) +{ + int sg_fd, res, c; + int reset_all = 0; + int verbose = 0; + int zid_given = 0; + uint64_t zid = 0; + int64_t ll; + const char * device_name = NULL; + int ret = 0; + + while (1) { + int option_index = 0; + + c = getopt_long(argc, argv, "hRvVz:", long_options, + &option_index); + if (c == -1) + break; + + switch (c) { + case 'h': + case '?': + usage(); + return 0; + case 'R': + ++reset_all; + break; + case 'v': + ++verbose; + break; + case 'V': + pr2serr("version: %s\n", version_str); + return 0; + case 'z': + ll = sg_get_llnum(optarg); + if (-1 == ll) { + fprintf(stderr, "bad argument to '--zone=ID'\n"); + return SG_LIB_SYNTAX_ERROR; + } + zid = (uint64_t)ll; + ++zid_given; + break; + default: + pr2serr("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) + pr2serr("Unexpected extra argument: %s\n", + argv[optind]); + usage(); + return SG_LIB_SYNTAX_ERROR; + } + } + + if ((! zid_given) && (0 == reset_all)) { + pr2serr("either the --zone=ID or --reset-all option is required\n"); + usage(); + return SG_LIB_SYNTAX_ERROR; + } + if (NULL == device_name) { + pr2serr("missing device name!\n"); + usage(); + return SG_LIB_SYNTAX_ERROR; + } + + sg_fd = sg_cmds_open_device(device_name, 0, verbose); + if (sg_fd < 0) { + pr2serr("open error: %s: %s\n", device_name, + safe_strerror(-sg_fd)); + return SG_LIB_FILE_ERROR; + } + + res = sg_ll_reset_write_pointer(sg_fd, zid, reset_all, 1, verbose); + ret = res; + if (res) { + if (SG_LIB_CAT_INVALID_OP == res) + pr2serr("Reset write pointer command not supported\n"); + else { + char b[80]; + + sg_get_category_sense_str(res, sizeof(b), b, verbose); + pr2serr("Reset write pointer command: %s\n", b); + } + } + + res = sg_cmds_close_device(sg_fd); + if (res < 0) { + pr2serr("close error: %s\n", safe_strerror(-res)); + if (0 == ret) + return SG_LIB_FILE_ERROR; + } + return (ret >= 0) ? ret : SG_LIB_CAT_OTHER; +} diff --git a/src/sg_vpd.c b/src/sg_vpd.c index 0cb1cfef..84e9c248 100644 --- a/src/sg_vpd.c +++ b/src/sg_vpd.c @@ -33,7 +33,7 @@ */ -static const char * version_str = "0.85 20140522"; /* spc4r37 + sbc4r01 */ +static const char * version_str = "0.86 20140527"; /* spc4r37 + sbc4r01 */ /* And with sbc3r35, vale Mark Evans */ void svpd_enumerate_vendor(int vp_num); @@ -664,7 +664,7 @@ const char * sg_ansi_version_arr[] = "SPC-2", "SPC-3", "SPC-4", - "reserved [7h]", + "SPC-5", "ecma=1, [8h]", "ecma=1, [9h]", "ecma=1, [Ah]", @@ -2410,9 +2410,9 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt) printf(": reserved\n"); break; } - printf(" HAW_ZBC=%d\n", buff[8] & 0x10); /* sbc4r01 */ - printf(" FUAB=%d\n", buff[8] & 0x2); - printf(" VBULS=%d\n", buff[8] & 0x1); + printf(" HAW_ZBC=%d\n", !!(buff[8] & 0x10)); /* sbc4r01 */ + printf(" FUAB=%d\n", !!(buff[8] & 0x2)); + printf(" VBULS=%d\n", !!(buff[8] & 0x1)); break; case PDT_TAPE: case PDT_MCHANGER: case PDT_ADC: printf(" Manufacturer-assigned serial number: %.*s\n", |