Remove legacy CDROM drivers
Jens Axboe [Thu, 21 Jun 2007 06:29:34 +0000 (08:29 +0200)]
They are all broken beyond repair. Given that nobody has complained
about them (most haven't worked in 2.6 AT ALL), remove them from the
tree.

A new mitsumi driver that actually works is in progress, it'll get
added when completed.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

23 files changed:
drivers/Kconfig
drivers/cdrom/Kconfig [deleted file]
drivers/cdrom/Makefile
drivers/cdrom/aztcd.c [deleted file]
drivers/cdrom/aztcd.h [deleted file]
drivers/cdrom/cdu31a.c [deleted file]
drivers/cdrom/cdu31a.h [deleted file]
drivers/cdrom/cm206.c [deleted file]
drivers/cdrom/cm206.h [deleted file]
drivers/cdrom/gscd.c [deleted file]
drivers/cdrom/gscd.h [deleted file]
drivers/cdrom/isp16.c [deleted file]
drivers/cdrom/isp16.h [deleted file]
drivers/cdrom/mcdx.c [deleted file]
drivers/cdrom/mcdx.h [deleted file]
drivers/cdrom/optcd.c [deleted file]
drivers/cdrom/optcd.h [deleted file]
drivers/cdrom/sbpcd.c [deleted file]
drivers/cdrom/sbpcd.h [deleted file]
drivers/cdrom/sjcd.c [deleted file]
drivers/cdrom/sjcd.h [deleted file]
drivers/cdrom/sonycd535.c [deleted file]
drivers/cdrom/sonycd535.h [deleted file]

index 050323f..4e6487d 100644 (file)
@@ -24,8 +24,6 @@ source "drivers/scsi/Kconfig"
 
 source "drivers/ata/Kconfig"
 
-source "drivers/cdrom/Kconfig"
-
 source "drivers/md/Kconfig"
 
 source "drivers/message/fusion/Kconfig"
diff --git a/drivers/cdrom/Kconfig b/drivers/cdrom/Kconfig
deleted file mode 100644 (file)
index 4b12e90..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-#
-# CDROM driver configuration
-#
-
-menu "Old CD-ROM drivers (not SCSI, not IDE)"
-       depends on ISA && BLOCK
-
-config CD_NO_IDESCSI
-       bool "Support non-SCSI/IDE/ATAPI CDROM drives"
-       ---help---
-         If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
-         here, otherwise N. Read the CD-ROM-HOWTO, available from
-         <http://www.tldp.org/docs.html#howto>.
-
-         Note that the answer to this question doesn't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about these CD-ROM drives. If you are unsure what you
-         have, say Y and find out whether you have one of the following
-         drives.
-
-         For each of these drivers, a <file:Documentation/cdrom/{driver_name}>
-         exists. Especially in cases where you do not know exactly which kind
-         of drive you have you should read there. Most of these drivers use a
-         file drivers/cdrom/{driver_name}.h where you can define your
-         interface parameters and switch some internal goodies.
-
-         To compile these CD-ROM drivers as a module, choose M instead of Y.
-
-         If you want to use any of these CD-ROM drivers, you also have to
-         answer Y or M to "ISO 9660 CD-ROM file system support" below (this
-         answer will get "defaulted" for you if you enable any of the Linux
-         CD-ROM drivers).
-
-config AZTCD
-       tristate "Aztech/Orchid/Okano/Wearnes/TXC/CyDROM  CDROM support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         This is your driver if you have an Aztech CDA268-01A, Orchid
-         CD-3110, Okano or Wearnes CDD110, Conrad TXC, or CyCD-ROM CR520 or
-         CR540 CD-ROM drive.  This driver -- just like all these CD-ROM
-         drivers -- is NOT for CD-ROM drives with IDE/ATAPI interfaces, such
-         as Aztech CDA269-031SE. Please read the file
-         <file:Documentation/cdrom/aztcd>.
-
-         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 aztcd.
-
-config GSCD
-       tristate "Goldstar R420 CDROM support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         If this is your CD-ROM drive, say Y here.  As described in the file
-         <file:Documentation/cdrom/gscd>, you might have to change a setting
-         in the file <file:drivers/cdrom/gscd.h> before compiling the
-         kernel.  Please read the file <file:Documentation/cdrom/gscd>.
-
-         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 gscd.
-
-config SBPCD
-       tristate "Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support"
-       depends on CD_NO_IDESCSI && BROKEN_ON_SMP
-       ---help---
-         This driver supports most of the drives which use the Panasonic or
-         Sound Blaster interface.  Please read the file
-         <file:Documentation/cdrom/sbpcd>.
-
-         The Matsushita CR-521, CR-522, CR-523, CR-562, CR-563 drives
-         (sometimes labeled "Creative"), the Creative Labs CD200, the
-         Longshine LCS-7260, the "IBM External ISA CD-ROM" (in fact a CR-56x
-         model), the TEAC CD-55A fall under this category.  Some other
-         "electrically compatible" drives (Vertos, Genoa, some Funai models)
-         are currently not supported; for the Sanyo H94A drive currently a
-         separate driver (asked later) is responsible.  Most drives have a
-         uniquely shaped faceplate, with a caddyless motorized drawer, but
-         without external brand markings.  The older CR-52x drives have a
-         caddy and manual loading/eject, but still no external markings.  The
-         driver is able to do an extended auto-probing for interface
-         addresses and drive types; this can help to find facts in cases you
-         are not sure, but can consume some time during the boot process if
-         none of the supported drives gets found.  Once your drive got found,
-         you should enter the reported parameters into
-         <file:drivers/cdrom/sbpcd.h> and set "DISTRIBUTION 0" there.
-
-         This driver can support up to four CD-ROM controller cards, and each
-         card can support up to four CD-ROM drives; if you say Y here, you
-         will be asked how many controller cards you have.  If compiled as a
-         module, only one controller card (but with up to four drives) is
-         usable.
-
-         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 sbpcd.
-
-config MCDX
-       tristate "Mitsumi CDROM support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         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
-         CD-ROMs.
-
-         To compile this driver as a module, choose M here: the
-         module will be called mcdx.
-
-config OPTCD
-       tristate "Optics Storage DOLPHIN 8000AT CDROM support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         This is the driver for the 'DOLPHIN' drive with a 34-pin Sony
-         compatible interface. It also works with the Lasermate CR328A. If
-         you have one of those, say Y. This driver does not work for the
-         Optics Storage 8001 drive; use the IDE-ATAPI CD-ROM driver for that
-         one. Please read the file <file:Documentation/cdrom/optcd>.
-
-         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 optcd.
-
-config CM206
-       tristate "Philips/LMS CM206 CDROM support"
-       depends on CD_NO_IDESCSI && BROKEN_ON_SMP
-       ---help---
-         If you have a Philips/LMS CD-ROM drive cm206 in combination with a
-         cm260 host adapter card, say Y here. Please also read the file
-         <file:Documentation/cdrom/cm206>.
-
-         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 cm206.
-
-config SJCD
-       tristate "Sanyo CDR-H94A CDROM support"
-       depends on CD_NO_IDESCSI
-       help
-         If this is your CD-ROM drive, say Y here and read the file
-         <file:Documentation/cdrom/sjcd>. You should then 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 sjcd.
-
-config ISP16_CDI
-       tristate "ISP16/MAD16/Mozart soft configurable cdrom interface support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         These are sound cards with built-in cdrom interfaces using the OPTi
-         82C928 or 82C929 chips. Say Y here to have them detected and
-         possibly configured at boot time. In addition, You'll have to say Y
-         to a driver for the particular cdrom drive you have attached to the
-         card. Read <file:Documentation/cdrom/isp16> for details.
-
-         To compile this driver as a module, choose M here: the
-         module will be called isp16.
-
-config CDU31A
-       tristate "Sony CDU31A/CDU33A CDROM support"
-       depends on CD_NO_IDESCSI && BROKEN_ON_SMP
-       ---help---
-         These CD-ROM drives have a spring-pop-out caddyless drawer, and a
-         rectangular green LED centered beneath it.  NOTE: these CD-ROM
-         drives will not be auto detected by the kernel at boot time; you
-         have to provide the interface address as an option to the kernel at
-         boot time as described in <file:Documentation/cdrom/cdu31a> or fill
-         in your parameters into <file:drivers/cdrom/cdu31a.c>.  Try "man
-         bootparam" or see the documentation of your boot loader (lilo or
-         loadlin) about how to pass options to the kernel.
-
-         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 cdu31a.
-
-config CDU535
-       tristate "Sony CDU535 CDROM support"
-       depends on CD_NO_IDESCSI
-       ---help---
-         This is the driver for the older Sony CDU-535 and CDU-531 CD-ROM
-         drives. Please read the file <file:Documentation/cdrom/sonycd535>.
-
-         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 sonycd535.
-
-endmenu
index d1d1e5a..774c180 100644 (file)
@@ -10,14 +10,4 @@ obj-$(CONFIG_BLK_DEV_SR)     +=              cdrom.o
 obj-$(CONFIG_PARIDE_PCD)       +=              cdrom.o
 obj-$(CONFIG_CDROM_PKTCDVD)    +=              cdrom.o
 
-obj-$(CONFIG_AZTCD)            += aztcd.o
-obj-$(CONFIG_CDU31A)           += cdu31a.o     cdrom.o
-obj-$(CONFIG_CM206)            += cm206.o      cdrom.o
-obj-$(CONFIG_GSCD)             += gscd.o
-obj-$(CONFIG_ISP16_CDI)                += isp16.o
-obj-$(CONFIG_MCDX)             += mcdx.o       cdrom.o
-obj-$(CONFIG_OPTCD)            += optcd.o
-obj-$(CONFIG_SBPCD)            += sbpcd.o      cdrom.o
-obj-$(CONFIG_SJCD)             += sjcd.o
-obj-$(CONFIG_CDU535)           += sonycd535.o
 obj-$(CONFIG_VIOCD)            += viocd.o      cdrom.o
