[903] in linux-scsi channel archive

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

New features for CDROM-Drivers

daemon@ATHENA.MIT.EDU (Christian A. Lademann)
Fri Nov 8 15:04:50 1996

To: eric@aib.com
Date: 	Thu, 7 Nov 1996 16:23:41 +0100 (MEZ)
From: "Christian A. Lademann" <cal@zls.com>
Cc: linux-scsi@vger.rutgers.edu, linux-kernel@vger.rutgers.edu
Reply-To: cal@zls.com

Hi.

I wrote a program "cdctrl" to control some cdrom-features, mainly the
auto-lock feature. For that I did some patches to the ide-cdrom-driver
and the scsi-cdrom-driver.

Here is the usage-information: (Sorry, no man-page yet ;-)

------------

    usage: cdctrl [-f device] [-v] [-h] [-V] command [command...]

    cdctrl version 1.0.000

    valid options are:
      -f device       name of the cd-rom device (default: /dev/cd0)
      -v              verbose: show progress
      -h              show this message
      -V              show version
      --              end of options

    valid commands are:
      eject           eject cdrom
      close           close cdrom-tray
      lock            disable eject-button
      unlock          enable eject-button
      eject_on_close  eject cdrom on last close
      -eject_on_close don't eject cdrom on last close
      lock_on_use     disable eject-button while cdrom in use
      -lock_on_use    enable eject-button while cdrom in use

------------

Please, take a look at the patches for the ide-driver. I hope they look
usefull an I would be happy if they get integrated in further releases
of the driver.

Appended you find the patches against linux-2.0.24 and the source for
'cdctrl'.

--Christian
----------------------------------------------------------------------
Christian A. Lademann                             EMail: <cal@zls.com>
--------------------- speaking from, not for: ------------------------
    ZLS Software GmbH                         Tel.:  (+49) 6195 900500
     D-65779 Kelkheim                         Fax:   (+49) 6195 900600
----------------------------------------------------------------------

--( snip )--
diff -ruN linux-2.0.24p/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
--- linux-2.0.24p/drivers/block/ide-cd.c	Fri Sep 20 16:00:34 1996
+++ linux/drivers/block/ide-cd.c	Tue Nov  5 02:21:01 1996
@@ -250,7 +250,9 @@
 	__u8 door_locked   : 1; /* We think that the drive door is locked. */
 	__u8 eject_on_close: 1; /* Drive should eject when device is closed. */
 	__u8 sanyo_slot    : 2; /* Sanyo 3 CD changer support */
-	__u8 reserved      : 2;
+	__u8 auto_lock     : 1; /* Drive should locked when device is in use. */
+	__u8 auto_locked   : 1;
+	/* __u8 reserved      : 2; */
 };
 #define CDROM_STATE_FLAGS(drive)  ((struct ide_cd_state_flags *)&((drive)->bios_head))
 
@@ -1421,7 +1423,10 @@
 		    (pc->c[0] != REQUEST_SENSE &&
 		     pc->c[0] != ALLOW_MEDIUM_REMOVAL &&
 		     pc->c[0] != START_STOP)) {
-			(void) cdrom_lockdoor (drive, 1, NULL);
+
+			CDROM_STATE_FLAGS (drive)->auto_locked = 1;
+			if(CDROM_STATE_FLAGS (drive)->auto_lock)
+				(void) cdrom_lockdoor (drive, 1, NULL);
 		}
 		return 0;
 	}
@@ -2055,6 +2060,22 @@
 		return 0;
 	}
 
+	case CDROMLOCK:
+		return cdrom_lockdoor (drive, 1, NULL);
+
+	case CDROMUNLOCK:
+		return cdrom_lockdoor (drive, 0, NULL);
+
+	case CDROMLOCK_SW: {
+		if((CDROM_STATE_FLAGS (drive)->auto_lock = arg)) {
+			if(CDROM_STATE_FLAGS (drive)->auto_locked)
+				cdrom_lockdoor (drive, 1, NULL);
+		} else
+			cdrom_lockdoor (drive, 0, NULL);
+			
+		return 0;
+	}
+
 	case CDROMPAUSE:
 		return cdrom_pause (drive, 1, NULL);
 
