From: Adrian Bunk As described in my patch that marked this obsolete driver as BROKEN, this patch completely removes it. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton --- /dev/null | 1675 --------------------------------------- 25-akpm/Documentation/cdrom/mcdx | 17 25-akpm/drivers/cdrom/Kconfig | 56 - 25-akpm/drivers/cdrom/Makefile | 1 4 files changed, 6 insertions(+), 1743 deletions(-) diff -L Documentation/cdrom/mcd -puN Documentation/cdrom/mcd~kill-drivers-cdrom-mcdc /dev/null --- 25/Documentation/cdrom/mcd +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -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. diff -puN Documentation/cdrom/mcdx~kill-drivers-cdrom-mcdc Documentation/cdrom/mcdx --- 25/Documentation/cdrom/mcdx~kill-drivers-cdrom-mcdc 2005-03-15 22:11:18.000000000 -0800 +++ 25-akpm/Documentation/cdrom/mcdx 2005-03-15 22:11:18.000000000 -0800 @@ -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 @@ This driver: 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: diff -puN drivers/cdrom/Kconfig~kill-drivers-cdrom-mcdc drivers/cdrom/Kconfig --- 25/drivers/cdrom/Kconfig~kill-drivers-cdrom-mcdc 2005-03-15 22:11:18.000000000 -0800 +++ 25-akpm/drivers/cdrom/Kconfig 2005-03-15 22:11:18.000000000 -0800 @@ -103,60 +103,14 @@ config SBPCD 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 - . - - 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 - . + 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 . 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 diff -puN drivers/cdrom/Makefile~kill-drivers-cdrom-mcdc drivers/cdrom/Makefile --- 25/drivers/cdrom/Makefile~kill-drivers-cdrom-mcdc 2005-03-15 22:11:18.000000000 -0800 +++ 25-akpm/drivers/cdrom/Makefile 2005-03-15 22:11:18.000000000 -0800 @@ -15,7 +15,6 @@ obj-$(CONFIG_CDU31A) += cdu31a.o cd 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 diff -L drivers/cdrom/mcd.c -puN drivers/cdrom/mcd.c~kill-drivers-cdrom-mcdc /dev/null --- 25/drivers/cdrom/mcd.c +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -1,1565 +0,0 @@ -/* - linux/kernel/blk_drv/mcd.c - Mitsumi CDROM driver - - Copyright (C) 1992 Martin Harriss - Portions Copyright (C) 2001 Red Hat - - martin@bdsi.com (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 - (stud11@cc4.kuleuven.ac.be) - 0.3.2 bug fixes to the ioctls and merged with ALPHA0.99-pl12 - (Jon Tombs ) - 0.3.3 Added more #defines and mcd_setup() - (Jon Tombs ) - - 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 (zimmerma@rz.fht-esslingen.de), 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 - 07 July 1995 Modifications by Andrew J. Kroll - - Bjorn Ekwall added unregister_blkdev to mcd_init() - - Michael K. Johnson 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 - - September 2001 - Reformatted and cleaned up the code - Alan Cox -*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* #define REALLY_SLOW_IO */ -#include -#include -#include -#include -#include - -#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("", st)); - if (!(st & MFL_STATUS)) { - st = inb(MCDPORT(0)) & 0xFF; - test1(printk("", 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(¬Used) < 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); diff -L drivers/cdrom/mcd.h -puN drivers/cdrom/mcd.h~kill-drivers-cdrom-mcdc /dev/null --- 25/drivers/cdrom/mcd.h +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -1,106 +0,0 @@ -/* - * Definitions for a Mitsumi CD-ROM interface - * - * Copyright (C) 1992 Martin Harriss - * - * martin@bdsi.com - * - * 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) - _