/* linux/drivers/cdrom/cdrom.c Copyright (c) 1996, 1997 David A. van Leeuwen. Copyright (c) 1997, 1998 Erik Andersen <[email protected]> Copyright (c) 1998, 1999 Jens Axboe <[email protected]> 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.rst 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. ;-) Revision History ---------------------------------- 1.00 Date Unknown -- David van Leeuwen <[email protected]> -- 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 <[email protected]> -- New maintainer! As David A. van Leeuwen has been too busy to actively 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 <[email protected]> -- 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 <[email protected]> -- Fixed a bug in CDROM_SELECT_SPEED where you couldn't lower the speed of the drive. Thanks to Tobias Ringstr|m <[email protected]> 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 <[email protected]> -- 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 <[email protected]> for spotting this bug. -- Made a few things more pedanticly correct. 2.50 Oct 19, 1998 - Jens Axboe <[email protected]> -- New maintainers! Erik was too busy to continue the work on the driver, so now Chris Zwilling <[email protected]> and Jens Axboe <[email protected]> will do their best to follow in his footsteps 2.51 Dec 20, 1998 - Jens Axboe <[email protected]> -- 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 <[email protected]> -- Fixed an error in open_for_data where we would sometimes not return the correct error value. Thanks Huba Gaspar <[email protected]>. -- 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 <[email protected]> -- 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 <[email protected]> -- Check capability mask from low level driver when counting tracks as per suggestion from Corey J. Scotts <[email protected]>. 2.55 Apr 25, 1999 - Jens Axboe <[email protected]> -- 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 <[email protected]> -- 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 <[email protected]> -- 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 <[email protected]> -- Fixed volume control on SCSI drives (or others with longer audio page). -- Fixed a couple of DVD minors. Thanks to Andrew T. Veliath <[email protected]> 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 <[email protected]> -- 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 <[email protected]> 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 <[email protected]> -- 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 <[email protected]>. -- 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 <[email protected]> -- 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 <[email protected]> -- Added support for changing the region of DVD drives. -- Added sense data to generic command. 3.07 Feb 2, 2000 - Jens Axboe <[email protected]> -- 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 <[email protected]> -- 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 <[email protected]> -- 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 <[email protected]> -- 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 <[email protected]> -- Fix bug in getting rpc phase 2 region info. -- Reinstate "correct" CDROMPLAYTRKIND 3.12 Oct 18, 2000 - Jens Axboe <[email protected]> -- Use quiet bit on packet commands not known to work 3.20 Dec 17, 2003 - Jens Axboe <[email protected]> -- Various fixes and lots of cleanups not listed :-) -- Locking fixes -- Mt Rainier support -- DVD-RAM write open fixes Nov 5 2001, Aug 8 2002. Modified by Andy Polyakov <[email protected]> to support MMC-3 compliant DVD+RW units. Modified by Nigel Kukard <[email protected]> - support DVD+RW 2.4.x patch by Andy Polyakov <[email protected]> -------------------------------------------------------------------------*/ #define pr_fmt(fmt) … #define REVISION … #define VERSION … /* 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 … #define CD_WARNING … #define CD_REG_UNREG … #define CD_DO_IOCTL … #define CD_OPEN … #define CD_CLOSE … #define CD_COUNT_TRACKS … #define CD_CHANGER … #define CD_DVD … /* Define this to remove _all_ the debugging messages */ /* #define ERRLOGMASK CD_NOTHING */ #define ERRLOGMASK … /* #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/atomic.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/nospec.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 <linux/uaccess.h> #include <scsi/scsi_common.h> /* used to tell the module to turn on full debugging messages */ static bool debug; /* default compatibility mode */ static bool autoclose= …; static bool autoeject; static bool lockdoor = …; /* will we ever get to use this... sigh. */ static bool check_media_type; /* automatically restart mrw format */ static bool mrw_format_restart = …; module_param(debug, bool, 0); module_param(autoclose, bool, 0); module_param(autoeject, bool, 0); module_param(lockdoor, bool, 0); module_param(check_media_type, bool, 0); module_param(mrw_format_restart, bool, 0); static DEFINE_MUTEX(cdrom_mutex); static const char *mrw_format_status[] = …; static const char *mrw_address_space[] = …; #if (ERRLOGMASK != CD_NOTHING) #define cd_dbg(type, fmt, ...) … #else #define cd_dbg … #endif /* 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) … /* * Another popular OS uses 7 seconds as the hard timeout for default * commands, so it is a good choice for us as well. */ #define CDROM_DEF_TIMEOUT … /* Not-exported routines. */ static void cdrom_sysctl_register(void); static LIST_HEAD(cdrom_list); static void signal_media_change(struct cdrom_device_info *cdi) { … } int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, struct packet_command *cgc) { … } EXPORT_SYMBOL(…); static int cdrom_flush_cache(struct cdrom_device_info *cdi) { … } /* requires CD R/RW */ static int cdrom_get_disc_info(struct cdrom_device_info *cdi, disc_information *di) { … } /* 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 … /* * the first prototypes used 0x2c as the page code for the mrw mode page, * subsequently this was changed to 0x03. probe the one used by this drive */ static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi) { … } static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write) { … } static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont) { … } static int cdrom_mrw_bgformat_susp(struct cdrom_device_info *cdi, int immed) { … } static int cdrom_mrw_exit(struct cdrom_device_info *cdi) { … } static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space) { … } int register_cdrom(struct gendisk *disk, struct cdrom_device_info *cdi) { … } EXPORT_SYMBOL(…); #undef ENSURE void unregister_cdrom(struct cdrom_device_info *cdi) { … } EXPORT_SYMBOL(…); int cdrom_get_media_event(struct cdrom_device_info *cdi, struct media_event_desc *med) { … } EXPORT_SYMBOL(…); static int cdrom_get_random_writable(struct cdrom_device_info *cdi, struct rwrt_feature_desc *rfd) { … } static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi) { … } static int cdrom_is_random_writable(struct cdrom_device_info *cdi, int *write) { … } static int cdrom_media_erasable(struct cdrom_device_info *cdi) { … } /* * FIXME: check RO bit */ static int cdrom_dvdram_open_write(struct cdrom_device_info *cdi) { … } static int cdrom_mrw_open_write(struct cdrom_device_info *cdi) { … } static int mo_open_write(struct cdrom_device_info *cdi) { … } static int cdrom_ram_open_write(struct cdrom_device_info *cdi) { … } static void cdrom_mmc3_profile(struct cdrom_device_info *cdi) { … } static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi) { … } /* * returns 0 for ok to open write, non-0 to disallow */ static int cdrom_open_write(struct cdrom_device_info *cdi) { … } static void cdrom_dvd_rw_close_write(struct cdrom_device_info *cdi) { … } /* badly broken, I know. Is due for a fixup anytime. */ static void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype *tracks) { … } static int open_for_data(struct cdrom_device_info *cdi) { … } /* We use the open-option O_NONBLOCK to indicate that the * purpose of opening is only for subsequent ioctl() calls; no device * integrity checks are performed. * * We hope that all cd-player programs will adopt this convention. It * is in their own interest: device control becomes a lot easier * this way. */ int cdrom_open(struct cdrom_device_info *cdi, blk_mode_t mode) { … } EXPORT_SYMBOL(…); /* This code is similar to that in open_for_data. The routine is called whenever an audio play operation is requested. */ static int check_for_audio_disc(struct cdrom_device_info *cdi, const struct cdrom_device_ops *cdo) { … } void cdrom_release(struct cdrom_device_info *cdi) { … } EXPORT_SYMBOL(…); static int cdrom_read_mech_status(struct cdrom_device_info *cdi, struct cdrom_changer_info *buf) { … } static int cdrom_slot_status(struct cdrom_device_info *cdi, int slot) { … } /* Return the number of slots for an ATAPI/SCSI cdrom, * return 1 if not a changer. */ int cdrom_number_of_slots(struct cdrom_device_info *cdi) { … } EXPORT_SYMBOL(…); /* If SLOT < 0, unload the current slot. Otherwise, try to load SLOT. */ static int cdrom_load_unload(struct cdrom_device_info *cdi, int slot) { … } static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot) { … } /* * As cdrom implements an extra ioctl consumer for media changed * event, it needs to buffer ->check_events() output, such that event * is not lost for both the usual VFS and ioctl paths. * cdi->{vfs|ioctl}_events are used to buffer pending events for each * path. * * XXX: Locking is non-existent. cdi->ops->check_events() can be * called in parallel and buffering fields are accessed without any * exclusion. The original media_changed code had the same problem. * It might be better to simply deprecate CDROM_MEDIA_CHANGED ioctl * and remove this cruft altogether. It doesn't have much usefulness * at this point. */ static void cdrom_update_events(struct cdrom_device_info *cdi, unsigned int clearing) { … } unsigned int cdrom_check_events(struct cdrom_device_info *cdi, unsigned int clearing) { … } EXPORT_SYMBOL(…); /* We want to make media_changed accessible to the user through an * ioctl. The main problem now is that we must double-buffer the * low-level implementation, to assure that the VFS and the user both * see a medium change once. */ static int media_changed(struct cdrom_device_info *cdi, int queue) { … } /* Requests to the low-level drivers will /always/ be done in the following format convention: CDROM_LBA: all data-related requests. CDROM_MSF: all audio-related requests. However, a low-level implementation is allowed to refuse this request, and return information in its own favorite format. It doesn't make sense /at all/ to ask for a play_audio in LBA format, or ask for multi-session info in MSF format. However, for backward compatibility these format requests will be satisfied, but the requests to the low-level drivers will be sanitized in the more meaningful format indicated above. */ static void sanitize_format(union cdrom_addr *addr, u_char * curr, u_char requested) { … } void init_cdrom_command(struct packet_command *cgc, void *buf, int len, int type) { … } EXPORT_SYMBOL(…); /* DVD handling */ #define copy_key(dest,src) … #define copy_chal(dest,src) … static void setup_report_key(struct packet_command *cgc, unsigned agid, unsigned type) { … } static void setup_send_key(struct packet_command *cgc, unsigned agid, unsigned type) { … } static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai) { … } static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s, struct packet_command *cgc) { … } static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s, struct packet_command *cgc) { … } static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s, struct packet_command *cgc) { … } static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s, struct packet_command *cgc) { … } static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s, struct packet_command *cgc) { … } static int dvd_read_struct(struct cdrom_device_info *cdi, dvd_struct *s, struct packet_command *cgc) { … } int cdrom_mode_sense(struct cdrom_device_info *cdi, struct packet_command *cgc, int page_code, int page_control) { … } EXPORT_SYMBOL(…); int cdrom_mode_select(struct cdrom_device_info *cdi, struct packet_command *cgc) { … } EXPORT_SYMBOL(…); static int cdrom_read_subchannel(struct cdrom_device_info *cdi, struct cdrom_subchnl *subchnl, int mcn) { … } /* * Specific READ_10 interface */ static int cdrom_read_cd(struct cdrom_device_info *cdi, struct packet_command *cgc, int lba, int blocksize, int nblocks) { … } /* very generic interface for reading the various types of blocks */ static int cdrom_read_block(struct cdrom_device_info *cdi, struct packet_command *cgc, int lba, int nblocks, int format, int blksize) { … } static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, int lba, int nframes) { … } static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, int lba, int nframes) { … } static int cdrom_read_cdda(struct cdrom_device_info *cdi, __u8 __user *ubuf, int lba, int nframes) { … } int cdrom_multisession(struct cdrom_device_info *cdi, struct cdrom_multisession *info) { … } EXPORT_SYMBOL_GPL(…); static int cdrom_ioctl_multisession(struct cdrom_device_info *cdi, void __user *argp) { … } static int cdrom_ioctl_eject(struct cdrom_device_info *cdi) { … } static int cdrom_ioctl_closetray(struct cdrom_device_info *cdi) { … } static int cdrom_ioctl_eject_sw(struct cdrom_device_info *cdi, unsigned long arg) { … } static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, unsigned long arg) { … } /* * Media change detection with timing information. * * arg is a pointer to a cdrom_timed_media_change_info struct. * arg->last_media_change may be set by calling code to signal * the timestamp (in ms) of the last known media change (by the caller). * Upon successful return, ioctl call will set arg->last_media_change * to the latest media change timestamp known by the kernel/driver * and set arg->has_changed to 1 if that timestamp is more recent * than the timestamp set by the caller. */ static int cdrom_ioctl_timed_media_change(struct cdrom_device_info *cdi, unsigned long arg) { … } static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi, unsigned long arg) { … } static int cdrom_ioctl_clear_options(struct cdrom_device_info *cdi, unsigned long arg) { … } static int cdrom_ioctl_select_speed(struct cdrom_device_info *cdi, unsigned long arg) { … } static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi, unsigned long arg) { … } static int cdrom_ioctl_reset(struct cdrom_device_info *cdi, struct block_device *bdev) { … } static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi, unsigned long arg) { … } static int cdrom_ioctl_debug(struct cdrom_device_info *cdi, unsigned long arg) { … } static int cdrom_ioctl_get_capability(struct cdrom_device_info *cdi) { … } /* * The following function is implemented, although very few audio * discs give Universal Product Code information, which should just be * the Medium Catalog Number on the box. Note, that the way the code * is written on the CD is /not/ uniform across all discs! */ static int cdrom_ioctl_get_mcn(struct cdrom_device_info *cdi, void __user *argp) { … } static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi, unsigned long arg) { … } /* * Ok, this is where problems start. The current interface for the * CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption that * CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunately, while this * is often the case, it is also very common for CDs to have some tracks * with data, and some tracks with audio. Just because I feel like it, * I declare the following to be the best way to cope. If the CD has ANY * data tracks on it, it will be returned as a data CD. If it has any XA * tracks, I will return it as that. Now I could simplify this interface * by combining these returns with the above, but this more clearly * demonstrates the problem with the current interface. Too bad this * wasn't designed to use bitmasks... -Erik * * Well, now we have the option CDS_MIXED: a mixed-type CD. * User level programmers might feel the ioctl is not very useful. * ---david */ static int cdrom_ioctl_disc_status(struct cdrom_device_info *cdi) { … } static int cdrom_ioctl_changer_nslots(struct cdrom_device_info *cdi) { … } static int cdrom_ioctl_get_subchnl(struct cdrom_device_info *cdi, void __user *argp) { … } static int cdrom_ioctl_read_tochdr(struct cdrom_device_info *cdi, void __user *argp) { … } int cdrom_read_tocentry(struct cdrom_device_info *cdi, struct cdrom_tocentry *entry) { … } EXPORT_SYMBOL_GPL(…); static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi, void __user *argp) { … } static int cdrom_ioctl_play_msf(struct cdrom_device_info *cdi, void __user *argp) { … } static int cdrom_ioctl_play_trkind(struct cdrom_device_info *cdi, void __user *argp) { … } static int cdrom_ioctl_volctrl(struct cdrom_device_info *cdi, void __user *argp) { … } static int cdrom_ioctl_volread(struct cdrom_device_info *cdi, void __user *argp) { … } static int cdrom_ioctl_audioctl(struct cdrom_device_info *cdi, unsigned int cmd) { … } /* * Required when we need to use READ_10 to issue other than 2048 block * reads */ static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size) { … } static int cdrom_get_track_info(struct cdrom_device_info *cdi, __u16 track, __u8 type, track_information *ti) { … } /* return the last written block on the CD-R media. this is for the udf file system. */ int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written) { … } EXPORT_SYMBOL(…); /* return the next writable block. also for udf file system. */ static int cdrom_get_next_writable(struct cdrom_device_info *cdi, long *next_writable) { … } static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi, void __user *arg, struct packet_command *cgc, int cmd) { … } static noinline int mmc_ioctl_cdrom_read_audio(struct cdrom_device_info *cdi, void __user *arg) { … } static noinline int mmc_ioctl_cdrom_subchannel(struct cdrom_device_info *cdi, void __user *arg) { … } static noinline int mmc_ioctl_cdrom_play_msf(struct cdrom_device_info *cdi, void __user *arg, struct packet_command *cgc) { … } static noinline int mmc_ioctl_cdrom_play_blk(struct cdrom_device_info *cdi, void __user *arg, struct packet_command *cgc) { … } static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi, void __user *arg, struct packet_command *cgc, unsigned int cmd) { … } static noinline int mmc_ioctl_cdrom_start_stop(struct cdrom_device_info *cdi, struct packet_command *cgc, int cmd) { … } static noinline int mmc_ioctl_cdrom_pause_resume(struct cdrom_device_info *cdi, struct packet_command *cgc, int cmd) { … } static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi, void __user *arg, struct packet_command *cgc) { … } static noinline int mmc_ioctl_dvd_auth(struct cdrom_device_info *cdi, void __user *arg) { … } static noinline int mmc_ioctl_cdrom_next_writable(struct cdrom_device_info *cdi, void __user *arg) { … } static noinline int mmc_ioctl_cdrom_last_written(struct cdrom_device_info *cdi, void __user *arg) { … } static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, unsigned long arg) { … } /* * Just about every imaginable ioctl is supported in the Uniform layer * these days. * ATAPI / SCSI specific code now mainly resides in mmc_ioctl(). */ int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, unsigned int cmd, unsigned long arg) { … } EXPORT_SYMBOL(…); #ifdef CONFIG_SYSCTL #define CDROM_STR_SIZE … static struct cdrom_sysctl_settings { … } cdrom_sysctl_settings; enum cdrom_print_option { … }; static int cdrom_print_info(const char *header, int val, char *info, int *pos, enum cdrom_print_option option) { … } static int cdrom_sysctl_info(const struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos) { … } /* Unfortunately, per device settings are not implemented through procfs/sysctl yet. When they are, this will naturally disappear. For now just update all drives. Later this will become the template on which new registered drives will be based. */ static void cdrom_update_settings(void) { … } static int cdrom_sysctl_handler(const struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos) { … } /* Place files in /proc/sys/dev/cdrom */ static struct ctl_table cdrom_table[] = …; static struct ctl_table_header *cdrom_sysctl_header; static void cdrom_sysctl_register(void) { … } static void cdrom_sysctl_unregister(void) { … } #else /* CONFIG_SYSCTL */ static void cdrom_sysctl_register(void) { } static void cdrom_sysctl_unregister(void) { } #endif /* CONFIG_SYSCTL */ static int __init cdrom_init(void) { … } static void __exit cdrom_exit(void) { … } module_init(…) …; module_exit(cdrom_exit); MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;