lkml.org 
[lkml]   [1996]   [Nov]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
SubjectNew features for CDROM-Drivers
Date
From
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 )--
\
 
 \ /
  Last update: 2005-03-22 13:38    [W:0.030 / U:1.272 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site