Hi folks, please find the next version of haltest.c attached, which serves as a demonstration on how to spin down the drive.
The idea is as follows: 1. Open the drive 2. Check if drive is active (see hdparm -C /dev/hdc) 3. If the drive is active requeuery the drive state, until it gets not_active and _do not_ close the filedescriptor meanwhile. Active:the the drive is spinning. Not_active: the drive has spun down. 4. If the drive is not active close the file descriptor. 5. Wait some time 6. Restart with 1. Can ohter people confirm that this works on other systems as well, please ? Hope that helps. Regards Jürgen
#include <stdlib.h> #include <unistd.h> #include <termios.h> #include <fcntl.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> #include <sys/ioctl.h> #include <errno.h> #include <string.h> #include <time.h> #include <linux/types.h> #include <linux/hdreg.h> #include <linux/major.h> /* test program for cdrom spinning problem */ /* tested hardware ibm thinkpad r51 */ /* (dmesg) hdc: HL-DS-ST DVDRAM GSA-4080N */ /* without any intervention,after opening and closing the */ /* tray, the drive spins up and stops later */ /* author Juergen Lueters <jlueters intranet-engineering.de > */ /* published under gplv2 and later */ #define DRIVE_ACTIVE 1 #define DRIVE_NOT_ACTIVE 0 static int isDriveActive(int fd ) { /* this query has been taken from the */ /* hdparm.c sources */ unsigned char args[4]={WIN_CHECKPOWERMODE1,0,0,0}; int state=0; if (ioctl(fd, HDIO_DRIVE_CMD, &args) && (args[0] = WIN_CHECKPOWERMODE2) && ioctl(fd, HDIO_DRIVE_CMD, &args)) { if (errno != EIO || args[0] != 0 || args[1] != 0) { state = -1; /* "unknown"; */ } else state = DRIVE_NOT_ACTIVE; /* "sleeping"; */ } else { if ( args[2] == 255) state=DRIVE_ACTIVE; else state=DRIVE_NOT_ACTIVE; } printf(" drive state is: %d\n", state); return(state); } static void pollDrive(short cycles) { int i=0; int rc=0; int fd=0; for (i=0;i<cycles;i++) { fd=open("/dev/hdc", O_RDONLY|O_NONBLOCK|O_EXCL|00100000); printf("halTest.main open /dev/hdc fd: %d iteration: %d\n",fd,i); rc=isDriveActive(fd); while(rc==DRIVE_ACTIVE) { rc=isDriveActive(fd); printf("halTest.main isActive: %d \n", rc); usleep(1000000); } close(fd); usleep(1000000); } } int main(int argc, char *argv[]) { int i=0; printf("the first iteration shall show that the cdrom remains silent even if it is beeing polled \n"); pollDrive(10); printf("please open and close the cdrom tray \n"); sleep(8); printf("polling the drive (let the wheel spin)"); printf("the drive shall spin down after some seconds \n"); pollDrive(30); printf("repolling the drive - it shall remain silent \n"); sleep(1); pollDrive(10); printf("Thats it - spin test over \n"); exit(0); }