As described in my patch that marked this obsolete driver as BROKEN,
this patch completely removes it.

Signed-off-by: Adrian Bunk <[EMAIL PROTECTED]>

---

 Documentation/cdrom/mcd  |    4 
 Documentation/cdrom/mcdx |   17 
 drivers/cdrom/Kconfig    |   56 -
 drivers/cdrom/Makefile   |    1 
 drivers/cdrom/mcd.c      | 1565 ---------------------------------------
 drivers/cdrom/mcd.h      |  106 --
 6 files changed, 6 insertions(+), 1743 deletions(-)

--- linux-2.6.11-mm3-full/drivers/cdrom/Kconfig.old     2005-03-15 
04:14:03.000000000 +0100
+++ linux-2.6.11-mm3-full/drivers/cdrom/Kconfig 2005-03-15 04:20:07.000000000 
+0100
@@ -103,60 +103,14 @@
          To compile this driver as a module, choose M here: the
          module will be called sbpcd.
 
-config MCD
-       tristate "Mitsumi (standard) [no XA/Multisession] CDROM support"
-       depends on CD_NO_IDESCSI && BROKEN
-       ---help---
-         This is the older of the two drivers for the older Mitsumi models
-         LU-005, FX-001 and FX-001D. This is not the right driver for the
-         FX-001DE and the triple or quad speed models (all these are
-         IDE/ATAPI models). Please also the file
-         <file:Documentation/cdrom/mcd>.
-
-         With the old LU-005 model, the whole drive chassis slides out for cd
-         insertion. The FX-xxx models use a motorized tray type mechanism.
-         Note that this driver does not support XA or MultiSession CDs
-         (PhotoCDs). There is a new driver (next question) which can do
-         this. If you want that one, say N here.
-
-         If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
-         file system support" below, because that's the file system used on
-         CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called mcd.
-
-config MCD_IRQ
-       int "MCD IRQ"
-       depends on MCD
-       default "11"
-       help
-         This allows you to specify the default value of the IRQ used by the
-         driver. This setting can be overridden by passing the "mcd="
-         parameter to the kernel at boot time (or at module load time if you
-         said M to "Standard Mitsumi CD-ROM support").
-
-config MCD_BASE
-       hex "MCD I/O base"
-       depends on MCD
-       default "300"
-       help
-         This allows you to specify the default value of the I/O base address
-         used by the driver. This setting can be overridden by passing the
-         "mcd=" parameter to the kernel at boot time (or at module load time
-         if you said M to "Standard Mitsumi CD-ROM support").
-
 config MCDX
-       tristate "Mitsumi [XA/MultiSession] CDROM support"
+       tristate "Mitsumi CDROM support"
        depends on CD_NO_IDESCSI
        ---help---
-         Use this driver if you want to be able to read XA or MultiSession
-         CDs (PhotoCDs) as well as ordinary CDs with your Mitsumi LU-005,
-         FX-001 or FX-001D CD-ROM drive. In addition, this driver uses much
-         less kernel memory than the old one, if that is a concern. This
-         driver is able to support more than one drive, but each drive needs
-         a separate interface card. Please read the file
-         <file:Documentation/cdrom/mcdx>.
+         Use this driver if you want to be able to use your Mitsumi LU-005,
+         FX-001 or FX-001D CD-ROM drive.
+
+         Please read the file <file:Documentation/cdrom/mcdx>.
 
          If you say Y here, you should also say Y or M to "ISO 9660 CD-ROM
          file system support" below, because that's the file system used on
--- linux-2.6.11-mm3-full/drivers/cdrom/Makefile.old    2005-03-15 
04:14:34.000000000 +0100
+++ linux-2.6.11-mm3-full/drivers/cdrom/Makefile        2005-03-15 
04:14:43.000000000 +0100
@@ -15,7 +15,6 @@
 obj-$(CONFIG_CM206)            += cm206.o      cdrom.o
 obj-$(CONFIG_GSCD)             += gscd.o
 obj-$(CONFIG_ISP16_CDI)                += isp16.o
-obj-$(CONFIG_MCD)              += mcd.o        cdrom.o
 obj-$(CONFIG_MCDX)             += mcdx.o       cdrom.o
 obj-$(CONFIG_OPTCD)            += optcd.o
 obj-$(CONFIG_SBPCD)            += sbpcd.o      cdrom.o
--- linux-2.6.11-mm3-full/Documentation/cdrom/mcdx.old  2005-03-15 
04:21:07.000000000 +0100
+++ linux-2.6.11-mm3-full/Documentation/cdrom/mcdx      2005-03-15 
04:21:40.000000000 +0100
@@ -1,16 +1,3 @@
-This is a first attempt to create an `improved' driver for the Mitsumi drives.
-It is able to "live together" with mcd.c, if you have at least two Mitsumi
-drives: each driver can use its own drive.
-
-To allow this "coexistence" as long as mcdx.c is not a superset of mcd.c,
-this driver has to use its own device files. We use MAJOR 20 for it. So,
-you have to do
-
- # mknod /dev/mcdx0 b 20 0
- # mknod /dev/mcdx1 b 20 1
-
-and so on, one entry for each drive to support, once.
-
 If you are using the driver as a module, you can specify your ports and IRQs
 like
 
@@ -25,9 +12,7 @@
         ordinary CDs;
     o   supports up to 5 drives (of course, you'll need free 
         IRQs, i/o ports and slots);
-    o   uses much less kernel memory than the standard mcd driver
-        (no extra driver internal buffers!).
-    o   plays audio (like the `old' driver, I hope)
+    o   plays audio
 
 This version doesn't support yet:
 
