/* mu-hdparm, reduced for muLinux Based on hdparm.c, by by Mark S. Lord (c) 1994-1997 NOTE: Support only power mode settings. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include char *prgname; unsigned int standby; int fd; char devname[64]; long parm, multcount; struct stat stat_buf; int is_scsi_hd=0; enum {UNDEF,SET_STANDBY,GET_POWERMODE, SET_STANDBYNOW, SET_SLEEPNOW}; int op=UNDEF; /* functions */ void no_scsi (void) { if (is_scsi_hd) { fputs (" operation not supported on SCSI disks\n", stderr); exit(EINVAL); } } int usage() { printf("%s - get/set hard disk parameters \n\ - Based on hdparm.c (Mark Lord ) \n\ - rustic version by M.Andreoli\n",prgname); printf("Usage: %s [options] device\n", prgname); printf("options:\n"); printf("\t%-15s%s","-h","this cruft\n"); printf("\t%-15s%s","-S timeout","set standby (spindown) timeout to x\n"); printf("\t%-15s%s","-C","check IDE power mode status\n"); printf("\t%-15s%s","-y","put IDE drive in standby mode, now\n"); printf("--- Note\n"); printf("\ A value \n\ of zero means [off]. Values from 1 to 240 specify \n\ multiples of 5 seconds, for timeouts from 5 seconds \n\ to 20 minutes. Values from 241 to 251 specify from \n\ 1 to 11 units of 30 minutes, for timeouts from 30 \n\ minutes to 5.5 hours. A value of 252 signifies a \n\ timeout of 21 minutes, 253 sets a vendor-defined \n\ timeout, and 255 is interpreted as 21 minutes plus \n\ 15 seconds. \n\ "); exit(0); } static void interpret_standby (unsigned int standby) { printf(" ("); switch(standby) { case 0: printf("off"); break; case 252: printf("21 minutes"); break; case 253: printf("vendor-specific"); break; case 254: printf("?reserved"); break; case 255: printf("21 minutes + 15 seconds"); break; default: if (standby <= 240) { unsigned int secs = standby * 5; unsigned int mins = secs / 60; secs %= 60; if (mins) printf("%d minutes", mins); if (mins && secs) printf(" + "); if (secs) printf("%d seconds", secs); } else if (standby <= 251) { unsigned int mins = (standby - 240) * 30; unsigned int hrs = mins / 60; mins %= 60; if (hrs) printf("%d hours", hrs); if (hrs && mins) printf(" + "); if (mins) printf("%d minutes", mins); } else printf("illegal value)\n"); break; } printf(")\n"); } main(int argc, char *argv[]) { char *s=argv[0]; int i; /* prgname */ prgname=argv[0]; while ( *s != '\0' ) { if ( *s++ == '/' ) prgname = s; } /* syntax */ i=1; while (i<=argc-1) { if ( argv[i][0] == '-' ) switch( argv[i][1] ) { case 'h': usage(); case 'S': { standby=atoi(argv[++i]); strcpy(devname,argv[++i]); op=SET_STANDBY; break;} case 'C': op=GET_POWERMODE; strcpy(devname,argv[++i]); break; case 'y': op=SET_STANDBYNOW; strcpy(devname,argv[++i]); break; default: usage(); } i++; } if (op==UNDEF) usage(); /* chech device */ if (stat(devname,&stat_buf)) { perror(devname); exit(errno); } if ((major(stat_buf.st_rdev) == SCSI_DISK_MAJOR) #ifdef MD_MAJOR || (major(stat_buf.st_rdev) == MD_MAJOR) #endif ) is_scsi_hd = 1; else if (major(stat_buf.st_rdev) != IDE0_MAJOR && major(stat_buf.st_rdev) != IDE1_MAJOR #ifdef IDE2_MAJOR && major(stat_buf.st_rdev) != IDE2_MAJOR #endif #ifdef IDE3_MAJOR && major(stat_buf.st_rdev) != IDE3_MAJOR #endif ) { fprintf(stderr,"%s is not a hard disk.\n",devname); exit(EINVAL); } /* open device */ fd = open (devname, O_RDONLY); if (fd < 0) { perror(devname); exit(errno); } /* Ok, operate */ switch(op) { case SET_STANDBY: { unsigned char args[4] = {WIN_SETIDLE1,standby,0,0}; printf("%s: setting standby to %ld", devname,standby); interpret_standby(standby); if (ioctl(fd, HDIO_DRIVE_CMD, &args)) perror(" HDIO_DRIVE_CMD failed"); break; } case GET_POWERMODE: { #define WIN_CHECKPOWERMODE 0x98 unsigned char args[4] = {WIN_CHECKPOWERMODE,0,0,0}; const char *state; no_scsi(); if (ioctl(fd, HDIO_DRIVE_CMD, &args)) { if (errno != EIO || args[0] != 0 || args[1] != 0) { /* perror(" HDIO_DRIVE_CMD failed"); */ state = "unknown"; } else { state = "sleeping"; } } else { if (args[2] == 255) state = "active/idle"; else state = "standby"; } printf("%s: drive state is: %s\n",devname, state); break; } case SET_STANDBYNOW: { #define WIN_STANDBYNOW 0x94 unsigned char args[4] = {WIN_STANDBYNOW,0,0,0}; no_scsi(); printf("%s: issuing standby command\n",devname); if (ioctl(fd, HDIO_DRIVE_CMD, &args)) perror(" HDIO_DRIVE_CMD failed"); break; } } /* end switch */ } /* end main */