commit hdparm for openSUSE:Factory
![](https://seccdn.libravatar.org/avatar/e2145bc5cf53dda95c308a3c75e8fef3.jpg?s=120&d=mm&r=g)
Hello community, here is the log from the commit of package hdparm for openSUSE:Factory checked in at Fri Sep 24 11:26:54 CEST 2010. -------- --- hdparm/hdparm.changes 2010-09-15 17:01:57.000000000 +0200 +++ /mounts/work_src_done/STABLE/hdparm/hdparm.changes 2010-09-24 10:56:51.000000000 +0200 @@ -1,0 +2,6 @@ +Fri Sep 24 08:51:25 UTC 2010 - puzel@novell.com + +- update to hdparm-9.32 + * fix b0rked (since 9.27?) SET_FEATURES commands; eg. -B, -M, etc.. + +------------------------------------------------------------------- calling whatdependson for head-i586 Old: ---- hdparm-9.30.tar.bz2 New: ---- hdparm-9.32.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hdparm.spec ++++++ --- /var/tmp/diff_new_pack.j5RDIR/_old 2010-09-24 11:26:48.000000000 +0200 +++ /var/tmp/diff_new_pack.j5RDIR/_new 2010-09-24 11:26:48.000000000 +0200 @@ -1,5 +1,5 @@ # -# spec file for package hdparm (Version 9.30) +# spec file for package hdparm (Version 9.32) # # Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. # @@ -24,7 +24,7 @@ PreReq: %insserv_prereq %fillup_prereq coreutils Provides: base:/sbin/hdparm AutoReqProv: on -Version: 9.30 +Version: 9.32 Release: 1 Summary: A Program to get and set hard disk parameters Source: %{name}-%{version}.tar.bz2 ++++++ hdparm-9.30.tar.bz2 -> hdparm-9.32.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.30/Changelog new/hdparm-9.32/Changelog --- old/hdparm-9.30/Changelog 2010-08-19 23:08:53.000000000 +0200 +++ new/hdparm-9.32/Changelog 2010-09-24 08:17:44.000000000 +0200 @@ -1,3 +1,13 @@ +hdparm-9.32 + - fix b0rked (since 9.27?) SET_FEATURES commands; eg. -B, -M, etc.. +hdparm-9.31 + - fix oflags bug in do_taskfile_cmd(). + - change --user-master to default to "user" instead of "master", for better drive compatibility. + - use drive-supplied timeout (plus a little) for security-erase commands + - use 15 secs as default general timeout (instead of 5) + - ensure timeouts get passed through to sg16 correctly + - increment revision-code when setting master-password, rather than always using 0xff11 + - update HPA description in manpage hdparm-9.30 - report word[105] in -I : max 512-byte blocks of range-data per DSM/Trim command - fix wiper.sh/hdparm to use only as many LBA ranges per TRIM as the drive can handle diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.30/hdparm.8 new/hdparm-9.32/hdparm.8 --- old/hdparm-9.30/hdparm.8 2010-08-19 23:09:10.000000000 +0200 +++ new/hdparm-9.32/hdparm.8 2010-09-24 08:13:00.000000000 +0200 @@ -1,4 +1,4 @@ -.TH HDPARM 8 "August 2010" "Version 9.30" +.TH HDPARM 8 "September 2010" "Version 9.32" .SH NAME hdparm \- get/set SATA/IDE device parameters @@ -424,6 +424,10 @@ .B Host Protected Area (HPA). This area is often used by computer makers to hold diagnostic software, and/or a copy of the originally provided operating system for recovery purposes. +Another possible use is to hide the true capacity of a very large disk +from a BIOS/system that cannot normally cope with drives of that size +(eg. most current {2010} BIOSs cannot deal with drives larger than 2TB, +so an HPA could be used to cause a 3TB drive to report itself as a 2TB drive). To change the current max (VERY DANGEROUS, DATA LOSS IS EXTREMELY LIKELY), a new value should be provided (in base10) immediately following the @@ -723,7 +727,7 @@ .PP These switches are .B DANGEROUS -to experiment with, and might not work with every kernel. +to experiment with, and might not work with some kernels. .B USE AT YOUR OWN RISK. .TP .I --security-help @@ -739,9 +743,9 @@ .I --security-unlock PWD Unlock the drive, using password PWD. Password is given as an ASCII string and is padded with NULs to reach 32 bytes. -The applicable drive password is selected with the --user-master switch. +The applicable drive password is selected with the --user-master switch +(default is "user" password). No other options are permitted on the command line with this one. -.B THIS FEATURE IS EXPERIMENTAL AND NOT WELL TESTED. USE AT YOUR OWN RISK. .TP .I --security-set-pass PWD Lock the drive, using password PWD (Set Password) @@ -750,17 +754,17 @@ Use the special password .B NULL to set an empty password. -The applicable drive password is selected with the --user-master switch and the -applicable security mode with the --security-mode switch. +The applicable drive password is selected with the --user-master switch +(default is "user" password) +and the applicable security mode with the --security-mode switch. No other options are permitted on the command line with this one. -.B THIS FEATURE IS EXPERIMENTAL AND NOT WELL TESTED. USE AT YOUR OWN RISK. .TP .I --security-disable PWD Disable drive locking, using password PWD. Password is given as an ASCII string and is padded with NULs to reach 32 bytes. -The applicable drive password is selected with the --user-master switch. +The applicable drive password is selected with the --user-master switch +(default is "user" password). No other options are permitted on the command line with this one. -.B THIS FEATURE IS EXPERIMENTAL AND NOT WELL TESTED. USE AT YOUR OWN RISK. .TP .I --security-erase PWD Erase (locked) drive, using password PWD @@ -769,27 +773,26 @@ Use the special password .B NULL to represent an empty password. -The applicable drive password is selected with the --user-master switch. +The applicable drive password is selected with the --user-master switch +(default is "user" password). No other options are permitted on the command line with this one. -.B THIS FEATURE IS EXPERIMENTAL AND NOT WELL TESTED. USE AT YOUR OWN RISK. .TP .I --security-erase-enhanced PWD Enhanced erase (locked) drive, using password PWD .B (DANGEROUS). Password is given as an ASCII string and is padded with NULs to reach 32 bytes. -The applicable drive password is selected with the --user-master switch. +The applicable drive password is selected with the --user-master switch +(default is "user" password). No other options are permitted on the command line with this one. -.B THIS FEATURE IS EXPERIMENTAL AND NOT WELL TESTED. USE AT YOUR OWN RISK. .TP .I --user-master USER Specifies which password (user/master) to select. -.B Defaults to master. +.B Defaults to "user" password. Only useful in combination with --security-unlock, --security-set-pass, --security-disable, --security-erase or --security-erase-enhanced. u user password m master password -.B THIS FEATURE IS EXPERIMENTAL AND NOT WELL TESTED. USE AT YOUR OWN RISK. .TP .I --security-mode MODE Specifies which security mode (high/maximum) to set. @@ -851,4 +854,4 @@ Serial ATA International Organization. .PP .B http://www.compactflash.org/ -CompactFlash Association +CompactFlash Association. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.30/hdparm.c new/hdparm-9.32/hdparm.c --- old/hdparm-9.30/hdparm.c 2010-08-19 23:08:19.000000000 +0200 +++ new/hdparm-9.32/hdparm.c 2010-09-24 08:12:50.000000000 +0200 @@ -35,7 +35,7 @@ extern const char *minor_str[]; -#define VERSION "v9.30" +#define VERSION "v9.32" #ifndef O_DIRECT #define O_DIRECT 040000 /* direct disk access, not easily obtained from headers */ @@ -94,7 +94,7 @@ static int set_powerup_in_standby = 0, get_powerup_in_standby = 0, powerup_in_standby = 0; static int get_hitachi_temp = 0, set_hitachi_temp = 0; static int security_freeze = 0; -static int security_master = 1, security_mode = 0; +static int security_master = 0, security_mode = 0; static int enhanced_erase = 0; static int set_security = 0; static int do_dco_freeze = 0, do_dco_restore = 0, do_dco_identify = 0; @@ -139,8 +139,9 @@ static int i_know_what_i_am_doing = 0; static int please_destroy_my_drive = 0; -const int timeout_12secs = 12; -const int timeout_5mins = (5 * 60); +const int timeout_15secs = 15; +const int timeout_60secs = 60; +const int timeout_5mins = (5 * 60); const int timeout_2hrs = (2 * 60 * 60); static int open_flags = O_RDONLY|O_NONBLOCK; @@ -186,7 +187,7 @@ if (ioctl(fd, BLKFLSBUF, NULL)) /* do it again, big time */ perror("BLKFLSBUF failed"); else - do_drive_cmd(fd, NULL); /* IDE: await completion */ + do_drive_cmd(fd, NULL, 0); /* IDE: await completion */ sync(); } @@ -389,12 +390,15 @@ printf("%s%s", prefix, s[i]); } +static __u16 *id; +static void get_identify_data (int fd); + static __u64 get_lba_capacity (__u16 *idw) { - __u64 nsects = (idw[58] << 16) | idw[57]; + __u64 nsects = ((__u32)idw[58] << 16) | idw[57]; if (idw[49] & 0x200) { - nsects = (idw[61] << 16) | idw[60]; + nsects = ((__u32)idw[61] << 16) | idw[60]; if ((idw[83] & 0xc000) == 0x4000 && (idw[86] & 0x0400)) { nsects = (__u64)idw[103] << 48 | (__u64)idw[102] << 32 | (__u64)idw[101] << 16 | idw[100]; @@ -702,6 +706,27 @@ printf(")\n"); } +static unsigned int get_erase_timeout_secs (int fd, int enhanced) +{ + unsigned int timeout = 0; + unsigned int idx = 89 + enhanced; + + get_identify_data(fd); + if (id) { + timeout = id[idx]; + if (timeout && timeout <= 0xff) { + if (timeout == 0xff) + timeout = 508 + 60; /* spec says > 508 minutes */ + else + timeout = (timeout * 2) + 5; /* Add on a 5min margin */ + } + } + if (!timeout) + timeout = 2 * 60; /* default: two hours */ + timeout *= 60; /* secs */ + return timeout; +} + static void do_set_security (int fd) { @@ -726,8 +751,6 @@ data[0] = security_master & 0x01; memcpy(data+2, security_password, 32); - /* Not setting any oflags causes a segfault and most - of the times a kernel panic */ r->oflags.lob.command = 1; r->oflags.lob.feat = 1; @@ -746,9 +769,17 @@ description = "SECURITY_SET_PASS"; data[1] = (security_mode & 0x01); if (security_master) { - /* master password revision code */ - data[34] = 0x11; - data[35] = 0xff; + /* increment master-password revision-code */ + __u16 revcode; + get_identify_data(fd); + if (!id) + exit(EIO); + revcode = id[92]; + if (revcode == 0xffff) + revcode = 0; + revcode += 1; + data[34] = revcode; + data[35] = revcode >> 8; } break; default: @@ -775,12 +806,13 @@ * assuming the segfault isn't followed by an oops. */ if (security_command == ATA_OP_SECURITY_ERASE_UNIT) { + unsigned int timeout = get_erase_timeout_secs(fd, enhanced_erase); __u8 args[4] = {ATA_OP_SECURITY_ERASE_PREPARE,0,0,0}; - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror("ERASE_PREPARE"); } else { - if ((do_taskfile_cmd(fd, r, timeout_2hrs))) { + if ((do_taskfile_cmd(fd, r, timeout))) { err = errno; perror("SECURITY_ERASE"); } @@ -788,24 +820,24 @@ } else if (security_command == ATA_OP_SECURITY_DISABLE) { /* First attempt an unlock */ r->lob.command = ATA_OP_SECURITY_UNLOCK; - if ((do_taskfile_cmd(fd, r, timeout_12secs))) { + if ((do_taskfile_cmd(fd, r, timeout_15secs))) { err = errno; perror("SECURITY_UNLOCK"); } else { /* Then the security disable */ r->lob.command = security_command; - if ((do_taskfile_cmd(fd, r, timeout_12secs))) { + if ((do_taskfile_cmd(fd, r, timeout_15secs))) { err = errno; perror("SECURITY_DISABLE"); } } } else if (security_command == ATA_OP_SECURITY_UNLOCK) { - if ((do_taskfile_cmd(fd, r, timeout_12secs))) { + if ((do_taskfile_cmd(fd, r, timeout_15secs))) { err = errno; perror("SECURITY_UNLOCK"); } } else if (security_command == ATA_OP_SECURITY_SET_PASS) { - if ((do_taskfile_cmd(fd, r, timeout_12secs))) { + if ((do_taskfile_cmd(fd, r, timeout_15secs))) { err = errno; perror("SECURITY_SET_PASS"); } @@ -820,34 +852,33 @@ static __u8 last_identify_op = 0; -static void *get_identify_data (int fd, void *prev) +static void get_identify_data (int fd) { static __u8 args[4+512]; - __u16 *id = (void *)(args + 4); int i; - if (prev != (void *)-1) - return prev; + if (id) + return; memset(args, 0, sizeof(args)); last_identify_op = ATA_OP_IDENTIFY; args[0] = last_identify_op; args[3] = 1; /* sector count */ - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { prefer_ata12 = 0; last_identify_op = ATA_OP_PIDENTIFY; args[0] = last_identify_op; args[1] = 0; args[2] = 0; args[3] = 1; /* sector count */ - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { perror(" HDIO_DRIVE_CMD(identify) failed"); - return NULL; + return; } } /* byte-swap the little-endian IDENTIFY data to match byte-order on host CPU */ + id = (void *)(args + 4); for (i = 0; i < 0x100; ++i) __le16_to_cpus(&id[i]); - return id; } static void confirm_i_know_what_i_am_doing (const char *opt, const char *explanation) @@ -870,16 +901,15 @@ } } -static int flush_wcache (int fd, __u16 **id_p) +static int flush_wcache (int fd) { __u8 args[4] = {ATA_OP_FLUSHCACHE,0,0,0}; - __u16 *id; int err = 0; - *id_p = id = get_identify_data(fd, *id_p); + get_identify_data(fd); if (id && (id[83] & 0xe000) == 0x6000) args[0] = ATA_OP_FLUSHCACHE_EXT; - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, timeout_60secs)) { err = errno; perror (" HDIO_DRIVE_CMD(flushcache) failed"); } @@ -975,7 +1005,7 @@ args[0] = ATA_OP_DCO; args[2] = 0xc2; args[3] = 1; - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { if (!quietly) perror(" HDIO_DRIVE_CMD(dco_identify) failed"); return NULL; @@ -988,7 +1018,7 @@ } } -static __u64 do_get_native_max_sectors (int fd, __u16 *id) +static __u64 do_get_native_max_sectors (int fd) { int err = 0; __u64 max = 0; @@ -1005,6 +1035,9 @@ 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; @@ -1023,7 +1056,7 @@ } else { r.iflags.lob.dev = 1; r.lob.command = ATA_OP_READ_NATIVE_MAX; - if (do_taskfile_cmd(fd, &r, timeout_12secs)) { + if (do_taskfile_cmd(fd, &r, 0)) { err = errno; perror (" READ_NATIVE_MAX_ADDRESS failed"); } else { @@ -1034,9 +1067,9 @@ return max; } -static int do_make_bad_sector (int fd, __u16 *id, __u64 lba, const char *devname) +static int do_make_bad_sector (int fd, __u64 lba, const char *devname) { - int err = 0, has_write_unc; + int err = 0, has_write_unc = 0; struct hdio_taskfile *r; const char *flagged; @@ -1048,8 +1081,10 @@ return err; } - has_write_unc = (id[ 83] & 0xc000) == 0x4000 && (id[ 86] & 0x8000) == 0x8000 - && (id[119] & 0xc004) == 0x4004 && (id[120] & 0xc000) == 0x4000; + get_identify_data(fd); + if (id) + has_write_unc = (id[ 83] & 0xc000) == 0x4000 && (id[ 86] & 0x8000) == 0x8000 + && (id[119] & 0xc004) == 0x4004 && (id[120] & 0xc000) == 0x4000; if (has_write_unc || make_bad_sector_flagged || lba >= lba28_limit) { if (!has_write_unc) { @@ -1071,7 +1106,7 @@ /* Try and ensure that the system doesn't have our sector in cache */ flush_buffer_cache(fd); - if (do_taskfile_cmd(fd, r, timeout_12secs)) { + if (do_taskfile_cmd(fd, r, timeout_60secs)) { err = errno; perror("FAILED"); } else { @@ -1100,7 +1135,7 @@ printf("re-formatting lba %llu: ", lba); fflush(stdout); - if (do_taskfile_cmd(fd, r, timeout_12secs)) { + if (do_taskfile_cmd(fd, r, timeout_60secs)) { err = errno; perror("FAILED"); } else { @@ -1131,7 +1166,7 @@ printf("erasing sectors %llu-%llu: ", lba, lba + 255); fflush(stdout); - if (do_taskfile_cmd(fd, r, timeout_12secs)) { + if (do_taskfile_cmd(fd, r, timeout_60secs)) { err = errno; perror("FAILED"); } else { @@ -1227,14 +1262,13 @@ } static int -get_trim_dev_limit (void *id) +get_trim_dev_limit (void) { - __u16 *idw = id; char model[41]; - if (idw[105] && idw[105] != 0xffff) - return idw[105]; - extract_id_string(idw + 27, 20, model); + if (id[105] && id[105] != 0xffff) + return id[105]; + extract_id_string(id + 27, 20, model); if (0 == strcmp(model, "OCZ VERTEX-LE")) return 8; if (0 == strcmp(model, "OCZ-VERTEX")) @@ -1243,16 +1277,18 @@ } static int -do_trim_from_stdin (int fd, const char *devname, void *id) +do_trim_from_stdin (int fd, const char *devname) { __u64 *data, range, nsectors = 0, lba_limit; unsigned int max_kb, data_sects, data_bytes; unsigned int total_ranges = 0, nranges = 0, max_ranges, dev_limit; int err = 0; - id = get_identify_data(fd, id); - lba_limit = id ? get_lba_capacity(id) : (1ULL << 48) - 1; - dev_limit = get_trim_dev_limit(id); + get_identify_data(fd); + if (!id) + exit(EIO); + lba_limit = get_lba_capacity(id); + dev_limit = get_trim_dev_limit(); err = sysfs_get_attr(fd, "queue/max_sectors_kb", "%u", &max_kb, NULL, 0); if (err || max_kb == 0) @@ -1328,7 +1364,7 @@ // Try and ensure that the system doesn't have our sector in cache: flush_buffer_cache(fd); - if (do_taskfile_cmd(fd, r, timeout_12secs)) { + if (do_taskfile_cmd(fd, r, timeout_60secs)) { err = errno; perror("FAILED"); } else { @@ -1358,7 +1394,7 @@ printf("reading sector %llu: ", lba); fflush(stdout); - if (do_taskfile_cmd(fd, r, timeout_12secs)) { + if (do_taskfile_cmd(fd, r, timeout_60secs)) { err = errno; perror("FAILED"); } else { @@ -1379,19 +1415,22 @@ r.oflags.lob.feat = 1; r.lob.feat = 0x44; - if (do_taskfile_cmd(fd, &r, timeout_12secs)) { + if (do_taskfile_cmd(fd, &r, 0)) { err = errno; perror("TASKFILE(idle_immediate_unload) failed"); } return err; } -static int do_set_max_sectors (int fd, __u16 *id, __u64 max_lba, int permanent) +static int do_set_max_sectors (int fd, __u64 max_lba, int permanent) { int err = 0; struct hdio_taskfile r; __u8 nsect = permanent ? 1 : 0; + get_identify_data(fd); + if (!id) + exit(EIO); if ((max_lba >= lba28_limit) || (id && ((id[83] & 0xc400) == 0x4400) && (id[86] & 0x0400))) { init_hdio_taskfile(&r, ATA_OP_SET_MAX_EXT, RW_READ, LBA48_FORCE, max_lba, nsect, 0); } else { @@ -1400,11 +1439,11 @@ } /* spec requires that we do this immediately in front.. racey */ - if (!do_get_native_max_sectors(fd, id)) + if (!do_get_native_max_sectors(fd)) return errno; /* now set the new value */ - if (do_taskfile_cmd(fd, &r, timeout_12secs)) { + if (do_taskfile_cmd(fd, &r, 0)) { err = errno; perror(" SET_MAX_ADDRESS failed"); } @@ -1499,8 +1538,8 @@ fprintf(desc, "\n" "ATA Security Commands:\n" - " Most of these are VERY DANGEROUS and can KILL your drive!\n" - " Due to bugs in most Linux kernels, use of these commands may even\n" + " Most of these are VERY DANGEROUS and can destroy all of your data!\n" + " Due to bugs in older Linux kernels, use of these commands may even\n" " trigger kernel segfaults or worse. EXPERIMENT AT YOUR OWN RISK!\n" "\n" " --security-freeze Freeze security settings until reset.\n" @@ -1518,8 +1557,8 @@ " h high security (default).\n" " m maximum security.\n" " --user-master WHICH Use WHICH to choose password type:\n" - " u user-password.\n" - " m master-password (default).\n" + " u user-password (default).\n" + " m master-password\n" ); exit(rc); } @@ -1529,8 +1568,8 @@ int fd; int err = 0; static long parm, multcount; - __u16 *id = (void *)-1; + id = NULL; fd = open(devname, open_flags); if (fd < 0) { err = errno; @@ -1544,7 +1583,7 @@ if (num_flags_processed > 1 || argc) usage_help(12,EINVAL); confirm_please_destroy_my_drive("--trim-sector-ranges-stdin", "This might destroy the drive and/or all data on it."); - exit(do_trim_from_stdin(fd, devname, id)); + exit(do_trim_from_stdin(fd, devname)); } //if (set_wdidle3) @@ -1594,7 +1633,7 @@ } else { __u8 args[4] = {ATA_OP_SET_MULTIPLE,mult,0,0}; confirm_i_know_what_i_am_doing("-m", "Only the old IDE drivers work correctly with -m with kernels up to at least 2.6.29.\nlibata drives may fail and get hung if you set this flag."); - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(set_multi_count) failed"); } @@ -1664,7 +1703,7 @@ printf(" setting drive doorlock to %d", doorlock); on_off(doorlock); } - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, timeout_15secs)) { err = errno; perror(" HDIO_DRIVE_CMD(doorlock) failed"); } @@ -1677,7 +1716,7 @@ on_off(dkeep); } args[2] = dkeep ? 0x66 : 0xcc; - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(keepsettings) failed"); } @@ -1687,7 +1726,7 @@ args[2] = defects ? 0x04 : 0x84; if (get_defects) printf(" setting drive defect management to %d\n", defects); - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(defectmgmt) failed"); } @@ -1697,7 +1736,7 @@ args[1] = prefetch; if (get_prefetch) printf(" setting drive prefetch to %d\n", prefetch); - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(setprefetch) failed"); } @@ -1709,7 +1748,7 @@ printf(" setting xfermode to %d", xfermode_requested); interpret_xfermode(xfermode_requested); } - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(setxfermode) failed"); } @@ -1721,7 +1760,7 @@ printf(" setting drive read-lookahead to %d", lookahead); on_off(lookahead); } - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(setreadahead) failed"); } @@ -1732,7 +1771,7 @@ __u8 args1[4] = {ATA_OP_SETFEATURES,0,0x07,0}; /* spinup from standby */ printf(" spin-up:"); fflush(stdout); - (void) do_drive_cmd(fd, args1); + (void) do_drive_cmd(fd, args1, 0); } else { confirm_i_know_what_i_am_doing("-s1", "This requires BIOS and kernel support to recognize/boot the drive."); @@ -1744,7 +1783,7 @@ } args[0] = ATA_OP_SETFEATURES; args[2] = powerup_in_standby ? 0x06 : 0x86; - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(powerup_in_standby) failed"); } @@ -1764,7 +1803,7 @@ if (get_apmmode) printf(" 0x%02x (%d)\n",apmmode,apmmode); } - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD failed"); } @@ -1793,7 +1832,7 @@ args[1] = acoustic; args[2] = acoustic ? 0x42 : 0xc2; args[3] = 0; - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD:ACOUSTIC failed"); } @@ -1804,25 +1843,24 @@ on_off(wcache); } if (!wcache) - err = flush_wcache(fd, &id); + err = flush_wcache(fd); if (ioctl(fd, HDIO_SET_WCACHE, wcache)) { __u8 setcache[4] = {ATA_OP_SETFEATURES,0,0,0}; setcache[2] = wcache ? 0x02 : 0x82; - if (do_drive_cmd(fd, setcache)) { + if (do_drive_cmd(fd, setcache, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(setcache) failed"); } } if (!wcache) - err = flush_wcache(fd, &id); + err = flush_wcache(fd); } if (set_standbynow) { __u8 args1[4] = {ATA_OP_STANDBYNOW1,0,0,0}; __u8 args2[4] = {ATA_OP_STANDBYNOW2,0,0,0}; if (get_standbynow) printf(" issuing standby command\n"); - if (do_drive_cmd(fd, args1) - && do_drive_cmd(fd, args2)) { + if (do_drive_cmd(fd, args1, 0) && do_drive_cmd(fd, args2, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(standby) failed"); } @@ -1831,7 +1869,7 @@ __u8 args[4] = {ATA_OP_IDLEIMMEDIATE,0,0,0}; if (get_idleimmediate) printf(" issuing idle_immediate command\n"); - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(idle_immediate) failed"); } @@ -1846,8 +1884,7 @@ __u8 args2[4] = {ATA_OP_SLEEPNOW2,0,0,0}; if (get_sleepnow) printf(" issuing sleep command\n"); - if (do_drive_cmd(fd, args1) - && do_drive_cmd(fd, args2)) { + if (do_drive_cmd(fd, args1, 0) && do_drive_cmd(fd, args2, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(sleep) failed"); } @@ -1864,7 +1901,7 @@ __u8 args[4] = {ATA_OP_DCO,0,0xc0,0}; confirm_i_know_what_i_am_doing("--dco-restore", "You are trying to deliberately reset your drive configuration back to the factory defaults.\nThis may change the apparent capacity and feature set of the drive, making all data on it inaccessible.\nYou could lose *everything*."); printf(" issuing DCO restore command\n"); - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(dco_restore) failed"); } @@ -1872,7 +1909,7 @@ if (do_dco_freeze) { __u8 args[4] = {ATA_OP_DCO,0,0xc1,0}; printf(" issuing DCO freeze command\n"); - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(dco_freeze) failed"); } @@ -1880,7 +1917,7 @@ if (security_freeze) { __u8 args[4] = {ATA_OP_SECURITY_FREEZE_LOCK,0,0,0}; printf(" issuing security freeze command\n"); - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(security_freeze) failed"); } @@ -1889,7 +1926,7 @@ __u8 args[4] = {0xfb,0,0,0}; if (get_seagate) printf(" disabling Seagate auto powersaving mode\n"); - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(seagatepwrsave) failed"); } @@ -1900,7 +1937,7 @@ printf(" setting standby to %u", standby); interpret_standby(); } - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(setidle) failed"); } @@ -1916,19 +1953,19 @@ if (set_max_sectors) { if (get_native_max_sectors) printf(" setting max visible sectors to %llu (%s)\n", set_max_addr, set_max_permanent ? "permanent" : "temporary"); - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { if (set_max_addr < get_lba_capacity(id)) confirm_i_know_what_i_am_doing("-Nnnnnn", "You have requested reducing the apparent size of the drive.\nThis is a BAD idea, and can easily destroy all of the drive's contents."); - err = do_set_max_sectors(fd, id, set_max_addr - 1, set_max_permanent); - id = (void *)-1; /* invalidate existing identify data */ + err = do_set_max_sectors(fd, set_max_addr - 1, set_max_permanent); + id = NULL; /* invalidate existing identify data */ } } if (make_bad_sector) { - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { confirm_i_know_what_i_am_doing("--make-bad-sector", "You are trying to deliberately corrupt a low-level sector on the media.\nThis is a BAD idea, and can easily result in total data loss."); - err = do_make_bad_sector(fd, id, make_bad_sector_addr, devname); + err = do_make_bad_sector(fd, make_bad_sector_addr, devname); } } #ifdef FORMAT_AND_ERASE @@ -1961,7 +1998,7 @@ abort_if_not_full_device (fd, 0, devname, "--fwdownload requires the raw device, not a partition."); confirm_i_know_what_i_am_doing("--fwdownload", "This flag has not been tested with many drives to date.\nYou are trying to deliberately overwrite the drive firmware with the contents of the specified file.\nIf this fails, your drive could be toast."); confirm_please_destroy_my_drive("--fwdownload", "This might destroy the drive and well as all of the data on it."); - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { err = fwdownload(fd, id, fwpath, xfer_mode); if (err) @@ -1971,23 +2008,23 @@ if (read_sector) err = do_read_sector(fd, read_sector_addr, devname); if (drq_hsm_error) { - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { __u8 args[4] = {0,0,0,0}; args[0] = last_identify_op; printf(" triggering \"stuck DRQ\" host state machine error\n"); flush_buffer_cache(fd); sleep(1); - do_drive_cmd(fd, args); + do_drive_cmd(fd, args, timeout_60secs); err = errno; perror("drq_hsm_error"); fprintf(stderr, "ata status=0x%02x ata error=0x%02x\n", args[0], args[1]); } } - id = (void *)-1; /* force re-IDENTIFY in case something above modified settings */ + id = NULL; /* force re-IDENTIFY in case something above modified settings */ if (get_hitachi_temp) { __u8 args[4] = {0xf0,0,0x01,0}; /* "Sense Condition", vendor-specific */ - if (do_drive_cmd(fd, args)) { + if (do_drive_cmd(fd, args, 0)) { err = errno; perror(" HDIO_DRIVE_CMD(hitachisensecondition) failed"); } else { @@ -2006,7 +2043,7 @@ err = 0; if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) { err = errno; - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { err = 0; if ((id[59] & 0xff00) == 0x100) @@ -2119,9 +2156,9 @@ if (get_powermode) { __u8 args[4] = {ATA_OP_CHECKPOWERMODE1,0,0,0}; const char *state = "unknown"; - if (do_drive_cmd(fd, args) + if (do_drive_cmd(fd, args, 0) && (args[0] = ATA_OP_CHECKPOWERMODE2) /* (single =) try again with 0x98 */ - && do_drive_cmd(fd, args)) { + && do_drive_cmd(fd, args, 0)) { err = errno; } else { switch (args[2]) { @@ -2152,7 +2189,7 @@ } } if (do_IDentity) { - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { if (do_IDentity == 2) dump_sectors(id, 1); @@ -2161,7 +2198,7 @@ } } if (get_lookahead) { - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { int supported = id[82] & 0x0040; if (supported) { @@ -2174,7 +2211,7 @@ } } if (get_wcache) { - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { int supported = id[82] & 0x0020; if (supported) { @@ -2187,10 +2224,10 @@ } } if (get_apmmode) { - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { printf(" APM_level = "); - if((id[83] & 0xc008) == 0x4008) { + if ((id[83] & 0xc008) == 0x4008) { if (id[86] & 0x0008) printf("%u\n", id[91] & 0xff); else @@ -2200,7 +2237,7 @@ } } if (get_acoustic) { - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { int supported = id[83] & 0x200; if (supported) @@ -2219,10 +2256,10 @@ } if (get_native_max_sectors) { __u64 visible, native; - id = get_identify_data(fd, id); + get_identify_data(fd); if (id) { visible = get_lba_capacity(id); - native = do_get_native_max_sectors(fd, id); + native = do_get_native_max_sectors(fd); if (!native) { err = errno; } else { @@ -2250,7 +2287,7 @@ if (do_ctimings) time_cache(fd); if (do_flush_wcache) - err = flush_wcache(fd, &id); + err = flush_wcache(fd); if (do_timings) err = time_device(fd); if (do_flush) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.30/hdparm.lsm new/hdparm-9.32/hdparm.lsm --- old/hdparm-9.30/hdparm.lsm 2010-08-19 23:12:42.000000000 +0200 +++ new/hdparm-9.32/hdparm.lsm 2010-09-24 08:18:35.000000000 +0200 @@ -1,8 +1,10 @@ Begin4 Title: hdparm -Version: 9.30 -Entered-date: 2010-08-19 +Version: 9.32 +Entered-date: 2010-09-24 Description: hdparm - get/set hard disk parameters for Linux SATA/IDE drives. + v9.32 Fixed various commands broken since 9.27. Eg. -B, -M, etc.. + v9.31 Fixed security-erase issues; changed default of --user-master to user v9.30 Restrict LBA range counts for TRIM to what the drive reports it can handle v9.29 Assorted fixes, updated wiper.sh, made trim compatible with many more SSDs v9.28 Assorted fixes, updated wiper.sh @@ -104,8 +106,8 @@ Maintained-by: mlord@pobox.com (Mark Lord) Primary-site: http://sourceforge.net/projects/hdparm/ Alternate-site: http://www.ibiblio.org/pub/Linux/system/hardware - 117K hdparm-9.30.tar.gz + 117K hdparm-9.32.tar.gz 4K hdparm.lsm -Platforms: Linux, kernels 2.2 through 2.6 +Platforms: Linux Copying-policy: BSD License End diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.30/identify.c new/hdparm-9.32/identify.c --- old/hdparm-9.30/identify.c 2010-08-03 04:51:18.000000000 +0200 +++ new/hdparm-9.32/identify.c 2010-09-24 01:24:50.000000000 +0200 @@ -1326,12 +1326,12 @@ else printf("high\n"); } } - jj = val[ERASE_TIME] & ERASE_BITS; - kk = val[ENH_ERASE_TIME] & ERASE_BITS; - if(jj || kk) { + jj = val[ERASE_TIME]; + kk = val[ENH_ERASE_TIME]; + if((jj && jj <= 0x00ff) || (kk && kk <= 0x00ff)) { printf("\t"); - if(jj) printf("%umin for SECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1); - if(kk) printf("%umin for ENHANCED SECURITY ERASE UNIT.", kk==ERASE_BITS ? 508 : kk<<1); + 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)); printf("\n"); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.30/sgio.c new/hdparm-9.32/sgio.c --- old/hdparm-9.30/sgio.c 2010-05-12 15:35:22.000000000 +0200 +++ new/hdparm-9.32/sgio.c 2010-09-24 08:17:01.000000000 +0200 @@ -20,6 +20,8 @@ extern int verbose; extern int prefer_ata12; +static const int default_timeout_secs = 15; + /* * Taskfile layout for SG_ATA_16 cdb: * @@ -67,6 +69,9 @@ 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; @@ -223,7 +228,7 @@ io_hdr.cmdp = cdb; io_hdr.sbp = sb; io_hdr.pack_id = tf_to_lba(tf); - io_hdr.timeout = (timeout_secs ? timeout_secs : 5) * 1000; /* msecs */ + io_hdr.timeout = (timeout_secs ? timeout_secs : default_timeout_secs) * 1000; /* msecs */ if (verbose) { dump_bytes("outgoing cdb", cdb, sizeof(cdb)); @@ -282,7 +287,7 @@ } if (verbose) { - unsigned int len = desc[1], maxlen = sizeof(sb) - 8 - 2; + unsigned int len = desc[1] + 2, maxlen = sizeof(sb) - 8 - 2; if (len > maxlen) len = maxlen; dump_bytes("SG_IO: desc[]", desc, len); @@ -326,7 +331,7 @@ #endif /* SG_IO */ -int do_drive_cmd (int fd, unsigned char *args) +int do_drive_cmd (int fd, unsigned char *args, unsigned int timeout_secs) { #ifdef SG_IO @@ -340,20 +345,20 @@ /* * Reformat and try to issue via SG_IO: */ - if (args[3]) { + if (args[3] && args[0] != ATA_OP_SETFEATURES) { data_bytes = args[3] * 512; data = args + 4; } tf_init(&tf, args[0], 0, args[1]); tf.lob.feat = args[2]; - 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, 0); + 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; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.30/sgio.h new/hdparm-9.32/sgio.h --- old/hdparm-9.30/sgio.h 2009-09-01 16:14:11.000000000 +0200 +++ new/hdparm-9.32/sgio.h 2010-09-24 05:17:46.000000000 +0200 @@ -114,8 +114,7 @@ TASKFILE_DPHASE_PIO_OUT = 4, /* ide: TASKFILE_OUT */ }; -union reg_flags { - unsigned all : 16; +struct reg_flags { union { unsigned lob_all : 8; struct { @@ -158,8 +157,8 @@ struct hdio_taskfile { struct taskfile_regs lob; struct taskfile_regs hob; - union reg_flags oflags; - union reg_flags iflags; + struct reg_flags oflags; + struct reg_flags iflags; int dphase; int cmd_req; /* IDE command_type */ unsigned long obytes; @@ -225,7 +224,7 @@ void tf_init (struct ata_tf *tf, __u8 ata_op, __u64 lba, unsigned int nsect); __u64 tf_to_lba (struct ata_tf *tf); int sg16 (int fd, int rw, int dma, struct ata_tf *tf, void *data, unsigned int data_bytes, unsigned int timeout_secs); -int do_drive_cmd (int fd, unsigned char *args); +int do_drive_cmd (int fd, unsigned char *args, unsigned int timeout); int do_taskfile_cmd (int fd, struct hdio_taskfile *r, unsigned int timeout_secs); int dev_has_sgio (int fd); void init_hdio_taskfile (struct hdio_taskfile *r, __u8 ata_op, int rw, int force_lba48, ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun... -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org
participants (1)
-
root@hilbert.suse.de