@@ -2469,7 +2490,10 @@
 
                 cdrom_saw_media_change (drive);
                 if (arg == -1) {
-			(void) cdrom_lockdoor (drive, 0, NULL);
+			CDROM_STATE_FLAGS (drive)->auto_locked = 0;
+			if(CDROM_STATE_FLAGS (drive)->auto_lock)
+				(void) cdrom_lockdoor (drive, 0, NULL);
+
 			return 0;
 		}
 		(void) cdrom_load_unload (drive, (int)arg, NULL);
@@ -2587,7 +2611,9 @@
 		/* If things worked ok, lock the door and read the
 		   TOC information. */
 		if (stat == 0 || my_reqbuf.sense_key == UNIT_ATTENTION) {
-			(void) cdrom_lockdoor (drive, 1, &my_reqbuf);
+			CDROM_STATE_FLAGS (drive)->auto_locked = 1;
+			if(CDROM_STATE_FLAGS (drive)->auto_lock)
+				(void) cdrom_lockdoor (drive, 1, &my_reqbuf);
 			(void) cdrom_read_toc (drive, &my_reqbuf);
 		}
 	}
@@ -2607,7 +2633,9 @@
 		invalidate_buffers (inode->i_rdev);
 
 		/* Unlock the door. */
-		(void) cdrom_lockdoor (drive, 0, NULL);
+		CDROM_STATE_FLAGS (drive)->auto_locked = 0;
+		if(CDROM_STATE_FLAGS (drive)->auto_lock)
+			(void) cdrom_lockdoor (drive, 0, NULL);
 
 		/* Do an eject if we were requested to do so. */
 		if (CDROM_STATE_FLAGS (drive)->eject_on_close)
@@ -2638,13 +2666,18 @@
 
 #if NO_DOOR_LOCKING
 	CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1;
+	CDROM_STATE_FLAGS (drive)->auto_lock = 0;
 #else
 	CDROM_CONFIG_FLAGS (drive)->no_doorlock = 0;
+	CDROM_STATE_FLAGS (drive)->auto_lock = 1;
 #endif
 
+	CDROM_STATE_FLAGS (drive)->auto_locked = 0;
+
 	/* by default Sanyo 3 CD changer support is turned off and
            ATAPI Rev 2.2+ standard support for CD changers is used */
 	CDROM_STATE_FLAGS (drive)->sanyo_slot = 0;
+
 
 	if (drive->id != NULL)
 		CDROM_CONFIG_FLAGS (drive)->drq_interrupt =
diff -ruN linux-2.0.24p/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- linux-2.0.24p/drivers/scsi/sr.c	Fri Sep 20 16:00:34 1996
+++ linux/drivers/scsi/sr.c	Mon Nov  4 22:21:25 1996
@@ -72,7 +72,10 @@
 	sync_dev(inode->i_rdev);
 	if(! --scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
 	{
-	    sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
+    	scsi_CDs[MINOR(inode->i_rdev)].auto_locked = 0;
+    	if(scsi_CDs[MINOR(inode->i_rdev)].auto_lock)
+	    	sr_ioctl(inode, NULL, CDROMUNLOCK, 0);
+
 	    if (scsi_CDs[MINOR(inode->i_rdev)].auto_eject)
 		sr_ioctl(inode, NULL, CDROMEJECT, 0);
 	}
@@ -604,7 +607,11 @@
     check_disk_change(inode->i_rdev);
     
     if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
-	sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
+
+    scsi_CDs[MINOR(inode->i_rdev)].auto_locked = 1;
+    if(scsi_CDs[MINOR(inode->i_rdev)].auto_lock)
+		sr_ioctl(inode, NULL, CDROMLOCK, 0);
+
     if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
 	(*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++;
     if(sr_template.usage_count) (*sr_template.usage_count)++;
@@ -662,9 +669,11 @@
  	     * from user space, since we do not want to
  	     * sleep from an interrupt.
  	     */
- 	    if( SDev->removable && !intr_count )
+ 	    if( SDev->lockable && !intr_count )
  	    {
-		scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
+			scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].auto_locked = 1;
+			if(scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].auto_lock)
+				scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
  	    }
  	    SDev->was_reset = 0;
 	}
@@ -1183,6 +1192,8 @@
 	scsi_CDs[i].remap = 1;
 	scsi_CDs[i].auto_eject = 0; /* Default is not to eject upon unmount. */
 	sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS - 9);
+	scsi_CDs[i].auto_lock = 1; /* Default is to lock upon usage. */
+	scsi_CDs[i].auto_locked = 0;
     }
     
     