--- linux-2.6.11-mm3-full/Documentation/cdrom/mcd       2005-03-02 
08:38:13.000000000 +0100
+++ /dev/null   2004-11-25 03:16:25.000000000 +0100
@@ -1,4 +0,0 @@
-This driver does not support XA or MultiSession CDs (PhotoCDs). Use the
-experimental driver mcdx.c for that.
-
-You can use mcd for one interface, and mcdx for another.
--- linux-2.6.11-mm3-full/drivers/cdrom/mcd.h   2005-03-02 08:38:00.000000000 
+0100
+++ /dev/null   2004-11-25 03:16:25.000000000 +0100
@@ -1,106 +0,0 @@
-/*
- * Definitions for a Mitsumi CD-ROM interface
- *
- *     Copyright (C) 1992  Martin Harriss
- *
- *     [EMAIL PROTECTED]
- *
- *  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
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-/* Increase this if you get lots of timeouts */
-#define MCD_STATUS_DELAY       1000
-
-/* number of times to retry a command before giving up */
-#define MCD_RETRY_ATTEMPTS      10
-
-/* port access macro */
-#define MCDPORT(x)             (mcd_port + (x))
-
-/* How many sectors to read at 1x when an error at 2x speed occurs. */
-/* You can change this to anything from 2 to 32767, but 30 seems to */
-/* work best for me.  I have found that when the drive has problems */
-/* reading one sector, it will have troubles reading the next few.  */
-#define SINGLE_HOLD_SECTORS 30 
-
-#define MCMD_2X_READ 0xC1      /* Double Speed Read DON'T TOUCH! */
-
-/* status bits */
-
-#define MST_CMD_CHECK          0x01            /* command error */
-#define MST_BUSY               0x02            /* now playing */
-#define MST_READ_ERR           0x04            /* read error */
-#define MST_DSK_TYPE           0x08
-#define MST_SERVO_CHECK                0x10
-#define MST_DSK_CHG            0x20            /* disk removed or changed */
-#define MST_READY              0x40            /* disk in the drive */
-#define MST_DOOR_OPEN          0x80            /* door is open */
-
-/* flag bits */
-
-#define MFL_DATA               0x02            /* data available */
-#define MFL_STATUS             0x04            /* status available */
-
-/* commands */
-
-#define MCMD_GET_DISK_INFO     0x10            /* read info from disk */
-#define MCMD_GET_Q_CHANNEL     0x20            /* read info from q channel */
-#define MCMD_GET_STATUS                0x40
-#define MCMD_SET_MODE          0x50
-#define MCMD_SOFT_RESET                0x60
-#define MCMD_STOP              0x70            /* stop play */
-#define MCMD_CONFIG_DRIVE      0x90
-#define MCMD_SET_VOLUME                0xAE            /* set audio level */
-#define MCMD_PLAY_READ         0xC0            /* play or read data */
-#define MCMD_GET_VERSION       0xDC
-#define MCMD_EJECT             0xF6            /* eject (FX drive) */
-
-/* borrowed from hd.c */
-
-#define MAX_TRACKS             104
-
-struct msf {
-       unsigned char   min;
-       unsigned char   sec;
-       unsigned char   frame;
-};
-
-struct mcd_Play_msf {
-       struct msf      start;
-       struct msf      end;
-};
-
-struct mcd_DiskInfo {
-       unsigned char   first;
-       unsigned char   last;
-       struct msf      diskLength;
-       struct msf      firstTrack;
-};
-
-struct mcd_Toc {
-       unsigned char   ctrl_addr;
-       unsigned char   track;
-       unsigned char   pointIndex;
-       struct msf      trackTime;
-       struct msf      diskTime;
-};
-
-#define test1(x)
-#define test2(x)
-#define test3(x)
-#define test4(x)
-#define test5(x)
-
--- linux-2.6.11-mm3-full/drivers/cdrom/mcd.c   2005-03-12 13:33:21.000000000 
+0100
+++ /dev/null   2004-11-25 03:16:25.000000000 +0100
@@ -1,1565 +0,0 @@
-/*
-       linux/kernel/blk_drv/mcd.c - Mitsumi CDROM driver
-
-       Copyright (C) 1992  Martin Harriss
-       Portions Copyright (C) 2001 Red Hat
-
-       [EMAIL PROTECTED] (no longer valid - where are you now, Martin?)
-
-       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
-       the Free Software Foundation; either version 2, or (at your option)
-       any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-       HISTORY
-
-       0.1     First attempt - internal use only
-       0.2     Cleaned up delays and use of timer - alpha release
-       0.3     Audio support added
-       0.3.1 Changes for mitsumi CRMC LU005S march version
-                  ([EMAIL PROTECTED])
-        0.3.2 bug fixes to the ioctls and merged with ALPHA0.99-pl12
-                  (Jon Tombs <[EMAIL PROTECTED]>)
-        0.3.3 Added more #defines and mcd_setup()
-                  (Jon Tombs <[EMAIL PROTECTED]>)
-
-       October 1993 Bernd Huebner and Ruediger Helsch, Unifix Software GmbH,
-       Braunschweig, Germany: rework to speed up data read operation.
-       Also enabled definition of irq and address from bootstrap, using the
-       environment.
-       November 93 added code for FX001 S,D (single & double speed).
-       February 94 added code for broken M 5/6 series of 16-bit single speed.
-
-
-        0.4   
-        Added support for loadable MODULEs, so mcd can now also be loaded by 
-        insmod and removed by rmmod during runtime.
-        Werner Zimmermann ([EMAIL PROTECTED]), Mar. 26, 95
-
-       0.5
-       I added code for FX001 D to drop from double speed to single speed 
-       when encountering errors... this helps with some "problematic" CD's
-       that are supposedly "OUT OF TOLERANCE" (but are really shitty presses!)
-       severely scratched, or possibly slightly warped! I have noticed that
-       the Mitsumi 2x/4x drives are just less tolerant and the firmware is 
-       not smart enough to drop speed, so let's just kludge it with software!
-       ****** THE 4X SPEED MITSUMI DRIVES HAVE THE SAME PROBLEM!!!!!! ******
-       Anyone want to "DONATE" one to me?! ;) I hear sometimes they are
-       even WORSE! ;)
-       ** HINT... HINT... TAKE NOTES MITSUMI This could save some hassles with
-       certain "large" CD's that have data on the outside edge in your 
-       DOS DRIVERS .... Accuracy counts... speed is secondary ;)
-       17 June 95 Modifications By Andrew J. Kroll <[EMAIL PROTECTED]>
-       07 July 1995 Modifications by Andrew J. Kroll
-
-       Bjorn Ekwall <[EMAIL PROTECTED]> added unregister_blkdev to mcd_init()
-
-       Michael K. Johnson <[EMAIL PROTECTED]> added retries on open
-       for slow drives which take a while to recognize that they contain
-       a CD.
-
-       November 1997 -- ported to the Uniform CD-ROM driver by Erik Andersen.
-       March    1999 -- made io base and irq CONFIG_ options (Tigran Aivazian).
-       
-       November 1999 -- Make kernel-parameter implementation work with 2.3.x 
-                        Removed init_module & cleanup_module in favor of 
-                        module_init & module_exit.
-                        Torben Mathiasen <[EMAIL PROTECTED]>
-               
-       September 2001 - Reformatted and cleaned up the code
-                        Alan Cox <[EMAIL PROTECTED]>                    
-*/
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/signal.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/config.h>
-
-/* #define REALLY_SLOW_IO  */
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/current.h>
-#include <asm/uaccess.h>
-#include <linux/blkdev.h>
-
-#include "mcd.h"
-
-/* I added A flag to drop to 1x speed if too many errors 0 = 1X ; 1 = 2X */
-static int mcdDouble;
-
-/* How many sectors to hold at 1x speed counter */
-static int mcd1xhold;
-
-/* Is the drive connected properly and responding?? */
-static int mcdPresent;
-static struct request_queue *mcd_queue;
-
-#define MAJOR_NR MITSUMI_CDROM_MAJOR
-#define QUEUE (mcd_queue)
-#define CURRENT elv_next_request(mcd_queue)
-
-#define QUICK_LOOP_DELAY udelay(45)    /* use udelay */
-#define QUICK_LOOP_COUNT 20
-
-static int current_valid(void)
-{
-        return CURRENT &&
-               CURRENT->cmd == READ &&
-               CURRENT->sector != -1;
-}
-
-#define MFL_STATUSorDATA (MFL_STATUS | MFL_DATA)
-#define MCD_BUF_SIZ 16
-static volatile int mcd_transfer_is_active;
-static char mcd_buf[2048 * MCD_BUF_SIZ];       /* buffer for block size 
conversion */
-static volatile int mcd_buf_bn[MCD_BUF_SIZ], mcd_next_bn;
-static volatile int mcd_buf_in, mcd_buf_out = -1;
-static volatile int mcd_error;
-static int mcd_open_count;
-enum mcd_state_e {
-       MCD_S_IDLE,             /* 0 */
-       MCD_S_START,            /* 1 */
-       MCD_S_MODE,             /* 2 */
-       MCD_S_READ,             /* 3 */
-       MCD_S_DATA,             /* 4 */
-       MCD_S_STOP,             /* 5 */
-       MCD_S_STOPPING          /* 6 */
-};
-static volatile enum mcd_state_e mcd_state = MCD_S_IDLE;
-static int mcd_mode = -1;
-static int MCMD_DATA_READ = MCMD_PLAY_READ;
-
-#define READ_TIMEOUT 3000
-
-int mitsumi_bug_93_wait;
-
-static short mcd_port = CONFIG_MCD_BASE;       /* used as "mcd" by "insmod" */
-static int mcd_irq = CONFIG_MCD_IRQ;   /* must directly follow mcd_port */
-
-static int McdTimeout, McdTries;
-static DECLARE_WAIT_QUEUE_HEAD(mcd_waitq);
-
-static struct mcd_DiskInfo DiskInfo;
-static struct mcd_Toc Toc[MAX_TRACKS];
-static struct mcd_Play_msf mcd_Play;
-
-static int audioStatus;
-static char mcdDiskChanged;
-static char tocUpToDate;
-static char mcdVersion;
-
-static void mcd_transfer(void);
-static void mcd_poll(unsigned long dummy);
-static void mcd_invalidate_buffers(void);
-static void hsg2msf(long hsg, struct msf *msf);
-static void bin2bcd(unsigned char *p);
-static int bcd2bin(unsigned char bcd);
-static int mcdStatus(void);
-static void sendMcdCmd(int cmd, struct mcd_Play_msf *params);
-static int getMcdStatus(int timeout);
-static int GetQChannelInfo(struct mcd_Toc *qp);
-static int updateToc(void);
-static int GetDiskInfo(void);
-static int GetToc(void);
-static int getValue(unsigned char *result);
-static int mcd_open(struct cdrom_device_info *cdi, int purpose);
-static void mcd_release(struct cdrom_device_info *cdi);
-static int mcd_media_changed(struct cdrom_device_info *cdi, int disc_nr);
-static int mcd_tray_move(struct cdrom_device_info *cdi, int position);
-static DEFINE_SPINLOCK(mcd_spinlock);
-static int mcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
-                   void *arg);
-static int mcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
-
-static struct timer_list mcd_timer = TIMER_INITIALIZER(NULL, 0, 0);
-
-static struct cdrom_device_ops mcd_dops = {
-       .open                   = mcd_open,
-       .release                = mcd_release,
-       .drive_status           = mcd_drive_status,
-       .media_changed          = mcd_media_changed,
-       .tray_move              = mcd_tray_move,
-       .audio_ioctl            = mcd_audio_ioctl,
-       .capability             = CDC_OPEN_TRAY | CDC_MEDIA_CHANGED |
-                                 CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
-};
-
-static struct cdrom_device_info mcd_info = {
-       .ops            = &mcd_dops,
-       .speed          = 2,
-       .capacity       = 1,
-       .name           = "mcd",
-};
-
-static int mcd_block_open(struct inode *inode, struct file *file)
-{
-       return cdrom_open(&mcd_info, inode, file);
-}
-
-static int mcd_block_release(struct inode *inode, struct file *file)
-{
-       return cdrom_release(&mcd_info, file);
-}
-
-static int mcd_block_ioctl(struct inode *inode, struct file *file,
-                               unsigned cmd, unsigned long arg)
-{
-       return cdrom_ioctl(file, &mcd_info, inode, cmd, arg);
-}
-
-static int mcd_block_media_changed(struct gendisk *disk)
-{
-       return cdrom_media_changed(&mcd_info);
-}
-
-static struct block_device_operations mcd_bdops =
-{
-       .owner          = THIS_MODULE,
-       .open           = mcd_block_open,
-       .release        = mcd_block_release,
-       .ioctl          = mcd_block_ioctl,
-       .media_changed  = mcd_block_media_changed,
-};
-
-static struct gendisk *mcd_gendisk;
-
-static int __init mcd_setup(const char *str)
-{
-       int ints[9];
-
-       (void) get_options(str, ARRAY_SIZE(ints), ints);
-
-       if (ints[0] > 0)
-               mcd_port = ints[1];
-       if (ints[0] > 1)
-               mcd_irq = ints[2];
-       if (ints[0] > 2)
-               mitsumi_bug_93_wait = ints[3];
-
-       return 1;
-}
-
-__setup("mcd=", mcd_setup);
-
-#ifdef MODULE
-static int __init param_set_mcd(const char *val, struct kernel_param *kp)
-{
-       mcd_setup(val);
-       return 0;
-}
-module_param_call(mcd, param_set_mcd, NULL, NULL, 0);
-#endif
-
-static int mcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-{
-       return 0;
-}
-
-
-/*
- * Do a 'get status' command and get the result.  Only use from the top half
- * because it calls 'getMcdStatus' which sleeps.
- */
-
-static int statusCmd(void)
-{
-       int st = -1, retry;
-
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
-               /* send get-status cmd */
-               outb(MCMD_GET_STATUS, MCDPORT(0));
-
-               st = getMcdStatus(MCD_STATUS_DELAY);
-               if (st != -1)
-                       break;
-       }
-
-       return st;
-}
-
-
-/*
- * Send a 'Play' command and get the status.  Use only from the top half.
- */
-
-static int mcdPlay(struct mcd_Play_msf *arg)
-{
-       int retry, st = -1;
-
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
-               sendMcdCmd(MCMD_PLAY_READ, arg);
-               st = getMcdStatus(2 * MCD_STATUS_DELAY);
-               if (st != -1)
-                       break;
-       }
-
-       return st;
-}
-
-
-static int mcd_tray_move(struct cdrom_device_info *cdi, int position)
-{
-       int i;
-       if (position) {
-               /*  Eject */
-               /* all drives can at least stop! */
-               if (audioStatus == CDROM_AUDIO_PLAY) {
-                       outb(MCMD_STOP, MCDPORT(0));
-                       i = getMcdStatus(MCD_STATUS_DELAY);
-               }
-
-               audioStatus = CDROM_AUDIO_NO_STATUS;
-
-               outb(MCMD_EJECT, MCDPORT(0));
-               /*
-                * the status (i) shows failure on all but the FX drives.
-                * But nothing we can do about that in software!
-                * So just read the status and forget it. - Jon.
-                */
-               i = getMcdStatus(MCD_STATUS_DELAY);
-               return 0;
-       } else
-               return -EINVAL;
-}
-
-long msf2hsg(struct msf *mp)
-{
-       return bcd2bin(mp->frame) + bcd2bin(mp->sec) * 75 + bcd2bin(mp->min) * 
4500 - 150;
-}
-
-
-int mcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
-                   void *arg)
-{
-       int i, st;
-       struct mcd_Toc qInfo;
-       struct cdrom_ti *ti;
-       struct cdrom_tochdr *tocHdr;
-       struct cdrom_msf *msf;
-       struct cdrom_subchnl *subchnl;
-       struct cdrom_tocentry *entry;
-       struct mcd_Toc *tocPtr;
-       struct cdrom_volctrl *volctrl;
-
-       st = statusCmd();
-       if (st < 0)
-               return -EIO;
-
-       if (!tocUpToDate) {
-               i = updateToc();
-               if (i < 0)
-                       return i;       /* error reading TOC */
-       }
-
-       switch (cmd) {
-       case CDROMSTART:        /* Spin up the drive */
-               /* Don't think we can do this.  Even if we could,
-                * I think the drive times out and stops after a while
-                * anyway.  For now, ignore it.
-                */
-
-               return 0;
-
-       case CDROMSTOP: /* Spin down the drive */
-               outb(MCMD_STOP, MCDPORT(0));
-               i = getMcdStatus(MCD_STATUS_DELAY);
-
-               /* should we do anything if it fails? */
-
-               audioStatus = CDROM_AUDIO_NO_STATUS;
-               return 0;
-
-       case CDROMPAUSE:        /* Pause the drive */
-               if (audioStatus != CDROM_AUDIO_PLAY)
-                       return -EINVAL;
-
-               outb(MCMD_STOP, MCDPORT(0));
-               i = getMcdStatus(MCD_STATUS_DELAY);
-
-               if (GetQChannelInfo(&qInfo) < 0) {
-                       /* didn't get q channel info */
-
-                       audioStatus = CDROM_AUDIO_NO_STATUS;
-                       return 0;
-               }
-
-               mcd_Play.start = qInfo.diskTime;        /* remember restart 
point */
-
-               audioStatus = CDROM_AUDIO_PAUSED;
-               return 0;
-
-       case CDROMRESUME:       /* Play it again, Sam */
-               if (audioStatus != CDROM_AUDIO_PAUSED)
-                       return -EINVAL;
-
-               /* restart the drive at the saved position. */
-
-               i = mcdPlay(&mcd_Play);
-               if (i < 0) {
-                       audioStatus = CDROM_AUDIO_ERROR;
-                       return -EIO;
-               }
-
-               audioStatus = CDROM_AUDIO_PLAY;
-               return 0;
-
-       case CDROMPLAYTRKIND:   /* Play a track.  This currently ignores index. 
*/
-
-               ti = (struct cdrom_ti *) arg;
-
-               if (ti->cdti_trk0 < DiskInfo.first
-                   || ti->cdti_trk0 > DiskInfo.last
-                   || ti->cdti_trk1 < ti->cdti_trk0) {
-                       return -EINVAL;
-               }
-
-               if (ti->cdti_trk1 > DiskInfo.last)
-                       ti->cdti_trk1 = DiskInfo.last;
-
-               mcd_Play.start = Toc[ti->cdti_trk0].diskTime;
-               mcd_Play.end = Toc[ti->cdti_trk1 + 1].diskTime;
-
-#ifdef MCD_DEBUG
-               printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-                      mcd_Play.start.min, mcd_Play.start.sec,
-                      mcd_Play.start.frame, mcd_Play.end.min,
-                      mcd_Play.end.sec, mcd_Play.end.frame);
-#endif
-
-               i = mcdPlay(&mcd_Play);
-               if (i < 0) {
-                       audioStatus = CDROM_AUDIO_ERROR;
-                       return -EIO;
-               }
-
-               audioStatus = CDROM_AUDIO_PLAY;
-               return 0;
-
-       case CDROMPLAYMSF:      /* Play starting at the given MSF address. */
-
-               if (audioStatus == CDROM_AUDIO_PLAY) {
-                       outb(MCMD_STOP, MCDPORT(0));
-                       i = getMcdStatus(MCD_STATUS_DELAY);
-                       audioStatus = CDROM_AUDIO_NO_STATUS;
-               }
-
-               msf = (struct cdrom_msf *) arg;
-
-               /* convert to bcd */
-
-               bin2bcd(&msf->cdmsf_min0);
-               bin2bcd(&msf->cdmsf_sec0);
-               bin2bcd(&msf->cdmsf_frame0);
-               bin2bcd(&msf->cdmsf_min1);
-               bin2bcd(&msf->cdmsf_sec1);
-               bin2bcd(&msf->cdmsf_frame1);
-
-               mcd_Play.start.min = msf->cdmsf_min0;
-               mcd_Play.start.sec = msf->cdmsf_sec0;
-               mcd_Play.start.frame = msf->cdmsf_frame0;
-               mcd_Play.end.min = msf->cdmsf_min1;
-               mcd_Play.end.sec = msf->cdmsf_sec1;
-               mcd_Play.end.frame = msf->cdmsf_frame1;
-
-#ifdef MCD_DEBUG
-               printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-                      mcd_Play.start.min, mcd_Play.start.sec,
-                      mcd_Play.start.frame, mcd_Play.end.min,
-                      mcd_Play.end.sec, mcd_Play.end.frame);
-#endif
-
-               i = mcdPlay(&mcd_Play);
-               if (i < 0) {
-                       audioStatus = CDROM_AUDIO_ERROR;
-                       return -EIO;
-               }
-
-               audioStatus = CDROM_AUDIO_PLAY;
-               return 0;
-
-       case CDROMREADTOCHDR:   /* Read the table of contents header */
-               tocHdr = (struct cdrom_tochdr *) arg;
-               tocHdr->cdth_trk0 = DiskInfo.first;
-               tocHdr->cdth_trk1 = DiskInfo.last;
-               return 0;
-
-       case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
-               entry = (struct cdrom_tocentry *) arg;
-               if (entry->cdte_track == CDROM_LEADOUT)
-                       tocPtr = &Toc[DiskInfo.last - DiskInfo.first + 1];
-
-               else if (entry->cdte_track > DiskInfo.last
-                        || entry->cdte_track < DiskInfo.first)
-                       return -EINVAL;
-
-               else
-                       tocPtr = &Toc[entry->cdte_track];
-
-               entry->cdte_adr = tocPtr->ctrl_addr;
-               entry->cdte_ctrl = tocPtr->ctrl_addr >> 4;
-
-               if (entry->cdte_format == CDROM_LBA)
-                       entry->cdte_addr.lba = msf2hsg(&tocPtr->diskTime);
-
-               else if (entry->cdte_format == CDROM_MSF) {
-                       entry->cdte_addr.msf.minute =
-                           bcd2bin(tocPtr->diskTime.min);
-                       entry->cdte_addr.msf.second =
-                           bcd2bin(tocPtr->diskTime.sec);
-                       entry->cdte_addr.msf.frame =
-                           bcd2bin(tocPtr->diskTime.frame);
-               }
-
-               else
-                       return -EINVAL;
-
-               return 0;
-
-       case CDROMSUBCHNL:      /* Get subchannel info */
-
-               subchnl = (struct cdrom_subchnl *) arg;
-               if (GetQChannelInfo(&qInfo) < 0)
-                       return -EIO;
-
-               subchnl->cdsc_audiostatus = audioStatus;
-               subchnl->cdsc_adr = qInfo.ctrl_addr;
-               subchnl->cdsc_ctrl = qInfo.ctrl_addr >> 4;
-               subchnl->cdsc_trk = bcd2bin(qInfo.track);
-               subchnl->cdsc_ind = bcd2bin(qInfo.pointIndex);
-               subchnl->cdsc_absaddr.msf.minute = bcd2bin(qInfo.diskTime.min);
-               subchnl->cdsc_absaddr.msf.second = bcd2bin(qInfo.diskTime.sec);
-               subchnl->cdsc_absaddr.msf.frame  = 
bcd2bin(qInfo.diskTime.frame);
-               subchnl->cdsc_reladdr.msf.minute = bcd2bin(qInfo.trackTime.min);
-               subchnl->cdsc_reladdr.msf.second = bcd2bin(qInfo.trackTime.sec);
-               subchnl->cdsc_reladdr.msf.frame  = 
bcd2bin(qInfo.trackTime.frame);
-               return (0);
-
-       case CDROMVOLCTRL:      /* Volume control */
-               volctrl = (struct cdrom_volctrl *) arg;
-               outb(MCMD_SET_VOLUME, MCDPORT(0));
-               outb(volctrl->channel0, MCDPORT(0));
-               outb(255, MCDPORT(0));
-               outb(volctrl->channel1, MCDPORT(0));
-               outb(255, MCDPORT(0));
-
-               i = getMcdStatus(MCD_STATUS_DELAY);
-               if (i < 0)
-                       return -EIO;
-
-               {
-                       char a, b, c, d;
-
-                       getValue(&a);
-                       getValue(&b);
-                       getValue(&c);
-                       getValue(&d);
-               }
-
-               return 0;
-
-       default:
-               return -EINVAL;
-       }
-}
-
-/*
- * Take care of the different block sizes between cdrom and Linux.
- * When Linux gets variable block sizes this will probably go away.
- */
-
-static void mcd_transfer(void)
-{
-       if (!current_valid())
-               return;
-
-       while (CURRENT->nr_sectors) {
-               int bn = CURRENT->sector / 4;
-               int i;
-               for (i = 0; i < MCD_BUF_SIZ && mcd_buf_bn[i] != bn; ++i)
-                       ;
-               if (i < MCD_BUF_SIZ) {
-                       int offs =(i * 4 + (CURRENT->sector & 3)) * 512;
-                       int nr_sectors = 4 - (CURRENT->sector & 3);
-                       if (mcd_buf_out != i) {
-                               mcd_buf_out = i;
-                               if (mcd_buf_bn[i] != bn) {
-                                       mcd_buf_out = -1;
-                                       continue;
-                               }
-                       }
-                       if (nr_sectors > CURRENT->nr_sectors)
-                               nr_sectors = CURRENT->nr_sectors;
-                       memcpy(CURRENT->buffer, mcd_buf + offs, nr_sectors * 
512);
-                       CURRENT->nr_sectors -= nr_sectors;
-                       CURRENT->sector += nr_sectors;
-                       CURRENT->buffer += nr_sectors * 512;
-               } else {
-                       mcd_buf_out = -1;
-                       break;
-               }
-       }
-}
-
-
-/*
- * We only seem to get interrupts after an error.
- * Just take the interrupt and clear out the status reg.
- */
-
-static irqreturn_t mcd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-       int st;
-
-       st = inb(MCDPORT(1)) & 0xFF;
-       test1(printk("<int1-%02X>", st));
-       if (!(st & MFL_STATUS)) {
-               st = inb(MCDPORT(0)) & 0xFF;
-               test1(printk("<int0-%02X>", st));
-               if ((st & 0xFF) != 0xFF)
-                       mcd_error = st ? st & 0xFF : -1;
-       }
-       return IRQ_HANDLED;
-}
-
-
-static void do_mcd_request(request_queue_t * q)
-{
-       test2(printk(" do_mcd_request(%ld+%ld)\n", CURRENT->sector,
-              CURRENT->nr_sectors));
-
-               mcd_transfer_is_active = 1;
-       while (current_valid()) {
-               mcd_transfer();
-               if (CURRENT->nr_sectors == 0) {
-                       end_request(CURRENT, 1);
-               } else {
-                       mcd_buf_out = -1;       /* Want to read a block not in 
buffer */
-                       if (mcd_state == MCD_S_IDLE) {
-                               if (!tocUpToDate) {
-                                       if (updateToc() < 0) {
-                                               while (current_valid())
-                                                       end_request(CURRENT, 0);
-                                               break;
-                                       }
-                               }
-                               mcd_state = MCD_S_START;
-                               McdTries = 5;
-                               mcd_timer.function = mcd_poll;
-                               mod_timer(&mcd_timer, jiffies + 1);
-                       }
-                       break;
-               }
-       }
-       mcd_transfer_is_active = 0;
-       test2(printk(" do_mcd_request ends\n"));
-}
-
-
-
-static void mcd_poll(unsigned long dummy)
-{
-       int st;
-
-
-       if (mcd_error) {
-               if (mcd_error & 0xA5) {
-                       printk(KERN_ERR "mcd: I/O error 0x%02x", mcd_error);
-                       if (mcd_error & 0x80)
-                               printk(" (Door open)");
-                       if (mcd_error & 0x20)
-                               printk(" (Disk changed)");
-                       if (mcd_error & 0x04) {
-                               printk(" (Read error)");        /* Bitch about 
the problem. */
-
-                               /* Time to get fancy! If at 2x speed and 1 
error, drop to 1x speed! */
-                               /* Interesting how it STAYS at 
MCD_RETRY_ATTEMPTS on first error! */
-                               /* But I find that rather HANDY!!! */
-                               /* Neat! it REALLY WORKS on those LOW QUALITY 
CD's!!! Smile! :) */
-                               /* AJK [06/17/95] */
-
-                               /* Slap the CD down to single speed! */
-                               if (mcdDouble == 1
-                                   && McdTries == MCD_RETRY_ATTEMPTS
-                                   && MCMD_DATA_READ == MCMD_2X_READ) {
-                                       MCMD_DATA_READ = MCMD_PLAY_READ;        
/* Uhhh, Ummmm, muhuh-huh! */
-                                       mcd1xhold = SINGLE_HOLD_SECTORS;        
/* Hey Beavis! */
-                                       printk(" Speed now 1x");        /* Pull 
my finger! */
-                               }
-                       }
-                       printk("\n");
-                       mcd_invalidate_buffers();
-#ifdef WARN_IF_READ_FAILURE
-                       if (McdTries == MCD_RETRY_ATTEMPTS)
-                               printk(KERN_ERR "mcd: read of block %d 
failed\n",
-                                      mcd_next_bn);
-#endif
-                       if (!McdTries--) {
-                               /* Nuts! This cd is ready for recycling! */
-                               /* When WAS the last time YOU cleaned it 
CORRECTLY?! */
-                               printk(KERN_ERR "mcd: read of block %d failed, 
giving up\n",
-                                    mcd_next_bn);
-                               if (mcd_transfer_is_active) {
-                                       McdTries = 0;
-                                       goto ret;
-                               }
-                               if (current_valid())
-                                       end_request(CURRENT, 0);
-                               McdTries = MCD_RETRY_ATTEMPTS;
-                       }
-               }
-               mcd_error = 0;
-               mcd_state = MCD_S_STOP;
-       }
-       /* Switch back to Double speed if enough GOOD sectors were read! */
-
-       /* Are we a double speed with a crappy CD?! */
-       if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS
-           && MCMD_DATA_READ == MCMD_PLAY_READ) {
-               /* We ARE a double speed and we ARE bitching! */
-               if (mcd1xhold == 0) {   /* Okay, Like are we STILL at single 
speed? *//* We need to switch back to double speed now... */
-                       MCMD_DATA_READ = MCMD_2X_READ;  /* Uhhh... BACK You GO! 
*/
-                       printk(KERN_INFO "mcd: Switching back to 2X speed!\n"); 
/* Tell 'em! */
-               } else
-                       mcd1xhold--;    /* No?! Count down the good reads some 
more... */
-               /* and try, try again! */
-       }
-
-immediately:
-       switch (mcd_state) {
-       case MCD_S_IDLE:
-               test3(printk("MCD_S_IDLE\n"));
-               goto out;
-
-       case MCD_S_START:
-               test3(printk("MCD_S_START\n"));
-               outb(MCMD_GET_STATUS, MCDPORT(0));
-               mcd_state = mcd_mode == 1 ? MCD_S_READ : MCD_S_MODE;
-               McdTimeout = 3000;
-               break;
-
-       case MCD_S_MODE:
-               test3(printk("MCD_S_MODE\n"));
-               if ((st = mcdStatus()) != -1) {
-                       if (st & MST_DSK_CHG) {
-                               mcdDiskChanged = 1;
-                               tocUpToDate = 0;
-                               mcd_invalidate_buffers();
-                       }
-
-set_mode_immediately:
-                       if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
-                               mcdDiskChanged = 1;
-                               tocUpToDate = 0;
-                               if (mcd_transfer_is_active) {
-                                       mcd_state = MCD_S_START;
-                                       goto immediately;
-                               }
-                               printk(KERN_INFO);
-                               printk((st & MST_DOOR_OPEN) ?
-                                      "mcd: door open\n" :
-                                      "mcd: disk removed\n");
-                               mcd_state = MCD_S_IDLE;
-                               while (current_valid())
-                                       end_request(CURRENT, 0);
-                               goto out;
-                       }
-                       outb(MCMD_SET_MODE, MCDPORT(0));
-                       outb(1, MCDPORT(0));
-                       mcd_mode = 1;
-                       mcd_state = MCD_S_READ;
-                       McdTimeout = 3000;
-               }
-               break;
-
-       case MCD_S_READ:
-               test3(printk("MCD_S_READ\n"));
-               if ((st = mcdStatus()) != -1) {
-                       if (st & MST_DSK_CHG) {
-                               mcdDiskChanged = 1;
-                               tocUpToDate = 0;
-                               mcd_invalidate_buffers();
-                       }
-
-read_immediately:
-                       if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
-                               mcdDiskChanged = 1;
-                               tocUpToDate = 0;
-                               if (mcd_transfer_is_active) {
-                                       mcd_state = MCD_S_START;
-                                       goto immediately;
-                               }
-                               printk(KERN_INFO);
-                               printk((st & MST_DOOR_OPEN) ?
-                                      "mcd: door open\n" :
-                                      "mcd: disk removed\n");
-                               mcd_state = MCD_S_IDLE;
-                               while (current_valid())
-                                       end_request(CURRENT, 0);
-                               goto out;
-                       }
-
-                       if (current_valid()) {
-                               struct mcd_Play_msf msf;
-                               mcd_next_bn = CURRENT->sector / 4;
-                               hsg2msf(mcd_next_bn, &msf.start);
-                               msf.end.min = ~0;
-                               msf.end.sec = ~0;
-                               msf.end.frame = ~0;
-                               sendMcdCmd(MCMD_DATA_READ, &msf);
-                               mcd_state = MCD_S_DATA;
-                               McdTimeout = READ_TIMEOUT;
-                       } else {
-                               mcd_state = MCD_S_STOP;
-                               goto immediately;
-                       }
-
-               }
-               break;
-
-       case MCD_S_DATA:
-               test3(printk("MCD_S_DATA\n"));
-               st = inb(MCDPORT(1)) & (MFL_STATUSorDATA);
-data_immediately:
-               test5(printk("Status %02x\n", st))
-               switch (st) {
-               case MFL_DATA:
-#ifdef WARN_IF_READ_FAILURE
-                       if (McdTries == 5)
-                               printk(KERN_WARNING "mcd: read of block %d 
failed\n",
-                                      mcd_next_bn);
-#endif
-                       if (!McdTries--) {
-                               printk(KERN_ERR "mcd: read of block %d failed, 
giving up\n", mcd_next_bn);
-                               if (mcd_transfer_is_active) {
-                                       McdTries = 0;
-                                       break;
-                               }
-                               if (current_valid())
-                                       end_request(CURRENT, 0);
-                               McdTries = 5;
-                       }
-                       mcd_state = MCD_S_START;
-                       McdTimeout = READ_TIMEOUT;
-                       goto immediately;
-
-               case MFL_STATUSorDATA:
-                       break;
-
-               default:
-                       McdTries = 5;
-                       if (!current_valid() && mcd_buf_in == mcd_buf_out) {
-                               mcd_state = MCD_S_STOP;
-                               goto immediately;
-                       }
-                       mcd_buf_bn[mcd_buf_in] = -1;
-                       insb(MCDPORT(0), mcd_buf + 2048 * mcd_buf_in,
-                                 2048);
-                       mcd_buf_bn[mcd_buf_in] = mcd_next_bn++;
-                       if (mcd_buf_out == -1)
-                               mcd_buf_out = mcd_buf_in;
-                       mcd_buf_in = mcd_buf_in + 1 == MCD_BUF_SIZ ? 0 : 
mcd_buf_in + 1;
-                       if (!mcd_transfer_is_active) {
-                               while (current_valid()) {
-                                       mcd_transfer();
-                                       if (CURRENT->nr_sectors == 0)
-                                               end_request(CURRENT, 1);
-                                       else
-                                               break;
-                               }
-                       }
-
-                       if (current_valid()
-                           && (CURRENT->sector / 4 < mcd_next_bn ||
-                               CURRENT->sector / 4 > mcd_next_bn + 16)) {
-                               mcd_state = MCD_S_STOP;
-                               goto immediately;
-                       }
-                       McdTimeout = READ_TIMEOUT;
-                       {
-                               int count = QUICK_LOOP_COUNT;
-                               while (count--) {
-                                       QUICK_LOOP_DELAY;
-                                       if ((st = (inb(MCDPORT(1))) & 
(MFL_STATUSorDATA)) != (MFL_STATUSorDATA)) {
-                                               test4(printk(" %d ", 
QUICK_LOOP_COUNT - count));
-                                               goto data_immediately;
-                                       }
-                               }
-                               test4(printk("ended "));
-                       }
-                       break;
-               }
-               break;
-
-       case MCD_S_STOP:
-               test3(printk("MCD_S_STOP\n"));
-               if (!mitsumi_bug_93_wait)
-                       goto do_not_work_around_mitsumi_bug_93_1;
-
-               McdTimeout = mitsumi_bug_93_wait;
-               mcd_state = 9 + 3 + 1;
-               break;
-
-       case 9 + 3 + 1:
-               if (McdTimeout)
-                       break;
-
-do_not_work_around_mitsumi_bug_93_1:
-               outb(MCMD_STOP, MCDPORT(0));
-               if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
-                       int i = 4096;
-                       do {
-                               inb(MCDPORT(0));
-                       } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == 
MFL_STATUS && --i);
-                       outb(MCMD_STOP, MCDPORT(0));
-                       if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) 
{
-                               i = 4096;
-                               do {
-                                       inb(MCDPORT(0));
-                               } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) 
== MFL_STATUS && --i);
-                               outb(MCMD_STOP, MCDPORT(0));
-                       }
-               }
-
-               mcd_state = MCD_S_STOPPING;
-               McdTimeout = 1000;
-               break;
-
-       case MCD_S_STOPPING:
-               test3(printk("MCD_S_STOPPING\n"));
-               if ((st = mcdStatus()) == -1 && McdTimeout)
-                       break;
-
-               if ((st != -1) && (st & MST_DSK_CHG)) {
-                       mcdDiskChanged = 1;
-                       tocUpToDate = 0;
-                       mcd_invalidate_buffers();
-               }
-               if (!mitsumi_bug_93_wait)
-                       goto do_not_work_around_mitsumi_bug_93_2;
-
-               McdTimeout = mitsumi_bug_93_wait;
-               mcd_state = 9 + 3 + 2;
-               break;
-
-       case 9 + 3 + 2:
-               if (McdTimeout)
-                       break;
-               st = -1;
-
-do_not_work_around_mitsumi_bug_93_2:
-               test3(printk("CURRENT_VALID %d mcd_mode %d\n", current_valid(),
-                           mcd_mode));
-               if (current_valid()) {
-                       if (st != -1) {
-                               if (mcd_mode == 1)
-                                       goto read_immediately;
-                               else
-                                       goto set_mode_immediately;
-                       } else {
-                               mcd_state = MCD_S_START;
-                               McdTimeout = 1;
-                       }
-               } else {
-                       mcd_state = MCD_S_IDLE;
-                       goto out;
-               }
-               break;
-       default:
-               printk(KERN_ERR "mcd: invalid state %d\n", mcd_state);
-               goto out;
-       }
-ret:
-       if (!McdTimeout--) {
-               printk(KERN_WARNING "mcd: timeout in state %d\n", mcd_state);
-               mcd_state = MCD_S_STOP;
-       }
-       mcd_timer.function = mcd_poll;
-       mod_timer(&mcd_timer, jiffies + 1);
-out:
-       return;
-}
-
-static void mcd_invalidate_buffers(void)
-{
-       int i;
-       for (i = 0; i < MCD_BUF_SIZ; ++i)
-               mcd_buf_bn[i] = -1;
-       mcd_buf_out = -1;
-}
-
-/*
- * Open the device special file.  Check that a disk is in.
- */
-static int mcd_open(struct cdrom_device_info *cdi, int purpose)
-{
-       int st, count = 0;
-       if (mcdPresent == 0)
-               return -ENXIO;  /* no hardware */
-
-       if (mcd_open_count || mcd_state != MCD_S_IDLE)
-               goto bump_count;
-
-       mcd_invalidate_buffers();
-       do {
-               st = statusCmd();       /* check drive status */
-               if (st == -1)
-                       goto err_out;   /* drive doesn't respond */
-               if ((st & MST_READY) == 0)      /* no disk? wait a sec... */
-                       msleep(1000);
-
-       } while (((st & MST_READY) == 0) && count++ < MCD_RETRY_ATTEMPTS);
-
-       if (updateToc() < 0)
-               goto err_out;
-
-bump_count:
-       ++mcd_open_count;
-       return 0;
-
-err_out:
-       return -EIO;
-}
-
-
-/*
- * On close, we flush all mcd blocks from the buffer cache.
- */
-static void mcd_release(struct cdrom_device_info *cdi)
-{
-       if (!--mcd_open_count) {
-               mcd_invalidate_buffers();
-       }
-}
-
-/*
- * Test for presence of drive and initialize it.  Called at boot time.
- */
-
-int __init mcd_init(void)
-{
-       struct gendisk *disk = alloc_disk(1);
-       int count;
-       unsigned char result[3];
-       char msg[80];
-
-       if (!disk) {
-               printk(KERN_INFO "mcd: can't allocated disk.\n");
-               return -ENOMEM;
-       }
-       if (mcd_port <= 0 || mcd_irq <= 0) {
-               printk(KERN_INFO "mcd: not probing.\n");
-               put_disk(disk);
-               return -EIO;
-       }
-       if (register_blkdev(MAJOR_NR, "mcd")) {
-               put_disk(disk);
-               return -EIO;
-       }
-       if (!request_region(mcd_port, 4, "mcd")) {
-               printk(KERN_ERR "mcd: Initialization failed, I/O port (%X) 
already in use\n", mcd_port);
-               goto out_region;
-       }
-
-       mcd_queue = blk_init_queue(do_mcd_request, &mcd_spinlock);
-       if (!mcd_queue)
-               goto out_queue;
-
-       /* check for card */
-
-       outb(0, MCDPORT(1));    /* send reset */
-       for (count = 0; count < 2000000; count++)
-               (void) inb(MCDPORT(1)); /* delay a bit */
-
-       outb(0x40, MCDPORT(0)); /* send get-stat cmd */
-       for (count = 0; count < 2000000; count++)
-               if (!(inb(MCDPORT(1)) & MFL_STATUS))
-                       break;
-
-       if (count >= 2000000) {
-               printk(KERN_INFO "mcd: initialisation failed - No mcd device at 
0x%x irq %d\n",
-                      mcd_port, mcd_irq);
-               goto out_probe;
-       }
-       count = inb(MCDPORT(0));        /* pick up the status */
-
-       outb(MCMD_GET_VERSION, MCDPORT(0));
-       for (count = 0; count < 3; count++)
-               if (getValue(result + count)) {
-                       printk(KERN_ERR "mcd: mitsumi get version failed at 
0x%x\n",
-                              mcd_port);
-                       goto out_probe;
-               }
-
-       if (result[0] == result[1] && result[1] == result[2])
-               goto out_probe;
-
-       mcdVersion = result[2];
-
-       if (mcdVersion >= 4)
-               outb(4, MCDPORT(2));    /* magic happens */
-
-       /* don't get the IRQ until we know for sure the drive is there */
-
-       if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", 
NULL)) {
-               printk(KERN_ERR "mcd: Unable to get IRQ%d for Mitsumi 
CD-ROM\n", mcd_irq);
-               goto out_probe;
-       }
-
-       if (result[1] == 'D') {
-               MCMD_DATA_READ = MCMD_2X_READ;
-               /* Added flag to drop to 1x speed if too many errors */
-               mcdDouble = 1;
-       } else
-               mcd_info.speed = 1;
-       sprintf(msg, " mcd: Mitsumi %s Speed CD-ROM at port=0x%x,"
-               " irq=%d\n", mcd_info.speed == 1 ? "Single" : "Double",
-               mcd_port, mcd_irq);
-
-       outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
-       outb(0x02, MCDPORT(0));
-       outb(0x00, MCDPORT(0));
-       getValue(result);
-
-       outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
-       outb(0x10, MCDPORT(0));
-       outb(0x04, MCDPORT(0));
-       getValue(result);
-
-       mcd_invalidate_buffers();
-       mcdPresent = 1;
-
-       disk->major = MAJOR_NR;
-       disk->first_minor = 0;
-       sprintf(disk->disk_name, "mcd");
-       disk->fops = &mcd_bdops;
-       disk->flags = GENHD_FL_CD;
-       mcd_gendisk = disk;
-
-       if (register_cdrom(&mcd_info) != 0) {
-               printk(KERN_ERR "mcd: Unable to register Mitsumi CD-ROM.\n");
-               goto out_cdrom;
-       }
-       disk->queue = mcd_queue;
-       add_disk(disk);
-       printk(msg);
-       return 0;
-
-out_cdrom:
-       free_irq(mcd_irq, NULL);
-out_queue:
-       release_region(mcd_port, 4);
-out_probe:
-       blk_cleanup_queue(mcd_queue);
-out_region:
-       unregister_blkdev(MAJOR_NR, "mcd");
-       put_disk(disk);
-       return -EIO;
-}
-
-
-static void hsg2msf(long hsg, struct msf *msf)
-{
-       hsg += 150;
-       msf->min = hsg / 4500;
-       hsg %= 4500;
-       msf->sec = hsg / 75;
-       msf->frame = hsg % 75;
-
-       bin2bcd(&msf->min);     /* convert to BCD */
-       bin2bcd(&msf->sec);
-       bin2bcd(&msf->frame);
-}
-
-
-static void bin2bcd(unsigned char *p)
-{
-       int u, t;
-
-       u = *p % 10;
-       t = *p / 10;
-       *p = u | (t << 4);
-}
-
-static int bcd2bin(unsigned char bcd)
-{
-       return (bcd >> 4) * 10 + (bcd & 0xF);
-}
-
-
-/*
- * See if a status is ready from the drive and return it
- * if it is ready.
- */
-
-static int mcdStatus(void)
-{
-       int i;
-       int st;
-
-       st = inb(MCDPORT(1)) & MFL_STATUS;
-       if (!st) {
-               i = inb(MCDPORT(0)) & 0xFF;
-               return i;
-       } else
-               return -1;
-}
-
-
-/*
- * Send a play or read command to the drive
- */
-
-static void sendMcdCmd(int cmd, struct mcd_Play_msf *params)
-{
-       outb(cmd, MCDPORT(0));
-       outb(params->start.min, MCDPORT(0));
-       outb(params->start.sec, MCDPORT(0));
-       outb(params->start.frame, MCDPORT(0));
-       outb(params->end.min, MCDPORT(0));
-       outb(params->end.sec, MCDPORT(0));
-       outb(params->end.frame, MCDPORT(0));
-}
-
-
-/*
- * Timer interrupt routine to test for status ready from the drive.
- * (see the next routine)
- */
-
-static void mcdStatTimer(unsigned long dummy)
-{
-       if (!(inb(MCDPORT(1)) & MFL_STATUS)) {
-               wake_up(&mcd_waitq);
-               return;
-       }
-
-       McdTimeout--;
-       if (McdTimeout <= 0) {
-               wake_up(&mcd_waitq);
-               return;
-       }
-       mcd_timer.function = mcdStatTimer;
-       mod_timer(&mcd_timer, jiffies + 1);
-}
-
-
-/*
- * Wait for a status to be returned from the drive.  The actual test
- * (see routine above) is done by the timer interrupt to avoid
- * excessive rescheduling.
- */
-
-static int getMcdStatus(int timeout)
-{
-       int st;
-
-       McdTimeout = timeout;
-       mcd_timer.function = mcdStatTimer;
-       mod_timer(&mcd_timer, jiffies + 1);
-       sleep_on(&mcd_waitq);
-       if (McdTimeout <= 0)
-               return -1;
-
-       st = inb(MCDPORT(0)) & 0xFF;
-       if (st == 0xFF)
-               return -1;
-
-       if ((st & MST_BUSY) == 0 && audioStatus == CDROM_AUDIO_PLAY)
-               /* XXX might be an error? look at q-channel? */
-               audioStatus = CDROM_AUDIO_COMPLETED;
-
-       if (st & MST_DSK_CHG) {
-               mcdDiskChanged = 1;
-               tocUpToDate = 0;
-               audioStatus = CDROM_AUDIO_NO_STATUS;
-       }
-
-       return st;
-}
-
-
-/* gives current state of the drive This function is quite unreliable, 
-   and should probably be rewritten by someone, eventually... */
-
-int mcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
-{
-       int st;
-
-       st = statusCmd();       /* check drive status */
-       if (st == -1)
-               return -EIO;    /* drive doesn't respond */
-       if ((st & MST_READY))
-               return CDS_DISC_OK;
-       if ((st & MST_DOOR_OPEN))
-               return CDS_TRAY_OPEN;
-       if ((st & MST_DSK_CHG))
-               return CDS_NO_DISC;
-       if ((st & MST_BUSY))
-               return CDS_DRIVE_NOT_READY;
-       return -EIO;
-}
-
-
-/*
- * Read a value from the drive.
- */
-
-static int getValue(unsigned char *result)
-{
-       int count;
-       int s;
-
-       for (count = 0; count < 2000; count++)
-               if (!(inb(MCDPORT(1)) & MFL_STATUS))
-                       break;
-
-       if (count >= 2000) {
-               printk("mcd: getValue timeout\n");
-               return -1;
-       }
-
-       s = inb(MCDPORT(0)) & 0xFF;
-       *result = (unsigned char) s;
-       return 0;
-}
-
-/*
- * Read the current Q-channel info.  Also used for reading the
- * table of contents.
- */
-
-int GetQChannelInfo(struct mcd_Toc *qp)
-{
-       unsigned char notUsed;
-       int retry;
-
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
-               outb(MCMD_GET_Q_CHANNEL, MCDPORT(0));
-               if (getMcdStatus(MCD_STATUS_DELAY) != -1)
-                       break;
-       }
-
-       if (retry >= MCD_RETRY_ATTEMPTS)
-               return -1;
-
-       if (getValue(&qp->ctrl_addr) < 0)
-               return -1;
-       if (getValue(&qp->track) < 0)
-               return -1;
-       if (getValue(&qp->pointIndex) < 0)
-               return -1;
-       if (getValue(&qp->trackTime.min) < 0)
-               return -1;
-       if (getValue(&qp->trackTime.sec) < 0)
-               return -1;
-       if (getValue(&qp->trackTime.frame) < 0)
-               return -1;
-       if (getValue(&notUsed) < 0)
-               return -1;
-       if (getValue(&qp->diskTime.min) < 0)
-               return -1;
-       if (getValue(&qp->diskTime.sec) < 0)
-               return -1;
-       if (getValue(&qp->diskTime.frame) < 0)
-               return -1;
-
-       return 0;
-}
-
-/*
- * Read the table of contents (TOC) and TOC header if necessary
- */
-
-static int updateToc(void)
-{
-       if (tocUpToDate)
-               return 0;
-
-       if (GetDiskInfo() < 0)
-               return -EIO;
-
-       if (GetToc() < 0)
-               return -EIO;
-
-       tocUpToDate = 1;
-       return 0;
-}
-
-/*
- * Read the table of contents header
- */
-
-static int GetDiskInfo(void)
-{
-       int retry;
-
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
-               outb(MCMD_GET_DISK_INFO, MCDPORT(0));
-               if (getMcdStatus(MCD_STATUS_DELAY) != -1)
-                       break;
-       }
-
-       if (retry >= MCD_RETRY_ATTEMPTS)
-               return -1;
-
-       if (getValue(&DiskInfo.first) < 0)
-               return -1;
-       if (getValue(&DiskInfo.last) < 0)
-               return -1;
-
-       DiskInfo.first = bcd2bin(DiskInfo.first);
-       DiskInfo.last = bcd2bin(DiskInfo.last);
-
-#ifdef MCD_DEBUG
-       printk
-           ("Disk Info: first %d last %d length %02x:%02x.%02x first 
%02x:%02x.%02x\n",
-            DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
-            DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
-            DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
-            DiskInfo.firstTrack.frame);
-#endif
-
-       if (getValue(&DiskInfo.diskLength.min) < 0)
-               return -1;
-       if (getValue(&DiskInfo.diskLength.sec) < 0)
-               return -1;
-       if (getValue(&DiskInfo.diskLength.frame) < 0)
-               return -1;
-       if (getValue(&DiskInfo.firstTrack.min) < 0)
-               return -1;
-       if (getValue(&DiskInfo.firstTrack.sec) < 0)
-               return -1;
-       if (getValue(&DiskInfo.firstTrack.frame) < 0)
-               return -1;
-
-       return 0;
-}
-
-/*
- * Read the table of contents (TOC)
- */
-
-static int GetToc(void)
-{
-       int i, px;
-       int limit;
-       int retry;
-       struct mcd_Toc qInfo;
-
-       for (i = 0; i < MAX_TRACKS; i++)
-               Toc[i].pointIndex = 0;
-
-       i = DiskInfo.last + 3;
-
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
-               outb(MCMD_STOP, MCDPORT(0));
-               if (getMcdStatus(MCD_STATUS_DELAY) != -1)
-                       break;
-       }
-
-       if (retry >= MCD_RETRY_ATTEMPTS)
-               return -1;
-
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
-               outb(MCMD_SET_MODE, MCDPORT(0));
-               outb(0x05, MCDPORT(0)); /* mode: toc */
-               mcd_mode = 0x05;
-               if (getMcdStatus(MCD_STATUS_DELAY) != -1)
-                       break;
-       }
-
-       if (retry >= MCD_RETRY_ATTEMPTS)
-               return -1;
-
-       for (limit = 300; limit > 0; limit--) {
-               if (GetQChannelInfo(&qInfo) < 0)
-                       break;
-
-               px = bcd2bin(qInfo.pointIndex);
-               if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
-                       if (Toc[px].pointIndex == 0) {
-                               Toc[px] = qInfo;
-                               i--;
-                       }
-
-               if (i <= 0)
-                       break;
-       }
-
-       Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
-
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
-               outb(MCMD_SET_MODE, MCDPORT(0));
-               outb(0x01, MCDPORT(0));
-               mcd_mode = 1;
-               if (getMcdStatus(MCD_STATUS_DELAY) != -1)
-                       break;
-       }
-
-#ifdef MCD_DEBUG
-       for (i = 1; i <= DiskInfo.last; i++)
-               printk
-                   ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X   
 %02X:%02X.%02X\n",
