[2386] in linux-scsi channel archive

home help back first fref pref prev next nref lref last post

Re: ZIP autoeject?

daemon@ATHENA.MIT.EDU (Gerd Knorr)
Fri Aug 29 15:50:44 1997

Date: 	Fri, 29 Aug 1997 19:53:11 +0200
From: Gerd Knorr <kraxel@goldbach.isdn.cs.tu-berlin.de>
To: linux-scsi@vger.rutgers.edu
In-Reply-To: <19970829113018.15835@beijing.itri.loyola.edu>

In article <19970829113018.15835@beijing.itri.loyola.edu>, you wrote:
>Iomega reccommends that zip disks be ejected before the machine is shut
>down, and their latest windows software does this automatically. I'd
>like to know if there's a way to get this effect using linux. I took a
>look at the 'eject' utility, but it only seems to support cdroms. Is
>there a similar utility for zip drives (or removable scsi drives in
>general)? Or, (perhaps better) a flag to autoeject on umount? If there
>isn't a utility, is there a kernel function I could use to write such a
>utility?

Here comes one. What it does depends on the name of the executeable.
It sends scsi commands via ioctl to the kernel, bypassing all
sanity-checks (you can eject mounted media), so be careful. Stick this
somewhere (well, best after umount -a) into your shutdown sequence.

  Gerd

---------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#include "scsi/scsi.h"
#include "scsi/scsi_ioctl.h"

#define DEFAULT_DEVICE	"/dev/sda"

extern char *sys_errlist[];


typedef struct scsi_ioctl_command {
        unsigned int inlen;
        unsigned int outlen;
        unsigned char data[0];
} Scsi_Ioctl_Command;


void
main(int argc, char *argv[])
{
    int  fd,val;
    char *prog, device[256], request[256], *h;
    Scsi_Ioctl_Command *sic = (Scsi_Ioctl_Command*)request;

    h = strchr(argv[0],'/');
    prog = h ? h+1 : argv[0];

    if (0 == strcmp(prog,"eject") || 0 == strcmp(prog,"unload"))
	val=2;
    else if (0 == strcmp(prog,"close") || 0 == strcmp(prog,"load"))
	val=3;
    else if (0 == strcmp(prog,"spindown"))
	val=0;
    else if (0 == strcmp(prog,"spinup"))
	val=1;
    else {
	fprintf(stderr,"undefined: %s\n",prog);
	exit(1);
    }

    if (argc > 1) {
	strcpy(device,argv[1]);
    } else {
	strcpy(device,DEFAULT_DEVICE);
    }

    if (-1 == (fd = open(device, O_RDONLY))) {
	fprintf(stderr,"%s: can't open %s: %s\n",prog,device,
		sys_errlist[errno]);
	exit(1);
    }

    if (-1 == ioctl(fd,SCSI_IOCTL_DOORUNLOCK,sic)) {
	perror("ioctl (unlock)");
	exit(1);
    }

    memset(request,0,256);
    sic->inlen  = 0;
    sic->outlen = 0;
    sic->data[0] = START_STOP;
    sic->data[1] = 0;
    sic->data[2] = 0;
    sic->data[3] = 0;
    sic->data[4] = val;
    sic->data[5] = 0;

    if (-1 == ioctl(fd,SCSI_IOCTL_SEND_COMMAND,sic)) {
	perror("ioctl (eject)");
	exit(1);
    }

    close(fd);
    exit(0);
}

home help back first fref pref prev next nref lref last post