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

📄 cdrom.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 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/malloc.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 cdrom_open(struct inode *ip, struct file *fp);static int cdrom_release(struct inode *ip, struct file *fp);static int cdrom_ioctl(struct inode *ip, struct file *fp,				unsigned int cmd, unsigned long arg);static int cdrom_media_changed(kdev_t dev);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_SYSCTLstatic void cdrom_sysctl_register(void);#endif /* CONFIG_SYSCTL */ static struct cdrom_device_info *topCdromPtr;static devfs_handle_t devfs_handle;struct block_device_operations cdrom_fops ={	open:			cdrom_open,	release:		cdrom_release,	ioctl:			cdrom_ioctl,	check_media_change:	cdrom_media_changed,};/* 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 */	char vname[16];	static unsigned int cdrom_counter;	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);	sprintf (vname, "cdrom%u", cdrom_counter++);	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) {			strncpy (rname + pos, "../", 3);			devfs_mk_symlink (devfs_handle, vname,					  DEVFS_FL_DEFAULT,					  rname + pos, &slave, NULL);			devfs_auto_unregister (cdi->de, slave);		}	}	else {		cdi->de =		    devfs_register (devfs_handle, vname, DEVFS_FL_DEFAULT,				    MAJOR (cdi->dev), MINOR (cdi->dev),				    S_IFBLK | S_IRUGO | S_IWUGO,				    &cdrom_fops, NULL);	}	cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);	cdi->next = topCdromPtr; 		topCdromPtr = cdi;	return 0;}#undef ENSUREint unregister_cdrom(struct cdrom_device_info *unreg){	struct cdrom_device_info *cdi, *prev;	int major = MAJOR(unreg->dev);

⌨️ 快捷键说明

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