diff -ruN linux-2.0.24p/drivers/scsi/sr.h linux/drivers/scsi/sr.h
--- linux-2.0.24p/drivers/scsi/sr.h	Thu Oct 31 15:58:29 1996
+++ linux/drivers/scsi/sr.h	Mon Nov  4 23:43:38 1996
@@ -33,6 +33,8 @@
 	unsigned 	remap:1;		/* support remapping			*/
 	unsigned 	use:1;			/* is this device still supportable	*/
 	unsigned	auto_eject:1;		/* auto-eject medium on last release.	*/
+	unsigned	auto_lock:1;		/* auto-lock on usage.	*/
+	unsigned	auto_locked:1;		/* auto_lock status.	*/
 	} Scsi_CD;
 	
 extern Scsi_CD * scsi_CDs;
diff -ruN linux-2.0.24p/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- linux-2.0.24p/drivers/scsi/sr_ioctl.c	Sat May 18 21:19:19 1996
+++ linux/drivers/scsi/sr_ioctl.c	Mon Nov  4 22:43:29 1996
@@ -307,7 +307,9 @@
 
         /* Gather information about newly inserted disc */
         check_disk_change (inode->i_rdev);
-        sr_ioctl (inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
+		scsi_CDs[MINOR(inode->i_rdev)].auto_locked = 1;
+		if(scsi_CDs[MINOR(inode->i_rdev)].auto_lock)
+        	sr_ioctl (inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
         sr_photocd (inode);
 
         if (scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
@@ -322,7 +324,9 @@
 	if (scsi_CDs[target].device -> access_count > 1)
 	    return -EBUSY;
 	
-	sr_ioctl (inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
+	scsi_CDs[target].auto_locked = 0;
+	if(scsi_CDs[target].auto_lock)
+		sr_ioctl (inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
 	sr_cmd[0] = START_STOP;
 	sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 1;
 	sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
@@ -335,6 +339,21 @@
 	
     case CDROMEJECT_SW:
         scsi_CDs[target].auto_eject = !!arg;
+        return 0;
+
+    case CDROMLOCK:
+		return(sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0));
+	
+    case CDROMUNLOCK:
+		return(sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0));
+	
+    case CDROMLOCK_SW:
+        if((scsi_CDs[target].auto_lock = !!arg)) {
+       		if(scsi_CDs[target].auto_locked)
+				sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
+		} else
+			sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
+
         return 0;
 
     case CDROMVOLCTRL:
diff -ruN linux-2.0.24p/include/linux/cdrom.h linux/include/linux/cdrom.h
--- linux-2.0.24p/include/linux/cdrom.h	Fri Sep 20 16:00:36 1996
+++ linux/include/linux/cdrom.h	Mon Nov  4 17:02:21 1996
@@ -285,6 +285,13 @@
  */
 #define CDROMLOADFROMSLOT	0x531a	/* LOAD disk from slot*/
 
+#define CDROMLOCK			0x531b	/* lock tray */
+#define CDROMUNLOCK			0x531c	/* unlock tray */
+
+/*
+ * enable (1) / disable (0) auto-locking
+ */
+#define CDROMLOCK_SW		0x531d	/* arg: 0 or 1 */
 
 /*
  * CD-ROM-specific SCSI command opcodes
--( snip )--
/* cdctrl.c */
/*
	control behaviour of cdrom-drives

	written by Christian Lademann <cal@zls.de>
*/
/*
07.11.1996:cal:version 1.0.000
*/

#include	<stdio.h>
#include	<fcntl.h>
#include	<string.h>
#include	<unistd.h>
#include	<sys/types.h>
#include	<linux/cdrom.h>

#define VERSION				"1.0.000"
#define	DEF_DEVICE			"/dev/cd0"

#define	CMD_EJECT			1
#define	CMD_CLOSE_TRAY		2
#define	CMD_LOCK			3
#define	CMD_UNLOCK			4
#define	CMD_EJECT_ON_CLOSE	5
#define	CMD_LOCK_ON_USE		6


int	usage() {
	fprintf(stderr, "usage: cdctrl [-f device] [-v] [-h] [-V] command [command...]\n");
	fprintf(stderr, "\ncdctrl version %s\n", VERSION);
	fprintf(stderr, "\nvalid options are:\n");
	fprintf(stderr, "  -f device       name of the cd-rom device (default: /dev/cd0)\n");
	fprintf(stderr, "  -v              verbose: show progress\n");
	fprintf(stderr, "  -h              show this message\n");
	fprintf(stderr, "  -V              show version\n");
	fprintf(stderr, "  --              end of options\n");
	fprintf(stderr, "\nvalid commands are:\n");
	fprintf(stderr, "  eject           eject cdrom\n");
	fprintf(stderr, "  close           close cdrom-tray\n");
	fprintf(stderr, "  lock            disable eject-button\n");
	fprintf(stderr, "  unlock          enable eject-button\n");
	fprintf(stderr, "  eject_on_close  eject cdrom on last close\n");
	fprintf(stderr, "  -eject_on_close don't eject cdrom on last close\n");
	fprintf(stderr, "  lock_on_use     disable eject-button while cdrom in use\n");
	fprintf(stderr, "  -lock_on_use    enable eject-button while cdrom in use\n");
	exit(1);
}


int	version() {
	printf("cdctrl version %s\n", VERSION);
	exit(0);
}


main(int argc, char *argv []) {
	extern int	optind, opterr;
	extern char	*optarg;

	char		*device = NULL,
				msg [80];

	int			c,
				cmd = 0,
				dev = -1,
				toggle = 1,
				ioctl_cmd = 0,
				ioctl_arg = 0,
				verbose = 0;


	while((c = getopt(argc, argv, "f:hvV")) != EOF)
		switch(c) {
		case 'f':	device = strdup(optarg); break;
		case 'v':	verbose++; break;
		case 'V':	version(); break;
		case 'h':
		case '?':	usage(); break;
		case '-':	break;
		}

	if(device == NULL)
		device = strdup(DEF_DEVICE);

	if(optind >= argc)
		usage();

	if((dev = open(device, O_RDONLY)) < 0) {
		sprintf(msg, "cannot open device \"%s\"", device);
		perror(msg);
		exit(1);
	}

	while(optind < argc) {
		cmd = 0;
		toggle = 1;

		if(strcmp(argv [optind], "eject") == 0)
			cmd = CMD_EJECT;
		else if(strcmp(argv [optind], "close") == 0)
			cmd = CMD_CLOSE_TRAY;
		else if(strcmp(argv [optind], "lock") == 0)
			cmd = CMD_LOCK;
		else if(strcmp(argv [optind], "unlock") == 0)
			cmd = CMD_UNLOCK;
		else {
			if(argv [optind] [0] == '-' || argv [optind] [0] == '+') {
				toggle = (argv [optind] [0] == '+');
				argv [optind]++;
			}

			if(strcmp(argv [optind], "eject_on_close") == 0)
				cmd = CMD_EJECT_ON_CLOSE;
			else if(strcmp(argv [optind], "lock_on_use") == 0)
				cmd = CMD_LOCK_ON_USE;
		}

		ioctl_cmd = ioctl_arg = 0;

		switch(cmd) {
		case CMD_EJECT:
			if(verbose)
				sprintf(msg, "eject cdrom");

			ioctl_cmd = CDROMEJECT;
			break;

		case CMD_CLOSE_TRAY:
			if(verbose)
				sprintf(msg, "close tray");

			ioctl_cmd = CDROMCLOSETRAY;
			break;

		case CMD_LOCK:
			if(verbose)
				sprintf(msg, "lock cdrom");

			ioctl_cmd = CDROMLOCK;
			break;

		case CMD_UNLOCK:
			if(verbose)
				sprintf(msg, "unlock cdrom");

			ioctl_cmd = CDROMUNLOCK;
			break;

		case CMD_EJECT_ON_CLOSE:
			if(verbose)
				sprintf(msg, "%s eject-on-close flag", (toggle ? "set" : "clear"));

			ioctl_cmd = CDROMEJECT_SW;
			ioctl_arg = toggle;
			break;

		case CMD_LOCK_ON_USE:
			if(verbose)
				sprintf(msg, "%s lock-on-use flag", (toggle ? "set" : "clear"));

			ioctl_cmd = CDROMLOCK_SW;
			ioctl_arg = toggle;
			break;

		default:
			fprintf(stderr, "unrecognized command \"%s\"\n", argv [optind]);
			exit(1);
			break;
		}

		if(ioctl_cmd) {
			if(verbose)
				printf("%s ... ", msg);

			if(ioctl(dev, ioctl_cmd, ioctl_arg) < 0) {
				perror("ioctl failed");
				exit(1);
			}

			if(verbose)
				printf("ok.\n");
		}

		optind++;
	}

	close(dev);

	exit(0);
}
--( snip )--

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