hdparm.c (hdparm-9.58) | : | hdparm.c (hdparm-9.60) | ||
---|---|---|---|---|
/* | /* | |||
* hdparm.c - Command line interface to get/set hard disk parameters. | * hdparm.c - Command line interface to get/set hard disk parameters. | |||
* - by Mark Lord (C) 1994-2018 -- freely distributable. | * - by Mark Lord (C) 1994-2018 -- freely distributable. | |||
*/ | */ | |||
#define HDPARM_VERSION "v9.58" | #define HDPARM_VERSION "v9.60" | |||
#define _LARGEFILE64_SOURCE /*for lseek64*/ | #define _LARGEFILE64_SOURCE /*for lseek64*/ | |||
#define _BSD_SOURCE /* for strtoll() */ | #define _BSD_SOURCE /* for strtoll() */ | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <stdio.h> | #include <stdio.h> | |||
#define __USE_GNU /* for O_DIRECT */ | #define __USE_GNU /* for O_DIRECT */ | |||
#include <string.h> | #include <string.h> | |||
#include <fcntl.h> | #include <fcntl.h> | |||
#include <errno.h> | #include <errno.h> | |||
skipping to change at line 373 | skipping to change at line 373 | |||
/* | /* | |||
* get device size | * get device size | |||
*/ | */ | |||
if (do_ctimings || do_timings) { | if (do_ctimings || do_timings) { | |||
__u64 nsectors; | __u64 nsectors; | |||
do_flush = 1; | do_flush = 1; | |||
err = get_dev_geometry(fd, NULL, NULL, NULL, NULL, &nsectors); | err = get_dev_geometry(fd, NULL, NULL, NULL, NULL, &nsectors); | |||
if (!err) | if (!err) | |||
max_iterations = nsectors / (2 * 1024) / TIMING_BUF_MB; | max_iterations = nsectors / (2 * 1024) / TIMING_BUF_MB; | |||
err = 0; | ||||
} | } | |||
buf = prepare_timing_buf(TIMING_BUF_BYTES); | buf = prepare_timing_buf(TIMING_BUF_BYTES); | |||
if (!buf) | if (!buf) | |||
err = ENOMEM; | err = ENOMEM; | |||
if (err) | if (err) | |||
goto quit; | goto quit; | |||
printf(" Timing %s disk reads", (open_flags & O_DIRECT) ? "O_DIRECT" : "b uffered"); | printf(" Timing %s disk reads", (open_flags & O_DIRECT) ? "O_DIRECT" : "b uffered"); | |||
if (set_timings_offset) | if (set_timings_offset) | |||
printf(" (offset %llu GB)", timings_offset / 0x40000000ULL); | printf(" (offset %llu GB)", timings_offset / 0x40000000ULL); | |||
skipping to change at line 1077 | skipping to change at line 1078 | |||
last_identify_op = ATA_OP_IDENTIFY; | last_identify_op = ATA_OP_IDENTIFY; | |||
args[0] = last_identify_op; | args[0] = last_identify_op; | |||
args[3] = 1; /* sector count */ | args[3] = 1; /* sector count */ | |||
if (do_drive_cmd(fd, args, 0)) { | if (do_drive_cmd(fd, args, 0)) { | |||
prefer_ata12 = 0; | prefer_ata12 = 0; | |||
memset(args, 0, sizeof(args)); | memset(args, 0, sizeof(args)); | |||
last_identify_op = ATA_OP_PIDENTIFY; | last_identify_op = ATA_OP_PIDENTIFY; | |||
args[0] = last_identify_op; | args[0] = last_identify_op; | |||
args[3] = 1; /* sector count */ | args[3] = 1; /* sector count */ | |||
if (do_drive_cmd(fd, args, 0)) { | if (do_drive_cmd(fd, args, 0)) { | |||
perror(" HDIO_DRIVE_CMD(identify) failed"); | if (verbose) | |||
perror(" HDIO_DRIVE_CMD(identify) failed"); | ||||
return; | return; | |||
} | } | |||
} | } | |||
/* byte-swap the little-endian IDENTIFY data to match byte-order on host CPU */ | /* byte-swap the little-endian IDENTIFY data to match byte-order on host CPU */ | |||
id = (void *)(args + 4); | id = (void *)(args + 4); | |||
for (i = 0; i < 0x100; ++i) { | for (i = 0; i < 0x100; ++i) { | |||
unsigned char *b = (unsigned char *)&id[i]; | unsigned char *b = (unsigned char *)&id[i]; | |||
id[i] = b[0] | (b[1] << 8); /* le16_to_cpu() */ | id[i] = b[0] | (b[1] << 8); /* le16_to_cpu() */ | |||
} | } | |||
} | } | |||
skipping to change at line 1120 | skipping to change at line 1122 | |||
int get_log_page_data (int fd, __u8 log_address, __u8 pagenr, __u8 *buf) | int get_log_page_data (int fd, __u8 log_address, __u8 pagenr, __u8 *buf) | |||
{ | { | |||
static __u16 *page0 = NULL, page0_buf[512] = {0,}; | static __u16 *page0 = NULL, page0_buf[512] = {0,}; | |||
int err; | int err; | |||
get_identify_data(fd); | get_identify_data(fd); | |||
if (!id) | if (!id) | |||
exit(EIO); | exit(EIO); | |||
if ((id[84] && (1<<5)) == 0) | if ((id[84] && (1<<5)) == 0) | |||
return -ENOENT; /* READ_LOG_EXT not supported */ | return ENOENT; /* READ_LOG_EXT not supported */ | |||
if (!page0) { | if (!page0) { | |||
err = do_read_log(fd, 0, 0, page0_buf); | err = do_read_log(fd, 0, 0, page0_buf); | |||
if (err) { | if (err) { | |||
fprintf(stderr, "READ_LOG_EXT(0,0) failed: %s\n", strerro r(err)); | fprintf(stderr, "READ_LOG_EXT(0,0) failed: %s\n", strerro r(err)); | |||
return -ENOENT; | return ENOENT; | |||
} | } | |||
page0 = page0_buf; | page0 = page0_buf; | |||
} | } | |||
if (page0[log_address] <= pagenr) | if (page0[log_address] <= pagenr) | |||
return -ENOENT; | return ENOENT; | |||
err = do_read_log(fd, log_address, pagenr, buf); | err = do_read_log(fd, log_address, pagenr, buf); | |||
if (err) { | if (err) { | |||
fprintf(stderr, "READ_LOG_EXT(0x%02x, %u) failed: %s\n", log_addr ess, pagenr, strerror(err)); | fprintf(stderr, "READ_LOG_EXT(0x%02x, %u) failed: %s\n", log_addr ess, pagenr, strerror(err)); | |||
return -ENOENT; | return ENOENT; | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
static void confirm_i_know_what_i_am_doing (const char *opt, const char *explana tion) | static void confirm_i_know_what_i_am_doing (const char *opt, const char *explana tion) | |||
{ | { | |||
if (!i_know_what_i_am_doing) { | if (!i_know_what_i_am_doing) { | |||
fprintf(stderr, "Use of %s is VERY DANGEROUS.\n%s\n" | fprintf(stderr, "Use of %s is VERY DANGEROUS.\n%s\n" | |||
"Please supply the --yes-i-know-what-i-am-doing flag if you reall y want this.\n" | "Please supply the --yes-i-know-what-i-am-doing flag if you reall y want this.\n" | |||
"Program aborted.\n", opt, explanation); | "Program aborted.\n", opt, explanation); | |||
skipping to change at line 1196 | skipping to change at line 1198 | |||
unsigned char *b = (unsigned char *)w++; | unsigned char *b = (unsigned char *)w++; | |||
printf("%02x%02x", b[0], b[1]); | printf("%02x%02x", b[0], b[1]); | |||
putchar(word == 7 ? '\n' : ' '); | putchar(word == 7 ? '\n' : ' '); | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
static int abort_if_not_full_device (int fd, __u64 lba, const char *devname, con st char *msg) | static int abort_if_not_full_device (int fd, __u64 lba, const char *devname, con st char *msg) | |||
{ | { | |||
struct stat stat; | struct stat st; | |||
__u64 start_lba; | __u64 start_lba; | |||
int i, err, shortened = 0; | int i, err, shortened = 0; | |||
char *fdevname = strdup(devname); | char *fdevname = strdup(devname); | |||
if (0 == fstat(fd, &stat) && S_ISCHR(stat.st_mode)) | if (0 == fstat(fd, &st) && S_ISCHR(st.st_mode)) | |||
return 0; /* skip geometry test for character (non-block) devices ; eg. /dev/sg* */ | return 0; /* skip geometry test for character (non-block) devices ; eg. /dev/sg* */ | |||
err = get_dev_geometry(fd, NULL, NULL, NULL, &start_lba, NULL); | err = get_dev_geometry(fd, NULL, NULL, NULL, &start_lba, NULL); | |||
if (err) | if (err) | |||
exit(err); | exit(err); | |||
for (i = strlen(fdevname); --i > 2 && (fdevname[i] >= '0' && fdevname[i] <= '9');) { | for (i = strlen(fdevname); --i > 2 && (fdevname[i] >= '0' && fdevname[i] <= '9');) { | |||
fdevname[i] = '\0'; | fdevname[i] = '\0'; | |||
shortened = 1; | shortened = 1; | |||
} | } | |||
if (!shortened) | if (!shortened) | |||
skipping to change at line 1635 | skipping to change at line 1637 | |||
*checkword = d[i + 2] | (d[i + 3] << 8); | *checkword = d[i + 2] | (d[i + 3] << 8); | |||
return i / 16; /* descriptor index */ | return i / 16; /* descriptor index */ | |||
} | } | |||
} | } | |||
fprintf(stderr, "ERROR: unsupported sector size: %d\n", wanted_sector_siz e); | fprintf(stderr, "ERROR: unsupported sector size: %d\n", wanted_sector_siz e); | |||
exit (-1); | exit (-1); | |||
} | } | |||
static int do_set_sector_size_cmd (int fd, const char *devname) | static int do_set_sector_size_cmd (int fd, const char *devname) | |||
{ | { | |||
int index, err = 0; | int idx, err = 0; | |||
__u8 ata_op; | __u8 ata_op; | |||
struct hdio_taskfile *r; | struct hdio_taskfile *r; | |||
int checkword = 0; | int checkword = 0; | |||
abort_if_not_full_device(fd, 0, devname, NULL); | abort_if_not_full_device(fd, 0, devname, NULL); | |||
r = malloc(sizeof(struct hdio_taskfile) + 512); | r = malloc(sizeof(struct hdio_taskfile) + 512); | |||
if (!r) { | if (!r) { | |||
err = errno; | err = errno; | |||
perror("malloc()"); | perror("malloc()"); | |||
return err; | return err; | |||
} | } | |||
ata_op = ATA_OP_SET_SECTOR_CONFIGURATION; | ata_op = ATA_OP_SET_SECTOR_CONFIGURATION; | |||
init_hdio_taskfile(r, ata_op, RW_WRITE, LBA48_FORCE, 0, 0, 0); | init_hdio_taskfile(r, ata_op, RW_WRITE, LBA48_FORCE, 0, 0, 0); | |||
index = get_set_sector_index(fd, new_sector_size, &checkword); | idx = get_set_sector_index(fd, new_sector_size, &checkword); | |||
r->hob.feat = checkword >> 8; | r->hob.feat = checkword >> 8; | |||
r->lob.feat = checkword; | r->lob.feat = checkword; | |||
r->hob.nsect = 0; | r->hob.nsect = 0; | |||
r->lob.nsect = index; | r->lob.nsect = idx; | |||
r->oflags.bits.hob.feat = 1; | r->oflags.bits.hob.feat = 1; | |||
printf("changing sector size configuration to %llu: ", new_sector_size); | printf("changing sector size configuration to %llu: ", new_sector_size); | |||
fflush(stdout); | fflush(stdout); | |||
if (do_taskfile_cmd(fd, r, timeout_60secs)) { | if (do_taskfile_cmd(fd, r, timeout_60secs)) { | |||
err = errno; | err = errno; | |||
perror("FAILED"); | perror("FAILED"); | |||
} else { | } else { | |||
printf("succeeded\n"); | printf("succeeded\n"); | |||
End of changes. 12 change blocks. | ||||
11 lines changed or deleted | 13 lines changed or added |