Messages in this thread Patch in this message |  | | Subject | New features for CDROM-Drivers | Date | Thu, 7 Nov 1996 16:23:41 +0100 (MEZ) | From | "Christian A. Lademann" <> |
| |
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 )--
|  |