Hello community, here is the log from the commit of package hdparm for openSUSE:Factory checked in at 2012-01-09 16:22:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hdparm (Old) and /work/SRC/openSUSE:Factory/.hdparm.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hdparm", Maintainer is "[email protected]" Changes: -------- --- /work/SRC/openSUSE:Factory/hdparm/hdparm.changes 2011-10-04 18:11:34.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.hdparm.new/hdparm.changes 2012-01-09 16:22:53.000000000 +0100 @@ -1,0 +2,8 @@ +Sun Jan 8 19:51:06 UTC 2012 - [email protected] + +- update to hdparm-9.38 + - updated wiper.sh to allow all SCSI_DISK major numbers + - updated handing for very long SECURITY-ERASE times + - added -J flag for wdidle3 set/get + +------------------------------------------------------------------- Old: ---- hdparm-9.37.tar.gz New: ---- hdparm-9.38.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hdparm.spec ++++++ --- /var/tmp/diff_new_pack.Sn1Viu/_old 2012-01-09 16:22:56.000000000 +0100 +++ /var/tmp/diff_new_pack.Sn1Viu/_new 2012-01-09 16:22:56.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package hdparm # -# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -15,18 +15,15 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # -# norootforbuild - Name: hdparm -License: PERMISSIVE-OSI-COMPLIANT -Group: Hardware/Other PreReq: %insserv_prereq %fillup_prereq coreutils Provides: base:/sbin/hdparm -AutoReqProv: on -Version: 9.37 -Release: 1 +Version: 9.38 +Release: 0 Summary: A Program to get and set hard disk parameters +License: PERMISSIVE-OSI-COMPLIANT +Group: Hardware/Other Source: http://sourceforge.net/projects/hdparm/files/hdparm/%{name}-%{version}.tar.gz Source1: 56-idedma.rules Source2: sysconfig.ide ++++++ hdparm-9.37.tar.gz -> hdparm-9.38.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/Changelog new/hdparm-9.38/Changelog --- old/hdparm-9.37/Changelog 2011-01-24 16:15:10.000000000 +0100 +++ new/hdparm-9.38/Changelog 2012-01-06 17:47:10.000000000 +0100 @@ -1,3 +1,7 @@ +9.37+ + - updated wiper.sh to allow all SCSI_DISK major numbers + - updated handing for very long SECURITY-ERASE times + - added -J flag for wdidle3 set/get hdparm-9.37 - handle raid1 start_lba values, and show -1 for indeterminte raid start_lba values - abort --fibmap when start_lba is indeterminate diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/Makefile new/hdparm-9.38/Makefile --- old/hdparm-9.37/Makefile 2011-01-08 15:56:44.000000000 +0100 +++ new/hdparm-9.38/Makefile 2012-01-06 17:05:37.000000000 +0100 @@ -22,7 +22,7 @@ INSTALL_DIR = $(INSTALL) -m 755 -d INSTALL_PROGRAM = $(INSTALL) -OBJS = hdparm.o identify.o sgio.o sysfs.o geom.o fallocate.o fibmap.o fwdownload.o dvdspeed.o +OBJS = hdparm.o identify.o sgio.o sysfs.o geom.o fallocate.o fibmap.o fwdownload.o dvdspeed.o wdidle3.o all: hdparm diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/contrib/wdidle3_trace.txt new/hdparm-9.38/contrib/wdidle3_trace.txt --- old/hdparm-9.37/contrib/wdidle3_trace.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/hdparm-9.38/contrib/wdidle3_trace.txt 2012-01-07 21:52:53.000000000 +0100 @@ -0,0 +1,255 @@ +These are FIS (SATA Frame Information Structures) traces captured with a SATA analyser +when using the WDIDLE3-1.03 program under DOS. I do not know the sequence that these +four traces were done in, which may affect the exact actions/values used. + + +---------------------------------------------------------------------------------------------------------------------------------------------------- + +wdidle3-report.sata: report state of the idle3 timer: + +RESET_DEVICE: +fis: 27 00 80 44 01 00 00 00 00 00 00 d5 01 00 00 06 00 00 00 00 +fis: 27 00 80 44 01 00 00 00 00 00 00 d5 01 00 00 02 00 00 00 00 + +IDENTIFY_DEVICE: +fis: 27 80 ec 44 01 00 00 a0 00 00 00 d5 01 00 00 02 00 00 00 00 +data_in: + 0: 7a 42 ff 3f 37 c8 10 00 00 00 00 00 3f 00 00 00 00 00 00 00 20 20 20 20 57 20 2d 44 4d 57 56 41 30 35 32 33 35 36 36 38 00 00 ff ff 32 00 31 30 + 48: 30 2e 41 30 31 30 44 57 20 43 44 57 30 35 30 30 41 41 53 44 30 2d 4d 30 42 32 20 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 80 + 96: 00 00 00 2f 01 40 00 00 00 00 07 00 ff 3f 10 00 3f 00 10 fc fb 00 00 01 ff ff ff 0f 00 00 07 00 03 00 78 00 78 00 78 00 78 00 00 00 00 00 00 00 +144: 00 00 00 00 00 00 1f 00 06 17 00 00 44 00 40 00 fe 01 00 00 6b 74 61 7f 23 41 69 74 41 bc 23 41 7f 40 4a 00 4a 00 00 00 fe ff 00 00 fe 80 00 00 +192: 00 00 00 00 00 00 00 00 30 60 38 3a 00 00 00 00 00 00 00 00 00 00 00 00 01 50 e0 4e 81 ac a1 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1c 40 +240: 1c 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 00 00 ce 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 +288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +336: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +384: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 37 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +432: 00 00 00 00 00 00 00 00 00 00 00 00 1e 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 10 00 00 00 00 00 00 00 00 +480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a5 60 + +VSC_ENABLE: +fis: 27 80 80 45 01 44 57 a0 00 00 00 44 00 00 00 02 00 00 00 00 + +SMART_WRITE_LOG: +fis: 27 80 b0 d6 be 4f c2 a0 01 44 57 45 01 00 00 02 00 00 00 00 +data_out: 57 00 1a 00.. + +SMART_READ_LOG: +fis: 27 80 b0 d5 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_in: 40 1f 00 00.. + +SMART_WRITE_LOG: +fis: 27 80 b0 d6 be 4f c2 a0 bf 00 00 d5 01 00 00 02 00 00 00 00 +data_out: 2a 00 01 00 02 00 0d 00 16 00 01 00.. + +SMART_READ_LOG: +fis: 27 80 b0 d5 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_in: 50 00.. + +VSC_DISABLE: +fis: 27 80 80 44 bf 44 57 a0 00 00 00 d5 00 00 00 02 00 00 00 00 + +---------------------------------------------------------------------------------------------------------------------------------------------------- + +wdidle3-disable.sata: completely disable the idle3 timer: + +RESET, +IDENTIFY: +fis: 27 80 ec 44 01 00 00 a0 00 00 00 d5 01 00 00 02 00 00 00 00 +data_in: + 0: 7a 42 ff 3f 37 c8 10 00 00 00 00 00 3f 00 00 00 00 00 00 00 20 20 20 20 57 20 2d 44 4d 57 56 41 30 35 32 33 35 36 36 38 00 00 ff ff 32 00 31 30 + 48: 30 2e 41 30 31 30 44 57 20 43 44 57 30 35 30 30 41 41 53 44 30 2d 4d 30 42 32 20 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 80 + 96: 00 00 00 2f 01 40 00 00 00 00 07 00 ff 3f 10 00 3f 00 10 fc fb 00 00 01 ff ff ff 0f 00 00 07 00 03 00 78 00 78 00 78 00 78 00 00 00 00 00 00 00 +144: 00 00 00 00 00 00 1f 00 06 17 00 00 44 00 40 00 fe 01 00 00 6b 74 61 7f 23 41 69 74 41 bc 23 41 7f 40 4a 00 4a 00 00 00 fe ff 00 00 fe 80 00 00 +192: 00 00 00 00 00 00 00 00 30 60 38 3a 00 00 00 00 00 00 00 00 00 00 00 00 01 50 e0 4e 81 ac a1 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1c 40 +240: 1c 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 00 00 ce 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 +288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +336: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +384: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 37 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +432: 00 00 00 00 00 00 00 00 00 00 00 00 1e 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 10 00 00 00 00 00 00 00 00 +480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a5 60 + +vSC_ENABLE: +fis: 27 80 80 45 01 44 57 a0 00 00 00 44 00 00 00 02 00 00 00 00 + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 01 44 57 45 01 00 00 02 00 00 00 00 +data_out: 57 00 1b 00.. + +SMART: +fis: 27 80 b0 d6 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_out: + 0: 00 00 00 00 f2 0b 00 00 d3 de 43 00 ff ff ff ff 00 00 00 00 78 57 55 00 3c 2d 4c 00 60 70 4b 00 63 70 4b 00 00 00 00 00 00 00 00 00 f2 0b 00 00 + 48: d4 2e 4c 00 60 70 4b 00 d0 67 4c 00 08 60 4c 00 6e 4f 44 00 63 70 4b 00 14 00 00 00 14 00 00 00 f2 0b 00 00 b2 80 43 00 64 00 00 00 a0 00 00 00 + 96: 50 40 55 00 73 00 83 00 73 00 63 00 e8 06 00 00 d4 33 03 00 00 00 00 00 00 00 00 00 00 00 00 00 b7 01 87 01 83 00 83 00 e8 06 00 00 38 00 00 00 +144: d4 2d 4c 00 a4 2d 4c 00 21 00 00 00 19 00 00 00 00 00 00 00 00 03 00 00 46 32 21 00 00 00 6e 0d 15 00 c3 00 22 04 00 00 00 00 00 00 73 00 af 01 +192: 73 00 63 00 0c 2e 4c 00 d4 33 03 00 00 00 00 00 00 00 00 00 00 00 00 00 b7 01 00 00 af 01 d3 00 0c 2e 4c 00 00 00 00 00 0c 2e 4c 00 fc 2d 4c 00 +240: 21 00 00 00 21 00 00 00 00 00 4b 00 00 30 00 00 02 30 21 00 c2 55 6a 0d 08 00 c3 00 8a 3e 00 00 69 61 4c 00 00 00 00 00 00 00 00 00 e4 23 00 00 +288: 01 00 00 00 19 00 00 00 c2 55 4b 00 01 68 00 00 02 30 4c 00 00 00 00 00 00 00 00 00 4c 2e 00 24 01 31 00 00 b7 01 00 00 00 00 00 00 af 01 00 00 +336: af 01 00 00 00 32 00 00 00 00 00 00 12 2b 00 00 58 18 48 00 a7 01 00 00 5d 18 48 00 01 00 00 00 f0 a9 47 00 19 00 00 00 69 61 4c 00 86 00 00 00 +384: c2 55 4b 00 00 06 00 00 0a 00 00 00 05 9a 47 00 d7 80 4a 00 70 5c 47 00 44 2f 4c 00 00 0a 00 00 ac 2e 4c 00 7c 5c 47 00 73 2e 4c 00 05 9b 47 00 +432: c2 55 4b 00 f1 ff ff ff ff ff ff ff d0 67 4c 00 18 00 00 00 d0 73 20 00 d0 67 4c 00 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +480: 00 00 00 00 00 00 00 00 00 51 43 00 ef 20 46 00 cd 01 00 00 f7 20 46 00 14 00 00 00 14 00 00 00 + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 bf 00 00 d6 01 01 00 02 00 00 00 00 +data_out: 57 00 1a 00.. + +SMART: +fis: 27 80 b0 d5 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_in: 01 00.. + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 bf 00 00 d5 01 00 00 02 00 00 00 00 +data_out: 2a 00 02 00 02 00 0d 00 16 00 01 00.. + +SMART: +fis: 27 80 b0 d6 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_out: fc 2c 4c 00 01 + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 bf 00 00 d6 01 01 00 02 00 00 00 00 +data_out: 2a 00 01 00 02 00 0d 00 16 00 01 00.. + +SMART: +fis: 27 80 b0 d5 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_in: fc 00.. + +VSC_DISABLE: +fis: 27 80 80 44 bf 44 57 a0 00 00 00 d5 00 00 00 02 00 00 00 00 + +---------------------------------------------------------------------------------------------------------------------------------------------------- + +wdidle3-300.sata: set idle3 timeout to 300 seconds. + +IDENTIFY: +data_in: + 0: 7a 42 ff 3f 37 c8 10 00 00 00 00 00 3f 00 00 00 00 00 00 00 20 20 20 20 57 20 2d 44 4d 57 56 41 30 35 32 33 35 36 36 38 00 00 ff ff 32 00 31 30 + 48: 30 2e 41 30 31 30 44 57 20 43 44 57 30 35 30 30 41 41 53 44 30 2d 4d 30 42 32 20 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 80 + 96: 00 00 00 2f 01 40 00 00 00 00 07 00 ff 3f 10 00 3f 00 10 fc fb 00 00 01 ff ff ff 0f 00 00 07 00 03 00 78 00 78 00 78 00 78 00 00 00 00 00 00 00 +144: 00 00 00 00 00 00 1f 00 06 17 00 00 44 00 40 00 fe 01 00 00 6b 74 61 7f 23 41 69 74 41 bc 23 41 7f 40 4a 00 4a 00 00 00 fe ff 00 00 fe 80 00 00 +192: 00 00 00 00 00 00 00 00 30 60 38 3a 00 00 00 00 00 00 00 00 00 00 00 00 01 50 e0 4e 81 ac a1 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1c 40 +240: 1c 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 00 00 ce 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 +288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +336: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +384: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 37 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +432: 00 00 00 00 00 00 00 00 00 00 00 00 1e 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 10 00 00 00 00 00 00 00 00 +480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a5 60 + +VSC_ENABLE: +fis: 27 80 80 45 01 44 57 a0 00 00 00 44 00 00 00 02 00 00 00 00 + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 01 44 57 45 01 00 00 02 00 00 00 00 +data_out: 57 00 1b 00.. + +SMART: +fis: 27 80 b0 d6 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_out: + 0: e0 93 04 00 f2 0b 00 00 d3 de 43 00 ff ff ff ff 00 00 00 00 78 57 55 00 3c 2d 4c 00 60 70 4b 00 66 70 4b 00 00 00 00 00 00 00 00 00 f2 0b 00 00 + 48: d4 2e 4c 00 60 70 4b 00 d8 67 4c 00 08 60 4c 00 6e 4f 44 00 66 70 4b 00 14 00 00 00 14 00 00 00 f2 0b 00 00 b2 80 43 00 64 00 00 00 a0 00 00 00 + 96: 50 40 55 00 73 00 83 00 73 00 63 00 e8 06 00 00 d4 33 03 00 00 00 00 00 00 00 00 00 00 00 00 00 b7 01 87 01 83 00 83 00 e8 06 00 00 38 00 00 00 +144: d4 2d 4c 00 a4 2d 4c 00 21 00 00 00 19 00 00 00 00 00 00 00 00 03 00 00 46 32 21 00 00 00 6e 0d 15 00 c3 00 22 04 00 00 00 00 00 00 00 00 46 32 +192: d8 2d 46 32 00 02 00 00 00 03 00 00 46 32 00 00 46 32 00 00 00 03 00 00 81 00 00 00 e8 06 00 00 71 61 4c 00 1c 2e 4c 00 f8 2d 4c 00 21 00 00 00 +240: 19 00 00 00 19 00 00 00 01 ff 00 00 b7 01 00 00 87 01 00 00 83 00 00 00 af 01 00 00 b6 05 00 00 37 01 00 00 00 32 00 00 c3 05 00 00 60 00 00 00 +288: 19 00 00 00 01 00 00 00 58 61 4c 00 3c 2e 4c 00 01 00 00 00 58 61 4c 00 19 00 00 00 19 00 00 00 b7 01 00 00 00 00 00 00 af 01 00 00 af 01 00 00 +336: 1f 01 48 00 a7 01 00 00 44 32 00 00 19 00 00 00 00 00 00 00 58 61 4c 00 19 00 00 00 c2 55 4b 00 59 a9 47 00 19 00 00 00 71 61 4c 00 86 00 00 00 +384: c2 55 4b 00 00 06 00 00 0a 00 00 00 05 9a 47 00 d7 80 4a 00 70 5c 47 00 44 2f 4c 00 00 0a 00 00 ac 2e 4c 00 7c 5c 47 00 73 2e 4c 00 05 9b 47 00 +432: c2 55 4b 00 f1 ff ff ff ff ff ff ff d8 67 4c 00 18 00 00 00 d8 73 20 00 d8 67 4c 00 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +480: 00 00 00 00 00 00 00 00 00 51 43 00 ef 20 46 00 17 02 00 00 f7 20 46 00 14 00 00 00 14 00 00 00 + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 bf 00 00 d6 01 01 00 02 00 00 00 00 +data_out: 57 00 1a 00.. + +SMART: +fis: 27 80 b0 d5 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_in: e0 93 04 00.. + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 bf 00 00 d5 01 00 00 02 00 00 00 00 +data_out: 2a 00 02 00 02 00 0d 00 16 00 01 00.. + +SMART: +fis: 27 80 b0 d6 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data: 8a 2c 4c 00 e0 93 04 00.. + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 bf 00 00 d6 01 01 00 02 00 00 00 00 +data_out: 2a 00 01 00 02 00 0d 00 16 00 01 00 + +SMART: +fis: 27 80 b0 d5 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_in: 8a 00.. + +VSC_DISABLE: +fis: 27 80 80 44 bf 44 57 a0 00 00 00 d5 00 00 00 02 00 00 00 00 + +---------------------------------------------------------------------------------------------------------------------------------------------------- + +wdidle3-30.5.sata: change idle3 timeout to 30.5(?) seconds. + +IDENTIFY: +fis: 27 80 ec 44 01 00 00 a0 00 00 00 d5 01 00 00 02 00 00 00 00 +data_in: + 0: 7a 42 ff 3f 37 c8 10 00 00 00 00 00 3f 00 00 00 00 00 00 00 20 20 20 20 57 20 2d 44 4d 57 56 41 30 35 32 33 35 36 36 38 00 00 ff ff 32 00 31 30 + 48: 30 2e 41 30 31 30 44 57 20 43 44 57 30 35 30 30 41 41 53 44 30 2d 4d 30 42 32 20 30 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 10 80 + 96: 00 00 00 2f 01 40 00 00 00 00 07 00 ff 3f 10 00 3f 00 10 fc fb 00 00 01 ff ff ff 0f 00 00 07 00 03 00 78 00 78 00 78 00 78 00 00 00 00 00 00 00 +144: 00 00 00 00 00 00 1f 00 06 17 00 00 44 00 40 00 fe 01 00 00 6b 74 61 7f 23 41 69 74 41 bc 23 41 7f 40 4a 00 4a 00 00 00 fe ff 00 00 fe 80 00 00 +192: 00 00 00 00 00 00 00 00 30 60 38 3a 00 00 00 00 00 00 00 00 00 00 00 00 01 50 e0 4e 81 ac a1 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1c 40 +240: 1c 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 00 00 ce 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 +288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +336: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +384: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 37 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +432: 00 00 00 00 00 00 00 00 00 00 00 00 1e 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 10 00 00 00 00 00 00 00 00 +480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a5 60 + +VSC_ENABLE: +fis: 27 80 80 45 01 44 57 a0 00 00 00 44 00 00 00 02 00 00 00 00 + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 01 44 57 45 01 00 00 02 00 00 00 00 +data_out: 57 00 1b 00.. + +SMART: +fis: 27 80 b0 d6 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_out: + 0: 24 77 00 00 f2 0b 00 00 d3 de 43 00 ff ff ff ff 00 00 00 00 78 57 55 00 3c 2d 4c 00 60 70 4b 00 67 70 4b 00 00 00 00 00 00 00 00 00 f2 0b 00 00 + 48: d4 2e 4c 00 60 70 4b 00 d8 67 4c 00 08 60 4c 00 6e 4f 44 00 67 70 4b 00 14 00 00 00 14 00 00 00 f2 0b 00 00 b2 80 43 00 64 00 00 00 a0 00 00 00 + 96: 50 40 55 00 73 00 83 00 73 00 63 00 e8 06 00 00 d4 33 03 00 00 00 00 00 00 00 00 00 00 00 00 00 b7 01 87 01 83 00 83 00 e8 06 00 00 38 00 00 00 +144: d4 2d 4c 00 a4 2d 4c 00 21 00 00 00 19 00 00 00 00 00 00 00 00 03 00 00 46 32 21 00 00 00 6e 0d 15 00 c3 00 22 04 00 00 00 00 00 00 00 00 46 32 +192: d8 2d 46 32 00 02 00 00 00 03 00 00 46 32 00 00 46 32 00 00 00 03 00 00 81 00 00 00 e8 06 00 00 71 61 4c 00 1c 2e 4c 00 f8 2d 4c 00 21 00 00 00 +240: 19 00 00 00 19 00 00 00 01 ff 00 00 b7 01 00 00 87 01 00 00 83 00 00 00 af 01 00 00 b6 05 00 00 37 01 00 00 00 32 00 00 c3 05 00 00 60 00 00 00 +288: 19 00 00 00 01 00 00 00 58 61 4c 00 3c 2e 4c 00 01 00 00 00 58 61 4c 00 19 00 00 00 19 00 00 00 b7 01 00 00 00 00 00 00 af 01 00 00 af 01 00 00 +336: 1f 01 48 00 a7 01 00 00 44 32 00 00 19 00 00 00 00 00 00 00 58 61 4c 00 19 00 00 00 c2 55 4b 00 59 a9 47 00 19 00 00 00 71 61 4c 00 86 00 00 00 +384: c2 55 4b 00 00 06 00 00 0a 00 00 00 05 9a 47 00 d7 80 4a 00 70 5c 47 00 44 2f 4c 00 00 0a 00 00 ac 2e 4c 00 7c 5c 47 00 73 2e 4c 00 05 9b 47 00 +432: c2 55 4b 00 f1 ff ff ff ff ff ff ff d8 67 4c 00 18 00 00 00 d8 73 20 00 d8 67 4c 00 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +480: 00 00 00 00 00 00 00 00 00 51 43 00 ef 20 46 00 4c 02 00 00 f7 20 46 00 14 00 00 00 14 00 00 00 + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 bf 00 00 d6 01 01 00 02 00 00 00 00 +data_out: 57 00 1a 00.. + +SMART: +fis: 27 80 b0 d5 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_in: 24 77 00.. + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 bf 00 00 d5 01 00 00 02 00 00 00 00 +data_out: 2A 00 02 00 02 00 0D 00 16 00 01 00.. + +SMART: +fis: 27 80 b0 d6 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_out: 81 2c 4c 00 24 77 00 + +SMART: +fis: 27 80 b0 d6 be 4f c2 a0 bf 00 00 d6 01 01 00 02 00 00 00 00 +data_out: 2a 00 01 00 02 00 0d 00 16 00 01 00.. + +SMART: +fis: 27 80 b0 d5 bf 4f c2 a0 00 01 00 d6 01 00 00 02 00 00 00 00 +data_in: 81 00.. + +VSC_DISABLE: +fis: 27 80 80 44 bf 44 57 a0 00 00 00 d5 00 00 00 02 + +---------------------------------------------------------------------------------------------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/hdparm.8 new/hdparm-9.38/hdparm.8 --- old/hdparm-9.37/hdparm.8 2010-11-11 15:35:57.000000000 +0100 +++ new/hdparm-9.38/hdparm.8 2012-01-07 22:58:56.000000000 +0100 @@ -1,4 +1,4 @@ -.TH HDPARM 8 "November 2010" "Version 9.36" +.TH HDPARM 8 "January 2012" "Version 9.38" .SH NAME hdparm \- get/set SATA/IDE device parameters @@ -308,6 +308,31 @@ .B --Istdin option. .TP +.I -J +Get/set the Western Digital (WD) Green Drive's "idle3" timeout value. +This timeout controls how often the drive parks its heads and enters +a low power consumption state. The factory default is eight (8) seconds, +which is a very poor choice for use with Linux. Leaving it at the default +will result in hundreds of thousands of head load/unload cycles in a very +short period of time. The drive mechanism is only rated for 300,000 to 1,000,000 +cycles, so leaving it at the default could result in premature failure, +not to mention the performance impact of the drive often having to wake-up +before doing routine I/O. +.IP +WD supply a WDIDLE3.EXE DOS utility for tweaking this setting, +and you should use that program instead of hdparm +if at all possible. The reverse-engineered implementation in hdparm +is not as complete as the original official program, even though it does +seem to work on at a least a few drives. A full power cycle is required +for any change in setting to take effect, regardless of which program is +used to tweak things. +.IP +A setting of 30 seconds is recommended for Linux use. +Permitted values are from 8 to 12 seconds, and from 30 to 300 seconds +in 30-second increments. +Specify a value of zero (0) to disable the WD idle3 timer completely +(NOT RECOMMENDED!). +.TP .I -k Get/set the "keep_settings_over_reset" flag for the drive. When this flag is set, the drive will preserve the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/hdparm.c new/hdparm-9.38/hdparm.c --- old/hdparm-9.37/hdparm.c 2011-01-24 16:15:17.000000000 +0100 +++ new/hdparm-9.38/hdparm.c 2012-01-07 22:57:24.000000000 +0100 @@ -35,7 +35,7 @@ extern const char *minor_str[]; -#define VERSION "v9.37" +#define VERSION "v9.38" #ifndef O_DIRECT #define O_DIRECT 040000 /* direct disk access, not easily obtained from headers */ @@ -55,7 +55,7 @@ static int do_identity = 0, get_geom = 0, noisy = 1, quiet = 0; static int do_flush_wcache = 0; -//static int set_wdidle3 = 0; +static int set_wdidle3 = 0, get_wdidle3 = 0, wdidle3 = 0; static int set_timings_offset = 0; static __u64 timings_offset = 0; static int set_fsreadahead= 0, get_fsreadahead= 0, fsreadahead= 0; @@ -706,15 +706,25 @@ if (id) { timeout = id[idx]; if (timeout && timeout <= 0xff) { - if (timeout == 0xff) + /* + * 0xff means "more than 254 2-minute intervals (508+ minutes), + * but we really want a better idea than that. + * Norman Diamond suggests allowing 1sec per 30MB of capacity. + */ + if (timeout == 0xff) { + __u64 lba_limit = get_lba_capacity(id); + __u64 estimate = (lba_limit / 2048ULL) / 30ULL / 60; timeout = 508 + 60; /* spec says > 508 minutes */ - else + if (timeout < estimate) + timeout = estimate; + } else { timeout = (timeout * 2) + 5; /* Add on a 5min margin */ + } } } if (!timeout) timeout = 2 * 60; /* default: two hours */ - timeout *= 60; /* secs */ + timeout *= 60; /* convert minutes to seconds */ return timeout; } @@ -778,7 +788,7 @@ exit(EINVAL); } printf(" Issuing %s command, password=\"%s\", user=%s", - description, security_password, data[0] ? "master" : "user"); + description, security_password, (data[0] & 1) ? "master" : "user"); if (security_command == ATA_OP_SECURITY_SET_PASS) printf(", mode=%s", data[1] ? "max" : "high"); printf("\n"); @@ -949,44 +959,6 @@ exit(EINVAL); } -#if 0 -static int do_wdidle3 (int fd, const char *devname) -{ - struct ata_tf tf; - int err = 0; - const unsigned char vu_op = 0x8a; - - abort_if_not_full_device(fd, 0, devname, NULL); - confirm_please_destroy_my_drive("--wdidle3", "This is not fully implemented yet, and could destroy the drive and/or all data on it."); - printf("attempting to tweak Western Digital \"idle-3\" parameters\n"); - fflush(stdout); - - { - unsigned char bits; - for (bits = 0; bits <= 0x1f; ++bits) { - tf_init(&tf, vu_op, 0, 0); - tf.lob.feat = 'W'; - tf.lob.nsect = 'D'; - tf.lob.lbal = 'C'; - tf.lob.lbam = 0x00; - tf.lob.lbah = 0x00; - tf.dev = 0xa0 | (tf.dev & 0xb0) | (bits & 0xf); - if (bits >= 0x10) - tf.dev |= 0x40; - - /* This probably wants to transfer data, but.. ???? */ - if (sg16(fd, SG_WRITE, SG_PIO, &tf, NULL, 0, 5 /* seconds */)) { - err = errno; - perror("FAILED"); - } else { - printf("succeeded\n"); - } - } - } - return err; -} -#endif - static __u16 *get_dco_identify_data (int fd, int quietly) { static __u8 args[4+512]; @@ -1016,6 +988,9 @@ __u64 max = 0; struct hdio_taskfile r; + get_identify_data(fd); + if (!id) + exit(EIO); memset(&r, 0, sizeof(r)); r.cmd_req = TASKFILE_CMD_REQ_NODATA; r.dphase = TASKFILE_DPHASE_NONE; @@ -1027,9 +1002,6 @@ r.iflags.lob.lbah = 1; r.lob.dev = 0x40; - get_identify_data(fd); - if (!id) - exit(EIO); if (((id[83] & 0xc400) == 0x4400) && (id[86] & 0x0400)) { r.iflags.hob.lbal = 1; r.iflags.hob.lbam = 1; @@ -1466,6 +1438,7 @@ " -H Read temperature from drive (Hitachi only)\n" " -i Display drive identification\n" " -I Detailed/current information directly from drive\n" + " -J Get/set Western DIgital \"Idle3\" timeout for a WDC \"Green\" drive (DANGEROUS)\n" " -k Get/set keep_settings_over_reset flag (0/1)\n" " -K Set drive keep_features_over_reset flag (0/1)\n" " -L Set drive doorlock (0/1) (removable harddisks only)\n" @@ -1518,7 +1491,6 @@ " --trim-sector-ranges Tell SSD firmware to discard unneeded data sectors: lba:count ..\n" " --trim-sector-ranges-stdin Same as above, but reads lba:count pairs from stdin\n" " --verbose Display extra diagnostics from some commands\n" - //" --wdidle3 Issue the Western Digitial \"Idle3\" command (EXTREMELY DANGEROUS)\n" " --write-sector Repair/overwrite a (possibly bad) sector directly on the media (VERY DANGEROUS)\n" "\n"); exit(rc); @@ -1578,8 +1550,16 @@ exit(do_trim_from_stdin(fd, devname)); } - //if (set_wdidle3) - // do_wdidle3(fd, devname); + if (set_wdidle3) { + unsigned char timeout = wdidle3_msecs_to_timeout(wdidle3); + confirm_please_destroy_my_drive("-J", "This implementation is not as thorough as the official WDIDLE3.EXE. Use at your own risk!"); + if (get_wdidle3) { + printf(" setting wdidle3 to "); + wdidle3_print_timeout(timeout); + putchar('\n'); + } + err = wdidle3_set_timeout(fd, timeout); + } if (set_fsreadahead) { if (get_fsreadahead) printf(" setting fs readahead to %d\n", fsreadahead); @@ -2149,6 +2129,15 @@ printf("%lld\n", start_lba); } } + if (get_wdidle3) { + unsigned char timeout = 0; + err = wdidle3_get_timeout(fd, &timeout); + if (!err) { + printf(" wdidle3 = "); + wdidle3_print_timeout(timeout); + putchar('\n'); + } + } if (get_powermode) { __u8 args[4] = {ATA_OP_CHECKPOWERMODE1,0,0,0}; const char *state = "unknown"; @@ -2670,8 +2659,6 @@ } else if (0 == strcasecmp(name, "read-sector")) { read_sector = 1; get_u64_parm(0, 0, NULL, &read_sector_addr, 0, lba_limit, name, lba_emsg); - //} else if (0 == strcasecmp(name, "wdidle3")) { - // set_wdidle3 = 1; } else if (0 == strcasecmp(name, "Istdout")) { do_IDentity = 2; } else if (0 == strcasecmp(name, "security-mode")) { @@ -2759,6 +2746,7 @@ case SET_FLAG('H',hitachi_temp); case DO_FLAG('i',do_identity); case DO_FLAG('I',do_IDentity); + case GET_SET_PARM('J',"WDC-idle3-timeout",wdidle3,0,300); case GET_SET_PARM('k',"kernel-keep-settings",keep,0,1); case SET_PARM('K',"drive-keep-settings",dkeep,0,1); case SET_PARM('L',"door-lock",doorlock,0,1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/hdparm.h new/hdparm-9.38/hdparm.h --- old/hdparm-9.37/hdparm.h 2010-11-24 22:54:19.000000000 +0100 +++ new/hdparm-9.38/hdparm.h 2012-01-06 17:38:59.000000000 +0100 @@ -25,6 +25,11 @@ int set_dvdspeed(int fd, int speed); int fd_is_raid (int fd); +int wdidle3_set_timeout (int fd, unsigned char timeout); +int wdidle3_get_timeout (int fd, unsigned char *timeout); +void wdidle3_print_timeout (unsigned char timeout); +unsigned char wdidle3_msecs_to_timeout (unsigned int msecs); + extern const char *BuffType[4]; struct local_hd_big_geometry { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/hdparm.lsm new/hdparm-9.38/hdparm.lsm --- old/hdparm-9.37/hdparm.lsm 2011-01-24 16:17:21.000000000 +0100 +++ new/hdparm-9.38/hdparm.lsm 2012-01-07 23:00:13.000000000 +0100 @@ -1,9 +1,10 @@ Begin4 Title: hdparm -Version: 9.37 -Entered-date: 2011-01-24 +Version: 9.38 +Entered-date: 2012-01-07 Description: hdparm - get/set hard disk parameters for Linux SATA/IDE drives. - v9.37 Enable --fibmap to work on RAID1; other tweaks. + v9.38 Added -J, fixed erase timeouts, updated wiper.sh + v9.37 Enable --fibmap to work on RAID1; other tweaks v9.36 manpage updates, wiper.sh version 3.1 v9.35 Fixed CDB breakage from v9.34; -B works again now v9.34 Fixed CDB transfer length bug that affected some commands @@ -111,7 +112,7 @@ Maintained-by: [email protected] (Mark Lord) Primary-site: http://sourceforge.net/projects/hdparm/ Alternate-site: http://www.ibiblio.org/pub/Linux/system/hardware - 122K hdparm-9.37.tar.gz + 131K hdparm-9.38.tar.gz 4K hdparm.lsm Platforms: Linux Copying-policy: BSD License diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/identify.c new/hdparm-9.38/identify.c --- old/hdparm-9.37/identify.c 2010-09-24 01:24:50.000000000 +0200 +++ new/hdparm-9.38/identify.c 2011-12-04 23:49:22.000000000 +0100 @@ -1330,8 +1330,20 @@ kk = val[ENH_ERASE_TIME]; if((jj && jj <= 0x00ff) || (kk && kk <= 0x00ff)) { printf("\t"); - if(jj) printf("%umin for SECURITY ERASE UNIT. ", (jj == 0xff) ? 508 : (jj * 2)); - if(kk) printf("%umin for ENHANCED SECURITY ERASE UNIT.", (kk == 0xff) ? 508 : (kk * 2)); + if (jj) { + if (jj == 0xff) + printf("more than 508"); + else + printf("%u", jj * 2); + printf("min for SECURITY ERASE UNIT. "); + } + if (kk) { + if (kk == 0xff) + printf("more than 508"); + else + printf("%u", kk * 2); + printf("min for ENHANCED SECURITY ERASE UNIT. "); + } printf("\n"); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/sgio.c new/hdparm-9.38/sgio.c --- old/hdparm-9.37/sgio.c 2010-10-19 15:10:00.000000000 +0200 +++ new/hdparm-9.38/sgio.c 2012-01-06 17:06:03.000000000 +0100 @@ -95,6 +95,8 @@ return 1; case ATA_OP_SECURITY_ERASE_PREPARE: case ATA_OP_SECURITY_ERASE_UNIT: + case ATA_OP_VENDOR_SPECIFIC_0x80: + case ATA_OP_SMART: return 0; } if (lba >= lba28_limit) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/sgio.c.orig new/hdparm-9.38/sgio.c.orig --- old/hdparm-9.37/sgio.c.orig 1970-01-01 01:00:00.000000000 +0100 +++ new/hdparm-9.38/sgio.c.orig 2010-10-19 15:10:00.000000000 +0200 @@ -0,0 +1,580 @@ +/* sgio.c - by Mark Lord (C) 2007 -- freely distributable */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <scsi/scsi.h> +#include <scsi/sg.h> + +#include "sgio.h" +#include "hdparm.h" + +#include <linux/hdreg.h> + +extern int verbose; +extern int prefer_ata12; + +static const int default_timeout_secs = 15; + +/* + * Taskfile layout for SG_ATA_16 cdb: + * + * LBA48: + * cdb[ 3] = hob_feat + * cdb[ 5] = hob_nsect + * cdb[ 7] = hob_lbal + * cdb[ 9] = hob_lbam + * cdb[11] = hob_lbah + * + * LBA28/LBA48: + * cdb[ 4] = feat + * cdb[ 6] = nsect + * cdb[ 8] = lbal + * cdb[10] = lbam + * cdb[12] = lbah + * cdb[13] = device + * cdb[14] = command + * + * Taskfile layout for SG_ATA_12 cdb: + * + * cdb[ 3] = feat + * cdb[ 4] = nsect + * cdb[ 5] = lbal + * cdb[ 6] = lbam + * cdb[ 7] = lbah + * cdb[ 8] = device + * cdb[ 9] = command + * + * dxfer_direction choices: + * SG_DXFER_TO_DEV, SG_DXFER_FROM_DEV, SG_DXFER_NONE + */ + +#if 0 /* maybe use this in sg16 later.. ? */ +static inline int get_rw (__u8 ata_op) +{ + switch (ata_op) { + case ATA_OP_DSM: + case ATA_OP_WRITE_PIO: + case ATA_OP_WRITE_LONG: + case ATA_OP_WRITE_LONG_ONCE: + case ATA_OP_WRITE_PIO_EXT: + case ATA_OP_WRITE_DMA_EXT: + case ATA_OP_WRITE_FPDMA: + case ATA_OP_WRITE_UNC_EXT: + case ATA_OP_WRITE_DMA: + case ATA_OP_SECURITY_UNLOCK: + case ATA_OP_SECURITY_DISABLE: + case ATA_OP_SECURITY_ERASE_UNIT: + case ATA_OP_SECURITY_SET_PASS: + return SG_WRITE; + default: + return SG_READ; + } +} +#endif + +static inline int needs_lba48 (__u8 ata_op, __u64 lba, unsigned int nsect) +{ + switch (ata_op) { + case ATA_OP_DSM: + case ATA_OP_READ_PIO_EXT: + case ATA_OP_READ_DMA_EXT: + case ATA_OP_WRITE_PIO_EXT: + case ATA_OP_WRITE_DMA_EXT: + case ATA_OP_READ_VERIFY_EXT: + case ATA_OP_WRITE_UNC_EXT: + case ATA_OP_READ_NATIVE_MAX_EXT: + case ATA_OP_SET_MAX_EXT: + case ATA_OP_FLUSHCACHE_EXT: + return 1; + case ATA_OP_SECURITY_ERASE_PREPARE: + case ATA_OP_SECURITY_ERASE_UNIT: + return 0; + } + if (lba >= lba28_limit) + return 1; + if (nsect) { + if (nsect > 0xff) + return 1; + if ((lba + nsect - 1) >= lba28_limit) + return 1; + } + return 0; +} + +static inline int is_dma (__u8 ata_op) +{ + switch (ata_op) { + case ATA_OP_DSM: + case ATA_OP_READ_DMA_EXT: + case ATA_OP_READ_FPDMA: + case ATA_OP_WRITE_DMA_EXT: + case ATA_OP_WRITE_FPDMA: + case ATA_OP_READ_DMA: + case ATA_OP_WRITE_DMA: + return SG_DMA; + default: + return SG_PIO; + } +} + +void tf_init (struct ata_tf *tf, __u8 ata_op, __u64 lba, unsigned int nsect) +{ + memset(tf, 0, sizeof(*tf)); + tf->command = ata_op; + tf->dev = ATA_USING_LBA; + tf->lob.lbal = lba; + tf->lob.lbam = lba >> 8; + tf->lob.lbah = lba >> 16; + tf->lob.nsect = nsect; + if (needs_lba48(ata_op, lba, nsect)) { + tf->is_lba48 = 1; + tf->hob.nsect = nsect >> 8; + tf->hob.lbal = lba >> 24; + tf->hob.lbam = lba >> 32; + tf->hob.lbah = lba >> 40; + } else { + tf->dev |= (lba >> 24) & 0x0f; + } +} + +#ifdef SG_IO + +__u64 tf_to_lba (struct ata_tf *tf) +{ + __u32 lba24, lbah; + __u64 lba64; + + lba24 = (tf->lob.lbah << 16) | (tf->lob.lbam << 8) | (tf->lob.lbal); + if (tf->is_lba48) + lbah = (tf->hob.lbah << 16) | (tf->hob.lbam << 8) | (tf->hob.lbal); + else + lbah = (tf->dev & 0x0f); + lba64 = (((__u64)lbah) << 24) | (__u64)lba24; + return lba64; +} + +enum { + SG_CDB2_TLEN_NODATA = 0 << 0, + SG_CDB2_TLEN_FEAT = 1 << 0, + SG_CDB2_TLEN_NSECT = 2 << 0, + + SG_CDB2_TLEN_BYTES = 0 << 2, + SG_CDB2_TLEN_SECTORS = 1 << 2, + + SG_CDB2_TDIR_TO_DEV = 0 << 3, + SG_CDB2_TDIR_FROM_DEV = 1 << 3, + + SG_CDB2_CHECK_COND = 1 << 5, +}; + +static void dump_bytes (const char *prefix, unsigned char *p, int len) +{ + int i; + + if (prefix) + fprintf(stderr, "%s: ", prefix); + for (i = 0; i < len; ++i) + fprintf(stderr, " %02x", p[i]); + fprintf(stderr, "\n"); +} + +int sg16 (int fd, int rw, int dma, struct ata_tf *tf, + void *data, unsigned int data_bytes, unsigned int timeout_secs) +{ + unsigned char cdb[SG_ATA_16_LEN]; + unsigned char sb[32], *desc; + struct scsi_sg_io_hdr io_hdr; + int prefer12 = prefer_ata12, demanded_sense = 0; + + if (tf->command == ATA_OP_PIDENTIFY) + prefer12 = 0; + + memset(&cdb, 0, sizeof(cdb)); + memset(&sb, 0, sizeof(sb)); + memset(&io_hdr, 0, sizeof(struct scsi_sg_io_hdr)); + if (data && data_bytes && !rw) + memset(data, 0, data_bytes); + + if (dma) { + //cdb[1] = data ? (rw ? SG_ATA_PROTO_UDMA_OUT : SG_ATA_PROTO_UDMA_IN) : SG_ATA_PROTO_NON_DATA; + cdb[1] = data ? SG_ATA_PROTO_DMA : SG_ATA_PROTO_NON_DATA; + } else { + cdb[1] = data ? (rw ? SG_ATA_PROTO_PIO_OUT : SG_ATA_PROTO_PIO_IN) : SG_ATA_PROTO_NON_DATA; + } + + /* libata/AHCI workaround: don't demand sense data for IDENTIFY commands */ + if (data) { + cdb[2] |= SG_CDB2_TLEN_NSECT | SG_CDB2_TLEN_SECTORS; + cdb[2] |= rw ? SG_CDB2_TDIR_TO_DEV : SG_CDB2_TDIR_FROM_DEV; + } else { + cdb[2] = SG_CDB2_CHECK_COND; + } + + if (!prefer12 || tf->is_lba48) { + cdb[ 0] = SG_ATA_16; + cdb[ 4] = tf->lob.feat; + cdb[ 6] = tf->lob.nsect; + cdb[ 8] = tf->lob.lbal; + cdb[10] = tf->lob.lbam; + cdb[12] = tf->lob.lbah; + cdb[13] = tf->dev; + cdb[14] = tf->command; + if (tf->is_lba48) { + cdb[ 1] |= SG_ATA_LBA48; + cdb[ 3] = tf->hob.feat; + cdb[ 5] = tf->hob.nsect; + cdb[ 7] = tf->hob.lbal; + cdb[ 9] = tf->hob.lbam; + cdb[11] = tf->hob.lbah; + } + io_hdr.cmd_len = SG_ATA_16_LEN; + } else { + cdb[ 0] = SG_ATA_12; + cdb[ 3] = tf->lob.feat; + cdb[ 4] = tf->lob.nsect; + cdb[ 5] = tf->lob.lbal; + cdb[ 6] = tf->lob.lbam; + cdb[ 7] = tf->lob.lbah; + cdb[ 8] = tf->dev; + cdb[ 9] = tf->command; + io_hdr.cmd_len = SG_ATA_12_LEN; + } + + io_hdr.interface_id = 'S'; + io_hdr.mx_sb_len = sizeof(sb); + io_hdr.dxfer_direction = data ? (rw ? SG_DXFER_TO_DEV : SG_DXFER_FROM_DEV) : SG_DXFER_NONE; + io_hdr.dxfer_len = data ? data_bytes : 0; + io_hdr.dxferp = data; + io_hdr.cmdp = cdb; + io_hdr.sbp = sb; + io_hdr.pack_id = tf_to_lba(tf); + io_hdr.timeout = (timeout_secs ? timeout_secs : default_timeout_secs) * 1000; /* msecs */ + + if (verbose) { + dump_bytes("outgoing cdb", cdb, sizeof(cdb)); + if (rw && data) + dump_bytes("outgoing_data", data, data_bytes); + } + + if (ioctl(fd, SG_IO, &io_hdr) == -1) { + if (verbose) + perror("ioctl(fd,SG_IO)"); + return -1; /* SG_IO not supported */ + } + + if (verbose) + fprintf(stderr, "SG_IO: ATA_%u status=0x%x, host_status=0x%x, driver_status=0x%x\n", + io_hdr.cmd_len, io_hdr.status, io_hdr.host_status, io_hdr.driver_status); + + if (io_hdr.status && io_hdr.status != SG_CHECK_CONDITION) { + if (verbose) + fprintf(stderr, "SG_IO: bad status: 0x%x\n", io_hdr.status); + errno = EBADE; + return -1; + } + if (io_hdr.host_status) { + if (verbose) + fprintf(stderr, "SG_IO: bad host status: 0x%x\n", io_hdr.host_status); + errno = EBADE; + return -1; + } + if (verbose) { + dump_bytes("SG_IO: sb[]", sb, sizeof(sb)); + if (!rw && data) + dump_bytes("incoming_data", data, data_bytes); + } + + if (io_hdr.driver_status && (io_hdr.driver_status != SG_DRIVER_SENSE)) { + if (verbose) + fprintf(stderr, "SG_IO: bad driver status: 0x%x\n", io_hdr.driver_status); + errno = EBADE; + return -1; + } + + desc = sb + 8; + if (io_hdr.driver_status != SG_DRIVER_SENSE) { + if (sb[0] | sb[1] | sb[2] | sb[3] | sb[4] | sb[5] | sb[6] | sb[7] | sb[8] | sb[9]) { + static int second_try = 0; + if (!second_try++) + fprintf(stderr, "SG_IO: questionable sense data, results may be incorrect\n"); + } else if (demanded_sense) { + static int second_try = 0; + if (!second_try++) + fprintf(stderr, "SG_IO: missing sense data, results may be incorrect\n"); + } + } else if (sb[0] != 0x72 || sb[7] < 14 || desc[0] != 0x09 || desc[1] < 0x0c) { + dump_bytes("SG_IO: bad/missing sense data, sb[]", sb, sizeof(sb)); + } + + if (verbose) { + unsigned int len = desc[1] + 2, maxlen = sizeof(sb) - 8 - 2; + if (len > maxlen) + len = maxlen; + dump_bytes("SG_IO: desc[]", desc, len); + } + + tf->is_lba48 = desc[ 2] & 1; + tf->error = desc[ 3]; + tf->lob.nsect = desc[ 5]; + tf->lob.lbal = desc[ 7]; + tf->lob.lbam = desc[ 9]; + tf->lob.lbah = desc[11]; + tf->dev = desc[12]; + tf->status = desc[13]; + tf->hob.feat = 0; + if (tf->is_lba48) { + tf->hob.nsect = desc[ 4]; + tf->hob.lbal = desc[ 6]; + tf->hob.lbam = desc[ 8]; + tf->hob.lbah = desc[10]; + } else { + tf->hob.nsect = 0; + tf->hob.lbal = 0; + tf->hob.lbam = 0; + tf->hob.lbah = 0; + } + + if (verbose) + fprintf(stderr, " ATA_%u stat=%02x err=%02x nsect=%02x lbal=%02x lbam=%02x lbah=%02x dev=%02x\n", + io_hdr.cmd_len, tf->status, tf->error, tf->lob.nsect, tf->lob.lbal, tf->lob.lbam, tf->lob.lbah, tf->dev); + + if (tf->status & (ATA_STAT_ERR | ATA_STAT_DRQ)) { + if (verbose) { + fprintf(stderr, "I/O error, ata_op=0x%02x ata_status=0x%02x ata_error=0x%02x\n", + tf->command, tf->status, tf->error); + } + errno = EIO; + return -1; + } + return 0; +} + +#endif /* SG_IO */ + +int do_drive_cmd (int fd, unsigned char *args, unsigned int timeout_secs) +{ +#ifdef SG_IO + + struct ata_tf tf; + void *data = NULL; + unsigned int data_bytes = 0; + int rc; + + if (args == NULL) + goto use_legacy_ioctl; + /* + * Reformat and try to issue via SG_IO: + * args[0]: command in; status out. + * args[1]: lbal for SMART, nsect for all others; error out + * args[2]: feat in; nsect out. + * args[3]: data-count (512 multiple) for all cmds. + */ + tf_init(&tf, args[0], 0, 0); + tf.lob.nsect = args[1]; + tf.lob.feat = args[2]; + if (args[3]) { + data_bytes = args[3] * 512; + data = args + 4; + if (!tf.lob.nsect) + tf.lob.nsect = args[3]; + } + if (tf.command == ATA_OP_SMART) { + tf.lob.nsect = args[3]; + tf.lob.lbal = args[1]; + tf.lob.lbam = 0x4f; + tf.lob.lbah = 0xc2; + } + + rc = sg16(fd, SG_READ, is_dma(tf.command), &tf, data, data_bytes, timeout_secs); + if (rc == -1) { + if (errno == EINVAL || errno == ENODEV || errno == EBADE) + goto use_legacy_ioctl; + } + + if (rc == 0 || errno == EIO) { + args[0] = tf.status; + args[1] = tf.error; + args[2] = tf.lob.nsect; + } + return rc; + +use_legacy_ioctl: +#endif /* SG_IO */ + if (verbose) { + if (args) + fprintf(stderr, "Trying legacy HDIO_DRIVE_CMD\n"); + } + return ioctl(fd, HDIO_DRIVE_CMD, args); +} + +int do_taskfile_cmd (int fd, struct hdio_taskfile *r, unsigned int timeout_secs) +{ + int rc; +#ifdef SG_IO + struct ata_tf tf; + void *data = NULL; + unsigned int data_bytes = 0; + int rw = SG_READ; + /* + * Reformat and try to issue via SG_IO: + */ + tf_init(&tf, 0, 0, 0); +#if 1 /* debugging */ + if (verbose) { + printf("oflags.lob_all=0x%02x, flags={", r->oflags.lob_all); + if (r->oflags.lob.feat) printf(" feat"); + if (r->oflags.lob.nsect)printf(" nsect"); + if (r->oflags.lob.lbal) printf(" lbal"); + if (r->oflags.lob.lbam) printf(" lbam"); + if (r->oflags.lob.lbah) printf(" lbah"); + if (r->oflags.lob.dev) printf(" dev"); + if (r->oflags.lob.command) printf(" command"); + printf(" }\n"); + printf("oflags.hob_all=0x%02x, flags={", r->oflags.hob_all); + if (r->oflags.hob.feat) printf(" feat"); + if (r->oflags.hob.nsect)printf(" nsect"); + if (r->oflags.hob.lbal) printf(" lbal"); + if (r->oflags.hob.lbam) printf(" lbam"); + if (r->oflags.hob.lbah) printf(" lbah"); + printf(" }\n"); + } +#endif + if (r->oflags.lob.feat) tf.lob.feat = r->lob.feat; + if (r->oflags.lob.lbal) tf.lob.lbal = r->lob.lbal; + if (r->oflags.lob.nsect) tf.lob.nsect = r->lob.nsect; + if (r->oflags.lob.lbam) tf.lob.lbam = r->lob.lbam; + if (r->oflags.lob.lbah) tf.lob.lbah = r->lob.lbah; + if (r->oflags.lob.dev) tf.dev = r->lob.dev; + if (r->oflags.lob.command) tf.command = r->lob.command; + if (needs_lba48(tf.command,0,0) || r->oflags.hob_all || r->iflags.hob_all) { + tf.is_lba48 = 1; + if (r->oflags.hob.feat) tf.hob.feat = r->hob.feat; + if (r->oflags.hob.lbal) tf.hob.lbal = r->hob.lbal; + if (r->oflags.hob.nsect)tf.hob.nsect = r->hob.nsect; + if (r->oflags.hob.lbam) tf.hob.lbam = r->hob.lbam; + if (r->oflags.hob.lbah) tf.hob.lbah = r->hob.lbah; + if (verbose) + fprintf(stderr, "using LBA48 taskfile\n"); + } + switch (r->cmd_req) { + case TASKFILE_CMD_REQ_OUT: + case TASKFILE_CMD_REQ_RAW_OUT: + data_bytes = r->obytes; + data = r->data; + rw = SG_WRITE; + break; + case TASKFILE_CMD_REQ_IN: + data_bytes = r->ibytes; + data = r->data; + break; + } + + rc = sg16(fd, rw, is_dma(tf.command), &tf, data, data_bytes, timeout_secs); + if (rc == -1) { + if (errno == EINVAL || errno == ENODEV || errno == EBADE) + goto use_legacy_ioctl; + } + + if (rc == 0 || errno == EIO) { + if (r->iflags.lob.feat) r->lob.feat = tf.error; + if (r->iflags.lob.lbal) r->lob.lbal = tf.lob.lbal; + if (r->iflags.lob.nsect) r->lob.nsect = tf.lob.nsect; + if (r->iflags.lob.lbam) r->lob.lbam = tf.lob.lbam; + if (r->iflags.lob.lbah) r->lob.lbah = tf.lob.lbah; + if (r->iflags.lob.dev) r->lob.dev = tf.dev; + if (r->iflags.lob.command) r->lob.command = tf.status; + if (r->iflags.hob.feat) r->hob.feat = tf.hob.feat; + if (r->iflags.hob.lbal) r->hob.lbal = tf.hob.lbal; + if (r->iflags.hob.nsect) r->hob.nsect = tf.hob.nsect; + if (r->iflags.hob.lbam) r->hob.lbam = tf.hob.lbam; + if (r->iflags.hob.lbah) r->hob.lbah = tf.hob.lbah; + } + return rc; + +use_legacy_ioctl: +#else + timeout_secs = 0; /* keep compiler happy */ +#endif /* SG_IO */ + if (verbose) + fprintf(stderr, "trying legacy HDIO_DRIVE_TASKFILE\n"); + errno = 0; + + rc = ioctl(fd, HDIO_DRIVE_TASKFILE, r); + if (verbose) { + int err = errno; + fprintf(stderr, "rc=%d, errno=%d, returned ATA registers: ", rc, err); + if (r->iflags.lob.feat) fprintf(stderr, " er=%02x", r->lob.feat); + if (r->iflags.lob.nsect) fprintf(stderr, " ns=%02x", r->lob.nsect); + if (r->iflags.lob.lbal) fprintf(stderr, " ll=%02x", r->lob.lbal); + if (r->iflags.lob.lbam) fprintf(stderr, " lm=%02x", r->lob.lbam); + if (r->iflags.lob.lbah) fprintf(stderr, " lh=%02x", r->lob.lbah); + if (r->iflags.lob.dev) fprintf(stderr, " dh=%02x", r->lob.dev); + if (r->iflags.lob.command) fprintf(stderr, " st=%02x", r->lob.command); + if (r->iflags.hob.feat) fprintf(stderr, " err=%02x", r->hob.feat); + if (r->iflags.hob.nsect) fprintf(stderr, " err=%02x", r->hob.nsect); + if (r->iflags.hob.lbal) fprintf(stderr, " err=%02x", r->hob.lbal); + if (r->iflags.hob.lbam) fprintf(stderr, " err=%02x", r->hob.lbam); + if (r->iflags.hob.lbah) fprintf(stderr, " err=%02x", r->hob.lbah); + fprintf(stderr, "\n"); + errno = err; + } + if (rc == -1 && errno == EINVAL) { + fprintf(stderr, "The running kernel lacks CONFIG_IDE_TASK_IOCTL support for this device.\n"); + errno = EINVAL; + } + return rc; +} + +void init_hdio_taskfile (struct hdio_taskfile *r, __u8 ata_op, int rw, int force_lba48, + __u64 lba, unsigned int nsect, int data_bytes) +{ + memset(r, 0, sizeof(struct hdio_taskfile) + data_bytes); + if (!data_bytes) { + r->dphase = TASKFILE_DPHASE_NONE; + r->cmd_req = TASKFILE_CMD_REQ_NODATA; + } else if (rw == RW_WRITE) { + r->dphase = TASKFILE_DPHASE_PIO_OUT; + r->cmd_req = TASKFILE_CMD_REQ_RAW_OUT; + r->obytes = data_bytes; + } else { /* rw == RW_READ */ + r->dphase = TASKFILE_DPHASE_PIO_IN; + r->cmd_req = TASKFILE_CMD_REQ_IN; + r->ibytes = data_bytes; + } + r->lob.command = ata_op; + r->oflags.lob.command = 1; + r->oflags.lob.dev = 1; + r->oflags.lob.lbal = 1; + r->oflags.lob.lbam = 1; + r->oflags.lob.lbah = 1; + r->oflags.lob.nsect = 1; + + r->iflags.lob.command = 1; + r->iflags.lob.feat = 1; + + r->lob.nsect = nsect; + r->lob.lbal = lba; + r->lob.lbam = lba >> 8; + r->lob.lbah = lba >> 16; + r->lob.dev = 0xa0 | ATA_USING_LBA; + + if (needs_lba48(ata_op, lba, nsect) || force_lba48) { + r->hob.nsect = nsect >> 8; + r->hob.lbal = lba >> 24; + r->hob.lbam = lba >> 32; + r->hob.lbah = lba >> 40; + r->oflags.hob.nsect = 1; + r->oflags.hob.lbal = 1; + r->oflags.hob.lbam = 1; + r->oflags.hob.lbah = 1; + } else { + r->lob.dev |= (lba >> 24) & 0x0f; + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/sgio.h new/hdparm-9.38/sgio.h --- old/hdparm-9.37/sgio.h 2010-10-19 14:45:47.000000000 +0200 +++ new/hdparm-9.38/sgio.h 2012-01-06 15:45:00.000000000 +0100 @@ -54,6 +54,7 @@ ATA_OP_SECURITY_ERASE_UNIT = 0xf4, ATA_OP_SECURITY_FREEZE_LOCK = 0xf5, ATA_OP_SECURITY_DISABLE = 0xf6, + ATA_OP_VENDOR_SPECIFIC_0x80 = 0x80, }; /* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/wdidle3.c new/hdparm-9.38/wdidle3.c --- old/hdparm-9.37/wdidle3.c 1970-01-01 01:00:00.000000000 +0100 +++ new/hdparm-9.38/wdidle3.c 2012-01-07 22:40:49.000000000 +0100 @@ -0,0 +1,212 @@ +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/syscall.h> +#include <linux/types.h> +#include <linux/fs.h> + +#include "sgio.h" +#include "hdparm.h" + +extern int verbose; /* hdparm.c */ + +/* + * The Western Digital (WD) "Green" drive IDLE3 timeout value is 8-bits. + * Earlier models used a strict value from 8.0 to 25.5 seconds (0x50 to 0xff). + * Later models use 8.0 to 12.7 secs (0x50 to 0x7f), and 30 to 300 secs (0x81 to 0x8a). + * Other values are undefined, but have been observed on some drives. + * + * Older drives (from WDIDLE3.EXE documentation): + * 0x00 timer disabled. + * 0x50-0xff timeout in tenths of a second, from 8.0 to 25.5 seconds. + * + * + * Some drives (found by observation): + * 0x01-0x50 timeout in seconds, from 1 to 30 seconds (?). + * + * Newer drives (from WDIDLE3.EXE documentation): + * 0x00 timer disabled. + * 0x01-0x49 not permitted by WDIDLE3.EXE; reports as 0.1 to 7.9 seconds. + * 0x50-0x7f timeout in tenths of a second, from 8.0 to 12.7 seconds. + * 0x80 not permitted by WDIDLE3.EXE; reports as 12.8 seconds. + * 0x81-0x8a timeout in 30s of seconds, from 30 to 300 seconds. + * 0x90-0xff not permitted; reports as 330 to 3810 seconds. + * + * A WD whitepaper identified some models/versions of drives with the "older" firmware, + * but no comprehensive list exists. Models with firmware 02.01B01 are "older", + * and models with "02.01B02" are "newer". + * + * The real WDIDLE3 utility determines the correct value ranges + * by interogating the drive somehow, or perhaps based on the reported firmware version. + * + * WDIDLE3.EXE also writes some scary looking full 512-byte sequences to the drives + * in addition to what we do here. + * + * So this (hdparm) method may be somewhat risky, since it doesn't do everything WD does. + */ + +enum { + WDC_VSC_DISABLED = 'D', + WDC_VSC_ENABLED = 'E', + WDC_IDLE3_READ = 1, + WDC_IDLE3_WRITE = 2, + WDC_OP_TIMEOUT_SECS = 12, + WDC_TIMEOUT_THRESHOLD = 128, +}; + +static int wdidle3_issue (int fd, int rw, struct ata_tf *tf, void *data, const char *msg) +{ + int ret = sg16(fd, rw, SG_PIO, tf, data, data ? 512 : 0, WDC_OP_TIMEOUT_SECS); + if (ret != 0) { + ret = errno; + perror(msg); + } + return ret; +} + +/* + * Note: when WD vendor-specific-commands (vsc) are enabled, + * the ATA_OP_SMART command is "enhanced" to support additional + * functions to read/write specific data "registers" from the firmware. + * This may (or not) also cause regular SMART commands to fail (?). + */ +static int wdidle3_vsc_enable_disable (int fd, int setting) +{ + struct ata_tf tf; + unsigned long long vendor_WD0 = ('W' << 16) | ('D' << 8) | 0; + + tf_init(&tf, ATA_OP_VENDOR_SPECIFIC_0x80, vendor_WD0, 0); + tf.lob.feat = setting; + tf.dev = 0xa0; + return wdidle3_issue(fd, SG_WRITE, &tf, NULL, __func__); +} + +/* + * This sends a key (password? I2C address?) to the drive + * in preparation for a data_in or data_out command. + */ +static int wdidle3_vsc_send_key (int fd, int rw) +{ + char data[512]; + struct ata_tf tf; + + memset(data, 0, sizeof(data)); + tf_init(&tf, ATA_OP_SMART, 0xc24fbe, 1); + tf.lob.feat = 0xd6; + tf.dev = 0xa0; + data[ 0] = 0x2a; + data[ 2] = rw; + data[ 4] = 0x02; + data[ 6] = 0x0d; + data[ 8] = 0x16; + data[10] = 0x01; + return wdidle3_issue(fd, SG_WRITE, &tf, data, __func__); +} + +/* + * This reads a data value from the drive. + */ +static int wdidle3_data_in (int fd, unsigned char *timeout) +{ + char data[512]; + int ret; + struct ata_tf tf; + + memset(data, 0, sizeof(data)); + tf_init(&tf, ATA_OP_SMART, 0xc24fbf, 1); + tf.lob.feat = 0xd5; + tf.dev = 0xa0; + ret = wdidle3_issue(fd, SG_READ, &tf, data, __func__); + if (!ret) + *timeout = data[0]; + return ret; +} + +/* + * This writes a data value to the drive. + */ +static int wdidle3_vsc_data_out (int fd, unsigned char timeout) +{ + char data[512]; + struct ata_tf tf; + + memset(data, 0, sizeof(data)); + tf_init(&tf, ATA_OP_SMART, 0xc24fbf, 1); + tf.lob.feat = 0xd6; + tf.dev = 0xa0; + data[0] = timeout; + return wdidle3_issue(fd, SG_WRITE, &tf, data, __func__); +} + +int wdidle3_set_timeout (int fd, unsigned char timeout) +{ + int ret, ret2; + + ret = wdidle3_vsc_enable_disable(fd, WDC_VSC_ENABLED); + if (!ret) { + ret = wdidle3_vsc_send_key(fd, WDC_IDLE3_WRITE); + if (!ret) + ret = wdidle3_vsc_data_out(fd, timeout); + ret2 = wdidle3_vsc_enable_disable(fd, WDC_VSC_DISABLED); + if (!ret) + ret = ret2; + } + return ret; +} + +int wdidle3_get_timeout (int fd, unsigned char *timeout) +{ + int ret, ret2; + + ret = wdidle3_vsc_enable_disable(fd, WDC_VSC_ENABLED); + if (!ret) { + ret = wdidle3_vsc_send_key(fd, WDC_IDLE3_READ); + if (!ret) + ret = wdidle3_data_in(fd, timeout); + ret2 = wdidle3_vsc_enable_disable(fd, WDC_VSC_DISABLED); + if (!ret) + ret = ret2; + } + return ret; +} + +unsigned char wdidle3_msecs_to_timeout (unsigned int secs) +{ + unsigned char timeout; + + if (secs == 0) + timeout = 0; /* disabled */ + else if (secs < 8) + timeout = 80; /* 8.0 seconds minimum */ + else if (secs <= (WDC_TIMEOUT_THRESHOLD / 10)) + timeout = secs * 10; /* 8.0 to 12.7 seconds */ + else { + secs += 29; /* round up to next multiple of 30 */ + if (secs > 300) + secs = 300; /* max timeout is 300 secs */ + timeout = (secs / 30) + WDC_TIMEOUT_THRESHOLD; + } + return timeout; +} + +void wdidle3_print_timeout (unsigned char timeout) +{ + if (verbose) + printf("[raw=0x%02x] ", timeout); //FIXME + if (timeout == 0) + printf("disabled"); + else if (timeout < 0x50 || timeout == WDC_TIMEOUT_THRESHOLD) + printf("%u ??", timeout); + else if (timeout < WDC_TIMEOUT_THRESHOLD) + printf("%u.%u secs", timeout / 10, timeout % 10); + else { + if (timeout > (WDC_TIMEOUT_THRESHOLD + 10)) + printf("%u ??", timeout); + else + printf("%u secs", (timeout - WDC_TIMEOUT_THRESHOLD) * 30); + printf(" (or %u.%u secs for older drives)", timeout / 10, timeout % 10); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/wiper/Changelog new/hdparm-9.38/wiper/Changelog --- old/hdparm-9.37/wiper/Changelog 2011-01-24 16:14:26.000000000 +0100 +++ new/hdparm-9.38/wiper/Changelog 2011-02-21 15:59:43.000000000 +0100 @@ -1,3 +1,5 @@ +wiper.sh-3.4 + - updated to allow all SCSI_DISK_MAJOR numbers, not just "8" wiper.sh-3.3 - remove need for external "rdev" utility, to keep Suse/Redhat/Fedora users happy diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.37/wiper/wiper.sh new/hdparm-9.38/wiper/wiper.sh --- old/hdparm-9.37/wiper/wiper.sh 2011-01-16 23:01:28.000000000 +0100 +++ new/hdparm-9.38/wiper/wiper.sh 2011-02-21 15:58:26.000000000 +0100 @@ -2,7 +2,7 @@ # # SATA SSD free-space TRIM utility, by Mark Lord <[email protected]> -VERSION=3.3 +VERSION=3.4 # Copyright (C) 2009-2010 Mark Lord. All rights reserved. # @@ -370,15 +370,24 @@ rawdev="" elif [ "`get_major $fsdev`" -ne "`get_major $rawdev`" ]; then ## sanity check rawdev="" -elif [ "`get_major $fsdev`" -ne "8" ]; then ## "SCSI" drives only; no LVM confusion for now - echo "$rawdev: does not appear to be a SCSI/SATA SSD, aborting." >&2 - exit 1 -elif ! $HDPARM -I $rawdev | $GREP -i '[ ][*][ ]*Data Set Management TRIM supported' &>/dev/null ; then - if [ "$commit" = "yes" ]; then - echo "$rawdev: DSM/TRIM command not supported, aborting." >&2 +else + ## "SCSI" drives only; no LVM confusion for now: + maj="$(get_major $fsdev)" + maj_ok=0 + for scsi_major in 8 65 66 67 68 69 70 71 ; do + [ "$maj" = "$scsi_major" ] && maj_ok=1 + done + if [ $maj_ok -eq 0 ]; then + echo "$rawdev: does not appear to be a SCSI/SATA SSD, aborting." >&2 exit 1 fi - echo "$rawdev: DSM/TRIM command not supported (continuing with dry-run)." >&2 + if ! $HDPARM -I $rawdev | $GREP -i '[ ][*][ ]*Data Set Management TRIM supported' &>/dev/null ; then + if [ "$commit" = "yes" ]; then + echo "$rawdev: DSM/TRIM command not supported, aborting." >&2 + exit 1 + fi + echo "$rawdev: DSM/TRIM command not supported (continuing with dry-run)." >&2 + fi fi if [ "$rawdev" = "" ]; then echo "$fsdev: unable to reliably determine the underlying physical device name, aborting" >&2 -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