-                    i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-                    Toc[i].trackTime.min, Toc[i].trackTime.sec,
-                    Toc[i].trackTime.frame, Toc[i].diskTime.min,
-                    Toc[i].diskTime.sec, Toc[i].diskTime.frame);
-       for (i = 100; i < 103; i++)
-               printk
-                   ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X   
 %02X:%02X.%02X\n",
-                    i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-                    Toc[i].trackTime.min, Toc[i].trackTime.sec,
-                    Toc[i].trackTime.frame, Toc[i].diskTime.min,
-                    Toc[i].diskTime.sec, Toc[i].diskTime.frame);
-#endif
-
-       return limit > 0 ? 0 : -1;
-}
-
-void __exit mcd_exit(void)
-{
-       del_gendisk(mcd_gendisk);
-       put_disk(mcd_gendisk);
-       if (unregister_cdrom(&mcd_info)) {
-               printk(KERN_WARNING "Can't unregister cdrom mcd\n");
-               return;
-       }
-       free_irq(mcd_irq, NULL);
-       release_region(mcd_port, 4);
-       if (unregister_blkdev(MAJOR_NR, "mcd")) {
-               printk(KERN_WARNING "Can't unregister major mcd\n");
-               return;
-       }
-       blk_cleanup_queue(mcd_queue);
-       del_timer_sync(&mcd_timer);
-}
-
-#ifdef MODULE
-module_init(mcd_init);
-#endif
-module_exit(mcd_exit);
-
-MODULE_AUTHOR("Martin Harriss");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(MITSUMI_CDROM_MAJOR);

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to