Hello community, here is the log from the commit of package hdparm for openSUSE:Factory checked in at 2018-04-26 13:34:45 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hdparm (Old) and /work/SRC/openSUSE:Factory/.hdparm.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "hdparm" Thu Apr 26 13:34:45 2018 rev:70 rq:599787 version:9.56 Changes: -------- --- /work/SRC/openSUSE:Factory/hdparm/hdparm.changes 2017-12-19 10:47:42.880553298 +0100 +++ /work/SRC/openSUSE:Factory/.hdparm.new/hdparm.changes 2018-04-26 13:34:48.159179587 +0200 @@ -1,0 +2,17 @@ +Fri Apr 20 14:20:48 UTC 2018 - kstreitova@suse.com + +- update to version 9.56 + * 9.56 - fixed byte order for --Istdout so that --Istdin can + grok it + - added --Iraw for raw binary output of IDENTIFY data + to a file + * 9.55 - added #include <sys/sysmacros.h> for major()/minor() + macros + * 9.54 - Partial revert of Jmicron changes, from Jan Friesse. + * 9.53 - Read Drive Capacity fixes from Iestyn Walters. + - SET MAX ADDRESS fixes from Tom Yan <tom.ty89@gmail.com> + - added --security-prompt-for-password to --security-help + output + - fwdownload changes from Jihoon Lee. + +------------------------------------------------------------------- Old: ---- hdparm-9.52.tar.gz New: ---- hdparm-9.56.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hdparm.spec ++++++ --- /var/tmp/diff_new_pack.5DwEg0/_old 2018-04-26 13:34:48.955150420 +0200 +++ /var/tmp/diff_new_pack.5DwEg0/_new 2018-04-26 13:34:48.959150273 +0200 @@ -1,7 +1,7 @@ # # spec file for package hdparm # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: hdparm -Version: 9.52 +Version: 9.56 Release: 0 Summary: A Program to get and set hard disk parameters License: SUSE-Permissive @@ -65,7 +65,7 @@ %files %doc Changelog README.acoustic contrib/README.contrib README.wiper -%{_mandir}/man8/hdparm.8%{ext_man} +%{_mandir}/man8/hdparm.8%{?ext_man} #UsrMerge /sbin/hdparm /sbin/wiper.sh ++++++ hdparm-9.52.tar.gz -> hdparm-9.56.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/Changelog new/hdparm-9.56/Changelog --- old/hdparm-9.52/Changelog 2017-05-01 21:12:59.000000000 +0200 +++ new/hdparm-9.56/Changelog 2018-03-25 19:07:14.000000000 +0200 @@ -1,3 +1,17 @@ +hdparm-9.56: + - fixed byte order for --Istdout so that --Istdin can grok it + - added --Iraw for raw binary output of IDENTIFY data to a file +hdparm-9.55: + - added #include <sys/sysmacros.h> for major()/minor() macros +hdparm-9.54: + - Partial revert of Jmicron changes, from Jan Friesse. +hdparm-9.53: + - Read Drive Capacity fixes from Iestyn Walters. + - SET MAX ADDRESS fixes from Tom Yan <tom.ty89@gmail.com>. + - added --security-prompt-for-password to --security-help output. + - fwdownload changes from Jihoon Lee. +hdparm-9.52: + - Jmicron SATA-USB bridge support from Jan Friesse <jfriesse@gmail.com>. hdparm-9.51: - add support for Jmicron USB-SATA bridges, courtesy Jan Friesse <jfriesse@gmail.com>. hdparm-9.51: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/apt.c new/hdparm-9.56/apt.c --- old/hdparm-9.52/apt.c 2017-05-01 21:10:11.000000000 +0200 +++ new/hdparm-9.56/apt.c 2018-02-03 19:10:16.000000000 +0100 @@ -264,47 +264,8 @@ static int apt_jmicron_sg16(int fd, int rw, int dma, struct ata_tf *tf, void *data, unsigned int data_bytes, unsigned int timeout_secs) { - int res; - unsigned char regs[16]; - memset(regs, 0, sizeof(tf)); - - res = apt_jmicron_int_sg(fd, rw, dma, tf, data, data_bytes, timeout_secs, 0); - - if (res == -1) return res; - - if ((res = apt_jmicron_int_get_registers(fd, - (apt_data.jmicron.port == 0xa0 ? 0x8000 : 0x9000), regs, sizeof(regs))) == -1) { - return res; - } - - tf->is_lba48 = 0; - tf->error = regs[13]; - tf->lob.nsect = regs[ 0]; - tf->lob.lbal = regs[ 6]; - tf->lob.lbam = regs[ 4]; - tf->lob.lbah = regs[10]; - tf->dev = regs[ 9]; - tf->status = regs[14]; - tf->hob.feat = 0; - tf->hob.nsect = 0; - tf->hob.lbal = 0; - tf->hob.lbam = 0; - tf->hob.lbah = 0; - - if (apt_data.verbose) - fprintf(stderr, " ATA_%u stat=%02x err=%02x nsect=%02x lbal=%02x lbam=%02x lbah=%02x dev=%02x\n", - 12, 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 (apt_data.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; + return apt_jmicron_int_sg(fd, rw, dma, tf, data, data_bytes, timeout_secs, 0); } #else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/fwdownload.c new/hdparm-9.56/fwdownload.c --- old/hdparm-9.52/fwdownload.c 2016-10-17 20:01:05.000000000 +0200 +++ new/hdparm-9.56/fwdownload.c 2017-12-06 13:41:40.000000000 +0100 @@ -160,9 +160,16 @@ } else if (xfer_mode == 3) { xfer_size = xfer_min; } else if (xfer_mode == 0x0e) { +#if 0 xfer_size = xfer_max; } else if (xfer_mode == 0xe0) { xfer_size = xfer_min; +#else + xfer_size = xfer_min; + } else if (xfer_mode == 0xe0) { + xfer_mode = 0x0e; + xfer_size = xfer_max; +#endif } else { xfer_size = st.st_size / 512; if (xfer_size > 0xffff) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/geom.c new/hdparm-9.56/geom.c --- old/hdparm-9.52/geom.c 2016-10-13 01:50:52.000000000 +0200 +++ new/hdparm-9.56/geom.c 2018-03-15 20:27:21.000000000 +0100 @@ -15,6 +15,7 @@ #include <errno.h> #include <dirent.h> #include <sys/stat.h> +#include <sys/sysmacros.h> #include <sys/ioctl.h> #include <linux/types.h> #include <linux/fs.h> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/hdparm.8 new/hdparm-9.56/hdparm.8 --- old/hdparm-9.52/hdparm.8 2017-01-19 18:07:27.000000000 +0100 +++ new/hdparm-9.56/hdparm.8 2018-03-25 19:08:09.000000000 +0200 @@ -1,4 +1,4 @@ -.TH HDPARM 8 "January 2017" "Version 9.51" +.TH HDPARM 8 "March 2018" "Version 9.55" .SH NAME hdparm \- get/set SATA/IDE device parameters @@ -282,6 +282,9 @@ .B -i option. .TP +.I --Iraw <pathname> +This option dumps the drive's identify data in raw binary to the specified file. +.TP .I --Istdin This is a special variation on the .B -I diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/hdparm.c new/hdparm-9.56/hdparm.c --- old/hdparm-9.52/hdparm.c 2017-05-01 21:14:16.000000000 +0200 +++ new/hdparm-9.56/hdparm.c 2018-03-25 19:06:24.000000000 +0200 @@ -2,7 +2,7 @@ * hdparm.c - Command line interface to get/set hard disk parameters. * - by Mark Lord (C) 1994-2017 -- freely distributable. */ -#define HDPARM_VERSION "v9.52" +#define HDPARM_VERSION "v9.56" #define _LARGEFILE64_SOURCE /*for lseek64*/ #define _BSD_SOURCE /* for strtoll() */ @@ -95,7 +95,7 @@ static int do_dco_freeze = 0, do_dco_restore = 0, do_dco_identify = 0, do_dco_setmax = 0; static unsigned int security_command = ATA_OP_SECURITY_UNLOCK; -static char security_password[33], *fwpath; +static char security_password[33], *fwpath, *raw_identify_path; static int do_sanitize = 0; static __u16 sanitize_feature = 0; @@ -427,6 +427,11 @@ } static __u16 *id; + +#define SUPPORTS_ACS3(id) ((id)[80] & 0x400) +#define SUPPORTS_AMAX_ADDR(id) (SUPPORTS_ACS3(id) && ((id)[119] & (1u << 8))) +#define SUPPORTS_48BIT_ADDR(id) ((((id)[83] & 0xc400) == 0x4400) && ((id)[86] & 0x0400)) + static void get_identify_data (int fd); static __u64 get_lba_capacity (__u16 *idw) @@ -865,7 +870,6 @@ r.cmd_req = TASKFILE_CMD_REQ_NODATA; r.dphase = TASKFILE_DPHASE_NONE; - r.oflags.bits.lob.dev = 1; r.oflags.bits.lob.command = 1; r.oflags.bits.lob.feat = 1; r.oflags.bits.lob.lbal = 1; @@ -875,7 +879,6 @@ r.oflags.bits.hob.lbam = 1; r.oflags.bits.hob.lbah = 1; - r.lob.dev = 0x40; r.lob.command = ATA_OP_SANITIZE; r.lob.feat = sanitize_feature; r.lob.lbal = lba; @@ -1135,23 +1138,23 @@ return err; } -static void dump_sectors (__u16 *w, unsigned int count) +static void dump_sectors (__u16 *w, unsigned int count, int raw) { unsigned int i; for (i = 0; i < (count*256/8); ++i) { -#if 0 - printf("%04x %04x %04x %04x %04x %04x %04x %04x\n", - w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7]); - w += 8; -#else - int word; - for (word = 0; word < 8; ++word) { - unsigned char *b = (unsigned char *)w++; - printf("%02x%02x", b[0], b[1]); - putchar(word == 7 ? '\n' : ' '); + if (raw) { + printf("%04x %04x %04x %04x %04x %04x %04x %04x\n", + w[0], w[1], w[2], w[3], w[4], w[5], w[6], w[7]); + w += 8; + } else { + int word; + for (word = 0; word < 8; ++word) { + unsigned char *b = (unsigned char *)w++; + printf("%02x%02x", b[0], b[1]); + putchar(word == 7 ? '\n' : ' '); + } } -#endif } } @@ -1208,7 +1211,7 @@ unsigned char *b = (unsigned char *)&dco[i]; dco[i] = b[0] | (b[1] << 8); /* le16_to_cpu */ } - //dump_sectors(dco, 1); + //dump_sectors(dco, 1, 0); return dco; } } @@ -1240,7 +1243,7 @@ } if (verbose) { printf("Original DCO:\n"); - dump_sectors(dco, 1); + dump_sectors(dco, 1, 0); } // set the new MAXLBA to the requested sectors - 1 *maxlba = set_max_addr - 1; @@ -1248,7 +1251,7 @@ dco[255] = (dco[255] & 0xFF) | ((__u16) dco_verify_checksum(dco) << 8); if (verbose) { printf("New DCO:\n"); - dump_sectors(dco, 1); + dump_sectors(dco, 1, 0); } } else { @@ -1288,47 +1291,40 @@ memset(&r, 0, sizeof(r)); r.cmd_req = TASKFILE_CMD_REQ_NODATA; r.dphase = TASKFILE_DPHASE_NONE; - r.oflags.bits.lob.dev = 1; r.oflags.bits.lob.command = 1; r.iflags.bits.lob.command = 1; r.iflags.bits.lob.lbal = 1; r.iflags.bits.lob.lbam = 1; r.iflags.bits.lob.lbah = 1; - r.lob.dev = 0x40; - if((id[80]&0x400)==0x400) { //ACS3 supported - if (((id[83] & 0xc400) == 0x4400) && (id[86] & 0x0400)) { - r.iflags.bits.hob.lbal = 1; - r.iflags.bits.hob.lbam = 1; - r.iflags.bits.hob.lbah = 1; - r.lob.command = ATA_OP_GET_NATIVE_MAX_EXT; - if (do_taskfile_cmd(fd, &r, 10)) { - err = errno; - perror (" READ_NATIVE_MAX_ADDRESS_EXT failed"); - } else { - if (verbose) - printf("READ_NATIVE_MAX_ADDRESS_EXT response: hob={%02x %02x %02x} lob={%02x %02x %02x}\n", - r.hob.lbah, r.hob.lbam, r.hob.lbal, r.lob.lbah, r.lob.lbam, r.lob.lbal); - max = (((__u64)((r.hob.lbah << 16) | (r.hob.lbam << 8) | r.hob.lbal) << 24) - | ((r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal)) + 1; - } + if (SUPPORTS_AMAX_ADDR(id)) { + /* ACS3 supported, no 28-bit variant defined in spec */ + r.iflags.bits.hob.lbal = 1; + r.iflags.bits.hob.lbam = 1; + r.iflags.bits.hob.lbah = 1; + r.oflags.bits.lob.feat = 1; + r.lob.command = ATA_OP_GET_NATIVE_MAX_EXT; + r.lob.feat = 0x00; //GET NATIVE MAX ADDRESS EXT is 78h/0000h + //bit 6 of DEVICE field is defined as "N/A" + if (do_taskfile_cmd(fd, &r, 0)) { + err = errno; + perror (" GET_NATIVE_MAX_ADDRESS_EXT failed"); } else { - r.iflags.bits.lob.dev = 1; - r.lob.command = ATA_OP_GET_NATIVE_MAX_EXT; - if (do_taskfile_cmd(fd, &r, timeout_15secs)) { - err = errno; - perror (" READ_NATIVE_MAX_ADDRESS failed"); - } else { - max = ((r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal) + 1; - } - } - } else { //ACS2 supported - if (((id[83] & 0xc400) == 0x4400) && (id[86] & 0x0400)) { + if (verbose) + printf("GET_NATIVE_MAX_ADDRESS_EXT response: hob={%02x %02x %02x} lob={%02x %02x %02x}\n", + r.hob.lbah, r.hob.lbam, r.hob.lbal, r.lob.lbah, r.lob.lbam, r.lob.lbal); + max = (((__u64)((r.hob.lbah << 16) | (r.hob.lbam << 8) | r.hob.lbal) << 24) + | ((r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal)) + 1; + } + } else { // ACS2 or below, or optional AMAX not present + if (SUPPORTS_48BIT_ADDR(id)) { r.iflags.bits.hob.lbal = 1; r.iflags.bits.hob.lbam = 1; r.iflags.bits.hob.lbah = 1; + r.oflags.bits.lob.dev = 1; r.lob.command = ATA_OP_READ_NATIVE_MAX_EXT; - if (do_taskfile_cmd(fd, &r, 10)) { + r.lob.dev = 0x40; + if (do_taskfile_cmd(fd, &r, timeout_15secs)) { //timeout for pre-ACS3 case of do_set_max_sectors err = errno; perror (" READ_NATIVE_MAX_ADDRESS_EXT failed"); } else { @@ -1339,16 +1335,19 @@ | ((r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal)) + 1; } } else { - r.iflags.bits.lob.dev = 1; + /* DEVICE (3:0) / LBA (27:24) "remap" does NOT apply in ATA Status Return */ + r.iflags.bits.hob.lbal = 1; r.lob.command = ATA_OP_READ_NATIVE_MAX; - if (do_taskfile_cmd(fd, &r, 0)) { + //bit 7:5 of DEVICE field is defined as "Obsolete" + if (do_taskfile_cmd(fd, &r, timeout_15secs)) { //timeout for pre-ACS3 case of do_set_max_sectors err = errno; perror (" READ_NATIVE_MAX_ADDRESS failed"); } else { - max = (((r.lob.dev & 0x0f) << 24) | (r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal) + 1; + max = (((r.hob.lbal & 0x0f) << 24) | (r.lob.lbah << 16) | (r.lob.lbam << 8) | r.lob.lbal) + 1; } } } + errno = err; return max; @@ -1681,7 +1680,7 @@ perror("FAILED"); } else { printf("succeeded\n"); - dump_sectors(r->data, 1); + dump_sectors(r->data, 1, 0); } free(r); return err; @@ -1714,45 +1713,40 @@ if (!id) exit(EIO); - if((id[80]&0x400)==0x400){ - //ACS3 supported - if ((max_lba >> 28) || (id && ((id[83] & 0xc400) == 0x4400) && (id[86] & 0x0400))) { - - init_hdio_taskfile(&r, ATA_OP_GET_NATIVE_MAX_EXT, RW_READ, LBA48_FORCE, max_lba, nsect, 0); - r.oflags.bits.lob.feat = 1; - r.lob.feat = 0x01; - } else { - init_hdio_taskfile(&r, ATA_OP_GET_NATIVE_MAX_EXT, RW_READ, LBA28_OK, max_lba, nsect, 0); - r.oflags.bits.lob.feat = 1; /*this ATA op requires feat == 0 */ - } + if (SUPPORTS_AMAX_ADDR(id)) { + /* ACS3 supported, no 28-bit variant defined in spec */ + init_hdio_taskfile(&r, ATA_OP_GET_NATIVE_MAX_EXT, RW_READ, LBA48_FORCE, max_lba, nsect, 0); + r.oflags.bits.lob.feat = 1; + r.lob.feat = 0x01; //SET ACCESSIBLE MAX ADDRESS EXT is 78h/0001h + //bit 6 of DEVICE field is defined as "N/A" + /* No more "racey" in ACS3+AMAX case? */ if (do_taskfile_cmd(fd, &r, timeout_15secs)) { err = errno; - perror(" SET_MAX_ADDRESS failed"); + perror(" SET_ACCESSIBLE_MAX_ADDRESS_EXT failed"); + } + } else { + if ((max_lba >= lba28_limit) || SUPPORTS_48BIT_ADDR(id)) { + init_hdio_taskfile(&r, ATA_OP_SET_MAX_EXT, RW_READ, LBA48_FORCE, max_lba, nsect, 0); + r.oflags.bits.lob.dev = 1; + r.lob.dev = 0x40; + } else { + init_hdio_taskfile(&r, ATA_OP_SET_MAX, RW_READ, LBA28_OK, max_lba, nsect, 0); + //bit 7:5 of DEVICE field is defined as "Obsolete" } - return err; + /* spec requires that we do this immediately in front.. racey */ + if (!do_get_native_max_sectors(fd)) + return errno; + /* now set the new value */ + if (do_taskfile_cmd(fd, &r, 0)) { + err = errno; + perror(" SET_MAX_ADDRESS(_EXT) failed"); } - else{ - 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 { - init_hdio_taskfile(&r, ATA_OP_SET_MAX, RW_READ, LBA28_OK, max_lba, nsect, 0); - r.oflags.bits.lob.feat = 1; /* this ATA op requires feat==0 */ } - /* spec requires that we do this immediately in front.. racey */ - if (!do_get_native_max_sectors(fd)) - return errno; - - /* now set the new value */ - if (do_taskfile_cmd(fd, &r, 0)) { - err = errno; - perror(" SET_MAX_ADDRESS failed"); - } return err; - } } static void usage_help (int clue, int rc) @@ -1825,6 +1819,7 @@ " --fwdownload-modee-max Download firmware using mode E (max-size segments) (EXTREMELY DANGEROUS)\n" " --idle-immediate Idle drive immediately\n" " --idle-unload Idle immediately and unload heads\n" + " --Iraw filename Write raw binary identify data to the specfied file\n" " --Istdin Read identify data from stdin as ASCII hex\n" " --Istdout Write identify data to stdout as ASCII hex\n" " --make-bad-sector Deliberately corrupt a sector directly on the media (VERY DANGEROUS)\n" @@ -1862,6 +1857,8 @@ " --security-set-pass PASSWD Lock drive, using password PASSWD:\n" " Use 'NULL' to set empty password.\n" " Drive gets locked if user-passwd is selected.\n" + " --security-prompt-for-password Prompt user to enter the drive password.\n" + "\n" " --security-unlock PASSWD Unlock drive.\n" " --security-disable PASSWD Disable drive locking.\n" " --security-erase PASSWD Erase a (locked) drive.\n" @@ -2538,10 +2535,31 @@ if (do_IDentity) { get_identify_data(fd); if (id) { - if (do_IDentity == 2) - dump_sectors(id, 1); - else + if (do_IDentity == 2) { + dump_sectors(id, 1, 1); + } else if (do_IDentity == 3) { + /* Write raw binary IDENTIFY DEVICE data to the specified file */ + int rfd = open(raw_identify_path, O_WRONLY|O_TRUNC|O_CREAT, 0644); + if (rfd == -1) { + err = errno; + perror(raw_identify_path); + exit(err); + } + err = write(rfd, id, 0x200); + if (err == -1) { + err = errno; + perror(raw_identify_path); + exit(err); + } else if (err != 0x200) { + fprintf(stderr, "Error writing IDENTIFY DEVICE data to \"%s\"\n", raw_identify_path); + exit(EIO); + } else { + fprintf(stderr, "Wrote IDENTIFY DEVICE data to \"%s\"\n", raw_identify_path); + close(rfd); + } + } else { identify(fd, (void *)id); + } } } if (get_lookahead) { @@ -2612,30 +2630,27 @@ } } if (get_native_max_sectors) { - __u64 visible, native; get_identify_data(fd); if (id) { - visible = get_lba_capacity(id); - native = do_get_native_max_sectors(fd); + __u64 visible = get_lba_capacity(id); + __u64 native = do_get_native_max_sectors(fd); if (!native) { err = errno; } else { printf(" max sectors = %llu/%llu", visible, native); if (visible < native){ - - if((id[80]&0x400)==0x400){ + if (SUPPORTS_AMAX_ADDR(id)) { printf(", ACCESSIBLE MAX ADDRESS enabled\n"); printf("Power cycle your device after every ACCESSIBLE MAX ADDRESS\n"); - } else - printf(", HPA is enabled\n"); + printf(", HPA is enabled\n"); } else if (visible == native){ - if((id[80]&0x400)==0x400) + if (SUPPORTS_AMAX_ADDR(id)) printf(", ACCESSIBLE MAX ADDRESS disabled\n"); - else - printf(", HPA is disabled\n"); + else + printf(", HPA is disabled\n"); } else { __u16 *dco = get_dco_identify_data(fd, 1); @@ -3182,6 +3197,9 @@ get_u64_parm(0, 0, NULL, &read_sector_addr, 0, lba_limit, name, lba_emsg); } else if (0 == strcasecmp(name, "Istdout")) { do_IDentity = 2; + } else if (0 == strcasecmp(name, "Iraw")) { + do_IDentity = 3; + get_filename_parm(&raw_identify_path, name); } else if (0 == strcasecmp(name, "security-mode")) { if (argc && isalpha(**argv)) { argp = *argv++, --argc; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/hdparm.lsm new/hdparm-9.56/hdparm.lsm --- old/hdparm-9.52/hdparm.lsm 2017-05-01 21:16:35.000000000 +0200 +++ new/hdparm-9.56/hdparm.lsm 2018-03-25 19:08:50.000000000 +0200 @@ -1,8 +1,12 @@ Begin4 Title: hdparm -Version: 9.52 -Entered-date: 2017-05-01 +Version: 9.56 +Entered-date: 2018-03-25 Description: hdparm - get/set hard disk parameters for Linux SATA/IDE drives. + v9.56 fixed --Istdout, added --Iraw + v9.55 #include <sys/sysmacros.h> + v9.54 partial revert of JMicron changes. + v9.53 Read Drive Capacity fixes, SET MAX ADDRESS fixes, fwdownload fixes. v9.52 added JMicron USB-SATA bridge support, courtesy Jan Friesse <jfriesse@gmail.com>. v9.51 minor fixes/tweaks, new --security-prompt-for-password flag. v9.50 minor fixes for sanitize device stuff. @@ -126,7 +130,7 @@ Maintained-by: mlord@pobox.com (Mark Lord) Primary-site: http://sourceforge.net/projects/hdparm/ Alternate-site: http://www.ibiblio.org/pub/Linux/system/hardware - 140K hdparm-9.52.tar.gz + 137K hdparm-9.56.tar.gz 7K hdparm.lsm Platforms: Linux Copying-policy: BSD License diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/jmicron-usb-try1.patch new/hdparm-9.56/jmicron-usb-try1.patch --- old/hdparm-9.52/jmicron-usb-try1.patch 2017-05-01 21:05:00.000000000 +0200 +++ new/hdparm-9.56/jmicron-usb-try1.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,491 +0,0 @@ -diff --git a/Makefile b/Makefile -index d28b703..44aaefb 100644 ---- a/Makefile -+++ b/Makefile -@@ -22,7 +22,7 @@ INSTALL_DATA = $(INSTALL) -m 644 - INSTALL_DIR = $(INSTALL) -m 755 -d - INSTALL_PROGRAM = $(INSTALL) - --OBJS = hdparm.o identify.o sgio.o sysfs.o geom.o fibmap.o fwdownload.o dvdspeed.o -+OBJS = hdparm.o identify.o sgio.o sysfs.o geom.o fibmap.o fwdownload.o dvdspeed.o apt.o - - all: hdparm - -@@ -38,6 +38,8 @@ dvdspeed.o: dvdspeed.c - - sgio.o: sgio.c sgio.h hdparm.h - -+apt.o: apt.c -+ - install: all hdparm.8 - if [ ! -z $(DESTDIR) ]; then $(INSTALL_DIR) $(DESTDIR) ; fi - if [ ! -z $(DESTDIR)$(sbindir) ]; then $(INSTALL_DIR) $(DESTDIR)$(sbindir) ; fi -diff --git a/apt.c b/apt.c -new file mode 100644 -index 0000000..afbb992 ---- /dev/null -+++ b/apt.c -@@ -0,0 +1,334 @@ -+#include <stdio.h> -+#include <stdlib.h> -+#include <fcntl.h> -+#include <string.h> -+#include <unistd.h> -+#include <sys/ioctl.h> -+#include <linux/cdrom.h> -+#include <scsi/scsi.h> -+#include <scsi/sg.h> -+#include <sys/types.h> -+#include <errno.h> -+#include "hdparm.h" -+#include "sgio.h" -+ -+/* -+ * apt - Support for ATA PASS THROUGH devices. Currently supported only -+ * JMicron devices. -+ * -+ * Copyright (c) 2009 Jan Friesse <jfriesse@gmail.com> -+ * -+ * Magic numbers are taken from smartmontools source code -+ * (http://smartmontools.sourceforge.net/) -+ * -+ * You may use/distribute this freely, under the terms of either -+ * (your choice) the GNU General Public License version 2, -+ * or a BSD style license. -+ */ -+ -+#ifdef SG_IO -+ -+/* External functions*/ -+int sysfs_get_attr_recursive (int fd, const char *attr, const char *fmt, void *val1, void *val2, int verbose); -+ -+/* Device initialization functions */ -+static int apt_jmicron_int_init(int fd); -+ -+/* Device sg16 functions*/ -+static int apt_jmicron_sg16(int fd, int rw, int dma, struct ata_tf *tf, -+ void *data, unsigned int data_bytes, unsigned int timeout_secs); -+ -+/* Structs */ -+struct apt_usb_id_entry { -+ int vendor_id; -+ int product_id; -+ int version; -+ const char *type; -+ int (*init_func)(int fd); -+ int (*sg16_func)(int fd, int rw, int dma, struct ata_tf *tf, -+ void *data, unsigned int data_bytes, unsigned int timeout_secs); -+ -+}; -+ -+struct apt_data_struct { -+ int is_apt; -+ struct apt_usb_id_entry id; -+ int verbose; -+ union { -+ struct { -+ int port; -+ } jmicron; -+ }; -+}; -+ -+static struct apt_data_struct apt_data; -+ -+const char apt_ds_jmicron[] = "jmicron"; -+const char apt_ds_unsup[] = "unsupported"; -+ -+const struct apt_usb_id_entry apt_usb_id_map[] = { -+ {0x152d, 0x2329, 0x0100, apt_ds_jmicron, -+ apt_jmicron_int_init, apt_jmicron_sg16}, /* JMicron JM20329 (USB->SATA) */ -+ {0x152d, 0x2336, 0x0100, apt_ds_jmicron, -+ apt_jmicron_int_init, apt_jmicron_sg16}, /* JMicron JM20336 (USB+SATA->SATA, USB->2xSATA) */ -+ {0x152d, 0x2338, 0x0100, apt_ds_jmicron, -+ apt_jmicron_int_init, apt_jmicron_sg16}, /* JMicron JM20337/8 (USB->SATA+PATA, USB+SATA->PATA) */ -+ {0x152d, 0x2339, 0x0100, apt_ds_jmicron, -+ apt_jmicron_int_init, apt_jmicron_sg16} /* JMicron JM20339 (USB->SATA) */ -+}; -+ -+int apt_detect (int fd, int verbose) -+{ -+ int err; -+ unsigned int i; -+ -+ apt_data.is_apt = 0; -+ -+ err = sysfs_get_attr_recursive(fd, "idVendor", "%x", &apt_data.id.vendor_id, NULL, verbose); -+ if (err) { -+ if (verbose) printf("APT: No idVendor found -> not USB bridge device\n"); -+ return 0; -+ } -+ -+ err = sysfs_get_attr_recursive(fd, "idProduct", "%x", &apt_data.id.product_id, NULL, verbose); -+ if (err) return 0; -+ -+ err = sysfs_get_attr_recursive(fd, "bcdDevice", "%x", &apt_data.id.version, NULL, verbose); -+ if (err) return 0; -+ -+ if (verbose) -+ printf("APT: USB ID = 0x%04x:0x%04x (0x%03x)\n", apt_data.id.vendor_id, apt_data.id.product_id, -+ apt_data.id.version); -+ -+ /* We have all needed informations, let's find if we support that device*/ -+ for (i = 0; i < sizeof(apt_usb_id_map)/sizeof(*apt_usb_id_map); i++) { -+ if (apt_data.id.vendor_id == apt_usb_id_map[i].vendor_id && -+ apt_data.id.product_id == apt_usb_id_map[i].product_id) { -+ /* Maybe two devices with same vendor and product id -> use version*/ -+ if (apt_usb_id_map[i].version > 0 && apt_data.id.type && -+ apt_usb_id_map[i].version == apt_data.id.version) { -+ apt_data.id.type = apt_usb_id_map[i].type; -+ apt_data.id.init_func = apt_usb_id_map[i].init_func; -+ apt_data.id.sg16_func = apt_usb_id_map[i].sg16_func; -+ } -+ -+ /* We don't have type -> set it (don't care about version) */ -+ if (!apt_data.id.type) { -+ apt_data.id.type = apt_usb_id_map[i].type; -+ apt_data.id.init_func = apt_usb_id_map[i].init_func; -+ apt_data.id.sg16_func = apt_usb_id_map[i].sg16_func; -+ } -+ } -+ } -+ -+ if (!apt_data.id.type || apt_data.id.type == apt_ds_unsup) { -+ if (verbose) -+ printf("APT: Unsupported device\n"); -+ -+ return 0; -+ } -+ -+ apt_data.is_apt = 1; -+ if (verbose) -+ printf("APT: Found supported device %s\n", apt_data.id.type); -+ -+ apt_data.verbose = verbose; -+ -+ return (apt_data.id.init_func(fd)); -+} -+ -+int apt_is_apt (void) -+{ -+ return apt_data.is_apt; -+} -+ -+int apt_sg16(int fd, int rw, int dma, struct ata_tf *tf, -+ void *data, unsigned int data_bytes, unsigned int timeout_secs) -+{ -+ return apt_data.id.sg16_func(fd, rw, dma, tf, data, data_bytes, timeout_secs); -+} -+ -+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"); -+} -+ -+/***** JMicron support ********/ -+static int apt_jmicron_int_sg(int fd, int rw, int dma, struct ata_tf *tf, -+ void *data, unsigned int data_bytes, unsigned int timeout_secs, -+ int port) -+{ -+ unsigned char cdb[12]; -+ struct scsi_sg_io_hdr io_hdr; -+ -+ if (dma && apt_data.verbose) -+ printf("APT: JMicron doesn't support DMA\n"); -+ -+ if (tf->is_lba48) { -+ if (apt_data.verbose) -+ fprintf(stderr, "APT: JMicron doesn't support 48-bit ATA commands\n"); -+ errno = EBADE; -+ return -1; -+ } -+ -+ memset(&cdb, 0, sizeof(cdb)); -+ memset(&io_hdr, 0, sizeof(struct scsi_sg_io_hdr)); -+ -+ // Build pass through command -+ cdb[ 0] = 0xdf; -+ cdb[ 1] = (rw ? 0x00 : 0x10); -+ cdb[ 2] = 0x00; -+ cdb[ 3] = (unsigned char)((data ? data_bytes : 0) >> 8); -+ cdb[ 4] = (unsigned char)((data ? data_bytes : 0) ); -+ cdb[ 5] = tf->lob.feat; -+ cdb[ 6] = tf->lob.nsect; -+ cdb[ 7] = tf->lob.lbal; -+ cdb[ 8] = tf->lob.lbam; -+ cdb[ 9] = tf->lob.lbah; -+ cdb[10] = (port ? port : apt_data.jmicron.port); -+ cdb[11] = tf->command; -+ -+ io_hdr.interface_id = 'S'; -+ io_hdr.mx_sb_len = 0; -+ 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.pack_id = tf_to_lba(tf); -+ io_hdr.timeout = (timeout_secs ? timeout_secs : 5) * 1000; /* msecs */ -+ io_hdr.cmd_len = sizeof(cdb); -+ -+ if (apt_data.verbose) -+ dump_bytes("outgoing cdb", cdb, sizeof(cdb)); -+ if (ioctl(fd, SG_IO, &io_hdr) == -1) { -+ if (apt_data.verbose) -+ perror("ioctl(fd,SG_IO)"); -+ return -1; /* SG_IO not supported */ -+ } -+ if (apt_data.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.host_status || io_hdr.driver_status) { -+ errno = EBADE; -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int apt_jmicron_int_get_registers(int fd, unsigned short addr, -+ unsigned char * buf, unsigned short size) -+{ -+ struct ata_tf tf; -+ -+ memset(&tf, 0, sizeof(tf)); -+ -+ tf.lob.feat = 0x00; -+ tf.lob.nsect = (unsigned char)(addr >> 8); -+ tf.lob.lbal = (unsigned char)(addr); -+ tf.lob.lbam = 0x00; -+ tf.lob.lbah = 0x00; -+ tf.command = 0xfd; -+ -+ return apt_jmicron_int_sg(fd, 0, 0, &tf, buf, (unsigned int)size, 0, 0x00); -+} -+ -+static int apt_jmicron_int_init(int fd) -+{ -+ unsigned char regbuf = 0; -+ int res; -+ -+ if ((res = apt_jmicron_int_get_registers(fd, 0x720F, ®buf, 1)) == -1) { -+ return res; -+ } -+ -+ if (regbuf & 0x04) { -+ apt_data.jmicron.port = 0xa0; -+ } else if (regbuf & 0x40) { -+ apt_data.jmicron.port = 0xb0; -+ } else { -+ perror("APT: No JMicron device connected"); -+ errno = ENODEV; -+ return -1; -+ } -+ -+ if (apt_data.verbose) -+ printf("APT: JMicron Port: 0x%X\n", apt_data.jmicron.port); -+ return 0; -+} -+ -+static int apt_jmicron_sg16(int fd, int rw, int dma, struct ata_tf *tf, -+ void *data, unsigned int data_bytes, unsigned int timeout_secs) -+{ -+ int res; -+ unsigned char regs[16]; -+ -+ memset(regs, 0, sizeof(tf)); -+ -+ res = apt_jmicron_int_sg(fd, rw, dma, tf, data, data_bytes, timeout_secs, 0); -+ -+ if (res == -1) return res; -+ -+ if ((res = apt_jmicron_int_get_registers(fd, -+ (apt_data.jmicron.port == 0xa0 ? 0x8000 : 0x9000), regs, sizeof(regs))) == -1) { -+ return res; -+ } -+ -+ tf->is_lba48 = 0; -+ tf->error = regs[13]; -+ tf->lob.nsect = regs[ 0]; -+ tf->lob.lbal = regs[ 6]; -+ tf->lob.lbam = regs[ 4]; -+ tf->lob.lbah = regs[10]; -+ tf->dev = regs[ 9]; -+ tf->status = regs[14]; -+ tf->hob.feat = 0; -+ tf->hob.nsect = 0; -+ tf->hob.lbal = 0; -+ tf->hob.lbam = 0; -+ tf->hob.lbah = 0; -+ -+ if (apt_data.verbose) -+ fprintf(stderr, " ATA_%u stat=%02x err=%02x nsect=%02x lbal=%02x lbam=%02x lbah=%02x dev=%02x\n", -+ 12, 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 (apt_data.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; -+} -+ -+#else -+/* No SGIO -> no support*/ -+int apt_detect (int fd, int verbose) -+{ -+ if (verbose) -+ printf("APT: SGIO Support needed for fd %d\n", fd); -+ return 0; -+} -+ -+int apt_is_apt (void) -+{ -+ return 0; -+} -+ -+int apt_sg16(int fd, int rw, int dma, struct ata_tf *tf, -+ void *data, unsigned int data_bytes, unsigned int timeout_secs) -+{ -+ printf("APT: SG16 fd %d rw %d dma %d tf %p data %p data_bytes %d timeout %d need SGIO\n", -+ fd, rw, dma, tf, data, data_bytes, timeout_secs); -+ return -1; -+} -+#endif -diff --git a/hdparm.c b/hdparm.c -index f18ec6e..55d75bc 100644 ---- a/hdparm.c -+++ b/hdparm.c -@@ -1194,6 +1194,13 @@ void process_dev (char *devname) - if (!quiet) - printf("\n%s:\n", devname); - -+ if (apt_detect(fd, verbose) == -1) { -+ err = errno; -+ perror(devname); -+ close(fd); -+ exit(err); -+ } -+ - if (set_fsreadahead) { - if (get_fsreadahead) - printf(" setting fs readahead to %d\n", fsreadahead); -diff --git a/hdparm.h b/hdparm.h -index 60a0045..0f38b16 100644 ---- a/hdparm.h -+++ b/hdparm.h -@@ -21,6 +21,10 @@ int fwdownload(int fd, __u16 *id, const char *fwpath); - void dco_identify_print (__u16 *dco); - int set_dvdspeed(int fd, int speed); - -+/* APT Functions */ -+int apt_detect (int fd, int verbose); -+int apt_is_apt (void); -+ - extern const char *BuffType[4]; - - struct local_hd_big_geometry { -diff --git a/sgio.c b/sgio.c -index e3de83e..18f3926 100644 ---- a/sgio.c -+++ b/sgio.c -@@ -148,6 +148,10 @@ int sg16 (int fd, int rw, int dma, struct ata_tf *tf, - unsigned char sb[32], *desc; - struct scsi_sg_io_hdr io_hdr; - -+ if (apt_is_apt()) { -+ return apt_sg16(fd, rw, dma, tf, data, data_bytes, timeout_secs); -+ } -+ - memset(&cdb, 0, sizeof(cdb)); - memset(&sb, 0, sizeof(sb)); - memset(&io_hdr, 0, sizeof(struct scsi_sg_io_hdr)); -diff --git a/sgio.h b/sgio.h -index 7ad2d11..155c4d8 100644 ---- a/sgio.h -+++ b/sgio.h -@@ -228,3 +228,7 @@ 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, - __u64 lba, unsigned int nsect, int data_bytes); -+ -+/* APT */ -+int apt_sg16(int fd, int rw, int dma, struct ata_tf *tf, -+ void *data, unsigned int data_bytes, unsigned int timeout_secs); -diff --git a/sysfs.c b/sysfs.c -index d21e678..fd51d5c 100644 ---- a/sysfs.c -+++ b/sysfs.c -@@ -194,3 +194,64 @@ int sysfs_set_attr (int fd, const char *attr, const char *fmt, void *val_p, int - err = sysfs_write_attr(path, attr, fmt, val_p, verbose); - return err; - } -+ -+static int sysfs_find_attr_file_path (const char *start_path, char **dest_path, const char *attr) -+{ -+ static char path[PATH_MAX]; -+ static char have_prev = 0; -+ char file_path[PATH_MAX + FILENAME_MAX]; -+ struct stat st; -+ ino_t stop_inode; -+ int depth = 0; -+ -+ if (have_prev) { -+ *dest_path = path; -+ -+ return 0; -+ } -+ -+ stat("/sys/devices", &st); -+ stop_inode = st.st_ino; -+ -+ strcpy(path, start_path); -+ -+ while (depth < 20) { -+ strcat(path, "/.."); -+ -+ if (stat(path, &st) != 0) -+ return errno; -+ -+ if (st.st_ino == stop_inode) -+ return EINVAL; -+ -+ strcpy(file_path, path); -+ strcat(file_path, "/"); -+ strcat(file_path, attr); -+ -+ if (access(file_path, F_OK | R_OK) == 0) { -+ *dest_path = path; -+ -+ return 0; -+ } -+ } -+ -+ return EINVAL; -+} -+ -+int sysfs_get_attr_recursive (int fd, const char *attr, const char *fmt, void *val1, void *val2, int verbose) -+{ -+ char *path; -+ char *attr_path; -+ int err; -+ -+ err = sysfs_find_fd(fd, &path, verbose); -+ if (!err) { -+ err = sysfs_find_attr_file_path(path, &attr_path, attr); -+ -+ if (!err) { -+ err = sysfs_read_attr(attr_path, attr, fmt, val1, val2, verbose); -+ } -+ } -+ -+ return err; -+} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hdparm-9.52/sysfs.c new/hdparm-9.56/sysfs.c --- old/hdparm-9.52/sysfs.c 2017-05-01 21:07:50.000000000 +0200 +++ new/hdparm-9.56/sysfs.c 2018-03-15 20:27:21.000000000 +0100 @@ -15,6 +15,7 @@ #include <dirent.h> #include <limits.h> #include <sys/stat.h> +#include <sys/sysmacros.h> #include <linux/types.h> #include "hdparm.h"