diff --git a/drivers/cdrom/aztcd.c b/drivers/cdrom/aztcd.c
deleted file mode 100644 (file)
index d7fbfaa..0000000
+++ /dev/null
@@ -1,2492 +0,0 @@
-#define AZT_VERSION "2.60"
-
-/*      $Id: aztcd.c,v 2.60 1997/11/29 09:51:19 root Exp root $
-       linux/drivers/block/aztcd.c - Aztech CD268 CDROM driver
-
-       Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de)
-
-       based on Mitsumi CDROM driver by  Martin Hariss and preworks by
-       Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby 
-       Schirmer.
-
-       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
-       V0.0    Adaption to Aztech CD268-01A Version 1.3
-               Version is PRE_ALPHA, unresolved points:
-               1. I use busy wait instead of timer wait in STEN_LOW,DTEN_LOW
-                  thus driver causes CPU overhead and is very slow 
-               2. could not find a way to stop the drive, when it is
-                  in data read mode, therefore I had to set
-                  msf.end.min/sec/frame to 0:0:1 (in azt_poll); so only one
-                  frame can be read in sequence, this is also the reason for
-               3. getting 'timeout in state 4' messages, but nevertheless
-                  it works
-               W.Zimmermann, Oct. 31, 1994
-       V0.1    Version is ALPHA, problems #2 and #3 resolved.  
-               W.Zimmermann, Nov. 3, 1994
-       V0.2    Modification to some comments, debugging aids for partial test
-               with Borland C under DOS eliminated. Timer interrupt wait 
-               STEN_LOW_WAIT additionally to busy wait for STEN_LOW implemented; 
-               use it only for the 'slow' commands (ACMD_GET_Q_CHANNEL, ACMD_
-               SEEK_TO_LEAD_IN), all other commands are so 'fast', that busy 
-               waiting seems better to me than interrupt rescheduling.
-               Besides that, when used in the wrong place, STEN_LOW_WAIT causes
-               kernel panic.
-               In function aztPlay command ACMD_PLAY_AUDIO added, should make
-               audio functions work. The Aztech drive needs different commands
-               to read data tracks and play audio tracks.
-               W.Zimmermann, Nov. 8, 1994
-       V0.3    Recognition of missing drive during boot up improved (speeded up).
-               W.Zimmermann, Nov. 13, 1994
-       V0.35   Rewrote the control mechanism in azt_poll (formerly mcd_poll) 
-               including removal of all 'goto' commands. :-); 
-               J. Nardone, Nov. 14, 1994
-       V0.4    Renamed variables and constants to 'azt' instead of 'mcd'; had
-               to make some "compatibility" defines in azt.h; please note,
-               that the source file was renamed to azt.c, the include file to
-               azt.h                
-               Speeded up drive recognition during init (will be a little bit 
-               slower than before if no drive is installed!); suggested by
-               Robby Schirmer.
-               read_count declared volatile and set to AZT_BUF_SIZ to make
-               drive faster (now 300kB/sec, was 60kB/sec before, measured
-               by 'time dd if=/dev/cdrom of=/dev/null bs=2048 count=4096';
-               different AZT_BUF_SIZes were test, above 16 no further im-
-               provement seems to be possible; suggested by E.Moenkeberg.
-               W.Zimmermann, Nov. 18, 1994
-       V0.42   Included getAztStatus command in GetQChannelInfo() to allow
-               reading Q-channel info on audio disks, if drive is stopped, 
-               and some other bug fixes in the audio stuff, suggested by 
-               Robby Schirmer.
-               Added more ioctls (reading data in mode 1 and mode 2).
-               Completely removed the old azt_poll() routine.
-               Detection of ORCHID CDS-3110 in aztcd_init implemented.
-               Additional debugging aids (see the readme file).
-               W.Zimmermann, Dec. 9, 1994  
-       V0.50   Autodetection of drives implemented.
-               W.Zimmermann, Dec. 12, 1994
-       V0.52   Prepared for including in the standard kernel, renamed most
-               variables to contain 'azt', included autoconf.h
-               W.Zimmermann, Dec. 16, 1994        
-       V0.6    Version for being included in the standard Linux kernel.
-               Renamed source and header file to aztcd.c and aztcd.h
-               W.Zimmermann, Dec. 24, 1994
-       V0.7    Changed VERIFY_READ to VERIFY_WRITE in aztcd_ioctl, case
-               CDROMREADMODE1 and CDROMREADMODE2; bug fix in the ioctl,
-               which causes kernel crashes when playing audio, changed 
-               include-files (config.h instead of autoconf.h, removed
-               delay.h)
-               W.Zimmermann, Jan. 8, 1995
-       V0.72   Some more modifications for adaption to the standard kernel.
-               W.Zimmermann, Jan. 16, 1995
-        V0.80   aztcd is now part of the standard kernel since version 1.1.83.
-                Modified the SET_TIMER and CLEAR_TIMER macros to comply with
-                the new timer scheme.
-                W.Zimmermann, Jan. 21, 1995
-        V0.90   Included CDROMVOLCTRL, but with my Aztech drive I can only turn
-                the channels on and off. If it works better with your drive, 
-                please mail me. Also implemented ACMD_CLOSE for CDROMSTART.
-                W.Zimmermann, Jan. 24, 1995
-        V1.00   Implemented close and lock tray commands. Patches supplied by
-               Frank Racis        
-                Added support for loadable MODULEs, so aztcd can now also be
-                loaded by insmod and removed by rmmod during run time
-                Werner Zimmermann, Mar. 24, 95
-        V1.10   Implemented soundcard configuration for Orchid CDS-3110 drives
-                connected to Soundwave32 cards. Release for LST 2.1.
-                (still experimental)
-                Werner Zimmermann, May 8, 95
-        V1.20   Implemented limited support for DOSEMU0.60's cdrom.c. Now it works, but
-                sometimes DOSEMU may hang for 30 seconds or so. A fully functional ver-
-                sion needs an update of Dosemu0.60's cdrom.c, which will come with the 
-                next revision of Dosemu.
-                Also Soundwave32 support now works.
-                Werner Zimmermann, May 22, 95
-       V1.30   Auto-eject feature. Inspired by Franc Racis (racis@psu.edu)
-               Werner Zimmermann, July 4, 95
-       V1.40   Started multisession support. Implementation copied from mcdx.c
-               by Heiko Schlittermann. Not tested yet.
-               Werner Zimmermann, July 15, 95
-        V1.50   Implementation of ioctl CDROMRESET, continued multisession, began
-                XA, but still untested. Heavy modifications to drive status de-
-                tection.
-                Werner Zimmermann, July 25, 95
-        V1.60   XA support now should work. Speeded up drive recognition in cases, 
-                where no drive is installed.
-                Werner Zimmermann, August 8, 1995
-        V1.70   Multisession support now is completed, but there is still not 
-                enough testing done. If you can test it, please contact me. For
-                details please read Documentation/cdrom/aztcd
-                Werner Zimmermann, August 19, 1995
-        V1.80   Modification to suit the new kernel boot procedure introduced
-                with kernel 1.3.33. Will definitely not work with older kernels.
-                Programming done by Linus himself.
-                Werner Zimmermann, October 11, 1995
-       V1.90   Support for Conrad TXC drives, thank's to Jochen Kunz and Olaf Kaluza.
-               Werner Zimmermann, October 21, 1995
-        V2.00   Changed #include "blk.h" to <linux/blk.h> as the directory
-                structure was changed. README.aztcd is now /usr/src/docu-
-                mentation/cdrom/aztcd
-                Werner Zimmermann, November 10, 95
-        V2.10   Started to modify azt_poll to prevent reading beyond end of
-                tracks.
-                Werner Zimmermann, December 3, 95
-        V2.20   Changed some comments
-                Werner Zimmermann, April 1, 96
-        V2.30   Implemented support for CyCDROM CR520, CR940, Code for CR520 
-               delivered by H.Berger with preworks by E.Moenkeberg.
-                Werner Zimmermann, April 29, 96
-        V2.40   Reorganized the placement of functions in the source code file
-                to reflect the layered approach; did not actually change code
-                Werner Zimmermann, May 1, 96
-        V2.50   Heiko Eissfeldt suggested to remove some VERIFY_READs in 
-                aztcd_ioctl; check_aztcd_media_change modified 
-                Werner Zimmermann, May 16, 96       
-       V2.60   Implemented Auto-Probing; made changes for kernel's 2.1.xx blocksize
-                Adaption to linux kernel > 2.1.0
-               Werner Zimmermann, Nov 29, 97
-               
-        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 <tmm@image.dk>
-*/
-
-#include <linux/blkdev.h>
-#include "aztcd.h"
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/major.h>
-
-#include <linux/init.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include <asm/uaccess.h>
-
-/*###########################################################################
-  Defines
-  ###########################################################################
-*/
-
-#define MAJOR_NR AZTECH_CDROM_MAJOR
-#define QUEUE (azt_queue)
-#define CURRENT elv_next_request(azt_queue)
-#define SET_TIMER(func, jifs)   delay_timer.expires = jiffies + (jifs); \
-                                delay_timer.function = (void *) (func); \
-                                add_timer(&delay_timer);
-
-#define CLEAR_TIMER             del_timer(&delay_timer);
-
-#define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
-                                return value;}
-#define RETURN(message)        {printk("aztcd: Warning: %s failed\n",message);\
-                                return;}
-
-/* Macros to switch the IDE-interface to the slave device and back to the master*/
-#define SWITCH_IDE_SLAVE  outb_p(0xa0,azt_port+6); \
-                         outb_p(0x10,azt_port+6); \
-                         outb_p(0x00,azt_port+7); \
-                         outb_p(0x10,azt_port+6);
-#define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
-
-
-#if 0
-#define AZT_TEST
-#define AZT_TEST1              /* <int-..> */
-#define AZT_TEST2              /* do_aztcd_request */
-#define AZT_TEST3              /* AZT_S_state */
-#define AZT_TEST4              /* QUICK_LOOP-counter */
-#define AZT_TEST5              /* port(1) state */
-#define AZT_DEBUG
-#define AZT_DEBUG_MULTISESSION
-#endif
-
-static struct request_queue *azt_queue;
-
-static int current_valid(void)
-{
-        return CURRENT &&
-               rq_data_dir(CURRENT) == READ &&
-               CURRENT->sector != -1;
-}
-
-#define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
-#define AZT_BUF_SIZ 16
-
-#define READ_TIMEOUT 3000
-
-#define azt_port aztcd         /*needed for the modutils */
-
-/*##########################################################################
-  Type Definitions
-  ##########################################################################
-*/
-enum azt_state_e { AZT_S_IDLE, /* 0 */
-       AZT_S_START,            /* 1 */
-       AZT_S_MODE,             /* 2 */
-       AZT_S_READ,             /* 3 */
-       AZT_S_DATA,             /* 4 */
-       AZT_S_STOP,             /* 5 */
-       AZT_S_STOPPING          /* 6 */
-};
-enum azt_read_modes { AZT_MODE_0,      /*read mode for audio disks, not supported by Aztech firmware */
-       AZT_MODE_1,             /*read mode for normal CD-ROMs */
-       AZT_MODE_2              /*read mode for XA CD-ROMs */
-};
-
-/*##########################################################################
-  Global Variables
-  ##########################################################################
-*/
-static int aztPresent = 0;
-
-static volatile int azt_transfer_is_active = 0;
-
-static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ];   /*buffer for block size conversion */
-#if AZT_PRIVATE_IOCTLS
-static char buf[CD_FRAMESIZE_RAW];     /*separate buffer for the ioctls */
-#endif
-
-static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
-static volatile int azt_buf_in, azt_buf_out = -1;
-static volatile int azt_error = 0;
-static int azt_open_count = 0;
-static volatile enum azt_state_e azt_state = AZT_S_IDLE;
-#ifdef AZT_TEST3
-static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
-static volatile int azt_st_old = 0;
-#endif
-static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
-
-static int azt_mode = -1;
-static volatile int azt_read_count = 1;
-
-static int azt_port = AZT_BASE_ADDR;
-
-module_param(azt_port, int, 0);
-
-static int azt_port_auto[16] = AZT_BASE_AUTO;
-
-static char azt_cont = 0;
-static char azt_init_end = 0;
-static char azt_auto_eject = AZT_AUTO_EJECT;
-
-static int AztTimeout, AztTries;
-static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
-static DEFINE_TIMER(delay_timer, NULL, 0, 0);
-
-static struct azt_DiskInfo DiskInfo;
-static struct azt_Toc Toc[MAX_TRACKS];
-static struct azt_Play_msf azt_Play;
-
-static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-static char aztDiskChanged = 1;
-static char aztTocUpToDate = 0;
-
-static unsigned char aztIndatum;
-static unsigned long aztTimeOutCount;
-static int aztCmd = 0;
-
-static DEFINE_SPINLOCK(aztSpin);
-
-/*###########################################################################
-   Function Prototypes
-  ###########################################################################
-*/
-/* CDROM Drive Low Level I/O Functions */
-static void aztStatTimer(void);
-
-/* CDROM Drive Command Functions */
-static int aztGetDiskInfo(void);
-#if AZT_MULTISESSION
-static int aztGetMultiDiskInfo(void);
-#endif
-static int aztGetToc(int multi);
-
-/* Kernel Interface Functions */
-static int check_aztcd_media_change(struct gendisk *disk);
-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
-                      unsigned long arg);
-static int aztcd_open(struct inode *ip, struct file *fp);
-static int aztcd_release(struct inode *inode, struct file *file);
-
-static struct block_device_operations azt_fops = {
-       .owner          = THIS_MODULE,
-       .open           = aztcd_open,
-       .release        = aztcd_release,
-       .ioctl          = aztcd_ioctl,
-       .media_changed  = check_aztcd_media_change,
-};
-
-/* Aztcd State Machine: Controls Drive Operating State */
-static void azt_poll(void);
-
-/* Miscellaneous support functions */
-static void azt_hsg2msf(long hsg, struct msf *msf);
-static long azt_msf2hsg(struct msf *mp);
-static void azt_bin2bcd(unsigned char *p);
-static int azt_bcd2bin(unsigned char bcd);
-
-/*##########################################################################
-  CDROM Drive Low Level I/O Functions
-  ##########################################################################
-*/
-/* Macros for the drive hardware interface handshake, these macros use
-   busy waiting */
-/* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
-# define OP_OK op_ok()
-static void op_ok(void)
-{
-       aztTimeOutCount = 0;
-       do {
-               aztIndatum = inb(DATA_PORT);
-               aztTimeOutCount++;
-               if (aztTimeOutCount >= AZT_TIMEOUT) {
-                       printk("aztcd: Error Wait OP_OK\n");
-                       break;
-               }
-       } while (aztIndatum != AFL_OP_OK);
-}
-
-/* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
-#if 0
-# define PA_OK pa_ok()
-static void pa_ok(void)
-{
-       aztTimeOutCount = 0;
-       do {
-               aztIndatum = inb(DATA_PORT);
-               aztTimeOutCount++;
-               if (aztTimeOutCount >= AZT_TIMEOUT) {
-                       printk("aztcd: Error Wait PA_OK\n");
-                       break;
-               }
-       } while (aztIndatum != AFL_PA_OK);
-}
-#endif
-
-/* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
-# define STEN_LOW  sten_low()
-static void sten_low(void)
-{
-       aztTimeOutCount = 0;
-       do {
-               aztIndatum = inb(STATUS_PORT);
-               aztTimeOutCount++;
-               if (aztTimeOutCount >= AZT_TIMEOUT) {
-                       if (azt_init_end)
-                               printk
-                                   ("aztcd: Error Wait STEN_LOW commands:%x\n",
-                                    aztCmd);
-                       break;
-               }
-       } while (aztIndatum & AFL_STATUS);
-}
-
-/* Wait for DTEN=Low = handshake signal 'Data available'*/
-# define DTEN_LOW dten_low()
-static void dten_low(void)
-{
-       aztTimeOutCount = 0;
-       do {
-               aztIndatum = inb(STATUS_PORT);
-               aztTimeOutCount++;
-               if (aztTimeOutCount >= AZT_TIMEOUT) {
-                       printk("aztcd: Error Wait DTEN_OK\n");
-                       break;
-               }
-       } while (aztIndatum & AFL_DATA);
-}
-
-/* 
- * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
- * may cause kernel panic when used in the wrong place
-*/
-#define STEN_LOW_WAIT   statusAzt()
-static void statusAzt(void)
-{
-       AztTimeout = AZT_STATUS_DELAY;
-       SET_TIMER(aztStatTimer, HZ / 100);
-       sleep_on(&azt_waitq);
-       if (AztTimeout <= 0)
-               printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",
-                      aztCmd);
-       return;
-}
-
-static void aztStatTimer(void)
-{
-       if (!(inb(STATUS_PORT) & AFL_STATUS)) {
-               wake_up(&azt_waitq);
-               return;
-       }
-       AztTimeout--;
-       if (AztTimeout <= 0) {
-               wake_up(&azt_waitq);
-               printk("aztcd: Error aztStatTimer: Timeout\n");
-               return;
-       }
-       SET_TIMER(aztStatTimer, HZ / 100);
-}
-
-/*##########################################################################
-  CDROM Drive Command Functions
-  ##########################################################################
-*/
-/* 
- * Send a single command, return -1 on error, else 0
-*/
-static int aztSendCmd(int cmd)
-{
-       unsigned char data;
-       int retry;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: Executing command %x\n", cmd);
-#endif
-
-       if ((azt_port == 0x1f0) || (azt_port == 0x170))
-               SWITCH_IDE_SLAVE;       /*switch IDE interface to slave configuration */
-
-       aztCmd = cmd;
-       outb(POLLED, MODE_PORT);
-       do {
-               if (inb(STATUS_PORT) & AFL_STATUS)
-                       break;
-               inb(DATA_PORT); /* if status left from last command, read and */
-       } while (1);            /* discard it */
-       do {
-               if (inb(STATUS_PORT) & AFL_DATA)
-                       break;
-               inb(DATA_PORT); /* if data left from last command, read and */
-       } while (1);            /* discard it */
-       for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
-               outb((unsigned char) cmd, CMD_PORT);
-               STEN_LOW;
-               data = inb(DATA_PORT);
-               if (data == AFL_OP_OK) {
-                       return 0;
-               }               /*OP_OK? */
-               if (data == AFL_OP_ERR) {
-                       STEN_LOW;
-                       data = inb(DATA_PORT);
-                       printk
-                           ("### Error 1 aztcd: aztSendCmd %x  Error Code %x\n",
-                            cmd, data);
-               }
-       }
-       if (retry >= AZT_RETRY_ATTEMPTS) {
-               printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);
-               azt_error = 0xA5;
-       }
-       RETURNM("aztSendCmd", -1);
-}
-
-/*
- * Send a play or read command to the drive, return -1 on error, else 0
-*/
-static int sendAztCmd(int cmd, struct azt_Play_msf *params)
-{
-       unsigned char data;
-       int retry;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: play start=%02x:%02x:%02x  end=%02x:%02x:%02x\n",
-              params->start.min, params->start.sec, params->start.frame,
-              params->end.min, params->end.sec, params->end.frame);
-#endif
-       for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
-               aztSendCmd(cmd);
-               outb(params->start.min, CMD_PORT);
-               outb(params->start.sec, CMD_PORT);
-               outb(params->start.frame, CMD_PORT);
-               outb(params->end.min, CMD_PORT);
-               outb(params->end.sec, CMD_PORT);
-               outb(params->end.frame, CMD_PORT);
-               STEN_LOW;
-               data = inb(DATA_PORT);
-               if (data == AFL_PA_OK) {
-                       return 0;
-               }               /*PA_OK ? */
-               if (data == AFL_PA_ERR) {
-                       STEN_LOW;
-                       data = inb(DATA_PORT);
-                       printk
-                           ("### Error 1 aztcd: sendAztCmd %x  Error Code %x\n",
-                            cmd, data);
-               }
-       }
-       if (retry >= AZT_RETRY_ATTEMPTS) {
-               printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);
-               azt_error = 0xA5;
-       }
-       RETURNM("sendAztCmd", -1);
-}
-
-/*
- * Send a seek command to the drive, return -1 on error, else 0
-*/
-static int aztSeek(struct azt_Play_msf *params)
-{
-       unsigned char data;
-       int retry;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: aztSeek %02x:%02x:%02x\n",
-              params->start.min, params->start.sec, params->start.frame);
-#endif
-       for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
-               aztSendCmd(ACMD_SEEK);
-               outb(params->start.min, CMD_PORT);
-               outb(params->start.sec, CMD_PORT);
-               outb(params->start.frame, CMD_PORT);
-               STEN_LOW;
-               data = inb(DATA_PORT);
-               if (data == AFL_PA_OK) {
-                       return 0;
-               }               /*PA_OK ? */
-               if (data == AFL_PA_ERR) {
-                       STEN_LOW;
-                       data = inb(DATA_PORT);
-                       printk("### Error 1 aztcd: aztSeek\n");
-               }
-       }
-       if (retry >= AZT_RETRY_ATTEMPTS) {
-               printk("### Error 2 aztcd: aztSeek\n ");
-               azt_error = 0xA5;
-       }
-       RETURNM("aztSeek", -1);
-}
-
-/* Send a Set Disk Type command
-   does not seem to work with Aztech drives, behavior is completely indepen-
-   dent on which mode is set ???
-*/
-static int aztSetDiskType(int type)
-{
-       unsigned char data;
-       int retry;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: set disk type command: type= %i\n", type);
-#endif
-       for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
-               aztSendCmd(ACMD_SET_DISK_TYPE);
-               outb(type, CMD_PORT);
-               STEN_LOW;
-               data = inb(DATA_PORT);
-               if (data == AFL_PA_OK) {        /*PA_OK ? */
-                       azt_read_mode = type;
-                       return 0;
-               }
-               if (data == AFL_PA_ERR) {
-                       STEN_LOW;
-                       data = inb(DATA_PORT);
-                       printk
-                           ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",
-                            type, data);
-               }
-       }
-       if (retry >= AZT_RETRY_ATTEMPTS) {
-               printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);
-               azt_error = 0xA5;
-       }
-       RETURNM("aztSetDiskType", -1);
-}
-
-
-/* used in azt_poll to poll the status, expects another program to issue a 
- * ACMD_GET_STATUS directly before 
- */
-static int aztStatus(void)
-{
-       int st;
-/*     int i;
-
-       i = inb(STATUS_PORT) & AFL_STATUS;    is STEN=0?    ???
-       if (!i)
-*/ STEN_LOW;
-       if (aztTimeOutCount < AZT_TIMEOUT) {
-               st = inb(DATA_PORT) & 0xFF;
-               return st;
-       } else
-               RETURNM("aztStatus", -1);
-}
-
-/*
- * Get the drive status
- */
-static int getAztStatus(void)
-{
-       int st;
-
-       if (aztSendCmd(ACMD_GET_STATUS))
-               RETURNM("getAztStatus 1", -1);
-       STEN_LOW;
-       st = inb(DATA_PORT) & 0xFF;
-#ifdef AZT_DEBUG
-       printk("aztcd: Status = %x\n", st);
-#endif
-       if ((st == 0xFF) || (st & AST_CMD_CHECK)) {
-               printk
-                   ("aztcd: AST_CMD_CHECK error or no status available\n");
-               return -1;
-       }
-
-       if (((st & AST_MODE_BITS) != AST_BUSY)
-           && (aztAudioStatus == CDROM_AUDIO_PLAY))
-               /* XXX might be an error? look at q-channel? */
-               aztAudioStatus = CDROM_AUDIO_COMPLETED;
-
-       if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {
-               aztDiskChanged = 1;
-               aztTocUpToDate = 0;
-               aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-       }
-       return st;
-}
-
-
-/*
- * Send a 'Play' command and get the status.  Use only from the top half.
- */
-static int aztPlay(struct azt_Play_msf *arg)
-{
-       if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)
-               RETURNM("aztPlay", -1);
-       return 0;
-}
-
-/*
- * Subroutines to automatically close the door (tray) and 
- * lock it closed when the cd is mounted.  Leave the tray
- * locking as an option
- */
-static void aztCloseDoor(void)
-{
-       aztSendCmd(ACMD_CLOSE);
-       STEN_LOW;
-       return;
-}
-
-static void aztLockDoor(void)
-{
-#if AZT_ALLOW_TRAY_LOCK
-       aztSendCmd(ACMD_LOCK);
-       STEN_LOW;
-#endif
-       return;
-}
-
-static void aztUnlockDoor(void)
-{
-#if AZT_ALLOW_TRAY_LOCK
-       aztSendCmd(ACMD_UNLOCK);
-       STEN_LOW;
-#endif
-       return;
-}
-
-/*
- * Read a value from the drive.  Should return quickly, so a busy wait
- * is used to avoid excessive rescheduling. The read command itself must
- * be issued with aztSendCmd() directly before
- */
-static int aztGetValue(unsigned char *result)
-{
-       int s;
-
-       STEN_LOW;
-       if (aztTimeOutCount >= AZT_TIMEOUT) {
-               printk("aztcd: aztGetValue timeout\n");
-               return -1;
-       }
-       s = inb(DATA_PORT) & 0xFF;
-       *result = (unsigned char) s;
-       return 0;
-}
-
-/*
- * Read the current Q-channel info.  Also used for reading the
- * table of contents.
- */
-static int aztGetQChannelInfo(struct azt_Toc *qp)
-{
-       unsigned char notUsed;
-       int st;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztGetQChannelInfo  Time:%li\n", jiffies);
-#endif
-       if ((st = getAztStatus()) == -1)
-               RETURNM("aztGetQChannelInfo 1", -1);
-       if (aztSendCmd(ACMD_GET_Q_CHANNEL))
-               RETURNM("aztGetQChannelInfo 2", -1);
-       /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */
-       if (aztGetValue(&notUsed))
-               RETURNM("aztGetQChannelInfo 3", -1);    /*??? Nullbyte einlesen */
-       if ((st & AST_MODE_BITS) == AST_INITIAL) {
-               qp->ctrl_addr = 0;      /* when audio stop ACMD_GET_Q_CHANNEL returns */
-               qp->track = 0;  /* only one byte with Aztech drives */
-               qp->pointIndex = 0;
-               qp->trackTime.min = 0;
-               qp->trackTime.sec = 0;
-               qp->trackTime.frame = 0;
-               qp->diskTime.min = 0;
-               qp->diskTime.sec = 0;
-               qp->diskTime.frame = 0;
-               return 0;
-       } else {
-               if (aztGetValue(&qp->ctrl_addr) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->track) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->pointIndex) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->trackTime.min) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->trackTime.sec) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->trackTime.frame) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&notUsed) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->diskTime.min) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->diskTime.sec) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-               if (aztGetValue(&qp->diskTime.frame) < 0)
-                       RETURNM("aztGetQChannelInfo 4", -1);
-       }
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztGetQChannelInfo  Time:%li\n", jiffies);
-#endif
-       return 0;
-}
-
-/*
- * Read the table of contents (TOC) and TOC header if necessary
- */
-static int aztUpdateToc(void)
-{
-       int st;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztUpdateToc  Time:%li\n", jiffies);
-#endif
-       if (aztTocUpToDate)
-               return 0;
-
-       if (aztGetDiskInfo() < 0)
-               return -EIO;
-
-       if (aztGetToc(0) < 0)
-               return -EIO;
-
-       /*audio disk detection
-          with my Aztech drive there is no audio status bit, so I use the copy
-          protection bit of the first track. If this track is copy protected 
-          (copy bit = 0), I assume, it's an audio  disk. Strange, but works ??? */
-       if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
-               DiskInfo.audio = 1;
-       else
-               DiskInfo.audio = 0;
-
-       /* XA detection */
-       if (!DiskInfo.audio) {
-               azt_Play.start.min = 0; /*XA detection only seems to work */
-               azt_Play.start.sec = 2; /*when we play a track */
-               azt_Play.start.frame = 0;
-               azt_Play.end.min = 0;
-               azt_Play.end.sec = 0;
-               azt_Play.end.frame = 1;
-               if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
-                       return -1;
-               DTEN_LOW;
-               for (st = 0; st < CD_FRAMESIZE; st++)
-                       inb(DATA_PORT);
-       }
-       DiskInfo.xa = getAztStatus() & AST_MODE;
-       if (DiskInfo.xa) {
-               printk
-                   ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
-       }
-
-       /*multisession detection
-          support for multisession CDs is done automatically with Aztech drives,
-          we don't have to take care about TOC redirection; if we want the isofs
-          to take care about redirection, we have to set AZT_MULTISESSION to 1 */
-       DiskInfo.multi = 0;
-#if AZT_MULTISESSION
-       if (DiskInfo.xa) {
-               aztGetMultiDiskInfo();  /*here Disk.Info.multi is set */
-       }
-#endif
-       if (DiskInfo.multi) {
-               DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
-               DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
-               DiskInfo.lastSession.frame =
-                   Toc[DiskInfo.next].diskTime.frame;
-               printk("aztcd: Multisession support experimental\n");
-       } else {
-               DiskInfo.lastSession.min =
-                   Toc[DiskInfo.first].diskTime.min;
-               DiskInfo.lastSession.sec =
-                   Toc[DiskInfo.first].diskTime.sec;
-               DiskInfo.lastSession.frame =
-                   Toc[DiskInfo.first].diskTime.frame;
-       }
-
-       aztTocUpToDate = 1;
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztUpdateToc  Time:%li\n", jiffies);
-#endif
-       return 0;
-}
-
-
-/* Read the table of contents header, i.e. no. of tracks and start of first 
- * track
- */
-static int aztGetDiskInfo(void)
-{
-       int limit;
-       unsigned char test;
-       struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztGetDiskInfo  Time:%li\n", jiffies);
-#endif
-       if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
-               RETURNM("aztGetDiskInfo 1", -1);
-       STEN_LOW_WAIT;
-       test = 0;
-       for (limit = 300; limit > 0; limit--) {
-               if (aztGetQChannelInfo(&qInfo) < 0)
-                       RETURNM("aztGetDiskInfo 2", -1);
-               if (qInfo.pointIndex == 0xA0) { /*Number of FirstTrack */
-                       DiskInfo.first = qInfo.diskTime.min;
-                       DiskInfo.first = azt_bcd2bin(DiskInfo.first);
-                       test = test | 0x01;
-               }
-               if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
-                       DiskInfo.last = qInfo.diskTime.min;
-                       DiskInfo.last = azt_bcd2bin(DiskInfo.last);
-                       test = test | 0x02;
-               }
-               if (qInfo.pointIndex == 0xA2) { /*DiskLength */
-                       DiskInfo.diskLength.min = qInfo.diskTime.min;
-                       DiskInfo.diskLength.sec = qInfo.diskTime.sec;
-                       DiskInfo.diskLength.frame = qInfo.diskTime.frame;
-                       test = test | 0x04;
-               }
-               if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) {    /*StartTime of First Track */
-                       DiskInfo.firstTrack.min = qInfo.diskTime.min;
-                       DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
-                       DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
-                       test = test | 0x08;
-               }
-               if (test == 0x0F)
-                       break;
-       }
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztGetDiskInfo  Time:%li\n", jiffies);
-       printk
-           ("Disk Info: first %d last %d length %02X:%02X.%02X dez  first %02X:%02X.%02X dez\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 (test != 0x0F)
-               return -1;
-       return 0;
-}
-
-#if AZT_MULTISESSION
-/*
- * Get Multisession Disk Info
- */
-static int aztGetMultiDiskInfo(void)
-{
-       int limit, k = 5;
-       unsigned char test;
-       struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztGetMultiDiskInfo\n");
-#endif
-
-       do {
-               azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
-               azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
-               azt_Play.start.frame =
-                   Toc[DiskInfo.last + 1].diskTime.frame;
-               test = 0;
-
-               for (limit = 30; limit > 0; limit--) {  /*Seek for LeadIn of next session */
-                       if (aztSeek(&azt_Play))
-                               RETURNM("aztGetMultiDiskInfo 1", -1);
-                       if (aztGetQChannelInfo(&qInfo) < 0)
-                               RETURNM("aztGetMultiDiskInfo 2", -1);
-                       if ((qInfo.track == 0) && (qInfo.pointIndex))
-                               break;  /*LeadIn found */
-                       if ((azt_Play.start.sec += 10) > 59) {
-                               azt_Play.start.sec = 0;
-                               azt_Play.start.min++;
-                       }
-               }
-               if (!limit)
-                       break;  /*Check, if a leadin track was found, if not we're
-                                  at the end of the disk */
-#ifdef AZT_DEBUG_MULTISESSION
-               printk("leadin found track %d  pointIndex %x  limit %d\n",
-                      qInfo.track, qInfo.pointIndex, limit);
-#endif
-               for (limit = 300; limit > 0; limit--) {
-                       if (++azt_Play.start.frame > 74) {
-                               azt_Play.start.frame = 0;
-                               if (azt_Play.start.sec > 59) {
-                                       azt_Play.start.sec = 0;
-                                       azt_Play.start.min++;
-                               }
-                       }
-                       if (aztSeek(&azt_Play))
-                               RETURNM("aztGetMultiDiskInfo 3", -1);
-                       if (aztGetQChannelInfo(&qInfo) < 0)
-                               RETURNM("aztGetMultiDiskInfo 4", -1);
-                       if (qInfo.pointIndex == 0xA0) { /*Number of NextTrack */
-                               DiskInfo.next = qInfo.diskTime.min;
-                               DiskInfo.next = azt_bcd2bin(DiskInfo.next);
-                               test = test | 0x01;
-                       }
-                       if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
-                               DiskInfo.last = qInfo.diskTime.min;
-                               DiskInfo.last = azt_bcd2bin(DiskInfo.last);
-                               test = test | 0x02;
-                       }
-                       if (qInfo.pointIndex == 0xA2) { /*DiskLength */
-                               DiskInfo.diskLength.min =
-                                   qInfo.diskTime.min;
-                               DiskInfo.diskLength.sec =
-                                   qInfo.diskTime.sec;
-                               DiskInfo.diskLength.frame =
-                                   qInfo.diskTime.frame;
-                               test = test | 0x04;
-                       }
-                       if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) {     /*StartTime of Next Track */
-                               DiskInfo.nextSession.min =
-                                   qInfo.diskTime.min;
-                               DiskInfo.nextSession.sec =
-                                   qInfo.diskTime.sec;
-                               DiskInfo.nextSession.frame =
-                                   qInfo.diskTime.frame;
-                               test = test | 0x08;
-                       }
-                       if (test == 0x0F)
-                               break;
-               }
-#ifdef AZT_DEBUG_MULTISESSION
-               printk
-                   ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez  first %02x:%02x.%02x dez  next %02x:%02x.%02x dez\n",
-                    DiskInfo.first, DiskInfo.next, DiskInfo.last,
-                    DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
-                    DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
-                    DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
-                    DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
-                    DiskInfo.nextSession.frame);
-#endif
-               if (test != 0x0F)
-                       break;
-               else
-                       DiskInfo.multi = 1;     /*found TOC of more than one session */
-               aztGetToc(1);
-       } while (--k);
-
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztGetMultiDiskInfo  Time:%li\n", jiffies);
-#endif
-       return 0;
-}
-#endif
-
-/*
- * Read the table of contents (TOC)
- */
-static int aztGetToc(int multi)
-{
-       int i, px;
-       int limit;
-       struct azt_Toc qInfo;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztGetToc  Time:%li\n", jiffies);
-#endif
-       if (!multi) {
-               for (i = 0; i < MAX_TRACKS; i++)
-                       Toc[i].pointIndex = 0;
-               i = DiskInfo.last + 3;
-       } else {
-               for (i = DiskInfo.next; i < MAX_TRACKS; i++)
-                       Toc[i].pointIndex = 0;
-               i = DiskInfo.last + 4 - DiskInfo.next;
-       }
-
-/*Is there a good reason to stop motor before TOC read?
-  if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
-      STEN_LOW_WAIT;
-*/
-
-       if (!multi) {
-               azt_mode = 0x05;
-               if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
-                       RETURNM("aztGetToc 2", -1);
-               STEN_LOW_WAIT;
-       }
-       for (limit = 300; limit > 0; limit--) {
-               if (multi) {
-                       if (++azt_Play.start.sec > 59) {
-                               azt_Play.start.sec = 0;
-                               azt_Play.start.min++;
-                       }
-                       if (aztSeek(&azt_Play))
-                               RETURNM("aztGetToc 3", -1);
-               }
-               if (aztGetQChannelInfo(&qInfo) < 0)
-                       break;
-
-               px = azt_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;
-       Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
-
-#ifdef AZT_DEBUG_MULTISESSION
-       printk("aztcd: exiting aztGetToc\n");
-       for (i = 1; i <= DiskInfo.last + 1; i++)
-               printk
-                   ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\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 dez  %02X:%02X.%02X dez\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;
-}
-
-
-/*##########################################################################
-  Kernel Interface Functions
-  ##########################################################################
-*/
-
-#ifndef MODULE
-static int __init aztcd_setup(char *str)
-{
-       int ints[4];
-
-       (void) get_options(str, ARRAY_SIZE(ints), ints);
-
-       if (ints[0] > 0)
-               azt_port = ints[1];
-       if (ints[1] > 1)
-               azt_cont = ints[2];
-       return 1;
-}
-
-__setup("aztcd=", aztcd_setup);
-
-#endif                         /* !MODULE */
-
-/* 
- * Checking if the media has been changed
-*/
-static int check_aztcd_media_change(struct gendisk *disk)
-{
-       if (aztDiskChanged) {   /* disk changed */
-               aztDiskChanged = 0;
-               return 1;
-       } else
-               return 0;       /* no change */
-}
-
-/*
- * Kernel IO-controls
-*/
-static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
-                      unsigned long arg)
-{
-       int i;
-       struct azt_Toc qInfo;
-       struct cdrom_ti ti;
-       struct cdrom_tochdr tocHdr;
-       struct cdrom_msf msf;
-       struct cdrom_tocentry entry;
-       struct azt_Toc *tocPtr;
-       struct cdrom_subchnl subchnl;
-       struct cdrom_volctrl volctrl;
-       void __user *argp = (void __user *)arg;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztcd_ioctl - Command:%x   Time: %li\n",
-              cmd, jiffies);
-       printk("aztcd Status %x\n", getAztStatus());
-#endif
-       if (!ip)
-               RETURNM("aztcd_ioctl 1", -EINVAL);
-       if (getAztStatus() < 0)
-               RETURNM("aztcd_ioctl 2", -EIO);
-       if ((!aztTocUpToDate) || (aztDiskChanged)) {
-               if ((i = aztUpdateToc()) < 0)
-                       RETURNM("aztcd_ioctl 3", i);    /* error reading TOC */
-       }
-
-       switch (cmd) {
-       case CDROMSTART:        /* Spin up the drive. Don't know, what to do,
-                                  at least close the tray */
-#if AZT_PRIVATE_IOCTLS
-               if (aztSendCmd(ACMD_CLOSE))
-                       RETURNM("aztcd_ioctl 4", -1);
-               STEN_LOW_WAIT;
-#endif
-               break;
-       case CDROMSTOP: /* Spin down the drive */
-               if (aztSendCmd(ACMD_STOP))
-                       RETURNM("aztcd_ioctl 5", -1);
-               STEN_LOW_WAIT;
-               /* should we do anything if it fails? */
-               aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-               break;
-       case CDROMPAUSE:        /* Pause the drive */
-               if (aztAudioStatus != CDROM_AUDIO_PLAY)
-                       return -EINVAL;
-
-               if (aztGetQChannelInfo(&qInfo) < 0) {   /* didn't get q channel info */
-                       aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-                       RETURNM("aztcd_ioctl 7", 0);
-               }
-               azt_Play.start = qInfo.diskTime;        /* remember restart point */
-
-               if (aztSendCmd(ACMD_PAUSE))
-                       RETURNM("aztcd_ioctl 8", -1);
-               STEN_LOW_WAIT;
-               aztAudioStatus = CDROM_AUDIO_PAUSED;
-               break;
-       case CDROMRESUME:       /* Play it again, Sam */
-               if (aztAudioStatus != CDROM_AUDIO_PAUSED)
-                       return -EINVAL;
-               /* restart the drive at the saved position. */
-               i = aztPlay(&azt_Play);
-               if (i < 0) {
-                       aztAudioStatus = CDROM_AUDIO_ERROR;
-                       return -EIO;
-               }
-               aztAudioStatus = CDROM_AUDIO_PLAY;
-               break;
-       case CDROMMULTISESSION: /*multisession support -- experimental */
-               {
-                       struct cdrom_multisession ms;
-#ifdef AZT_DEBUG
-                       printk("aztcd ioctl MULTISESSION\n");
-#endif
-                       if (copy_from_user(&ms, argp,
-                            sizeof(struct cdrom_multisession)))
-                               return -EFAULT;
-                       if (ms.addr_format == CDROM_MSF) {
-                               ms.addr.msf.minute =
-                                   azt_bcd2bin(DiskInfo.lastSession.min);
-                               ms.addr.msf.second =
-                                   azt_bcd2bin(DiskInfo.lastSession.sec);
-                               ms.addr.msf.frame =
-                                   azt_bcd2bin(DiskInfo.lastSession.
-                                               frame);
-                       } else if (ms.addr_format == CDROM_LBA)
-                               ms.addr.lba =
-                                   azt_msf2hsg(&DiskInfo.lastSession);
-                       else
-                               return -EINVAL;
-                       ms.xa_flag = DiskInfo.xa;
-                       if (copy_to_user(argp, &ms,
-                            sizeof(struct cdrom_multisession)))
-                               return -EFAULT;
-#ifdef AZT_DEBUG
-                       if (ms.addr_format == CDROM_MSF)
-                               printk
-                                   ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
-                                    ms.xa_flag, ms.addr.msf.minute,
-                                    ms.addr.msf.second, ms.addr.msf.frame,
-                                    DiskInfo.lastSession.min,
-                                    DiskInfo.lastSession.sec,
-                                    DiskInfo.lastSession.frame);
-                       else
-                               printk
-                                   ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
-                                    ms.xa_flag, ms.addr.lba,
-                                    DiskInfo.lastSession.min,
-                                    DiskInfo.lastSession.sec,
-                                    DiskInfo.lastSession.frame);
-#endif
-                       return 0;
-               }
-       case CDROMPLAYTRKIND:   /* Play a track.  This currently ignores index. */
-               if (copy_from_user(&ti, argp, sizeof ti))
-                       return -EFAULT;
-               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;
-               azt_Play.start = Toc[ti.cdti_trk0].diskTime;
-               azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
-#ifdef AZT_DEBUG
-               printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-                      azt_Play.start.min, azt_Play.start.sec,
-                      azt_Play.start.frame, azt_Play.end.min,
-                      azt_Play.end.sec, azt_Play.end.frame);
-#endif
-               i = aztPlay(&azt_Play);
-               if (i < 0) {
-                       aztAudioStatus = CDROM_AUDIO_ERROR;
-                       return -EIO;
-               }
-               aztAudioStatus = CDROM_AUDIO_PLAY;
-               break;
-       case CDROMPLAYMSF:      /* Play starting at the given MSF address. */
-/*              if (aztAudioStatus == CDROM_AUDIO_PLAY) 
-               { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
-                 STEN_LOW;
-                 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-               }
-*/
-               if (copy_from_user(&msf, argp, sizeof msf))
-                       return -EFAULT;
-               /* convert to bcd */
-               azt_bin2bcd(&msf.cdmsf_min0);
-               azt_bin2bcd(&msf.cdmsf_sec0);
-               azt_bin2bcd(&msf.cdmsf_frame0);
-               azt_bin2bcd(&msf.cdmsf_min1);
-               azt_bin2bcd(&msf.cdmsf_sec1);
-               azt_bin2bcd(&msf.cdmsf_frame1);
-               azt_Play.start.min = msf.cdmsf_min0;
-               azt_Play.start.sec = msf.cdmsf_sec0;
-               azt_Play.start.frame = msf.cdmsf_frame0;
-               azt_Play.end.min = msf.cdmsf_min1;
-               azt_Play.end.sec = msf.cdmsf_sec1;
-               azt_Play.end.frame = msf.cdmsf_frame1;
-#ifdef AZT_DEBUG
-               printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-                      azt_Play.start.min, azt_Play.start.sec,
-                      azt_Play.start.frame, azt_Play.end.min,
-                      azt_Play.end.sec, azt_Play.end.frame);
-#endif
-               i = aztPlay(&azt_Play);
-               if (i < 0) {
-                       aztAudioStatus = CDROM_AUDIO_ERROR;
-                       return -EIO;
-               }
-               aztAudioStatus = CDROM_AUDIO_PLAY;
-               break;
-
-       case CDROMREADTOCHDR:   /* Read the table of contents header */
-               tocHdr.cdth_trk0 = DiskInfo.first;
-               tocHdr.cdth_trk1 = DiskInfo.last;
-               if (copy_to_user(argp, &tocHdr, sizeof tocHdr))
-                       return -EFAULT;
-               break;
-       case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
-               if (copy_from_user(&entry, argp, sizeof entry))
-                       return -EFAULT;
-               if ((!aztTocUpToDate) || aztDiskChanged)
-                       aztUpdateToc();
-               if (entry.cdte_track == CDROM_LEADOUT)
-                       tocPtr = &Toc[DiskInfo.last + 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 =
-                           azt_msf2hsg(&tocPtr->diskTime);
-               else if (entry.cdte_format == CDROM_MSF) {
-                       entry.cdte_addr.msf.minute =
-                           azt_bcd2bin(tocPtr->diskTime.min);
-                       entry.cdte_addr.msf.second =
-                           azt_bcd2bin(tocPtr->diskTime.sec);
-                       entry.cdte_addr.msf.frame =
-                           azt_bcd2bin(tocPtr->diskTime.frame);
-               } else {
-                       return -EINVAL;
-               }
-               if (copy_to_user(argp, &entry, sizeof entry))
-                       return -EFAULT;
-               break;
-       case CDROMSUBCHNL:      /* Get subchannel info */
-               if (copy_from_user
-                   (&subchnl, argp, sizeof(struct cdrom_subchnl)))
-                       return -EFAULT;
-               if (aztGetQChannelInfo(&qInfo) < 0) {
-#ifdef AZT_DEBUG
-                       printk
-                           ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
-                            cmd);
-#endif
-                       return -EIO;
-               }
-               subchnl.cdsc_audiostatus = aztAudioStatus;
-               subchnl.cdsc_adr = qInfo.ctrl_addr;
-               subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
-               subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
-               subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
-               if (subchnl.cdsc_format == CDROM_LBA) {
-                       subchnl.cdsc_absaddr.lba =
-                           azt_msf2hsg(&qInfo.diskTime);
-                       subchnl.cdsc_reladdr.lba =
-                           azt_msf2hsg(&qInfo.trackTime);
-               } else {        /*default */
-                       subchnl.cdsc_format = CDROM_MSF;
-                       subchnl.cdsc_absaddr.msf.minute =
-                           azt_bcd2bin(qInfo.diskTime.min);
-                       subchnl.cdsc_absaddr.msf.second =
-                           azt_bcd2bin(qInfo.diskTime.sec);
-                       subchnl.cdsc_absaddr.msf.frame =
-                           azt_bcd2bin(qInfo.diskTime.frame);
-                       subchnl.cdsc_reladdr.msf.minute =
-                           azt_bcd2bin(qInfo.trackTime.min);
-                       subchnl.cdsc_reladdr.msf.second =
-                           azt_bcd2bin(qInfo.trackTime.sec);
-                       subchnl.cdsc_reladdr.msf.frame =
-                           azt_bcd2bin(qInfo.trackTime.frame);
-               }
-               if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl)))
-                       return -EFAULT;
-               break;
-       case CDROMVOLCTRL:      /* Volume control 
-                                  * With my Aztech CD268-01A volume control does not work, I can only
-                                  turn the channels on (any value !=0) or off (value==0). Maybe it
-                                  works better with your drive */
-               if (copy_from_user(&volctrl, argp, sizeof(volctrl)))
-                       return -EFAULT;
-               azt_Play.start.min = 0x21;
-               azt_Play.start.sec = 0x84;
-               azt_Play.start.frame = volctrl.channel0;
-               azt_Play.end.min = volctrl.channel1;
-               azt_Play.end.sec = volctrl.channel2;
-               azt_Play.end.frame = volctrl.channel3;
-               sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
-               STEN_LOW_WAIT;
-               break;
-       case CDROMEJECT:
-               aztUnlockDoor();        /* Assume user knows what they're doing */
-               /* all drives can at least stop! */
-               if (aztAudioStatus == CDROM_AUDIO_PLAY) {
-                       if (aztSendCmd(ACMD_STOP))
-                               RETURNM("azt_ioctl 10", -1);
-                       STEN_LOW_WAIT;
-               }
-               if (aztSendCmd(ACMD_EJECT))
-                       RETURNM("azt_ioctl 11", -1);
-               STEN_LOW_WAIT;
-               aztAudioStatus = CDROM_AUDIO_NO_STATUS;
-               break;
-       case CDROMEJECT_SW:
-               azt_auto_eject = (char) arg;
-               break;
-       case CDROMRESET:
-               outb(ACMD_SOFT_RESET, CMD_PORT);        /*send reset */
-               STEN_LOW;
-               if (inb(DATA_PORT) != AFL_OP_OK) {      /*OP_OK? */
-                       printk
-                           ("aztcd: AZTECH CD-ROM drive does not respond\n");
-               }
-               break;
-/*Take care, the following code is not compatible with other CD-ROM drivers,
-  use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
-  if you do not want to use it!
-*/
-#if AZT_PRIVATE_IOCTLS
-       case CDROMREADCOOKED:   /*read data in mode 1 (2048 Bytes) */
-       case CDROMREADRAW:      /*read data in mode 2 (2336 Bytes) */
-               {
-                       if (copy_from_user(&msf, argp, sizeof msf))
-                               return -EFAULT;
-                       /* convert to bcd */
-                       azt_bin2bcd(&msf.cdmsf_min0);
-                       azt_bin2bcd(&msf.cdmsf_sec0);
-                       azt_bin2bcd(&msf.cdmsf_frame0);
-                       msf.cdmsf_min1 = 0;
-                       msf.cdmsf_sec1 = 0;
-                       msf.cdmsf_frame1 = 1;   /*read only one frame */
-                       azt_Play.start.min = msf.cdmsf_min0;
-                       azt_Play.start.sec = msf.cdmsf_sec0;
-                       azt_Play.start.frame = msf.cdmsf_frame0;
-                       azt_Play.end.min = msf.cdmsf_min1;
-                       azt_Play.end.sec = msf.cdmsf_sec1;
-                       azt_Play.end.frame = msf.cdmsf_frame1;
-                       if (cmd == CDROMREADRAW) {
-                               if (DiskInfo.xa) {
-                                       return -1;      /*XA Disks can't be read raw */
-                               } else {
-                                       if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play))
-                                               return -1;
-                                       DTEN_LOW;
-                                       insb(DATA_PORT, buf, CD_FRAMESIZE_RAW);
-                                       if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW))
-                                               return -EFAULT;
-                               }
-                       } else
-                               /*CDROMREADCOOKED*/ {
-                               if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
-                                       return -1;
-                               DTEN_LOW;
-                               insb(DATA_PORT, buf, CD_FRAMESIZE);
-                               if (copy_to_user(argp, &buf, CD_FRAMESIZE))
-                                       return -EFAULT;
-                               }
-               }
-               break;
-       case CDROMSEEK: /*seek msf address */
-               if (copy_from_user(&msf, argp, sizeof msf))
-                       return -EFAULT;
-               /* convert to bcd */
-               azt_bin2bcd(&msf.cdmsf_min0);
-               azt_bin2bcd(&msf.cdmsf_sec0);
-               azt_bin2bcd(&msf.cdmsf_frame0);
-               azt_Play.start.min = msf.cdmsf_min0;
-               azt_Play.start.sec = msf.cdmsf_sec0;
-               azt_Play.start.frame = msf.cdmsf_frame0;
-               if (aztSeek(&azt_Play))
-                       return -1;
-               break;
-#endif                         /*end of incompatible code */
-       case CDROMREADMODE1:    /*set read data in mode 1 */
-               return aztSetDiskType(AZT_MODE_1);
-       case CDROMREADMODE2:    /*set read data in mode 2 */
-               return aztSetDiskType(AZT_MODE_2);
-       default:
-               return -EINVAL;
-       }
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztcd_ioctl Command:%x  Time:%li\n", cmd,
-              jiffies);
-#endif
-       return 0;
-}
-
-/*
- * Take care of the different block sizes between cdrom and Linux.
- * When Linux gets variable block sizes this will probably go away.
- */
-static void azt_transfer(void)
-{
-#ifdef AZT_TEST
-       printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
-#endif
-       if (!current_valid())
-               return;
-
-       while (CURRENT->nr_sectors) {
-               int bn = CURRENT->sector / 4;
-               int i;
-               for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i);
-               if (i < AZT_BUF_SIZ) {
-                       int offs = (i * 4 + (CURRENT->sector & 3)) * 512;
-                       int nr_sectors = 4 - (CURRENT->sector & 3);
-                       if (azt_buf_out != i) {
-                               azt_buf_out = i;
-                               if (azt_buf_bn[i] != bn) {
-                                       azt_buf_out = -1;
-                                       continue;
-                               }
-                       }
-                       if (nr_sectors > CURRENT->nr_sectors)
-                           nr_sectors = CURRENT->nr_sectors;
-                       memcpy(CURRENT->buffer, azt_buf + offs,
-                               nr_sectors * 512);
-                       CURRENT->nr_sectors -= nr_sectors;
-                       CURRENT->sector += nr_sectors;
-                       CURRENT->buffer += nr_sectors * 512;
-               } else {
-                       azt_buf_out = -1;
-                       break;
-               }
-       }
-}
-
-static void do_aztcd_request(request_queue_t * q)
-{
-#ifdef AZT_TEST
-       printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
-              CURRENT->nr_sectors, jiffies);
-#endif
-       if (DiskInfo.audio) {
-               printk("aztcd: Error, tried to mount an Audio CD\n");
-               end_request(CURRENT, 0);
-               return;
-       }
-       azt_transfer_is_active = 1;
-       while (current_valid()) {
-               azt_transfer();
-               if (CURRENT->nr_sectors == 0) {
-                       end_request(CURRENT, 1);
-               } else {
-                       azt_buf_out = -1;       /* Want to read a block not in buffer */
-                       if (azt_state == AZT_S_IDLE) {
-                               if ((!aztTocUpToDate) || aztDiskChanged) {
-                                       if (aztUpdateToc() < 0) {
-                                               while (current_valid())
-                                                       end_request(CURRENT, 0);
-                                               break;
-                                       }
-                               }
-                               azt_state = AZT_S_START;
-                               AztTries = 5;
-                               SET_TIMER(azt_poll, HZ / 100);
-                       }
-                       break;
-               }
-       }
-       azt_transfer_is_active = 0;
-#ifdef AZT_TEST2
-       printk
-           ("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n",
-            azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
-       printk(" do_aztcd_request ends  Time:%li\n", jiffies);
-#endif
-}
-
-
-static void azt_invalidate_buffers(void)
-{
-       int i;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: executing azt_invalidate_buffers\n");
-#endif
-       for (i = 0; i < AZT_BUF_SIZ; ++i)
-               azt_buf_bn[i] = -1;
-       azt_buf_out = -1;
-}
-
-/*
- * Open the device special file.  Check that a disk is in.
- */
-static int aztcd_open(struct inode *ip, struct file *fp)
-{
-       int st;
-
-#ifdef AZT_DEBUG
-       printk("aztcd: starting aztcd_open\n");
-#endif
-
-       if (aztPresent == 0)
-               return -ENXIO;  /* no hardware */
-
-       if (!azt_open_count && azt_state == AZT_S_IDLE) {
-               azt_invalidate_buffers();
-
-               st = getAztStatus();    /* check drive status */
-               if (st == -1)
-                       goto err_out;   /* drive doesn't respond */
-
-               if (st & AST_DOOR_OPEN) {       /* close door, then get the status again. */
-                       printk("aztcd: Door Open?\n");
-                       aztCloseDoor();
-                       st = getAztStatus();
-               }
-
-               if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) {       /*no disk in drive or changed */
-                       printk
-                           ("aztcd: Disk Changed or No Disk in Drive?\n");
-                       aztTocUpToDate = 0;
-               }
-               if (aztUpdateToc())
-                       goto err_out;
-
-       }
-       ++azt_open_count;
-       aztLockDoor();
-
-#ifdef AZT_DEBUG
-       printk("aztcd: exiting aztcd_open\n");
-#endif
-       return 0;
-
-      err_out:
-       return -EIO;
-}
-
-
-/*
- * On close, we flush all azt blocks from the buffer cache.
- */
-static int aztcd_release(struct inode *inode, struct file *file)
-{
-#ifdef AZT_DEBUG
-       printk("aztcd: executing aztcd_release\n");
-       printk("inode: %p, device: %s    file: %p\n", inode,
-              inode->i_bdev->bd_disk->disk_name, file);
-#endif
-       if (!--azt_open_count) {
-               azt_invalidate_buffers();
-               aztUnlockDoor();
-               if (azt_auto_eject)
-                       aztSendCmd(ACMD_EJECT);
-               CLEAR_TIMER;
-       }
-       return 0;
-}
-
-static struct gendisk *azt_disk;
-
-/*
- * Test for presence of drive and initialize it.  Called at boot time.
- */
-
-static int __init aztcd_init(void)
-{
-       long int count, max_count;
-       unsigned char result[50];
-       int st;
-       void* status = NULL;
-       int i = 0;
-       int ret = 0;
-
-       if (azt_port == 0) {
-               printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization");
-               return -EIO;
-       }
-
-       printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM "
-              "CD-ROM Driver\n");
-       printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
-       if (azt_port == -1) {
-               printk
-                   ("aztcd: DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
-                    AZT_VERSION);
-       } else
-               printk
-                   ("aztcd: DriverVersion=%s BaseAddress=0x%x  For IDE/ATAPI-drives use ide-cd.c\n",
-                    AZT_VERSION, azt_port);
-       printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/"
-              "Documentation/cdrom/aztcd\n");
-
-
-#ifdef AZT_SW32                        /*CDROM connected to Soundwave32 card */
-       if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
-               printk
-                   ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
-                    AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
-                    AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
-               return -EIO;
-       } else {
-               printk(KERN_INFO
-                      "aztcd: Soundwave32 card detected at %x  Version %x\n",
-                      AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
-               outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
-               for (count = 0; count < 10000; count++);        /*delay a bit */
-       }
-#endif
-
-       /* check for presence of drive */
-
-       if (azt_port == -1) {   /* autoprobing for proprietary interface  */
-               for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
-                       azt_port = azt_port_auto[i];
-                       printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x"
-                              "\n", azt_port);
-                        /*proprietary interfaces need 4 bytes */
-                       if (!request_region(azt_port, 4, "aztcd")) {
-                               continue;
-                       }
-                       outb(POLLED, MODE_PORT);
-                       inb(CMD_PORT);
-                       inb(CMD_PORT);
-                       outb(ACMD_GET_VERSION, CMD_PORT);       /*Try to get version info */
-
-                       aztTimeOutCount = 0;
-                       do {
-                               aztIndatum = inb(STATUS_PORT);
-                               aztTimeOutCount++;
-                               if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
-                                       break;
-                       } while (aztIndatum & AFL_STATUS);
-                       if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */
-                               break;
-                       }
-                       else {  /* Drive not found on this port - try next one */
-                               release_region(azt_port, 4);
-                       }
-               }
-               if ((i == 16) || (azt_port_auto[i] == 0)) {
-                       printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n");
-                       return -EIO;
-               }
-       } else {                /* no autoprobing */
-               if ((azt_port == 0x1f0) || (azt_port == 0x170))
-                       status = request_region(azt_port, 8, "aztcd");  /*IDE-interfaces need 8 bytes */
-               else
-                       status = request_region(azt_port, 4, "aztcd");  /*proprietary interfaces need 4 bytes */
-               if (!status) {
-                       printk(KERN_WARNING "aztcd: conflict, I/O port (%X) "
-                              "already used\n", azt_port);
-                       return -EIO;
-               }
-
-               if ((azt_port == 0x1f0) || (azt_port == 0x170))
-                       SWITCH_IDE_SLAVE;       /*switch IDE interface to slave configuration */
-
-               outb(POLLED, MODE_PORT);
-               inb(CMD_PORT);
-               inb(CMD_PORT);
-               outb(ACMD_GET_VERSION, CMD_PORT);       /*Try to get version info */
-
-               aztTimeOutCount = 0;
-               do {
-                       aztIndatum = inb(STATUS_PORT);
-                       aztTimeOutCount++;
-                       if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
-                               break;
-               } while (aztIndatum & AFL_STATUS);
-
-               if (inb(DATA_PORT) != AFL_OP_OK) {      /*OP_OK? If not, reset and try again */
-#ifndef MODULE
-                       if (azt_cont != 0x79) {
-                               printk(KERN_WARNING "aztcd: no AZTECH CD-ROM "
-                                      "drive found-Try boot parameter aztcd="
-                                      "<BaseAddress>,0x79\n");
-                               ret = -EIO;
-                               goto err_out;
-                       }
-#else
-                       if (0) {
-                       }
-#endif
-                       else {
-                               printk(KERN_INFO "aztcd: drive reset - "
-                                      "please wait\n");
-                               for (count = 0; count < 50; count++) {
-                                       inb(STATUS_PORT);       /*removing all data from earlier tries */
-                                       inb(DATA_PORT);
-                               }
-                               outb(POLLED, MODE_PORT);
-                               inb(CMD_PORT);
-                               inb(CMD_PORT);
-                               getAztStatus(); /*trap errors */
-                               outb(ACMD_SOFT_RESET, CMD_PORT);        /*send reset */
-                               STEN_LOW;
-                               if (inb(DATA_PORT) != AFL_OP_OK) {      /*OP_OK? */
-                                       printk(KERN_WARNING "aztcd: no AZTECH "
-                                              "CD-ROM drive found\n");
-                                       ret = -EIO;
-                                       goto err_out;
-                               }
-
-                               for (count = 0; count < AZT_TIMEOUT;
-                                    count++)
-                                       barrier();      /* Stop gcc 2.96 being smart */
-                               /* use udelay(), damnit -- AV */
-
-                               if ((st = getAztStatus()) == -1) {
-                                       printk(KERN_WARNING "aztcd: Drive Status"
-                                              " Error Status=%x\n", st);
-                                       ret = -EIO;
-                                       goto err_out;
-                               }
-#ifdef AZT_DEBUG
-                               printk(KERN_DEBUG "aztcd: Status = %x\n", st);
-#endif
-                               outb(POLLED, MODE_PORT);
-                               inb(CMD_PORT);
-                               inb(CMD_PORT);
-                               outb(ACMD_GET_VERSION, CMD_PORT);       /*GetVersion */
-                               STEN_LOW;
-                               OP_OK;
-                       }
-               }
-       }
-
-       azt_init_end = 1;
-       STEN_LOW;
-       result[0] = inb(DATA_PORT);     /*reading in a null byte??? */
-       for (count = 1; count < 50; count++) {  /*Reading version string */
-               aztTimeOutCount = 0;    /*here we must implement STEN_LOW differently */
-               do {
-                       aztIndatum = inb(STATUS_PORT);  /*because we want to exit by timeout */
-                       aztTimeOutCount++;
-                       if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
-                               break;
-               } while (aztIndatum & AFL_STATUS);
-               if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
-                       break;  /*all chars read? */
-               result[count] = inb(DATA_PORT);
-       }
-       if (count > 30)
-               max_count = 30; /*print max.30 chars of the version string */
-       else
-               max_count = count;
-       printk(KERN_INFO "aztcd: FirmwareVersion=");
-       for (count = 1; count < max_count; count++)
-               printk("%c", result[count]);
-       printk("<<>> ");
-
-       if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
-               printk("AZTECH drive detected\n");
-       /*AZTECH*/}
-               else if ((result[2] == 'C') && (result[3] == 'D')
-                        && (result[4] == 'D')) {
-               printk("ORCHID or WEARNES drive detected\n");   /*ORCHID or WEARNES */
-       } else if ((result[1] == 0x03) && (result[2] == '5')) {
-               printk("TXC or CyCDROM drive detected\n");      /*Conrad TXC, CyCDROM */
-       } else {                /*OTHERS or none */
-               printk("\nunknown drive or firmware version detected\n");
-               printk
-                   ("aztcd may not run stable, if you want to try anyhow,\n");
-               printk("boot with: aztcd=<BaseAddress>,0x79\n");
-               if ((azt_cont != 0x79)) {
-                       printk("aztcd: FirmwareVersion=");
-                       for (count = 1; count < 5; count++)
-                               printk("%c", result[count]);
-                       printk("<<>> ");
-                       printk("Aborted\n");
-                       ret = -EIO;
-                       goto err_out;
-               }
-       }
-       azt_disk = alloc_disk(1);
-       if (!azt_disk)
-               goto err_out;
-
-       if (register_blkdev(MAJOR_NR, "aztcd")) {
-               ret = -EIO;
-               goto err_out2;
-       }
-
-       azt_queue = blk_init_queue(do_aztcd_request, &aztSpin);
-       if (!azt_queue) {
-               ret = -ENOMEM;
-               goto err_out3;
-       }
-
-       blk_queue_hardsect_size(azt_queue, 2048);
-       azt_disk->major = MAJOR_NR;
-       azt_disk->first_minor = 0;
-       azt_disk->fops = &azt_fops;
-       sprintf(azt_disk->disk_name, "aztcd");
-       azt_disk->queue = azt_queue;
-       add_disk(azt_disk);
-       azt_invalidate_buffers();
-       aztPresent = 1;
-       aztCloseDoor();
-       return 0;
-err_out3:
-       unregister_blkdev(MAJOR_NR, "aztcd");
-err_out2:
-       put_disk(azt_disk);
-err_out:
-       if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
-               SWITCH_IDE_MASTER;
-               release_region(azt_port, 8);    /*IDE-interface */
-       } else
-               release_region(azt_port, 4);    /*proprietary interface */
-       return ret;
-
-}
-
-static void __exit aztcd_exit(void)
-{
-       del_gendisk(azt_disk);
-       put_disk(azt_disk);
-       if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
-               printk("What's that: can't unregister aztcd\n");
-               return;
-       }
-       blk_cleanup_queue(azt_queue);
-       if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
-               SWITCH_IDE_MASTER;
-               release_region(azt_port, 8);    /*IDE-interface */
-       } else
-               release_region(azt_port, 4);    /*proprietary interface */
-       printk(KERN_INFO "aztcd module released.\n");
-}
-
-module_init(aztcd_init);
-module_exit(aztcd_exit);
-
-/*##########################################################################
-  Aztcd State Machine: Controls Drive Operating State
-  ##########################################################################
-*/
-static void azt_poll(void)
-{
-       int st = 0;
-       int loop_ctl = 1;
-       int skip = 0;
-
-       if (azt_error) {
-               if (aztSendCmd(ACMD_GET_ERROR))
-                       RETURN("azt_poll 1");
-               STEN_LOW;
-               azt_error = inb(DATA_PORT) & 0xFF;
-               printk("aztcd: I/O error 0x%02x\n", azt_error);
-               azt_invalidate_buffers();
-#ifdef WARN_IF_READ_FAILURE
-               if (AztTries == 5)
-                       printk
-                           ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
-                            azt_next_bn);
-#endif
-               if (!AztTries--) {
-                       printk
-                           ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
-                            azt_next_bn);
-                       if (azt_transfer_is_active) {
-                               AztTries = 0;
-                               loop_ctl = 0;
-                       }
-                       if (current_valid())
-                               end_request(CURRENT, 0);
-                       AztTries = 5;
-               }
-               azt_error = 0;
-               azt_state = AZT_S_STOP;
-       }
-
-       while (loop_ctl) {
-               loop_ctl = 0;   /* each case must flip this back to 1 if we want
-                                  to come back up here */
-               switch (azt_state) {
-
-               case AZT_S_IDLE:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_IDLE\n");
-                       }
-#endif
-                       return;
-
-               case AZT_S_START:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_START\n");
-                       }
-#endif
-                       if (aztSendCmd(ACMD_GET_STATUS))
-                               RETURN("azt_poll 2");   /*result will be checked by aztStatus() */
-                       azt_state =
-                           azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
-                       AztTimeout = 3000;
-                       break;
-
-               case AZT_S_MODE:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_MODE\n");
-                       }
-#endif
-                       if (!skip) {
-                               if ((st = aztStatus()) != -1) {
-                                       if ((st & AST_DSK_CHG)
-                                           || (st & AST_NOT_READY)) {
-                                               aztDiskChanged = 1;
-                                               aztTocUpToDate = 0;
-                                               azt_invalidate_buffers();
-                                               end_request(CURRENT, 0);
-                                               printk
-                                                   ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
-                                       }
-                               } else
-                                       break;
-                       }
-                       skip = 0;
-
-                       if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
-                               aztDiskChanged = 1;
-                               aztTocUpToDate = 0;
-                               printk
-                                   ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
-                               end_request(CURRENT, 0);
-                               printk((st & AST_DOOR_OPEN) ?
-                                      "aztcd: door open\n" :
-                                      "aztcd: disk removed\n");
-                               if (azt_transfer_is_active) {
-                                       azt_state = AZT_S_START;
-                                       loop_ctl = 1;   /* goto immediately */
-                                       break;
-                               }
-                               azt_state = AZT_S_IDLE;
-                               while (current_valid())
-                                       end_request(CURRENT, 0);
-                               return;
-                       }
-
-/*       if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
-         outb(0x01, DATA_PORT);
-         PA_OK;
-         STEN_LOW;
-*/
-                       if (aztSendCmd(ACMD_GET_STATUS))
-                               RETURN("azt_poll 4");
-                       STEN_LOW;
-                       azt_mode = 1;
-                       azt_state = AZT_S_READ;
-                       AztTimeout = 3000;
-
-                       break;
-
-
-               case AZT_S_READ:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_READ\n");
-                       }
-#endif
-                       if (!skip) {
-                               if ((st = aztStatus()) != -1) {
-                                       if ((st & AST_DSK_CHG)
-                                           || (st & AST_NOT_READY)) {
-                                               aztDiskChanged = 1;
-                                               aztTocUpToDate = 0;
-                                               azt_invalidate_buffers();
-                                               printk
-                                                   ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
-                                               end_request(CURRENT, 0);
-                                       }
-                               } else
-                                       break;
-                       }
-
-                       skip = 0;
-                       if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
-                               aztDiskChanged = 1;
-                               aztTocUpToDate = 0;
-                               printk((st & AST_DOOR_OPEN) ?
-                                      "aztcd: door open\n" :
-                                      "aztcd: disk removed\n");
-                               if (azt_transfer_is_active) {
-                                       azt_state = AZT_S_START;
-                                       loop_ctl = 1;
-                                       break;
-                               }
-                               azt_state = AZT_S_IDLE;
-                               while (current_valid())
-                                       end_request(CURRENT, 0);
-                               return;
-                       }
-
-                       if (current_valid()) {
-                               struct azt_Play_msf msf;
-                               int i;
-                               azt_next_bn = CURRENT->sector / 4;
-                               azt_hsg2msf(azt_next_bn, &msf.start);
-                               i = 0;
-                               /* find out in which track we are */
-                               while (azt_msf2hsg(&msf.start) >
-                                      azt_msf2hsg(&Toc[++i].trackTime)) {
-                               };
-                               if (azt_msf2hsg(&msf.start) <
-                                   azt_msf2hsg(&Toc[i].trackTime) -
-                                   AZT_BUF_SIZ) {
-                                       azt_read_count = AZT_BUF_SIZ;   /*fast, because we read ahead */
-                                       /*azt_read_count=CURRENT->nr_sectors;    slow, no read ahead */
-                               } else  /* don't read beyond end of track */
-#if AZT_MULTISESSION
-                               {
-                                       azt_read_count =
-                                           (azt_msf2hsg(&Toc[i].trackTime)
-                                            / 4) * 4 -
-                                           azt_msf2hsg(&msf.start);
-                                       if (azt_read_count < 0)
-                                               azt_read_count = 0;
-                                       if (azt_read_count > AZT_BUF_SIZ)
-                                               azt_read_count =
-                                                   AZT_BUF_SIZ;
-                                       printk
-                                           ("aztcd: warning - trying to read beyond end of track\n");
-/*               printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
-*/ }
-#else
-                               {
-                                       azt_read_count = AZT_BUF_SIZ;
-                               }
-#endif
-                               msf.end.min = 0;
-                               msf.end.sec = 0;
-                               msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
-#ifdef AZT_TEST3
-                               printk
-                                   ("---reading msf-address %x:%x:%x  %x:%x:%x\n",
-                                    msf.start.min, msf.start.sec,
-                                    msf.start.frame, msf.end.min,
-                                    msf.end.sec, msf.end.frame);
-                               printk
-                                   ("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n",
-                                    azt_next_bn, azt_buf_in, azt_buf_out,
-                                    azt_buf_bn[azt_buf_in]);
-#endif
-                               if (azt_read_mode == AZT_MODE_2) {
-                                       sendAztCmd(ACMD_PLAY_READ_RAW, &msf);   /*XA disks in raw mode */
-                               } else {
-                                       sendAztCmd(ACMD_PLAY_READ, &msf);       /*others in cooked mode */
-                               }
-                               azt_state = AZT_S_DATA;
-                               AztTimeout = READ_TIMEOUT;
-                       } else {
-                               azt_state = AZT_S_STOP;
-                               loop_ctl = 1;
-                               break;
-                       }
-
-                       break;
-
-
-               case AZT_S_DATA:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_DATA\n");
-                       }
-#endif
-
-                       st = inb(STATUS_PORT) & AFL_STATUSorDATA;
-
-                       switch (st) {
-
-                       case AFL_DATA:
-#ifdef AZT_TEST3
-                               if (st != azt_st_old) {
-                                       azt_st_old = st;
-                                       printk("---AFL_DATA st:%x\n", st);
-                               }
-#endif
-                               if (!AztTries--) {
-                                       printk
-                                           ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
-                                            azt_next_bn);
-                                       if (azt_transfer_is_active) {
-                                               AztTries = 0;
-                                               break;
-                                       }
-                                       if (current_valid())
-                                               end_request(CURRENT, 0);
-                                       AztTries = 5;
-                               }
-                               azt_state = AZT_S_START;
-                               AztTimeout = READ_TIMEOUT;
-                               loop_ctl = 1;
-                               break;
-
-                       case AFL_STATUSorDATA:
-#ifdef AZT_TEST3
-                               if (st != azt_st_old) {
-                                       azt_st_old = st;
-                                       printk
-                                           ("---AFL_STATUSorDATA st:%x\n",
-                                            st);
-                               }
-#endif
-                               break;
-
-                       default:
-#ifdef AZT_TEST3
-                               if (st != azt_st_old) {
-                                       azt_st_old = st;
-                                       printk("---default: st:%x\n", st);
-                               }
-#endif
-                               AztTries = 5;
-                               if (!current_valid() && azt_buf_in == azt_buf_out) {
-                                       azt_state = AZT_S_STOP;
-                                       loop_ctl = 1;
-                                       break;
-                               }
-                               if (azt_read_count <= 0)
-                                       printk
-                                           ("aztcd: warning - try to read 0 frames\n");
-                               while (azt_read_count) {        /*??? fast read ahead loop */
-                                       azt_buf_bn[azt_buf_in] = -1;
-                                       DTEN_LOW;       /*??? unsolved problem, very
-                                                          seldom we get timeouts
-                                                          here, don't now the real
-                                                          reason. With my drive this
-                                                          sometimes also happens with
-                                                          Aztech's original driver under
-                                                          DOS. Is it a hardware bug? 
-                                                          I tried to recover from such
-                                                          situations here. Zimmermann */
-                                       if (aztTimeOutCount >= AZT_TIMEOUT) {
-                                               printk
-                                                   ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
-                                                    azt_read_count,
-                                                    CURRENT->nr_sectors,
-                                                    azt_buf_in);
-                                               printk
-                                                   ("azt_transfer_is_active:%x\n",
-                                                    azt_transfer_is_active);
-                                               azt_read_count = 0;
-                                               azt_state = AZT_S_STOP;
-                                               loop_ctl = 1;
-                                               end_request(CURRENT, 1);        /*should we have here (1) or (0)? */
-                                       } else {
-                                               if (azt_read_mode ==
-                                                   AZT_MODE_2) {
-                                                       insb(DATA_PORT,
-                                                            azt_buf +
-                                                            CD_FRAMESIZE_RAW
-                                                            * azt_buf_in,
-                                                            CD_FRAMESIZE_RAW);
-                                               } else {
-                                                       insb(DATA_PORT,
-                                                            azt_buf +
-                                                            CD_FRAMESIZE *
-                                                            azt_buf_in,
-                                                            CD_FRAMESIZE);
-                                               }
-                                               azt_read_count--;
-#ifdef AZT_TEST3
-                                               printk
-                                                   ("AZT_S_DATA; ---I've read data- read_count: %d\n",
-                                                    azt_read_count);
-                                               printk
-                                                   ("azt_next_bn:%d  azt_buf_in:%d azt_buf_out:%d  azt_buf_bn:%d\n",
-                                                    azt_next_bn,
-                                                    azt_buf_in,
-                                                    azt_buf_out,
-                                                    azt_buf_bn
-                                                    [azt_buf_in]);
-#endif
-                                               azt_buf_bn[azt_buf_in] =
-                                                   azt_next_bn++;
-                                               if (azt_buf_out == -1)
-                                                       azt_buf_out =
-                                                           azt_buf_in;
-                                               azt_buf_in =
-                                                   azt_buf_in + 1 ==
-                                                   AZT_BUF_SIZ ? 0 :
-                                                   azt_buf_in + 1;
-                                       }
-                               }
-                               if (!azt_transfer_is_active) {
-                                       while (current_valid()) {
-                                               azt_transfer();
-                                               if (CURRENT->nr_sectors ==
-                                                   0)
-                                                       end_request(CURRENT, 1);
-                                               else
-                                                       break;
-                                       }
-                               }
-
-                               if (current_valid()
-                                   && (CURRENT->sector / 4 < azt_next_bn
-                                       || CURRENT->sector / 4 >
-                                       azt_next_bn + AZT_BUF_SIZ)) {
-                                       azt_state = AZT_S_STOP;
-                                       loop_ctl = 1;
-                                       break;
-                               }
-                               AztTimeout = READ_TIMEOUT;
-                               if (azt_read_count == 0) {
-                                       azt_state = AZT_S_STOP;
-                                       loop_ctl = 1;
-                                       break;
-                               }
-                               break;
-                       }
-                       break;
-
-
-               case AZT_S_STOP:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_STOP\n");
-                       }
-#endif
-                       if (azt_read_count != 0)
-                               printk("aztcd: discard data=%x frames\n",
-                                      azt_read_count);
-                       while (azt_read_count != 0) {
-                               int i;
-                               if (!(inb(STATUS_PORT) & AFL_DATA)) {
-                                       if (azt_read_mode == AZT_MODE_2)
-                                               for (i = 0;
-                                                    i < CD_FRAMESIZE_RAW;
-                                                    i++)
-                                                       inb(DATA_PORT);
-                                       else
-                                               for (i = 0;
-                                                    i < CD_FRAMESIZE; i++)
-                                                       inb(DATA_PORT);
-                               }
-                               azt_read_count--;
-                       }
-                       if (aztSendCmd(ACMD_GET_STATUS))
-                               RETURN("azt_poll 5");
-                       azt_state = AZT_S_STOPPING;
-                       AztTimeout = 1000;
-                       break;
-
-               case AZT_S_STOPPING:
-#ifdef AZT_TEST3
-                       if (azt_state != azt_state_old) {
-                               azt_state_old = azt_state;
-                               printk("AZT_S_STOPPING\n");
-                       }
-#endif
-
-                       if ((st = aztStatus()) == -1 && AztTimeout)
-                               break;
-
-                       if ((st != -1)
-                           && ((st & AST_DSK_CHG)
-                               || (st & AST_NOT_READY))) {
-                               aztDiskChanged = 1;
-                               aztTocUpToDate = 0;
-                               azt_invalidate_buffers();
-                               printk
-                                   ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
-                               end_request(CURRENT, 0);
-                       }
-
-#ifdef AZT_TEST3
-                       printk("CURRENT_VALID %d azt_mode %d\n",
-                              current_valid(), azt_mode);
-#endif
-
-                       if (current_valid()) {
-                               if (st != -1) {
-                                       if (azt_mode == 1) {
-                                               azt_state = AZT_S_READ;
-                                               loop_ctl = 1;
-                                               skip = 1;
-                                               break;
-                                       } else {
-                                               azt_state = AZT_S_MODE;
-                                               loop_ctl = 1;
-                                               skip = 1;
-                                               break;
-                                       }
-                               } else {
-                                       azt_state = AZT_S_START;
-                                       AztTimeout = 1;
-                               }
-                       } else {
-                               azt_state = AZT_S_IDLE;
-                               return;
-                       }
-                       break;
-
-               default:
-                       printk("aztcd: invalid state %d\n", azt_state);
-                       return;
-               }               /* case */
-       }                       /* while */
-
-
-       if (!AztTimeout--) {
-               printk("aztcd: timeout in state %d\n", azt_state);
-               azt_state = AZT_S_STOP;
-               if (aztSendCmd(ACMD_STOP))
-                       RETURN("azt_poll 6");
-               STEN_LOW_WAIT;
-       };
-
-       SET_TIMER(azt_poll, HZ / 100);
-}
-
-
-/*###########################################################################
- * Miscellaneous support functions
-  ###########################################################################
-*/
-static void azt_hsg2msf(long hsg, struct msf *msf)
-{
-       hsg += 150;
-       msf->min = hsg / 4500;
-       hsg %= 4500;
-       msf->sec = hsg / 75;
-       msf->frame = hsg % 75;
-#ifdef AZT_DEBUG
-       if (msf->min >= 70)
-               printk("aztcd: Error hsg2msf address Minutes\n");
-       if (msf->sec >= 60)
-               printk("aztcd: Error hsg2msf address Seconds\n");
-       if (msf->frame >= 75)
-               printk("aztcd: Error hsg2msf address Frames\n");
-#endif
-       azt_bin2bcd(&msf->min); /* convert to BCD */
-       azt_bin2bcd(&msf->sec);
-       azt_bin2bcd(&msf->frame);
-}
-
-static long azt_msf2hsg(struct msf *mp)
-{
-       return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
-           + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
-}
-
-static void azt_bin2bcd(unsigned char *p)
-{
-       int u, t;
-
-       u = *p % 10;
-       t = *p / 10;
-       *p = u | (t << 4);
-}
-
-static int azt_bcd2bin(unsigned char bcd)
-{
-       return (bcd >> 4) * 10 + (bcd & 0xF);
-}
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);
diff --git a/drivers/cdrom/aztcd.h b/drivers/cdrom/aztcd.h
deleted file mode 100644 (file)
index 057501e..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* $Id: aztcd.h,v 2.60 1997/11/29 09:51:22 root Exp root $
- *
- * Definitions for a AztechCD268 CD-ROM interface
- *     Copyright (C) 1994-98  Werner Zimmermann
- *
- *     based on Mitsumi CDROM driver by Martin Harriss
- *
- *  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.
- *
- *  History:   W.Zimmermann adaption to Aztech CD268-01A Version 1.3
- *             October 1994 Email: Werner.Zimmermann@fht-esslingen.de
- */
-
-/* *** change this to set the I/O port address of your CD-ROM drive,
-       set to '-1', if you want autoprobing */
-#define AZT_BASE_ADDR          -1
-
-/* list of autoprobing addresses (not more than 15), last value must be 0x000
-   Note: Autoprobing is only enabled, if AZT_BASE_ADDR is set to '-1' ! */
-#define AZT_BASE_AUTO          { 0x320, 0x300, 0x310, 0x330, 0x000 }
-
-/* Uncomment this, if your CDROM is connected to a Soundwave32-soundcard
-   and configure AZT_BASE_ADDR and AZT_SW32_BASE_ADDR */
-/*#define AZT_SW32 1
-*/
-
-#ifdef AZT_SW32 
-#define AZT_SW32_BASE_ADDR      0x220  /*I/O port base address of your soundcard*/
-#endif
-
-/* Set this to 1, if you want your tray to be locked, set to 0 to prevent tray 
-   from locking */
-#define AZT_ALLOW_TRAY_LOCK    1
-
-/*Set this to 1 to allow auto-eject when unmounting a disk, set to 0, if you 
-  don't want the auto-eject feature*/
-#define AZT_AUTO_EJECT          0
-
-/*Set this to 1, if you want to use incompatible ioctls for reading in raw and
-  cooked mode */
-#define AZT_PRIVATE_IOCTLS      1
-
-/*Set this to 1, if you want multisession support by the ISO fs. Even if you set 
-  this value to '0' you can use multisession CDs. In that case the drive's firm-
-  ware will do the appropriate redirection automatically. The CD will then look
-  like a single session CD (but nevertheless all data may be read). Please read 
-  chapter '5.1 Multisession support' in README.aztcd for details. Normally it's 
-  uncritical to leave this setting untouched */
-#define AZT_MULTISESSION        1
-
-/*Uncomment this, if you are using a linux kernel version prior to 2.1.0 */
-/*#define AZT_KERNEL_PRIOR_2_1 */
-
-/*---------------------------------------------------------------------------*/
-/*-----nothing to be configured for normal applications below this line------*/
-
-
-/* Increase this if you get lots of timeouts; if you get kernel panic, replace
-   STEN_LOW_WAIT by STEN_LOW in the source code */
-#define AZT_STATUS_DELAY       400       /*for timer wait, STEN_LOW_WAIT*/
-#define AZT_TIMEOUT            8000000   /*for busy wait STEN_LOW, DTEN_LOW*/
-#define AZT_FAST_TIMEOUT       10000     /*for reading the version string*/
-
-/* number of times to retry a command before giving up */
-#define AZT_RETRY_ATTEMPTS     3
-
-/* port access macros */
-#define CMD_PORT               azt_port
-#define DATA_PORT              azt_port
-#define STATUS_PORT            azt_port+1
-#define MODE_PORT              azt_port+2
-#ifdef  AZT_SW32                
- #define AZT_SW32_INIT          (unsigned int) (0xFF00 & (AZT_BASE_ADDR*16))
- #define AZT_SW32_CONFIG_REG    AZT_SW32_BASE_ADDR+0x16  /*Soundwave32 Config. Register*/
- #define AZT_SW32_ID_REG        AZT_SW32_BASE_ADDR+0x04  /*Soundwave32 ID Version Register*/
-#endif
-
-/* status bits */
-#define AST_CMD_CHECK          0x80            /* 1 = command error */
-#define AST_DOOR_OPEN          0x40            /* 1 = door is open */
-#define AST_NOT_READY          0x20            /* 1 = no disk in the drive */
-#define AST_DSK_CHG            0x02            /* 1 = disk removed or changed */
-#define AST_MODE                0x01            /* 0=MODE1, 1=MODE2 */
-#define AST_MODE_BITS          0x1C            /* Mode Bits */
-#define AST_INITIAL            0x0C            /* initial, only valid ... */
-#define AST_BUSY               0x04            /* now playing, only valid
-                                                  in combination with mode
-                                                  bits */
-/* flag bits */
-#define AFL_DATA               0x02            /* data available if low */
-#define AFL_STATUS             0x04            /* status available if low */
-#define AFL_OP_OK              0x01            /* OP_OK command correct*/
-#define AFL_PA_OK              0x02            /* PA_OK parameter correct*/
-#define AFL_OP_ERR             0x05            /* error in command*/
-#define AFL_PA_ERR             0x06            /* error in parameters*/
-#define POLLED                 0x04            /* polled mode */
-
-/* commands */
-#define ACMD_SOFT_RESET                0x10            /* reset drive */
-#define ACMD_PLAY_READ         0x20            /* read data track in cooked mode */
-#define ACMD_PLAY_READ_RAW      0x21           /* reading in raw mode*/
-#define ACMD_SEEK               0x30            /* seek msf address*/
-#define ACMD_SEEK_TO_LEADIN     0x31           /* seek to leadin track*/
-#define ACMD_GET_ERROR         0x40            /* get error code */
-#define ACMD_GET_STATUS                0x41            /* get status */
-#define ACMD_GET_Q_CHANNEL      0x50           /* read info from q channel */
-#define ACMD_EJECT             0x60            /* eject/open tray */
-#define ACMD_CLOSE              0x61            /* close tray */
-#define ACMD_LOCK              0x71            /* lock tray closed */
-#define ACMD_UNLOCK            0x72            /* unlock tray */
-#define ACMD_PAUSE             0x80            /* pause */
-#define ACMD_STOP              0x81            /* stop play */
-#define ACMD_PLAY_AUDIO                0x90            /* play audio track */
-#define ACMD_SET_VOLUME                0x93            /* set audio level */
-#define ACMD_GET_VERSION       0xA0            /* get firmware version */
-#define ACMD_SET_DISK_TYPE     0xA1            /* set disk data mode */
-
-#define MAX_TRACKS             104
-
-struct msf {
-       unsigned char   min;
-       unsigned char   sec;
-       unsigned char   frame;
-};
-
-struct azt_Play_msf {
-       struct msf      start;
-       struct msf      end;
-};
-
-struct azt_DiskInfo {
-       unsigned char   first;
-        unsigned char   next;
-       unsigned char   last;
-       struct msf      diskLength;
-       struct msf      firstTrack;
-        unsigned char   multi;
-        struct msf      nextSession;
-        struct msf      lastSession;
-        unsigned char   xa;
-        unsigned char   audio;
-};
-
-struct azt_Toc {
-       unsigned char   ctrl_addr;
-       unsigned char   track;
-       unsigned char   pointIndex;
-       struct msf      trackTime;
-       struct msf      diskTime;
-};
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
deleted file mode 100644 (file)
index 2157c58..0000000
+++ /dev/null
@@ -1,3251 +0,0 @@
-/*
-* Sony CDU-31A CDROM interface device driver.
-*
-* Corey Minyard (minyard@wf-rch.cirr.com)
-*
-* Colossians 3:17
-*
-*  See Documentation/cdrom/cdu31a for additional details about this driver.
-* 
-* The Sony interface device driver handles Sony interface CDROM
-* drives and provides a complete block-level interface as well as an
-* ioctl() interface compatible with the Sun (as specified in
-* include/linux/cdrom.h).  With this interface, CDROMs can be
-* accessed and standard audio CDs can be played back normally.
-*
-* WARNING -    All autoprobes have been removed from the driver.
-*              You MUST configure the CDU31A via a LILO config
-*              at boot time or in lilo.conf.  I have the
-*              following in my lilo.conf:
-*
-*                append="cdu31a=0x1f88,0,PAS"
-*
-*              The first number is the I/O base address of the
-*              card.  The second is the interrupt (0 means none).
- *             The third should be "PAS" if on a Pro-Audio
- *             spectrum, or nothing if on something else.
- *
- * This interface is (unfortunately) a polled interface.  This is
- * because most Sony interfaces are set up with DMA and interrupts
- * disables.  Some (like mine) do not even have the capability to
- * handle interrupts or DMA.  For this reason you will see a lot of
- * the following:
- *
- *   retry_count = jiffies+ SONY_JIFFIES_TIMEOUT;
- *   while (time_before(jiffies, retry_count) && (! <some condition to wait for))
- *   {
- *      while (handle_sony_cd_attention())
- *         ;
- *
- *      sony_sleep();
- *   }
- *   if (the condition not met)
- *   {
- *      return an error;
- *   }
- *
- * This ugly hack waits for something to happen, sleeping a little
- * between every try.  it also handles attentions, which are
- * asynchronous events from the drive informing the driver that a disk
- * has been inserted, removed, etc.
- *
- * NEWS FLASH - The driver now supports interrupts but they are
- * turned off by default.  Use of interrupts is highly encouraged, it
- * cuts CPU usage down to a reasonable level.  I had DMA in for a while
- * but PC DMA is just too slow.  Better to just insb() it.
- *
- * One thing about these drives: They talk in MSF (Minute Second Frame) format.
- * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
- * disk.  The funny thing is that these are sent to the drive in BCD, but the
- * interface wants to see them in decimal.  A lot of conversion goes on.
- *
- * DRIVER SPECIAL FEATURES
- * -----------------------
- *
- * This section describes features beyond the normal audio and CD-ROM
- * functions of the drive.
- *
- * XA compatibility
- *
- * The driver should support XA disks for both the CDU31A and CDU33A.
- * It does this transparently, the using program doesn't need to set it.
- *
- * Multi-Session
- *
- * A multi-session disk looks just like a normal disk to the user.
- * Just mount one normally, and all the data should be there.
- * A special thanks to Koen for help with this!
- * 
- * Raw sector I/O
- *
- * Using the CDROMREADAUDIO it is possible to read raw audio and data
- * tracks.  Both operations return 2352 bytes per sector.  On the data
- * tracks, the first 12 bytes is not returned by the drive and the value
- * of that data is indeterminate.
- *
- *
- *  Copyright (C) 1993  Corey Minyard
- *
- *  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.
- *
- * TODO: 
- *       CDs with form1 and form2 sectors cause problems
- *       with current read-ahead strategy.
- *
- * Credits:
- *    Heiko Eissfeldt <heiko@colossus.escape.de>
- *         For finding abug in the return of the track numbers.
- *         TOC processing redone for proper multisession support.
- *
- *
- *  It probably a little late to be adding a history, but I guess I
- *  will start.
- *
- *  10/24/95 - Added support for disabling the eject button when the
- *             drive is open.  Note that there is a small problem
- *             still here, if the eject button is pushed while the
- *             drive light is flashing, the drive will return a bad
- *             status and be reset.  It recovers, though.
- *
- *  03/07/97 - Fixed a problem with timers.
- *
- *
- *  18 Spetember 1997 -- Ported to Uniform CD-ROM driver by 
- *                 Heiko Eissfeldt <heiko@colossus.escape.de> with additional
- *                 changes by Erik Andersen <andersee@debian.org>
- *
- *  24 January 1998 -- Removed the scd_disc_status() function, which was now
- *                     just dead code left over from the port.
- *                          Erik Andersen <andersee@debian.org>
- *
- *  16 July 1998 -- Drive donated to Erik Andersen by John Kodis
- *                   <kodis@jagunet.com>.  Work begun on fixing driver to
- *                   work under 2.1.X.  Added temporary extra printks
- *                   which seem to slow it down enough to work.
- *
- *  9 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 <tmm@image.dk>
- *
- * 22 October 2004 -- Make the driver work in 2.6.X
- *                   Added workaround to fix hard lockups on eject
- *                   Fixed door locking problem after mounting empty drive
- *                   Set double-speed drives to double speed by default
- *                   Removed all readahead things - not needed anymore
- *                     Ondrej Zary <rainbow@rainbow-software.org>
-*/
-
-#define DEBUG 1
-
-#include <linux/major.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/hdreg.h>
-#include <linux/genhd.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/cdrom.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/dma.h>
-
-#include "cdu31a.h"
-
-#define MAJOR_NR CDU31A_CDROM_MAJOR
-#include <linux/blkdev.h>
-
-#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
-
-#define PFX "CDU31A: "
-
-/*
-** Edit the following data to change interrupts, DMA channels, etc.
-** Default is polled and no DMA.  DMA is not recommended for double-speed
-** drives.
-*/
-static struct {
-       unsigned short base;    /* I/O Base Address */
-       short int_num;          /* Interrupt Number (-1 means scan for it,
-                                  0 means don't use) */
-} cdu31a_addresses[] __initdata = {
-       {0}
-};
-
-static int handle_sony_cd_attention(void);
-static int read_subcode(void);
-static void sony_get_toc(void);
-static int scd_spinup(void);
-/*static int scd_open(struct inode *inode, struct file *filp);*/
-static int scd_open(struct cdrom_device_info *, int);
-static void do_sony_cd_cmd(unsigned char cmd,
-                          unsigned char *params,
-                          unsigned int num_params,
-                          unsigned char *result_buffer,
-                          unsigned int *result_size);
-static void size_to_buf(unsigned int size, unsigned char *buf);
-
-/* Parameters for the read-ahead. */
-static unsigned int sony_next_block;   /* Next 512 byte block offset */
-static unsigned int sony_blocks_left = 0;      /* Number of 512 byte blocks left
-                                                  in the current read command. */
-
-
-/* The base I/O address of the Sony Interface.  This is a variable (not a
-   #define) so it can be easily changed via some future ioctl() */
-static unsigned int cdu31a_port = 0;
-module_param(cdu31a_port, uint, 0);
-
-/*
- * The following are I/O addresses of the various registers for the drive.  The
- * comment for the base address also applies here.
- */
-static volatile unsigned short sony_cd_cmd_reg;
-static volatile unsigned short sony_cd_param_reg;
-static volatile unsigned short sony_cd_write_reg;
-static volatile unsigned short sony_cd_control_reg;
-static volatile unsigned short sony_cd_status_reg;
-static volatile unsigned short sony_cd_result_reg;
-static volatile unsigned short sony_cd_read_reg;
-static volatile unsigned short sony_cd_fifost_reg;
-
-static struct request_queue *cdu31a_queue;
-static DEFINE_SPINLOCK(cdu31a_lock); /* queue lock */
-
-static int sony_spun_up = 0;   /* Has the drive been spun up? */
-
-static int sony_speed = 0;     /* Last wanted speed */
-
-static int sony_xa_mode = 0;   /* Is an XA disk in the drive
-                                  and the drive a CDU31A? */
-
-static int sony_raw_data_mode = 1;     /* 1 if data tracks, 0 if audio.
-                                          For raw data reads. */
-
-static unsigned int sony_usage = 0;    /* How many processes have the
-                                          drive open. */
-
-static int sony_pas_init = 0;  /* Initialize the Pro-Audio
-                                  Spectrum card? */
-
-static struct s_sony_session_toc single_toc;   /* Holds the
-                                                  table of
-                                                  contents. */
-
-static struct s_all_sessions_toc sony_toc;     /* entries gathered from all
-                                                  sessions */
-
-static int sony_toc_read = 0;  /* Has the TOC been read for
-                                  the drive? */
-
-static struct s_sony_subcode last_sony_subcode;        /* Points to the last
-                                                  subcode address read */
-
-static DECLARE_MUTEX(sony_sem);                /* Semaphore for drive hardware access */
-
-static int is_double_speed = 0;        /* does the drive support double speed ? */
-
-static int is_auto_eject = 1;  /* Door has been locked? 1=No/0=Yes */
-
-/*
- * The audio status uses the values from read subchannel data as specified
- * in include/linux/cdrom.h.
- */
-static volatile int sony_audio_status = CDROM_AUDIO_NO_STATUS;
-
-/*
- * The following are a hack for pausing and resuming audio play.  The drive
- * does not work as I would expect it, if you stop it then start it again,
- * the drive seeks back to the beginning and starts over.  This holds the
- * position during a pause so a resume can restart it.  It uses the
- * audio status variable above to tell if it is paused.
- */
-static unsigned volatile char cur_pos_msf[3] = { 0, 0, 0 };
-static unsigned volatile char final_pos_msf[3] = { 0, 0, 0 };
-
-/* What IRQ is the drive using?  0 if none. */
-static int cdu31a_irq = 0;
-module_param(cdu31a_irq, int, 0);
-
-/* The interrupt handler will wake this queue up when it gets an
-   interrupts. */
-static DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
-static int irq_flag = 0;
-
-static int curr_control_reg = 0;       /* Current value of the control register */
-
-/* A disk changed variable.  When a disk change is detected, it will
-   all be set to TRUE.  As the upper layers ask for disk_changed status
-   it will be cleared. */
-static char disk_changed;
-
-/* This was readahead_buffer once... Now it's used only for audio reads */
-static char audio_buffer[CD_FRAMESIZE_RAW];
-
-/* Used to time a short period to abort an operation after the
-   drive has been idle for a while.  This keeps the light on
-   the drive from flashing for very long. */
-static struct timer_list cdu31a_abort_timer;
-
-/* Marks if the timeout has started an abort read.  This is used
-   on entry to the drive to tell the code to read out the status
-   from the abort read. */
-static int abort_read_started = 0;
-
-/*
- * Uniform cdrom interface function
- * report back, if disc has changed from time of last request.
- */
-static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
-{
-       int retval;
-
-       retval = disk_changed;
-       disk_changed = 0;
-
-       return retval;
-}
-
-/*
- * Uniform cdrom interface function
- * report back, if drive is ready
- */
-static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
-{
-       if (CDSL_CURRENT != slot_nr)
-               /* we have no changer support */
-               return -EINVAL;
-       if (sony_spun_up)
-               return CDS_DISC_OK;
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       if (scd_spinup() == 0)
-               sony_spun_up = 1;
-       up(&sony_sem);
-       return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
-}
-
-static inline void enable_interrupts(void)
-{
-       curr_control_reg |= (SONY_ATTN_INT_EN_BIT
-                            | SONY_RES_RDY_INT_EN_BIT
-                            | SONY_DATA_RDY_INT_EN_BIT);
-       outb(curr_control_reg, sony_cd_control_reg);
-}
-
-static inline void disable_interrupts(void)
-{
-       curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
-                             | SONY_RES_RDY_INT_EN_BIT
-                             | SONY_DATA_RDY_INT_EN_BIT);
-       outb(curr_control_reg, sony_cd_control_reg);
-}
-
-/*
- * Wait a little while (used for polling the drive).  If in initialization,
- * setting a timeout doesn't work, so just loop for a while.
- */
-static inline void sony_sleep(void)
-{
-       if (cdu31a_irq <= 0) {
-               yield();
-       } else {                /* Interrupt driven */
-               DEFINE_WAIT(w);
-               int first = 1;
-
-               while (1) {
-                       prepare_to_wait(&cdu31a_irq_wait, &w,
-                                       TASK_INTERRUPTIBLE);
-                       if (first) {
-                               enable_interrupts();
-                               first = 0;
-                       }
-
-                       if (irq_flag != 0)
-                               break;
-                       if (!signal_pending(current)) {
-                               schedule();
-                               continue;
-                       } else
-                               disable_interrupts();
-                       break;
-               }
-               finish_wait(&cdu31a_irq_wait, &w);
-               irq_flag = 0;
-       }
-}
-
-
-/*
- * The following are convenience routine to read various status and set
- * various conditions in the drive.
- */
-static inline int is_attention(void)
-{
-       return (inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0;
-}
-
-static inline int is_busy(void)
-{
-       return (inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0;
-}
-
-static inline int is_data_ready(void)
-{
-       return (inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0;
-}
-
-static inline int is_data_requested(void)
-{
-       return (inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0;
-}
-
-static inline int is_result_ready(void)
-{
-       return (inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0;
-}
-
-static inline int is_param_write_rdy(void)
-{
-       return (inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0;
-}
-
-static inline int is_result_reg_not_empty(void)
-{
-       return (inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0;
-}
-
-static inline void reset_drive(void)
-{
-       curr_control_reg = 0;
-       sony_toc_read = 0;
-       outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
-}
-
-/*
- * Uniform cdrom interface function
- * reset drive and return when it is ready
- */
-static int scd_reset(struct cdrom_device_info *cdi)
-{
-       unsigned long retry_count;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       reset_drive();
-
-       retry_count = jiffies + SONY_RESET_TIMEOUT;
-       while (time_before(jiffies, retry_count) && (!is_attention())) {
-               sony_sleep();
-       }
-
-       up(&sony_sem);
-       return 0;
-}
-
-static inline void clear_attention(void)
-{
-       outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
-}
-
-static inline void clear_result_ready(void)
-{
-       outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
-}
-
-static inline void clear_data_ready(void)
-{
-       outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT,
-            sony_cd_control_reg);
-}
-
-static inline void clear_param_reg(void)
-{
-       outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
-}
-
-static inline unsigned char read_status_register(void)
-{
-       return inb(sony_cd_status_reg);
-}
-
-static inline unsigned char read_result_register(void)
-{
-       return inb(sony_cd_result_reg);
-}
-
-static inline unsigned char read_data_register(void)
-{
-       return inb(sony_cd_read_reg);
-}
-
-static inline void write_param(unsigned char param)
-{
-       outb(param, sony_cd_param_reg);
-}
-
-static inline void write_cmd(unsigned char cmd)
-{
-       outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT,
-            sony_cd_control_reg);
-       outb(cmd, sony_cd_cmd_reg);
-}
-
-static irqreturn_t cdu31a_interrupt(int irq, void *dev_id)
-{
-       unsigned char val;
-
-       if (abort_read_started) {
-               /* We might be waiting for an abort to finish.  Don't
-                  disable interrupts yet, though, because we handle
-                  this one here. */
-               /* Clear out the result registers. */
-               while (is_result_reg_not_empty()) {
-                       val = read_result_register();
-               }
-               clear_data_ready();
-               clear_result_ready();
-
-               /* Clear out the data */
-               while (is_data_requested()) {
-                       val = read_data_register();
-               }
-               abort_read_started = 0;
-
-               /* If something was waiting, wake it up now. */
-               if (waitqueue_active(&cdu31a_irq_wait)) {
-                       disable_interrupts();
-                       irq_flag = 1;
-                       wake_up_interruptible(&cdu31a_irq_wait);
-               }
-       } else if (waitqueue_active(&cdu31a_irq_wait)) {
-               disable_interrupts();
-               irq_flag = 1;
-               wake_up_interruptible(&cdu31a_irq_wait);
-       } else {
-               disable_interrupts();
-               printk(KERN_NOTICE PFX
-                               "Got an interrupt but nothing was waiting\n");
-       }
-       return IRQ_HANDLED;
-}
-
-/*
- * give more verbose error messages
- */
-static unsigned char *translate_error(unsigned char err_code)
-{
-       static unsigned char errbuf[80];
-
-       switch (err_code) {
-               case 0x10: return "illegal command ";
-               case 0x11: return "illegal parameter ";
-
-               case 0x20: return "not loaded ";
-               case 0x21: return "no disc ";
-               case 0x22: return "not spinning ";
-               case 0x23: return "spinning ";
-               case 0x25: return "spindle servo ";
-               case 0x26: return "focus servo ";
-               case 0x29: return "eject mechanism ";
-               case 0x2a: return "audio playing ";
-               case 0x2c: return "emergency eject ";
-
-               case 0x30: return "focus ";
-               case 0x31: return "frame sync ";
-               case 0x32: return "subcode address ";
-               case 0x33: return "block sync ";
-               case 0x34: return "header address ";
-
-               case 0x40: return "illegal track read ";
-               case 0x41: return "mode 0 read ";
-               case 0x42: return "illegal mode read ";
-               case 0x43: return "illegal block size read ";
-               case 0x44: return "mode read ";
-               case 0x45: return "form read ";
-               case 0x46: return "leadout read ";
-               case 0x47: return "buffer overrun ";
-
-               case 0x53: return "unrecoverable CIRC ";
-               case 0x57: return "unrecoverable LECC ";
-
-               case 0x60: return "no TOC ";
-               case 0x61: return "invalid subcode data ";
-               case 0x63: return "focus on TOC read ";
-               case 0x64: return "frame sync on TOC read ";
-               case 0x65: return "TOC data ";
-
-               case 0x70: return "hardware failure ";
-               case 0x91: return "leadin ";
-               case 0x92: return "leadout ";
-               case 0x93: return "data track ";
-       }
-       sprintf(errbuf, "unknown 0x%02x ", err_code);
-       return errbuf;
-}
-
-/*
- * Set the drive parameters so the drive will auto-spin-up when a
- * disk is inserted.
- */
-static void set_drive_params(int want_doublespeed)
-{
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       unsigned char params[3];
-
-
-       params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
-       params[1] = 0x00;       /* Never spin down the drive. */
-       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                      params, 2, res_reg, &res_size);
-       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
-               printk(KERN_NOTICE PFX
-                       "Unable to set spin-down time: 0x%2.2x\n", res_reg[1]);
-       }
-
-       params[0] = SONY_SD_MECH_CONTROL;
-       params[1] = SONY_AUTO_SPIN_UP_BIT;      /* Set auto spin up */
-
-       if (is_auto_eject)
-               params[1] |= SONY_AUTO_EJECT_BIT;
-
-       if (is_double_speed && want_doublespeed) {
-               params[1] |= SONY_DOUBLE_SPEED_BIT;     /* Set the drive to double speed if 
-                                                          possible */
-       }
-       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                      params, 2, res_reg, &res_size);
-       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
-               printk(KERN_NOTICE PFX "Unable to set mechanical "
-                               "parameters: 0x%2.2x\n", res_reg[1]);
-       }
-}
-
-/*
- * Uniform cdrom interface function
- * select reading speed for data access
- */
-static int scd_select_speed(struct cdrom_device_info *cdi, int speed)
-{
-       if (speed == 0)
-               sony_speed = 1;
-       else
-               sony_speed = speed - 1;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       set_drive_params(sony_speed);
-       up(&sony_sem);
-       return 0;
-}
-
-/*
- * Uniform cdrom interface function
- * lock or unlock eject button
- */
-static int scd_lock_door(struct cdrom_device_info *cdi, int lock)
-{
-       if (lock == 0) {
-               is_auto_eject = 1;
-       } else {
-               is_auto_eject = 0;
-       }
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       set_drive_params(sony_speed);
-       up(&sony_sem);
-       return 0;
-}
-
-/*
- * This code will reset the drive and attempt to restore sane parameters.
- */
-static void restart_on_error(void)
-{
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       unsigned long retry_count;
-
-
-       printk(KERN_NOTICE PFX "Resetting drive on error\n");
-       reset_drive();
-       retry_count = jiffies + SONY_RESET_TIMEOUT;
-       while (time_before(jiffies, retry_count) && (!is_attention())) {
-               sony_sleep();
-       }
-       set_drive_params(sony_speed);
-       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
-               printk(KERN_NOTICE PFX "Unable to spin up drive: 0x%2.2x\n",
-                      res_reg[1]);
-       }
-
-       msleep(2000);
-
-       sony_get_toc();
-}
-
-/*
- * This routine writes data to the parameter register.  Since this should
- * happen fairly fast, it is polled with no OS waits between.
- */
-static int write_params(unsigned char *params, int num_params)
-{
-       unsigned int retry_count;
-
-
-       retry_count = SONY_READY_RETRIES;
-       while ((retry_count > 0) && (!is_param_write_rdy())) {
-               retry_count--;
-       }
-       if (!is_param_write_rdy()) {
-               return -EIO;
-       }
-
-       while (num_params > 0) {
-               write_param(*params);
-               params++;
-               num_params--;
-       }
-
-       return 0;
-}
-
-
-/*
- * The following reads data from the command result register.  It is a
- * fairly complex routine, all status info flows back through this
- * interface.  The algorithm is stolen directly from the flowcharts in
- * the drive manual.
- */
-static void
-get_result(unsigned char *result_buffer, unsigned int *result_size)
-{
-       unsigned char a, b;
-       int i;
-       unsigned long retry_count;
-
-
-       while (handle_sony_cd_attention());
-       /* Wait for the result data to be ready */
-       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-       while (time_before(jiffies, retry_count)
-              && (is_busy() || (!(is_result_ready())))) {
-               sony_sleep();
-
-               while (handle_sony_cd_attention());
-       }
-       if (is_busy() || (!(is_result_ready()))) {
-               pr_debug(PFX "timeout out %d\n", __LINE__);
-               result_buffer[0] = 0x20;
-               result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-               *result_size = 2;
-               return;
-       }
-
-       /*
-        * Get the first two bytes.  This determines what else needs
-        * to be done.
-        */
-       clear_result_ready();
-       a = read_result_register();
-       *result_buffer = a;
-       result_buffer++;
-
-       /* Check for block error status result. */
-       if ((a & 0xf0) == 0x50) {
-               *result_size = 1;
-               return;
-       }
-
-       b = read_result_register();
-       *result_buffer = b;
-       result_buffer++;
-       *result_size = 2;
-
-       /*
-        * 0x20 means an error occurred.  Byte 2 will have the error code.
-        * Otherwise, the command succeeded, byte 2 will have the count of
-        * how many more status bytes are coming.
-        *
-        * The result register can be read 10 bytes at a time, a wait for
-        * result ready to be asserted must be done between every 10 bytes.
-        */
-       if ((a & 0xf0) != 0x20) {
-               if (b > 8) {
-                       for (i = 0; i < 8; i++) {
-                               *result_buffer = read_result_register();
-                               result_buffer++;
-                               (*result_size)++;
-                       }
-                       b = b - 8;
-
-                       while (b > 10) {
-                               retry_count = SONY_READY_RETRIES;
-                               while ((retry_count > 0)
-                                      && (!is_result_ready())) {
-                                       retry_count--;
-                               }
-                               if (!is_result_ready()) {
-                                       pr_debug(PFX "timeout out %d\n",
-                                              __LINE__);
-                                       result_buffer[0] = 0x20;
-                                       result_buffer[1] =
-                                           SONY_TIMEOUT_OP_ERR;
-                                       *result_size = 2;
-                                       return;
-                               }
-
-                               clear_result_ready();
-
-                               for (i = 0; i < 10; i++) {
-                                       *result_buffer =
-                                           read_result_register();
-                                       result_buffer++;
-                                       (*result_size)++;
-                               }
-                               b = b - 10;
-                       }
-
-                       if (b > 0) {
-                               retry_count = SONY_READY_RETRIES;
-                               while ((retry_count > 0)
-                                      && (!is_result_ready())) {
-                                       retry_count--;
-                               }
-                               if (!is_result_ready()) {
-                                       pr_debug(PFX "timeout out %d\n",
-                                              __LINE__);
-                                       result_buffer[0] = 0x20;
-                                       result_buffer[1] =
-                                           SONY_TIMEOUT_OP_ERR;
-                                       *result_size = 2;
-                                       return;
-                               }
-                       }
-               }
-
-               while (b > 0) {
-                       *result_buffer = read_result_register();
-                       result_buffer++;
-                       (*result_size)++;
-                       b--;
-               }
-       }
-}
-
-/*
- * Do a command that does not involve data transfer.  This routine must
- * be re-entrant from the same task to support being called from the
- * data operation code when an error occurs.
- */
-static void
-do_sony_cd_cmd(unsigned char cmd,
-              unsigned char *params,
-              unsigned int num_params,
-              unsigned char *result_buffer, unsigned int *result_size)
-{
-       unsigned long retry_count;
-       int num_retries = 0;
-
-retry_cd_operation:
-
-       while (handle_sony_cd_attention());
-
-       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-       while (time_before(jiffies, retry_count) && (is_busy())) {
-               sony_sleep();
-
-               while (handle_sony_cd_attention());
-       }
-       if (is_busy()) {
-               pr_debug(PFX "timeout out %d\n", __LINE__);
-               result_buffer[0] = 0x20;
-               result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-               *result_size = 2;
-       } else {
-               clear_result_ready();
-               clear_param_reg();
-
-               write_params(params, num_params);
-               write_cmd(cmd);
-
-               get_result(result_buffer, result_size);
-       }
-
-       if (((result_buffer[0] & 0xf0) == 0x20)
-           && (num_retries < MAX_CDU31A_RETRIES)) {
-               num_retries++;
-               msleep(100);
-               goto retry_cd_operation;
-       }
-}
-
-
-/*
- * Handle an attention from the drive.  This will return 1 if it found one
- * or 0 if not (if one is found, the caller might want to call again).
- *
- * This routine counts the number of consecutive times it is called
- * (since this is always called from a while loop until it returns
- * a 0), and returns a 0 if it happens too many times.  This will help
- * prevent a lockup.
- */
-static int handle_sony_cd_attention(void)
-{
-       unsigned char atten_code;
-       static int num_consecutive_attentions = 0;
-       volatile int val;
-
-
-#if 0
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-#endif
-       if (is_attention()) {
-               if (num_consecutive_attentions >
-                   CDU31A_MAX_CONSECUTIVE_ATTENTIONS) {
-                       printk(KERN_NOTICE PFX "Too many consecutive "
-                               "attentions: %d\n", num_consecutive_attentions);
-                       num_consecutive_attentions = 0;
-                       pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__,
-                              __LINE__);
-                       return 0;
-               }
-
-               clear_attention();
-               atten_code = read_result_register();
-
-               switch (atten_code) {
-                       /* Someone changed the CD.  Mark it as changed */
-               case SONY_MECH_LOADED_ATTN:
-                       disk_changed = 1;
-                       sony_toc_read = 0;
-                       sony_audio_status = CDROM_AUDIO_NO_STATUS;
-                       sony_blocks_left = 0;
-                       break;
-
-               case SONY_SPIN_DOWN_COMPLETE_ATTN:
-                       /* Mark the disk as spun down. */
-                       sony_spun_up = 0;
-                       break;
-
-               case SONY_AUDIO_PLAY_DONE_ATTN:
-                       sony_audio_status = CDROM_AUDIO_COMPLETED;
-                       read_subcode();
-                       break;
-
-               case SONY_EJECT_PUSHED_ATTN:
-                       if (is_auto_eject) {
-                               sony_audio_status = CDROM_AUDIO_INVALID;
-                       }
-                       break;
-
-               case SONY_LEAD_IN_ERR_ATTN:
-               case SONY_LEAD_OUT_ERR_ATTN:
-               case SONY_DATA_TRACK_ERR_ATTN:
-               case SONY_AUDIO_PLAYBACK_ERR_ATTN:
-                       sony_audio_status = CDROM_AUDIO_ERROR;
-                       break;
-               }
-
-               num_consecutive_attentions++;
-               pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-               return 1;
-       } else if (abort_read_started) {
-               while (is_result_reg_not_empty()) {
-                       val = read_result_register();
-               }
-               clear_data_ready();
-               clear_result_ready();
-               /* Clear out the data */
-               while (is_data_requested()) {
-                       val = read_data_register();
-               }
-               abort_read_started = 0;
-               pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-               return 1;
-       }
-
-       num_consecutive_attentions = 0;
-#if 0
-       pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-#endif
-       return 0;
-}
-
-
-/* Convert from an integer 0-99 to BCD */
-static inline unsigned int int_to_bcd(unsigned int val)
-{
-       int retval;
-
-
-       retval = (val / 10) << 4;
-       retval = retval | val % 10;
-       return retval;
-}
-
-
-/* Convert from BCD to an integer from 0-99 */
-static unsigned int bcd_to_int(unsigned int bcd)
-{
-       return (((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f);
-}
-
-
-/*
- * Convert a logical sector value (like the OS would want to use for
- * a block device) to an MSF format.
- */
-static void log_to_msf(unsigned int log, unsigned char *msf)
-{
-       log = log + LOG_START_OFFSET;
-       msf[0] = int_to_bcd(log / 4500);
-       log = log % 4500;
-       msf[1] = int_to_bcd(log / 75);
-       msf[2] = int_to_bcd(log % 75);
-}
-
-
-/*
- * Convert an MSF format to a logical sector.
- */
-static unsigned int msf_to_log(unsigned char *msf)
-{
-       unsigned int log;
-
-
-       log = msf[2];
-       log += msf[1] * 75;
-       log += msf[0] * 4500;
-       log = log - LOG_START_OFFSET;
-
-       return log;
-}
-
-
-/*
- * Take in integer size value and put it into a buffer like
- * the drive would want to see a number-of-sector value.
- */
-static void size_to_buf(unsigned int size, unsigned char *buf)
-{
-       buf[0] = size / 65536;
-       size = size % 65536;
-       buf[1] = size / 256;
-       buf[2] = size % 256;
-}
-
-/* Starts a read operation. Returns 0 on success and 1 on failure. 
-   The read operation used here allows multiple sequential sectors 
-   to be read and status returned for each sector.  The driver will
-   read the output one at a time as the requests come and abort the
-   operation if the requested sector is not the next one from the
-   drive. */
-static int
-start_request(unsigned int sector, unsigned int nsect)
-{
-       unsigned char params[6];
-       unsigned long retry_count;
-
-
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-       log_to_msf(sector, params);
-       size_to_buf(nsect, &params[3]);
-
-       /*
-        * Clear any outstanding attentions and wait for the drive to
-        * complete any pending operations.
-        */
-       while (handle_sony_cd_attention());
-
-       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-       while (time_before(jiffies, retry_count) && (is_busy())) {
-               sony_sleep();
-
-               while (handle_sony_cd_attention());
-       }
-
-       if (is_busy()) {
-               printk(KERN_NOTICE PFX "Timeout while waiting "
-                               "to issue command\n");
-               pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-               return 1;
-       } else {
-               /* Issue the command */
-               clear_result_ready();
-               clear_param_reg();
-
-               write_params(params, 6);
-               write_cmd(SONY_READ_BLKERR_STAT_CMD);
-
-               sony_blocks_left = nsect * 4;
-               sony_next_block = sector * 4;
-               pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-               return 0;
-       }
-       pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-}
-
-/* Abort a pending read operation.  Clear all the drive status variables. */
-static void abort_read(void)
-{
-       unsigned char result_reg[2];
-       int result_size;
-       volatile int val;
-
-
-       do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
-       if ((result_reg[0] & 0xf0) == 0x20) {
-               printk(KERN_ERR PFX "Aborting read, %s error\n",
-                      translate_error(result_reg[1]));
-       }
-
-       while (is_result_reg_not_empty()) {
-               val = read_result_register();
-       }
-       clear_data_ready();
-       clear_result_ready();
-       /* Clear out the data */
-       while (is_data_requested()) {
-               val = read_data_register();
-       }
-
-       sony_blocks_left = 0;
-}
-
-/* Called when the timer times out.  This will abort the
-   pending read operation. */
-static void handle_abort_timeout(unsigned long data)
-{
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-       /* If it is in use, ignore it. */
-       if (down_trylock(&sony_sem) == 0) {
-               /* We can't use abort_read(), because it will sleep
-                  or schedule in the timer interrupt.  Just start
-                  the operation, finish it on the next access to
-                  the drive. */
-               clear_result_ready();
-               clear_param_reg();
-               write_cmd(SONY_ABORT_CMD);
-
-               sony_blocks_left = 0;
-               abort_read_started = 1;
-               up(&sony_sem);
-       }
-       pr_debug(PFX "Leaving %s\n", __FUNCTION__);
-}
-
-/* Actually get one sector of data from the drive. */
-static void
-input_data_sector(char *buffer)
-{
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
-       /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
-          the disk.  The real data is after that. We can use audio_buffer. */
-       if (sony_xa_mode)
-               insb(sony_cd_read_reg, audio_buffer, CD_XA_HEAD);
-
-       clear_data_ready();
-
-       insb(sony_cd_read_reg, buffer, 2048);
-
-       /* If an XA disk, we have to clear out the rest of the unused
-          error correction data. We can use audio_buffer for that. */
-       if (sony_xa_mode)
-               insb(sony_cd_read_reg, audio_buffer, CD_XA_TAIL);
-
-       pr_debug(PFX "Leaving %s\n", __FUNCTION__);
-}
-
-/* read data from the drive.  Note the nsect must be <= 4. */
-static void
-read_data_block(char *buffer,
-               unsigned int block,
-               unsigned int nblocks,
-               unsigned char res_reg[], int *res_size)
-{
-       unsigned long retry_count;
-
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
-       res_reg[0] = 0;
-       res_reg[1] = 0;
-       *res_size = 0;
-
-       /* Wait for the drive to tell us we have something */
-       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-       while (time_before(jiffies, retry_count) && !(is_data_ready())) {
-               while (handle_sony_cd_attention());
-
-               sony_sleep();
-       }
-       if (!(is_data_ready())) {
-               if (is_result_ready()) {
-                       get_result(res_reg, res_size);
-                       if ((res_reg[0] & 0xf0) != 0x20) {
-                               printk(KERN_NOTICE PFX "Got result that should"
-                                       " have been error: %d\n", res_reg[0]);
-                               res_reg[0] = 0x20;
-                               res_reg[1] = SONY_BAD_DATA_ERR;
-                               *res_size = 2;
-                       }
-                       abort_read();
-               } else {
-                       pr_debug(PFX "timeout out %d\n", __LINE__);
-                       res_reg[0] = 0x20;
-                       res_reg[1] = SONY_TIMEOUT_OP_ERR;
-                       *res_size = 2;
-                       abort_read();
-               }
-       } else {
-               input_data_sector(buffer);
-               sony_blocks_left -= nblocks;
-               sony_next_block += nblocks;
-
-               /* Wait for the status from the drive. */
-               retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-               while (time_before(jiffies, retry_count)
-                      && !(is_result_ready())) {
-                       while (handle_sony_cd_attention());
-
-                       sony_sleep();
-               }
-
-               if (!is_result_ready()) {
-                       pr_debug(PFX "timeout out %d\n", __LINE__);
-                       res_reg[0] = 0x20;
-                       res_reg[1] = SONY_TIMEOUT_OP_ERR;
-                       *res_size = 2;
-                       abort_read();
-               } else {
-                       get_result(res_reg, res_size);
-
-                       /* If we got a buffer status, handle that. */
-                       if ((res_reg[0] & 0xf0) == 0x50) {
-
-                               if ((res_reg[0] ==
-                                    SONY_NO_CIRC_ERR_BLK_STAT)
-                                   || (res_reg[0] ==
-                                       SONY_NO_LECC_ERR_BLK_STAT)
-                                   || (res_reg[0] ==
-                                       SONY_RECOV_LECC_ERR_BLK_STAT)) {
-                                       /* nothing here */
-                               } else {
-                                       printk(KERN_ERR PFX "Data block "
-                                               "error: 0x%x\n", res_reg[0]);
-                                       res_reg[0] = 0x20;
-                                       res_reg[1] = SONY_BAD_DATA_ERR;
-                                       *res_size = 2;
-                               }
-
-                               /* Final transfer is done for read command, get final result. */
-                               if (sony_blocks_left == 0) {
-                                       get_result(res_reg, res_size);
-                               }
-                       } else if ((res_reg[0] & 0xf0) != 0x20) {
-                               /* The drive gave me bad status, I don't know what to do.
-                                  Reset the driver and return an error. */
-                               printk(KERN_ERR PFX "Invalid block "
-                                       "status: 0x%x\n", res_reg[0]);
-                               restart_on_error();
-                               res_reg[0] = 0x20;
-                               res_reg[1] = SONY_BAD_DATA_ERR;
-                               *res_size = 2;
-                       }
-               }
-       }
-       pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-}
-
-
-/*
- * The OS calls this to perform a read or write operation to the drive.
- * Write obviously fail.  Reads to a read ahead of sony_buffer_size
- * bytes to help speed operations.  This especially helps since the OS
- * uses 1024 byte blocks and the drive uses 2048 byte blocks.  Since most
- * data access on a CD is done sequentially, this saves a lot of operations.
- */
-static void do_cdu31a_request(request_queue_t * q)
-{
-       struct request *req;
-       int block, nblock, num_retries;
-       unsigned char res_reg[12];
-       unsigned int res_size;
-
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
-       spin_unlock_irq(q->queue_lock);
-       if (down_interruptible(&sony_sem)) {
-               spin_lock_irq(q->queue_lock);
-               return;
-       }
-
-       /* Get drive status before doing anything. */
-       while (handle_sony_cd_attention());
-
-       /* Make sure we have a valid TOC. */
-       sony_get_toc();
-
-
-       /* Make sure the timer is cancelled. */
-       del_timer(&cdu31a_abort_timer);
-
-       while (1) {
-               /*
-                * The beginning here is stolen from the hard disk driver.  I hope
-                * it's right.
-                */
-               req = elv_next_request(q);
-               if (!req)
-                       goto end_do_cdu31a_request;
-
-               if (!sony_spun_up)
-                       scd_spinup();
-
-               block = req->sector;
-               nblock = req->nr_sectors;
-               pr_debug(PFX "request at block %d, length %d blocks\n",
-                       block, nblock);
-               if (!sony_toc_read) {
-                       printk(KERN_NOTICE PFX "TOC not read\n");
-                       end_request(req, 0);
-                       continue;
-               }
-
-               /* WTF??? */
-               if (!blk_fs_request(req)) {
-                       end_request(req, 0);
-                       continue;
-               }
-               if (rq_data_dir(req) == WRITE) {
-                       end_request(req, 0);
-                       continue;
-               }
-
-               /*
-                * If the block address is invalid or the request goes beyond the end of
-                * the media, return an error.
-                */
-               if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba) {
-                       printk(KERN_NOTICE PFX "Request past end of media\n");
-                       end_request(req, 0);
-                       continue;
-               }
-
-               if (nblock > 4)
-                       nblock = 4;
-               num_retries = 0;
-
-       try_read_again:
-               while (handle_sony_cd_attention());
-
-               if (!sony_toc_read) {
-                       printk(KERN_NOTICE PFX "TOC not read\n");
-                       end_request(req, 0);
-                       continue;
-               }
-
-               /* If no data is left to be read from the drive, start the
-                  next request. */
-               if (sony_blocks_left == 0) {
-                       if (start_request(block / 4, nblock / 4)) {
-                               end_request(req, 0);
-                               continue;
-                       }
-               }
-               /* If the requested block is not the next one waiting in
-                  the driver, abort the current operation and start a
-                  new one. */
-               else if (block != sony_next_block) {
-                       pr_debug(PFX "Read for block %d, expected %d\n",
-                                block, sony_next_block);
-                       abort_read();
-                       if (!sony_toc_read) {
-                               printk(KERN_NOTICE PFX "TOC not read\n");
-                               end_request(req, 0);
-                               continue;
-                       }
-                       if (start_request(block / 4, nblock / 4)) {
-                               printk(KERN_NOTICE PFX "start request failed\n");
-                               end_request(req, 0);
-                               continue;
-                       }
-               }
-
-               read_data_block(req->buffer, block, nblock, res_reg, &res_size);
-
-               if (res_reg[0] != 0x20) {
-                       if (!end_that_request_first(req, 1, nblock)) {
-                               spin_lock_irq(q->queue_lock);
-                               blkdev_dequeue_request(req);
-                               end_that_request_last(req, 1);
-                               spin_unlock_irq(q->queue_lock);
-                       }
-                       continue;
-               }
-
-               if (num_retries > MAX_CDU31A_RETRIES) {
-                       end_request(req, 0);
-                       continue;
-               }
-
-               num_retries++;
-               if (res_reg[1] == SONY_NOT_SPIN_ERR) {
-                       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
-                                       &res_size);
-               } else {
-                       printk(KERN_NOTICE PFX "%s error for block %d, nblock %d\n",
-                                translate_error(res_reg[1]), block, nblock);
-               }
-               goto try_read_again;
-       }
-      end_do_cdu31a_request:
-#if 0
-       /* After finished, cancel any pending operations. */
-       abort_read();
-#else
-       /* Start a timer to time out after a while to disable
-          the read. */
-       cdu31a_abort_timer.expires = jiffies + 2 * HZ;  /* Wait 2 seconds */
-       add_timer(&cdu31a_abort_timer);
-#endif
-
-       up(&sony_sem);
-       spin_lock_irq(q->queue_lock);
-       pr_debug(PFX "Leaving %s at %d\n", __FUNCTION__, __LINE__);
-}
-
-
-/*
- * Read the table of contents from the drive and set up TOC if
- * successful.
- */
-static void sony_get_toc(void)
-{
-       unsigned char res_reg[2];
-       unsigned int res_size;
-       unsigned char parms[1];
-       int session;
-       int num_spin_ups;
-       int totaltracks = 0;
-       int mint = 99;
-       int maxt = 0;
-
-       pr_debug(PFX "Entering %s\n", __FUNCTION__);
-
-       num_spin_ups = 0;
-       if (!sony_toc_read) {
-             respinup_on_gettoc:
-               /* Ignore the result, since it might error if spinning already. */
-               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               /* The drive sometimes returns error 0.  I don't know why, but ignore
-                  it.  It seems to mean the drive has already done the operation. */
-               if ((res_size < 2)
-                   || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
-                       /* If the drive is already playing, it's ok.  */
-                       if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
-                           || (res_reg[1] == 0)) {
-                               goto gettoc_drive_spinning;
-                       }
-
-                       /* If the drive says it is not spun up (even though we just did it!)
-                          then retry the operation at least a few times. */
-                       if ((res_reg[1] == SONY_NOT_SPIN_ERR)
-                           && (num_spin_ups < MAX_CDU31A_RETRIES)) {
-                               num_spin_ups++;
-                               goto respinup_on_gettoc;
-                       }
-
-                       printk("cdu31a: Error reading TOC: %x %s\n",
-                              res_reg[0], translate_error(res_reg[1]));
-                       return;
-               }
-
-             gettoc_drive_spinning:
-
-               /* The idea here is we keep asking for sessions until the command
-                  fails.  Then we know what the last valid session on the disk is.
-                  No need to check session 0, since session 0 is the same as session
-                  1; the command returns different information if you give it 0. 
-                */
-#if DEBUG
-               memset(&sony_toc, 0x0e, sizeof(sony_toc));
-               memset(&single_toc, 0x0f, sizeof(single_toc));
-#endif
-               session = 1;
-               while (1) {
-/* This seems to slow things down enough to make it work.  This
- * appears to be a problem in do_sony_cd_cmd.  This printk seems 
- * to address the symptoms...  -Erik */
-                       pr_debug(PFX "Trying session %d\n", session);
-                       parms[0] = session;
-                       do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
-                                      parms, 1, res_reg, &res_size);
-
-                       pr_debug(PFX "%2.2x %2.2x\n", res_reg[0], res_reg[1]);
-
-                       if ((res_size < 2)
-                           || ((res_reg[0] & 0xf0) == 0x20)) {
-                               /* An error reading the TOC, this must be past the last session. */
-                               if (session == 1)
-                                       printk
-                                           ("Yikes! Couldn't read any sessions!");
-                               break;
-                       }
-                       pr_debug(PFX "Reading session %d\n", session);
-
-                       parms[0] = session;
-                       do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
-                                      parms,
-                                      1,
-                                      (unsigned char *) &single_toc,
-                                      &res_size);
-                       if ((res_size < 2)
-                           || ((single_toc.exec_status[0] & 0xf0) ==
-                               0x20)) {
-                               printk(KERN_ERR PFX "Error reading "
-                                               "session %d: %x %s\n",
-                                    session, single_toc.exec_status[0],
-                                    translate_error(single_toc.
-                                                    exec_status[1]));
-                               /* An error reading the TOC.  Return without sony_toc_read
-                                  set. */
-                               return;
-                       }
-                       pr_debug(PFX "add0 %01x, con0 %01x, poi0 %02x, "
-                                       "1st trk %d, dsktyp %x, dum0 %x\n",
-                            single_toc.address0, single_toc.control0,
-                            single_toc.point0,
-                            bcd_to_int(single_toc.first_track_num),
-                            single_toc.disk_type, single_toc.dummy0);
-                       pr_debug(PFX "add1 %01x, con1 %01x, poi1 %02x, "
-                                       "lst trk %d, dummy1 %x, dum2 %x\n",
-                            single_toc.address1, single_toc.control1,
-                            single_toc.point1,
-                            bcd_to_int(single_toc.last_track_num),
-                            single_toc.dummy1, single_toc.dummy2);
-                       pr_debug(PFX "add2 %01x, con2 %01x, poi2 %02x "
-                               "leadout start min %d, sec %d, frame %d\n",
-                            single_toc.address2, single_toc.control2,
-                            single_toc.point2,
-                            bcd_to_int(single_toc.lead_out_start_msf[0]),
-                            bcd_to_int(single_toc.lead_out_start_msf[1]),
-                            bcd_to_int(single_toc.lead_out_start_msf[2]));
-                       if (res_size > 18 && single_toc.pointb0 > 0xaf)
-                               pr_debug(PFX "addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
-                                    "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
-                                    single_toc.addressb0,
-                                    single_toc.controlb0,
-                                    single_toc.pointb0,
-                                    bcd_to_int(single_toc.
-                                               next_poss_prog_area_msf
-                                               [0]),
-                                    bcd_to_int(single_toc.
-                                               next_poss_prog_area_msf
-                                               [1]),
-                                    bcd_to_int(single_toc.
-                                               next_poss_prog_area_msf
-                                               [2]),
-                                    single_toc.num_mode_5_pointers,
-                                    bcd_to_int(single_toc.
-                                               max_start_outer_leadout_msf
-                                               [0]),
-                                    bcd_to_int(single_toc.
-                                               max_start_outer_leadout_msf
-                                               [1]),
-                                    bcd_to_int(single_toc.
-                                               max_start_outer_leadout_msf
-                                               [2]));
-                       if (res_size > 27 && single_toc.pointb1 > 0xaf)
-                               pr_debug(PFX "addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
-                                    single_toc.addressb1,
-                                    single_toc.controlb1,
-                                    single_toc.pointb1,
-                                    single_toc.dummyb0_1[0],
-                                    single_toc.dummyb0_1[1],
-                                    single_toc.dummyb0_1[2],
-                                    single_toc.dummyb0_1[3],
-                                    single_toc.num_skip_interval_pointers,
-                                    single_toc.num_skip_track_assignments,
-                                    single_toc.dummyb0_2);
-                       if (res_size > 36 && single_toc.pointb2 > 0xaf)
-                               pr_debug(PFX "addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-                                    single_toc.addressb2,
-                                    single_toc.controlb2,
-                                    single_toc.pointb2,
-                                    single_toc.tracksb2[0],
-                                    single_toc.tracksb2[1],
-                                    single_toc.tracksb2[2],
-                                    single_toc.tracksb2[3],
-                                    single_toc.tracksb2[4],
-                                    single_toc.tracksb2[5],
-                                    single_toc.tracksb2[6]);
-                       if (res_size > 45 && single_toc.pointb3 > 0xaf)
-                               pr_debug(PFX "addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-                                    single_toc.addressb3,
-                                    single_toc.controlb3,
-                                    single_toc.pointb3,
-                                    single_toc.tracksb3[0],
-                                    single_toc.tracksb3[1],
-                                    single_toc.tracksb3[2],
-                                    single_toc.tracksb3[3],
-                                    single_toc.tracksb3[4],
-                                    single_toc.tracksb3[5],
-                                    single_toc.tracksb3[6]);
-                       if (res_size > 54 && single_toc.pointb4 > 0xaf)
-                               pr_debug(PFX "addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-                                    single_toc.addressb4,
-                                    single_toc.controlb4,
-                                    single_toc.pointb4,
-                                    single_toc.tracksb4[0],
-                                    single_toc.tracksb4[1],
-                                    single_toc.tracksb4[2],
-                                    single_toc.tracksb4[3],
-                                    single_toc.tracksb4[4],
-                                    single_toc.tracksb4[5],
-                                    single_toc.tracksb4[6]);
-                       if (res_size > 63 && single_toc.pointc0 > 0xaf)
-                               pr_debug(PFX "addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-                                    single_toc.addressc0,
-                                    single_toc.controlc0,
-                                    single_toc.pointc0,
-                                    single_toc.dummyc0[0],
-                                    single_toc.dummyc0[1],
-                                    single_toc.dummyc0[2],
-                                    single_toc.dummyc0[3],
-                                    single_toc.dummyc0[4],
-                                    single_toc.dummyc0[5],
-                                    single_toc.dummyc0[6]);
-#undef DEBUG
-#define DEBUG 0
-
-                       sony_toc.lead_out_start_msf[0] =
-                           bcd_to_int(single_toc.lead_out_start_msf[0]);
-                       sony_toc.lead_out_start_msf[1] =
-                           bcd_to_int(single_toc.lead_out_start_msf[1]);
-                       sony_toc.lead_out_start_msf[2] =
-                           bcd_to_int(single_toc.lead_out_start_msf[2]);
-                       sony_toc.lead_out_start_lba =
-                           single_toc.lead_out_start_lba =
-                           msf_to_log(sony_toc.lead_out_start_msf);
-
-                       /* For points that do not exist, move the data over them
-                          to the right location. */
-                       if (single_toc.pointb0 != 0xb0) {
-                               memmove(((char *) &single_toc) + 27,
-                                       ((char *) &single_toc) + 18,
-                                       res_size - 18);
-                               res_size += 9;
-                       } else if (res_size > 18) {
-                               sony_toc.lead_out_start_msf[0] =
-                                   bcd_to_int(single_toc.
-                                              max_start_outer_leadout_msf
-                                              [0]);
-                               sony_toc.lead_out_start_msf[1] =
-                                   bcd_to_int(single_toc.
-                                              max_start_outer_leadout_msf
-                                              [1]);
-                               sony_toc.lead_out_start_msf[2] =
-                                   bcd_to_int(single_toc.
-                                              max_start_outer_leadout_msf
-                                              [2]);
-                               sony_toc.lead_out_start_lba =
-                                   msf_to_log(sony_toc.
-                                              lead_out_start_msf);
-                       }
-                       if (single_toc.pointb1 != 0xb1) {
-                               memmove(((char *) &single_toc) + 36,
-                                       ((char *) &single_toc) + 27,
-                                       res_size - 27);
-                               res_size += 9;
-                       }
-                       if (single_toc.pointb2 != 0xb2) {
-                               memmove(((char *) &single_toc) + 45,
-                                       ((char *) &single_toc) + 36,
-                                       res_size - 36);
-                               res_size += 9;
-                       }
-                       if (single_toc.pointb3 != 0xb3) {
-                               memmove(((char *) &single_toc) + 54,
-                                       ((char *) &single_toc) + 45,
-                                       res_size - 45);
-                               res_size += 9;
-                       }
-                       if (single_toc.pointb4 != 0xb4) {
-                               memmove(((char *) &single_toc) + 63,
-                                       ((char *) &single_toc) + 54,
-                                       res_size - 54);
-                               res_size += 9;
-                       }
-                       if (single_toc.pointc0 != 0xc0) {
-                               memmove(((char *) &single_toc) + 72,
-                                       ((char *) &single_toc) + 63,
-                                       res_size - 63);
-                               res_size += 9;
-                       }
-#if DEBUG
-                       printk(PRINT_INFO PFX "start track lba %u,  "
-                                       "leadout start lba %u\n",
-                            single_toc.start_track_lba,
-                            single_toc.lead_out_start_lba);
-                       {
-                               int i;
-                               for (i = 0;
-                                    i <
-                                    1 +
-                                    bcd_to_int(single_toc.last_track_num)
-                                    -
-                                    bcd_to_int(single_toc.
-                                               first_track_num); i++) {
-                                       printk(KERN_INFO PFX "trk %02d: add 0x%01x, con 0x%01x,  track %02d, start min %02d, sec %02d, frame %02d\n",
-                                            i,
-                                            single_toc.tracks[i].address,
-                                            single_toc.tracks[i].control,
-                                            bcd_to_int(single_toc.
-                                                       tracks[i].track),
-                                            bcd_to_int(single_toc.
-                                                       tracks[i].
-                                                       track_start_msf
-                                                       [0]),
-                                            bcd_to_int(single_toc.
-                                                       tracks[i].
-                                                       track_start_msf
-                                                       [1]),
-                                            bcd_to_int(single_toc.
-                                                       tracks[i].
-                                                       track_start_msf
-                                                       [2]));
-                                       if (mint >
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].track))
-                                               mint =
-                                                   bcd_to_int(single_toc.
-                                                              tracks[i].
-                                                              track);
-                                       if (maxt <
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].track))
-                                               maxt =
-                                                   bcd_to_int(single_toc.
-                                                              tracks[i].
-                                                              track);
-                               }
-                               printk(KERN_INFO PFX "min track number %d,  "
-                                               "max track number %d\n",
-                                    mint, maxt);
-                       }
-#endif
-
-                       /* prepare a special table of contents for a CD-I disc. They don't have one. */
-                       if (single_toc.disk_type == 0x10 &&
-                           single_toc.first_track_num == 2 &&
-                           single_toc.last_track_num == 2 /* CD-I */ ) {
-                               sony_toc.tracks[totaltracks].address = 1;
-                               sony_toc.tracks[totaltracks].control = 4;       /* force data tracks */
-                               sony_toc.tracks[totaltracks].track = 1;
-                               sony_toc.tracks[totaltracks].
-                                   track_start_msf[0] = 0;
-                               sony_toc.tracks[totaltracks].
-                                   track_start_msf[1] = 2;
-                               sony_toc.tracks[totaltracks].
-                                   track_start_msf[2] = 0;
-                               mint = maxt = 1;
-                               totaltracks++;
-                       } else
-                               /* gather track entries from this session */
-                       {
-                               int i;
-                               for (i = 0;
-                                    i <
-                                    1 +
-                                    bcd_to_int(single_toc.last_track_num)
-                                    -
-                                    bcd_to_int(single_toc.
-                                               first_track_num);
-                                    i++, totaltracks++) {
-                                       sony_toc.tracks[totaltracks].
-                                           address =
-                                           single_toc.tracks[i].address;
-                                       sony_toc.tracks[totaltracks].
-                                           control =
-                                           single_toc.tracks[i].control;
-                                       sony_toc.tracks[totaltracks].
-                                           track =
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].track);
-                                       sony_toc.tracks[totaltracks].
-                                           track_start_msf[0] =
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].
-                                                      track_start_msf[0]);
-                                       sony_toc.tracks[totaltracks].
-                                           track_start_msf[1] =
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].
-                                                      track_start_msf[1]);
-                                       sony_toc.tracks[totaltracks].
-                                           track_start_msf[2] =
-                                           bcd_to_int(single_toc.
-                                                      tracks[i].
-                                                      track_start_msf[2]);
-                                       if (i == 0)
-                                               single_toc.
-                                                   start_track_lba =
-                                                   msf_to_log(sony_toc.
-                                                              tracks
-                                                              [totaltracks].
-                                                              track_start_msf);
-                                       if (mint >
-                                           sony_toc.tracks[totaltracks].
-                                           track)
-                                               mint =
-                                                   sony_toc.
-                                                   tracks[totaltracks].
-                                                   track;
-                                       if (maxt <
-                                           sony_toc.tracks[totaltracks].
-                                           track)
-                                               maxt =
-                                                   sony_toc.
-                                                   tracks[totaltracks].
-                                                   track;
-                               }
-                       }
-                       sony_toc.first_track_num = mint;
-                       sony_toc.last_track_num = maxt;
-                       /* Disk type of last session wins. For example:
-                          CD-Extra has disk type 0 for the first session, so
-                          a dumb HiFi CD player thinks it is a plain audio CD.
-                          We are interested in the disk type of the last session,
-                          which is 0x20 (XA) for CD-Extra, so we can access the
-                          data track ... */
-                       sony_toc.disk_type = single_toc.disk_type;
-                       sony_toc.sessions = session;
-
-                       /* don't believe everything :-) */
-                       if (session == 1)
-                               single_toc.start_track_lba = 0;
-                       sony_toc.start_track_lba =
-                           single_toc.start_track_lba;
-
-                       if (session > 1 && single_toc.pointb0 == 0xb0 &&
-                           sony_toc.lead_out_start_lba ==
-                           single_toc.lead_out_start_lba) {
-                               break;
-                       }
-
-                       /* Let's not get carried away... */
-                       if (session > 40) {
-                               printk(KERN_NOTICE PFX "too many sessions: "
-                                               "%d\n", session);
-                               break;
-                       }
-                       session++;
-               }
-               sony_toc.track_entries = totaltracks;
-               /* add one entry for the LAST track with track number CDROM_LEADOUT */
-               sony_toc.tracks[totaltracks].address = single_toc.address2;
-               sony_toc.tracks[totaltracks].control = single_toc.control2;
-               sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
-               sony_toc.tracks[totaltracks].track_start_msf[0] =
-                   sony_toc.lead_out_start_msf[0];
-               sony_toc.tracks[totaltracks].track_start_msf[1] =
-                   sony_toc.lead_out_start_msf[1];
-               sony_toc.tracks[totaltracks].track_start_msf[2] =
-                   sony_toc.lead_out_start_msf[2];
-
-               sony_toc_read = 1;
-
-               pr_debug(PFX "Disk session %d, start track: %d, "
-                               "stop track: %d\n",
-                    session, single_toc.start_track_lba,
-                    single_toc.lead_out_start_lba);
-       }
-       pr_debug(PFX "Leaving %s\n", __FUNCTION__);
-}
-
-
-/*
- * Uniform cdrom interface function
- * return multisession offset and sector information
- */
-static int scd_get_last_session(struct cdrom_device_info *cdi,
-                               struct cdrom_multisession *ms_info)
-{
-       if (ms_info == NULL)
-               return 1;
-
-       if (!sony_toc_read) {
-               if (down_interruptible(&sony_sem))
-                       return -ERESTARTSYS;
-               sony_get_toc();
-               up(&sony_sem);
-       }
-
-       ms_info->addr_format = CDROM_LBA;
-       ms_info->addr.lba = sony_toc.start_track_lba;
-       ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
-           sony_toc.disk_type == 0x10 /* CDI */ ;
-
-       return 0;
-}
-
-/*
- * Search for a specific track in the table of contents.
- */
-static int find_track(int track)
-{
-       int i;
-
-       for (i = 0; i <= sony_toc.track_entries; i++) {
-               if (sony_toc.tracks[i].track == track) {
-                       return i;
-               }
-       }
-
-       return -1;
-}
-
-
-/*
- * Read the subcode and put it in last_sony_subcode for future use.
- */
-static int read_subcode(void)
-{
-       unsigned int res_size;
-
-
-       do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
-                      NULL,
-                      0, (unsigned char *) &last_sony_subcode, &res_size);
-       if ((res_size < 2)
-           || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) {
-               printk(KERN_ERR PFX "Sony CDROM error %s (read_subcode)\n",
-                      translate_error(last_sony_subcode.exec_status[1]));
-               return -EIO;
-       }
-
-       last_sony_subcode.track_num =
-           bcd_to_int(last_sony_subcode.track_num);
-       last_sony_subcode.index_num =
-           bcd_to_int(last_sony_subcode.index_num);
-       last_sony_subcode.abs_msf[0] =
-           bcd_to_int(last_sony_subcode.abs_msf[0]);
-       last_sony_subcode.abs_msf[1] =
-           bcd_to_int(last_sony_subcode.abs_msf[1]);
-       last_sony_subcode.abs_msf[2] =
-           bcd_to_int(last_sony_subcode.abs_msf[2]);
-
-       last_sony_subcode.rel_msf[0] =
-           bcd_to_int(last_sony_subcode.rel_msf[0]);
-       last_sony_subcode.rel_msf[1] =
-           bcd_to_int(last_sony_subcode.rel_msf[1]);
-       last_sony_subcode.rel_msf[2] =
-           bcd_to_int(last_sony_subcode.rel_msf[2]);
-       return 0;
-}
-
-/*
- * Uniform cdrom interface function
- * return the media catalog number found on some older audio cds
- */
-static int
-scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
-{
-       unsigned char resbuffer[2 + 14];
-       unsigned char *mcnp = mcn->medium_catalog_number;
-       unsigned char *resp = resbuffer + 3;
-       unsigned int res_size;
-
-       memset(mcn->medium_catalog_number, 0, 14);
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
-                      NULL, 0, resbuffer, &res_size);
-       up(&sony_sem);
-       if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20));
-       else {
-               /* packed bcd to single ASCII digits */
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-               *mcnp++ = (*resp++ & 0x0f) + '0';
-               *mcnp++ = (*resp >> 4) + '0';
-       }
-       *mcnp = '\0';
-       return 0;
-}
-
-
-/*
- * Get the subchannel info like the CDROMSUBCHNL command wants to see it.  If
- * the drive is playing, the subchannel needs to be read (since it would be
- * changing).  If the drive is paused or completed, the subcode information has
- * already been stored, just use that.  The ioctl call wants things in decimal
- * (not BCD), so all the conversions are done.
- */
-static int sony_get_subchnl_info(struct cdrom_subchnl *schi)
-{
-       /* Get attention stuff */
-       while (handle_sony_cd_attention());
-
-       sony_get_toc();
-       if (!sony_toc_read) {
-               return -EIO;
-       }
-
-       switch (sony_audio_status) {
-       case CDROM_AUDIO_NO_STATUS:
-       case CDROM_AUDIO_PLAY:
-               if (read_subcode() < 0) {
-                       return -EIO;
-               }
-               break;
-
-       case CDROM_AUDIO_PAUSED:
-       case CDROM_AUDIO_COMPLETED:
-               break;
-
-#if 0
-       case CDROM_AUDIO_NO_STATUS:
-               schi->cdsc_audiostatus = sony_audio_status;
-               return 0;
-               break;
-#endif
-       case CDROM_AUDIO_INVALID:
-       case CDROM_AUDIO_ERROR:
-       default:
-               return -EIO;
-       }
-
-       schi->cdsc_audiostatus = sony_audio_status;
-       schi->cdsc_adr = last_sony_subcode.address;
-       schi->cdsc_ctrl = last_sony_subcode.control;
-       schi->cdsc_trk = last_sony_subcode.track_num;
-       schi->cdsc_ind = last_sony_subcode.index_num;
-       if (schi->cdsc_format == CDROM_MSF) {
-               schi->cdsc_absaddr.msf.minute =
-                   last_sony_subcode.abs_msf[0];
-               schi->cdsc_absaddr.msf.second =
-                   last_sony_subcode.abs_msf[1];
-               schi->cdsc_absaddr.msf.frame =
-                   last_sony_subcode.abs_msf[2];
-
-               schi->cdsc_reladdr.msf.minute =
-                   last_sony_subcode.rel_msf[0];
-               schi->cdsc_reladdr.msf.second =
-                   last_sony_subcode.rel_msf[1];
-               schi->cdsc_reladdr.msf.frame =
-                   last_sony_subcode.rel_msf[2];
-       } else if (schi->cdsc_format == CDROM_LBA) {
-               schi->cdsc_absaddr.lba =
-                   msf_to_log(last_sony_subcode.abs_msf);
-               schi->cdsc_reladdr.lba =
-                   msf_to_log(last_sony_subcode.rel_msf);
-       }
-
-       return 0;
-}
-
-/* Get audio data from the drive.  This is fairly complex because I
-   am looking for status and data at the same time, but if I get status
-   then I just look for data.  I need to get the status immediately so
-   the switch from audio to data tracks will happen quickly. */
-static void
-read_audio_data(char *buffer, unsigned char res_reg[], int *res_size)
-{
-       unsigned long retry_count;
-       int result_read;
-
-
-       res_reg[0] = 0;
-       res_reg[1] = 0;
-       *res_size = 0;
-       result_read = 0;
-
-       /* Wait for the drive to tell us we have something */
-       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-      continue_read_audio_wait:
-       while (time_before(jiffies, retry_count) && !(is_data_ready())
-              && !(is_result_ready() || result_read)) {
-               while (handle_sony_cd_attention());
-
-               sony_sleep();
-       }
-       if (!(is_data_ready())) {
-               if (is_result_ready() && !result_read) {
-                       get_result(res_reg, res_size);
-
-                       /* Read block status and continue waiting for data. */
-                       if ((res_reg[0] & 0xf0) == 0x50) {
-                               result_read = 1;
-                               goto continue_read_audio_wait;
-                       }
-                       /* Invalid data from the drive.  Shut down the operation. */
-                       else if ((res_reg[0] & 0xf0) != 0x20) {
-                               printk(KERN_WARNING PFX "Got result that "
-                                               "should have been error: %d\n",
-                                    res_reg[0]);
-                               res_reg[0] = 0x20;
-                               res_reg[1] = SONY_BAD_DATA_ERR;
-                               *res_size = 2;
-                       }
-                       abort_read();
-               } else {
-                       pr_debug(PFX "timeout out %d\n", __LINE__);
-                       res_reg[0] = 0x20;
-                       res_reg[1] = SONY_TIMEOUT_OP_ERR;
-                       *res_size = 2;
-                       abort_read();
-               }
-       } else {
-               clear_data_ready();
-
-               /* If data block, then get 2340 bytes offset by 12. */
-               if (sony_raw_data_mode) {
-                       insb(sony_cd_read_reg, buffer + CD_XA_HEAD,
-                            CD_FRAMESIZE_RAW1);
-               } else {
-                       /* Audio gets the whole 2352 bytes. */
-                       insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
-               }
-
-               /* If I haven't already gotten the result, get it now. */
-               if (!result_read) {
-                       /* Wait for the drive to tell us we have something */
-                       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-                       while (time_before(jiffies, retry_count)
-                              && !(is_result_ready())) {
-                               while (handle_sony_cd_attention());
-
-                               sony_sleep();
-                       }
-
-                       if (!is_result_ready()) {
-                               pr_debug(PFX "timeout out %d\n", __LINE__);
-                               res_reg[0] = 0x20;
-                               res_reg[1] = SONY_TIMEOUT_OP_ERR;
-                               *res_size = 2;
-                               abort_read();
-                               return;
-                       } else {
-                               get_result(res_reg, res_size);
-                       }
-               }
-
-               if ((res_reg[0] & 0xf0) == 0x50) {
-                       if ((res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
-                           || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
-                           || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
-                           || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) {
-                               /* Ok, nothing to do. */
-                       } else {
-                               printk(KERN_ERR PFX "Data block error: 0x%x\n",
-                                      res_reg[0]);
-                               res_reg[0] = 0x20;
-                               res_reg[1] = SONY_BAD_DATA_ERR;
-                               *res_size = 2;
-                       }
-               } else if ((res_reg[0] & 0xf0) != 0x20) {
-                       /* The drive gave me bad status, I don't know what to do.
-                          Reset the driver and return an error. */
-                       printk(KERN_NOTICE PFX "Invalid block status: 0x%x\n",
-                              res_reg[0]);
-                       restart_on_error();
-                       res_reg[0] = 0x20;
-                       res_reg[1] = SONY_BAD_DATA_ERR;
-                       *res_size = 2;
-               }
-       }
-}
-
-/* Perform a raw data read.  This will automatically detect the
-   track type and read the proper data (audio or data). */
-static int read_audio(struct cdrom_read_audio *ra)
-{
-       int retval;
-       unsigned char params[2];
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       unsigned int cframe;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       if (!sony_spun_up)
-               scd_spinup();
-
-       /* Set the drive to do raw operations. */
-       params[0] = SONY_SD_DECODE_PARAM;
-       params[1] = 0x06 | sony_raw_data_mode;
-       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                      params, 2, res_reg, &res_size);
-       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
-               printk(KERN_ERR PFX "Unable to set decode params: 0x%2.2x\n",
-                      res_reg[1]);
-               retval = -EIO;
-               goto out_up;
-       }
-
-       /* From here down, we have to goto exit_read_audio instead of returning
-          because the drive parameters have to be set back to data before
-          return. */
-
-       retval = 0;
-       if (start_request(ra->addr.lba, ra->nframes)) {
-               retval = -EIO;
-               goto exit_read_audio;
-       }
-
-       /* For every requested frame. */
-       cframe = 0;
-       while (cframe < ra->nframes) {
-               read_audio_data(audio_buffer, res_reg, &res_size);
-               if ((res_reg[0] & 0xf0) == 0x20) {
-                       if (res_reg[1] == SONY_BAD_DATA_ERR) {
-                               printk(KERN_ERR PFX "Data error on audio "
-                                               "sector %d\n",
-                                    ra->addr.lba + cframe);
-                       } else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) {
-                               /* Illegal track type, change track types and start over. */
-                               sony_raw_data_mode =
-                                   (sony_raw_data_mode) ? 0 : 1;
-
-                               /* Set the drive mode. */
-                               params[0] = SONY_SD_DECODE_PARAM;
-                               params[1] = 0x06 | sony_raw_data_mode;
-                               do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                                              params,
-                                              2, res_reg, &res_size);
-                               if ((res_size < 2)
-                                   || ((res_reg[0] & 0xf0) == 0x20)) {
-                                       printk(KERN_ERR PFX "Unable to set "
-                                               "decode params: 0x%2.2x\n",
-                                            res_reg[1]);
-                                       retval = -EIO;
-                                       goto exit_read_audio;
-                               }
-
-                               /* Restart the request on the current frame. */
-                               if (start_request
-                                   (ra->addr.lba + cframe,
-                                    ra->nframes - cframe)) {
-                                       retval = -EIO;
-                                       goto exit_read_audio;
-                               }
-
-                               /* Don't go back to the top because don't want to get into
-                                  and infinite loop.  A lot of code gets duplicated, but
-                                  that's no big deal, I don't guess. */
-                               read_audio_data(audio_buffer, res_reg,
-                                               &res_size);
-                               if ((res_reg[0] & 0xf0) == 0x20) {
-                                       if (res_reg[1] ==
-                                           SONY_BAD_DATA_ERR) {
-                                               printk(KERN_ERR PFX "Data error"
-                                                       " on audio sector %d\n",
-                                                    ra->addr.lba +
-                                                    cframe);
-                                       } else {
-                                               printk(KERN_ERR PFX "Error reading audio data on sector %d: %s\n",
-                                                    ra->addr.lba + cframe,
-                                                    translate_error
-                                                    (res_reg[1]));
-                                               retval = -EIO;
-                                               goto exit_read_audio;
-                                       }
-                               } else if (copy_to_user(ra->buf +
-                                                              (CD_FRAMESIZE_RAW
-                                                               * cframe),
-                                                       audio_buffer,
-                                                       CD_FRAMESIZE_RAW)) {
-                                       retval = -EFAULT;
-                                       goto exit_read_audio;
-                               }
-                       } else {
-                               printk(KERN_ERR PFX "Error reading audio "
-                                               "data on sector %d: %s\n",
-                                    ra->addr.lba + cframe,
-                                    translate_error(res_reg[1]));
-                               retval = -EIO;
-                               goto exit_read_audio;
-                       }
-               } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe),
-                                       (char *)audio_buffer,
-                                       CD_FRAMESIZE_RAW)) {
-                       retval = -EFAULT;
-                       goto exit_read_audio;
-               }
-
-               cframe++;
-       }
-
-       get_result(res_reg, &res_size);
-       if ((res_reg[0] & 0xf0) == 0x20) {
-               printk(KERN_ERR PFX "Error return from audio read: %s\n",
-                      translate_error(res_reg[1]));
-               retval = -EIO;
-               goto exit_read_audio;
-       }
-
-      exit_read_audio:
-
-       /* Set the drive mode back to the proper one for the disk. */
-       params[0] = SONY_SD_DECODE_PARAM;
-       if (!sony_xa_mode) {
-               params[1] = 0x0f;
-       } else {
-               params[1] = 0x07;
-       }
-       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                      params, 2, res_reg, &res_size);
-       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
-               printk(KERN_ERR PFX "Unable to reset decode params: 0x%2.2x\n",
-                      res_reg[1]);
-               retval = -EIO;
-       }
-
- out_up:
-       up(&sony_sem);
-
-       return retval;
-}
-
-static int
-do_sony_cd_cmd_chk(const char *name,
-                  unsigned char cmd,
-                  unsigned char *params,
-                  unsigned int num_params,
-                  unsigned char *result_buffer, unsigned int *result_size)
-{
-       do_sony_cd_cmd(cmd, params, num_params, result_buffer,
-                      result_size);
-       if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) {
-               printk(KERN_ERR PFX "Error %s (CDROM%s)\n",
-                      translate_error(result_buffer[1]), name);
-               return -EIO;
-       }
-       return 0;
-}
-
-/*
- * Uniform cdrom interface function
- * open the tray
- */
-static int scd_tray_move(struct cdrom_device_info *cdi, int position)
-{
-       int retval;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       if (position == 1 /* open tray */ ) {
-               unsigned char res_reg[12];
-               unsigned int res_size;
-
-               do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
-                              &res_size);
-               do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               sony_audio_status = CDROM_AUDIO_INVALID;
-               retval = do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0,
-                                         res_reg, &res_size);
-       } else {
-               if (0 == scd_spinup())
-                       sony_spun_up = 1;
-               retval = 0;
-       }
-       up(&sony_sem);
-       return retval;
-}
-
-/*
- * The big ugly ioctl handler.
- */
-static int scd_audio_ioctl(struct cdrom_device_info *cdi,
-                          unsigned int cmd, void *arg)
-{
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       unsigned char params[7];
-       int i, retval;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       switch (cmd) {
-       case CDROMSTART:        /* Spin up the drive */
-               retval = do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL,
-                                         0, res_reg, &res_size);
-               break;
-
-       case CDROMSTOP: /* Spin down the drive */
-               do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               /*
-                * Spin the drive down, ignoring the error if the disk was
-                * already not spinning.
-                */
-               sony_audio_status = CDROM_AUDIO_NO_STATUS;
-               retval = do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL,
-                                         0, res_reg, &res_size);
-               break;
-
-       case CDROMPAUSE:        /* Pause the drive */
-               if (do_sony_cd_cmd_chk
-                   ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
-                    &res_size)) {
-                       retval = -EIO;
-                       break;
-               }
-               /* Get the current position and save it for resuming */
-               if (read_subcode() < 0) {
-                       retval = -EIO;
-                       break;
-               }
-               cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
-               cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
-               cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
-               sony_audio_status = CDROM_AUDIO_PAUSED;
-               retval = 0;
-               break;
-
-       case CDROMRESUME:       /* Start the drive after being paused */
-               if (sony_audio_status != CDROM_AUDIO_PAUSED) {
-                       retval = -EINVAL;
-                       break;
-               }
-
-               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               /* Start the drive at the saved position. */
-               params[1] = int_to_bcd(cur_pos_msf[0]);
-               params[2] = int_to_bcd(cur_pos_msf[1]);
-               params[3] = int_to_bcd(cur_pos_msf[2]);
-               params[4] = int_to_bcd(final_pos_msf[0]);
-               params[5] = int_to_bcd(final_pos_msf[1]);
-               params[6] = int_to_bcd(final_pos_msf[2]);
-               params[0] = 0x03;
-               if (do_sony_cd_cmd_chk
-                   ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg,
-                    &res_size) < 0) {
-                       retval = -EIO;
-                       break;
-               }
-               sony_audio_status = CDROM_AUDIO_PLAY;
-               retval = 0;
-               break;
-
-       case CDROMPLAYMSF:      /* Play starting at the given MSF address. */
-               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               /* The parameters are given in int, must be converted */
-               for (i = 1; i < 7; i++) {
-                       params[i] =
-                           int_to_bcd(((unsigned char *) arg)[i - 1]);
-               }
-               params[0] = 0x03;
-               if (do_sony_cd_cmd_chk
-                   ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7,
-                    res_reg, &res_size) < 0) {
-                       retval = -EIO;
-                       break;
-               }
-
-               /* Save the final position for pauses and resumes */
-               final_pos_msf[0] = bcd_to_int(params[4]);
-               final_pos_msf[1] = bcd_to_int(params[5]);
-               final_pos_msf[2] = bcd_to_int(params[6]);
-               sony_audio_status = CDROM_AUDIO_PLAY;
-               retval = 0;
-               break;
-
-       case CDROMREADTOCHDR:   /* Read the table of contents header */
-               {
-                       struct cdrom_tochdr *hdr;
-
-                       sony_get_toc();
-                       if (!sony_toc_read) {
-                               retval = -EIO;
-                               break;
-                       }
-
-                       hdr = (struct cdrom_tochdr *) arg;
-                       hdr->cdth_trk0 = sony_toc.first_track_num;
-                       hdr->cdth_trk1 = sony_toc.last_track_num;
-               }
-               retval = 0;
-               break;
-
-       case CDROMREADTOCENTRY: /* Read a given table of contents entry */
-               {
-                       struct cdrom_tocentry *entry;
-                       int track_idx;
-                       unsigned char *msf_val = NULL;
-
-                       sony_get_toc();
-                       if (!sony_toc_read) {
-                               retval = -EIO;
-                               break;
-                       }
-
-                       entry = (struct cdrom_tocentry *) arg;
-
-                       track_idx = find_track(entry->cdte_track);
-                       if (track_idx < 0) {
-                               retval = -EINVAL;
-                               break;
-                       }
-
-                       entry->cdte_adr =
-                           sony_toc.tracks[track_idx].address;
-                       entry->cdte_ctrl =
-                           sony_toc.tracks[track_idx].control;
-                       msf_val =
-                           sony_toc.tracks[track_idx].track_start_msf;
-
-                       /* Logical buffer address or MSF format requested? */
-                       if (entry->cdte_format == CDROM_LBA) {
-                               entry->cdte_addr.lba = msf_to_log(msf_val);
-                       } else if (entry->cdte_format == CDROM_MSF) {
-                               entry->cdte_addr.msf.minute = *msf_val;
-                               entry->cdte_addr.msf.second =
-                                   *(msf_val + 1);
-                               entry->cdte_addr.msf.frame =
-                                   *(msf_val + 2);
-                       }
-               }
-               retval = 0;
-               break;
-
-       case CDROMPLAYTRKIND:   /* Play a track.  This currently ignores index. */
-               {
-                       struct cdrom_ti *ti = (struct cdrom_ti *) arg;
-                       int track_idx;
-
-                       sony_get_toc();
-                       if (!sony_toc_read) {
-                               retval = -EIO;
-                               break;
-                       }
-
-                       if ((ti->cdti_trk0 < sony_toc.first_track_num)
-                           || (ti->cdti_trk0 > sony_toc.last_track_num)
-                           || (ti->cdti_trk1 < ti->cdti_trk0)) {
-                               retval = -EINVAL;
-                               break;
-                       }
-
-                       track_idx = find_track(ti->cdti_trk0);
-                       if (track_idx < 0) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       params[1] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[0]);
-                       params[2] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[1]);
-                       params[3] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[2]);
-
-                       /*
-                        * If we want to stop after the last track, use the lead-out
-                        * MSF to do that.
-                        */
-                       if (ti->cdti_trk1 >= sony_toc.last_track_num) {
-                               track_idx = find_track(CDROM_LEADOUT);
-                       } else {
-                               track_idx = find_track(ti->cdti_trk1 + 1);
-                       }
-                       if (track_idx < 0) {
-                               retval = -EINVAL;
-                               break;
-                       }
-                       params[4] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[0]);
-                       params[5] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[1]);
-                       params[6] =
-                           int_to_bcd(sony_toc.tracks[track_idx].
-                                      track_start_msf[2]);
-                       params[0] = 0x03;
-
-                       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
-                                      &res_size);
-
-                       do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7,
-                                      res_reg, &res_size);
-
-                       if ((res_size < 2)
-                           || ((res_reg[0] & 0xf0) == 0x20)) {
-                               printk(KERN_ERR PFX
-                                       "Params: %x %x %x %x %x %x %x\n",
-                                      params[0], params[1], params[2],
-                                      params[3], params[4], params[5],
-                                      params[6]);
-                               printk(KERN_ERR PFX
-                                       "Error %s (CDROMPLAYTRKIND)\n",
-                                    translate_error(res_reg[1]));
-                               retval = -EIO;
-                               break;
-                       }
-
-                       /* Save the final position for pauses and resumes */
-                       final_pos_msf[0] = bcd_to_int(params[4]);
-                       final_pos_msf[1] = bcd_to_int(params[5]);
-                       final_pos_msf[2] = bcd_to_int(params[6]);
-                       sony_audio_status = CDROM_AUDIO_PLAY;
-                       retval = 0;
-                       break;
-               }
-
-       case CDROMVOLCTRL:      /* Volume control.  What volume does this change, anyway? */
-               {
-                       struct cdrom_volctrl *volctrl =
-                           (struct cdrom_volctrl *) arg;
-
-                       params[0] = SONY_SD_AUDIO_VOLUME;
-                       params[1] = volctrl->channel0;
-                       params[2] = volctrl->channel1;
-                       retval = do_sony_cd_cmd_chk("VOLCTRL",
-                                                 SONY_SET_DRIVE_PARAM_CMD,
-                                                 params, 3, res_reg,
-                                                 &res_size);
-                       break;
-               }
-       case CDROMSUBCHNL:      /* Get subchannel info */
-               retval = sony_get_subchnl_info((struct cdrom_subchnl *) arg);
-               break;
-
-       default:
-               retval = -EINVAL;
-               break;
-       }
-       up(&sony_sem);
-       return retval;
-}
-
-static int scd_read_audio(struct cdrom_device_info *cdi,
-                        unsigned int cmd, unsigned long arg)
-{
-       void __user *argp = (void __user *)arg;
-       int retval;
-
-       if (down_interruptible(&sony_sem))
-               return -ERESTARTSYS;
-       switch (cmd) {
-       case CDROMREADAUDIO:    /* Read 2352 byte audio tracks and 2340 byte
-                                  raw data tracks. */
-               {
-                       struct cdrom_read_audio ra;
-
-
-                       sony_get_toc();
-                       if (!sony_toc_read) {
-                               retval = -EIO;
-                               break;
-                       }
-
-                       if (copy_from_user(&ra, argp, sizeof(ra))) {
-                               retval = -EFAULT;
-                               break;
-                       }
-
-                       if (ra.nframes == 0) {
-                               retval = 0;
-                               break;
-                       }
-
-                       if (!access_ok(VERIFY_WRITE, ra.buf,
-                                       CD_FRAMESIZE_RAW * ra.nframes))
-                               return -EFAULT;
-
-                       if (ra.addr_format == CDROM_LBA) {
-                               if ((ra.addr.lba >=
-                                    sony_toc.lead_out_start_lba)
-                                   || (ra.addr.lba + ra.nframes >=
-                                       sony_toc.lead_out_start_lba)) {
-                                       retval = -EINVAL;
-                                       break;
-                               }
-                       } else if (ra.addr_format == CDROM_MSF) {
-                               if ((ra.addr.msf.minute >= 75)
-                                   || (ra.addr.msf.second >= 60)
-                                   || (ra.addr.msf.frame >= 75)) {
-                                       retval = -EINVAL;
-                                       break;
-                               }
-
-                               ra.addr.lba = ((ra.addr.msf.minute * 4500)
-                                              + (ra.addr.msf.second * 75)
-                                              + ra.addr.msf.frame);
-                               if ((ra.addr.lba >=
-                                    sony_toc.lead_out_start_lba)
-                                   || (ra.addr.lba + ra.nframes >=
-                                       sony_toc.lead_out_start_lba)) {
-                                       retval = -EINVAL;
-                                       break;
-                               }
-
-                               /* I know, this can go negative on an unsigned.  However,
-                                  the first thing done to the data is to add this value,
-                                  so this should compensate and allow direct msf access. */
-                               ra.addr.lba -= LOG_START_OFFSET;
-                       } else {
-                               retval = -EINVAL;
-                               break;
-                       }
-
-                       retval = read_audio(&ra);
-                       break;
-               }
-               retval = 0;
-               break;
-
-       default:
-               retval = -EINVAL;
-       }
-       up(&sony_sem);
-       return retval;
-}
-
-static int scd_spinup(void)
-{
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       int num_spin_ups;
-
-       num_spin_ups = 0;
-
-      respinup_on_open:
-       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
-       /* The drive sometimes returns error 0.  I don't know why, but ignore
-          it.  It seems to mean the drive has already done the operation. */
-       if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
-               printk(KERN_ERR PFX "%s error (scd_open, spin up)\n",
-                      translate_error(res_reg[1]));
-               return 1;
-       }
-
-       do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
-
-       /* The drive sometimes returns error 0.  I don't know why, but ignore
-          it.  It seems to mean the drive has already done the operation. */
-       if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
-               /* If the drive is already playing, it's ok.  */
-               if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
-                   || (res_reg[1] == 0)) {
-                       return 0;
-               }
-
-               /* If the drive says it is not spun up (even though we just did it!)
-                  then retry the operation at least a few times. */
-               if ((res_reg[1] == SONY_NOT_SPIN_ERR)
-                   && (num_spin_ups < MAX_CDU31A_RETRIES)) {
-                       num_spin_ups++;
-                       goto respinup_on_open;
-               }
-
-               printk(KERN_ERR PFX "Error %s (scd_open, read toc)\n",
-                      translate_error(res_reg[1]));
-               do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
-                              &res_size);
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * Open the drive for operations.  Spin the drive up and read the table of
- * contents if these have not already been done.
- */
-static int scd_open(struct cdrom_device_info *cdi, int purpose)
-{
-       unsigned char res_reg[12];
-       unsigned int res_size;
-       unsigned char params[2];
-
-       if (purpose == 1) {
-               /* Open for IOCTLs only - no media check */
-               sony_usage++;
-               return 0;
-       }
-
-       if (sony_usage == 0) {
-               if (scd_spinup() != 0)
-                       return -EIO;
-               sony_get_toc();
-               if (!sony_toc_read) {
-                       do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0,
-                                      res_reg, &res_size);
-                       return -EIO;
-               }
-
-               /* For XA on the CDU31A only, we have to do special reads.
-                  The CDU33A handles XA automagically. */
-               /* if (   (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
-               if ((sony_toc.disk_type != 0x00)
-                   && (!is_double_speed)) {
-                       params[0] = SONY_SD_DECODE_PARAM;
-                       params[1] = 0x07;
-                       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                                      params, 2, res_reg, &res_size);
-                       if ((res_size < 2)
-                           || ((res_reg[0] & 0xf0) == 0x20)) {
-                               printk(KERN_WARNING PFX "Unable to set "
-                                       "XA params: 0x%2.2x\n", res_reg[1]);
-                       }
-                       sony_xa_mode = 1;
-               }
-               /* A non-XA disk.  Set the parms back if necessary. */
-               else if (sony_xa_mode) {
-                       params[0] = SONY_SD_DECODE_PARAM;
-                       params[1] = 0x0f;
-                       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                                      params, 2, res_reg, &res_size);
-                       if ((res_size < 2)
-                           || ((res_reg[0] & 0xf0) == 0x20)) {
-                               printk(KERN_WARNING PFX "Unable to reset "
-                                       "XA params: 0x%2.2x\n", res_reg[1]);
-                       }
-                       sony_xa_mode = 0;
-               }
-
-               sony_spun_up = 1;
-       }
-
-       sony_usage++;
-
-       return 0;
-}
-
-
-/*
- * Close the drive.  Spin it down if no task is using it.  The spin
- * down will fail if playing audio, so audio play is OK.
- */
-static void scd_release(struct cdrom_device_info *cdi)
-{
-       if (sony_usage == 1) {
-               unsigned char res_reg[12];
-               unsigned int res_size;
-
-               do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
-                              &res_size);
-
-               sony_spun_up = 0;
-       }
-       sony_usage--;
-}
-
-static struct cdrom_device_ops scd_dops = {
-       .open                   = scd_open,
-       .release                = scd_release,
-       .drive_status           = scd_drive_status,
-       .media_changed          = scd_media_changed,
-       .tray_move              = scd_tray_move,
-       .lock_door              = scd_lock_door,
-       .select_speed           = scd_select_speed,
-       .get_last_session       = scd_get_last_session,
-       .get_mcn                = scd_get_mcn,
-       .reset                  = scd_reset,
-       .audio_ioctl            = scd_audio_ioctl,
-       .capability             = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
-                                 CDC_SELECT_SPEED | CDC_MULTI_SESSION |
-                                 CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
-                                 CDC_RESET | CDC_DRIVE_STATUS,
-       .n_minors               = 1,
-};
-
-static struct cdrom_device_info scd_info = {
-       .ops            = &scd_dops,
-       .speed          = 2,
-       .capacity       = 1,
-       .name           = "cdu31a"
-};
-
-static int scd_block_open(struct inode *inode, struct file *file)
-{
-       return cdrom_open(&scd_info, inode, file);
-}
-
-static int scd_block_release(struct inode *inode, struct file *file)
-{
-       return cdrom_release(&scd_info, file);
-}
-
-static int scd_block_ioctl(struct inode *inode, struct file *file,
-                               unsigned cmd, unsigned long arg)
-{
-       int retval;
-
-       /* The eject and close commands should be handled by Uniform CD-ROM
-        * driver - but I always got hard lockup instead of eject
-        * until I put this here.
-        */
-       switch (cmd) {
-               case CDROMEJECT:
-                       scd_lock_door(&scd_info, 0);
-                       retval = scd_tray_move(&scd_info, 1);
-                       break;
-               case CDROMCLOSETRAY:
-                       retval = scd_tray_move(&scd_info, 0);
-                       break;
-               case CDROMREADAUDIO:
-                       retval = scd_read_audio(&scd_info, CDROMREADAUDIO, arg);
-                       break;
-               default:
-                       retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg);
-       }
-       return retval;
-}
-
-static int scd_block_media_changed(struct gendisk *disk)
-{
-       return cdrom_media_changed(&scd_info);
-}
-
-static struct block_device_operations scd_bdops =
-{
-       .owner          = THIS_MODULE,
-       .open           = scd_block_open,
-       .release        = scd_block_release,
-       .ioctl          = scd_block_ioctl,
-       .media_changed  = scd_block_media_changed,
-};
-
-static struct gendisk *scd_gendisk;
-
-/* The different types of disc loading mechanisms supported */
-static char *load_mech[] __initdata =
-    { "caddy", "tray", "pop-up", "unknown" };
-
-static int __init
-get_drive_configuration(unsigned short base_io,
-                       unsigned char res_reg[], unsigned int *res_size)
-{
-       unsigned long retry_count;
-
-
-       if (!request_region(base_io, 4, "cdu31a"))
-               return 0;
-
-       /* Set the base address */
-       cdu31a_port = base_io;
-
-       /* Set up all the register locations */
-       sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
-       sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
-       sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
-       sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
-       sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
-       sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
-       sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
-       sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
-
-       /*
-        * Check to see if anything exists at the status register location.
-        * I don't know if this is a good way to check, but it seems to work
-        * ok for me.
-        */
-       if (read_status_register() != 0xff) {
-               /*
-                * Reset the drive and wait for attention from it (to say it's reset).
-                * If you don't wait, the next operation will probably fail.
-                */
-               reset_drive();
-               retry_count = jiffies + SONY_RESET_TIMEOUT;
-               while (time_before(jiffies, retry_count)
-                      && (!is_attention())) {
-                       sony_sleep();
-               }
-
-#if 0
-               /* If attention is never seen probably not a CDU31a present */
-               if (!is_attention()) {
-                       res_reg[0] = 0x20;
-                       goto out_err;
-               }
-#endif
-
-               /*
-                * Get the drive configuration.
-                */
-               do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
-                              NULL,
-                              0, (unsigned char *) res_reg, res_size);
-               if (*res_size <= 2 || (res_reg[0] & 0xf0) != 0)
-                       goto out_err;
-               return 1;
-       }
-
-       /* Return an error */
-       res_reg[0] = 0x20;
-out_err:
-       release_region(cdu31a_port, 4);
-       cdu31a_port = 0;
-       return 0;
-}
-
-#ifndef MODULE
-/*
- * Set up base I/O and interrupts, called from main.c.
- */
-
-static int __init cdu31a_setup(char *strings)
-{
-       int ints[4];
-
-       (void) get_options(strings, ARRAY_SIZE(ints), ints);
-
-       if (ints[0] > 0) {
-               cdu31a_port = ints[1];
-       }
-       if (ints[0] > 1) {
-               cdu31a_irq = ints[2];
-       }
-       if ((strings != NULL) && (*strings != '\0')) {
-               if (strcmp(strings, "PAS") == 0) {
-                       sony_pas_init = 1;
-               } else {
-                       printk(KERN_NOTICE PFX "Unknown interface type: %s\n",
-                              strings);
-               }
-       }
-
-       return 1;
-}
-
-__setup("cdu31a=", cdu31a_setup);
-
-#endif
-
-/*
- * Initialize the driver.
- */
-int __init cdu31a_init(void)
-{
-       struct s_sony_drive_config drive_config;
-       struct gendisk *disk;
-       int deficiency = 0;
-       unsigned int res_size;
-       char msg[255];
-       char buf[40];
-       int i;
-       int tmp_irq;
-
-       /*
-        * According to Alex Freed (freed@europa.orion.adobe.com), this is
-        * required for the Fusion CD-16 package.  If the sound driver is
-        * loaded, it should work fine, but just in case...
-        *
-        * The following turn on the CD-ROM interface for a Fusion CD-16.
-        */
-       if (sony_pas_init) {
-               outb(0xbc, 0x9a01);
-               outb(0xe2, 0x9a01);
-       }
-
-       /* Setting the base I/O address to 0xffff will disable it. */
-       if (cdu31a_port == 0xffff)
-               goto errout3;
-
-       if (cdu31a_port != 0) {
-               /* Need IRQ 0 because we can't sleep here. */
-               tmp_irq = cdu31a_irq;
-               cdu31a_irq = 0;
-               if (!get_drive_configuration(cdu31a_port,
-                                           drive_config.exec_status,
-                                           &res_size))
-                       goto errout3;
-               cdu31a_irq = tmp_irq;
-       } else {
-               cdu31a_irq = 0;
-               for (i = 0; cdu31a_addresses[i].base; i++) {
-                       if (get_drive_configuration(cdu31a_addresses[i].base,
-                                                    drive_config.exec_status,
-                                                    &res_size)) {
-                               cdu31a_irq = cdu31a_addresses[i].int_num;
-                               break;
-                       }
-               }
-               if (!cdu31a_port)
-                       goto errout3;
-       }
-
-       if (register_blkdev(MAJOR_NR, "cdu31a"))
-               goto errout2;
-
-       disk = alloc_disk(1);
-       if (!disk)
-               goto errout1;
-       disk->major = MAJOR_NR;
-       disk->first_minor = 0;
-       sprintf(disk->disk_name, "cdu31a");
-       disk->fops = &scd_bdops;
-       disk->flags = GENHD_FL_CD;
-
-       if (SONY_HWC_DOUBLE_SPEED(drive_config))
-               is_double_speed = 1;
-
-       tmp_irq = cdu31a_irq;   /* Need IRQ 0 because we can't sleep here. */
-       cdu31a_irq = 0;
-
-       sony_speed = is_double_speed; /* Set 2X drives to 2X by default */
-       set_drive_params(sony_speed);
-
-       cdu31a_irq = tmp_irq;
-
-       if (cdu31a_irq > 0) {
-               if (request_irq
-                   (cdu31a_irq, cdu31a_interrupt, IRQF_DISABLED,
-                    "cdu31a", NULL)) {
-                       printk(KERN_WARNING PFX "Unable to grab IRQ%d for "
-                                       "the CDU31A driver\n", cdu31a_irq);
-                       cdu31a_irq = 0;
-               }
-       }
-
-       sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
-               drive_config.vendor_id,
-               drive_config.product_id,
-               drive_config.product_rev_level);
-       sprintf(buf, "  Capabilities: %s",
-               load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
-       strcat(msg, buf);
-       if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
-               strcat(msg, ", audio");
-       else
-               deficiency |= CDC_PLAY_AUDIO;
-       if (SONY_HWC_EJECT(drive_config))
-               strcat(msg, ", eject");
-       else
-               deficiency |= CDC_OPEN_TRAY;
-       if (SONY_HWC_LED_SUPPORT(drive_config))
-               strcat(msg, ", LED");
-       if (SONY_HWC_ELECTRIC_VOLUME(drive_config))
-               strcat(msg, ", elec. Vol");
-       if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config))
-               strcat(msg, ", sep. Vol");
-       if (is_double_speed)
-               strcat(msg, ", double speed");
-       else
-               deficiency |= CDC_SELECT_SPEED;
-       if (cdu31a_irq > 0) {
-               sprintf(buf, ", irq %d", cdu31a_irq);
-               strcat(msg, buf);
-       }
-       strcat(msg, "\n");
-       printk(KERN_INFO PFX "%s",msg);
-
-       cdu31a_queue = blk_init_queue(do_cdu31a_request, &cdu31a_lock);
-       if (!cdu31a_queue)
-               goto errout0;
-       blk_queue_hardsect_size(cdu31a_queue, 2048);
-
-       init_timer(&cdu31a_abort_timer);
-       cdu31a_abort_timer.function = handle_abort_timeout;
-
-       scd_info.mask = deficiency;
-       scd_gendisk = disk;
-       if (register_cdrom(&scd_info))
-               goto err;
-       disk->queue = cdu31a_queue;
-       add_disk(disk);
-
-       disk_changed = 1;
-       return 0;
-
-err:
-       blk_cleanup_queue(cdu31a_queue);
-errout0:
-       if (cdu31a_irq)
-               free_irq(cdu31a_irq, NULL);
-       printk(KERN_ERR PFX "Unable to register with Uniform cdrom driver\n");
-       put_disk(disk);
-errout1:
-       if (unregister_blkdev(MAJOR_NR, "cdu31a")) {
-               printk(KERN_WARNING PFX "Can't unregister block device\n");
-       }
-errout2:
-       release_region(cdu31a_port, 4);
-errout3:
-       return -EIO;
-}
-
-
-static void __exit cdu31a_exit(void)
-{
-       del_gendisk(scd_gendisk);
-       put_disk(scd_gendisk);
-       if (unregister_cdrom(&scd_info)) {
-               printk(KERN_WARNING PFX "Can't unregister from Uniform "
-                               "cdrom driver\n");
-               return;
-       }
-       if ((unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) {
-               printk(KERN_WARNING PFX "Can't unregister\n");
-               return;
-       }
-
-       blk_cleanup_queue(cdu31a_queue);
-
-       if (cdu31a_irq > 0)
-               free_irq(cdu31a_irq, NULL);
-
-       release_region(cdu31a_port, 4);
-       printk(KERN_INFO PFX "module released.\n");
-}
-
-#ifdef MODULE
-module_init(cdu31a_init);
-#endif
-module_exit(cdu31a_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_BLOCKDEV_MAJOR(CDU31A_CDROM_MAJOR);
diff --git a/drivers/cdrom/cdu31a.h b/drivers/cdrom/cdu31a.h
deleted file mode 100644 (file)
index 61d4768..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-/*
- * Definitions for a Sony interface CDROM drive.
- *
- * Corey Minyard (minyard@wf-rch.cirr.com)
- *
- *  Copyright (C) 1993  Corey Minyard
- *
- *  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.
- *
- */
-
-/*
- * General defines.
- */
-#define SONY_XA_DISK_TYPE 0x20
-
-/*
- * Offsets (from the base address) and bits for the various write registers
- * of the drive.
- */
-#define SONY_CMD_REG_OFFSET     0
-#define SONY_PARAM_REG_OFFSET   1
-#define SONY_WRITE_REG_OFFSET   2
-#define SONY_CONTROL_REG_OFFSET 3
-#       define SONY_ATTN_CLR_BIT        0x01
-#       define SONY_RES_RDY_CLR_BIT     0x02
-#       define SONY_DATA_RDY_CLR_BIT    0x04
-#       define SONY_ATTN_INT_EN_BIT     0x08
-#       define SONY_RES_RDY_INT_EN_BIT  0x10
-#       define SONY_DATA_RDY_INT_EN_BIT 0x20
-#       define SONY_PARAM_CLR_BIT       0x40
-#       define SONY_DRIVE_RESET_BIT     0x80
-
-/*
- * Offsets (from the base address) and bits for the various read registers
- * of the drive.
- */
-#define SONY_STATUS_REG_OFFSET  0
-#       define SONY_ATTN_BIT            0x01
-#       define SONY_RES_RDY_BIT         0x02
-#       define SONY_DATA_RDY_BIT        0x04
-#       define SONY_ATTN_INT_ST_BIT     0x08
-#       define SONY_RES_RDY_INT_ST_BIT  0x10
-#       define SONY_DATA_RDY_INT_ST_BIT 0x20
-#       define SONY_DATA_REQUEST_BIT    0x40
-#       define SONY_BUSY_BIT            0x80
-#define SONY_RESULT_REG_OFFSET  1
-#define SONY_READ_REG_OFFSET    2
-#define SONY_FIFOST_REG_OFFSET  3
-#       define SONY_PARAM_WRITE_RDY_BIT 0x01
-#       define SONY_PARAM_REG_EMPTY_BIT 0x02
-#       define SONY_RES_REG_NOT_EMP_BIT 0x04
-#       define SONY_RES_REG_FULL_BIT    0x08
-
-#define LOG_START_OFFSET        150     /* Offset of first logical sector */
-
-#define SONY_DETECT_TIMEOUT    (8*HZ/10) /* Maximum amount of time
-                                           that drive detection code
-                                           will wait for response
-                                           from drive (in 1/100th's
-                                           of seconds). */
-#define SONY_JIFFIES_TIMEOUT    (10*HZ)        /* Maximum number of times the
-                                           drive will wait/try for an
-                                           operation */
-#define SONY_RESET_TIMEOUT      HZ     /* Maximum number of times the
-                                           drive will wait/try a reset
-                                           operation */
-#define SONY_READY_RETRIES      20000   /* How many times to retry a
-                                           spin waiting for a register
-                                           to come ready */
-
-#define MAX_CDU31A_RETRIES      3       /* How many times to retry an
-                                           operation */
-
-/* Commands to request or set drive control parameters and disc information */
-#define SONY_REQ_DRIVE_CONFIG_CMD       0x00    /* Returns s_sony_drive_config */
-#define SONY_REQ_DRIVE_MODE_CMD         0x01
-#define SONY_REQ_DRIVE_PARAM_CMD        0x02
-#define SONY_REQ_MECH_STATUS_CMD        0x03
-#define SONY_REQ_AUDIO_STATUS_CMD       0x04
-#define SONY_SET_DRIVE_PARAM_CMD        0x10
-#define SONY_REQ_TOC_DATA_CMD           0x20    /* Returns s_sony_toc */
-#define SONY_REQ_SUBCODE_ADDRESS_CMD    0x21    /* Returns s_sony_subcode */
-#define SONY_REQ_UPC_EAN_CMD            0x22
-#define SONY_REQ_ISRC_CMD               0x23
-#define SONY_REQ_TOC_DATA_SPEC_CMD      0x24    /* Returns s_sony_session_toc */
-
-/* Commands to request information from the drive */
-#define SONY_READ_TOC_CMD               0x30    /* let the drive firmware grab the TOC */
-#define SONY_SEEK_CMD                   0x31
-#define SONY_READ_CMD                   0x32
-#define SONY_READ_BLKERR_STAT_CMD       0x34
-#define SONY_ABORT_CMD                  0x35
-#define SONY_READ_TOC_SPEC_CMD          0x36
-
-/* Commands to control audio */
-#define SONY_AUDIO_PLAYBACK_CMD         0x40
-#define SONY_AUDIO_STOP_CMD             0x41
-#define SONY_AUDIO_SCAN_CMD             0x42
-
-/* Miscellaneous control commands */
-#define SONY_EJECT_CMD                  0x50
-#define SONY_SPIN_UP_CMD                0x51
-#define SONY_SPIN_DOWN_CMD              0x52
-
-/* Diagnostic commands */
-#define SONY_WRITE_BUFFER_CMD           0x60
-#define SONY_READ_BUFFER_CMD            0x61
-#define SONY_DIAGNOSTICS_CMD            0x62
-
-
-/*
- * The following are command parameters for the set drive parameter command
- */
-#define SONY_SD_DECODE_PARAM            0x00
-#define SONY_SD_INTERFACE_PARAM         0x01
-#define SONY_SD_BUFFERING_PARAM         0x02
-#define SONY_SD_AUDIO_PARAM             0x03
-#define SONY_SD_AUDIO_VOLUME            0x04
-#define SONY_SD_MECH_CONTROL            0x05
-#define SONY_SD_AUTO_SPIN_DOWN_TIME     0x06
-
-/*
- * The following are parameter bits for the mechanical control command
- */
-#define SONY_AUTO_SPIN_UP_BIT           0x01
-#define SONY_AUTO_EJECT_BIT             0x02
-#define SONY_DOUBLE_SPEED_BIT           0x04
-
-/*
- * The following extract information from the drive configuration about
- * the drive itself.
- */
-#define SONY_HWC_GET_LOAD_MECH(c)       (c.hw_config[0] & 0x03)
-#define SONY_HWC_EJECT(c)               (c.hw_config[0] & 0x04)
-#define SONY_HWC_LED_SUPPORT(c)         (c.hw_config[0] & 0x08)
-#define SONY_HWC_DOUBLE_SPEED(c)        (c.hw_config[0] & 0x10)
-#define SONY_HWC_GET_BUF_MEM_SIZE(c)    ((c.hw_config[0] & 0xc0) >> 6)
-#define SONY_HWC_AUDIO_PLAYBACK(c)      (c.hw_config[1] & 0x01)
-#define SONY_HWC_ELECTRIC_VOLUME(c)     (c.hw_config[1] & 0x02)
-#define SONY_HWC_ELECTRIC_VOLUME_CTL(c) (c.hw_config[1] & 0x04)
-
-#define SONY_HWC_CADDY_LOAD_MECH        0x00
-#define SONY_HWC_TRAY_LOAD_MECH         0x01
-#define SONY_HWC_POPUP_LOAD_MECH        0x02
-#define SONY_HWC_UNKWN_LOAD_MECH        0x03
-
-#define SONY_HWC_8KB_BUFFER             0x00
-#define SONY_HWC_32KB_BUFFER            0x01
-#define SONY_HWC_64KB_BUFFER            0x02
-#define SONY_HWC_UNKWN_BUFFER           0x03
-
-/*
- * This is the complete status returned from the drive configuration request
- * command.
- */
-struct s_sony_drive_config
-{
-   unsigned char exec_status[2];
-   char vendor_id[8];
-   char product_id[16];
-   char product_rev_level[8];
-   unsigned char hw_config[2];
-};
-
-/* The following is returned from the request subcode address command */
-struct s_sony_subcode
-{
-   unsigned char exec_status[2];
-   unsigned char address        :4;
-   unsigned char control        :4;
-   unsigned char track_num;
-   unsigned char index_num;
-   unsigned char rel_msf[3];
-   unsigned char reserved1;
-   unsigned char abs_msf[3];
-};
-
-#define MAX_TRACKS 100 /* The maximum tracks a disk may have. */
-/*
- * The following is returned from the request TOC (Table Of Contents) command.
- * (last_track_num-first_track_num+1) values are valid in tracks.
- */
-struct s_sony_toc
-{
-   unsigned char exec_status[2];
-   unsigned char address0       :4;
-   unsigned char control0       :4;
-   unsigned char point0;
-   unsigned char first_track_num;
-   unsigned char disk_type;
-   unsigned char dummy0;
-   unsigned char address1       :4;
-   unsigned char control1       :4;
-   unsigned char point1;
-   unsigned char last_track_num;
-   unsigned char dummy1;
-   unsigned char dummy2;
-   unsigned char address2       :4;
-   unsigned char control2       :4;
-   unsigned char point2;
-   unsigned char lead_out_start_msf[3];
-   struct
-   {
-      unsigned char address     :4;
-      unsigned char control     :4;
-      unsigned char track;
-      unsigned char track_start_msf[3];
-   } tracks[MAX_TRACKS];
-
-   unsigned int lead_out_start_lba;
-};
-
-struct s_sony_session_toc
-{
-   unsigned char exec_status[2];
-   unsigned char session_number;
-   unsigned char address0       :4;
-   unsigned char control0       :4;
-   unsigned char point0;
-   unsigned char first_track_num;
-   unsigned char disk_type;
-   unsigned char dummy0;
-   unsigned char address1       :4;
-   unsigned char control1       :4;
-   unsigned char point1;
-   unsigned char last_track_num;
-   unsigned char dummy1;
-   unsigned char dummy2;
-   unsigned char address2       :4;
-   unsigned char control2       :4;
-   unsigned char point2;
-   unsigned char lead_out_start_msf[3];
-   unsigned char addressb0      :4;
-   unsigned char controlb0      :4;
-   unsigned char pointb0;
-   unsigned char next_poss_prog_area_msf[3];
-   unsigned char num_mode_5_pointers;
-   unsigned char max_start_outer_leadout_msf[3];
-   unsigned char addressb1      :4;
-   unsigned char controlb1      :4;
-   unsigned char pointb1;
-   unsigned char dummyb0_1[4];
-   unsigned char num_skip_interval_pointers;
-   unsigned char num_skip_track_assignments;
-   unsigned char dummyb0_2;
-   unsigned char addressb2      :4;
-   unsigned char controlb2      :4;
-   unsigned char pointb2;
-   unsigned char tracksb2[7];
-   unsigned char addressb3      :4;
-   unsigned char controlb3      :4;
-   unsigned char pointb3;
-   unsigned char tracksb3[7];
-   unsigned char addressb4      :4;
-   unsigned char controlb4      :4;
-   unsigned char pointb4;
-   unsigned char tracksb4[7];
-   unsigned char addressc0      :4;
-   unsigned char controlc0      :4;
-   unsigned char pointc0;
-   unsigned char dummyc0[7];
-   struct
-   {
-      unsigned char address     :4;
-      unsigned char control     :4;
-      unsigned char track;
-      unsigned char track_start_msf[3];
-   } tracks[MAX_TRACKS];
-
-   unsigned int start_track_lba;
-   unsigned int lead_out_start_lba;
-   unsigned int mint;
-   unsigned int maxt;
-};
-
-struct s_all_sessions_toc
-{
-   unsigned char sessions;
-   unsigned int track_entries;
-   unsigned char first_track_num;
-   unsigned char last_track_num;
-   unsigned char disk_type;
-   unsigned char lead_out_start_msf[3];
-   struct
-   {
-      unsigned char address     :4;
-      unsigned char control     :4;
-      unsigned char track;
-      unsigned char track_start_msf[3];
-   } tracks[MAX_TRACKS];
-
-   unsigned int start_track_lba;
-   unsigned int lead_out_start_lba;
-};
-
-
-/*
- * The following are errors returned from the drive.
- */
-
-/* Command error group */
-#define SONY_ILL_CMD_ERR                0x10
-#define SONY_ILL_PARAM_ERR              0x11
-
-/* Mechanism group */
-#define SONY_NOT_LOAD_ERR               0x20
-#define SONY_NO_DISK_ERR                0x21
-#define SONY_NOT_SPIN_ERR               0x22
-#define SONY_SPIN_ERR                   0x23
-#define SONY_SPINDLE_SERVO_ERR          0x25
-#define SONY_FOCUS_SERVO_ERR            0x26
-#define SONY_EJECT_MECH_ERR             0x29
-#define SONY_AUDIO_PLAYING_ERR          0x2a
-#define SONY_EMERGENCY_EJECT_ERR        0x2c
-
-/* Seek error group */
-#define SONY_FOCUS_ERR                  0x30
-#define SONY_FRAME_SYNC_ERR             0x31
-#define SONY_SUBCODE_ADDR_ERR           0x32
-#define SONY_BLOCK_SYNC_ERR             0x33
-#define SONY_HEADER_ADDR_ERR            0x34
-
-/* Read error group */
-#define SONY_ILL_TRACK_R_ERR            0x40
-#define SONY_MODE_0_R_ERR               0x41
-#define SONY_ILL_MODE_R_ERR             0x42
-#define SONY_ILL_BLOCK_SIZE_R_ERR       0x43
-#define SONY_MODE_R_ERR                 0x44
-#define SONY_FORM_R_ERR                 0x45
-#define SONY_LEAD_OUT_R_ERR             0x46
-#define SONY_BUFFER_OVERRUN_R_ERR       0x47
-
-/* Data error group */
-#define SONY_UNREC_CIRC_ERR             0x53
-#define SONY_UNREC_LECC_ERR             0x57
-
-/* Subcode error group */
-#define SONY_NO_TOC_ERR                 0x60
-#define SONY_SUBCODE_DATA_NVAL_ERR      0x61
-#define SONY_FOCUS_ON_TOC_READ_ERR      0x63
-#define SONY_FRAME_SYNC_ON_TOC_READ_ERR 0x64
-#define SONY_TOC_DATA_ERR               0x65
-
-/* Hardware failure group */
-#define SONY_HW_FAILURE_ERR             0x70
-#define SONY_LEAD_IN_A_ERR              0x91
-#define SONY_LEAD_OUT_A_ERR             0x92
-#define SONY_DATA_TRACK_A_ERR           0x93
-
-/*
- * The following are returned from the Read With Block Error Status command.
- * They are not errors but information (Errors from the 0x5x group above may
- * also be returned
- */
-#define SONY_NO_CIRC_ERR_BLK_STAT       0x50
-#define SONY_NO_LECC_ERR_BLK_STAT       0x54
-#define SONY_RECOV_LECC_ERR_BLK_STAT    0x55
-#define SONY_NO_ERR_DETECTION_STAT      0x59
-
-/* 
- * The following is not an error returned by the drive, but by the code
- * that talks to the drive.  It is returned because of a timeout.
- */
-#define SONY_TIMEOUT_OP_ERR             0x01
-#define SONY_SIGNAL_OP_ERR              0x02
-#define SONY_BAD_DATA_ERR               0x03
-
-
-/*
- * The following are attention code for asynchronous events from the drive.
- */
-
-/* Standard attention group */
-#define SONY_EMER_EJECT_ATTN            0x2c
-#define SONY_HW_FAILURE_ATTN            0x70
-#define SONY_MECH_LOADED_ATTN           0x80
-#define SONY_EJECT_PUSHED_ATTN          0x81
-
-/* Audio attention group */
-#define SONY_AUDIO_PLAY_DONE_ATTN       0x90
-#define SONY_LEAD_IN_ERR_ATTN           0x91
-#define SONY_LEAD_OUT_ERR_ATTN          0x92
-#define SONY_DATA_TRACK_ERR_ATTN        0x93
-#define SONY_AUDIO_PLAYBACK_ERR_ATTN    0x94
-
-/* Auto spin up group */
-#define SONY_SPIN_UP_COMPLETE_ATTN      0x24
-#define SONY_SPINDLE_SERVO_ERR_ATTN     0x25
-#define SONY_FOCUS_SERVO_ERR_ATTN       0x26
-#define SONY_TOC_READ_DONE_ATTN         0x62
-#define SONY_FOCUS_ON_TOC_READ_ERR_ATTN 0x63
-#define SONY_SYNC_ON_TOC_READ_ERR_ATTN  0x65
-
-/* Auto eject group */
-#define SONY_SPIN_DOWN_COMPLETE_ATTN    0x27
-#define SONY_EJECT_COMPLETE_ATTN        0x28
-#define SONY_EJECT_MECH_ERR_ATTN        0x29
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
deleted file mode 100644 (file)
index 2f8fe3b..0000000
+++ /dev/null
@@ -1,1594 +0,0 @@
-/* cm206.c. A linux-driver for the cm206 cdrom player with cm260 adapter card.
-   Copyright (c) 1995--1997 David A. van Leeuwen.
-   $Id: cm206.c,v 1.5 1997/12/26 11:02:51 david Exp $
-   
-     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.
-
-History:
- Started 25 jan 1994. Waiting for documentation...
- 22 feb 1995: 0.1a first reasonably safe polling driver.
-             Two major bugs, one in read_sector and one in 
-             do_cm206_request, happened to cancel!
- 25 feb 1995: 0.2a first reasonable interrupt driven version of above.
-              uart writes are still done in polling mode. 
- 25 feb 1995: 0.21a writes also in interrupt mode, still some
-             small bugs to be found... Larger buffer. 
-  2 mrt 1995: 0.22 Bug found (cd-> nowhere, interrupt was called in
-              initialization), read_ahead of 16. Timeouts implemented.
-             unclear if they do something...
-  7 mrt 1995: 0.23 Start of background read-ahead.
- 18 mrt 1995: 0.24 Working background read-ahead. (still problems)
- 26 mrt 1995: 0.25 Multi-session ioctl added (kernel v1.2).
-              Statistics implemented, though separate stats206.h.
-             Accessible through ioctl 0x1000 (just a number).
-             Hard to choose between v1.2 development and 1.1.75.
-             Bottom-half doesn't work with 1.2...
-             0.25a: fixed... typo. Still problems...
-  1 apr 1995: 0.26 Module support added. Most bugs found. Use kernel 1.2.n.
-  5 apr 1995: 0.27 Auto-probe for the adapter card base address.
-              Auto-probe for the adaptor card irq line.
-  7 apr 1995: 0.28 Added lilo setup support for base address and irq.
-              Use major number 32 (not in this source), officially
-             assigned to this driver.
-  9 apr 1995: 0.29 Added very limited audio support. Toc_header, stop, pause,
-              resume, eject. Play_track ignores track info, because we can't 
-             read a table-of-contents entry. Toc_entry is implemented
-             as a `placebo' function: always returns start of disc. 
-  3 may 1995: 0.30 Audio support completed. The get_toc_entry function
-              is implemented as a binary search. 
- 15 may 1995: 0.31 More work on audio stuff. Workman is not easy to 
-              satisfy; changed binary search into linear search.
-             Auto-probe for base address somewhat relaxed.
-  1 jun 1995: 0.32 Removed probe_irq_on/off for module version.
- 10 jun 1995: 0.33 Workman still behaves funny, but you should be
-              able to eject and substitute another disc.
-
- An adaptation of 0.33 is included in linux-1.3.7 by Eberhard Moenkeberg
-
- 18 jul 1995: 0.34 Patch by Heiko Eissfeldt included, mainly considering 
-              verify_area's in the ioctls. Some bugs introduced by 
-             EM considering the base port and irq fixed. 
-
- 18 dec 1995: 0.35 Add some code for error checking... no luck...
-
- We jump to reach our goal: version 1.0 in the next stable linux kernel.
-
- 19 mar 1996: 0.95 Different implementation of CDROM_GET_UPC, on
-             request of Thomas Quinot. 
- 25 mar 1996: 0.96 Interpretation of opening with O_WRONLY or O_RDWR:
-             open only for ioctl operation, e.g., for operation of
-             tray etc.
- 4 apr 1996:  0.97 First implementation of layer between VFS and cdrom
-              driver, a generic interface. Much of the functionality
-             of cm206_open() and cm206_ioctl() is transferred to a
-             new file cdrom.c and its header ucdrom.h. 
-
-             Upgrade to Linux kernel 1.3.78. 
-
- 11 apr 1996  0.98 Upgrade to Linux kernel 1.3.85
-              More code moved to cdrom.c
-             0.99 Some more small changes to decrease number
-             of oopses at module load; 
- 27 jul 1996  0.100 Many hours of debugging, kernel change from 1.2.13
-             to 2.0.7 seems to have introduced some weird behavior
-             in (interruptible_)sleep_on(&cd->data): the process
-             seems to be woken without any explicit wake_up in my own
-             code. Patch to try 100x in case such untriggered wake_up's 
-             occur. 
-
- 28 jul 1996  0.101 Rewriting of the code that receives the command echo,
-             using a fifo to store echoed bytes. 
-
-             Branch from 0.99:
-             0.99.1.0 Update to kernel release 2.0.10 dev_t -> kdev_t
-             (emoenke) various typos found by others.  extra
-             module-load oops protection.
-             0.99.1.1 Initialization constant cdrom_dops.speed
-             changed from float (2.0) to int (2); Cli()-sti() pair
-             around cm260_reset() in module initialization code.
-             0.99.1.2 Changes literally as proposed by Scott Snyder
-             <snyder@d0sgif.fnal.gov> for the 2.1 kernel line, which
-             have to do mainly with the poor minor support i had. The
-             major new concept is to change a cdrom driver's
-             operations struct from the capabilities struct. This
-             reflects the fact that there is one major for a driver,
-             whilst there can be many minors whith completely
-             different capabilities.
-
-             0.99.1.3 More changes for operations/info separation.
-
-             0.99.1.4 Added speed selection (someone had to do this
-             first).
-
-  23 jan 1997 0.99.1.5 MODULE_PARMS call added.
-
-  23 jan 1997 0.100.1.2--0.100.1.5 following similar lines as 
-             0.99.1.1--0.99.1.5. I get too many complaints about the
-             drive making read errors. What't wrong with the 2.0+
-             kernel line? Why get i (and othe cm206 owners) weird
-             results? Why were things good in the good old 1.1--1.2 
-             era? Why don't i throw away the drive?
-
- 2 feb 1997   0.102 Added `volatile' to values in cm206_struct. Seems to 
-             reduce many of the problems. Rewrote polling routines
-             to use fixed delays between polls. 
-             0.103 Changed printk behavior. 
-             0.104 Added a 0.100 -> 0.100.1.1 change
-
-11 feb 1997   0.105 Allow auto_probe during module load, disable
-              with module option "auto_probe=0". Moved some debugging
-             statements to lower priority. Implemented select_speed()
-             function. 
-
-13 feb 1997   1.0 Final version for 2.0 kernel line. 
-
-             All following changes will be for the 2.1 kernel line. 
-
-15 feb 1997   1.1 Keep up with kernel 2.1.26, merge in changes from 
-              cdrom.c 0.100.1.1--1.0. Add some more MODULE_PARMS. 
-
-14 sep 1997   1.2 Upgrade to Linux 2.1.55.  Added blksize_size[], patch
-              sent by James Bottomley <James.Bottomley@columbiasc.ncr.com>.
-
-21 dec 1997   1.4 Upgrade to Linux 2.1.72.  
-
-24 jan 1998   Removed the cm206_disc_status() function, as it was now dead
-              code.  The Uniform CDROM driver now provides this functionality.
-             
-9 Nov. 1999   Make kernel-parameter implementation work with 2.3.x 
-             Removed init_module & cleanup_module in favor of 
-             module_init & module_exit.
-             Torben Mathiasen <tmm@image.dk>
- * 
- * Parts of the code are based upon lmscd.c written by Kai Petzke,
- * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin
- * Harriss, but any off-the-shelf dynamic programming algorithm won't
- * be able to find them.
- *
- * The cm206 drive interface and the cm260 adapter card seem to be 
- * sufficiently different from their cm205/cm250 counterparts
- * in order to write a complete new driver.
- * 
- * I call all routines connected to the Linux kernel something
- * with `cm206' in it, as this stuff is too series-dependent. 
- * 
- * Currently, my limited knowledge is based on:
- * - The Linux Kernel Hacker's guide, v. 0.5, by Michael K. Johnson
- * - Linux Kernel Programmierung, by Michael Beck and others
- * - Philips/LMS cm206 and cm226 product specification
- * - Philips/LMS cm260 product specification
- *
- * David van Leeuwen, david@tm.tno.nl.  */
-#define REVISION "$Revision: 1.5 $"
-
-#include <linux/module.h>
-
-#include <linux/errno.h>       /* These include what we really need */
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/cdrom.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-/* #include <linux/ucdrom.h> */
-
-#include <asm/io.h>
-
-#define MAJOR_NR CM206_CDROM_MAJOR
-
-#include <linux/blkdev.h>
-
-#undef DEBUG
-#define STATISTICS             /* record times and frequencies of events */
-#define AUTO_PROBE_MODULE
-#define USE_INSW
-
-#include "cm206.h"
-
-/* This variable defines whether or not to probe for adapter base port 
-   address and interrupt request. It can be overridden by the boot 
-   parameter `auto'.
-*/
-static int auto_probe = 1;     /* Yes, why not? */
-
-static int cm206_base = CM206_BASE;
-static int cm206_irq = CM206_IRQ;
-#ifdef MODULE
-static int cm206[2] = { 0, 0 };        /* for compatible `insmod' parameter passing */
-module_param_array(cm206, int, NULL, 0);       /* base,irq or irq,base */
-#endif
-
-module_param(cm206_base, int, 0);      /* base */
-module_param(cm206_irq, int, 0);       /* irq */
-module_param(auto_probe, bool, 0);     /* auto probe base and irq */
-MODULE_LICENSE("GPL");
-
-#define POLLOOP 100            /* milliseconds */
-#define READ_AHEAD 1           /* defines private buffer, waste! */
-#define BACK_AHEAD 1           /* defines adapter-read ahead */
-#define DATA_TIMEOUT (3*HZ)    /* measured in jiffies (10 ms) */
-#define UART_TIMEOUT (5*HZ/100)
-#define DSB_TIMEOUT (7*HZ)     /* time for the slowest command to finish */
-#define UR_SIZE 4              /* uart receive buffer fifo size */
-
-#define LINUX_BLOCK_SIZE 512   /* WHERE is this defined? */
-#define RAW_SECTOR_SIZE 2352   /* ok, is also defined in cdrom.h */
-#define ISO_SECTOR_SIZE 2048
-#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE)  /* 4 */
-#define CD_SYNC_HEAD 16                /* CD_SYNC + CD_HEAD */
-
-#ifdef STATISTICS              /* keep track of errors in counters */
-#define stats(i) { ++cd->stats[st_ ## i]; \
-                    cd->last_stat[st_ ## i] = cd->stat_counter++; \
-                }
-#else
-#define stats(i) (void) 0;
-#endif
-
-#define Debug(a) {printk (KERN_DEBUG); printk a;}
-#ifdef DEBUG
-#define debug(a) Debug(a)
-#else
-#define debug(a) (void) 0;
-#endif
-
-typedef unsigned char uch;     /* 8-bits */
-typedef unsigned short ush;    /* 16-bits */
-
-struct toc_struct {            /* private copy of Table of Contents */
-       uch track, fsm[3], q0;
-};
-
-struct cm206_struct {
-       volatile ush intr_ds;   /* data status read on last interrupt */
-       volatile ush intr_ls;   /* uart line status read on last interrupt */
-       volatile uch ur[UR_SIZE];       /* uart receive buffer fifo */
-       volatile uch ur_w, ur_r;        /* write/read buffer index&nb