📄 cdrom.c
字号:
/* linux/drivers/cdrom/cdrom.c.
Copyright (c) 1996, 1997 David A. van Leeuwen.
Copyright (c) 1997, 1998 Erik Andersen <andersee@debian.org>
Copyright (c) 1998, 1999 Jens Axboe <axboe@image.dk>
May be copied or modified under the terms of the GNU General Public
License. See linux/COPYING for more information.
Uniform CD-ROM driver for Linux.
See Documentation/cdrom/cdrom-standard.tex for usage information.
The routines in the file provide a uniform interface between the
software that uses CD-ROMs and the various low-level drivers that
actually talk to the hardware. Suggestions are welcome.
Patches that work are more welcome though. ;-)
To Do List:
----------------------------------
-- Modify sysctl/proc interface. I plan on having one directory per
drive, with entries for outputing general drive information, and sysctl
based tunable parameters such as whether the tray should auto-close for
that drive. Suggestions (or patches) for this welcome!
Revision History
----------------------------------
1.00 Date Unknown -- David van Leeuwen <david@tm.tno.nl>
-- Initial version by David A. van Leeuwen. I don't have a detailed
changelog for the 1.x series, David?
2.00 Dec 2, 1997 -- Erik Andersen <andersee@debian.org>
-- New maintainer! As David A. van Leeuwen has been too busy to activly
maintain and improve this driver, I am now carrying on the torch. If
you have a problem with this driver, please feel free to contact me.
-- Added (rudimentary) sysctl interface. I realize this is really weak
right now, and is _very_ badly implemented. It will be improved...
-- Modified CDROM_DISC_STATUS so that it is now incorporated into
the Uniform CD-ROM driver via the cdrom_count_tracks function.
The cdrom_count_tracks function helps resolve some of the false
assumptions of the CDROM_DISC_STATUS ioctl, and is also used to check
for the correct media type when mounting or playing audio from a CD.
-- Remove the calls to verify_area and only use the copy_from_user and
copy_to_user stuff, since these calls now provide their own memory
checking with the 2.1.x kernels.
-- Major update to return codes so that errors from low-level drivers
are passed on through (thanks to Gerd Knorr for pointing out this
problem).
-- Made it so if a function isn't implemented in a low-level driver,
ENOSYS is now returned instead of EINVAL.
-- Simplified some complex logic so that the source code is easier to read.
-- Other stuff I probably forgot to mention (lots of changes).
2.01 to 2.11 Dec 1997-Jan 1998
-- TO-DO! Write changelogs for 2.01 to 2.12.
2.12 Jan 24, 1998 -- Erik Andersen <andersee@debian.org>
-- Fixed a bug in the IOCTL_IN and IOCTL_OUT macros. It turns out that
copy_*_user does not return EFAULT on error, but instead returns the number
of bytes not copied. I was returning whatever non-zero stuff came back from
the copy_*_user functions directly, which would result in strange errors.
2.13 July 17, 1998 -- Erik Andersen <andersee@debian.org>
-- Fixed a bug in CDROM_SELECT_SPEED where you couldn't lower the speed
of the drive. Thanks to Tobias Ringstr|m <tori@prosolvia.se> for pointing
this out and providing a simple fix.
-- Fixed the procfs-unload-module bug with the fill_inode procfs callback.
thanks to Andrea Arcangeli
-- Fixed it so that the /proc entry now also shows up when cdrom is
compiled into the kernel. Before it only worked when loaded as a module.
2.14 August 17, 1998 -- Erik Andersen <andersee@debian.org>
-- Fixed a bug in cdrom_media_changed and handling of reporting that
the media had changed for devices that _don't_ implement media_changed.
Thanks to Grant R. Guenther <grant@torque.net> for spotting this bug.
-- Made a few things more pedanticly correct.
2.50 Oct 19, 1998 - Jens Axboe <axboe@image.dk>
-- New maintainers! Erik was too busy to continue the work on the driver,
so now Chris Zwilling <chris@cloudnet.com> and Jens Axboe <axboe@image.dk>
will do their best to follow in his footsteps
2.51 Dec 20, 1998 - Jens Axboe <axboe@image.dk>
-- Check if drive is capable of doing what we ask before blindly changing
cdi->options in various ioctl.
-- Added version to proc entry.
2.52 Jan 16, 1999 - Jens Axboe <axboe@image.dk>
-- Fixed an error in open_for_data where we would sometimes not return
the correct error value. Thanks Huba Gaspar <huba@softcell.hu>.
-- Fixed module usage count - usage was based on /proc/sys/dev
instead of /proc/sys/dev/cdrom. This could lead to an oops when other
modules had entries in dev. Feb 02 - real bug was in sysctl.c where
dev would be removed even though it was used. cdrom.c just illuminated
that bug.
2.53 Feb 22, 1999 - Jens Axboe <axboe@image.dk>
-- Fixup of several ioctl calls, in particular CDROM_SET_OPTIONS has
been "rewritten" because capabilities and options aren't in sync. They
should be...
-- Added CDROM_LOCKDOOR ioctl. Locks the door and keeps it that way.
-- Added CDROM_RESET ioctl.
-- Added CDROM_DEBUG ioctl. Enable debug messages on-the-fly.
-- Added CDROM_GET_CAPABILITY ioctl. This relieves userspace programs
from parsing /proc/sys/dev/cdrom/info.
2.54 Mar 15, 1999 - Jens Axboe <axboe@image.dk>
-- Check capability mask from low level driver when counting tracks as
per suggestion from Corey J. Scotts <cstotts@blue.weeg.uiowa.edu>.
2.55 Apr 25, 1999 - Jens Axboe <axboe@image.dk>
-- autoclose was mistakenly checked against CDC_OPEN_TRAY instead of
CDC_CLOSE_TRAY.
-- proc info didn't mask against capabilities mask.
3.00 Aug 5, 1999 - Jens Axboe <axboe@image.dk>
-- Unified audio ioctl handling across CD-ROM drivers. A lot of the
code was duplicated before. Drives that support the generic packet
interface are now being fed packets from here instead.
-- First attempt at adding support for MMC2 commands - for DVD and
CD-R(W) drives. Only the DVD parts are in now - the interface used is
the same as for the audio ioctls.
-- ioctl cleanups. if a drive couldn't play audio, it didn't get
a change to perform device specific ioctls as well.
-- Defined CDROM_CAN(CDC_XXX) for checking the capabilities.
-- Put in sysctl files for autoclose, autoeject, check_media, debug,
and lock.
-- /proc/sys/dev/cdrom/info has been updated to also contain info about
CD-Rx and DVD capabilities.
-- Now default to checking media type.
-- CDROM_SEND_PACKET ioctl added. The infrastructure was in place for
doing this anyway, with the generic_packet addition.
3.01 Aug 6, 1999 - Jens Axboe <axboe@image.dk>
-- Fix up the sysctl handling so that the option flags get set
correctly.
-- Fix up ioctl handling so the device specific ones actually get
called :).
3.02 Aug 8, 1999 - Jens Axboe <axboe@image.dk>
-- Fixed volume control on SCSI drives (or others with longer audio
page).
-- Fixed a couple of DVD minors. Thanks to Andrew T. Veliath
<andrewtv@usa.net> for telling me and for having defined the various
DVD structures and ioctls in the first place! He designed the original
DVD patches for ide-cd and while I rearranged and unified them, the
interface is still the same.
3.03 Sep 1, 1999 - Jens Axboe <axboe@image.dk>
-- Moved the rest of the audio ioctls from the CD-ROM drivers here. Only
CDROMREADTOCENTRY and CDROMREADTOCHDR are left.
-- Moved the CDROMREADxxx ioctls in here.
-- Defined the cdrom_get_last_written and cdrom_get_next_block as ioctls
and exported functions.
-- Erik Andersen <andersen@xmission.com> modified all SCMD_ commands
to now read GPCMD_ for the new generic packet interface. All low level
drivers are updated as well.
-- Various other cleanups.
3.04 Sep 12, 1999 - Jens Axboe <axboe@image.dk>
-- Fixed a couple of possible memory leaks (if an operation failed and
we didn't free the buffer before returning the error).
-- Integrated Uniform CD Changer handling from Richard Sharman
<rsharman@pobox.com>.
-- Defined CD_DVD and CD_CHANGER log levels.
-- Fixed the CDROMREADxxx ioctls.
-- CDROMPLAYTRKIND uses the GPCMD_PLAY_AUDIO_MSF command - too few
drives supported it. We loose the index part, however.
-- Small modifications to accomodate opens of /dev/hdc1, required
for ide-cd to handle multisession discs.
-- Export cdrom_mode_sense and cdrom_mode_select.
-- init_cdrom_command() for setting up a cgc command.
3.05 Oct 24, 1999 - Jens Axboe <axboe@image.dk>
-- Changed the interface for CDROM_SEND_PACKET. Before it was virtually
impossible to send the drive data in a sensible way.
-- Lowered stack usage in mmc_ioctl(), dvd_read_disckey(), and
dvd_read_manufact.
-- Added setup of write mode for packet writing.
-- Fixed CDDA ripping with cdda2wav - accept much larger requests of
number of frames and split the reads in blocks of 8.
3.06 Dec 13, 1999 - Jens Axboe <axboe@image.dk>
-- Added support for changing the region of DVD drives.
-- Added sense data to generic command.
3.07 Feb 2, 2000 - Jens Axboe <axboe@suse.de>
-- Do same "read header length" trick in cdrom_get_disc_info() as
we do in cdrom_get_track_info() -- some drive don't obey specs and
fail if they can't supply the full Mt Fuji size table.
-- Deleted stuff related to setting up write modes. It has a different
home now.
-- Clear header length in mode_select unconditionally.
-- Removed the register_disk() that was added, not needed here.
3.08 May 1, 2000 - Jens Axboe <axboe@suse.de>
-- Fix direction flag in setup_send_key and setup_report_key. This
gave some SCSI adapters problems.
-- Always return -EROFS for write opens
-- Convert to module_init/module_exit style init and remove some
of the #ifdef MODULE stuff
-- Fix several dvd errors - DVD_LU_SEND_ASF should pass agid,
DVD_HOST_SEND_RPC_STATE did not set buffer size in cdb, and
dvd_do_auth passed uninitialized data to drive because init_cdrom_command
did not clear a 0 sized buffer.
3.09 May 12, 2000 - Jens Axboe <axboe@suse.de>
-- Fix Video-CD on SCSI drives that don't support READ_CD command. In
that case switch block size and issue plain READ_10 again, then switch
back.
3.10 Jun 10, 2000 - Jens Axboe <axboe@suse.de>
-- Fix volume control on CD's - old SCSI-II drives now use their own
code, as doing MODE6 stuff in here is really not my intention.
-- Use READ_DISC_INFO for more reliable end-of-disc.
3.11 Jun 12, 2000 - Jens Axboe <axboe@suse.de>
-- Fix bug in getting rpc phase 2 region info.
-- Reinstate "correct" CDROMPLAYTRKIND
3.12 Oct 18, 2000 - Jens Axboe <axboe@suse.de>
-- Use quiet bit on packet commands not known to work
-------------------------------------------------------------------------*/
#define REVISION "Revision: 3.12"
#define VERSION "Id: cdrom.c 3.12 2000/10/18"
/* I use an error-log mask to give fine grain control over the type of
messages dumped to the system logs. The available masks include: */
#define CD_NOTHING 0x0
#define CD_WARNING 0x1
#define CD_REG_UNREG 0x2
#define CD_DO_IOCTL 0x4
#define CD_OPEN 0x8
#define CD_CLOSE 0x10
#define CD_COUNT_TRACKS 0x20
#define CD_CHANGER 0x40
#define CD_DVD 0x80
/* Define this to remove _all_ the debugging messages */
/* #define ERRLOGMASK CD_NOTHING */
#define ERRLOGMASK (CD_WARNING)
/* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */
/* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/major.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/cdrom.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <asm/fcntl.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
/* used to tell the module to turn on full debugging messages */
static int debug;
/* used to keep tray locked at all times */
static int keeplocked;
/* default compatibility mode */
static int autoclose=1;
static int autoeject;
static int lockdoor = 1;
/* will we ever get to use this... sigh. */
static int check_media_type;
MODULE_PARM(debug, "i");
MODULE_PARM(autoclose, "i");
MODULE_PARM(autoeject, "i");
MODULE_PARM(lockdoor, "i");
MODULE_PARM(check_media_type, "i");
#if (ERRLOGMASK!=CD_NOTHING)
#define cdinfo(type, fmt, args...) \
if ((ERRLOGMASK & type) || debug==1 ) \
printk(KERN_INFO "cdrom: " fmt, ## args)
#else
#define cdinfo(type, fmt, args...)
#endif
/* These are used to simplify getting data in from and back to user land */
#define IOCTL_IN(arg, type, in) \
if (copy_from_user(&(in), (type *) (arg), sizeof (in))) \
return -EFAULT;
#define IOCTL_OUT(arg, type, out) \
if (copy_to_user((type *) (arg), &(out), sizeof (out))) \
return -EFAULT;
/* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
a lot of places. This macro makes the code more clear. */
#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & (type))
/* used in the audio ioctls */
#define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
/* Not-exported routines. */
static int open_for_data(struct cdrom_device_info * cdi);
static int check_for_audio_disc(struct cdrom_device_info * cdi,
struct cdrom_device_ops * cdo);
static void sanitize_format(union cdrom_addr *addr,
u_char * curr, u_char requested);
static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
unsigned long arg);
int cdrom_get_last_written(kdev_t dev, long *last_written);
int cdrom_get_next_writable(kdev_t dev, long *next_writable);
#ifdef CONFIG_SYSCTL
static void cdrom_sysctl_register(void);
#endif /* CONFIG_SYSCTL */
static struct cdrom_device_info *topCdromPtr;
static devfs_handle_t devfs_handle;
static struct unique_numspace cdrom_numspace = UNIQUE_NUMBERSPACE_INITIALISER;
/* This macro makes sure we don't have to check on cdrom_device_ops
* existence in the run-time routines below. Change_capability is a
* hack to have the capability flags defined const, while we can still
* change it here without gcc complaining at every line.
*/
#define ENSURE(call, bits) if (cdo->call == NULL) *change_capability &= ~(bits)
int register_cdrom(struct cdrom_device_info *cdi)
{
static char banner_printed;
int major = MAJOR(cdi->dev);
struct cdrom_device_ops *cdo = cdi->ops;
int *change_capability = (int *)&cdo->capability; /* hack */
cdinfo(CD_OPEN, "entering register_cdrom\n");
if (major < 0 || major >= MAX_BLKDEV)
return -1;
if (cdo->open == NULL || cdo->release == NULL)
return -2;
if ( !banner_printed ) {
printk(KERN_INFO "Uniform CD-ROM driver " REVISION "\n");
banner_printed = 1;
#ifdef CONFIG_SYSCTL
cdrom_sysctl_register();
#endif /* CONFIG_SYSCTL */
}
ENSURE(drive_status, CDC_DRIVE_STATUS );
ENSURE(media_changed, CDC_MEDIA_CHANGED);
ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
ENSURE(lock_door, CDC_LOCK);
ENSURE(select_speed, CDC_SELECT_SPEED);
ENSURE(get_last_session, CDC_MULTI_SESSION);
ENSURE(get_mcn, CDC_MCN);
ENSURE(reset, CDC_RESET);
ENSURE(audio_ioctl, CDC_PLAY_AUDIO);
ENSURE(dev_ioctl, CDC_IOCTLS);
ENSURE(generic_packet, CDC_GENERIC_PACKET);
cdi->mc_flags = 0;
cdo->n_minors = 0;
cdi->options = CDO_USE_FFLAGS;
if (autoclose==1 && CDROM_CAN(CDC_CLOSE_TRAY))
cdi->options |= (int) CDO_AUTO_CLOSE;
if (autoeject==1 && CDROM_CAN(CDC_OPEN_TRAY))
cdi->options |= (int) CDO_AUTO_EJECT;
if (lockdoor==1)
cdi->options |= (int) CDO_LOCK;
if (check_media_type==1)
cdi->options |= (int) CDO_CHECK_TYPE;
if (!devfs_handle)
devfs_handle = devfs_mk_dir (NULL, "cdroms", NULL);
cdi->number = devfs_alloc_unique_number (&cdrom_numspace);
if (cdi->de) {
int pos;
devfs_handle_t slave;
char rname[64];
pos = devfs_generate_path (cdi->de, rname + 3,
sizeof rname - 3);
if (pos >= 0) {
char vname[16];
sprintf (vname, "cdrom%d", cdi->number);
strncpy (rname + pos, "../", 3);
devfs_mk_symlink (devfs_handle, vname,
DEVFS_FL_DEFAULT,
rname + pos, &slave, NULL);
devfs_auto_unregister (cdi->de, slave);
}
}
cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
cdi->next = topCdromPtr;
topCdromPtr = cdi;
return 0;
}
#undef ENSURE
int unregister_cdrom(struct cdrom_device_info *unreg)
{
struct cdrom_device_info *cdi, *prev;
int major = MAJOR(unreg->dev);
cdinfo(CD_OPEN, "entering unregister_cdrom\n");
if (major < 0 || major >= MAX_BLKDEV)
return -1;
prev = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -