⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbpcd.c

📁 cdrom device drive for linux.
💻 C
📖 第 1 页 / 共 5 页
字号:


/*
 *  sbpcd.c   CD-ROM device driver for the whole family of traditional,
 *            non-ATAPI IDE-style Matsushita/Panasonic CR-5xx drives.
 *            Works with SoundBlaster compatible cards and with "no-sound"
 *            interface cards like Lasermate, Panasonic CI-101P, Teac, ...
 *            Also for the Longshine LCS-7260 drive.
 *            Also for the IBM "External ISA CD-Rom" drive.
 *            Also for the CreativeLabs CD200 drive.
 *            Also for the TEAC CD-55A drive.
 *            Also for the ECS-AT "Vertos 100" drive.
 *            Not for Sanyo drives (but for the H94A, sjcd is there...).
 *            Not for any other Funai drives than the CD200 types (sometimes
 *             labelled E2550UA or MK4015 or 2800F).
 */

#define VERSION "v4.63 Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000"

/*   Copyright (C) 1993, 1994, 1995  Eberhard Moenkeberg <emoenke@gwdg.de>
 *
 *   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.
 *
 *   You should have received a copy of the GNU General Public License
 *   (for example /usr/src/linux/COPYING); if not, write to the Free
 *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *   If you change this software, you should mail a .diff file with some
 *   description lines to emoenke@gwdg.de. I want to know about it.
 *
 *   If you are the editor of a Linux CD, you should enable sbpcd.c within
 *   your boot floppy kernel and send me one of your CDs for free.
 *
 *   If you would like to port the driver to an other operating system (f.e.
 *   FreeBSD or NetBSD) or use it as an information source, you shall not be
 *   restricted by the GPL under the following conditions:
 *     a) the source code of your work is freely available
 *     b) my part of the work gets mentioned at all places where your 
 *        authorship gets mentioned
 *     c) I receive a copy of your code together with a full installation
 *        package of your operating system for free.
 *
 *
 *  VERSION HISTORY
 *
 *  0.1  initial release, April/May 93, after mcd.c (Martin Harriss)
 *
 *  0.2  thek "repeat:"-loop in do_sbpcd_request did not check for
 *       end-of-request_queue (resulting in kernel panic).
 *       Flow control seems stable, but throughput is not better.  
 *
 *  0.3  interrupt locking totally eliminated (maybe "inb" and "outb"
 *       are still locking) - 0.2 made keyboard-type-ahead losses.
 *       check_sbpcd_media_change added (to use by isofs/inode.c)
 *       - but it detects almost nothing.
 *
 *  0.4  use MAJOR 25 definitely.
 *       Almost total re-design to support double-speed drives and
 *       "naked" (no sound) interface cards ("LaserMate" interface type).
 *       Flow control should be exact now.
 *       Don't occupy the SbPro IRQ line (not needed either); will
 *       live together with Hannu Savolainen's sndkit now.
 *       Speeded up data transfer to 150 kB/sec, with help from Kai
 *       Makisara, the "provider" of the "mt" tape utility.
 *       Give "SpinUp" command if necessary.
 *       First steps to support up to 4 drives (but currently only one).
 *       Implemented audio capabilities - workman should work, xcdplayer
 *       gives some problems.
 *       This version is still consuming too much CPU time, and
 *       sleeping still has to be worked on.
 *       During "long" implied seeks, it seems possible that a 
 *       ReadStatus command gets ignored. That gives the message
 *       "ResponseStatus timed out" (happens about 6 times here during
 *       a "ls -alR" of the YGGDRASIL LGX-Beta CD). Such a case is
 *       handled without data error, but it should get done better.
 *
 *  0.5  Free CPU during waits (again with help from Kai Makisara).
 *       Made it work together with the LILO/kernel setup standard.
 *       Included auto-probing code, as suggested by YGGDRASIL.
 *       Formal redesign to add DDI debugging.
 *       There are still flaws in IOCTL (workman with double speed drive).
 *
 *  1.0  Added support for all drive IDs (0...3, no longer only 0)
 *       and up to 4 drives on one controller.
 *       Added "#define MANY_SESSION" for "old" multi session CDs.
 *
 *  1.1  Do SpinUp for new drives, too.
 *       Revised for clean compile under "old" kernels (0.99pl9).
 *
 *  1.2  Found the "workman with double-speed drive" bug: use the driver's
 *       audio_state, not what the drive is reporting with ReadSubQ.
 *
 *  1.3  Minor cleanups.
 *       Refinements regarding Workman.
 *
 *  1.4  Read XA disks (PhotoCDs) with "old" drives, too (but only the first
 *       session - no chance to fully access a "multi-session" CD).
 *       This currently still is too slow (50 kB/sec) - but possibly
 *       the old drives won't do it faster.
 *       Implemented "door (un)lock" for new drives (still does not work
 *       as wanted - no lock possible after an unlock).
 *       Added some debugging printout for the UPC/EAN code - but my drives 
 *       return only zeroes. Is there no UPC/EAN code written?
 *
 *  1.5  Laborate with UPC/EAN code (not better yet).
 *       Adapt to kernel 1.1.8 change (have to explicitly include
 *       <linux/string.h> now).
 *
 *  1.6  Trying to read audio frames as data. Impossible with the current
 *       drive firmware levels, as it seems. Awaiting any hint. ;-)
 *       Changed "door unlock": repeat it until success.
 *       Changed CDROMSTOP routine (stop somewhat "softer" so that Workman
 *       won't get confused).
 *       Added a third interface type: Sequoia S-1000, as used with the SPEA
 *       Media FX sound card. This interface (usable for Sony and Mitsumi 
 *       drives, too) needs a special configuration setup and behaves like a 
 *       LaserMate type after that. Still experimental - I do not have such
 *       an interface.
 *       Use the "variable BLOCK_SIZE" feature (2048). But it does only work
 *       if you give the mount option "block=2048".
 *       The media_check routine is currently disabled; now that it gets
 *       called as it should I fear it must get synchronized for not to
 *       disturb the normal driver's activity.
 *
 *  2.0  Version number bumped - two reasons:
 *       - reading audio tracks as data works now with CR-562 and CR-563. We
 *       currently do it by an IOCTL (yet has to get standardized), one frame
 *       at a time; that is pretty slow. But it works.
 *       - we are maintaining now up to 4 interfaces (each up to 4 drives):
 *       did it the easy way - a different MAJOR (25, 26, ...) and a different
 *       copy of the driver (sbpcd.c, sbpcd2.c, sbpcd3.c, sbpcd4.c - only
 *       distinguished by the value of SBPCD_ISSUE and the driver's name),
 *       and a common sbpcd.h file.
 *       Bettered the "ReadCapacity error" problem with old CR-52x drives (the
 *       drives sometimes need a manual "eject/insert" before work): just
 *       reset the drive and do again. Needs lots of resets here and sometimes
 *       that does not cure, so this can't be the solution.
 *
 *  2.1  Found bug with multisession CDs (accessing frame 16).
 *       "read audio" works now with address type CDROM_MSF, too.
 *       Bigger audio frame buffer: allows reading max. 4 frames at time; this
 *       gives a significant speedup, but reading more than one frame at once
 *       gives missing chunks at each single frame boundary.
 *
 *  2.2  Kernel interface cleanups: timers, init, setup, media check.
 *
 *  2.3  Let "door lock" and "eject" live together.
 *       Implemented "close tray" (done automatically during open).
 *
 *  2.4  Use different names for device registering.
 *
 *  2.5  Added "#if EJECT" code (default: enabled) to automatically eject
 *       the tray during last call to "sbpcd_release".
 *       Added "#if JUKEBOX" code (default: disabled) to automatically eject
 *       the tray during call to "sbpcd_open" if no disk is in.
 *       Turn on the CD volume of "compatible" sound cards, too; just define
 *       SOUND_BASE (in sbpcd.h) accordingly (default: disabled).
 *
 *  2.6  Nothing new.  
 *
 *  2.7  Added CDROMEJECT_SW ioctl to set the "EJECT" behavior on the fly:
 *       0 disables, 1 enables auto-ejecting. Useful to keep the tray in
 *       during shutdown.
 *
 *  2.8  Added first support (still BETA, I need feedback or a drive) for
 *       the Longshine LCS-7260 drives. They appear as double-speed drives
 *       using the "old" command scheme, extended by tray control and door
 *       lock functions.
 *       Found (and fixed preliminary) a flaw with some multisession CDs: we
 *       have to re-direct not only the accesses to frame 16 (the isofs
 *       routines drive it up to max. 100), but also those to the continuation
 *       (repetition) frames (as far as they exist - currently set fix as
 *       16..20).
 *       Changed default of the "JUKEBOX" define. If you use this default,
 *       your tray will eject if you try to mount without a disk in. Next
 *       mount command will insert the tray - so, just fill in a disk. ;-)
 *
 *  2.9  Fulfilled the Longshine LCS-7260 support; with great help and
 *       experiments by Serge Robyns.
 *       First attempts to support the TEAC CD-55A drives; but still not
 *       usable yet.
 *       Implemented the CDROMMULTISESSION ioctl; this is an attempt to handle
 *       multi session CDs more "transparent" (redirection handling has to be
 *       done within the isofs routines, and only for the special purpose of
 *       obtaining the "right" volume descriptor; accesses to the raw device
 *       should not get redirected).
 *
 *  3.0  Just a "normal" increment, with some provisions to do it better. ;-)
 *       Introduced "#define READ_AUDIO" to specify the maximum number of 
 *       audio frames to grab with one request. This defines a buffer size
 *       within kernel space; a value of 0 will reserve no such space and
 *       disable the CDROMREADAUDIO ioctl. A value of 75 enables the reading
 *       of a whole second with one command, but will use a buffer of more
 *       than 172 kB.
 *       Started CD200 support. Drive detection should work, but nothing
 *       more.
 *
 *  3.1  Working to support the CD200 and the Teac CD-55A drives.
 *       AT-BUS style device numbering no longer used: use SCSI style now.
 *       So, the first "found" device has MINOR 0, regardless of the
 *       jumpered drive ID. This implies modifications to the /dev/sbpcd*
 *       entries for some people, but will help the DAU (german TLA, english:
 *       "newbie", maybe ;-) to install his "first" system from a CD.
 *
 *  3.2  Still testing with CD200 and CD-55A drives.
 *
 *  3.3  Working with CD200 support.
 *
 *  3.4  Auto-probing stops if an address of 0 is seen (to be entered with
 *       the kernel command line).
 *       Made the driver "loadable". If used as a module, "audio copy" is
 *       disabled, and the internal read ahead data buffer has a reduced size
 *       of 4 kB; so, throughput may be reduced a little bit with slow CPUs.
 *
 *  3.5  Provisions to handle weird photoCDs which have an interrupted
 *       "formatting" immediately after the last frames of some files: simply
 *       never "read ahead" with MultiSession CDs. By this, CPU usage may be
 *       increased with those CDs, and there may be a loss in speed.
 *       Re-structured the messaging system.
 *       The "loadable" version no longer has a limited READ_AUDIO buffer
 *       size.
 *       Removed "MANY_SESSION" handling for "old" multi session CDs.
 *       Added "private" IOCTLs CDROMRESET and CDROMVOLREAD.
 *       Started again to support the TEAC CD-55A drives, now that I found
 *       the money for "my own" drive. ;-)
 *       The TEAC CD-55A support is fairly working now.
 *       I have measured that the drive "delivers" at 600 kB/sec (even with
 *       bigger requests than the drive's 64 kB buffer can satisfy), but
 *       the "real" rate does not exceed 520 kB/sec at the moment. 
 *       Caused by the various changes to build in TEAC support, the timed
 *       loops are de-optimized at the moment (less throughput with CR-52x
 *       drives, and the TEAC will give speed only with SBP_BUFFER_FRAMES 64).
 *
 *  3.6  Fixed TEAC data read problems with SbPro interfaces.
 *       Initial size of the READ_AUDIO buffer is 0. Can get set to any size
 *       during runtime.
 *
 *  3.7  Introduced MAX_DRIVES for some poor interface cards (seen with TEAC
 *       drives) which allow only one drive (ID 0); this avoids repetitive
 *       detection under IDs 1..3. 
 *       Elongated cmd_out_T response waiting; necessary for photo CDs with
 *       a lot of sessions.
 *       Bettered the sbpcd_open() behavior with TEAC drives.
 *
 *  3.8  Elongated max_latency for CR-56x drives.
 *
 *  3.9  Finally fixed the long-known SoundScape/SPEA/Sequoia S-1000 interface
 *       configuration bug.
 *       Now Corey, Heiko, Ken, Leo, Vadim/Eric & Werner are invited to copy
 *       the config_spea() routine into their drivers. ;-)
 *
 *  4.0  No "big step" - normal version increment.
 *       Adapted the benefits from 1.3.33.
 *       Fiddled with CDROMREADAUDIO flaws.
 *       Avoid ReadCapacity command with CD200 drives (the MKE 1.01 version
 *       seems not to support it).
 *       Fulfilled "read audio" for CD200 drives, with help of Pete Heist
 *       (heistp@rpi.edu).
 *
 *  4.1  Use loglevel KERN_INFO with printk().
 *       Added support for "Vertos 100" drive ("ECS-AT") - it is very similar
 *       to the Longshine LCS-7260. Give feedback if you can - I never saw
 *       such a drive, and I have no specs.
 *
 *  4.2  Support for Teac 16-bit interface cards. Can't get auto-detected,
 *       so you have to jumper your card to 0x2C0. Still not 100% - come
 *       in contact if you can give qualified feedback.
 *       Use loglevel KERN_NOTICE with printk(). If you get annoyed by a
 *       flood of unwanted messages and the accompanied delay, try to read
 *       my documentation. Especially the Linux CDROM drivers have to do an
 *       important job for the newcomers, so the "distributed" version has
 *       to fit some special needs. Since generations, the flood of messages
 *       is user-configurable (even at runtime), but to get aware of this, one
 *       needs a special mental quality: the ability to read.
 *       
 *  4.3  CD200F does not like to receive a command while the drive is
 *       reading the ToC; still trying to solve it.
 *       Removed some redundant verify_area calls (yes, Heiko Eissfeldt
 *       is visiting all the Linux CDROM drivers ;-).
 *       
 *  4.4  Adapted one idea from tiensivu@pilot.msu.edu's "stripping-down"
 *       experiments: "KLOGD_PAUSE".
 *       Inhibited "play audio" attempts with data CDs. Provisions for a
 *       "data-safe" handling of "mixed" (data plus audio) Cds.
 *
 *  4.5  Meanwhile Gonzalo Tornaria <tornaria@cmat.edu.uy> (GTL) built a
 *       special end_request routine: we seem to have to take care for not
 *       to have two processes working at the request list. My understanding
 *       was and is that ll_rw_blk should not call do_sbpcd_request as long
 *       as there is still one call active (the first call will care for all
 *       outstanding I/Os, and if a second call happens, that is a bug in
 *       ll_rw_blk.c).
 *       "Check media change" without touching any drive.
 *
 *  4.6  Use a semaphore to synchronize multi-activity; elaborated by Rob
 *       Riggs <rriggs@tesser.com>. At the moment, we simply block "read"
 *       against "ioctl" and vice versa. This could be refined further, but
 *       I guess with almost no performance increase.
 *       Experiments to speed up the CD-55A; again with help of Rob Riggs
 *       (to be true, he gave both, idea & code. ;-)
 *
 *  4.61 Ported to Uniform CD-ROM driver by 
 *       Heiko Eissfeldt <heiko@colossus.escape.de> with additional
 *       changes by Erik Andersen <andersee@debian.org>
 *
 *  4.62 Fix a bug where playing audio left the drive in an unusable state.
 *         Heiko Eissfeldt <heiko@colossus.escape.de>
 *
 *  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>
 *
 *  4.63 Bug fixes for audio annoyances, new legacy CDROM maintainer.
 *		Annoying things fixed:
 *		TOC reread on automated disk changes
 *		TOC reread on manual cd changes
 *		Play IOCTL tries to play CD before it's actually ready... sometimes.
 *		CD_AUDIO_COMPLETED state so workman (and other playes) can repeat play.
 *		Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000
 *
 *  4.64 Fix module parameters - were being completely ignored.
 *	 Can also specify max_drives=N as a setup int to get rid of
 *	 "ghost" drives on crap hardware (aren't they all?)   Paul Gortmaker
 *
 *  TODO
 *     implement "read all subchannel data" (96 bytes per frame)
 *     remove alot of the virtual status bits and deal with hardware status
 *     move the change of cd for audio to a better place
 *     add debug levels to insmod parameters (trivial)
 *
 *     special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
 *     elaborated speed-up experiments (and the fabulous results!), for
 *     the "push" towards load-free wait loops, and for the extensive mail
 *     thread which brought additional hints and bug fixes.
 *
 */

