patch-1.3.41 linux/drivers/cdrom/mcdx.c
Next file: linux/drivers/char/Config.in
Previous file: linux/drivers/cdrom/mcd.c
Back to the patch index
Back to the overall index
- Lines: 797
- Date:
Mon Nov 13 08:54:55 1995
- Orig file:
v1.3.40/linux/drivers/cdrom/mcdx.c
- Orig date:
Thu Nov 9 11:23:47 1995
diff -u --recursive --new-file v1.3.40/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c
@@ -1,7 +1,7 @@
/*
* The Mitsumi CDROM interface
- * Copyright (C) 1995 Heiko Schlittermann
- * VERSION: 1.0a
+ * Copyright (C) 1995 Heiko Schlittermann <heiko@lotte.sax.de>
+ * VERSION: 1.3
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,10 +34,26 @@
#if RCS
static const char *mcdx_c_version
- = "mcdx.c,v 1.7 1995/08/27 01:46:41 heiko Exp";
+ = "mcdx.c,v 1.17 1995/11/06 01:07:57 heiko Exp";
#endif
+#include <linux/config.h>
+
+#ifdef MODULE
#include <linux/module.h>
+#endif
+
+#include <linux/version.h>
+
+#ifdef MODULE
+#ifndef CONFIG_MODVERSIONS
+char kernel_version[] = UTS_RELEASE;
+#endif
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#define MOD_IN_USE 1
+#endif MODULE
#include <linux/errno.h>
#include <linux/signal.h>
@@ -56,9 +72,11 @@
#include <linux/major.h>
-#ifndef MITSUMI_X_CDROM_MAJOR /* old kernel (doesn't know about MCDX) */
+/* old kernel (doesn't know about MCDX) */
+#ifndef MITSUMI_X_CDROM_MAJOR
#define MITSUMI_X_CDROM_MAJOR 20
-#define DEVICE_NAME "Mitsumi CD-ROM"
+#define DEVICE_NAME "mcdx"
+
/* #define DEVICE_INTR do_mcdx */
#define DEVICE_REQUEST do_mcdx_request
#define DEVICE_NR(device) (MINOR(device))
@@ -68,13 +86,20 @@
#define MAJOR_NR MITSUMI_X_CDROM_MAJOR
#include <linux/blk.h>
-#define mcdx_drive_map mcdx /* for compatible parameter passing with "insmod" */
+
+/* for compatible parameter passing with "insmod" */
+#define mcdx_drive_map mcdx
#include <linux/mcdx.h>
+#ifndef HZ
+#error HZ not defined
+#endif
+
/* CONSTANTS *******************************************************/
const int REQUEST_SIZE = 200;
const int DIRECT_SIZE = 200;
+const unsigned long ACLOSE_INHIBIT = 800; /* 1/100 s of autoclose inhibit */
enum drivemodes { TOC, DATA, RAW, COOKED };
enum datamodes { MODE0, MODE1, MODE2 };
@@ -134,7 +159,9 @@
volatile int introk; /* status of last irq operation */
volatile int busy; /* drive performs an operation */
volatile int lock; /* exclusive usage */
-
+ int eject_sw; /* 1 - eject on last close (default 0) */
+ int autoclose; /* 1 - close the door on open (default 1) */
+
/* cd infos */
struct s_diskinfo di;
struct s_multi multi;
@@ -166,10 +193,10 @@
char playcmd; /* play should always be single speed */
unsigned long changed; /* last jiff the media was changed */
unsigned long xxx; /* last jiff it was asked for media change */
+ unsigned long ejected; /* time we called the eject function */
int users; /* keeps track of open/close */
int lastsector; /* last block accessible */
int errno; /* last operation's error */
-
};
@@ -180,10 +207,18 @@
changed elsewhere. */
/* declared in blk.h */
+#if LINUX_VERSION_CODE < 66338
+unsigned long mcdx_init(unsigned long mem_start, unsigned long mem_end);
+#else
int mcdx_init(void);
+#endif
void do_mcdx_request(void);
+#if LINUX_VERSION_CODE < 66338
+int check_mcdx_media_change(dev_t);
+#else
int check_mcdx_media_change(kdev_t);
+#endif
/* already declared in init/main */
void mcdx_setup(char *, int *);
@@ -229,17 +264,17 @@
static int mcdx_requesttocdata(struct s_drive_stuff*, struct s_diskinfo*, int);
static int mcdx_getstatus(struct s_drive_stuff*, int);
static int mcdx_getval(struct s_drive_stuff*, int to, int delay, char*);
-
static int mcdx_talk(struct s_drive_stuff*,
- const unsigned char* cmd, size_t, void *buffer,
- size_t size, unsigned int timeout, int);
+ const unsigned char* cmd, size_t,
+ void *buffer, size_t size,
+ unsigned int timeout, int);
static int mcdx_readtoc(struct s_drive_stuff*);
static int mcdx_playtrk(struct s_drive_stuff*, const struct cdrom_ti*);
static int mcdx_playmsf(struct s_drive_stuff*, const struct cdrom_msf*);
+static int mcdx_setattentuator(struct s_drive_stuff*, struct cdrom_volctrl*, int);
/* static variables ************************************************/
-static int dummy0;
static int mcdx_drive_map[][2] = MCDX_DRIVEMAP;
static struct s_drive_stuff* mcdx_stuffp[MCDX_NDRIVES];
static struct s_drive_stuff* mcdx_irq_map[16] =
@@ -301,7 +336,7 @@
|| (ti.cdti_trk1 < stuffp->di.n_first))
return -EINVAL;
if (ti.cdti_trk1 > stuffp->di.n_last) ti.cdti_trk1 = stuffp->di.n_last;
- TRACE((IOCTL, "ioctl() track %d to %d\n", ti.cdti_trk0, ti.cdti_trk1));
+ TRACE((PLAYTRK, "ioctl() track %d to %d\n", ti.cdti_trk0, ti.cdti_trk1));
return mcdx_playtrk(stuffp, &ti);
}
@@ -388,20 +423,20 @@
if (-1 == mcdx_requestsubqcode(stuffp, &q, 2)) return -EIO;
- TRACE((IOCTL, "audiostatus: %x\n", stuffp->audiostatus));
+ TRACE((SUBCHNL, "audiostatus: %x\n", stuffp->audiostatus));
sub.cdsc_audiostatus = stuffp->audiostatus;
sub.cdsc_adr = q.control;
sub.cdsc_ctrl = q.control >> 4;
sub.cdsc_trk = bcd2uint(q.tno);
sub.cdsc_ind = bcd2uint(q.index);
- TRACE((IOCTL, "trk %d, ind %d\n",
+ TRACE((SUBCHNL, "trk %d, ind %d\n",
sub.cdsc_trk, sub.cdsc_ind));
if (sub.cdsc_format == CDROM_LBA) {
sub.cdsc_absaddr.lba = msf2log(&q.dt);
sub.cdsc_reladdr.lba = msf2log(&q.tt);
- TRACE((IOCTL, "lba: abs %d, rel %d\n",
+ TRACE((SUBCHNL, "lba: abs %d, rel %d\n",
sub.cdsc_absaddr.lba,
sub.cdsc_reladdr.lba));
} else if (sub.cdsc_format == CDROM_MSF) {
@@ -411,7 +446,7 @@
sub.cdsc_reladdr.msf.minute = bcd2uint(q.tt.minute);
sub.cdsc_reladdr.msf.second = bcd2uint(q.tt.second);
sub.cdsc_reladdr.msf.frame = bcd2uint(q.tt.frame);
- TRACE((IOCTL,
+ TRACE((SUBCHNL,
"msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
sub.cdsc_absaddr.msf.minute,
sub.cdsc_absaddr.msf.second,
@@ -438,7 +473,7 @@
toc.cdth_trk0 = stuffp->di.n_first;
toc.cdth_trk1 = stuffp->di.n_last;
memcpy_tofs((void*) arg, &toc, sizeof toc);
- TRACE((IOCTL, "ioctl() track0 = %d, track1 = %d\n",
+ TRACE((TOCHDR, "ioctl() track0 = %d, track1 = %d\n",
stuffp->di.n_first, stuffp->di.n_last));
return 0;
}
@@ -447,10 +482,9 @@
TRACE((IOCTL, "ioctl() PAUSE\n"));
if (stuffp->audiostatus != CDROM_AUDIO_PLAY) return -EINVAL;
if (-1 == mcdx_stop(stuffp, 1)) return -EIO;
+ stuffp->audiostatus = CDROM_AUDIO_PAUSED;
if (-1 == mcdx_requestsubqcode(stuffp, &stuffp->start, 1))
return -EIO;
-
- stuffp->audiostatus = CDROM_AUDIO_PAUSED;
return 0;
}
@@ -479,7 +513,7 @@
memcpy_tofs((void*) arg, &ms, sizeof(struct cdrom_multisession));
if (ms.addr_format == CDROM_MSF)
- TRACE((IOCTL,
+ TRACE((MS,
"ioctl() (%d, %02x:%02x.%02x [%02x:%02x.%02x])\n",
ms.xa_flag,
ms.addr.msf.minute,
@@ -490,8 +524,7 @@
stuffp->multi.msf_last.frame));
else
{
- dummy0=0;
- TRACE((IOCTL,
+ TRACE((MS,
"ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
ms.xa_flag,
ms.addr.lba,
@@ -509,11 +542,26 @@
return 0;
}
- case CDROMVOLCTRL: {
- TRACE((IOCTL, "ioctl() volctrl\n"));
+ case CDROMEJECT_SW: {
+ stuffp->eject_sw = arg;
return 0;
}
+ case CDROMVOLCTRL: {
+ int ans;
+ struct cdrom_volctrl volctrl;
+
+ TRACE((IOCTL, "ioctl() VOLCTRL\n"));
+ if ((ans = verify_area(
+ VERIFY_READ,
+ (void*) arg,
+ sizeof(volctrl))))
+ return ans;
+
+ memcpy_fromfs(&volctrl, (char *) arg, sizeof(volctrl));
+ return mcdx_setattentuator(stuffp, &volctrl, 1);
+ }
+
default:
WARN(("ioctl(): unknown request 0x%04x\n", cmd));
return -EINVAL;
@@ -529,20 +577,36 @@
TRACE((REQUEST, "do_request()\n"));
+#if LINUX_VERSION_CODE < 66338
+ if ((CURRENT == NULL) || (CURRENT->dev < 0)) {
+#else
if ((CURRENT == NULL) || (CURRENT->rq_status == RQ_INACTIVE)) {
+#endif
TRACE((REQUEST, "do_request() done\n"));
return;
}
+#if LINUX_VERSION_CODE < 66338
+ stuffp = mcdx_stuffp[MINOR(CURRENT->dev)];
+#else
stuffp = mcdx_stuffp[MINOR(CURRENT->rq_dev)];
+#endif
TRACE((REQUEST, "do_request() stuffp = %p\n", stuffp));
INIT_REQUEST;
+#if LINUX_VERSION_CODE < 66338
+ dev = MINOR(CURRENT->dev);
+#else
dev = MINOR(CURRENT->rq_dev);
+#endif
if ((dev < 0) || (dev >= MCDX_NDRIVES) || (!stuffp->present)) {
- WARN(("do_request(): bad device: %s\n",
- kdevname(CURRENT->rq_dev)));
+#if LINUX_VERSION_CODE < 66338
+ WARN(("do_request(): bad device: 0x%04x\n", CURRENT->dev));
+#else
+ WARN(("do_request(): bad device: %s\n",
+ kdevname(CURRENT->rq_dev)));
+#endif
end_request(0);
goto again;
}
@@ -569,13 +633,13 @@
CURRENT->buffer,
CURRENT->sector,
CURRENT->nr_sectors))) {
- WARN(("do_request() read error\n"));
- if (stuffp->errno == MCDX_EOM) {
- CURRENT->sector += CURRENT->nr_sectors;
- CURRENT->nr_sectors = 0;
- }
- end_request(0);
- goto again;
+ WARN(("do_request() read error\n"));
+ if (stuffp->errno == MCDX_EOM) {
+ CURRENT->sector += CURRENT->nr_sectors;
+ CURRENT->nr_sectors = 0;
+ }
+ end_request(0);
+ goto again;
}
CURRENT->sector += i;
CURRENT->nr_sectors -= i;
@@ -596,6 +660,8 @@
static int
mcdx_open(struct inode *ip, struct file *fp)
+/* actions done on open:
+ * 1) get the drives status */
{
struct s_drive_stuff *stuffp;
@@ -603,14 +669,21 @@
stuffp = mcdx_stuffp[MINOR(ip->i_rdev)];
if (!stuffp->present) return -ENXIO;
+ /* this is only done to test if the drive talks with us */
if (-1 == mcdx_getstatus(stuffp, 1)) return -EIO;
/* close the door, if necessary (get the door information
- from the hardware status register) */
- if (inb((unsigned int) stuffp->rreg_status) & MCDX_RBIT_DOOR)
- mcdx_closedoor(stuffp, 1);
+ from the hardware status register).
+ If the last eject is too recent, an autoclose wouldn't probably
+ be what we want ..., if we can't read the CD after an autoclose
+ no further autclose's will be tried */
+ if (inb((unsigned int) stuffp->rreg_status) & MCDX_RBIT_DOOR) {
+ if (jiffies - stuffp->ejected < ACLOSE_INHIBIT) return -EIO;
+ if (stuffp->autoclose) mcdx_closedoor(stuffp, 1);
+ else return -EIO;
+ }
- /* if the media changed we will have to little more */
+ /* if the media changed we will have to do a little more */
if (stuffp->xxx < stuffp->changed) {
TRACE((OPENCLOSE, "open() media changed\n"));
@@ -619,18 +692,23 @@
talk() will detect a media change ... (I think, config()
is the reason. */
- /*
- TRACE((OPENCLOSE, "open() hardware reset\n"));
- if (-1 == mcdx_reset(stuffp, HARD, 1)) return -EIO;
- */
-
stuffp->audiostatus = CDROM_AUDIO_INVALID;
/* get the multisession information */
{
+ int ans;
+
TRACE((OPENCLOSE, "open() Request multisession info\n"));
- if (-1 == mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))
- return -EIO;
+ ans = mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6);
+ if (ans == -1) {
+ stuffp->autoclose = 0;
+ mcdx_eject(stuffp, 1);
+ return -EIO;
+ }
+
+ /* we succeeded, so on next open(2) we could try auto close
+ again */
+ stuffp->autoclose = 1;
if (stuffp->multi.multi > 2)
WARN(("open() unknown multisession value (%d)\n", stuffp->multi.multi));
@@ -743,23 +821,36 @@
/* invalidate_inodes(ip->i_rdev); */
invalidate_buffers(ip->i_rdev);
- if (-1 == mcdx_lockdoor(stuffp, 0, 1))
- printk(MCDX ": Cannot unlock the door\n");
+ if (-1 == mcdx_lockdoor(stuffp, 0, 3))
+ INFO(("close() Cannot unlock the door\n"));
+
+ /* eject if wished */
+ if (stuffp->eject_sw) mcdx_eject(stuffp, 1);
+
}
MOD_DEC_USE_COUNT;
return;
}
+#if LINUX_VERSION_CODE < 66338
+int check_mcdx_media_change(dev_t full_dev)
+#else
int check_mcdx_media_change(kdev_t full_dev)
+#endif
/* Return: 1 if media changed since last call to
this function
0 else
Setting flag to 0 resets the changed state. */
{
+#if LINUX_VERSION_CODE < 66338
+ INFO(("check_mcdx_media_change called for device %x\n",
+ full_dev));
+#else
INFO(("check_mcdx_media_change called for device %s\n",
kdevname(full_dev)));
+#endif
return 0;
}
@@ -813,8 +904,8 @@
stuffp = mcdx_irq_map[irq];
- if (!stuffp->busy) {
- INFO(("intr() unexpected interrupt @ irq %d\n", irq));
+ if (stuffp == NULL || !stuffp->busy) {
+ TRACE((IRQ, "intr() unexpected interrupt @ irq %d\n", irq));
return;
}
@@ -825,8 +916,8 @@
irq, x, inb((unsigned int) stuffp->rreg_data)));
else
{
- dummy0=0;
TRACE((IRQ, "irq() irq %d ok, status %02x\n", irq, x));
+
}
stuffp->busy = 0;
wake_up_interruptible(&stuffp->busyq);
@@ -841,12 +932,16 @@
unsigned int timeout, int tries)
/* Send a command to the drive, wait for the result.
* returns -1 on timeout, drive status otherwise
+ * If buffer is not zero, the result (length size) is stored there.
+ * If buffer is zero the size should be the number of bytes to read
+ * from the drive. These bytes are discarded.
*/
{
- char c;
int st;
+ char c;
+ int disgard;
- if (!buffer || size == 0) buffer = &c, size = 1;
+ if ((disgard = (buffer == NULL))) buffer = &c;
while (stuffp->lock)
interruptible_sleep_on(&stuffp->lockq);
@@ -881,18 +976,20 @@
/* get the status byte */
if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
- WARN(("talk() %02x timed out (status), %d tr%s left\n",
+ INFO(("talk() %02x timed out (status), %d tr%s left\n",
cmd[0], tries - 1, tries == 2 ? "y" : "ies"));
continue;
}
- st = *bp++;
+ st = *bp;
sz--;
+ if (!disgard) bp++;
TRACE((TALK, "talk() got status 0x%02x\n", st));
/* command error? */
if (e_cmderr(st)) {
- WARN(("command error %02x (%d)\n", cmd[0], cmdlen));
+ WARN(("command error cmd = %02x %s \n",
+ cmd[0], cmdlen > 1 ? "..." : ""));
st = -1;
continue;
}
@@ -901,6 +998,9 @@
if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
stuffp->audiostatus =
e_audiobusy(st) ? CDROM_AUDIO_PLAY : CDROM_AUDIO_NO_STATUS;
+ else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
+ && e_audiobusy(st) == 0)
+ stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
/* media change? */
if (e_changed(st)) {
@@ -910,18 +1010,17 @@
/* now actually get the data */
while (sz--) {
- if (-1 == mcdx_getval(stuffp, timeout, -1, bp++)) {
- WARN(("talk() %02x timed out (data), %d tr%s left\n",
+ if (-1 == mcdx_getval(stuffp, timeout, -1, bp)) {
+ INFO(("talk() %02x timed out (data), %d tr%s left\n",
cmd[0], tries - 1, tries == 2 ? "y" : "ies"));
st = -1; break;
}
+ if (!disgard) bp++;
TRACE((TALK, "talk() got 0x%02x\n", *(bp - 1)));
}
}
-#if QUIET == 0
- if (!tries && st == -1) INFO(("talk() giving up\n"));
-#endif
+ if (!tries && st == -1) WARN(("talk() giving up\n"));
stuffp->lock = 0;
wake_up_interruptible(&stuffp->lockq);
@@ -938,7 +1037,11 @@
int i;
int drives = 0;
+#if LINUX_VERSION_CODE < 66338
+ mcdx_init(0, 0);
+#else
mcdx_init();
+#endif
for (i = 0; i < MCDX_NDRIVES; i++) {
if (mcdx_stuffp[i]) {
TRACE((INIT, "init_module() drive %d stuff @ %p\n",
@@ -950,6 +1053,7 @@
if (!drives)
return -EIO;
+ register_symtab(0);
return 0;
}
@@ -1009,12 +1113,18 @@
}
+#if LINUX_VERSION_CODE < 66338
+unsigned long mcdx_init(unsigned long mem_start, unsigned long mem_end)
+#else
int mcdx_init(void)
+#endif
{
int drive;
- INFO((": Version 1.0a "
- "mcdx.c,v 1.7 1995/08/27 01:46:41 heiko Exp\n"));
+ WARN(("Version 1.3 "
+ "mcdx.c,v 1.17 1995/11/06 01:07:57 heiko Exp\n"));
+ INFO((": Version 1.3 "
+ "mcdx.c,v 1.17 1995/11/06 01:07:57 heiko Exp\n"));
/* zero the pointer array */
for (drive = 0; drive < MCDX_NDRIVES; drive++)
@@ -1030,16 +1140,24 @@
TRACE((INIT, "init() try drive %d\n", drive));
+#if defined(MODULE) || LINUX_VERSION_CODE > 66338
+ TRACE((INIT, "kmalloc space for stuffpt's\n"));
TRACE((MALLOC, "init() malloc %d bytes\n", size));
if (!(stuffp = kmalloc(size, GFP_KERNEL))) {
WARN(("init() malloc failed\n"));
break;
}
+#else
+ TRACE((INIT, "adjust mem_start\n"));
+ stuffp = (struct s_drive_stuff *) mem_start;
+ mem_start += size;
+#endif
TRACE((INIT, "init() got %d bytes for drive stuff @ %p\n", sizeof(*stuffp), stuffp));
- /* zero the stuff */
+ /* set default values */
memset(stuffp, 0, sizeof(*stuffp));
+ stuffp->autoclose = 1; /* close the door on open(2) */
stuffp->present = 0; /* this should be 0 already */
stuffp->toc = NULL; /* this should be NULL already */
@@ -1165,7 +1283,11 @@
TRACE((INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp));
}
+#if MODULE || LINUX_VERSION_CODE > 66338
return 0;
+#else
+ return mem_start;
+#endif
}
@@ -1210,25 +1332,17 @@
current->timeout = jiffies + 5*HZ;
while (stuffp->busy) {
interruptible_sleep_on(&stuffp->busyq);
- if ((sig = (current->signal && ~current->blocked))
- || (to = (current->timeout == 0))) {
- break;
- }
}
current->timeout = 0;
/* test for possible errors */
if (((stuffp->busy == 0) && !stuffp->introk)
- || sig
|| to) {
if ((stuffp->busy == 0) && !stuffp->introk)
WARN(("mcdx_transfer() failure in data request\n"));
else if (to)
WARN(("mcdx_transfer(): timeout\n"));
- else if (sig)
- WARN(("mcdx_transfer(): got signal 0x%lx\n", current->signal));
-
stuffp->lock = 0;
stuffp->busy = 0;
wake_up_interruptible(&stuffp->lockq);
@@ -1365,16 +1479,16 @@
{
if (stuffp->toc) {
- TRACE((IOCTL, "ioctl() toc already read\n"));
+ TRACE((READTOC, "ioctl() toc already read\n"));
return 0;
}
- TRACE((IOCTL, "ioctl() readtoc for %d tracks\n",
+ TRACE((READTOC, "ioctl() readtoc for %d tracks\n",
stuffp->di.n_last - stuffp->di.n_first + 1));
if (-1 == mcdx_hold(stuffp, 1)) return -1;
- TRACE((IOCTL, "ioctl() tocmode\n"));
+ TRACE((READTOC, "ioctl() tocmode\n"));
if (-1 == mcdx_setdrivemode(stuffp, TOC, 1)) return -EIO;
/* all seems to be ok so far ... malloc */
@@ -1417,7 +1531,7 @@
&& (q.tno == 0)
&& (stuffp->toc[idx - stuffp->di.n_first].index == 0)) {
stuffp->toc[idx - stuffp->di.n_first] = q;
- TRACE((IOCTL, "ioctl() toc idx %d (trk %d)\n", idx, trk));
+ TRACE((READTOC, "ioctl() toc idx %d (trk %d)\n", idx, trk));
trk--;
}
if (trk == 0) break;
@@ -1429,16 +1543,16 @@
}
/* unset toc mode */
- TRACE((IOCTL, "ioctl() undo toc mode\n"));
+ TRACE((READTOC, "ioctl() undo toc mode\n"));
if (-1 == mcdx_setdrivemode(stuffp, DATA, 2))
return -EIO;
-#if MCDX_DEBUG && IOCTL
+#if MCDX_DEBUG && READTOC
{ int trk;
for (trk = 0;
trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
trk++)
- TRACE((IOCTL, "ioctl() %d readtoc %02x %02x %02x"
+ TRACE((READTOC, "ioctl() %d readtoc %02x %02x %02x"
" %02x:%02x.%02x %02x:%02x.%02x\n",
trk + stuffp->di.n_first,
stuffp->toc[trk].control, stuffp->toc[trk].tno, stuffp->toc[trk].index,
@@ -1466,14 +1580,14 @@
cmd[5] = msf->cdmsf_sec1;
cmd[6] = msf->cdmsf_frame1;
- TRACE((IOCTL, "ioctl(): play %x "
+ TRACE((PLAYMSF, "ioctl(): play %x "
"%02x:%02x:%02x -- %02x:%02x:%02x\n",
cmd[0], cmd[1], cmd[2], cmd[3],
cmd[4], cmd[5], cmd[6]));
outsb((unsigned int) stuffp->wreg_data, cmd, sizeof cmd);
- if (-1 == mcdx_getval(stuffp, 1*HZ, 0, NULL)) {
+ if (-1 == mcdx_getval(stuffp, 3*HZ, 0, NULL)) {
WARN(("playmsf() timeout\n"));
return -1;
}
@@ -1516,26 +1630,26 @@
mcdx_closedoor(struct s_drive_stuff *stuffp, int tries)
{
if (stuffp->present & DOOR)
- return mcdx_talk(stuffp, "\xf8", 1, NULL, 0, 5*HZ, tries);
+ return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5*HZ, tries);
else
return 0;
}
static int
mcdx_stop(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\xf0", 1, NULL, 0, 2*HZ, tries); }
+{ return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2*HZ, tries); }
static int
mcdx_hold(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\x70", 1, NULL, 0, 2*HZ, tries); }
+{ return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2*HZ, tries); }
static int
mcdx_eject(struct s_drive_stuff *stuffp, int tries)
{
- if (stuffp->present & DOOR)
- return mcdx_talk(stuffp, "\xf6", 1, NULL, 0, 5*HZ, tries);
- else
- return 0;
+ if (stuffp->present & DOOR) {
+ stuffp->ejected = jiffies;
+ return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5*HZ, tries);
+ } else return 0;
}
static int
@@ -1618,7 +1732,7 @@
default: break;
}
cmd[0] = 0x50;
- return mcdx_talk(stuffp, cmd, 2, NULL, 0, 5*HZ, tries);
+ return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5*HZ, tries);
}
@@ -1633,7 +1747,7 @@
case MODE2: cmd[1] = 0x02; break;
default: return -EINVAL;
}
- return mcdx_talk(stuffp, cmd, 2, NULL, 0, 5*HZ, tries);
+ return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5*HZ, tries);
}
static int
@@ -1648,13 +1762,13 @@
cmd[1] = 0x10; /* irq enable */
cmd[2] = 0x05; /* pre, err irq enable */
- if (-1 == mcdx_talk(stuffp, cmd, 3, NULL, 0, 1*HZ, tries))
+ if (-1 == mcdx_talk(stuffp, cmd, 3, NULL, 1, 1*HZ, tries))
return -1;
cmd[1] = 0x02; /* dma select */
cmd[2] = 0x00; /* no dma */
- return mcdx_talk(stuffp, cmd, 3, NULL, 0, 1*HZ, tries);
+ return mcdx_talk(stuffp, cmd, 3, NULL, 1, 1*HZ, tries);
}
static int
@@ -1679,7 +1793,7 @@
outb(0, (unsigned int) stuffp->wreg_chn); /* no dma, no irq -> hardware */
outb(0, (unsigned int) stuffp->wreg_reset); /* hw reset */
return 0;
- } else return mcdx_talk(stuffp, "\x60", 1, NULL, 0, 5*HZ, tries);
+ } else return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5*HZ, tries);
}
static int
@@ -1688,14 +1802,14 @@
char cmd[2] = { 0xfe };
if (stuffp->present & DOOR) {
cmd[1] = lock ? 0x01 : 0x00;
- return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 0, 5*HZ, tries);
+ return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5*HZ, tries);
} else
return 0;
}
static int
mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\x40", 1, NULL, 0, 5*HZ, tries); }
+{ return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5*HZ, tries); }
static int
mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char* buf)
@@ -1714,3 +1828,20 @@
return 0;
}
+
+static int
+mcdx_setattentuator(
+ struct s_drive_stuff* stuffp,
+ struct cdrom_volctrl* vol,
+ int tries)
+{
+ char cmd[5];
+ cmd[0] = 0xae;
+ cmd[1] = vol->channel0;
+ cmd[2] = 0;
+ cmd[3] = vol->channel1;
+ cmd[4] = 0;
+
+ return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
+}
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this