#define ADV_PIO_MODES 64 /* advanced PIO modes supported */
/* multiword DMA xfer cycle time: */
#define DMA_TIME_MIN 65 /* - minimum */
-#define DMA_TIME_NORM 66 /* - manufacturer's recommended */
+#define DMA_TIME_NORM 66 /* - manufacturer's recommended */
/* minimum PIO xfer cycle time: */
#define PIO_NO_FLOW 67 /* - without flow control */
#define PIO_FLOW 68 /* - with IORDY flow control */
#define ENH_ERASE_TIME 90 /* - enhanced */
#define ADV_PWR 91 /* current advanced power management level
in low byte, 0x40 in high byte. */
-#define PSWD_CODE 92 /* master password revision code */
+#define PSWD_CODE 92 /* master password revision code */
#define HWRST_RSLT 93 /* hardware reset result */
#define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
#define LBA_LSB 100 /* LBA: maximum. Currently only 48 */
smallint set_readonly, get_readonly;
smallint set_unmask, get_unmask;
smallint set_mult, get_mult;
- smallint set_dma_q, get_dma_q;
+#ifdef HDIO_GET_QDMA
+ smallint get_dma_q;
+#ifdef HDIO_SET_QDMA
+ smallint set_dma_q;
+#endif
+#endif
smallint set_nowerr, get_nowerr;
smallint set_keep, get_keep;
smallint set_io32bit, get_io32bit;
unsigned long readonly;
unsigned long unmask;
unsigned long mult;
+#ifdef HDIO_SET_QDMA
unsigned long dma_q;
+#endif
unsigned long nowerr;
unsigned long keep;
unsigned long io32bit;
smallint set_apmmode, get_apmmode;
int xfermode_requested;
unsigned long dkeep;
- unsigned long standby_requested;
+ unsigned long standby_requested; /* 0..255 */
unsigned long lookahead;
unsigned long prefetch;
unsigned long defects;
return err_dma;
}
-static const char *nth_str(const char *strings, int n)
-{
- while (n) {
- n--;
- strings += strlen(strings) + 1;
- }
- return strings;
-}
-
static const char pkt_str[] ALIGN1 =
"Direct-access device" "\0" /* word 0, bits 12-8 = 00 */
"Sequential-access device" "\0" /* word 0, bits 12-8 = 01 */
;
// Parse 512 byte disk identification block and print much crap.
-static void identify(uint16_t *val) ATTRIBUTE_NORETURN;
+static void identify(uint16_t *val) NORETURN;
static void identify(uint16_t *val)
{
uint16_t ii, jj, kk;
} else if (!(val[GEN_CONFIG] & NOT_ATAPI)) {
dev = ATAPI_DEV;
eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
- printf("ATAPI %s, with ", eqpt <= 0xf ? nth_str(pkt_str, eqpt) : "unknown");
+ printf("ATAPI %s, with ", eqpt <= 0xf ? nth_string(pkt_str, eqpt) : "unknown");
like_std = 3;
} else
/* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
if (like_std < 3) like_std = 3;
std = actual_ver[val[MINOR]];
- if (std) printf("\n\tUsed: %s ", nth_str(minor_str, val[MINOR]));
+ if (std) printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
}
/* looks like when they up-issue the std, they obsolete one;
jj = val[GEN_CONFIG] >> 1;
for (ii = 1; ii < 15; ii++) {
if (jj & 0x0001)
- printf("\t%s\n", nth_str(ata1_cfg_str, ii));
+ printf("\t%s\n", nth_string(ata1_cfg_str, ii));
jj >>=1;
}
}
jj = val[CMDS_SUPP_0];
kk = val[CMDS_EN_0];
for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) {
- const char *feat_str = nth_str(cmd_feat_str, ii);
+ const char *feat_str = nth_string(cmd_feat_str, ii);
if ((jj & 0x8000) && (*feat_str != '\0')) {
printf("\t%s\t%s\n", (kk & 0x8000) ? " *" : "", feat_str);
}
}
/* Removable Media Status Notification feature set */
if ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP)
- printf("\t%s supported\n", nth_str(cmd_feat_str, 27));
+ printf("\t%s supported\n", nth_string(cmd_feat_str, 27));
/* security */
if ((eqpt != CDROM) && (like_std > 3)
jj = val[SECU_STATUS];
if (jj) {
for (ii = 0; ii < NUM_SECU_STR; ii++) {
- printf("\t%s\t%s\n", (!(jj & 0x0001)) ? "not" : "", nth_str(secu_str, ii));
+ printf("\t%s\t%s\n", (!(jj & 0x0001)) ? "not" : "", nth_string(secu_str, ii));
jj >>=1;
}
if (val[SECU_STATUS] & SECU_ENABLED) {
jj = val[ERASE_TIME] & ERASE_BITS;
kk = val[ENH_ERASE_TIME] & ERASE_BITS;
if (jj || kk) {
- printf("\t");
+ bb_putchar('\t');
if (jj) printf("%umin for %sSECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1, "");
if (kk) printf("%umin for %sSECURITY ERASE UNIT. ", kk==ERASE_BITS ? 508 : kk<<1, "ENHANCED ");
bb_putchar('\n');
/* reset result */
jj = val[HWRST_RSLT];
if ((jj & VALID) == VALID_VAL) {
- if (!(oo = (jj & RST0)))
+ oo = (jj & RST0);
+ if (!oo)
jj >>= 8;
if ((jj & DEV_DET) == JUMPER_VAL)
strng = " determined by the jumper";
#if ENABLE_FEATURE_HDPARM_GET_IDENTITY
static const char cfg_str[] ALIGN1 =
- """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
- "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
- "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
- "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
+ """\0" "HardSect""\0" "SoftSect""\0" "NotMFM""\0"
+ "HdSw>15uSec""\0" "SpinMotCtl""\0" "Fixed""\0" "Removeable""\0"
+ "DTR<=5Mbs""\0" "DTR>5Mbs""\0" "DTR>10Mbs""\0" "RotSpdTol>.5%""\0"
+ "dStbOff""\0" "TrkOff""\0" "FmtGapReq""\0" "nonMagnetic"
;
static const char BuffType[] ALIGN1 =
static void dump_identity(const struct hd_driveid *id)
{
int i;
- const unsigned short int *id_regs = (const void*) id;
+ const unsigned short *id_regs = (const void*) id;
printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
id->model, id->fw_rev, id->serial_no);
for (i = 0; i <= 15; i++) {
if (id->config & (1<<i))
- printf(" %s", nth_str(cfg_str, i));
+ printf(" %s", nth_string(cfg_str, i));
}
printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n"
" BuffType=(%u) %s, BuffSize=%ukB, MaxMultSect=%u",
id->cyls, id->heads, id->sectors, id->track_bytes,
id->sector_bytes, id->ecc_bytes,
- id->buf_type, nth_str(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
+ id->buf_type, nth_string(BuffType, (id->buf_type > 3) ? 0 : id->buf_type),
id->buf_size/2, id->max_multsect);
if (id->max_multsect) {
printf(", MultSect=");
if (id->tPIO >= 2) printf("pio2 ");
}
if (id->field_valid & 2) {
- if (id->eide_pio_modes & 1) printf("pio3 ");
- if (id->eide_pio_modes & 2) printf("pio4 ");
- if (id->eide_pio_modes &~3) printf("pio? ");
+ static const masks_labels_t pio_modes = {
+ .masks = { 1, 2, ~3 },
+ .labels = "pio3 \0""pio4 \0""pio? \0",
+ };
+ print_flags(&pio_modes, id->eide_pio_modes);
}
if (id->capability & 1) {
if (id->dma_1word | id->dma_mword) {
+ static const int dma_wmode_masks[] = { 0x100, 1, 0x200, 2, 0x400, 4, 0xf800, 0xf8 };
printf("\n DMA modes: ");
- if (id->dma_1word & 0x100) printf("*");
- if (id->dma_1word & 1) printf("sdma0 ");
- if (id->dma_1word & 0x200) printf("*");
- if (id->dma_1word & 2) printf("sdma1 ");
- if (id->dma_1word & 0x400) printf("*");
- if (id->dma_1word & 4) printf("sdma2 ");
- if (id->dma_1word & 0xf800) printf("*");
- if (id->dma_1word & 0xf8) printf("sdma? ");
- if (id->dma_mword & 0x100) printf("*");
- if (id->dma_mword & 1) printf("mdma0 ");
- if (id->dma_mword & 0x200) printf("*");
- if (id->dma_mword & 2) printf("mdma1 ");
- if (id->dma_mword & 0x400) printf("*");
- if (id->dma_mword & 4) printf("mdma2 ");
- if (id->dma_mword & 0xf800) printf("*");
- if (id->dma_mword & 0xf8) printf("mdma? ");
+ print_flags_separated(dma_wmode_masks,
+ "*\0""sdma0 \0""*\0""sdma1 \0""*\0""sdma2 \0""*\0""sdma? \0",
+ id->dma_1word, NULL);
+ print_flags_separated(dma_wmode_masks,
+ "*\0""mdma0\0""*\0""mdma1\0""*\0""mdma2\0""*\0""mdma?\0",
+ id->dma_mword, NULL);
}
}
if (((id->capability & 8) || (id->field_valid & 2)) && id->field_valid & 4) {
+ static const masks_labels_t ultra_modes1 = {
+ .masks = { 0x100, 0x001, 0x200, 0x002, 0x400, 0x004 },
+ .labels = "*\0""udma0 \0""*\0""udma1 \0""*\0""udma2 \0",
+ };
+
printf("\n UDMA modes: ");
- if (id->dma_ultra & 0x100) printf("*");
- if (id->dma_ultra & 0x001) printf("udma0 ");
- if (id->dma_ultra & 0x200) printf("*");
- if (id->dma_ultra & 0x002) printf("udma1 ");
- if (id->dma_ultra & 0x400) printf("*");
- if (id->dma_ultra & 0x004) printf("udma2 ");
+ print_flags(&ultra_modes1, id->dma_ultra);
#ifdef __NEW_HD_DRIVE_ID
if (id->hw_config & 0x2000) {
#else /* !__NEW_HD_DRIVE_ID */
if (id->word93 & 0x2000) {
#endif /* __NEW_HD_DRIVE_ID */
- if (id->dma_ultra & 0x0800) printf("*");
- if (id->dma_ultra & 0x0008) printf("udma3 ");
- if (id->dma_ultra & 0x1000) printf("*");
- if (id->dma_ultra & 0x0010) printf("udma4 ");
- if (id->dma_ultra & 0x2000) printf("*");
- if (id->dma_ultra & 0x0020) printf("udma5 ");
- if (id->dma_ultra & 0x4000) printf("*");
- if (id->dma_ultra & 0x0040) printf("udma6 ");
- if (id->dma_ultra & 0x8000) printf("*");
- if (id->dma_ultra & 0x0080) printf("udma7 ");
+ static const masks_labels_t ultra_modes2 = {
+ .masks = { 0x0800, 0x0008, 0x1000, 0x0010,
+ 0x2000, 0x0020, 0x4000, 0x0040,
+ 0x8000, 0x0080 },
+ .labels = "*\0""udma3 \0""*\0""udma4 \0"
+ "*\0""udma5 \0""*\0""udma6 \0"
+ "*\0""udma7 \0"
+ };
+ print_flags(&ultra_modes2, id->dma_ultra);
}
}
printf("\n AdvancedPM=%s", (!(id_regs[83] & 8)) ? "no" : "yes");
if ((id->minor_rev_num && id->minor_rev_num <= 31)
|| (id->major_rev_num && id->minor_rev_num <= 31)
) {
- printf("\n Drive conforms to: %s: ", (id->minor_rev_num <= 31) ? nth_str(minor_str, id->minor_rev_num) : "unknown");
+ printf("\n Drive conforms to: %s: ", (id->minor_rev_num <= 31) ? nth_string(minor_str, id->minor_rev_num) : "unknown");
if (id->major_rev_num != 0x0000 && /* NOVAL_0 */
id->major_rev_num != 0xFFFF) { /* NOVAL_1 */
for (i = 0; i <= 15; i++) {
#endif
#ifdef HDIO_DRIVE_CMD
-static void interpret_standby(unsigned standby)
+static void interpret_standby(uint8_t standby)
{
- unsigned t;
-
printf(" (");
- if (standby == 0)
+ if (standby == 0) {
printf("off");
- else if (standby == 252)
- printf("21 minutes");
- else if (standby == 253)
+ } else if (standby <= 240 || standby == 252 || standby == 255) {
+ /* standby is in 5 sec units */
+ printf("%u minutes %u seconds", standby / 12, (standby*5) % 60);
+ } else if (standby <= 251) {
+ unsigned t = (standby - 240); /* t is in 30 min units */;
+ printf("%u.%c hours", t / 2, (t & 1) ? '0' : '5');
+ }
+ if (standby == 253)
printf("vendor-specific");
- else if (standby == 254)
+ if (standby == 254)
printf("reserved");
- else if (standby == 255)
- printf("21 minutes + 15 seconds");
- else if (standby <= 240) {
- t = standby * 5;
- printf("%u minutes + %u seconds", t / 60, t % 60);
- } else if (standby <= 251) {
- t = (standby - 240) * 30;
- printf("%u hours + %u minutes", t / 60, t % 60);
- } else
- printf("illegal value");
printf(")\n");
}
static int translate_xfermode(const char *name)
{
- int val, i;
+ int val;
+ unsigned i;
for (i = 0; i < ARRAY_SIZE(xfermode_val); i++) {
if (!strncmp(name, xfermode_name[i], 5))
ioctl_or_warn(fd, HDIO_SET_DMA, (int *)dma);
}
#endif /* FEATURE_HDPARM_HDIO_GETSET_DMA */
+#ifdef HDIO_SET_QDMA
if (set_dma_q) {
print_flag_on_off(get_dma_q, "DMA queue_depth", dma_q);
ioctl_or_warn(fd, HDIO_SET_QDMA, (int *)dma_q);
}
+#endif
if (set_nowerr) {
print_flag_on_off(get_nowerr, "nowerr", nowerr);
ioctl_or_warn(fd, HDIO_SET_NOWERR, (int *)nowerr);
}
}
if (get_unmask) {
- if(!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, (unsigned long *)parm))
+ if (!ioctl_or_warn(fd, HDIO_GET_UNMASKINTR, &parm))
print_value_on_off("unmaskirq", parm);
}
}
}
#endif
+#ifdef HDIO_GET_QDMA
if (get_dma_q) {
- if(!ioctl_or_warn(fd, HDIO_GET_QDMA, (unsigned long *)parm))
+ if (!ioctl_or_warn(fd, HDIO_GET_QDMA, &parm))
print_value_on_off("queue_depth", parm);
}
+#endif
if (get_keep) {
- if(!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, (unsigned long *)parm))
+ if (!ioctl_or_warn(fd, HDIO_GET_KEEPSETTINGS, &parm))
print_value_on_off("keepsettings", parm);
}
if (get_nowerr) {
- if(!ioctl_or_warn(fd, HDIO_GET_NOWERR, (unsigned long *)parm))
+ if (!ioctl_or_warn(fd, HDIO_GET_NOWERR, &parm))
print_value_on_off("nowerr", parm);
}
if (get_readonly) {
- if(!ioctl_or_warn(fd, BLKROGET, (unsigned long *)parm))
+ if (!ioctl_or_warn(fd, BLKROGET, &parm))
print_value_on_off("readonly", parm);
}
if (get_readahead) {
- if(!ioctl_or_warn(fd, BLKRAGET, (unsigned long *)parm))
+ if (!ioctl_or_warn(fd, BLKRAGET, &parm))
print_value_on_off("readahead", parm);
}
if (get_geom) {
bb_error_msg_and_die("bad char: '%c' 0x%02x", c, c);
}
-static void identify_from_stdin(void) ATTRIBUTE_NORETURN;
+static void identify_from_stdin(void) NORETURN;
static void identify_from_stdin(void)
{
uint16_t sbuf[256];
unsigned char *b = (unsigned char *)buf;
int i;
- xread(0, buf, 1280);
+ xread(STDIN_FILENO, buf, 1280);
// Convert the newline-separated hex data into an identify block.
do_flush |= do_timings |= (c == 't');
do_flush |= do_ctimings |= (c == 'T');
#ifdef HDIO_DRIVE_CMD
- if (c == 'S') parse_opts(&get_standby, &set_standby, &standby_requested, 0, INT_MAX);
+ if (c == 'S') parse_opts(&get_standby, &set_standby, &standby_requested, 0, 255);
if (c == 'D') parse_opts(&get_defects, &set_defects, &defects, 0, INT_MAX);
if (c == 'P') parse_opts(&get_prefetch, &set_prefetch, &prefetch, 0, INT_MAX);
parse_xfermode((c == 'X'), &get_xfermode, &set_xfermode, &xfermode_requested);