/*
 * Trying to merge requests breaks this driver horribly (as in it goes
 * boom and apparently has done so since 2.3.41).  As it is a legacy 
 * driver for a horribly slow double speed CD on a hideous interface 
 * designed for polled operation, I won't loose any sleep in simply 
 * disallowing merging.				Paul G.  02/2001
 */
#define DONT_MERGE_REQUESTS

#ifndef SBPCD_ISSUE
#define SBPCD_ISSUE 1
#endif /* SBPCD_ISSUE */

#include <linux/module.h>

#include <linux/version.h>
#include <linux/errno.h>
#include <linux/sched.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/devfs_fs_kernel.h>
#include <linux/major.h> 
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/interrupt.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <stdarg.h>
#include <linux/config.h>
#include "sbpcd.h"

#if !(SBPCD_ISSUE-1)
#define MAJOR_NR MATSUSHITA_CDROM_MAJOR
#endif
#if !(SBPCD_ISSUE-2)
#define MAJOR_NR MATSUSHITA_CDROM2_MAJOR /* second driver issue */
#endif
#if !(SBPCD_ISSUE-3)
#define MAJOR_NR MATSUSHITA_CDROM3_MAJOR /* third driver issue */
#endif
#if !(SBPCD_ISSUE-4)
#define MAJOR_NR MATSUSHITA_CDROM4_MAJOR /* fourth driver issue */
#endif

#include <linux/blk.h>

/*==========================================================================*/
/*
 * provisions for more than 1 driver issues
 * currently up to 4 drivers, expandable
 */
#if !(SBPCD_ISSUE-1)
#define DO_SBPCD_REQUEST(a) do_sbpcd_request(a)
#define SBPCD_INIT(a) sbpcd_init(a)
#endif
#if !(SBPCD_ISSUE-2)
#define DO_SBPCD_REQUEST(a) do_sbpcd2_request(a)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -