aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/hdparm.c2321
1 files changed, 1265 insertions, 1056 deletions
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c
index abc3f387f..017d5bf19 100644
--- a/miscutils/hdparm.c
+++ b/miscutils/hdparm.c
@@ -3,7 +3,9 @@
3 * hdparm implementation for busybox 3 * hdparm implementation for busybox
4 * 4 *
5 * 5 *
6 * Copyright (C) [2003] by [Matteo Croce] <3297627799@wind.it> 6 * Copyright (C) [2003] by [Matteo Croce] <pinnolo@tin.it>
7 *
8 * Hacked by Tito <farmatito@tiscali.it> for size optimization.
7 * 9 *
8 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -25,7 +27,7 @@
25 * hdparm.c - Command line interface to get/set hard disk parameters 27 * hdparm.c - Command line interface to get/set hard disk parameters
26 * - by Mark Lord (C) 1994-2002 -- freely distributable 28 * - by Mark Lord (C) 1994-2002 -- freely distributable
27 */ 29 */
28 30
29#include <unistd.h> 31#include <unistd.h>
30#include <string.h> 32#include <string.h>
31#include <stdlib.h> 33#include <stdlib.h>
@@ -116,7 +118,7 @@
116#define ERASE_TIME 89 /* - ordinary */ 118#define ERASE_TIME 89 /* - ordinary */
117#define ENH_ERASE_TIME 90 /* - enhanced */ 119#define ENH_ERASE_TIME 90 /* - enhanced */
118#define ADV_PWR 91 /* current advanced power management level 120#define ADV_PWR 91 /* current advanced power management level
119 in low byte, 0x40 in high byte. */ 121 in low byte, 0x40 in high byte. */
120#define PSWD_CODE 92 /* master password revision code */ 122#define PSWD_CODE 92 /* master password revision code */
121#define HWRST_RSLT 93 /* hardware reset result */ 123#define HWRST_RSLT 93 /* hardware reset result */
122#define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */ 124#define ACOUSTIC 94 /* acoustic mgmt values ( >= ATA-6) */
@@ -144,7 +146,7 @@
144#define NOVAL_1 0xffff 146#define NOVAL_1 0xffff
145 147
146/* word 0: gen_config */ 148/* word 0: gen_config */
147#define NOT_ATA 0x8000 149#define NOT_ATA 0x8000
148#define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */ 150#define NOT_ATAPI 0x4000 /* (check only if bit 15 == 1) */
149#define MEDIA_REMOVABLE 0x0080 151#define MEDIA_REMOVABLE 0x0080
150#define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */ 152#define DRIVE_NOT_REMOVABLE 0x0040 /* bit obsoleted in ATA 6 */
@@ -220,7 +222,7 @@ static const char *ata1_cfg_str[] = { /* word 0 in ATA-1 mode */
220/* word 1: number of logical cylinders */ 222/* word 1: number of logical cylinders */
221#define LCYLS_MAX 0x3fff /* maximum allowable value */ 223#define LCYLS_MAX 0x3fff /* maximum allowable value */
222 224
223/* word 2: specific configureation 225/* word 2: specific configureation
224 * (a) require SET FEATURES to spin-up 226 * (a) require SET FEATURES to spin-up
225 * (b) require spin-up to fully reply to IDENTIFY DEVICE 227 * (b) require spin-up to fully reply to IDENTIFY DEVICE
226 */ 228 */
@@ -309,7 +311,7 @@ static const char *minor_str[] = { /* word 81 value: */
309 "reserved" /* 0x001f-0xfffe*/ 311 "reserved" /* 0x001f-0xfffe*/
310}; 312};
311#endif 313#endif
312static const char actual_ver[] = { 314static const char actual_ver[] = {
313 /* word 81 value: */ 315 /* word 81 value: */
314 0, /* 0x0000 WARNING: */ 316 0, /* 0x0000 WARNING: */
315 1, /* 0x0001 WARNING: */ 317 1, /* 0x0001 WARNING: */
@@ -347,7 +349,7 @@ static const char actual_ver[] = {
347#define CMDS_W82 0x77ff /* word 82: defined command locations*/ 349#define CMDS_W82 0x77ff /* word 82: defined command locations*/
348#define CMDS_W83 0x3fff /* word 83: defined command locations*/ 350#define CMDS_W83 0x3fff /* word 83: defined command locations*/
349#define CMDS_W84 0x002f /* word 83: defined command locations*/ 351#define CMDS_W84 0x002f /* word 83: defined command locations*/
350#define SUPPORT_48_BIT 0x0400 352#define SUPPORT_48_BIT 0x0400
351#define NUM_CMD_FEAT_STR 48 353#define NUM_CMD_FEAT_STR 48
352 354
353#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY 355#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY
@@ -408,7 +410,7 @@ static const char *cmd_feat_str[] = {
408 410
409/* words 85-87: cmds/feats enabled */ 411/* words 85-87: cmds/feats enabled */
410/* use cmd_feat_str[] to display what commands and features have 412/* use cmd_feat_str[] to display what commands and features have
411 * been enabled with words 85-87 413 * been enabled with words 85-87
412 */ 414 */
413 415
414/* words 89, 90, SECU ERASE TIME */ 416/* words 89, 90, SECU ERASE TIME */
@@ -427,7 +429,7 @@ static const char *cmd_feat_str[] = {
427/* word 127: removable media status notification feature set support */ 429/* word 127: removable media status notification feature set support */
428#define RM_STAT_BITS 0x0003 430#define RM_STAT_BITS 0x0003
429#define RM_STAT_SUP 0x0001 431#define RM_STAT_SUP 0x0001
430 432
431/* word 128: security */ 433/* word 128: security */
432#define SECU_ENABLED 0x0002 434#define SECU_ENABLED 0x0002
433#define SECU_LEVEL 0x0010 435#define SECU_LEVEL 0x0010
@@ -453,39 +455,174 @@ static const char *secu_str[] = {
453#define SIG 0x00ff /* signature location */ 455#define SIG 0x00ff /* signature location */
454#define SIG_VAL 0x00A5 /* signature value */ 456#define SIG_VAL 0x00A5 /* signature value */
455 457
458#define VERSION "v5.4"
459
460#define TIMING_MB 64
461#define TIMING_BUF_MB 1
462#define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
463#define TIMING_BUF_COUNT (timing_MB / TIMING_BUF_MB)
464#define BUFCACHE_FACTOR 2
465
466#undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
467
468/* Busybox messages and functions */
469
470const char * const bb_msg_shared_mem ="could not %s sharedmem buf";
471const char * const bb_msg_op_not_supp =" operation not supported on %s disks";
472
473static void bb_ioctl(int fd, int request, void *argp, const char *string)
474{
475 if (ioctl (fd, request, argp) != 0)
476 bb_error_msg(" %s", string);
477}
478
479static void if_printf(unsigned long i, char *fmt, ... )
480{
481 va_list ap;
482 va_start(ap, fmt);
483 if (i)
484 vprintf(fmt, ap);
485 va_end(ap);
486}
487
488static void on_off (unsigned int value);
489
490static void if_printf_on_off(unsigned long get_arg,const char *fmt, unsigned long arg)
491{
492 if (get_arg)
493 {
494 printf(fmt, arg);
495 on_off(arg);
496 }
497}
498
499static void bb_ioctl_on_off(int fd, int request, void *argp, const char *string,
500 const char * fmt)
501{
502 if (ioctl (fd, request, &argp) != 0)
503 bb_error_msg(" %s", string);
504 else
505 {
506 printf(fmt, (unsigned long) argp);
507 on_off((unsigned long) argp);
508 }
509}
510static void if_else_printf(unsigned long i, char *fmt1, char *fmt2, ... )
511{
512 va_list ap;
513 va_start(ap, fmt2);
514 if (i)
515 vprintf(fmt1, ap);
516 else
517 vprintf(fmt2, ap);
518 va_end(ap);
519}
520
521static void print_ascii(uint16_t *p, uint8_t length);
522
523static void xprint_ascii(uint16_t *val ,int i, char * string, int n)
524{
525 if(val[i])
526 {
527 printf("\t%-20s",string);
528 print_ascii(&val[i], n);
529 }
530}
531
532static void sync_and_sleep(int i)
533{
534 sync();
535 sleep(i);
536}
537
538static void check_if_min_and_set_val(uint16_t a, uint16_t b)
539{
540 if( a < b)
541 a = b;
542}
543
544static void check_if_maj_and_set_val(uint16_t a, uint16_t b)
545{
546 if( a > b)
547 a = b;
548}
549
550char * check_ptr(char *p, int argc, char **argv)
551{
552 if (!*p && argc && isdigit(**argv))
553 p = *argv++, --argc;
554 return p;
555}
556
557char * check_ptr_v2(char *p, int argc, char **argv)
558{
559 if (!*p && argc && isalnum(**argv))
560 p = *argv++, --argc;
561 return p;
562}
563
564unsigned long int set_flag(char *p, char max)
565{
566 if (*p >= '0' && *p <= max )
567 return 1;
568 return 0;
569}
570
571static void if_strcat(unsigned long test, char *modes, char *string)
572{
573 if (test)
574 strcat(modes,string);
575}
576
577/* end of busybox specific stuff */
578
456#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY 579#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY
457static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode) { 580static uint8_t mode_loop(uint16_t mode_sup, uint16_t mode_sel, int cc, uint8_t *have_mode)
581{
458 uint16_t ii; 582 uint16_t ii;
459 uint8_t err_dma = 0; 583 uint8_t err_dma = 0;
460 for(ii = 0; ii <= MODE_MAX; ii++) { 584
461 if(mode_sel & 0x0001) { 585 for(ii = 0; ii <= MODE_MAX; ii++)
586 {
587 if(mode_sel & 0x0001)
588 {
462 printf("*%cdma%u ",cc,ii); 589 printf("*%cdma%u ",cc,ii);
463 if(*have_mode) err_dma = 1; 590 if(*have_mode)
591 err_dma = 1;
464 *have_mode = 1; 592 *have_mode = 1;
465 } else if(mode_sup & 0x0001) {
466 printf("%cdma%u ",cc,ii);
467 } 593 }
468 mode_sup >>=1; mode_sel >>=1; 594 else if(mode_sup & 0x0001)
595 printf("%cdma%u ",cc,ii);
596
597 mode_sup >>=1;
598 mode_sel >>=1;
469 } 599 }
470 return err_dma; 600 return err_dma;
471} 601}
602
472static void print_ascii(uint16_t *p, uint8_t length) { 603static void print_ascii(uint16_t *p, uint8_t length) {
473 uint8_t ii; 604 uint8_t ii;
474 char cl; 605 char cl;
475 606
476 /* find first non-space & print it */ 607 /* find first non-space & print it */
477 for(ii = 0; ii< length; ii++) { 608 for(ii = 0; ii< length; ii++)
478 if(((char) 0x00ff&((*p)>>8)) != ' ') break; 609 {
479 if((cl = (char) 0x00ff&(*p)) != ' ') { 610 if(((char) 0x00ff&((*p)>>8)) != ' ')
480 if(cl != '\0') printf("%c",cl); 611 break;
481 p++; ii++; 612 if((cl = (char) 0x00ff&(*p)) != ' ')
613 {
614 if_printf((cl != '\0'),"%c",cl);
615 p++;
616 ii++;
482 break; 617 break;
483 } 618 }
484 p++; 619 p++;
485 } 620 }
486 /* print the rest */ 621 /* print the rest */
487 for(; ii< length; ii++) { 622 for(; ii< length; ii++)
488 if(!(*p)) break; /* some older devices have NULLs */ 623 {
624 if(!(*p))
625 break; /* some older devices have NULLs */
489 printf("%c%c",(char)0x00ff&((*p)>>8),(char)(*p)&0x00ff); 626 printf("%c%c",(char)0x00ff&((*p)>>8),(char)(*p)&0x00ff);
490 p++; 627 p++;
491 } 628 }
@@ -499,7 +636,7 @@ static void print_ascii(uint16_t *p, uint8_t length) {
499static void identify (uint16_t *id_supplied, const char *devname) 636static void identify (uint16_t *id_supplied, const char *devname)
500{ 637{
501 638
502 char *id_file = NULL, fmt[]="/proc/ide/%s/identify"; 639 char *id_file = NULL;
503 FILE *fl; 640 FILE *fl;
504 uint16_t val[256], ii, jj, kk; 641 uint16_t val[256], ii, jj, kk;
505 uint16_t like_std = 1, std = 0, min_std = 0xffff; 642 uint16_t like_std = 1, std = 0, min_std = 0xffff;
@@ -509,29 +646,35 @@ static void identify (uint16_t *id_supplied, const char *devname)
509 uint32_t ll, mm, nn, oo; 646 uint32_t ll, mm, nn, oo;
510 __u64 bbbig; /* (:) */ 647 __u64 bbbig; /* (:) */
511 648
512 if (id_supplied) { 649 if (id_supplied)
650 {
513#if __BYTE_ORDER == __BIG_ENDIAN 651#if __BYTE_ORDER == __BIG_ENDIAN
514 swab(id_supplied, val, sizeof(val)); 652 swab(id_supplied, val, sizeof(val));
515#else 653#else
516 memcpy(val, id_supplied, sizeof(val)); 654 memcpy(val, id_supplied, sizeof(val));
517#endif 655#endif
518 } else { 656 }
519 id_file = xcalloc(1, strlen(devname)+1+strlen(fmt)); 657 else
520 sprintf(id_file, fmt, devname); 658 {
521 659 id_file = xcalloc(1, strlen(devname)+22);
660 sprintf(id_file, "/proc/ide/%s/identify", devname);
522 /* open the file, read in all the info and close it */ 661 /* open the file, read in all the info and close it */
523 if (id_file == NULL) { 662 if (id_file == NULL)
524 fl = stdin; 663 fl = stdin;
525 } else if(NULL == (fl = fopen(id_file, "r"))) 664 else
526 bb_perror_msg_and_die(id_file); 665 fl = bb_xfopen(id_file, "r");
666
527 /* calculate checksum over all bytes */ 667 /* calculate checksum over all bytes */
528 for(ii = GEN_CONFIG; ii<=INTEGRITY; ii++) { 668 for(ii = GEN_CONFIG; ii<=INTEGRITY; ii++)
669 {
529 unsigned int scratch; 670 unsigned int scratch;
530 if(1 != fscanf(fl,"%04x",&scratch)) break; 671 if(1 != fscanf(fl,"%04x",&scratch))
672 break;
531 val[ii] = (uint16_t)scratch; 673 val[ii] = (uint16_t)scratch;
532 chksum += val[ii] + (val[ii] >> 8); 674 chksum += val[ii] + (val[ii] >> 8);
533 } 675 }
534 fclose(fl); 676 fclose(fl);
677 /*bb_fclose_nonstdin(fl);*/
535 if(ii < (INTEGRITY+1)) 678 if(ii < (INTEGRITY+1))
536 bb_error_msg_and_die("Input file wrong format or length"); 679 bb_error_msg_and_die("Input file wrong format or length");
537 } 680 }
@@ -539,358 +682,407 @@ static void identify (uint16_t *id_supplied, const char *devname)
539 682
540 /* check if we recognise the device type */ 683 /* check if we recognise the device type */
541 printf("\n"); 684 printf("\n");
542 if(!(val[GEN_CONFIG] & NOT_ATA)) { 685 if(!(val[GEN_CONFIG] & NOT_ATA))
686 {
543 dev = ATA_DEV; 687 dev = ATA_DEV;
544 printf("ATA device, with "); 688 printf("ATA device, with ");
545 } else if(val[GEN_CONFIG]==CFA_SUPPORT_VAL) { 689 }
690 else if(val[GEN_CONFIG]==CFA_SUPPORT_VAL)
691 {
546 dev = ATA_DEV; 692 dev = ATA_DEV;
547 like_std = 4; 693 like_std = 4;
548 printf("CompactFlash ATA device, with "); 694 printf("CompactFlash ATA device, with ");
549 } else if(!(val[GEN_CONFIG] & NOT_ATAPI)) { 695 }
696 else if(!(val[GEN_CONFIG] & NOT_ATAPI))
697 {
550 dev = ATAPI_DEV; 698 dev = ATAPI_DEV;
551 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT; 699 eqpt = (val[GEN_CONFIG] & EQPT_TYPE) >> SHIFT_EQPT;
552 printf("ATAPI %s, with ", pkt_str[eqpt]); 700 printf("ATAPI %s, with ", pkt_str[eqpt]);
553 like_std = 3; 701 like_std = 3;
554 } else {
555 bb_error_msg_and_die("Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n");
556 } 702 }
557 if(!(val[GEN_CONFIG] & MEDIA_REMOVABLE)) 703 else
558 printf("non-"); 704 /*"Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n"*/
559 printf("removable media\n"); 705 bb_error_msg_and_die("Unknown device type");
560 706
707 if_printf(!(val[GEN_CONFIG] & MEDIA_REMOVABLE),"non-");
708 printf("removable media\n");
561 709
562 /* Info from the specific configuration word says whether or not the 710 /* Info from the specific configuration word says whether or not the
563 * ID command completed correctly. It is only defined, however in 711 * ID command completed correctly. It is only defined, however in
564 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior 712 * ATA/ATAPI-5 & 6; it is reserved (value theoretically 0) in prior
565 * standards. Since the values allowed for this word are extremely 713 * standards. Since the values allowed for this word are extremely
566 * specific, it should be safe to check it now, even though we don't 714 * specific, it should be safe to check it now, even though we don't
567 * know yet what standard this device is using. 715 * know yet what standard this device is using.
568 */ 716 */
569 if((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL) || 717 if((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL) ||
570 (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL) ) { 718 (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL) )
571 like_std = 5; 719 {
572 if((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)) 720 like_std = 5;
573 printf("powers-up in standby; SET FEATURES subcmd spins-up.\n"); 721 if_printf(((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)),
574 if(((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && 722 "powers-up in standby; SET FEATURES subcmd spins-up.\n");
575 (val[GEN_CONFIG] & INCOMPLETE)) 723 if_printf((((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE)),
576 printf("\n\tWARNING: ID response incomplete.\n\tWARNING: Following data may be incorrect.\n\n"); 724 "\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");
577 } 725 }
578 726
579 /* output the model and serial numbers and the fw revision */ 727 /* output the model and serial numbers and the fw revision */
580 if(val[START_MODEL]) { 728 xprint_ascii(val, START_MODEL, "Model Number:", LENGTH_MODEL);
581 printf("\t%-20s","Model Number:"); 729 xprint_ascii(val, START_SERIAL, "Serial Number:", LENGTH_SERIAL);
582 print_ascii(&val[START_MODEL], LENGTH_MODEL); 730 xprint_ascii(val, START_FW_REV, "Firmware Revision:", LENGTH_FW_REV);
583 } 731 xprint_ascii(val, START_MEDIA, "Media Serial Num:", LENGTH_MEDIA);
584 if(val[START_SERIAL]) { 732 xprint_ascii(val, START_MANUF, "Media Manufacturer:", LENGTH_MANUF);
585 printf("\t%-20s","Serial Number:");
586 print_ascii( &val[START_SERIAL], LENGTH_SERIAL);
587 }
588 if(val[START_FW_REV]) {
589 printf("\t%-20s","Firmware Revision:");
590 print_ascii(&val[START_FW_REV], LENGTH_FW_REV);
591 }
592 if(val[START_MEDIA]) {
593 printf("\t%-20s","Media Serial Num:");
594 print_ascii(&val[START_MEDIA], LENGTH_MEDIA);
595 }
596 if(val[START_MANUF]) {
597 printf("\t%-20s","Media Manufacturer:");
598 print_ascii(&val[START_MANUF], LENGTH_MANUF);
599 }
600 733
601 /* major & minor standards version number (Note: these words were not 734 /* major & minor standards version number (Note: these words were not
602 * defined until ATA-3 & the CDROM std uses different words.) */ 735 * defined until ATA-3 & the CDROM std uses different words.) */
603 printf("Standards:"); 736 printf("Standards:");
604 if(eqpt != CDROM) { 737 if(eqpt != CDROM)
605 if(val[MINOR] && (val[MINOR] <= MINOR_MAX)){ 738 {
606 if(like_std < 3) like_std = 3; 739 if(val[MINOR] && (val[MINOR] <= MINOR_MAX))
740 {
741 check_if_min_and_set_val( like_std, 3);
607 std = actual_ver[val[MINOR]]; 742 std = actual_ver[val[MINOR]];
608 if(std) { 743 if_printf(std,"\n\tUsed: %s ",minor_str[val[MINOR]]);
609 printf("\n\tUsed: "); 744
610 printf("%s ",minor_str[val[MINOR]]);
611 }
612 } 745 }
613 /* looks like when they up-issue the std, they obsolete one; 746 /* looks like when they up-issue the std, they obsolete one;
614 * thus, only the newest 4 issues need be supported. (That's 747 * thus, only the newest 4 issues need be supported. (That's
615 * what "kk" and "min_std" are all about.) */ 748 * what "kk" and "min_std" are all about.) */
616 if(val[MAJOR] && (val[MAJOR] !=NOVAL_1)) { 749 if(val[MAJOR] && (val[MAJOR] !=NOVAL_1))
750 {
617 printf("\n\tSupported: "); 751 printf("\n\tSupported: ");
618 jj = val[MAJOR] << 1; 752 jj = val[MAJOR] << 1;
619 kk = like_std >4 ? like_std-4: 0; 753 kk = like_std >4 ? like_std-4: 0;
620 for(ii = 14; (ii >0)&&(ii>kk); ii--) { 754 for(ii = 14; (ii >0)&&(ii>kk); ii--)
621 if(jj & 0x8000) { 755 {
756 if(jj & 0x8000)
757 {
622 printf("%u ", ii); 758 printf("%u ", ii);
623 if(like_std < ii) { 759 if(like_std < ii)
760 {
624 like_std = ii; 761 like_std = ii;
625 kk = like_std >4 ? like_std-4: 0; 762 kk = like_std >4 ? like_std-4: 0;
626 } 763 }
627 if(min_std > ii) min_std = ii; 764 check_if_maj_and_set_val(min_std, ii);
628 } 765 }
629 jj <<= 1; 766 jj <<= 1;
630 } 767 }
631 if(like_std < 3) like_std = 3; 768 check_if_min_and_set_val( like_std, 3);
632 } 769 }
633 /* Figure out what standard the device is using if it hasn't told 770 /* Figure out what standard the device is using if it hasn't told
634 * us. If we know the std, check if the device is using any of 771 * us. If we know the std, check if the device is using any of
635 * the words from the next level up. It happens. 772 * the words from the next level up. It happens.
636 */ 773 */
637 if(like_std < std) like_std = std; 774 check_if_min_and_set_val( like_std, std);
775
638 if(((std == 5) || (!std && (like_std < 6))) && 776 if(((std == 5) || (!std && (like_std < 6))) &&
639 ( (((val[CMDS_SUPP_1] & VALID) == VALID_VAL) && 777 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
640 ((val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) || 778 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x00ff)) ||
641 (((val[CMDS_SUPP_2] & VALID) == VALID_VAL) && 779 ((( val[CMDS_SUPP_2] & VALID) == VALID_VAL) &&
642 (val[CMDS_SUPP_2] & CMDS_W84) ) ) ) { 780 ( val[CMDS_SUPP_2] & CMDS_W84) ) ) )
781 {
643 like_std = 6; 782 like_std = 6;
644 } else if(((std == 4) || (!std && (like_std < 5))) && 783 }
645 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) || 784 else if(((std == 4) || (!std && (like_std < 5))) &&
646 ((val[HWRST_RSLT] & VALID) == VALID_VAL) || 785 ((((val[INTEGRITY] & SIG) == SIG_VAL) && !chksum) ||
647 (((val[CMDS_SUPP_1] & VALID) == VALID_VAL) && 786 (( val[HWRST_RSLT] & VALID) == VALID_VAL) ||
648 ((val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) ) { 787 ((( val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
788 (( val[CMDS_SUPP_1] & CMDS_W83) > 0x001f)) ) )
789 {
649 like_std = 5; 790 like_std = 5;
650 } else if(((std == 3) || (!std && (like_std < 4))) && 791 }
651 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) && 792 else if(((std == 3) || (!std && (like_std < 4))) &&
652 (((val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) || 793 ((((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
653 ((val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) || 794 ((( val[CMDS_SUPP_1] & CMDS_W83) > 0x0000) ||
654 ((val[CAPAB_1] & VALID) == VALID_VAL) || 795 (( val[CMDS_SUPP_0] & CMDS_W82) > 0x000f))) ||
655 ((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) || 796 (( val[CAPAB_1] & VALID) == VALID_VAL) ||
656 ((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) ) ) { 797 (( val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) ||
798 (( val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) ) )
799 {
657 like_std = 4; 800 like_std = 4;
658 } else if(((std == 2) || (!std && (like_std < 3))) && 801 }
659 ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) ) { 802 else if(((std == 2) || (!std && (like_std < 3))) &&
803 ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) )
804 {
660 like_std = 3; 805 like_std = 3;
661 } else if(((std == 1) || (!std && (like_std < 2))) && 806 }
662 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) || 807 else if(((std == 1) || (!std && (like_std < 2))) &&
663 (val[WHATS_VALID] & OK_W64_70)) ) { 808 ((val[CAPAB_0] & (IORDY_SUP | IORDY_OFF)) ||
809 (val[WHATS_VALID] & OK_W64_70)) )
810 {
664 like_std = 2; 811 like_std = 2;
665 } 812 }
666 if(!std) { 813 if(!std)
667 printf("\n\tLikely used: %u\n",like_std); 814 printf("\n\tLikely used: %u\n",like_std);
668 } else if(like_std > std) { 815 else if(like_std > std)
669 printf("& some of %u\n",like_std); 816 printf("& some of %u\n",like_std);
670 } else printf("\n"); 817 else
671 } else { 818 printf("\n");
819 }
820 else
821 {
672 /* TBD: do CDROM stuff more thoroughly. For now... */ 822 /* TBD: do CDROM stuff more thoroughly. For now... */
673 kk = 0; 823 kk = 0;
674 if(val[CDR_MINOR] == 9) { 824 if(val[CDR_MINOR] == 9)
825 {
675 kk = 1; 826 kk = 1;
676 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5"); 827 printf("\n\tUsed: ATAPI for CD-ROMs, SFF-8020i, r2.5");
677 } 828 }
678 if(val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1)) { 829 if(val[CDR_MAJOR] && (val[CDR_MAJOR] !=NOVAL_1))
830 {
679 kk = 1; 831 kk = 1;
680 printf("\n\tSupported: CD-ROM ATAPI"); 832 printf("\n\tSupported: CD-ROM ATAPI");
681 jj = val[CDR_MAJOR] >> 1; 833 jj = val[CDR_MAJOR] >> 1;
682 for(ii = 1; ii <15; ii++) { 834 for(ii = 1; ii <15; ii++)
683 if(jj & 0x0001) { 835 {
684 printf("-%u ", ii); 836 if_printf((jj & 0x0001),"-%u ", ii);
685 }
686 jj >>= 1; 837 jj >>= 1;
687 } 838 }
688 } 839 }
689 if(!kk) printf("\n\tLikely used CD-ROM ATAPI-1\n"); 840 if_else_printf((!kk),"\n\tLikely used CD-ROM ATAPI-1\n","\n");
690 else printf("\n");
691 /* the cdrom stuff is more like ATA-2 than anything else, so: */ 841 /* the cdrom stuff is more like ATA-2 than anything else, so: */
692 like_std = 2; 842 like_std = 2;
693 } 843 }
694 844
695 if(min_std == 0xffff) min_std = like_std > 4 ? like_std - 3 : 1; 845 if(min_std == 0xffff)
846 min_std = like_std > 4 ? like_std - 3 : 1;
696 847
697 printf("Configuration:\n"); 848 printf("Configuration:\n");
698 /* more info from the general configuration word */ 849 /* more info from the general configuration word */
699 if((eqpt != CDROM) && (like_std == 1)) { 850 if((eqpt != CDROM) && (like_std == 1))
851 {
700 jj = val[GEN_CONFIG] >> 1; 852 jj = val[GEN_CONFIG] >> 1;
701 for(ii = 1; ii < 15; ii++) { 853 for(ii = 1; ii < 15; ii++)
702 if(jj & 0x0001) printf("\t%s\n",ata1_cfg_str[ii]); 854 {
855 if_printf((jj & 0x0001),"\t%s\n",ata1_cfg_str[ii]);
703 jj >>=1; 856 jj >>=1;
704 } 857 }
705 } 858 }
706 if(dev == ATAPI_DEV) { 859 if(dev == ATAPI_DEV)
860 {
707 printf("\tDRQ response: "); /* Data Request (DRQ) */ 861 printf("\tDRQ response: "); /* Data Request (DRQ) */
708 switch(val[GEN_CONFIG] & DRQ_RESPONSE_TIME) { 862 switch(val[GEN_CONFIG] & DRQ_RESPONSE_TIME)
709 case DRQ_3MS_VAL : printf("3ms.\n"); break; 863 {
710 case DRQ_INTR_VAL : printf("<=10ms with INTRQ\n"); break; 864 case DRQ_3MS_VAL :
711 case DRQ_50US_VAL : printf("50us.\n"); break; 865 printf("3ms.\n");
712 default : printf("unknown.\n"); break; 866 break;
867 case DRQ_INTR_VAL :
868 printf("<=10ms with INTRQ\n");
869 break;
870 case DRQ_50US_VAL :
871 printf("50us.\n");
872 break;
873 default :
874 printf("unknown.\n");
875 break;
713 } 876 }
714 printf("\tPacket size: "); 877 printf("\tPacket size: ");
715 switch(val[GEN_CONFIG] & PKT_SIZE_SUPPORTED) { 878 switch(val[GEN_CONFIG] & PKT_SIZE_SUPPORTED)
716 case PKT_SIZE_12_VAL : printf("12 bytes\n"); break; 879 {
717 case PKT_SIZE_16_VAL : printf("16 bytes\n"); break; 880 case PKT_SIZE_12_VAL :
718 default : printf("Unknown\n"); break; 881 printf("12 bytes\n");
882 break;
883 case PKT_SIZE_16_VAL :
884 printf("16 bytes\n");
885 break;
886 default :
887 printf("Unknown\n");
888 break;
719 } 889 }
720 } else { 890 }
721 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */ 891 else
892 {
893 /* addressing...CHS? See section 6.2 of ATA specs 4 or 5 */
722 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB]; 894 ll = (uint32_t)val[LBA_SECTS_MSB] << 16 | val[LBA_SECTS_LSB];
723 mm = 0; bbbig = 0; 895 mm = 0; bbbig = 0;
724 if ( (ll > 0x00FBFC10) && (!val[LCYLS])) { 896 if ( (ll > 0x00FBFC10) && (!val[LCYLS]))
725 printf("\tCHS addressing not supported\n"); 897 printf("\tCHS addressing not supported\n");
726 } else { 898 else
899 {
727 jj = val[WHATS_VALID] & OK_W54_58; 900 jj = val[WHATS_VALID] & OK_W54_58;
728 printf("\tLogical\t\tmax\tcurrent\n"); 901 printf("\tLogical\t\tmax\tcurrent\n\tcylinders\t%u\t%u\n\theads\t\t%u\t%u\n\tsectors/track\t%u\t%u\n\t--\n",
729 printf("\tcylinders\t%u\t%u\n",val[LCYLS],jj?val[LCYLS_CUR]:0); 902 val[LCYLS],jj?val[LCYLS_CUR]:0, val[LHEADS],jj?val[LHEADS_CUR]:0, val[LSECTS],jj?val[LSECTS_CUR]:0);
730 printf("\theads\t\t%u\t%u\n",val[LHEADS],jj?val[LHEADS_CUR]:0); 903
731 printf("\tsectors/track\t%u\t%u\n",val[LSECTS],jj?val[LSECTS_CUR]:0); 904 if_printf(((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES])),
732 printf("\t--\n"); 905 "\tbytes/track: %u\tbytes/sector: %u\n",val[TRACK_BYTES], val[SECT_BYTES]);
733 if((min_std == 1) && (val[TRACK_BYTES] || val[SECT_BYTES])) { 906
734 printf("\tbytes/track: %u",val[TRACK_BYTES]); 907 if(jj)
735 printf("\tbytes/sector: %u\n",val[SECT_BYTES]); 908 {
736 }
737 if(jj) {
738 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB]; 909 mm = (uint32_t)val[CAPACITY_MSB] << 16 | val[CAPACITY_LSB];
739 if(like_std < 3) { /* check Endian of capacity bytes */ 910 if(like_std < 3)
911 {
912 /* check Endian of capacity bytes */
740 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR]; 913 nn = val[LCYLS_CUR] * val[LHEADS_CUR] * val[LSECTS_CUR];
741 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB]; 914 oo = (uint32_t)val[CAPACITY_LSB] << 16 | val[CAPACITY_MSB];
742 if(abs(mm - nn) > abs(oo - nn)) 915 if(abs(mm - nn) > abs(oo - nn))
743 mm = oo; 916 mm = oo;
744 } 917 }
745 printf("\tCHS current addressable sectors:%11u\n",mm); 918 printf("\tCHS current addressable sectors:%11u\n",mm);
746 } 919 }
747 } 920 }
748 /* LBA addressing */ 921 /* LBA addressing */
749 printf("\tLBA user addressable sectors:%11u\n",ll); 922 printf("\tLBA user addressable sectors:%11u\n",ll);
750 if( ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) && 923 if( ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) &&
751 (val[CMDS_SUPP_1] & SUPPORT_48_BIT) ) { 924 (val[CMDS_SUPP_1] & SUPPORT_48_BIT) )
752 bbbig = (__u64)val[LBA_64_MSB] << 48 | 925 {
753 (__u64)val[LBA_48_MSB] << 32 | 926 bbbig = (__u64)val[LBA_64_MSB] << 48 |
754 (__u64)val[LBA_MID] << 16 | 927 (__u64)val[LBA_48_MSB] << 32 |
755 val[LBA_LSB] ; 928 (__u64)val[LBA_MID] << 16 |
929 val[LBA_LSB] ;
756 printf("\tLBA48 user addressable sectors:%11llu\n",bbbig); 930 printf("\tLBA48 user addressable sectors:%11llu\n",bbbig);
757 } 931 }
758 if (!bbbig) bbbig = (__u64)(ll>mm ? ll : mm); /* # 512 byte blocks */ 932
933 if (!bbbig)
934 bbbig = (__u64)(ll>mm ? ll : mm); /* # 512 byte blocks */
759 printf("\tdevice size with M = 1024*1024: %11llu MBytes\n",bbbig>>11); 935 printf("\tdevice size with M = 1024*1024: %11llu MBytes\n",bbbig>>11);
760 bbbig = (bbbig<<9)/1000000; 936 bbbig = (bbbig<<9)/1000000;
761 printf("\tdevice size with M = 1000*1000: %11llu MBytes ",bbbig); 937 printf("\tdevice size with M = 1000*1000: %11llu MBytes ",bbbig);
762 if(bbbig > 1000) printf("(%llu GB)\n",bbbig/1000); 938
763 else printf("\n"); 939 if_else_printf((bbbig > 1000),"(%llu GB)\n","\n",bbbig/1000);
764 940
765 } 941 }
766 942
767 /* hw support of commands (capabilities) */ 943 /* hw support of commands (capabilities) */
768 printf("Capabilities:\n"); 944 printf("Capabilities:\n\t");
769 printf("\t"); 945
770 if(dev == ATAPI_DEV) { 946 if(dev == ATAPI_DEV)
771 if(eqpt != CDROM) { 947 {
772 if(val[CAPAB_0] & CMD_Q_SUP) printf("Cmd queuing, "); 948 if(eqpt != CDROM)
773 } 949 if_printf((val[CAPAB_0] & CMD_Q_SUP),"Cmd queuing, ");
774 if(val[CAPAB_0] & OVLP_SUP) printf("Cmd overlap, "); 950
951 if_printf((val[CAPAB_0] & OVLP_SUP),"Cmd overlap, ");
775 } 952 }
776 if(val[CAPAB_0] & LBA_SUP) printf("LBA, "); 953 if_printf((val[CAPAB_0] & LBA_SUP),"LBA, ");
777 if(like_std != 1) { 954
955 if(like_std != 1)
956 {
778 printf("IORDY"); 957 printf("IORDY");
779 if(!(val[CAPAB_0] & IORDY_SUP)) printf("(may be)"); 958 if_printf((!(val[CAPAB_0] & IORDY_SUP)),"(may be)");
780 if(val[CAPAB_0] & IORDY_OFF) printf("(can"); 959 if_else_printf((val[CAPAB_0] & IORDY_OFF),"(can","(cannot");
781 else printf("(cannot"); 960 printf(" be disabled)\n");
782 printf(" be disabled)"); 961 }
783 } else printf("no IORDY"); 962 else
784 printf("\n"); 963 printf("no IORDY\n");
785 if((like_std == 1) && val[BUF_TYPE]) { 964
965 if((like_std == 1) && val[BUF_TYPE])
966 {
786 kk = val[BUF_TYPE]; 967 kk = val[BUF_TYPE];
787 printf("\tBuffer type: %04x: ",kk); 968 printf("\tBuffer type: %04x: ",kk);
788 if (kk < 2) printf("single port, single-sector"); 969 if_else_printf((kk < 2),"single port, single-sector","dual port, multi-sector");
789 else printf("dual port, multi-sector"); 970 if_printf((kk > 2)," with read caching ability");
790 if (kk > 2) printf(" with read caching ability");
791 printf("\n"); 971 printf("\n");
792 } 972 }
793 jj = 0; 973 jj = 0;
794 if((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1))) { 974 if((min_std == 1) && (val[BUFFER__SIZE] && (val[BUFFER__SIZE] != NOVAL_1)))
975 {
795 printf("\tBuffer size: %.1fkB",(float)val[BUFFER__SIZE]/2); 976 printf("\tBuffer size: %.1fkB",(float)val[BUFFER__SIZE]/2);
796 jj = 1; 977 jj = 1;
797 } 978 }
798 if((min_std < 4) && (val[RW_LONG])) { 979 if((min_std < 4) && (val[RW_LONG]))
980 {
799 printf("\tbytes avail on r/w long: %u",val[RW_LONG]); 981 printf("\tbytes avail on r/w long: %u",val[RW_LONG]);
800 jj = 1; 982 jj = 1;
801 } 983 }
802 if((eqpt != CDROM) && (like_std > 3)) { 984 if((eqpt != CDROM) && (like_std > 3))
985 {
803 printf("\tQueue depth: %u",(val[QUEUE_DEPTH] & DEPTH_BITS)+1); 986 printf("\tQueue depth: %u",(val[QUEUE_DEPTH] & DEPTH_BITS)+1);
804 jj = 1; 987 jj = 1;
805 } 988 }
806 if(jj) printf("\n"); 989 if_printf(jj,"\n");
807 if(dev == ATA_DEV) { 990
808 if(like_std == 1) { 991 if(dev == ATA_DEV)
809 printf("\tCan"); 992 {
810 if(!val[DWORD_IO]) printf("not"); 993 if(like_std == 1)
811 printf(" perform double-word IO\n"); 994 printf("\tCan%s perform double-word IO\n",(!val[DWORD_IO]) ?"not":"");
812 } else { 995 else
996 {
813 printf("\tStandby timer values: spec'd by "); 997 printf("\tStandby timer values: spec'd by ");
814 if(val[CAPAB_0] & STD_STBY) printf("Standard"); 998 if_else_printf((val[CAPAB_0] & STD_STBY),"Standard","Vendor");
815 else printf("Vendor"); 999 if((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL))
816 if((like_std > 3) && ((val[CAPAB_1] & VALID) == VALID_VAL)) { 1000 printf(", %s device specific minimum\n",(val[CAPAB_1] & MIN_STANDBY_TIMER)?"with":"no");
817 if(val[CAPAB_1] & MIN_STANDBY_TIMER) printf(", with "); 1001 else
818 else printf(", no "); 1002 printf("\n");
819 printf("device specific minimum\n");
820 } else printf("\n");
821 } 1003 }
822 printf("\tR/W multiple sector transfer: "); 1004 printf("\tR/W multiple sector transfer: ");
823 if((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER)) { 1005 if((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER))
824 printf("not supported\n"); 1006 printf("not supported\n");
825 } else { 1007 else
826 printf("Max = %u\t",val[SECTOR_XFER_MAX] & SECTOR_XFER); 1008 {
827 printf("Current = "); 1009 printf("Max = %u\tCurrent = ",val[SECTOR_XFER_MAX] & SECTOR_XFER);
828 if(val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID) 1010 if_else_printf((val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID),
829 printf("%u\n",val[SECTOR_XFER_CUR] & SECTOR_XFER); 1011 "%u\n","?\n",val[SECTOR_XFER_CUR] & SECTOR_XFER);
830 else printf("?\n");
831 } 1012 }
832 if((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) { 1013 if((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008))
1014 {
833 /* We print out elsewhere whether the APM feature is enabled or 1015 /* We print out elsewhere whether the APM feature is enabled or
834 not. If it's not enabled, let's not repeat the info; just print 1016 not. If it's not enabled, let's not repeat the info; just print
835 nothing here. */ 1017 nothing here. */
836 printf("\tAdvanced power management level: "); 1018 printf("\tAdvancedPM level: ");
837 if ( (val[ADV_PWR] & 0xFF00) == 0x4000 ) { 1019 if ( (val[ADV_PWR] & 0xFF00) == 0x4000 )
1020 {
838 uint8_t apm_level = val[ADV_PWR] & 0x00FF; 1021 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
839
840 printf("%u (0x%x)\n", apm_level, apm_level); 1022 printf("%u (0x%x)\n", apm_level, apm_level);
841 } else {
842 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
843 }
844 }
845 if(like_std > 5) {
846 if(val[ACOUSTIC]) {
847 printf("\tRecommended acoustic management value: %u, current value: %u\n", (val[ACOUSTIC] >> 8) & 0x00ff, val[ACOUSTIC] & 0x00ff);
848 } 1023 }
1024 else
1025 printf("unknown setting (0x%04x)\n", val[ADV_PWR]);
849 } 1026 }
850 } else { /* ATAPI */ 1027 if(like_std > 5)
851 if(eqpt != CDROM) { 1028 {
852 if(val[CAPAB_0] & SWRST_REQ) printf("\tATA sw reset required\n"); 1029 if_printf(val[ACOUSTIC],"\tRecommended acoustic management value: %u, current value: %u\n",
1030 (val[ACOUSTIC] >> 8) & 0x00ff, val[ACOUSTIC] & 0x00ff);
853 } 1031 }
854 if(val[PKT_REL] || val[SVC_NBSY]) { 1032 }
1033 else
1034 {
1035 /* ATAPI */
1036 if(eqpt != CDROM)
1037 if_printf((val[CAPAB_0] & SWRST_REQ),"\tATA sw reset required\n");
1038
1039 if(val[PKT_REL] || val[SVC_NBSY])
1040 {
855 printf("\tOverlap support:"); 1041 printf("\tOverlap support:");
856 if(val[PKT_REL]) printf(" %uus to release bus.",val[PKT_REL]); 1042 if_printf(val[PKT_REL]," %uus to release bus.",val[PKT_REL]);
857 if(val[SVC_NBSY]) printf(" %uus to clear BSY after SERVICE cmd.",val[SVC_NBSY]); 1043 if_printf(val[SVC_NBSY]," %uus to clear BSY after SERVICE cmd.",val[SVC_NBSY]);
858 printf("\n"); 1044 printf("\n");
859 } 1045 }
860 } 1046 }
861 1047
862 /* DMA stuff. Check that only one DMA mode is selected. */ 1048 /* DMA stuff. Check that only one DMA mode is selected. */
863 printf("\tDMA: "); 1049 printf("\tDMA: ");
864 if(!(val[CAPAB_0] & DMA_SUP)) { 1050 if(!(val[CAPAB_0] & DMA_SUP))
865 printf("not supported\n"); 1051 printf("not supported\n");
866 } else { 1052 else
867 if(val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA]) 1053 {
868 printf(" sdma%u\n",(val[DMA_MODE] & MODE) >> 8); 1054 if_printf((val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA]),
869 if(val[SINGLE_DMA]) { 1055 " sdma%u\n",(val[DMA_MODE] & MODE) >> 8);
870 jj = val[SINGLE_DMA]; kk = val[SINGLE_DMA] >> 8; 1056 if(val[SINGLE_DMA])
1057 {
1058 jj = val[SINGLE_DMA];
1059 kk = val[SINGLE_DMA] >> 8;
871 err_dma += mode_loop(jj,kk,'s',&have_mode); 1060 err_dma += mode_loop(jj,kk,'s',&have_mode);
872 } 1061 }
873 if(val[MULTI_DMA]) { 1062 if(val[MULTI_DMA])
874 jj = val[MULTI_DMA]; kk = val[MULTI_DMA] >> 8; 1063 {
1064 jj = val[MULTI_DMA];
1065 kk = val[MULTI_DMA] >> 8;
875 err_dma += mode_loop(jj,kk,'m',&have_mode); 1066 err_dma += mode_loop(jj,kk,'m',&have_mode);
876 } 1067 }
877 if((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA]) { 1068 if((val[WHATS_VALID] & OK_W88) && val[ULTRA_DMA])
878 jj = val[ULTRA_DMA]; kk = val[ULTRA_DMA] >> 8; 1069 {
1070 jj = val[ULTRA_DMA];
1071 kk = val[ULTRA_DMA] >> 8;
879 err_dma += mode_loop(jj,kk,'u',&have_mode); 1072 err_dma += mode_loop(jj,kk,'u',&have_mode);
880 } 1073 }
881 if(err_dma || !have_mode) printf("(?)"); 1074 if_printf((err_dma || !have_mode),"(?)");
882 printf("\n"); 1075 printf("\n");
883 1076
884 if((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP)) 1077 if_printf(((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP)),
885 printf("\t Interleaved DMA support\n"); 1078 "\t Interleaved DMA support\n");
886 1079
887 if((val[WHATS_VALID] & OK_W64_70) && 1080 if((val[WHATS_VALID] & OK_W64_70) &&
888 (val[DMA_TIME_MIN] || val[DMA_TIME_NORM])) { 1081 (val[DMA_TIME_MIN] || val[DMA_TIME_NORM]))
1082 {
889 printf("\t Cycle time:"); 1083 printf("\t Cycle time:");
890 if(val[DMA_TIME_MIN]) 1084 if_printf(val[DMA_TIME_MIN]," min=%uns",val[DMA_TIME_MIN]);
891 printf(" min=%uns",val[DMA_TIME_MIN]); 1085 if_printf(val[DMA_TIME_NORM]," recommended=%uns",val[DMA_TIME_NORM]);
892 if(val[DMA_TIME_NORM])
893 printf(" recommended=%uns",val[DMA_TIME_NORM]);
894 printf("\n"); 1086 printf("\n");
895 } 1087 }
896 } 1088 }
@@ -899,98 +1091,115 @@ static void identify (uint16_t *id_supplied, const char *devname)
899 printf("\tPIO: "); 1091 printf("\tPIO: ");
900 /* If a drive supports mode n (e.g. 3), it also supports all modes less 1092 /* If a drive supports mode n (e.g. 3), it also supports all modes less
901 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */ 1093 * than n (e.g. 3, 2, 1 and 0). Print all the modes. */
902 if((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP)) { 1094 if((val[WHATS_VALID] & OK_W64_70) && (val[ADV_PIO_MODES] & PIO_SUP))
1095 {
903 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007; 1096 jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007;
904 for(ii = 0; ii <= PIO_MODE_MAX ; ii++) { 1097 for(ii = 0; ii <= PIO_MODE_MAX ; ii++)
905 if(jj & 0x0001) 1098 {
906 printf("pio%d ",ii); 1099 if_printf((jj & 0x0001),"pio%d ",ii);
907 jj >>=1; 1100 jj >>=1;
908 } 1101 }
909 printf("\n"); 1102 printf("\n");
910 } else if(((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE) ) { 1103 }
911 for(ii = 0; ii <= val[PIO_MODE]>>8; ii++) { 1104 else if(((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE) )
1105 {
1106 for(ii = 0; ii <= val[PIO_MODE]>>8; ii++)
912 printf("pio%d ",ii); 1107 printf("pio%d ",ii);
913 }
914 printf("\n"); 1108 printf("\n");
915 } else printf("unknown\n"); 1109 }
916 if(val[WHATS_VALID] & OK_W64_70) { 1110 else
917 if(val[PIO_NO_FLOW] || val[PIO_FLOW]) { 1111 printf("unknown\n");
1112
1113 if(val[WHATS_VALID] & OK_W64_70)
1114 {
1115 if(val[PIO_NO_FLOW] || val[PIO_FLOW])
1116 {
918 printf("\t Cycle time:"); 1117 printf("\t Cycle time:");
919 if(val[PIO_NO_FLOW]) 1118 if_printf(val[PIO_NO_FLOW]," no flow control=%uns", val[PIO_NO_FLOW]);
920 printf(" no flow control=%uns", val[PIO_NO_FLOW]); 1119 if_printf(val[PIO_FLOW]," IORDY flow control=%uns", val[PIO_FLOW]);
921 if(val[PIO_FLOW])
922 printf(" IORDY flow control=%uns", val[PIO_FLOW]);
923 printf("\n"); 1120 printf("\n");
924 } 1121 }
925 } 1122 }
926 1123
927 if((val[CMDS_SUPP_1] & VALID) == VALID_VAL){ 1124 if((val[CMDS_SUPP_1] & VALID) == VALID_VAL)
1125 {
928 printf("Commands/features:\n\tEnabled\tSupported:\n"); 1126 printf("Commands/features:\n\tEnabled\tSupported:\n");
929 jj = val[CMDS_SUPP_0]; 1127 jj = val[CMDS_SUPP_0];
930 kk = val[CMDS_EN_0]; 1128 kk = val[CMDS_EN_0];
931 for(ii = 0; ii < NUM_CMD_FEAT_STR; ii++) { 1129 for(ii = 0; ii < NUM_CMD_FEAT_STR; ii++)
932 if((jj & 0x8000) && (*cmd_feat_str[ii] != '\0')) { 1130 {
933 if(kk & 0x8000) printf("\t *"); 1131 if((jj & 0x8000) && (*cmd_feat_str[ii] != '\0'))
934 else printf("\t"); 1132 {
1133 if_else_printf((kk & 0x8000),"\t *","\t");
935 printf("\t%s\n",cmd_feat_str[ii]); 1134 printf("\t%s\n",cmd_feat_str[ii]);
936 } 1135 }
937 jj <<=1; kk<<=1; 1136 jj <<=1; kk<<=1;
938 if(ii%16 == 15) { 1137 if(ii%16 == 15)
1138 {
939 jj = val[CMDS_SUPP_0+1+(ii/16)]; 1139 jj = val[CMDS_SUPP_0+1+(ii/16)];
940 kk = val[CMDS_EN_0+1+(ii/16)]; 1140 kk = val[CMDS_EN_0+1+(ii/16)];
941 } 1141 }
942 if(ii == 31) { 1142 if(ii == 31)
943 if((val[CMDS_SUPP_2] & VALID) != VALID_VAL) ii +=16; 1143 {
1144 if((val[CMDS_SUPP_2] & VALID) != VALID_VAL)
1145 ii +=16;
944 } 1146 }
945 } 1147 }
946 } 1148 }
947 if((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP) 1149 if_printf(((val[RM_STAT] & RM_STAT_BITS) == RM_STAT_SUP),
948 printf("\tRemovable Media Status Notification feature set supported\n"); 1150 "\tRemovable Media Status Notification feature set supported\n");
949 1151
950 1152
951 /* security */ 1153 /* security */
952 if((eqpt != CDROM) && (like_std > 3) && 1154 if((eqpt != CDROM) && (like_std > 3) &&
953 (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME])) { 1155 (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME]))
1156 {
954 printf("Security: \n"); 1157 printf("Security: \n");
955 if(val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1)) 1158 if_printf((val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1)),
956 printf("\tMaster password revision code = %u\n",val[PSWD_CODE]); 1159 "\tMaster password revision code = %u\n",val[PSWD_CODE]);
957 jj = val[SECU_STATUS]; 1160 jj = val[SECU_STATUS];
958 if(jj) { 1161 if(jj)
959 for(ii = 0; ii < NUM_SECU_STR; ii++) { 1162 {
960 if(!(jj & 0x0001)) printf("\tnot\t"); 1163 for(ii = 0; ii < NUM_SECU_STR; ii++)
961 else printf("\t\t"); 1164 {
962 printf("%s\n",secu_str[ii]); 1165 if_else_printf((!(jj & 0x0001)),"\tnot\t%s\n", "\t\t%s\n", secu_str[ii]);
963 jj >>=1; 1166 jj >>=1;
964 } 1167 }
965 if(val[SECU_STATUS] & SECU_ENABLED) { 1168 if(val[SECU_STATUS] & SECU_ENABLED)
1169 {
966 printf("\tSecurity level "); 1170 printf("\tSecurity level ");
967 if(val[SECU_STATUS] & SECU_LEVEL) printf("maximum\n"); 1171 if_else_printf((val[SECU_STATUS] & SECU_LEVEL),"maximum\n","high\n");
968 else printf("high\n");
969 } 1172 }
970 } 1173 }
971 jj = val[ERASE_TIME] & ERASE_BITS; 1174 jj = val[ERASE_TIME] & ERASE_BITS;
972 kk = val[ENH_ERASE_TIME] & ERASE_BITS; 1175 kk = val[ENH_ERASE_TIME] & ERASE_BITS;
973 if(jj || kk) { 1176 if(jj || kk)
1177 {
974 printf("\t"); 1178 printf("\t");
975 if(jj) printf("%umin for SECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1); 1179 if_printf(jj,"%umin for SECURITY ERASE UNIT. ", jj==ERASE_BITS ? 508 : jj<<1);
976 if(kk) printf("%umin for ENHANCED SECURITY ERASE UNIT.", kk==ERASE_BITS ? 508 : kk<<1); 1180 if_printf(kk,"%umin for ENHANCED SECURITY ERASE UNIT.", kk==ERASE_BITS ? 508 : kk<<1);
977 printf("\n"); 1181 printf("\n");
978 } 1182 }
979 } 1183 }
980 1184
981 /* reset result */ 1185 /* reset result */
982 if((val[HWRST_RSLT] & VALID) == VALID_VAL) { 1186 if((val[HWRST_RSLT] & VALID) == VALID_VAL)
1187 {
983 printf("HW reset results:\n"); 1188 printf("HW reset results:\n");
984 if(val[HWRST_RSLT] & CBLID) printf("\tCBLID- above Vih\n"); 1189 if_else_printf((val[HWRST_RSLT] & CBLID),"\tCBLID- above Vih\n","\tCBLID- below Vih\n");
985 else printf("\tCBLID- below Vih\n"); 1190
986 if(val[HWRST_RSLT] & RST0) { 1191 if(val[HWRST_RSLT] & RST0)
1192 {
987 printf("\tDevice num = 0"); 1193 printf("\tDevice num = 0");
988 jj = val[HWRST_RSLT]; 1194 jj = val[HWRST_RSLT];
989 } else { 1195 }
1196 else
1197 {
990 printf("\tDevice num = 1"); 1198 printf("\tDevice num = 1");
991 jj = val[HWRST_RSLT] >> 8; 1199 jj = val[HWRST_RSLT] >> 8;
992 } 1200 }
993 if((jj & DEV_DET) == JUMPER_VAL) 1201
1202 if((jj & DEV_DET) == JUMPER_VAL)
994 printf(" determined by the jumper"); 1203 printf(" determined by the jumper");
995 else if((jj & DEV_DET) == CSEL_VAL) 1204 else if((jj & DEV_DET) == CSEL_VAL)
996 printf(" determined by CSEL"); 1205 printf(" determined by CSEL");
@@ -998,21 +1207,22 @@ static void identify (uint16_t *id_supplied, const char *devname)
998 } 1207 }
999 1208
1000 /* more stuff from std 5 */ 1209 /* more stuff from std 5 */
1001 if((like_std > 4) && (eqpt != CDROM)) { 1210 if((like_std > 4) && (eqpt != CDROM))
1002 if(val[CFA_PWR_MODE] & VALID_W160) { 1211 {
1212 if(val[CFA_PWR_MODE] & VALID_W160)
1213 {
1003 printf("CFA power mode 1:\n\t"); 1214 printf("CFA power mode 1:\n\t");
1004 if(val[CFA_PWR_MODE] & PWR_MODE_OFF) printf("dis"); 1215 if_else_printf((val[CFA_PWR_MODE] & PWR_MODE_OFF),"disabled","enabled");
1005 else printf("en"); 1216
1006 printf("abled"); 1217 if_printf((val[CFA_PWR_MODE] & PWR_MODE_REQ)," and required by some commands");
1007 if(val[CFA_PWR_MODE] & PWR_MODE_REQ)
1008 printf(" and required by some commands");
1009 printf("\n"); 1218 printf("\n");
1010 if(val[CFA_PWR_MODE] & MAX_AMPS) 1219
1011 printf("\tMaximum current = %uma\n",val[CFA_PWR_MODE] & MAX_AMPS); 1220 if_printf((val[CFA_PWR_MODE] & MAX_AMPS),"\tMaximum current = %uma\n",val[CFA_PWR_MODE] & MAX_AMPS);
1012 } 1221 }
1013 if((val[INTEGRITY] & SIG) == SIG_VAL) { 1222 if((val[INTEGRITY] & SIG) == SIG_VAL)
1223 {
1014 printf("Checksum: "); 1224 printf("Checksum: ");
1015 if(chksum) printf("in"); 1225 if_printf(chksum,"in");
1016 printf("correct\n"); 1226 printf("correct\n");
1017 } 1227 }
1018 } 1228 }
@@ -1021,23 +1231,13 @@ static void identify (uint16_t *id_supplied, const char *devname)
1021} 1231}
1022#endif 1232#endif
1023 1233
1024#define VERSION "v5.4"
1025
1026#define TIMING_MB 64
1027#define TIMING_BUF_MB 1
1028#define TIMING_BUF_BYTES (TIMING_BUF_MB * 1024 * 1024)
1029#define TIMING_BUF_COUNT (timing_MB / TIMING_BUF_MB)
1030#define BUFCACHE_FACTOR 2
1031
1032#undef DO_FLUSHCACHE /* under construction: force cache flush on -W0 */
1033
1034static int verbose = 0, get_identity = 0, get_geom = 0, noisy = 1, quiet = 0; 1234static int verbose = 0, get_identity = 0, get_geom = 0, noisy = 1, quiet = 0;
1035static int flagcount = 0, do_flush = 0, is_scsi_hd = 0, is_xt_hd = 0; 1235static int flagcount = 0, do_flush = 0, is_scsi_hd = 0, is_xt_hd = 0;
1036static int do_ctimings, do_timings = 0; 1236static int do_ctimings, do_timings = 0;
1037 1237
1038static unsigned long set_readahead= 0, get_readahead= 0, readahead= 0; 1238static unsigned long set_readahead= 0, get_readahead= 0, readahead= 0;
1039static unsigned long set_readonly = 0, get_readonly = 0, readonly = 0; 1239static unsigned long set_readonly = 0, get_readonly = 0, readonly = 0;
1040static unsigned long set_unmask = 0, get_unmask = 0, unmask = 0; 1240static unsigned long set_unmask = 0, get_unmask = 0, unmask = 0;
1041static unsigned long set_mult = 0, get_mult = 0, mult = 0; 1241static unsigned long set_mult = 0, get_mult = 0, mult = 0;
1042#ifdef CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA 1242#ifdef CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA
1043static unsigned long set_dma = 0, get_dma = 0, dma = 0; 1243static unsigned long set_dma = 0, get_dma = 0, dma = 0;
@@ -1110,16 +1310,6 @@ static const char *cfg_str[] =
1110 1310
1111static const char *BuffType[] = {"unknown", "1Sect", "DualPort", "DualPortCache"}; 1311static const char *BuffType[] = {"unknown", "1Sect", "DualPort", "DualPortCache"};
1112 1312
1113#define YN(b) (((b)==0)?"no":"yes")
1114
1115static void dmpstr (const char *prefix, unsigned int i, const char *s[], unsigned int maxi)
1116{
1117 if (i > maxi)
1118 printf("%s%u", prefix, i);
1119 else
1120 printf("%s%s", prefix, s[i]);
1121}
1122
1123static void dump_identity (const struct hd_driveid *id) 1313static void dump_identity (const struct hd_driveid *id)
1124{ 1314{
1125 int i; 1315 int i;
@@ -1127,20 +1317,23 @@ static void dump_identity (const struct hd_driveid *id)
1127 const unsigned short int *id_regs= (const void*) id; 1317 const unsigned short int *id_regs= (const void*) id;
1128 unsigned long capacity; 1318 unsigned long capacity;
1129 1319
1130 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s", 1320 printf("\n Model=%.40s, FwRev=%.8s, SerialNo=%.20s\n Config={",
1131 id->model, id->fw_rev, id->serial_no); 1321 id->model, id->fw_rev, id->serial_no);
1132 printf("\n Config={"); 1322 for (i=0; i<=15; i++)
1133 for (i=0; i<=15; i++) { 1323 if_printf((id->config & (1<<i)),"%s", cfg_str[i]);
1134 if (id->config & (1<<i)) 1324
1135 printf("%s", cfg_str[i]); 1325 printf(" }\n RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n",
1136 } 1326 id->cyls, id->heads, id->sectors, id->track_bytes,
1137 printf(" }\n"); 1327 id->sector_bytes, id->ecc_bytes);
1138 printf(" RawCHS=%u/%u/%u, TrkSize=%u, SectSize=%u, ECCbytes=%u\n", 1328
1139 id->cyls, id->heads, id->sectors, 1329 if (id->buf_type > 3)
1140 id->track_bytes, id->sector_bytes, id->ecc_bytes); 1330 printf("%s%u", " BuffType=", id->buf_type);
1141 dmpstr(" BuffType=",id->buf_type,BuffType,3); 1331 else
1332 printf("%s%s", " BuffType=", BuffType[id->buf_type]);
1333
1142 printf(", BuffSize=%ukB, MaxMultSect=%u", id->buf_size/2, id->max_multsect); 1334 printf(", BuffSize=%ukB, MaxMultSect=%u", id->buf_size/2, id->max_multsect);
1143 if (id->max_multsect) { 1335 if (id->max_multsect)
1336 {
1144 printf(", MultSect="); 1337 printf(", MultSect=");
1145 if (!(id->multsect_valid&1)) 1338 if (!(id->multsect_valid&1))
1146 printf("?%u?", id->multsect); 1339 printf("?%u?", id->multsect);
@@ -1149,42 +1342,46 @@ static void dump_identity (const struct hd_driveid *id)
1149 else 1342 else
1150 printf("off"); 1343 printf("off");
1151 } 1344 }
1152 putchar('\n'); 1345 printf("\n");
1153 if (id->tPIO <= 5) { 1346 if (id->tPIO <= 5)
1347 {
1154 strcat(pmodes, "pio0 "); 1348 strcat(pmodes, "pio0 ");
1155 if (id->tPIO >= 1) strcat(pmodes, "pio1 "); 1349 if_strcat((id->tPIO >= 1), pmodes, "pio1 ");
1156 if (id->tPIO >= 2) strcat(pmodes, "pio2 "); 1350 if_strcat((id->tPIO >= 2), pmodes, "pio2 ");
1351
1157 } 1352 }
1158 if (!(id->field_valid&1)) 1353 if_printf((!(id->field_valid&1))," (maybe):");
1159 printf(" (maybe):");
1160#if __BYTE_ORDER == __BIG_ENDIAN 1354#if __BYTE_ORDER == __BIG_ENDIAN
1161 capacity = (id->cur_capacity0 << 16) | id->cur_capacity1; 1355 capacity = (id->cur_capacity0 << 16) | id->cur_capacity1;
1162#else 1356#else
1163 capacity = (id->cur_capacity1 << 16) | id->cur_capacity0; 1357 capacity = (id->cur_capacity1 << 16) | id->cur_capacity0;
1164#endif 1358#endif
1165 printf(" CurCHS=%u/%u/%u, CurSects=%lu", id->cur_cyls, id->cur_heads, id->cur_sectors, capacity); 1359 printf(" CurCHS=%u/%u/%u, CurSects=%lu, LBA=%s",id->cur_cyls, id->cur_heads,
1166 printf(", LBA=%s", YN(id->capability&2)); 1360 id->cur_sectors, capacity ,
1167 if (id->capability&2) 1361 ((id->capability&2)==0)?"no":"yes");
1168 printf(", LBAsects=%u", id->lba_capacity); 1362
1169 1363 if_printf((id->capability&2),", LBAsects=%u", id->lba_capacity);
1170 if (id->capability&1) { 1364
1171 if (id->dma_1word | id->dma_mword) { 1365 if (id->capability&1)
1172 if (id->dma_1word & 0x100) strcat(dmodes,"*"); 1366 {
1173 if (id->dma_1word & 1) strcat(dmodes,"sdma0 "); 1367 if (id->dma_1word | id->dma_mword)
1174 if (id->dma_1word & 0x200) strcat(dmodes,"*"); 1368 {
1175 if (id->dma_1word & 2) strcat(dmodes,"sdma1 "); 1369 if_strcat((id->dma_1word & 0x100), dmodes, "*");
1176 if (id->dma_1word & 0x400) strcat(dmodes,"*"); 1370 if_strcat((id->dma_1word & 1), dmodes, "sdma0 ");
1177 if (id->dma_1word & 4) strcat(dmodes,"sdma2 "); 1371 if_strcat((id->dma_1word & 0x200), dmodes, "*");
1178 if (id->dma_1word & 0xf800) strcat(dmodes,"*"); 1372 if_strcat((id->dma_1word & 2), dmodes, "sdma1 ");
1179 if (id->dma_1word & 0xf8) strcat(dmodes,"sdma? "); 1373 if_strcat((id->dma_1word & 0x400), dmodes, "*");
1180 if (id->dma_mword & 0x100) strcat(dmodes,"*"); 1374 if_strcat((id->dma_1word & 4), dmodes, "sdma2 ");
1181 if (id->dma_mword & 1) strcat(dmodes,"mdma0 "); 1375 if_strcat((id->dma_1word & 0xf800), dmodes, "*");
1182 if (id->dma_mword & 0x200) strcat(dmodes,"*"); 1376 if_strcat((id->dma_1word & 0xf8), dmodes, "sdma? ");
1183 if (id->dma_mword & 2) strcat(dmodes,"mdma1 "); 1377 if_strcat((id->dma_mword & 0x100), dmodes, "*");
1184 if (id->dma_mword & 0x400) strcat(dmodes,"*"); 1378 if_strcat((id->dma_mword & 1), dmodes, "mdma0 ");
1185 if (id->dma_mword & 4) strcat(dmodes,"mdma2 "); 1379 if_strcat((id->dma_mword & 0x200), dmodes, "*");
1186 if (id->dma_mword & 0xf800) strcat(dmodes,"*"); 1380 if_strcat((id->dma_mword & 2), dmodes, "mdma1 ");
1187 if (id->dma_mword & 0xf8) strcat(dmodes,"mdma? "); 1381 if_strcat((id->dma_mword & 0x400), dmodes, "*");
1382 if_strcat((id->dma_mword & 4), dmodes, "mdma2 ");
1383 if_strcat((id->dma_mword & 0xf800), dmodes, "*");
1384 if_strcat((id->dma_mword & 0xf8), dmodes, "mdma? ");
1188 } 1385 }
1189 } 1386 }
1190 printf("\n IORDY="); 1387 printf("\n IORDY=");
@@ -1192,116 +1389,117 @@ static void dump_identity (const struct hd_driveid *id)
1192 printf((id->capability&4) ? "on/off" : "yes"); 1389 printf((id->capability&4) ? "on/off" : "yes");
1193 else 1390 else
1194 printf("no"); 1391 printf("no");
1195 if ((id->capability&8) || (id->field_valid&2)) { 1392
1196 if (id->field_valid&2) { 1393 if ((id->capability&8) || (id->field_valid&2))
1394 {
1395 if (id->field_valid&2)
1396 {
1197 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy); 1397 printf(", tPIO={min:%u,w/IORDY:%u}", id->eide_pio, id->eide_pio_iordy);
1198 if (id->eide_pio_modes & 1) strcat(pmodes, "pio3 "); 1398 if_strcat((id->eide_pio_modes & 1), pmodes, "pio3 ");
1199 if (id->eide_pio_modes & 2) strcat(pmodes, "pio4 "); 1399 if_strcat((id->eide_pio_modes & 2), pmodes, "pio4 ");
1200 if (id->eide_pio_modes &~3) strcat(pmodes, "pio? "); 1400 if_strcat((id->eide_pio_modes &~3), pmodes, "pio? ");
1201 } 1401 }
1202 if (id->field_valid&4) { 1402 if (id->field_valid&4)
1203 if (id->dma_ultra & 0x100) strcat(umodes,"*"); 1403 {
1204 if (id->dma_ultra & 0x001) strcat(umodes,"udma0 "); 1404 if_strcat((id->dma_ultra & 0x100),umodes,"*");
1205 if (id->dma_ultra & 0x200) strcat(umodes,"*"); 1405 if_strcat((id->dma_ultra & 0x001),umodes,"udma0 ");
1206 if (id->dma_ultra & 0x002) strcat(umodes,"udma1 "); 1406 if_strcat((id->dma_ultra & 0x200),umodes,"*");
1207 if (id->dma_ultra & 0x400) strcat(umodes,"*"); 1407 if_strcat((id->dma_ultra & 0x002),umodes,"udma1 ");
1208 if (id->dma_ultra & 0x004) strcat(umodes,"udma2 "); 1408 if_strcat((id->dma_ultra & 0x400),umodes,"*");
1409 if_strcat((id->dma_ultra & 0x004),umodes,"udma2 ");
1209#ifdef __NEW_HD_DRIVE_ID 1410#ifdef __NEW_HD_DRIVE_ID
1210 if (id->hw_config & 0x2000) { 1411 if (id->hw_config & 0x2000)
1412 {
1211#else /* !__NEW_HD_DRIVE_ID */ 1413#else /* !__NEW_HD_DRIVE_ID */
1212 if (id->word93 & 0x2000) { 1414 if (id->word93 & 0x2000)
1415 {
1213#endif /* __NEW_HD_DRIVE_ID */ 1416#endif /* __NEW_HD_DRIVE_ID */
1214 if (id->dma_ultra & 0x0800) strcat(umodes,"*"); 1417 if_strcat((id->dma_ultra & 0x0800),umodes,"*");
1215 if (id->dma_ultra & 0x0008) strcat(umodes,"udma3 "); 1418 if_strcat((id->dma_ultra & 0x0008),umodes,"udma3 ");
1216 if (id->dma_ultra & 0x1000) strcat(umodes,"*"); 1419 if_strcat((id->dma_ultra & 0x1000),umodes,"*");
1217 if (id->dma_ultra & 0x0010) strcat(umodes,"udma4 "); 1420 if_strcat((id->dma_ultra & 0x0010),umodes,"udma4 ");
1218 if (id->dma_ultra & 0x2000) strcat(umodes,"*"); 1421 if_strcat((id->dma_ultra & 0x2000),umodes,"*");
1219 if (id->dma_ultra & 0x0020) strcat(umodes,"udma5 "); 1422 if_strcat((id->dma_ultra & 0x0020),umodes,"udma5 ");
1220 if (id->dma_ultra & 0x4000) strcat(umodes,"*"); 1423 if_strcat((id->dma_ultra & 0x4000),umodes,"*");
1221 if (id->dma_ultra & 0x0040) strcat(umodes,"udma6 "); 1424 if_strcat((id->dma_ultra & 0x0040),umodes,"udma6 ");
1222 if (id->dma_ultra & 0x8000) strcat(umodes,"*"); 1425 if_strcat((id->dma_ultra & 0x8000),umodes,"*");
1223 if (id->dma_ultra & 0x0080) strcat(umodes,"udma7 "); 1426 if_strcat((id->dma_ultra & 0x0080),umodes,"udma7 ");
1224 } 1427 }
1225 } 1428 }
1226 } 1429 }
1227 if ((id->capability&1) && (id->field_valid&2)) 1430 if_printf(((id->capability&1) && (id->field_valid&2)),
1228 printf(", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time); 1431 ", tDMA={min:%u,rec:%u}", id->eide_dma_min, id->eide_dma_time);
1229 printf("\n PIO modes: %s", pmodes); 1432 printf("\n PIO modes: %s", pmodes);
1230 if (*dmodes) 1433 if_printf((*dmodes),"\n DMA modes: %s", dmodes);
1231 printf("\n DMA modes: %s", dmodes); 1434 if_printf((*umodes),"\n UDMA modes: %s", umodes);
1232 if (*umodes) 1435
1233 printf("\n UDMA modes: %s", umodes); 1436 printf("\n AdvancedPM=%s",((id_regs[83]&8)==0)?"no":"yes");
1234 1437 if (id_regs[83] & 8)
1235 printf("\n AdvancedPM=%s",YN(id_regs[83]&8)); 1438 {
1236 if (id_regs[83] & 8) { 1439 if (!(id_regs[86]&8))
1237 if (!(id_regs[86]&8)) 1440 printf(": disabled (255)");
1238 printf(": disabled (255)"); 1441 else if ((id_regs[91]&0xFF00)!=0x4000)
1239 else if ((id_regs[91]&0xFF00)!=0x4000) 1442 printf(": unknown setting");
1240 printf(": unknown setting"); 1443 else
1241 else 1444 printf(": mode=0x%02X (%u)",id_regs[91]&0xFF,id_regs[91]&0xFF);
1242 printf(": mode=0x%02X (%u)",id_regs[91]&0xFF,id_regs[91]&0xFF); 1445 }
1243 } 1446 if_printf( (id_regs[82]&0x20)," WriteCache=%s",(id_regs[85]&0x20) ? "enabled" : "disabled");
1244 if (id_regs[82]&0x20)
1245 printf(" WriteCache=%s",(id_regs[85]&0x20) ? "enabled" : "disabled");
1246#ifdef __NEW_HD_DRIVE_ID 1447#ifdef __NEW_HD_DRIVE_ID
1247 if ((id->minor_rev_num && id->minor_rev_num <= 31) || (id->major_rev_num && id->minor_rev_num <= 31)) { 1448 if ((id->minor_rev_num && id->minor_rev_num <= 31) || (id->major_rev_num && id->minor_rev_num <= 31))
1449 {
1248 printf("\n Drive conforms to: "); 1450 printf("\n Drive conforms to: ");
1249 if (id->minor_rev_num <= 31) 1451 if_else_printf((id->minor_rev_num <= 31),"%s: ","unknown: ", minor_str[id->minor_rev_num]);
1250 printf("%s: ", minor_str[id->minor_rev_num]); 1452 if (id->major_rev_num < 31)
1251 else 1453 {
1252 printf("unknown: "); 1454 for (i=0; i <= 15; i++)
1253 if (id->major_rev_num < 31) { 1455 if_printf((id->major_rev_num & (1<<i))," %u", i);
1254 for (i=0; i <= 15; i++) {
1255 if (id->major_rev_num & (1<<i))
1256 printf(" %u", i);
1257 }
1258 } 1456 }
1259 } 1457 }
1260#endif /* __NEW_HD_DRIVE_ID */ 1458#endif /* __NEW_HD_DRIVE_ID */
1261 printf("\n"); 1459 printf("\n\n * signifies the current active mode\n\n");
1262 printf("\n * signifies the current active mode\n");
1263 printf("\n");
1264} 1460}
1265#endif 1461#endif
1266 1462
1267static void flush_buffer_cache (int fd) 1463static void flush_buffer_cache (int fd)
1268{ 1464{
1269 fsync (fd); /* flush buffers */ 1465 fsync (fd); /* flush buffers */
1270 if (ioctl(fd, BLKFLSBUF, NULL)) /* do it again, big time */ 1466 bb_ioctl(fd, BLKFLSBUF, NULL,"BLKFLSBUF" ) ;/* do it again, big time */
1271 bb_perror_msg("BLKFLSBUF failed");
1272#ifdef HDIO_DRIVE_CMD 1467#ifdef HDIO_DRIVE_CMD
1273 if (is_scsi_hd || is_xt_hd) { 1468 sleep(1);
1274 sleep(1); 1469 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) /* await completion */
1275 } else { 1470 bb_error_msg("HDIO_DRIVE_CMD");
1276 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) /* await completion */
1277 bb_perror_msg("HDIO_DRIVE_CMD(null) (wait for flush complete) failed");
1278 }
1279#endif 1471#endif
1280} 1472}
1281 1473
1282static int seek_to_zero (int fd) 1474static int seek_to_zero (int fd)
1283{ 1475{
1284 if (lseek(fd, (off_t) 0, SEEK_SET)) { 1476 if (lseek(fd, (off_t) 0, SEEK_SET))
1285 bb_perror_msg("lseek() failed");
1286 return 1; 1477 return 1;
1287 }
1288 return 0; 1478 return 0;
1289} 1479}
1290 1480
1291static int read_big_block (int fd, char *buf) 1481static int read_big_block (int fd, char *buf)
1292{ 1482{
1483
1484 const char *string;
1293 int i, rc; 1485 int i, rc;
1294 if ((rc = read(fd, buf, TIMING_BUF_BYTES)) != TIMING_BUF_BYTES) { 1486 if ((rc = read(fd, buf, TIMING_BUF_BYTES)) != TIMING_BUF_BYTES)
1295 if (rc) { 1487 {
1296 if (rc == -1) 1488 switch(rc)
1297 bb_perror_msg("read() failed"); 1489 {
1298 else 1490 case -1:
1299 bb_error_msg("read(%u) returned %u bytes", TIMING_BUF_BYTES, rc); 1491 string = "read()";
1300 } else { 1492 break;
1301 fputs ("read() hit EOF - device too small\n", stderr); 1493 case 0:
1494 string = "read() hit EOF - device too small";
1495 break;
1496 default:
1497 string = "read(%u) returned %u bytes";
1302 } 1498 }
1499 bb_error_msg(string, TIMING_BUF_BYTES, rc);
1303 return 1; 1500 return 1;
1304 } 1501 }
1502
1305 /* access all sectors of buf to ensure the read fully completed */ 1503 /* access all sectors of buf to ensure the read fully completed */
1306 for (i = 0; i < TIMING_BUF_BYTES; i += 512) 1504 for (i = 0; i < TIMING_BUF_BYTES; i += 512)
1307 buf[i] &= 1; 1505 buf[i] &= 1;
@@ -1310,176 +1508,161 @@ static int read_big_block (int fd, char *buf)
1310 1508
1311static double correction = 0.0; 1509static double correction = 0.0;
1312 1510
1313void time_cache (int fd) 1511void do_time (int flag, int fd)
1512/*
1513 flag = 0 time_cache
1514 flag = 1 time_device
1515*/
1314{ 1516{
1315 int i; 1517 int i;
1316 char *buf; 1518 char *buf;
1519 double elapsed;
1317 struct itimerval e1, e2; 1520 struct itimerval e1, e2;
1318 int shmid; 1521 int shmid;
1319 int timing_MB = TIMING_MB; 1522 int timing_MB = TIMING_MB;
1320 1523
1321 if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1) { 1524 if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1)
1322 bb_perror_msg ("could not allocate sharedmem buf"); 1525 {
1526 bb_error_msg (bb_msg_shared_mem,"allocate"); /*"could not allocate sharedmem buf"*/
1323 return; 1527 return;
1324 } 1528 }
1325 if (shmctl(shmid, SHM_LOCK, NULL) == -1) { 1529 if (shmctl(shmid, SHM_LOCK, NULL) == -1)
1326 bb_perror_msg ("could not lock sharedmem buf"); 1530 {
1531 bb_error_msg (bb_msg_shared_mem,"lock"); /*"could not lock sharedmem buf"*/
1327 (void) shmctl(shmid, IPC_RMID, NULL); 1532 (void) shmctl(shmid, IPC_RMID, NULL);
1328 return; 1533 return;
1329 } 1534 }
1330 if ((buf = shmat(shmid, (char *) 0, 0)) == (char *) -1) { 1535 if ((buf = shmat(shmid, (char *) 0, 0)) == (char *) -1)
1331 bb_perror_msg ("could not attach sharedmem buf"); 1536 {
1537 bb_error_msg (bb_msg_shared_mem,"attach"); /*"could not attach sharedmem buf"*/
1332 (void) shmctl(shmid, IPC_RMID, NULL); 1538 (void) shmctl(shmid, IPC_RMID, NULL);
1333 return; 1539 return;
1334 } 1540 }
1335 if (shmctl(shmid, IPC_RMID, NULL) == -1) 1541 if (shmctl(shmid, IPC_RMID, NULL) == -1)
1336 bb_perror_msg ("shmctl(,IPC_RMID,) failed"); 1542 bb_error_msg ("shmctl(,IPC_RMID,)");
1337
1338 /* Clear out the device request queues & give them time to complete */
1339 sync();
1340 sleep(3);
1341
1342 /* Calculate a correction factor for the basic
1343 * overhead of doing a read() from the buffer cache.
1344 * To do this, we read the data once to "cache it" and
1345 * to force full preallocation of our timing buffer,
1346 * and then we re-read it 10 times while timing it.
1347 *
1348 * getitimer() is used rather than gettimeofday() because
1349 * it is much more consistent (on my machine, at least).
1350 */
1351 setitimer(ITIMER_REAL, &(struct itimerval){{1000,0},{1000,0}}, NULL);
1352 if (seek_to_zero (fd)) return;
1353 if (read_big_block (fd, buf)) return;
1354 printf(" Timing buffer-cache reads: ");
1355 fflush(stdout);
1356 1543
1357 /* Clear out the device request queues & give them time to complete */ 1544 /* Clear out the device request queues & give them time to complete */
1358 sync(); 1545 sync_and_sleep(3);
1359 sleep(1); 1546
1360 1547 if(flag == 0) /* Time cache */
1361 /* Time re-reading from the buffer-cache */ 1548 {
1362 getitimer(ITIMER_REAL, &e1); 1549 /* Calculate a correction factor for the basic
1363 for (i = (BUFCACHE_FACTOR * TIMING_BUF_COUNT) ; i > 0; --i) { 1550 * overhead of doing a read() from the buffer cache.
1364 if (seek_to_zero (fd)) goto quit; 1551 * To do this, we read the data once to "cache it" and
1365 if (read_big_block (fd, buf)) goto quit; 1552 * to force full preallocation of our timing buffer,
1366 } 1553 * and then we re-read it 10 times while timing it.
1367 getitimer(ITIMER_REAL, &e2); 1554 *
1368 correction = (e1.it_value.tv_sec - e2.it_value.tv_sec) 1555 * getitimer() is used rather than gettimeofday() because
1369 + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); 1556 * it is much more consistent (on my machine, at least).
1370 1557 */
1371 /* Now remove the lseek() from the correction factor */ 1558 setitimer(ITIMER_REAL, &(struct itimerval){{1000,0},{1000,0}}, NULL);
1372 getitimer(ITIMER_REAL, &e1); 1559 if (seek_to_zero (fd))
1373 for (i = (BUFCACHE_FACTOR * TIMING_BUF_COUNT) ; i > 0; --i) { 1560 return;
1374 if (seek_to_zero (fd)) goto quit; 1561 if (read_big_block (fd, buf))
1375 } 1562 return;
1376 getitimer(ITIMER_REAL, &e2); 1563 printf(" Timing buffer-cache reads: ");
1377 correction -= (e1.it_value.tv_sec - e2.it_value.tv_sec) 1564 fflush(stdout);
1378 + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); 1565
1379 1566 /* Clear out the device request queues & give them time to complete */
1380 if ((BUFCACHE_FACTOR * timing_MB) >= correction) /* more than 1MB/s */ 1567 sync_and_sleep(1);
1381 printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n", 1568
1382 (BUFCACHE_FACTOR * timing_MB), correction, 1569 /* Time re-reading from the buffer-cache */
1383 (BUFCACHE_FACTOR * timing_MB) / correction); 1570 getitimer(ITIMER_REAL, &e1);
1384 else 1571 for (i = (BUFCACHE_FACTOR * TIMING_BUF_COUNT) ; i > 0; --i)
1385 printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n", 1572 {
1386 (BUFCACHE_FACTOR * timing_MB), correction, 1573 if (seek_to_zero (fd))
1387 (BUFCACHE_FACTOR * timing_MB) / correction * 1024); 1574 goto quit;
1388 correction /= BUFCACHE_FACTOR; 1575 if (read_big_block (fd, buf))
1389 1576 goto quit;
1390 flush_buffer_cache(fd); 1577 }
1391 sleep(1); 1578 getitimer(ITIMER_REAL, &e2);
1392quit: 1579 correction = (e1.it_value.tv_sec - e2.it_value.tv_sec) + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
1393 if (-1 == shmdt(buf)) 1580
1394 bb_perror_msg ("could not detach sharedmem buf"); 1581 /* Now remove the lseek() from the correction factor */
1395} 1582 getitimer(ITIMER_REAL, &e1);
1396 1583 for (i = (BUFCACHE_FACTOR * TIMING_BUF_COUNT) ; i > 0; --i)
1397void time_device (int fd) 1584 {
1398{ 1585 if (seek_to_zero (fd))
1399 int i; 1586 goto quit;
1400 char *buf; 1587 }
1401 double elapsed; 1588 getitimer(ITIMER_REAL, &e2);
1402 struct itimerval e1, e2; 1589 correction -= (e1.it_value.tv_sec - e2.it_value.tv_sec)
1403 int shmid; 1590 + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
1404 int timing_MB = TIMING_MB; 1591
1592 if ((BUFCACHE_FACTOR * timing_MB) >= correction) /* more than 1MB/s */
1593 printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n",
1594 (BUFCACHE_FACTOR * timing_MB), correction,
1595 (BUFCACHE_FACTOR * timing_MB) / correction);
1596 else
1597 printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n",
1598 (BUFCACHE_FACTOR * timing_MB), correction,
1599 (BUFCACHE_FACTOR * timing_MB) / correction * 1024);
1600 correction /= BUFCACHE_FACTOR;
1405 1601
1406 if ((shmid = shmget(IPC_PRIVATE, TIMING_BUF_BYTES, 0600)) == -1) { 1602 flush_buffer_cache(fd);
1407 bb_perror_msg ("could not allocate sharedmem buf"); 1603 sleep(1);
1408 return;
1409 }
1410 if (shmctl(shmid, SHM_LOCK, NULL) == -1) {
1411 bb_perror_msg ("could not lock sharedmem buf");
1412 (void) shmctl(shmid, IPC_RMID, NULL);
1413 return;
1414 }
1415 if ((buf = shmat(shmid, (char *) 0, 0)) == (char *) -1) {
1416 bb_perror_msg ("could not attach sharedmem buf");
1417 (void) shmctl(shmid, IPC_RMID, NULL);
1418 return;
1419 } 1604 }
1420 if (shmctl(shmid, IPC_RMID, NULL) == -1) 1605 else /* Time device */
1421 bb_perror_msg ("shmctl(,IPC_RMID,) failed"); 1606 {
1607 printf(" Timing buffered disk reads: ");
1608 fflush(stdout);
1422 1609
1423 /* Clear out the device request queues & give them time to complete */ 1610 /*
1424 sync(); 1611 * getitimer() is used rather than gettimeofday() because
1425 sleep(3); 1612 * it is much more consistent (on my machine, at least).
1613 */
1614 setitimer(ITIMER_REAL, &(struct itimerval){{1000,0},{1000,0}}, NULL);
1426 1615
1427 printf(" Timing buffered disk reads: "); 1616 /* Now do the timings for real */
1428 fflush(stdout); 1617 getitimer(ITIMER_REAL, &e1);
1618 for (i = TIMING_BUF_COUNT; i > 0; --i)
1619 {
1620 if (read_big_block (fd, buf))
1621 goto quit;
1622 }
1623 getitimer(ITIMER_REAL, &e2);
1429 1624
1430 /* 1625 elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec) + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0);
1431 * getitimer() is used rather than gettimeofday() because
1432 * it is much more consistent (on my machine, at least).
1433 */
1434 setitimer(ITIMER_REAL, &(struct itimerval){{1000,0},{1000,0}}, NULL);
1435 1626
1436 /* Now do the timings for real */ 1627 if (timing_MB >= elapsed) /* more than 1MB/s */
1437 getitimer(ITIMER_REAL, &e1); 1628 printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n",timing_MB, elapsed, timing_MB / elapsed);
1438 for (i = TIMING_BUF_COUNT; i > 0; --i) { 1629 else
1439 if (read_big_block (fd, buf)) goto quit; 1630 printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n",timing_MB, elapsed, timing_MB / elapsed * 1024);
1440 }
1441 getitimer(ITIMER_REAL, &e2);
1442 1631
1443 elapsed = (e1.it_value.tv_sec - e2.it_value.tv_sec) 1632 /*"Hmm.. suspicious results: probably not enough free memory for a proper test.");*/
1444 + ((e1.it_value.tv_usec - e2.it_value.tv_usec) / 1000000.0); 1633 if (elapsed <= (correction * 2))
1445 if (timing_MB >= elapsed) /* more than 1MB/s */ 1634 bb_error_msg(bb_msg_memory_exhausted);
1446 printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n",
1447 timing_MB, elapsed, timing_MB / elapsed);
1448 else
1449 printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n",
1450 timing_MB, elapsed, timing_MB / elapsed * 1024);
1451 1635
1452 if (elapsed <= (correction * 2))
1453 printf("Hmm.. suspicious results: probably not enough free memory for a proper test.\n");
1454#if 0 /* the "estimate" is just plain wrong for many systems.. */ 1636#if 0 /* the "estimate" is just plain wrong for many systems.. */
1455 else if (correction != 0.0) { 1637 else if (correction != 0.0) {
1456 printf(" Estimating raw driver speed: "); 1638 printf(" Estimating raw driver speed: ");
1457 elapsed -= correction; 1639 elapsed -= correction;
1458 if (timing_MB >= elapsed) /* more than 1MB/s */ 1640 if (timing_MB >= elapsed) /* more than 1MB/s */
1459 printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n", 1641 printf("%2d MB in %5.2f seconds =%6.2f MB/sec\n",
1460 timing_MB, elapsed, timing_MB / elapsed); 1642 timing_MB, elapsed, timing_MB / elapsed);
1461 else 1643 else
1462 printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n", 1644 printf("%2d MB in %5.2f seconds =%6.2f kB/sec\n",
1463 timing_MB, elapsed, timing_MB / elapsed * 1024); 1645 timing_MB, elapsed, timing_MB / elapsed * 1024);
1464 } 1646 }
1465#endif 1647#endif
1648 }
1466quit: 1649quit:
1467 if (-1 == shmdt(buf)) 1650 if (-1 == shmdt(buf))
1468 bb_perror_msg ("could not detach sharedmem buf"); 1651 bb_error_msg (bb_msg_shared_mem,"detach"); /*"could not detach sharedmem buf"*/
1469} 1652}
1470 1653
1654
1471static void no_scsi (void) 1655static void no_scsi (void)
1472{ 1656{
1473 if (is_scsi_hd) { 1657 /*" operation not supported on SCSI disks"*/
1474 bb_error_msg_and_die(" operation not supported on SCSI disks\n"); 1658 if (is_scsi_hd)
1475 } 1659 bb_error_msg_and_die(bb_msg_op_not_supp,"SCSI");
1476} 1660}
1477 1661
1478static void no_xt (void) 1662static void no_xt (void)
1479{ 1663{
1480 if (is_xt_hd) { 1664 if (is_xt_hd)
1481 bb_error_msg_and_die (" operation not supported on XT disks\n"); 1665 bb_error_msg_and_die(bb_msg_op_not_supp,"XT");
1482 }
1483} 1666}
1484 1667
1485static void on_off (unsigned int value) 1668static void on_off (unsigned int value)
@@ -1492,19 +1675,20 @@ static void bus_state_value (unsigned int value)
1492{ 1675{
1493 const char *string; 1676 const char *string;
1494 1677
1495 switch (value) { 1678 switch (value)
1496 case BUSSTATE_ON: 1679 {
1497 string = " (on)\n"; 1680 case BUSSTATE_ON:
1498 break; 1681 string = " (on)\n";
1499 case BUSSTATE_OFF: 1682 break;
1500 string = " (off)\n"; 1683 case BUSSTATE_OFF:
1501 break; 1684 string = " (off)\n";
1502 case BUSSTATE_TRISTATE: 1685 break;
1503 string = " (tristate)\n"; 1686 case BUSSTATE_TRISTATE:
1504 break; 1687 string = " (tristate)\n";
1505 default: 1688 break;
1506 string = " (unknown: %d)\n"; 1689 default:
1507 break; 1690 string = " (unknown: %d)\n";
1691 break;
1508 } 1692 }
1509 printf(string, value); 1693 printf(string, value);
1510} 1694}
@@ -1514,33 +1698,43 @@ static void bus_state_value (unsigned int value)
1514static void interpret_standby (unsigned int standby) 1698static void interpret_standby (unsigned int standby)
1515{ 1699{
1516 printf(" ("); 1700 printf(" (");
1517 switch(standby) { 1701 switch(standby)
1518 case 0: printf("off"); 1702 {
1519 break; 1703 case 0:
1520 case 252: printf("21 minutes"); 1704 printf("off");
1521 break; 1705 break;
1522 case 253: printf("vendor-specific"); 1706 case 252:
1523 break; 1707 printf("21 minutes");
1524 case 254: printf("?reserved"); 1708 break;
1525 break; 1709 case 253:
1526 case 255: printf("21 minutes + 15 seconds"); 1710 printf("vendor-specific");
1527 break; 1711 break;
1712 case 254:
1713 printf("?reserved");
1714 break;
1715 case 255:
1716 printf("21 minutes + 15 seconds");
1717 break;
1528 default: 1718 default:
1529 if (standby <= 240) { 1719 if (standby <= 240)
1720 {
1530 unsigned int secs = standby * 5; 1721 unsigned int secs = standby * 5;
1531 unsigned int mins = secs / 60; 1722 unsigned int mins = secs / 60;
1532 secs %= 60; 1723 secs %= 60;
1533 if (mins) printf("%u minutes", mins); 1724 if_printf(mins,"%u minutes", mins);
1534 if (mins && secs) printf(" + "); 1725 if_printf((mins && secs)," + ");
1535 if (secs) printf("%u seconds", secs); 1726 if_printf(secs,"%u seconds", secs);
1536 } else if (standby <= 251) { 1727 }
1728 else if (standby <= 251)
1729 {
1537 unsigned int mins = (standby - 240) * 30; 1730 unsigned int mins = (standby - 240) * 30;
1538 unsigned int hrs = mins / 60; 1731 unsigned int hrs = mins / 60;
1539 mins %= 60; 1732 mins %= 60;
1540 if (hrs) printf("%u hours", hrs); 1733 if_printf(hrs,"%u hours", hrs);
1541 if (hrs && mins) printf(" + "); 1734 if_printf((hrs && mins)," + ");
1542 if (mins) printf("%u minutes", mins); 1735 if_printf(mins,"%u minutes", mins);
1543 } else 1736 }
1737 else
1544 printf("illegal value"); 1738 printf("illegal value");
1545 break; 1739 break;
1546 } 1740 }
@@ -1590,31 +1784,35 @@ static const struct xfermode_entry xfermode_table[] = {
1590 1784
1591static int translate_xfermode(char * name) 1785static int translate_xfermode(char * name)
1592{ 1786{
1593 const struct xfermode_entry *tmp; 1787 const struct xfermode_entry *tmp;
1594 char *endptr; 1788 char *endptr;
1595 int val = -1; 1789 int val = -1;
1790
1596 1791
1792 for (tmp = xfermode_table; tmp->name != NULL; ++tmp)
1793 {
1794 if (!strcmp(name, tmp->name))
1795 return tmp->val;
1597 1796
1598 for (tmp = xfermode_table; tmp->name != NULL; ++tmp) { 1797 }
1599 if (!strcmp(name, tmp->name))
1600 return tmp->val;
1601 }
1602 1798
1603 val = strtol(name, &endptr, 10); 1799 val = strtol(name, &endptr, 10);
1604 if (*endptr == '\0') 1800 if (*endptr == '\0')
1605 return val; 1801 return val;
1606 1802
1607 return -1; 1803 return -1;
1608} 1804}
1609 1805
1610static void interpret_xfermode (unsigned int xfermode) 1806static void interpret_xfermode (unsigned int xfermode)
1611{ 1807{
1612 printf(" ("); 1808 printf(" (");
1613 switch(xfermode) { 1809 switch(xfermode) {
1614 case 0: printf("default PIO mode"); 1810 case 0:
1615 break; 1811 printf("default PIO mode");
1616 case 1: printf("default PIO mode, disable IORDY"); 1812 break;
1617 break; 1813 case 1:
1814 printf("default PIO mode, disable IORDY");
1815 break;
1618 case 8: 1816 case 8:
1619 case 9: 1817 case 9:
1620 case 10: 1818 case 10:
@@ -1622,8 +1820,9 @@ static void interpret_xfermode (unsigned int xfermode)
1622 case 12: 1820 case 12:
1623 case 13: 1821 case 13:
1624 case 14: 1822 case 14:
1625 case 15: printf("PIO flow control mode%u", xfermode-8); 1823 case 15:
1626 break; 1824 printf("PIO flow control mode%u", xfermode-8);
1825 break;
1627 case 16: 1826 case 16:
1628 case 17: 1827 case 17:
1629 case 18: 1828 case 18:
@@ -1631,8 +1830,9 @@ static void interpret_xfermode (unsigned int xfermode)
1631 case 20: 1830 case 20:
1632 case 21: 1831 case 21:
1633 case 22: 1832 case 22:
1634 case 23: printf("singleword DMA mode%u", xfermode-16); 1833 case 23:
1635 break; 1834 printf("singleword DMA mode%u", xfermode-16);
1835 break;
1636 case 32: 1836 case 32:
1637 case 33: 1837 case 33:
1638 case 34: 1838 case 34:
@@ -1640,8 +1840,9 @@ static void interpret_xfermode (unsigned int xfermode)
1640 case 36: 1840 case 36:
1641 case 37: 1841 case 37:
1642 case 38: 1842 case 38:
1643 case 39: printf("multiword DMA mode%u", xfermode-32); 1843 case 39:
1644 break; 1844 printf("multiword DMA mode%u", xfermode-32);
1845 break;
1645 case 64: 1846 case 64:
1646 case 65: 1847 case 65:
1647 case 66: 1848 case 66:
@@ -1649,11 +1850,12 @@ static void interpret_xfermode (unsigned int xfermode)
1649 case 68: 1850 case 68:
1650 case 69: 1851 case 69:
1651 case 70: 1852 case 70:
1652 case 71: printf("UltraDMA mode%u", xfermode-64); 1853 case 71:
1653 break; 1854 printf("UltraDMA mode%u", xfermode-64);
1855 break;
1654 default: 1856 default:
1655 printf("unknown, probably not valid"); 1857 printf("unknown, probably not valid");
1656 break; 1858 break;
1657 } 1859 }
1658 printf(")\n"); 1860 printf(")\n");
1659} 1861}
@@ -1678,280 +1880,260 @@ static void process_dev (char *devname)
1678 if (stat(devname,&stat_buf)) 1880 if (stat(devname,&stat_buf))
1679 bb_perror_msg_and_die(devname); 1881 bb_perror_msg_and_die(devname);
1680 1882
1681 switch(major(stat_buf.st_rdev)) { 1883 switch(major(stat_buf.st_rdev))
1884 {
1682#ifdef SCSI_DISK0_MAJOR 1885#ifdef SCSI_DISK0_MAJOR
1683 case (SCSI_DISK0_MAJOR): 1886 case (SCSI_DISK0_MAJOR):
1684 case (SCSI_DISK1_MAJOR): 1887 case (SCSI_DISK1_MAJOR):
1685 case (SCSI_DISK2_MAJOR): 1888 case (SCSI_DISK2_MAJOR):
1686 case (SCSI_DISK3_MAJOR): 1889 case (SCSI_DISK3_MAJOR):
1687 case (SCSI_DISK4_MAJOR): 1890 case (SCSI_DISK4_MAJOR):
1688 case (SCSI_DISK5_MAJOR): 1891 case (SCSI_DISK5_MAJOR):
1689 case (SCSI_DISK6_MAJOR): 1892 case (SCSI_DISK6_MAJOR):
1690 case (SCSI_DISK7_MAJOR): 1893 case (SCSI_DISK7_MAJOR):
1691#else 1894#else
1692 case (SCSI_DISK_MAJOR): 1895 case (SCSI_DISK_MAJOR):
1693#endif 1896#endif
1694#ifdef MD_MAJOR 1897#ifdef MD_MAJOR
1695 case (MD_MAJOR): 1898 case (MD_MAJOR):
1696#endif 1899#endif
1697 case (VXVM_MAJOR): 1900 case (VXVM_MAJOR):
1698#ifdef LVM_BLK_MAJOR 1901#ifdef LVM_BLK_MAJOR
1699 case (LVM_BLK_MAJOR): 1902 case (LVM_BLK_MAJOR):
1700#endif 1903#endif
1701 case (CCISS_MAJOR): 1904 case (CCISS_MAJOR):
1702 is_scsi_hd = 1; 1905 is_scsi_hd = 1;
1703 break; 1906 break;
1704#ifdef XT_DISK_MAJOR 1907#ifdef XT_DISK_MAJOR
1705 case (XT_DISK_MAJOR): 1908 case (XT_DISK_MAJOR):
1706 is_xt_hd = 1; 1909 is_xt_hd = 1;
1707 break; 1910 break;
1708#endif 1911#endif
1709 case IDE0_MAJOR: 1912 case IDE0_MAJOR:
1710 case IDE1_MAJOR: 1913 case IDE1_MAJOR:
1711#ifdef IDE2_MAJOR 1914#ifdef IDE2_MAJOR
1712 case IDE2_MAJOR: 1915 case IDE2_MAJOR:
1713#endif 1916#endif
1714#ifdef IDE3_MAJOR 1917#ifdef IDE3_MAJOR
1715 case IDE3_MAJOR: 1918 case IDE3_MAJOR:
1716#endif 1919#endif
1717#ifdef IDE4_MAJOR 1920#ifdef IDE4_MAJOR
1718 case IDE4_MAJOR: 1921 case IDE4_MAJOR:
1719#endif 1922#endif
1720#ifdef IDE5_MAJOR 1923#ifdef IDE5_MAJOR
1721 case IDE5_MAJOR: 1924 case IDE5_MAJOR:
1722#endif 1925#endif
1723#ifdef IDE6_MAJOR 1926#ifdef IDE6_MAJOR
1724 case IDE6_MAJOR: 1927 case IDE6_MAJOR:
1725#endif 1928#endif
1726#ifdef IDE7_MAJOR 1929#ifdef IDE7_MAJOR
1727 case IDE7_MAJOR: 1930 case IDE7_MAJOR:
1728#endif 1931#endif
1729#ifdef IDE8_MAJOR 1932#ifdef IDE8_MAJOR
1730 case IDE8_MAJOR: 1933 case IDE8_MAJOR:
1731#endif 1934#endif
1732#ifdef IDE9_MAJOR 1935#ifdef IDE9_MAJOR
1733 case IDE9_MAJOR: 1936 case IDE9_MAJOR:
1734#endif 1937#endif
1735 break; /* do nothing */ 1938 break; /* do nothing */
1736 default: 1939 default:
1737 bb_error_msg_and_die("%s not supported by hdparm",devname); 1940 bb_error_msg_and_die("%s not supported",devname);
1738 } 1941 }
1739 1942
1740 fd = open (devname, O_RDONLY|O_NONBLOCK); 1943 fd = bb_xopen (devname, O_RDONLY|O_NONBLOCK);
1741 if (fd < 0) 1944 if_printf( (!quiet),"\n%s:\n", devname);
1742 bb_perror_msg_and_die(devname);
1743 if (!quiet)
1744 printf("\n%s:\n", devname);
1745 1945
1746 if (set_readahead) { 1946 if (set_readahead)
1747 if (get_readahead) 1947 {
1748 printf(" setting fs readahead to %ld\n", readahead); 1948 if_printf(get_readahead," setting fs readahead to %ld\n", readahead);
1749 if (ioctl(fd, BLKRASET, readahead)) 1949 bb_ioctl(fd, BLKRASET,(int *)readahead,"BLKRASET");
1750 bb_perror_msg(" BLKRASET failed");
1751 } 1950 }
1752#ifdef CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF 1951#ifdef CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
1753 if (unregister_hwif) { 1952 if (unregister_hwif)
1953 {
1754 no_scsi(); 1954 no_scsi();
1755 printf(" attempting to unregister hwif#%u\n", hwif); 1955 printf(" attempting to unregister hwif#%u\n", hwif);
1756 if (ioctl(fd, HDIO_UNREGISTER_HWIF, hwif)) 1956 bb_ioctl(fd, HDIO_UNREGISTER_HWIF,(int *)hwif,"HDIO_UNREGISTER_HWIF");
1757 bb_perror_msg(" HDIO_UNREGISTER_HWIF failed");
1758 } 1957 }
1759#endif 1958#endif
1760#ifdef CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF 1959#ifdef CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF
1761 if (scan_hwif) { 1960 if (scan_hwif)
1961 {
1762 int args[3]; 1962 int args[3];
1763 no_scsi(); 1963 no_scsi();
1764 printf(" attempting to scan hwif (0x%x, 0x%x, %u)\n", hwif_data, hwif_ctrl, hwif_irq); 1964 printf(" attempting to scan hwif (0x%x, 0x%x, %u)\n", hwif_data, hwif_ctrl, hwif_irq);
1765 args[0] = hwif_data; 1965 args[0] = hwif_data;
1766 args[1] = hwif_ctrl; 1966 args[1] = hwif_ctrl;
1767 args[2] = hwif_irq; 1967 args[2] = hwif_irq;
1768 if (ioctl(fd, HDIO_SCAN_HWIF, args)) 1968 bb_ioctl(fd, HDIO_SCAN_HWIF, args, "HDIO_SCAN_HWIF");
1769 bb_perror_msg(" HDIO_SCAN_HWIF failed");
1770 } 1969 }
1771#endif 1970#endif
1772 if (set_piomode) { 1971 if (set_piomode)
1972 {
1773 no_scsi(); 1973 no_scsi();
1774 no_xt(); 1974 no_xt();
1775 if (noisy_piomode) { 1975
1976 if (noisy_piomode)
1977 {
1978 printf(" attempting to ");
1776 if (piomode == 255) 1979 if (piomode == 255)
1777 printf(" attempting to auto-tune PIO mode\n"); 1980 printf("auto-tune PIO mode\n");
1778 else if (piomode < 100) 1981 else if (piomode < 100)
1779 printf(" attempting to set PIO mode to %d\n", piomode); 1982 printf("set PIO mode to %d\n", piomode);
1780 else if (piomode < 200) 1983 else if (piomode < 200)
1781 printf(" attempting to set MDMA mode to %d\n", (piomode-100)); 1984 printf("set MDMA mode to %d\n", (piomode-100));
1782 else 1985 else
1783 printf(" attempting to set UDMA mode to %d\n", (piomode-200)); 1986 printf("set UDMA mode to %d\n", (piomode-200));
1784 } 1987 }
1785 if (ioctl(fd, HDIO_SET_PIO_MODE, piomode)) 1988 bb_ioctl(fd, HDIO_SET_PIO_MODE, (int *)piomode, "HDIO_SET_PIO_MODE");
1786 bb_perror_msg(" HDIO_SET_PIO_MODE failed");
1787 } 1989 }
1788 if (set_io32bit) { 1990 if (set_io32bit)
1991 {
1789 no_scsi(); 1992 no_scsi();
1790 no_xt(); 1993 no_xt();
1791 if (get_io32bit) 1994 if_printf(get_io32bit," setting 32-bit IO_support flag to %ld\n", io32bit);
1792 printf(" setting 32-bit IO_support flag to %ld\n", io32bit); 1995 bb_ioctl(fd, HDIO_SET_32BIT, (int *)io32bit, "HDIO_SET_32BIT");
1793 if (ioctl(fd, HDIO_SET_32BIT, io32bit))
1794 bb_perror_msg(" HDIO_SET_32BIT failed");
1795 } 1996 }
1796 if (set_mult) { 1997 if (set_mult)
1998 {
1797 no_scsi(); 1999 no_scsi();
1798 no_xt(); 2000 no_xt();
1799 if (get_mult) 2001 if_printf(get_mult, " setting multcount to %ld\n", mult);
1800 printf(" setting multcount to %ld\n", mult); 2002 if(ioctl(fd, HDIO_SET_MULTCOUNT, mult))
1801 if (ioctl(fd, HDIO_SET_MULTCOUNT, mult)) 2003 bb_error_msg("HDIO_SET_MULTCOUNT");
1802 bb_perror_msg(" HDIO_SET_MULTCOUNT failed");
1803#ifndef HDIO_DRIVE_CMD 2004#ifndef HDIO_DRIVE_CMD
1804 else force_operation = 1; 2005 else
2006 force_operation = 1;
1805#endif 2007#endif
1806 } 2008 }
1807 if (set_readonly) { 2009 if (set_readonly)
1808 if (get_readonly) { 2010 {
1809 printf(" setting readonly to %ld", readonly); 2011 if_printf_on_off(get_readonly," setting readonly to %ld", readonly);
1810 on_off(readonly); 2012 bb_ioctl(fd, BLKROSET, &readonly, "BLKROSET");
1811 }
1812 if (ioctl(fd, BLKROSET, &readonly))
1813 bb_perror_msg(" BLKROSET failed");
1814 } 2013 }
1815 if (set_unmask) { 2014 if (set_unmask)
2015 {
1816 no_scsi(); 2016 no_scsi();
1817 no_xt(); 2017 no_xt();
1818 if (get_unmask) { 2018 if_printf_on_off(get_unmask," setting unmaskirq to %ld", unmask);
1819 printf(" setting unmaskirq to %ld", unmask); 2019 bb_ioctl(fd, HDIO_SET_UNMASKINTR, (int *)unmask, "HDIO_SET_UNMASKINTR");
1820 on_off(unmask);
1821 }
1822 if (ioctl(fd, HDIO_SET_UNMASKINTR, unmask))
1823 bb_perror_msg(" HDIO_SET_UNMASKINTR failed");
1824 } 2020 }
1825#ifdef CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA 2021#ifdef CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA
1826 if (set_dma) { 2022 if (set_dma)
2023 {
1827 no_scsi(); 2024 no_scsi();
1828 if (get_dma) { 2025 if_printf_on_off(get_dma," setting using_dma to %ld", dma);
1829 printf(" setting using_dma to %ld", dma); 2026 bb_ioctl(fd, HDIO_SET_DMA, (int *)dma, "HDIO_SET_DMA");
1830 on_off(dma);
1831 }
1832 if (ioctl(fd, HDIO_SET_DMA, dma))
1833 bb_perror_msg(" HDIO_SET_DMA failed");
1834 } 2027 }
1835#endif /* CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA */ 2028#endif /* CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA */
1836 if (set_dma_q) { 2029 if (set_dma_q)
2030 {
1837 no_scsi(); 2031 no_scsi();
1838 if (get_dma_q) { 2032 if_printf_on_off(get_dma_q," setting DMA queue_depth to %ld", dma_q);
1839 printf(" setting DMA queue_depth to %ld", dma_q); 2033 bb_ioctl(fd, HDIO_SET_QDMA, (int *)dma_q, "HDIO_SET_QDMA");
1840 on_off(dma_q);
1841 }
1842 if (ioctl(fd, HDIO_SET_QDMA, dma_q))
1843 bb_perror_msg(" HDIO_SET_QDMA failed");
1844 } 2034 }
1845 if (set_nowerr) { 2035 if (set_nowerr)
2036 {
1846 no_scsi(); 2037 no_scsi();
1847 no_xt(); 2038 no_xt();
1848 if (get_nowerr) { 2039 if_printf_on_off(get_nowerr," setting nowerr to %ld", nowerr);
1849 printf(" setting nowerr to %ld", nowerr); 2040 bb_ioctl(fd, HDIO_SET_NOWERR, (int *)nowerr,"HDIO_SET_NOWERR");
1850 on_off(nowerr);
1851 }
1852 if (ioctl(fd, HDIO_SET_NOWERR, nowerr))
1853 bb_perror_msg(" HDIO_SET_NOWERR failed");
1854 } 2041 }
1855 if (set_keep) { 2042 if (set_keep)
2043 {
1856 no_scsi(); 2044 no_scsi();
1857 no_xt(); 2045 no_xt();
1858 if (get_keep) { 2046 if_printf_on_off(get_keep," setting keep_settings to %ld", keep);
1859 printf(" setting keep_settings to %ld", keep); 2047 bb_ioctl(fd, HDIO_SET_KEEPSETTINGS, (int *)keep,"HDIO_SET_KEEPSETTINGS");
1860 on_off(keep);
1861 }
1862 if (ioctl(fd, HDIO_SET_KEEPSETTINGS, keep))
1863 bb_perror_msg(" HDIO_SET_KEEPSETTINGS failed");
1864 } 2048 }
1865#ifdef HDIO_DRIVE_CMD 2049#ifdef HDIO_DRIVE_CMD
1866 if (set_doorlock) { 2050 if (set_doorlock)
2051 {
1867 unsigned char args[4] = {0,0,0,0}; 2052 unsigned char args[4] = {0,0,0,0};
1868 no_scsi(); 2053 no_scsi();
1869 no_xt(); 2054 no_xt();
2055
1870 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK; 2056 args[0] = doorlock ? WIN_DOORLOCK : WIN_DOORUNLOCK;
1871 if (get_doorlock) { 2057 if_printf_on_off(get_doorlock," setting drive doorlock to %ld", doorlock);
1872 printf(" setting drive doorlock to %ld", doorlock); 2058 bb_ioctl(fd, HDIO_DRIVE_CMD, &args,"HDIO_DRIVE_CMD(doorlock)");
1873 on_off(doorlock);
1874 }
1875 if (ioctl(fd, HDIO_DRIVE_CMD, &args))
1876 bb_perror_msg(" HDIO_DRIVE_CMD(doorlock) failed");
1877 } 2059 }
1878 if (set_dkeep) { 2060 if (set_dkeep)
2061 {
1879 /* lock/unlock the drive's "feature" settings */ 2062 /* lock/unlock the drive's "feature" settings */
1880 unsigned char args[4] = {WIN_SETFEATURES,0,0,0}; 2063 unsigned char args[4] = {WIN_SETFEATURES,0,0,0};
1881 no_scsi(); 2064 no_scsi();
1882 no_xt(); 2065 no_xt();
1883 if (get_dkeep) { 2066
1884 printf(" setting drive keep features to %ld", dkeep); 2067 if_printf_on_off(get_dkeep," setting drive keep features to %ld", dkeep);
1885 on_off(dkeep);
1886 }
1887 args[2] = dkeep ? 0x66 : 0xcc; 2068 args[2] = dkeep ? 0x66 : 0xcc;
1888 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) 2069 bb_ioctl(fd, HDIO_DRIVE_CMD, &args,"HDIO_DRIVE_CMD(keepsettings)");
1889 bb_perror_msg(" HDIO_DRIVE_CMD(keepsettings) failed");
1890 } 2070 }
1891 if (set_defects) { 2071 if (set_defects)
2072 {
1892 unsigned char args[4] = {WIN_SETFEATURES,0,0x04,0}; 2073 unsigned char args[4] = {WIN_SETFEATURES,0,0x04,0};
1893 no_scsi(); 2074 no_scsi();
1894 args[2] = defects ? 0x04 : 0x84; 2075 args[2] = defects ? 0x04 : 0x84;
1895 if (get_defects) 2076 if_printf(get_defects," setting drive defect-mgmt to %ld\n", defects);
1896 printf(" setting drive defect-mgmt to %ld\n", defects); 2077 bb_ioctl(fd, HDIO_DRIVE_CMD, &args,"HDIO_DRIVE_CMD(defectmgmt)");
1897 if (ioctl(fd, HDIO_DRIVE_CMD, &args))
1898 bb_perror_msg(" HDIO_DRIVE_CMD(defectmgmt) failed");
1899 } 2078 }
1900 if (set_prefetch) { 2079 if (set_prefetch)
2080 {
1901 unsigned char args[4] = {WIN_SETFEATURES,0,0xab,0}; 2081 unsigned char args[4] = {WIN_SETFEATURES,0,0xab,0};
1902 no_scsi(); 2082 no_scsi();
1903 no_xt(); 2083 no_xt();
2084
1904 args[1] = prefetch; 2085 args[1] = prefetch;
1905 if (get_prefetch) 2086 if_printf(get_prefetch," setting drive prefetch to %ld\n", prefetch);
1906 printf(" setting drive prefetch to %ld\n", prefetch); 2087 bb_ioctl(fd, HDIO_DRIVE_CMD, &args, "HDIO_DRIVE_CMD(setprefetch)");
1907 if (ioctl(fd, HDIO_DRIVE_CMD, &args))
1908 bb_perror_msg(" HDIO_DRIVE_CMD(setprefetch) failed");
1909 } 2088 }
1910 if (set_xfermode) { 2089 if (set_xfermode)
2090 {
1911 unsigned char args[4] = {WIN_SETFEATURES,0,3,0}; 2091 unsigned char args[4] = {WIN_SETFEATURES,0,3,0};
1912 no_scsi(); 2092 no_scsi();
1913 no_xt(); 2093 no_xt();
2094
1914 args[1] = xfermode_requested; 2095 args[1] = xfermode_requested;
1915 if (get_xfermode) { 2096 if (get_xfermode)
2097 {
1916 printf(" setting xfermode to %d", xfermode_requested); 2098 printf(" setting xfermode to %d", xfermode_requested);
1917 interpret_xfermode(xfermode_requested); 2099 interpret_xfermode(xfermode_requested);
1918 } 2100 }
1919 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) 2101 bb_ioctl(fd, HDIO_DRIVE_CMD, &args,"HDIO_DRIVE_CMD(setxfermode)");
1920 bb_perror_msg(" HDIO_DRIVE_CMD(setxfermode) failed");
1921 } 2102 }
1922 if (set_lookahead) { 2103 if (set_lookahead)
2104 {
1923 unsigned char args[4] = {WIN_SETFEATURES,0,0,0}; 2105 unsigned char args[4] = {WIN_SETFEATURES,0,0,0};
1924 no_scsi(); 2106 no_scsi();
1925 no_xt(); 2107 no_xt();
2108
1926 args[2] = lookahead ? 0xaa : 0x55; 2109 args[2] = lookahead ? 0xaa : 0x55;
1927 if (get_lookahead) { 2110 if_printf_on_off(get_lookahead," setting drive read-lookahead to %ld", lookahead);
1928 printf(" setting drive read-lookahead to %ld", lookahead); 2111 bb_ioctl(fd, HDIO_DRIVE_CMD, &args, "HDIO_DRIVE_CMD(setreadahead)");
1929 on_off(lookahead);
1930 }
1931 if (ioctl(fd, HDIO_DRIVE_CMD, &args))
1932 bb_perror_msg(" HDIO_DRIVE_CMD(setreadahead) failed");
1933 } 2112 }
1934 if (set_apmmode) { 2113 if (set_apmmode)
2114 {
1935 unsigned char args[4] = {WIN_SETFEATURES,0,0,0}; 2115 unsigned char args[4] = {WIN_SETFEATURES,0,0,0};
1936 no_scsi(); 2116 no_scsi();
1937 if (apmmode<1) apmmode=1; 2117 check_if_min_and_set_val(apmmode,1);
1938 if (apmmode>255) apmmode=255; 2118 check_if_maj_and_set_val(apmmode,255);
1939 if (get_apmmode) 2119 if_printf(get_apmmode," setting APM level to");
1940 printf(" setting Advanced Power Management level to"); 2120 if (apmmode==255)
1941 if (apmmode==255) { 2121 {
1942 /* disable Advanced Power Management */ 2122 /* disable Advanced Power Management */
1943 args[2] = 0x85; /* feature register */ 2123 args[2] = 0x85; /* feature register */
1944 if (get_apmmode) printf(" disabled\n"); 2124 if_printf(get_apmmode," disabled\n");
1945 } else { 2125 }
2126 else
2127 {
1946 /* set Advanced Power Management mode */ 2128 /* set Advanced Power Management mode */
1947 args[2] = 0x05; /* feature register */ 2129 args[2] = 0x05; /* feature register */
1948 args[1] = apmmode; /* sector count register */ 2130 args[1] = apmmode; /* sector count register */
1949 if (get_apmmode) printf(" 0x%02lX (%ld)\n",apmmode,apmmode); 2131 if_printf(get_apmmode," 0x%02lX (%ld)\n",apmmode,apmmode);
1950 } 2132 }
1951 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) 2133 bb_ioctl(fd, HDIO_DRIVE_CMD, &args,"HDIO_DRIVE_CMD");
1952 bb_perror_msg(" HDIO_DRIVE_CMD failed");
1953 } 2134 }
1954 if (set_wcache) { 2135 if (set_wcache)
2136 {
1955#ifdef DO_FLUSHCACHE 2137#ifdef DO_FLUSHCACHE
1956#ifndef WIN_FLUSHCACHE 2138#ifndef WIN_FLUSHCACHE
1957#define WIN_FLUSHCACHE 0xe7 2139#define WIN_FLUSHCACHE 0xe7
@@ -1962,22 +2144,19 @@ static void process_dev (char *devname)
1962 no_scsi(); 2144 no_scsi();
1963 no_xt(); 2145 no_xt();
1964 args[2] = wcache ? 0x02 : 0x82; 2146 args[2] = wcache ? 0x02 : 0x82;
1965 if (get_wcache) { 2147 if_printf_on_off(get_wcache," setting drive write-caching to %ld", wcache);
1966 printf(" setting drive write-caching to %ld", wcache);
1967 on_off(wcache);
1968 }
1969#ifdef DO_FLUSHCACHE 2148#ifdef DO_FLUSHCACHE
1970 if (!wcache && ioctl(fd, HDIO_DRIVE_CMD, &flushcache)) 2149 if (!wcache && ioctl(fd, HDIO_DRIVE_CMD, &flushcache))
1971 bb_perror_msg (" HDIO_DRIVE_CMD(flushcache) failed"); 2150 bb_error_msg ("HDIO_DRIVE_CMD(flushcache)");
1972#endif /* DO_FLUSHCACHE */ 2151#endif /* DO_FLUSHCACHE */
1973 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) 2152 bb_ioctl(fd, HDIO_DRIVE_CMD, &args, "HDIO_DRIVE_CMD(setcache)");
1974 bb_perror_msg(" HDIO_DRIVE_CMD(setcache) failed");
1975#ifdef DO_FLUSHCACHE 2153#ifdef DO_FLUSHCACHE
1976 if (!wcache && ioctl(fd, HDIO_DRIVE_CMD, &flushcache)) 2154 if (!wcache && ioctl(fd, HDIO_DRIVE_CMD, &flushcache))
1977 bb_perror_msg (" HDIO_DRIVE_CMD(flushcache) failed"); 2155 bb_error_msg ("HDIO_DRIVE_CMD(flushcache)");
1978#endif /* DO_FLUSHCACHE */ 2156#endif /* DO_FLUSHCACHE */
1979 } 2157 }
1980 if (set_standbynow) { 2158 if (set_standbynow)
2159 {
1981#ifndef WIN_STANDBYNOW1 2160#ifndef WIN_STANDBYNOW1
1982#define WIN_STANDBYNOW1 0xE0 2161#define WIN_STANDBYNOW1 0xE0
1983#endif 2162#endif
@@ -1987,13 +2166,13 @@ static void process_dev (char *devname)
1987 unsigned char args1[4] = {WIN_STANDBYNOW1,0,0,0}; 2166 unsigned char args1[4] = {WIN_STANDBYNOW1,0,0,0};
1988 unsigned char args2[4] = {WIN_STANDBYNOW2,0,0,0}; 2167 unsigned char args2[4] = {WIN_STANDBYNOW2,0,0,0};
1989 no_scsi(); 2168 no_scsi();
1990 if (get_standbynow) 2169 if_printf(get_standbynow," issuing standby command\n");
1991 printf(" issuing standby command\n");
1992 if (ioctl(fd, HDIO_DRIVE_CMD, &args1) 2170 if (ioctl(fd, HDIO_DRIVE_CMD, &args1)
1993 && ioctl(fd, HDIO_DRIVE_CMD, &args2)) 2171 && ioctl(fd, HDIO_DRIVE_CMD, &args2))
1994 bb_perror_msg(" HDIO_DRIVE_CMD(standby) failed"); 2172 bb_error_msg("HDIO_DRIVE_CMD(standby)");
1995 } 2173 }
1996 if (set_sleepnow) { 2174 if (set_sleepnow)
2175 {
1997#ifndef WIN_SLEEPNOW1 2176#ifndef WIN_SLEEPNOW1
1998#define WIN_SLEEPNOW1 0xE6 2177#define WIN_SLEEPNOW1 0xE6
1999#endif 2178#endif
@@ -2003,93 +2182,106 @@ static void process_dev (char *devname)
2003 unsigned char args1[4] = {WIN_SLEEPNOW1,0,0,0}; 2182 unsigned char args1[4] = {WIN_SLEEPNOW1,0,0,0};
2004 unsigned char args2[4] = {WIN_SLEEPNOW2,0,0,0}; 2183 unsigned char args2[4] = {WIN_SLEEPNOW2,0,0,0};
2005 no_scsi(); 2184 no_scsi();
2006 if (get_sleepnow) 2185 if_printf(get_sleepnow," issuing sleep command\n");
2007 printf(" issuing sleep command\n");
2008 if (ioctl(fd, HDIO_DRIVE_CMD, &args1) 2186 if (ioctl(fd, HDIO_DRIVE_CMD, &args1)
2009 && ioctl(fd, HDIO_DRIVE_CMD, &args2)) 2187 && ioctl(fd, HDIO_DRIVE_CMD, &args2))
2010 bb_perror_msg(" HDIO_DRIVE_CMD(sleep) failed"); 2188 bb_error_msg("HDIO_DRIVE_CMD(sleep)");
2011 } 2189 }
2012 if (set_seagate) { 2190 if (set_seagate)
2191 {
2013 unsigned char args[4] = {0xfb,0,0,0}; 2192 unsigned char args[4] = {0xfb,0,0,0};
2014 no_scsi(); 2193 no_scsi();
2015 no_xt(); 2194 no_xt();
2016 if (get_seagate) 2195 if_printf(get_seagate," disabling Seagate auto powersaving mode\n");
2017 printf(" disabling Seagate auto powersaving mode\n"); 2196 bb_ioctl(fd, HDIO_DRIVE_CMD, &args, "HDIO_DRIVE_CMD(seagatepwrsave)");
2018 if (ioctl(fd, HDIO_DRIVE_CMD, &args))
2019 bb_perror_msg(" HDIO_DRIVE_CMD(seagatepwrsave) failed");
2020 } 2197 }
2021 if (set_standby) { 2198 if (set_standby)
2199 {
2022 unsigned char args[4] = {WIN_SETIDLE1,standby_requested,0,0}; 2200 unsigned char args[4] = {WIN_SETIDLE1,standby_requested,0,0};
2023 no_scsi(); 2201 no_scsi();
2024 no_xt(); 2202 no_xt();
2025 if (get_standby) { 2203 if (get_standby)
2204 {
2026 printf(" setting standby to %lu", standby_requested); 2205 printf(" setting standby to %lu", standby_requested);
2027 interpret_standby(standby_requested); 2206 interpret_standby(standby_requested);
2028 } 2207 }
2029 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) 2208 bb_ioctl(fd, HDIO_DRIVE_CMD, &args, "HDIO_DRIVE_CMD(setidle1)");
2030 bb_perror_msg(" HDIO_DRIVE_CMD(setidle1) failed");
2031 } 2209 }
2032#else /* HDIO_DRIVE_CMD */ 2210#else /* HDIO_DRIVE_CMD */
2033 if (force_operation) { 2211 if (force_operation)
2212 {
2034 char buf[512]; 2213 char buf[512];
2035 flush_buffer_cache(fd); 2214 flush_buffer_cache(fd);
2036 if (-1 == read(fd, buf, sizeof(buf))) 2215 if (-1 == read(fd, buf, sizeof(buf)))
2037 bb_perror_msg(" access failed"); 2216 bb_error_msg("access failed");
2038 } 2217 }
2039#endif /* HDIO_DRIVE_CMD */ 2218#endif /* HDIO_DRIVE_CMD */
2040 2219
2041 if (!flagcount) 2220 if (!flagcount)
2042 verbose = 1; 2221 verbose = 1;
2043 2222
2044 if ((verbose && !is_scsi_hd && !is_xt_hd) || get_mult || get_identity) { 2223 if ((verbose && !is_scsi_hd && !is_xt_hd) || get_mult || get_identity)
2224 {
2045 no_scsi(); 2225 no_scsi();
2046 multcount = -1; 2226 multcount = -1;
2047 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) { 2227 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount))
2228 {
2048 if ((verbose && !is_xt_hd) || get_mult) 2229 if ((verbose && !is_xt_hd) || get_mult)
2049 bb_perror_msg(" HDIO_GET_MULTCOUNT failed"); 2230 bb_error_msg("HDIO_GET_MULTCOUNT");
2050 } else if (verbose | get_mult) { 2231 }
2232 else if (verbose | get_mult)
2233 {
2051 printf(" multcount = %2ld", multcount); 2234 printf(" multcount = %2ld", multcount);
2052 on_off(multcount); 2235 on_off(multcount);
2053 } 2236 }
2054 } 2237 }
2055 if ((verbose && !is_scsi_hd && !is_xt_hd) || get_io32bit) { 2238 if ((verbose && !is_scsi_hd && !is_xt_hd) || get_io32bit)
2239 {
2056 no_scsi(); 2240 no_scsi();
2057 no_xt(); 2241 no_xt();
2058 if (ioctl(fd, HDIO_GET_32BIT, &parm)) 2242 if(ioctl(fd, HDIO_GET_32BIT, &parm))
2059 bb_perror_msg(" HDIO_GET_32BIT failed"); 2243 bb_error_msg("HDIO_GET_32BIT");
2060 else { 2244 else
2245 {
2061 printf(" IO_support =%3ld (", parm); 2246 printf(" IO_support =%3ld (", parm);
2062 switch (parm) { 2247 switch (parm)
2063 case 0: printf("default "); 2248 {
2064 case 2: printf("16-bit)\n"); 2249 case 0:
2250 printf("default ");
2251 case 2:
2252 printf("16-bit)\n");
2065 break; 2253 break;
2066 case 1: printf("32-bit)\n"); 2254 case 1:
2255 printf("32-bit)\n");
2067 break; 2256 break;
2068 case 3: printf("32-bit w/sync)\n"); 2257 case 3:
2258 printf("32-bit w/sync)\n");
2069 break; 2259 break;
2070 case 8: printf("Request-Queue-Bypass)\n"); 2260 case 8:
2261 printf("Request-Queue-Bypass)\n");
2071 break; 2262 break;
2072 default:printf("\?\?\?)\n"); 2263 default:
2264 printf("\?\?\?)\n");
2265 /*esac*/
2073 } 2266 }
2074 } 2267 }
2075 } 2268 }
2076 if ((verbose && !is_scsi_hd && !is_xt_hd) || get_unmask) { 2269 if ((verbose && !is_scsi_hd && !is_xt_hd) || get_unmask)
2270 {
2077 no_scsi(); 2271 no_scsi();
2078 no_xt(); 2272 no_xt();
2079 if (ioctl(fd, HDIO_GET_UNMASKINTR, &parm)) 2273 bb_ioctl_on_off(fd, HDIO_GET_UNMASKINTR,(unsigned long *)parm,
2080 bb_perror_msg(" HDIO_GET_UNMASKINTR failed"); 2274 "HDIO_GET_UNMASKINTR"," unmaskirq = %2ld");
2081 else {
2082 printf(" unmaskirq = %2ld", parm);
2083 on_off(parm);
2084 }
2085 } 2275 }
2086 2276
2277
2087#ifdef CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA 2278#ifdef CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA
2088 if ((verbose && !is_scsi_hd) || get_dma) { 2279 if ((verbose && !is_scsi_hd) || get_dma) {
2089 no_scsi(); 2280 no_scsi();
2090 if (ioctl(fd, HDIO_GET_DMA, &parm)) 2281 if(ioctl(fd, HDIO_GET_DMA, &parm))
2091 bb_perror_msg(" HDIO_GET_DMA failed"); 2282 bb_error_msg("HDIO_GET_DMA");
2092 else { 2283 else
2284 {
2093 printf(" using_dma = %2ld", parm); 2285 printf(" using_dma = %2ld", parm);
2094 if (parm == 8) 2286 if (parm == 8)
2095 printf(" (DMA-Assisted-PIO)\n"); 2287 printf(" (DMA-Assisted-PIO)\n");
@@ -2098,53 +2290,39 @@ static void process_dev (char *devname)
2098 } 2290 }
2099 } 2291 }
2100#endif 2292#endif
2101 if (get_dma_q) { 2293 if (get_dma_q)
2294 {
2102 no_scsi(); 2295 no_scsi();
2103 if(ioctl(fd, HDIO_GET_QDMA, &parm)) { 2296 bb_ioctl_on_off (fd, HDIO_GET_QDMA,(unsigned long *)parm,
2104 bb_perror_msg(" HDIO_GET_QDMA failed"); 2297 "HDIO_GET_QDMA"," queue_depth = %2ld");
2105 } else {
2106 printf(" queue_depth = %2ld", parm);
2107 on_off(parm);
2108 }
2109 } 2298 }
2110 if ((verbose && !is_scsi_hd && !is_xt_hd) || get_keep) { 2299 if ((verbose && !is_scsi_hd && !is_xt_hd) || get_keep)
2300 {
2111 no_scsi(); 2301 no_scsi();
2112 no_xt(); 2302 no_xt();
2113 if (ioctl(fd, HDIO_GET_KEEPSETTINGS, &parm)) 2303 bb_ioctl_on_off (fd, HDIO_GET_KEEPSETTINGS,(unsigned long *)parm,
2114 bb_perror_msg(" HDIO_GET_KEEPSETTINGS failed"); 2304 "HDIO_GET_KEEPSETTINGS"," keepsettings = %2ld");
2115 else {
2116 printf(" keepsettings = %2ld", parm);
2117 on_off(parm);
2118 }
2119 } 2305 }
2120 2306
2121 if (get_nowerr) { 2307 if (get_nowerr)
2308 {
2122 no_scsi(); 2309 no_scsi();
2123 no_xt(); 2310 no_xt();
2124 if (ioctl(fd, HDIO_GET_NOWERR, &parm)) 2311 bb_ioctl_on_off (fd, HDIO_GET_NOWERR,(unsigned long *)&parm,
2125 bb_perror_msg(" HDIO_GET_NOWERR failed"); 2312 " HDIO_GET_NOWERR"," nowerr = %2ld");
2126 else {
2127 printf(" nowerr = %2ld", parm);
2128 on_off(parm);
2129 }
2130 } 2313 }
2131 if (verbose || get_readonly) { 2314 if (verbose || get_readonly)
2132 if (ioctl(fd, BLKROGET, &parm)) 2315 {
2133 bb_perror_msg(" BLKROGET failed"); 2316 bb_ioctl_on_off(fd, BLKROGET,(unsigned long *)parm,
2134 else { 2317 " BLKROGET"," readonly = %2ld");
2135 printf(" readonly = %2ld", parm);
2136 on_off(parm);
2137 }
2138 } 2318 }
2139 if ((verbose && !is_scsi_hd) || get_readahead) { 2319 if ((verbose && !is_scsi_hd) || get_readahead)
2140 if (ioctl(fd, BLKRAGET, &parm)) 2320 {
2141 bb_perror_msg(" BLKRAGET failed"); 2321 bb_ioctl_on_off (fd, BLKRAGET, (unsigned long *) parm,
2142 else { 2322 " BLKRAGET"," readahead = %2ld");
2143 printf(" readahead = %2ld", parm);
2144 on_off(parm);
2145 }
2146 } 2323 }
2147 if (verbose || get_geom) { 2324 if (verbose || get_geom)
2325 {
2148 static const char msg[] = " geometry = %u/%u/%u, sectors = %ld, start = %ld\n"; 2326 static const char msg[] = " geometry = %u/%u/%u, sectors = %ld, start = %ld\n";
2149 static struct hd_geometry g; 2327 static struct hd_geometry g;
2150#ifdef HDIO_GETGEO_BIG 2328#ifdef HDIO_GETGEO_BIG
@@ -2152,17 +2330,19 @@ static void process_dev (char *devname)
2152#endif 2330#endif
2153 2331
2154 if (ioctl(fd, BLKGETSIZE, &parm)) 2332 if (ioctl(fd, BLKGETSIZE, &parm))
2155 bb_perror_msg(" BLKGETSIZE failed"); 2333 bb_error_msg("BLKGETSIZE");
2156#ifdef HDIO_GETGEO_BIG 2334#ifdef HDIO_GETGEO_BIG
2157 else if (!ioctl(fd, HDIO_GETGEO_BIG, &bg)) 2335 else if (!ioctl(fd, HDIO_GETGEO_BIG, &bg))
2158 printf(msg, bg.cylinders, bg.heads, bg.sectors, parm, bg.start); 2336 printf(msg, bg.cylinders, bg.heads, bg.sectors, parm, bg.start);
2159#endif 2337#endif
2160 else if (ioctl(fd, HDIO_GETGEO, &g)) 2338 else if (ioctl(fd, HDIO_GETGEO, &g))
2161 bb_perror_msg(" HDIO_GETGEO failed"); 2339 bb_error_msg("HDIO_GETGEO");
2162 else printf(msg, g.cylinders, g.heads, g.sectors, parm, g.start); 2340 else
2341 printf(msg, g.cylinders, g.heads, g.sectors, parm, g.start);
2163 } 2342 }
2164#ifdef HDIO_DRIVE_CMD 2343#ifdef HDIO_DRIVE_CMD
2165 if (get_powermode) { 2344 if (get_powermode)
2345 {
2166#ifndef WIN_CHECKPOWERMODE1 2346#ifndef WIN_CHECKPOWERMODE1
2167#define WIN_CHECKPOWERMODE1 0xE5 2347#define WIN_CHECKPOWERMODE1 0xE5
2168#endif 2348#endif
@@ -2173,133 +2353,125 @@ static void process_dev (char *devname)
2173 const char *state; 2353 const char *state;
2174 no_scsi(); 2354 no_scsi();
2175 if (ioctl(fd, HDIO_DRIVE_CMD, &args) 2355 if (ioctl(fd, HDIO_DRIVE_CMD, &args)
2176 && (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */ 2356 && (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */
2177 && ioctl(fd, HDIO_DRIVE_CMD, &args)) { 2357 && ioctl(fd, HDIO_DRIVE_CMD, &args))
2358 {
2178 if (errno != EIO || args[0] != 0 || args[1] != 0) 2359 if (errno != EIO || args[0] != 0 || args[1] != 0)
2179 state = "unknown"; 2360 state = "unknown";
2180 else 2361 else
2181 state = "sleeping"; 2362 state = "sleeping";
2182 } else {
2183 state = (args[2] == 255) ? "active/idle" : "standby";
2184 } 2363 }
2364 else
2365 state = (args[2] == 255) ? "active/idle" : "standby";
2366
2185 printf(" drive state is: %s\n", state); 2367 printf(" drive state is: %s\n", state);
2186 } 2368 }
2187#endif 2369#endif
2188#ifdef CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET 2370#ifdef CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET
2189 if (perform_reset) { 2371 if (perform_reset)
2372 {
2190 no_scsi(); 2373 no_scsi();
2191 no_xt(); 2374 no_xt();
2192 if (ioctl(fd, HDIO_DRIVE_RESET, NULL)) 2375 bb_ioctl(fd, HDIO_DRIVE_RESET, NULL, "HDIO_DRIVE_RESET");
2193 bb_perror_msg(" HDIO_DRIVE_RESET failed");
2194 } 2376 }
2195#endif /* CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET */ 2377#endif /* CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET */
2196#ifdef CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF 2378#ifdef CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
2197 if (perform_tristate) { 2379 if (perform_tristate)
2380 {
2198 unsigned char args[4] = {0,tristate,0,0}; 2381 unsigned char args[4] = {0,tristate,0,0};
2199 no_scsi(); 2382 no_scsi();
2200 no_xt(); 2383 no_xt();
2201 if (ioctl(fd, HDIO_TRISTATE_HWIF, &args)) 2384 bb_ioctl(fd, HDIO_TRISTATE_HWIF, &args, "HDIO_TRISTATE_HWIF");
2202 bb_perror_msg(" HDIO_TRISTATE_HWIF failed");
2203 } 2385 }
2204#endif /* CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF */ 2386#endif /* CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
2205#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY 2387#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY
2206 if (get_identity) { 2388 if (get_identity)
2389 {
2207 static struct hd_driveid id; 2390 static struct hd_driveid id;
2208 2391
2209 no_scsi(); 2392 no_scsi();
2210 no_xt(); 2393 no_xt();
2211 2394
2212 if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) { 2395 if (!ioctl(fd, HDIO_GET_IDENTITY, &id))
2213 if (multcount != -1) { 2396 {
2397 if (multcount != -1)
2398 {
2214 id.multsect = multcount; 2399 id.multsect = multcount;
2215 id.multsect_valid |= 1; 2400 id.multsect_valid |= 1;
2216 } else 2401 }
2402 else
2217 id.multsect_valid &= ~1; 2403 id.multsect_valid &= ~1;
2218 dump_identity(&id); 2404 dump_identity(&id);
2219 } else if (errno == -ENOMSG) 2405 }
2406 else if (errno == -ENOMSG)
2220 printf(" no identification info available\n"); 2407 printf(" no identification info available\n");
2221 else 2408 else
2222 bb_perror_msg(" HDIO_GET_IDENTITY failed"); 2409 bb_error_msg("HDIO_GET_IDENTITY");
2223 } 2410 }
2224 if (get_IDentity) { 2411
2412 if (get_IDentity)
2413 {
2225 unsigned char args[4+512] = {WIN_IDENTIFY,0,0,1,}; 2414 unsigned char args[4+512] = {WIN_IDENTIFY,0,0,1,};
2226 unsigned i; 2415 unsigned i;
2416
2227 no_scsi(); 2417 no_scsi();
2228 no_xt(); 2418 no_xt();
2229 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 2419
2420 if (ioctl(fd, HDIO_DRIVE_CMD, &args))
2421 {
2230 args[0] = WIN_PIDENTIFY; 2422 args[0] = WIN_PIDENTIFY;
2231 if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { 2423 if (ioctl(fd, HDIO_DRIVE_CMD, &args))
2232 bb_perror_msg(" HDIO_DRIVE_CMD(identify) failed"); 2424 {
2425 bb_error_msg("HDIO_DRIVE_CMD(identify)");
2233 goto identify_abort; 2426 goto identify_abort;
2234 } 2427 }
2235 } 2428 }
2236 for(i=0; i<(sizeof args)/2; i+=2) { 2429 for(i=0; i<(sizeof args)/2; i+=2)
2237 __le16_to_cpus((uint16_t *)(&args[i])); 2430 __le16_to_cpus((uint16_t *)(&args[i]));
2238 } 2431
2239 identify((void *)&args[4], NULL); 2432 identify((void *)&args[4], NULL);
2240identify_abort: ; 2433identify_abort:
2434 /* VOID */;
2241 } 2435 }
2242#endif 2436#endif
2243#ifdef CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF 2437#ifdef CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
2244 if (set_busstate) { 2438 if (set_busstate)
2439 {
2245 no_scsi(); 2440 no_scsi();
2246 if (get_busstate) { 2441 if (get_busstate)
2442 {
2247 printf(" setting bus state to %d", busstate); 2443 printf(" setting bus state to %d", busstate);
2248 bus_state_value(busstate); 2444 bus_state_value(busstate);
2249 } 2445 }
2250 if (ioctl(fd, HDIO_SET_BUSSTATE, busstate)) 2446 bb_ioctl(fd, HDIO_SET_BUSSTATE, (int *)busstate, "HDIO_SET_BUSSTATE");
2251 bb_perror_msg(" HDIO_SET_BUSSTATE failed");
2252 } 2447 }
2253#endif 2448#endif
2254#ifdef CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF 2449#ifdef CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
2255 if (get_busstate) { 2450 if (get_busstate)
2451 {
2256 no_scsi(); 2452 no_scsi();
2257 if (ioctl(fd, HDIO_GET_BUSSTATE, &parm)) 2453 if (ioctl(fd, HDIO_GET_BUSSTATE, &parm))
2258 bb_perror_msg(" HDIO_GET_BUSSTATE failed"); 2454 bb_error_msg("HDIO_GET_BUSSTATE");
2259 else { 2455 else
2456 {
2260 printf(" busstate = %2ld", parm); 2457 printf(" busstate = %2ld", parm);
2261 bus_state_value(parm); 2458 bus_state_value(parm);
2262 } 2459 }
2263 } 2460 }
2264#endif 2461#endif
2265 if (reread_partn) { 2462 if (reread_partn)
2266 if (ioctl(fd, BLKRRPART, NULL)) { 2463 bb_ioctl(fd, BLKRRPART, NULL, "BLKRRPART");
2267 bb_perror_msg(" BLKRRPART failed"); 2464
2268 }
2269 }
2270 2465
2271 if (do_ctimings) 2466 if (do_ctimings)
2272 time_cache (fd); 2467 do_time(0,fd); /*time cache */
2273 if (do_timings) 2468 if (do_timings)
2274 time_device (fd); 2469 do_time(1,fd); /*time device */
2275 if (do_flush) 2470 if (do_flush)
2276 flush_buffer_cache (fd); 2471 flush_buffer_cache (fd);
2277 close (fd); 2472 close (fd);
2278} 2473}
2279 2474
2280#define GET_NUMBER(flag,num) num = 0; \
2281 if (!*p && argc && isdigit(**argv)) \
2282 p = *argv++, --argc; \
2283 while (isdigit(*p)) { \
2284 flag = 1; \
2285 num = (num * 10) + (*p++ - '0'); \
2286 }
2287
2288#define GET_STRING(flag, num) tmpstr = name; \
2289 tmpstr[0] = '\0'; \
2290 if (!*p && argc && isalnum(**argv)) \
2291 p = *argv++, --argc; \
2292 while (isalnum(*p) && (tmpstr - name) < 31) { \
2293 tmpstr[0] = *p++; \
2294 tmpstr[1] = '\0'; \
2295 ++tmpstr; \
2296 } \
2297 num = translate_xfermode(name); \
2298 if (num == -1) \
2299 flag = 0; \
2300 else \
2301 flag = 1;
2302
2303#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY 2475#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY
2304static int fromhex (unsigned char c) 2476static int fromhex (unsigned char c)
2305{ 2477{
@@ -2318,7 +2490,8 @@ static int identify_from_stdin (void)
2318 2490
2319 if (count != 1280) 2491 if (count != 1280)
2320 bb_error_msg_and_die("read(1280 bytes) failed (rc=%d)", count); 2492 bb_error_msg_and_die("read(1280 bytes) failed (rc=%d)", count);
2321 for (i = 0; count >= 4; ++i) { 2493 for (i = 0; count >= 4; ++i)
2494 {
2322 sbuf[i] = (fromhex(b[0]) << 12) | (fromhex(b[1]) << 8) | (fromhex(b[2]) << 4) | fromhex(b[3]); 2495 sbuf[i] = (fromhex(b[0]) << 12) | (fromhex(b[1]) << 8) | (fromhex(b[2]) << 4) | fromhex(b[3]);
2323 __le16_to_cpus((uint16_t *)(&sbuf[i])); 2496 __le16_to_cpus((uint16_t *)(&sbuf[i]));
2324 b += 5; 2497 b += 5;
@@ -2332,29 +2505,39 @@ static int identify_from_stdin (void)
2332/* our main() routine: */ 2505/* our main() routine: */
2333int hdparm_main(int argc, char **argv) 2506int hdparm_main(int argc, char **argv)
2334{ 2507{
2508 const char * const bb_msg_missing_value ="missing value";
2335 char c, *p; 2509 char c, *p;
2336 char *tmpstr; 2510 char *tmpstr;
2337 char name[32]; 2511 char name[32];
2338 int neg; 2512 /*int neg;*/
2339 2513
2340 ++argv; 2514 ++argv;
2341 if (!--argc) 2515 if (!--argc)
2342 bb_show_usage(); 2516 bb_show_usage();
2343 while (argc--) { 2517
2518 while (argc--)
2519 {
2344#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY 2520#ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY
2345 if (!strcmp("-Istdin", *argv)) { 2521 if (!strcmp("-Istdin", *argv))
2522 {
2346 exit(identify_from_stdin()); 2523 exit(identify_from_stdin());
2347 } 2524 }
2348#endif 2525#endif
2349 p = *argv++; 2526 p = *argv++;
2350 if (*p == '-') { 2527 if (*p == '-')
2528 {
2351 if (!*++p) 2529 if (!*++p)
2352 bb_show_usage(); 2530 bb_show_usage();
2353 while ((c = *p++)) { 2531 while ((c = *p++))
2532 {
2354 ++flagcount; 2533 ++flagcount;
2355 switch (c) { 2534 switch (c)
2535 {
2356 case 'V': 2536 case 'V':
2357 bb_error_msg_and_die("%s", VERSION); 2537 /*bb_error_msg_and_die("%s", VERSION);*/
2538 /* We have to return 0 here and not 1 */
2539 printf("%s %s\n",bb_applet_name, VERSION);
2540 exit(EXIT_SUCCESS);
2358 case 'v': 2541 case 'v':
2359 verbose = 1; 2542 verbose = 1;
2360 break; 2543 break;
@@ -2379,138 +2562,169 @@ int hdparm_main(int argc, char **argv)
2379 case 'u': 2562 case 'u':
2380 get_unmask = noisy; 2563 get_unmask = noisy;
2381 noisy = 1; 2564 noisy = 1;
2382 if (!*p && argc && isdigit(**argv)) 2565 p = check_ptr(p,argc,argv);
2383 p = *argv++, --argc; 2566 if((set_unmask = set_flag(p,'1'))==1)
2384 if (*p == '0' || *p == '1') { 2567 unmask = *p++ - '0';
2385 set_unmask = 1;
2386 unmask = *p++ - '0';
2387 }
2388 break; 2568 break;
2389#ifdef CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA 2569#ifdef CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA
2390 case 'd': 2570 case 'd':
2391 get_dma = noisy; 2571 get_dma = noisy;
2392 noisy = 1; 2572 noisy = 1;
2393 if (!*p && argc && isdigit(**argv)) 2573 p = check_ptr(p,argc,argv);
2394 p = *argv++, --argc; 2574 if((set_dma = set_flag(p,'9'))==1)
2395 if (*p >= '0' && *p <= '9') {
2396 set_dma = 1;
2397 dma = *p++ - '0'; 2575 dma = *p++ - '0';
2398 }
2399 break; 2576 break;
2400#endif /* CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA */ 2577#endif /* CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA */
2401 case 'n': 2578 case 'n':
2402 get_nowerr = noisy; 2579 get_nowerr = noisy;
2403 noisy = 1; 2580 noisy = 1;
2404 if (!*p && argc && isdigit(**argv)) 2581 p = check_ptr(p,argc,argv);
2405 p = *argv++, --argc; 2582 if((set_nowerr = set_flag(p,'1'))==1)
2406 if (*p == '0' || *p == '1') { 2583 nowerr = *p++ - '0';
2407 set_nowerr = 1;
2408 nowerr = *p++ - '0';
2409 }
2410 break; 2584 break;
2411 case 'p': 2585 case 'p':
2412 noisy_piomode = noisy; 2586 noisy_piomode = noisy;
2413 noisy = 1; 2587 noisy = 1;
2414 GET_STRING(set_piomode,piomode); 2588 p = check_ptr_v2(p,argc,argv);
2589 tmpstr = name;
2590 tmpstr[0] = '\0';
2591 while (isalnum(*p) && (tmpstr - name) < 31)
2592 {
2593 tmpstr[0] = *p++;
2594 tmpstr[1] = '\0';
2595 ++tmpstr;
2596 }
2597 piomode = translate_xfermode(name);
2598 if (piomode == -1)
2599 set_piomode = 0;
2600 else
2601 set_piomode = 1;
2415 break; 2602 break;
2416 case 'r': 2603 case 'r':
2417 get_readonly = noisy; 2604 get_readonly = noisy;
2418 noisy = 1; 2605 noisy = 1;
2419 if (!*p && argc && isdigit(**argv)) 2606 p = check_ptr(p,argc,argv);
2420 p = *argv++, --argc; 2607 if((set_readonly = set_flag(p,'1'))==1)
2421 if (*p == '0' || *p == '1') { 2608 readonly = *p++ - '0';
2422 set_readonly = 1;
2423 readonly = *p++ - '0';
2424 }
2425 break; 2609 break;
2426 case 'm': 2610 case 'm':
2427 get_mult = noisy; 2611 get_mult = noisy;
2428 noisy = 1; 2612 noisy = 1;
2429 GET_NUMBER(set_mult,mult); 2613 p = check_ptr(p,argc,argv);
2614 while (isdigit(*p))
2615 {
2616 set_mult = 1;
2617 mult = (mult * 10) + (*p++ - '0');
2618 }
2430 break; 2619 break;
2431 case 'c': 2620 case 'c':
2432 get_io32bit = noisy; 2621 get_io32bit = noisy;
2433 noisy = 1; 2622 noisy = 1;
2434 GET_NUMBER(set_io32bit,io32bit); 2623 p = check_ptr(p,argc,argv);
2624 while (isdigit(*p))
2625 {
2626 set_io32bit = 1;
2627 io32bit = (io32bit * 10) + (*p++ - '0');
2628 }
2435 break; 2629 break;
2436#ifdef HDIO_DRIVE_CMD 2630#ifdef HDIO_DRIVE_CMD
2437 case 'S': 2631 case 'S':
2438 get_standby = noisy; 2632 get_standby = noisy;
2439 noisy = 1; 2633 noisy = 1;
2440 GET_NUMBER(set_standby,standby_requested); 2634 p = check_ptr(p,argc,argv);
2635 while (isdigit(*p))
2636 {
2637 set_standby = 1;
2638 standby_requested = (standby_requested * 10) + (*p++ - '0');
2639 }
2441 if (!set_standby) 2640 if (!set_standby)
2442 bb_error_msg("-S: missing value"); 2641 bb_error_msg("-S: %s", bb_msg_missing_value);
2443 break; 2642 break;
2444 2643
2445 case 'D': 2644 case 'D':
2446 get_defects = noisy; 2645 get_defects = noisy;
2447 noisy = 1; 2646 noisy = 1;
2448 GET_NUMBER(set_defects,defects); 2647 p = check_ptr(p,argc,argv);
2648 while (isdigit(*p))
2649 {
2650 set_defects = 1;
2651 defects = (defects * 10) + (*p++ - '0');
2652 }
2449 if (!set_defects) 2653 if (!set_defects)
2450 bb_error_msg("-D: missing value"); 2654 bb_error_msg("-D: %s", bb_msg_missing_value);
2451 break; 2655 break;
2452 case 'P': 2656 case 'P':
2453 get_prefetch = noisy; 2657 get_prefetch = noisy;
2454 noisy = 1; 2658 noisy = 1;
2455 GET_NUMBER(set_prefetch,prefetch); 2659 p = check_ptr(p,argc,argv);
2660 while (isdigit(*p))
2661 {
2662 set_prefetch = 1;
2663 prefetch = (prefetch * 10) + (*p++ - '0');
2664 }
2456 if (!set_prefetch) 2665 if (!set_prefetch)
2457 bb_error_msg("-P: missing value"); 2666 bb_error_msg("-P: %s", bb_msg_missing_value);
2458 break; 2667 break;
2459 2668
2460 case 'X': 2669 case 'X':
2461 get_xfermode = noisy; 2670 get_xfermode = noisy;
2462 noisy = 1; 2671 noisy = 1;
2463 GET_STRING(set_xfermode,xfermode_requested); 2672 p = check_ptr_v2(p,argc,argv);
2673 tmpstr = name;
2674 tmpstr[0] = '\0';
2675 while (isalnum(*p) && (tmpstr - name) < 31)
2676 {
2677 tmpstr[0] = *p++;
2678 tmpstr[1] = '\0';
2679 ++tmpstr;
2680 }
2681 xfermode_requested = translate_xfermode(name);
2682 if (xfermode_requested == -1)
2683 set_xfermode = 0;
2684 else
2685 set_xfermode = 1;
2464 if (!set_xfermode) 2686 if (!set_xfermode)
2465 bb_error_msg("-X: missing value"); 2687 bb_error_msg("-X: %s", bb_msg_missing_value);
2466 break; 2688 break;
2467 2689
2468 case 'K': 2690 case 'K':
2469 get_dkeep = noisy; 2691 get_dkeep = noisy;
2470 noisy = 1; 2692 noisy = 1;
2471 if (!*p && argc && isdigit(**argv)) 2693 p = check_ptr(p,argc,argv);
2472 p = *argv++, --argc; 2694 if((set_dkeep = set_flag(p,'1'))==1)
2473 if (*p == '0' || *p == '1') { 2695 dkeep = *p++ - '0';
2474 set_dkeep = 1; 2696 else
2475 dkeep = *p++ - '0'; 2697 bb_error_msg("-K: %s (0/1)", bb_msg_missing_value);
2476 } else
2477 bb_error_msg("-K: missing value (0/1)");
2478 break; 2698 break;
2479 2699
2480 case 'A': 2700 case 'A':
2481 get_lookahead = noisy; 2701 get_lookahead = noisy;
2482 noisy = 1; 2702 noisy = 1;
2483 if (!*p && argc && isdigit(**argv)) 2703 p = check_ptr(p,argc,argv);
2484 p = *argv++, --argc; 2704 if((set_lookahead = set_flag(p,'1'))==1)
2485 if (*p == '0' || *p == '1') { 2705 lookahead = *p++ - '0';
2486 set_lookahead = 1; 2706 else
2487 lookahead = *p++ - '0'; 2707 bb_error_msg("-A: %s (0/1)", bb_msg_missing_value);
2488 } else
2489 bb_error_msg("-A: missing value (0/1)");
2490 break; 2708 break;
2491 2709
2492 case 'L': 2710 case 'L':
2493 get_doorlock = noisy; 2711 get_doorlock = noisy;
2494 noisy = 1; 2712 noisy = 1;
2495 if (!*p && argc && isdigit(**argv)) 2713 p = check_ptr(p,argc,argv);
2496 p = *argv++, --argc; 2714 if((set_doorlock = set_flag(p,'1'))==1)
2497 if (*p == '0' || *p == '1') { 2715 doorlock = *p++ - '0';
2498 set_doorlock = 1; 2716 else
2499 doorlock = *p++ - '0'; 2717 bb_error_msg("-L: %s (0/1)", bb_msg_missing_value);
2500 } else
2501 bb_error_msg("-L: missing value (0/1)");
2502 break; 2718 break;
2503 2719
2504 case 'W': 2720 case 'W':
2505 get_wcache = noisy; 2721 get_wcache = noisy;
2506 noisy = 1; 2722 noisy = 1;
2507 if (!*p && argc && isdigit(**argv)) 2723 p = check_ptr(p,argc,argv);
2508 p = *argv++, --argc; 2724 if((set_wcache = set_flag(p,'1'))==1)
2509 if (*p == '0' || *p == '1') { 2725 wcache = *p++ - '0';
2510 set_wcache = 1; 2726 else
2511 wcache = *p++ - '0'; 2727 bb_error_msg("-W: %s (0/1)", bb_msg_missing_value);
2512 } else
2513 bb_error_msg("-W: missing value (0/1)");
2514 break; 2728 break;
2515 2729
2516 case 'C': 2730 case 'C':
@@ -2543,21 +2757,15 @@ int hdparm_main(int argc, char **argv)
2543 case 'k': 2757 case 'k':
2544 get_keep = noisy; 2758 get_keep = noisy;
2545 noisy = 1; 2759 noisy = 1;
2546 if (!*p && argc && isdigit(**argv)) 2760 p = check_ptr(p,argc,argv);
2547 p = *argv++, --argc; 2761 if((set_keep = set_flag(p,'1'))==1)
2548 if (*p == '0' || *p == '1') { 2762 keep = *p++ - '0';
2549 set_keep = 1;
2550 keep = *p++ - '0';
2551 }
2552 break; 2763 break;
2553#ifdef CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF 2764#ifdef CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
2554 case 'U': 2765 case 'U':
2555 if (!*p && argc && isdigit(**argv)) 2766 p = check_ptr(p,argc,argv);
2556 p = *argv++, --argc; 2767 if(! p)
2557 2768 goto error; /* "expected hwif_nr" */
2558 if(! p) {
2559 bb_error_msg_and_die("expected hwif_nr");
2560 }
2561 2769
2562 sscanf(p++, "%i", &hwif); 2770 sscanf(p++, "%i", &hwif);
2563 2771
@@ -2566,28 +2774,24 @@ int hdparm_main(int argc, char **argv)
2566#endif /* CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF */ 2774#endif /* CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF */
2567#ifdef CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF 2775#ifdef CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF
2568 case 'R': 2776 case 'R':
2569 if (!*p && argc && isdigit(**argv)) 2777 p = check_ptr(p,argc,argv);
2570 p = *argv++, --argc; 2778 if(! p)
2571 2779 goto error; /* "expected hwif_data" */
2572 if(! p) {
2573 bb_error_msg_and_die("expected hwif_data");
2574 }
2575 2780
2576 sscanf(p++, "%i", &hwif_data); 2781 sscanf(p++, "%i", &hwif_data);
2577 2782
2578 if (argc && isdigit(**argv)) 2783 if (argc && isdigit(**argv))
2579 p = *argv++, --argc; 2784 p = *argv++, --argc;
2580 else { 2785 else
2581 bb_error_msg_and_die("expected hwif_ctrl"); 2786 goto error; /* "expected hwif_ctrl" */
2582 }
2583 2787
2584 sscanf(p, "%i", &hwif_ctrl); 2788 sscanf(p, "%i", &hwif_ctrl);
2585 2789
2586 if (argc && isdigit(**argv)) 2790 if (argc && isdigit(**argv))
2587 p = *argv++, --argc; 2791 p = *argv++, --argc;
2588 else { 2792 else
2589 bb_error_msg_and_die("expected hwif_irq"); 2793error:
2590 } 2794 bb_error_msg_and_die("expected hwif value"); /* "expected hwif_irq" */
2591 2795
2592 sscanf(p, "%i", &hwif_irq); 2796 sscanf(p, "%i", &hwif_irq);
2593 2797
@@ -2599,10 +2803,16 @@ int hdparm_main(int argc, char **argv)
2599 case 'Q': 2803 case 'Q':
2600 get_dma_q = noisy; 2804 get_dma_q = noisy;
2601 noisy = 1; 2805 noisy = 1;
2602 neg = 0; 2806 /* neg = 0; */
2603 GET_NUMBER(set_dma_q, dma_q); 2807 p = check_ptr(p,argc,argv);
2604 if (neg) 2808 while (isdigit(*p))
2605 dma_q = -dma_q; 2809 {
2810 set_dma_q = 1;
2811 dma_q = (dma_q * 10) + (*p++ - '0');
2812 }
2813 /* what is this for ? as neg = 0 (see above) it seems to do nothing */
2814 /*if (neg)
2815 dma_q = -dma_q;*/
2606 break; 2816 break;
2607#ifdef CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET 2817#ifdef CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET
2608 case 'w': 2818 case 'w':
@@ -2611,27 +2821,35 @@ int hdparm_main(int argc, char **argv)
2611#endif /* CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET */ 2821#endif /* CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET */
2612#ifdef CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF 2822#ifdef CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
2613 case 'x': 2823 case 'x':
2614 if (!*p && argc && isdigit(**argv)) 2824 p = check_ptr(p,argc,argv);
2615 p = *argv++, --argc; 2825 if((perform_tristate = set_flag(p,'1'))==1)
2616 if (*p == '0' || *p == '1') { 2826 tristate = *p++ - '0';
2617 perform_tristate = 1; 2827 else
2618 tristate = *p++ - '0'; 2828 bb_error_msg("-x: %s (0/1)", bb_msg_missing_value);
2619 } else
2620 bb_error_msg("-x: missing value (0/1)");
2621 break; 2829 break;
2622 2830
2623#endif /* CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF */ 2831#endif /* CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF */
2624 case 'a': 2832 case 'a':
2625 get_readahead = noisy; 2833 get_readahead = noisy;
2626 noisy = 1; 2834 noisy = 1;
2627 GET_NUMBER(set_readahead,readahead); 2835 p = check_ptr(p,argc,argv);
2836 while (isdigit(*p))
2837 {
2838 set_readahead = 1;
2839 readahead = (readahead * 10) + (*p++ - '0');
2840 }
2628 break; 2841 break;
2629 case 'B': 2842 case 'B':
2630 get_apmmode = noisy; 2843 get_apmmode = noisy;
2631 noisy = 1; 2844 noisy = 1;
2632 GET_NUMBER(set_apmmode,apmmode); 2845 p = check_ptr(p,argc,argv);
2846 while (isdigit(*p))
2847 {
2848 set_apmmode = 1;
2849 apmmode = (io32bit * 10) + (*p++ - '0');
2850 }
2633 if (!set_apmmode) 2851 if (!set_apmmode)
2634 printf("-B: missing value (1-255)"); 2852 printf("-B: %s (1-255)", bb_msg_missing_value);
2635 break; 2853 break;
2636 case 't': 2854 case 't':
2637 do_timings = 1; 2855 do_timings = 1;
@@ -2645,18 +2863,9 @@ int hdparm_main(int argc, char **argv)
2645 case 'b': 2863 case 'b':
2646 get_busstate = noisy; 2864 get_busstate = noisy;
2647 noisy = 1; 2865 noisy = 1;
2648 if (!*p && argc && isdigit(**argv)) 2866 p = check_ptr(p,argc,argv);
2649 p = *argv++, --argc; 2867 if((set_busstate = set_flag(p,'2'))==1)
2650 switch (*p) { 2868 busstate = *p++ - '0';
2651 case '0':
2652 case '1':
2653 case '2':
2654 set_busstate = 1;
2655 busstate = *p++ - '0';
2656 break;
2657 default:
2658 break;
2659 }
2660 break; 2869 break;
2661#endif 2870#endif
2662 case 'h': 2871 case 'h':
@@ -2666,9 +2875,9 @@ int hdparm_main(int argc, char **argv)
2666 } 2875 }
2667 if (!argc) 2876 if (!argc)
2668 bb_show_usage(); 2877 bb_show_usage();
2669 } else {
2670 process_dev (p);
2671 } 2878 }
2879 else
2880 process_dev (p);
2672 } 2881 }
2673 return 0 ; 2882 return 0 ;
2674} 2883}