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);
}

Reply via email to