cdrom.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,340 行 · 第 1/5 页
C
2,340 行
/* 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 lose the index part, however. -- Small modifications to accommodate 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 3.20 Dec 17, 2003 - Jens Axboe <axboe@suse.de> -- Various fixes and lots of cleanups not listed :-) -- Locking fixes -- Mt Rainier support -- DVD-RAM write open fixes-------------------------------------------------------------------------*/#define REVISION "Revision: 3.20"#define VERSION "Id: cdrom.c 3.20 2003/12/17"/* 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/buffer_head.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/blkpg.h>#include <linux/init.h>#include <linux/fcntl.h>#include <linux/blkdev.h>#include <linux/times.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;/* automatically restart mrw format */static int mrw_format_restart = 1;MODULE_PARM(debug, "i");MODULE_PARM(autoclose, "i");MODULE_PARM(autoeject, "i");MODULE_PARM(lockdoor, "i");MODULE_PARM(check_media_type, "i");MODULE_PARM(mrw_format_restart, "i");static spinlock_t cdrom_lock = SPIN_LOCK_UNLOCKED;static const char *mrw_format_status[] = { "not mrw", "bgformat inactive", "bgformat active", "mrw complete",};static const char *mrw_address_space[] = { "DMA", "GAA" };#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 __user *) (arg), sizeof (in))) \ return -EFAULT;#define IOCTL_OUT(arg, type, out) \ if (copy_to_user((type __user *) (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(struct cdrom_device_info *, long *);static int cdrom_get_next_writable(struct cdrom_device_info *, long *);static void cdrom_count_tracks(struct cdrom_device_info *, tracktype*);static int cdrom_mrw_exit(struct cdrom_device_info *cdi);static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di);#ifdef CONFIG_SYSCTLstatic void cdrom_sysctl_register(void);#endif /* CONFIG_SYSCTL */ static struct cdrom_device_info *topCdromPtr;static int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, struct packet_command *cgc){ if (cgc->sense) { cgc->sense->sense_key = 0x05; cgc->sense->asc = 0x20; cgc->sense->ascq = 0x00; } cgc->stat = -EIO; return -EIO;}/* 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; struct cdrom_device_ops *cdo = cdi->ops; int *change_capability = (int *)&cdo->capability; /* hack */ cdinfo(CD_OPEN, "entering register_cdrom\n"); 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 (CDROM_CAN(CDC_MRW_W)) cdi->exit = cdrom_mrw_exit; if (cdi->disk) cdi->cdda_method = CDDA_BPC_FULL; else cdi->cdda_method = CDDA_OLD; if (!cdo->generic_packet) cdo->generic_packet = cdrom_dummy_generic_packet; cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); spin_lock(&cdrom_lock); cdi->next = topCdromPtr; topCdromPtr = cdi; spin_unlock(&cdrom_lock); return 0;}#undef ENSUREint unregister_cdrom(struct cdrom_device_info *unreg){ struct cdrom_device_info *cdi, *prev; cdinfo(CD_OPEN, "entering unregister_cdrom\n"); prev = NULL; spin_lock(&cdrom_lock); cdi = topCdromPtr; while (cdi && cdi != unreg) { prev = cdi; cdi = cdi->next; } if (cdi == NULL) { spin_unlock(&cdrom_lock); return -2; } if (prev) prev->next = cdi->next; else topCdromPtr = cdi->next; spin_unlock(&cdrom_lock); if (cdi->exit) cdi->exit(cdi); cdi->ops->n_minors--; cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name); return 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?