162306a36Sopenharmony_ci=======================
262306a36Sopenharmony_ciA Linux CD-ROM standard
362306a36Sopenharmony_ci=======================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci:Author: David van Leeuwen <david@ElseWare.cistron.nl>
662306a36Sopenharmony_ci:Date: 12 March 1999
762306a36Sopenharmony_ci:Updated by: Erik Andersen (andersee@debian.org)
862306a36Sopenharmony_ci:Updated by: Jens Axboe (axboe@image.dk)
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciIntroduction
1262306a36Sopenharmony_ci============
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ciLinux is probably the Unix-like operating system that supports
1562306a36Sopenharmony_cithe widest variety of hardware devices. The reasons for this are
1662306a36Sopenharmony_cipresumably
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci- The large list of hardware devices available for the many platforms
1962306a36Sopenharmony_ci  that Linux now supports (i.e., i386-PCs, Sparc Suns, etc.)
2062306a36Sopenharmony_ci- The open design of the operating system, such that anybody can write a
2162306a36Sopenharmony_ci  driver for Linux.
2262306a36Sopenharmony_ci- There is plenty of source code around as examples of how to write a driver.
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciThe openness of Linux, and the many different types of available
2562306a36Sopenharmony_cihardware has allowed Linux to support many different hardware devices.
2662306a36Sopenharmony_ciUnfortunately, the very openness that has allowed Linux to support
2762306a36Sopenharmony_ciall these different devices has also allowed the behavior of each
2862306a36Sopenharmony_cidevice driver to differ significantly from one device to another.
2962306a36Sopenharmony_ciThis divergence of behavior has been very significant for CD-ROM
3062306a36Sopenharmony_cidevices; the way a particular drive reacts to a `standard` *ioctl()*
3162306a36Sopenharmony_cicall varies greatly from one device driver to another. To avoid making
3262306a36Sopenharmony_citheir drivers totally inconsistent, the writers of Linux CD-ROM
3362306a36Sopenharmony_cidrivers generally created new device drivers by understanding, copying,
3462306a36Sopenharmony_ciand then changing an existing one. Unfortunately, this practice did not
3562306a36Sopenharmony_cimaintain uniform behavior across all the Linux CD-ROM drivers.
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ciThis document describes an effort to establish Uniform behavior across
3862306a36Sopenharmony_ciall the different CD-ROM device drivers for Linux. This document also
3962306a36Sopenharmony_cidefines the various *ioctl()'s*, and how the low-level CD-ROM device
4062306a36Sopenharmony_cidrivers should implement them. Currently (as of the Linux 2.1.\ *x*
4162306a36Sopenharmony_cidevelopment kernels) several low-level CD-ROM device drivers, including
4262306a36Sopenharmony_ciboth IDE/ATAPI and SCSI, now use this Uniform interface.
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ciWhen the CD-ROM was developed, the interface between the CD-ROM drive
4562306a36Sopenharmony_ciand the computer was not specified in the standards. As a result, many
4662306a36Sopenharmony_cidifferent CD-ROM interfaces were developed. Some of them had their
4762306a36Sopenharmony_ciown proprietary design (Sony, Mitsumi, Panasonic, Philips), other
4862306a36Sopenharmony_cimanufacturers adopted an existing electrical interface and changed
4962306a36Sopenharmony_cithe functionality (CreativeLabs/SoundBlaster, Teac, Funai) or simply
5062306a36Sopenharmony_ciadapted their drives to one or more of the already existing electrical
5162306a36Sopenharmony_ciinterfaces (Aztech, Sanyo, Funai, Vertos, Longshine, Optics Storage and
5262306a36Sopenharmony_cimost of the `NoName` manufacturers). In cases where a new drive really
5362306a36Sopenharmony_cibrought its own interface or used its own command set and flow control
5462306a36Sopenharmony_cischeme, either a separate driver had to be written, or an existing
5562306a36Sopenharmony_cidriver had to be enhanced. History has delivered us CD-ROM support for
5662306a36Sopenharmony_cimany of these different interfaces. Nowadays, almost all new CD-ROM
5762306a36Sopenharmony_cidrives are either IDE/ATAPI or SCSI, and it is very unlikely that any
5862306a36Sopenharmony_cimanufacturer will create a new interface. Even finding drives for the
5962306a36Sopenharmony_ciold proprietary interfaces is getting difficult.
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ciWhen (in the 1.3.70's) I looked at the existing software interface,
6262306a36Sopenharmony_ciwhich was expressed through `cdrom.h`, it appeared to be a rather wild
6362306a36Sopenharmony_ciset of commands and data formats [#f1]_. It seemed that many
6462306a36Sopenharmony_cifeatures of the software interface had been added to accommodate the
6562306a36Sopenharmony_cicapabilities of a particular drive, in an *ad hoc* manner. More
6662306a36Sopenharmony_ciimportantly, it appeared that the behavior of the `standard` commands
6762306a36Sopenharmony_ciwas different for most of the different drivers: e. g., some drivers
6862306a36Sopenharmony_ciclose the tray if an *open()* call occurs when the tray is open, while
6962306a36Sopenharmony_ciothers do not. Some drivers lock the door upon opening the device, to
7062306a36Sopenharmony_ciprevent an incoherent file system, but others don't, to allow software
7162306a36Sopenharmony_ciejection. Undoubtedly, the capabilities of the different drives vary,
7262306a36Sopenharmony_cibut even when two drives have the same capability their drivers'
7362306a36Sopenharmony_cibehavior was usually different.
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci.. [#f1]
7662306a36Sopenharmony_ci   I cannot recollect what kernel version I looked at, then,
7762306a36Sopenharmony_ci   presumably 1.2.13 and 1.3.34 --- the latest kernel that I was
7862306a36Sopenharmony_ci   indirectly involved in.
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciI decided to start a discussion on how to make all the Linux CD-ROM
8162306a36Sopenharmony_cidrivers behave more uniformly. I began by contacting the developers of
8262306a36Sopenharmony_cithe many CD-ROM drivers found in the Linux kernel. Their reactions
8362306a36Sopenharmony_ciencouraged me to write the Uniform CD-ROM Driver which this document is
8462306a36Sopenharmony_ciintended to describe. The implementation of the Uniform CD-ROM Driver is
8562306a36Sopenharmony_ciin the file `cdrom.c`. This driver is intended to be an additional software
8662306a36Sopenharmony_cilayer that sits on top of the low-level device drivers for each CD-ROM drive.
8762306a36Sopenharmony_ciBy adding this additional layer, it is possible to have all the different
8862306a36Sopenharmony_ciCD-ROM devices behave **exactly** the same (insofar as the underlying
8962306a36Sopenharmony_cihardware will allow).
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ciThe goal of the Uniform CD-ROM Driver is **not** to alienate driver developers
9262306a36Sopenharmony_ciwhohave not yet taken steps to support this effort. The goal of Uniform CD-ROM
9362306a36Sopenharmony_ciDriver is simply to give people writing application programs for CD-ROM drives
9462306a36Sopenharmony_ci**one** Linux CD-ROM interface with consistent behavior for all
9562306a36Sopenharmony_ciCD-ROM devices. In addition, this also provides a consistent interface
9662306a36Sopenharmony_cibetween the low-level device driver code and the Linux kernel. Care
9762306a36Sopenharmony_ciis taken that 100% compatibility exists with the data structures and
9862306a36Sopenharmony_ciprogrammer's interface defined in `cdrom.h`. This guide was written to
9962306a36Sopenharmony_cihelp CD-ROM driver developers adapt their code to use the Uniform CD-ROM
10062306a36Sopenharmony_ciDriver code defined in `cdrom.c`.
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciPersonally, I think that the most important hardware interfaces are
10362306a36Sopenharmony_cithe IDE/ATAPI drives and, of course, the SCSI drives, but as prices
10462306a36Sopenharmony_ciof hardware drop continuously, it is also likely that people may have
10562306a36Sopenharmony_cimore than one CD-ROM drive, possibly of mixed types. It is important
10662306a36Sopenharmony_cithat these drives behave in the same way. In December 1994, one of the
10762306a36Sopenharmony_cicheapest CD-ROM drives was a Philips cm206, a double-speed proprietary
10862306a36Sopenharmony_cidrive. In the months that I was busy writing a Linux driver for it,
10962306a36Sopenharmony_ciproprietary drives became obsolete and IDE/ATAPI drives became the
11062306a36Sopenharmony_cistandard. At the time of the last update to this document (November
11162306a36Sopenharmony_ci1997) it is becoming difficult to even **find** anything less than a
11262306a36Sopenharmony_ci16 speed CD-ROM drive, and 24 speed drives are common.
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci.. _cdrom_api:
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ciStandardizing through another software level
11762306a36Sopenharmony_ci============================================
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ciAt the time this document was conceived, all drivers directly
12062306a36Sopenharmony_ciimplemented the CD-ROM *ioctl()* calls through their own routines. This
12162306a36Sopenharmony_ciled to the danger of different drivers forgetting to do important things
12262306a36Sopenharmony_cilike checking that the user was giving the driver valid data. More
12362306a36Sopenharmony_ciimportantly, this led to the divergence of behavior, which has already
12462306a36Sopenharmony_cibeen discussed.
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ciFor this reason, the Uniform CD-ROM Driver was created to enforce consistent
12762306a36Sopenharmony_ciCD-ROM drive behavior, and to provide a common set of services to the various
12862306a36Sopenharmony_cilow-level CD-ROM device drivers. The Uniform CD-ROM Driver now provides another
12962306a36Sopenharmony_cisoftware-level, that separates the *ioctl()* and *open()* implementation
13062306a36Sopenharmony_cifrom the actual hardware implementation. Note that this effort has
13162306a36Sopenharmony_cimade few changes which will affect a user's application programs. The
13262306a36Sopenharmony_cigreatest change involved moving the contents of the various low-level
13362306a36Sopenharmony_ciCD-ROM drivers\' header files to the kernel's cdrom directory. This was
13462306a36Sopenharmony_cidone to help ensure that the user is only presented with only one cdrom
13562306a36Sopenharmony_ciinterface, the interface defined in `cdrom.h`.
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ciCD-ROM drives are specific enough (i. e., different from other
13862306a36Sopenharmony_ciblock-devices such as floppy or hard disc drives), to define a set
13962306a36Sopenharmony_ciof common **CD-ROM device operations**, *<cdrom-device>_dops*.
14062306a36Sopenharmony_ciThese operations are different from the classical block-device file
14162306a36Sopenharmony_cioperations, *<block-device>_fops*.
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ciThe routines for the Uniform CD-ROM Driver interface level are implemented
14462306a36Sopenharmony_ciin the file `cdrom.c`. In this file, the Uniform CD-ROM Driver interfaces
14562306a36Sopenharmony_ciwith the kernel as a block device by registering the following general
14662306a36Sopenharmony_ci*struct file_operations*::
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci	struct file_operations cdrom_fops = {
14962306a36Sopenharmony_ci		NULL,			/* lseek */
15062306a36Sopenharmony_ci		block _read ,		/* read--general block-dev read */
15162306a36Sopenharmony_ci		block _write,		/* write--general block-dev write */
15262306a36Sopenharmony_ci		NULL,			/* readdir */
15362306a36Sopenharmony_ci		NULL,			/* select */
15462306a36Sopenharmony_ci		cdrom_ioctl,		/* ioctl */
15562306a36Sopenharmony_ci		NULL,			/* mmap */
15662306a36Sopenharmony_ci		cdrom_open,		/* open */
15762306a36Sopenharmony_ci		cdrom_release,		/* release */
15862306a36Sopenharmony_ci		NULL,			/* fsync */
15962306a36Sopenharmony_ci		NULL,			/* fasync */
16062306a36Sopenharmony_ci		NULL			/* revalidate */
16162306a36Sopenharmony_ci	};
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ciEvery active CD-ROM device shares this *struct*. The routines
16462306a36Sopenharmony_cideclared above are all implemented in `cdrom.c`, since this file is the
16562306a36Sopenharmony_ciplace where the behavior of all CD-ROM-devices is defined and
16662306a36Sopenharmony_cistandardized. The actual interface to the various types of CD-ROM
16762306a36Sopenharmony_cihardware is still performed by various low-level CD-ROM-device
16862306a36Sopenharmony_cidrivers. These routines simply implement certain **capabilities**
16962306a36Sopenharmony_cithat are common to all CD-ROM (and really, all removable-media
17062306a36Sopenharmony_cidevices).
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ciRegistration of a low-level CD-ROM device driver is now done through
17362306a36Sopenharmony_cithe general routines in `cdrom.c`, not through the Virtual File System
17462306a36Sopenharmony_ci(VFS) any more. The interface implemented in `cdrom.c` is carried out
17562306a36Sopenharmony_cithrough two general structures that contain information about the
17662306a36Sopenharmony_cicapabilities of the driver, and the specific drives on which the
17762306a36Sopenharmony_cidriver operates. The structures are:
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_cicdrom_device_ops
18062306a36Sopenharmony_ci  This structure contains information about the low-level driver for a
18162306a36Sopenharmony_ci  CD-ROM device. This structure is conceptually connected to the major
18262306a36Sopenharmony_ci  number of the device (although some drivers may have different
18362306a36Sopenharmony_ci  major numbers, as is the case for the IDE driver).
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_cicdrom_device_info
18662306a36Sopenharmony_ci  This structure contains information about a particular CD-ROM drive,
18762306a36Sopenharmony_ci  such as its device name, speed, etc. This structure is conceptually
18862306a36Sopenharmony_ci  connected to the minor number of the device.
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ciRegistering a particular CD-ROM drive with the Uniform CD-ROM Driver
19162306a36Sopenharmony_ciis done by the low-level device driver though a call to::
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	register_cdrom(struct cdrom_device_info * <device>_info)
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ciThe device information structure, *<device>_info*, contains all the
19662306a36Sopenharmony_ciinformation needed for the kernel to interface with the low-level
19762306a36Sopenharmony_ciCD-ROM device driver. One of the most important entries in this
19862306a36Sopenharmony_cistructure is a pointer to the *cdrom_device_ops* structure of the
19962306a36Sopenharmony_cilow-level driver.
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ciThe device operations structure, *cdrom_device_ops*, contains a list
20262306a36Sopenharmony_ciof pointers to the functions which are implemented in the low-level
20362306a36Sopenharmony_cidevice driver. When `cdrom.c` accesses a CD-ROM device, it does it
20462306a36Sopenharmony_cithrough the functions in this structure. It is impossible to know all
20562306a36Sopenharmony_cithe capabilities of future CD-ROM drives, so it is expected that this
20662306a36Sopenharmony_cilist may need to be expanded from time to time as new technologies are
20762306a36Sopenharmony_cideveloped. For example, CD-R and CD-R/W drives are beginning to become
20862306a36Sopenharmony_cipopular, and support will soon need to be added for them. For now, the
20962306a36Sopenharmony_cicurrent *struct* is::
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci	struct cdrom_device_ops {
21262306a36Sopenharmony_ci		int (*open)(struct cdrom_device_info *, int)
21362306a36Sopenharmony_ci		void (*release)(struct cdrom_device_info *);
21462306a36Sopenharmony_ci		int (*drive_status)(struct cdrom_device_info *, int);
21562306a36Sopenharmony_ci		unsigned int (*check_events)(struct cdrom_device_info *,
21662306a36Sopenharmony_ci					     unsigned int, int);
21762306a36Sopenharmony_ci		int (*media_changed)(struct cdrom_device_info *, int);
21862306a36Sopenharmony_ci		int (*tray_move)(struct cdrom_device_info *, int);
21962306a36Sopenharmony_ci		int (*lock_door)(struct cdrom_device_info *, int);
22062306a36Sopenharmony_ci		int (*select_speed)(struct cdrom_device_info *, int);
22162306a36Sopenharmony_ci		int (*get_last_session) (struct cdrom_device_info *,
22262306a36Sopenharmony_ci					 struct cdrom_multisession *);
22362306a36Sopenharmony_ci		int (*get_mcn)(struct cdrom_device_info *, struct cdrom_mcn *);
22462306a36Sopenharmony_ci		int (*reset)(struct cdrom_device_info *);
22562306a36Sopenharmony_ci		int (*audio_ioctl)(struct cdrom_device_info *,
22662306a36Sopenharmony_ci				   unsigned int, void *);
22762306a36Sopenharmony_ci		const int capability;		/* capability flags */
22862306a36Sopenharmony_ci		int (*generic_packet)(struct cdrom_device_info *,
22962306a36Sopenharmony_ci				      struct packet_command *);
23062306a36Sopenharmony_ci	};
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ciWhen a low-level device driver implements one of these capabilities,
23362306a36Sopenharmony_ciit should add a function pointer to this *struct*. When a particular
23462306a36Sopenharmony_cifunction is not implemented, however, this *struct* should contain a
23562306a36Sopenharmony_ciNULL instead. The *capability* flags specify the capabilities of the
23662306a36Sopenharmony_ciCD-ROM hardware and/or low-level CD-ROM driver when a CD-ROM drive
23762306a36Sopenharmony_ciis registered with the Uniform CD-ROM Driver.
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ciNote that most functions have fewer parameters than their
24062306a36Sopenharmony_ci*blkdev_fops* counterparts. This is because very little of the
24162306a36Sopenharmony_ciinformation in the structures *inode* and *file* is used. For most
24262306a36Sopenharmony_cidrivers, the main parameter is the *struct* *cdrom_device_info*, from
24362306a36Sopenharmony_ciwhich the major and minor number can be extracted. (Most low-level
24462306a36Sopenharmony_ciCD-ROM drivers don't even look at the major and minor number though,
24562306a36Sopenharmony_cisince many of them only support one device.) This will be available
24662306a36Sopenharmony_cithrough *dev* in *cdrom_device_info* described below.
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ciThe drive-specific, minor-like information that is registered with
24962306a36Sopenharmony_ci`cdrom.c`, currently contains the following fields::
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci  struct cdrom_device_info {
25262306a36Sopenharmony_ci	const struct cdrom_device_ops * ops;	/* device operations for this major */
25362306a36Sopenharmony_ci	struct list_head list;			/* linked list of all device_info */
25462306a36Sopenharmony_ci	struct gendisk * disk;			/* matching block layer disk */
25562306a36Sopenharmony_ci	void *  handle;				/* driver-dependent data */
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	int mask;				/* mask of capability: disables them */
25862306a36Sopenharmony_ci	int speed;				/* maximum speed for reading data */
25962306a36Sopenharmony_ci	int capacity;				/* number of discs in a jukebox */
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	unsigned int options:30;		/* options flags */
26262306a36Sopenharmony_ci	unsigned mc_flags:2;			/*  media-change buffer flags */
26362306a36Sopenharmony_ci	unsigned int vfs_events;		/*  cached events for vfs path */
26462306a36Sopenharmony_ci	unsigned int ioctl_events;		/*  cached events for ioctl path */
26562306a36Sopenharmony_ci	int use_count;				/*  number of times device is opened */
26662306a36Sopenharmony_ci	char name[20];				/*  name of the device type */
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	__u8 sanyo_slot : 2;			/*  Sanyo 3-CD changer support */
26962306a36Sopenharmony_ci	__u8 keeplocked : 1;			/*  CDROM_LOCKDOOR status */
27062306a36Sopenharmony_ci	__u8 reserved : 5;			/*  not used yet */
27162306a36Sopenharmony_ci	int cdda_method;			/*  see CDDA_* flags */
27262306a36Sopenharmony_ci	__u8 last_sense;			/*  saves last sense key */
27362306a36Sopenharmony_ci	__u8 media_written;			/*  dirty flag, DVD+RW bookkeeping */
27462306a36Sopenharmony_ci	unsigned short mmc3_profile;		/*  current MMC3 profile */
27562306a36Sopenharmony_ci	int for_data;				/*  unknown:TBD */
27662306a36Sopenharmony_ci	int (*exit)(struct cdrom_device_info *);/*  unknown:TBD */
27762306a36Sopenharmony_ci	int mrw_mode_page;			/*  which MRW mode page is in use */
27862306a36Sopenharmony_ci  };
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ciUsing this *struct*, a linked list of the registered minor devices is
28162306a36Sopenharmony_cibuilt, using the *next* field. The device number, the device operations
28262306a36Sopenharmony_cistruct and specifications of properties of the drive are stored in this
28362306a36Sopenharmony_cistructure.
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ciThe *mask* flags can be used to mask out some of the capabilities listed
28662306a36Sopenharmony_ciin *ops->capability*, if a specific drive doesn't support a feature
28762306a36Sopenharmony_ciof the driver. The value *speed* specifies the maximum head-rate of the
28862306a36Sopenharmony_cidrive, measured in units of normal audio speed (176kB/sec raw data or
28962306a36Sopenharmony_ci150kB/sec file system data). The parameters are declared *const*
29062306a36Sopenharmony_cibecause they describe properties of the drive, which don't change after
29162306a36Sopenharmony_ciregistration.
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ciA few registers contain variables local to the CD-ROM drive. The
29462306a36Sopenharmony_ciflags *options* are used to specify how the general CD-ROM routines
29562306a36Sopenharmony_cishould behave. These various flags registers should provide enough
29662306a36Sopenharmony_ciflexibility to adapt to the different users' wishes (and **not** the
29762306a36Sopenharmony_ci`arbitrary` wishes of the author of the low-level device driver, as is
29862306a36Sopenharmony_cithe case in the old scheme). The register *mc_flags* is used to buffer
29962306a36Sopenharmony_cithe information from *media_changed()* to two separate queues. Other
30062306a36Sopenharmony_cidata that is specific to a minor drive, can be accessed through *handle*,
30162306a36Sopenharmony_ciwhich can point to a data structure specific to the low-level driver.
30262306a36Sopenharmony_ciThe fields *use_count*, *next*, *options* and *mc_flags* need not be
30362306a36Sopenharmony_ciinitialized.
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ciThe intermediate software layer that `cdrom.c` forms will perform some
30662306a36Sopenharmony_ciadditional bookkeeping. The use count of the device (the number of
30762306a36Sopenharmony_ciprocesses that have the device opened) is registered in *use_count*. The
30862306a36Sopenharmony_cifunction *cdrom_ioctl()* will verify the appropriate user-memory regions
30962306a36Sopenharmony_cifor read and write, and in case a location on the CD is transferred,
31062306a36Sopenharmony_ciit will `sanitize` the format by making requests to the low-level
31162306a36Sopenharmony_cidrivers in a standard format, and translating all formats between the
31262306a36Sopenharmony_ciuser-software and low level drivers. This relieves much of the drivers'
31362306a36Sopenharmony_cimemory checking and format checking and translation. Also, the necessary
31462306a36Sopenharmony_cistructures will be declared on the program stack.
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ciThe implementation of the functions should be as defined in the
31762306a36Sopenharmony_cifollowing sections. Two functions **must** be implemented, namely
31862306a36Sopenharmony_ci*open()* and *release()*. Other functions may be omitted, their
31962306a36Sopenharmony_cicorresponding capability flags will be cleared upon registration.
32062306a36Sopenharmony_ciGenerally, a function returns zero on success and negative on error. A
32162306a36Sopenharmony_cifunction call should return only after the command has completed, but of
32262306a36Sopenharmony_cicourse waiting for the device should not use processor time.
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci::
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci	int open(struct cdrom_device_info *cdi, int purpose)
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci*Open()* should try to open the device for a specific *purpose*, which
32962306a36Sopenharmony_cican be either:
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci- Open for reading data, as done by `mount()` (2), or the
33262306a36Sopenharmony_ci  user commands `dd` or `cat`.
33362306a36Sopenharmony_ci- Open for *ioctl* commands, as done by audio-CD playing programs.
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ciNotice that any strategic code (closing tray upon *open()*, etc.) is
33662306a36Sopenharmony_cidone by the calling routine in `cdrom.c`, so the low-level routine
33762306a36Sopenharmony_cishould only be concerned with proper initialization, such as spinning
33862306a36Sopenharmony_ciup the disc, etc.
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci::
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	void release(struct cdrom_device_info *cdi)
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ciDevice-specific actions should be taken such as spinning down the device.
34562306a36Sopenharmony_ciHowever, strategic actions such as ejection of the tray, or unlocking
34662306a36Sopenharmony_cithe door, should be left over to the general routine *cdrom_release()*.
34762306a36Sopenharmony_ciThis is the only function returning type *void*.
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci.. _cdrom_drive_status:
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci::
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	int drive_status(struct cdrom_device_info *cdi, int slot_nr)
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ciThe function *drive_status*, if implemented, should provide
35662306a36Sopenharmony_ciinformation on the status of the drive (not the status of the disc,
35762306a36Sopenharmony_ciwhich may or may not be in the drive). If the drive is not a changer,
35862306a36Sopenharmony_ci*slot_nr* should be ignored. In `cdrom.h` the possibilities are listed::
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	CDS_NO_INFO		/* no information available */
36262306a36Sopenharmony_ci	CDS_NO_DISC		/* no disc is inserted, tray is closed */
36362306a36Sopenharmony_ci	CDS_TRAY_OPEN		/* tray is opened */
36462306a36Sopenharmony_ci	CDS_DRIVE_NOT_READY	/* something is wrong, tray is moving? */
36562306a36Sopenharmony_ci	CDS_DISC_OK		/* a disc is loaded and everything is fine */
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci::
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	int tray_move(struct cdrom_device_info *cdi, int position)
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ciThis function, if implemented, should control the tray movement. (No
37262306a36Sopenharmony_ciother function should control this.) The parameter *position* controls
37362306a36Sopenharmony_cithe desired direction of movement:
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci- 0 Close tray
37662306a36Sopenharmony_ci- 1 Open tray
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ciThis function returns 0 upon success, and a non-zero value upon
37962306a36Sopenharmony_cierror. Note that if the tray is already in the desired position, no
38062306a36Sopenharmony_ciaction need be taken, and the return value should be 0.
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci::
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	int lock_door(struct cdrom_device_info *cdi, int lock)
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ciThis function (and no other code) controls locking of the door, if the
38762306a36Sopenharmony_cidrive allows this. The value of *lock* controls the desired locking
38862306a36Sopenharmony_cistate:
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci- 0 Unlock door, manual opening is allowed
39162306a36Sopenharmony_ci- 1 Lock door, tray cannot be ejected manually
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ciThis function returns 0 upon success, and a non-zero value upon
39462306a36Sopenharmony_cierror. Note that if the door is already in the requested state, no
39562306a36Sopenharmony_ciaction need be taken, and the return value should be 0.
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci::
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci	int select_speed(struct cdrom_device_info *cdi, int speed)
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ciSome CD-ROM drives are capable of changing their head-speed. There
40262306a36Sopenharmony_ciare several reasons for changing the speed of a CD-ROM drive. Badly
40362306a36Sopenharmony_cipressed CD-ROM s may benefit from less-than-maximum head rate. Modern
40462306a36Sopenharmony_ciCD-ROM drives can obtain very high head rates (up to *24x* is
40562306a36Sopenharmony_cicommon). It has been reported that these drives can make reading
40662306a36Sopenharmony_cierrors at these high speeds, reducing the speed can prevent data loss
40762306a36Sopenharmony_ciin these circumstances. Finally, some of these drives can
40862306a36Sopenharmony_cimake an annoyingly loud noise, which a lower speed may reduce.
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ciThis function specifies the speed at which data is read or audio is
41162306a36Sopenharmony_ciplayed back. The value of *speed* specifies the head-speed of the
41262306a36Sopenharmony_cidrive, measured in units of standard cdrom speed (176kB/sec raw data
41362306a36Sopenharmony_cior 150kB/sec file system data). So to request that a CD-ROM drive
41462306a36Sopenharmony_cioperate at 300kB/sec you would call the CDROM_SELECT_SPEED *ioctl*
41562306a36Sopenharmony_ciwith *speed=2*. The special value `0` means `auto-selection`, i. e.,
41662306a36Sopenharmony_cimaximum data-rate or real-time audio rate. If the drive doesn't have
41762306a36Sopenharmony_cithis `auto-selection` capability, the decision should be made on the
41862306a36Sopenharmony_cicurrent disc loaded and the return value should be positive. A negative
41962306a36Sopenharmony_cireturn value indicates an error.
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci::
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci	int get_last_session(struct cdrom_device_info *cdi,
42462306a36Sopenharmony_ci			     struct cdrom_multisession *ms_info)
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ciThis function should implement the old corresponding *ioctl()*. For
42762306a36Sopenharmony_cidevice *cdi->dev*, the start of the last session of the current disc
42862306a36Sopenharmony_cishould be returned in the pointer argument *ms_info*. Note that
42962306a36Sopenharmony_ciroutines in `cdrom.c` have sanitized this argument: its requested
43062306a36Sopenharmony_ciformat will **always** be of the type *CDROM_LBA* (linear block
43162306a36Sopenharmony_ciaddressing mode), whatever the calling software requested. But
43262306a36Sopenharmony_cisanitization goes even further: the low-level implementation may
43362306a36Sopenharmony_cireturn the requested information in *CDROM_MSF* format if it wishes so
43462306a36Sopenharmony_ci(setting the *ms_info->addr_format* field appropriately, of
43562306a36Sopenharmony_cicourse) and the routines in `cdrom.c` will make the transformation if
43662306a36Sopenharmony_cinecessary. The return value is 0 upon success.
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci::
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	int get_mcn(struct cdrom_device_info *cdi,
44162306a36Sopenharmony_ci		    struct cdrom_mcn *mcn)
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ciSome discs carry a `Media Catalog Number` (MCN), also called
44462306a36Sopenharmony_ci`Universal Product Code` (UPC). This number should reflect the number
44562306a36Sopenharmony_cithat is generally found in the bar-code on the product. Unfortunately,
44662306a36Sopenharmony_cithe few discs that carry such a number on the disc don't even use the
44762306a36Sopenharmony_cisame format. The return argument to this function is a pointer to a
44862306a36Sopenharmony_cipre-declared memory region of type *struct cdrom_mcn*. The MCN is
44962306a36Sopenharmony_ciexpected as a 13-character string, terminated by a null-character.
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci::
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci	int reset(struct cdrom_device_info *cdi)
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ciThis call should perform a hard-reset on the drive (although in
45662306a36Sopenharmony_cicircumstances that a hard-reset is necessary, a drive may very well not
45762306a36Sopenharmony_cilisten to commands anymore). Preferably, control is returned to the
45862306a36Sopenharmony_cicaller only after the drive has finished resetting. If the drive is no
45962306a36Sopenharmony_cilonger listening, it may be wise for the underlying low-level cdrom
46062306a36Sopenharmony_cidriver to time out.
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci::
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci	int audio_ioctl(struct cdrom_device_info *cdi,
46562306a36Sopenharmony_ci			unsigned int cmd, void *arg)
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ciSome of the CD-ROM-\ *ioctl()*\ 's defined in `cdrom.h` can be
46862306a36Sopenharmony_ciimplemented by the routines described above, and hence the function
46962306a36Sopenharmony_ci*cdrom_ioctl* will use those. However, most *ioctl()*\ 's deal with
47062306a36Sopenharmony_ciaudio-control. We have decided to leave these to be accessed through a
47162306a36Sopenharmony_cisingle function, repeating the arguments *cmd* and *arg*. Note that
47262306a36Sopenharmony_cithe latter is of type *void*, rather than *unsigned long int*.
47362306a36Sopenharmony_ciThe routine *cdrom_ioctl()* does do some useful things,
47462306a36Sopenharmony_cithough. It sanitizes the address format type to *CDROM_MSF* (Minutes,
47562306a36Sopenharmony_ciSeconds, Frames) for all audio calls. It also verifies the memory
47662306a36Sopenharmony_cilocation of *arg*, and reserves stack-memory for the argument. This
47762306a36Sopenharmony_cimakes implementation of the *audio_ioctl()* much simpler than in the
47862306a36Sopenharmony_ciold driver scheme. For example, you may look up the function
47962306a36Sopenharmony_ci*cm206_audio_ioctl()* `cm206.c` that should be updated with
48062306a36Sopenharmony_cithis documentation.
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ciAn unimplemented ioctl should return *-ENOSYS*, but a harmless request
48362306a36Sopenharmony_ci(e. g., *CDROMSTART*) may be ignored by returning 0 (success). Other
48462306a36Sopenharmony_cierrors should be according to the standards, whatever they are. When
48562306a36Sopenharmony_cian error is returned by the low-level driver, the Uniform CD-ROM Driver
48662306a36Sopenharmony_citries whenever possible to return the error code to the calling program.
48762306a36Sopenharmony_ci(We may decide to sanitize the return value in *cdrom_ioctl()* though, in
48862306a36Sopenharmony_ciorder to guarantee a uniform interface to the audio-player software.)
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci::
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci	int dev_ioctl(struct cdrom_device_info *cdi,
49362306a36Sopenharmony_ci		      unsigned int cmd, unsigned long arg)
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ciSome *ioctl()'s* seem to be specific to certain CD-ROM drives. That is,
49662306a36Sopenharmony_cithey are introduced to service some capabilities of certain drives. In
49762306a36Sopenharmony_cifact, there are 6 different *ioctl()'s* for reading data, either in some
49862306a36Sopenharmony_ciparticular kind of format, or audio data. Not many drives support
49962306a36Sopenharmony_cireading audio tracks as data, I believe this is because of protection
50062306a36Sopenharmony_ciof copyrights of artists. Moreover, I think that if audio-tracks are
50162306a36Sopenharmony_cisupported, it should be done through the VFS and not via *ioctl()'s*. A
50262306a36Sopenharmony_ciproblem here could be the fact that audio-frames are 2352 bytes long,
50362306a36Sopenharmony_ciso either the audio-file-system should ask for 75264 bytes at once
50462306a36Sopenharmony_ci(the least common multiple of 512 and 2352), or the drivers should
50562306a36Sopenharmony_cibend their backs to cope with this incoherence (to which I would be
50662306a36Sopenharmony_ciopposed). Furthermore, it is very difficult for the hardware to find
50762306a36Sopenharmony_cithe exact frame boundaries, since there are no synchronization headers
50862306a36Sopenharmony_ciin audio frames. Once these issues are resolved, this code should be
50962306a36Sopenharmony_cistandardized in `cdrom.c`.
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ciBecause there are so many *ioctl()'s* that seem to be introduced to
51262306a36Sopenharmony_cisatisfy certain drivers [#f2]_, any non-standard *ioctl()*\ s
51362306a36Sopenharmony_ciare routed through the call *dev_ioctl()*. In principle, `private`
51462306a36Sopenharmony_ci*ioctl()*\ 's should be numbered after the device's major number, and not
51562306a36Sopenharmony_cithe general CD-ROM *ioctl* number, `0x53`. Currently the
51662306a36Sopenharmony_cinon-supported *ioctl()'s* are:
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	CDROMREADMODE1, CDROMREADMODE2, CDROMREADAUDIO, CDROMREADRAW,
51962306a36Sopenharmony_ci	CDROMREADCOOKED, CDROMSEEK, CDROMPLAY-BLK and CDROM-READALL
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci.. [#f2]
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci   Is there software around that actually uses these? I'd be interested!
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci.. _cdrom_capabilities:
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ciCD-ROM capabilities
52862306a36Sopenharmony_ci-------------------
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ciInstead of just implementing some *ioctl* calls, the interface in
53162306a36Sopenharmony_ci`cdrom.c` supplies the possibility to indicate the **capabilities**
53262306a36Sopenharmony_ciof a CD-ROM drive. This can be done by ORing any number of
53362306a36Sopenharmony_cicapability-constants that are defined in `cdrom.h` at the registration
53462306a36Sopenharmony_ciphase. Currently, the capabilities are any of::
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	CDC_CLOSE_TRAY		/* can close tray by software control */
53762306a36Sopenharmony_ci	CDC_OPEN_TRAY		/* can open tray */
53862306a36Sopenharmony_ci	CDC_LOCK		/* can lock and unlock the door */
53962306a36Sopenharmony_ci	CDC_SELECT_SPEED	/* can select speed, in units of * sim*150 ,kB/s */
54062306a36Sopenharmony_ci	CDC_SELECT_DISC		/* drive is juke-box */
54162306a36Sopenharmony_ci	CDC_MULTI_SESSION	/* can read sessions *> rm1* */
54262306a36Sopenharmony_ci	CDC_MCN			/* can read Media Catalog Number */
54362306a36Sopenharmony_ci	CDC_MEDIA_CHANGED	/* can report if disc has changed */
54462306a36Sopenharmony_ci	CDC_PLAY_AUDIO		/* can perform audio-functions (play, pause, etc) */
54562306a36Sopenharmony_ci	CDC_RESET		/* hard reset device */
54662306a36Sopenharmony_ci	CDC_IOCTLS		/* driver has non-standard ioctls */
54762306a36Sopenharmony_ci	CDC_DRIVE_STATUS	/* driver implements drive status */
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ciThe capability flag is declared *const*, to prevent drivers from
55062306a36Sopenharmony_ciaccidentally tampering with the contents. The capability flags actually
55162306a36Sopenharmony_ciinform `cdrom.c` of what the driver can do. If the drive found
55262306a36Sopenharmony_ciby the driver does not have the capability, is can be masked out by
55362306a36Sopenharmony_cithe *cdrom_device_info* variable *mask*. For instance, the SCSI CD-ROM
55462306a36Sopenharmony_cidriver has implemented the code for loading and ejecting CD-ROM's, and
55562306a36Sopenharmony_cihence its corresponding flags in *capability* will be set. But a SCSI
55662306a36Sopenharmony_ciCD-ROM drive might be a caddy system, which can't load the tray, and
55762306a36Sopenharmony_cihence for this drive the *cdrom_device_info* struct will have set
55862306a36Sopenharmony_cithe *CDC_CLOSE_TRAY* bit in *mask*.
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ciIn the file `cdrom.c` you will encounter many constructions of the type::
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	if (cdo->capability & ~cdi->mask & CDC _<capability>) ...
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ciThere is no *ioctl* to set the mask... The reason is that
56562306a36Sopenharmony_ciI think it is better to control the **behavior** rather than the
56662306a36Sopenharmony_ci**capabilities**.
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ciOptions
56962306a36Sopenharmony_ci-------
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ciA final flag register controls the **behavior** of the CD-ROM
57262306a36Sopenharmony_cidrives, in order to satisfy different users' wishes, hopefully
57362306a36Sopenharmony_ciindependently of the ideas of the respective author who happened to
57462306a36Sopenharmony_cihave made the drive's support available to the Linux community. The
57562306a36Sopenharmony_cicurrent behavior options are::
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ci	CDO_AUTO_CLOSE	/* try to close tray upon device open() */
57862306a36Sopenharmony_ci	CDO_AUTO_EJECT	/* try to open tray on last device close() */
57962306a36Sopenharmony_ci	CDO_USE_FFLAGS	/* use file_pointer->f_flags to indicate purpose for open() */
58062306a36Sopenharmony_ci	CDO_LOCK	/* try to lock door if device is opened */
58162306a36Sopenharmony_ci	CDO_CHECK_TYPE	/* ensure disc type is data if opened for data */
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ciThe initial value of this register is
58462306a36Sopenharmony_ci`CDO_AUTO_CLOSE | CDO_USE_FFLAGS | CDO_LOCK`, reflecting my own view on user
58562306a36Sopenharmony_ciinterface and software standards. Before you protest, there are two
58662306a36Sopenharmony_cinew *ioctl()'s* implemented in `cdrom.c`, that allow you to control the
58762306a36Sopenharmony_cibehavior by software. These are::
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci	CDROM_SET_OPTIONS	/* set options specified in (int)arg */
59062306a36Sopenharmony_ci	CDROM_CLEAR_OPTIONS	/* clear options specified in (int)arg */
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ciOne option needs some more explanation: *CDO_USE_FFLAGS*. In the next
59362306a36Sopenharmony_cinewsection we explain what the need for this option is.
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ciA software package `setcd`, available from the Debian distribution
59662306a36Sopenharmony_ciand `sunsite.unc.edu`, allows user level control of these flags.
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ciThe need to know the purpose of opening the CD-ROM device
60062306a36Sopenharmony_ci=========================================================
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ciTraditionally, Unix devices can be used in two different `modes`,
60362306a36Sopenharmony_cieither by reading/writing to the device file, or by issuing
60462306a36Sopenharmony_cicontrolling commands to the device, by the device's *ioctl()*
60562306a36Sopenharmony_cicall. The problem with CD-ROM drives, is that they can be used for
60662306a36Sopenharmony_citwo entirely different purposes. One is to mount removable
60762306a36Sopenharmony_cifile systems, CD-ROM's, the other is to play audio CD's. Audio commands
60862306a36Sopenharmony_ciare implemented entirely through *ioctl()\'s*, presumably because the
60962306a36Sopenharmony_cifirst implementation (SUN?) has been such. In principle there is
61062306a36Sopenharmony_cinothing wrong with this, but a good control of the `CD player` demands
61162306a36Sopenharmony_cithat the device can **always** be opened in order to give the
61262306a36Sopenharmony_ci*ioctl* commands, regardless of the state the drive is in.
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ciOn the other hand, when used as a removable-media disc drive (what the
61562306a36Sopenharmony_cioriginal purpose of CD-ROM s is) we would like to make sure that the
61662306a36Sopenharmony_cidisc drive is ready for operation upon opening the device. In the old
61762306a36Sopenharmony_cischeme, some CD-ROM drivers don't do any integrity checking, resulting
61862306a36Sopenharmony_ciin a number of i/o errors reported by the VFS to the kernel when an
61962306a36Sopenharmony_ciattempt for mounting a CD-ROM on an empty drive occurs. This is not a
62062306a36Sopenharmony_ciparticularly elegant way to find out that there is no CD-ROM inserted;
62162306a36Sopenharmony_ciit more-or-less looks like the old IBM-PC trying to read an empty floppy
62262306a36Sopenharmony_cidrive for a couple of seconds, after which the system complains it
62362306a36Sopenharmony_cican't read from it. Nowadays we can **sense** the existence of a
62462306a36Sopenharmony_ciremovable medium in a drive, and we believe we should exploit that
62562306a36Sopenharmony_cifact. An integrity check on opening of the device, that verifies the
62662306a36Sopenharmony_ciavailability of a CD-ROM and its correct type (data), would be
62762306a36Sopenharmony_cidesirable.
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ciThese two ways of using a CD-ROM drive, principally for data and
63062306a36Sopenharmony_cisecondarily for playing audio discs, have different demands for the
63162306a36Sopenharmony_cibehavior of the *open()* call. Audio use simply wants to open the
63262306a36Sopenharmony_cidevice in order to get a file handle which is needed for issuing
63362306a36Sopenharmony_ci*ioctl* commands, while data use wants to open for correct and
63462306a36Sopenharmony_cireliable data transfer. The only way user programs can indicate what
63562306a36Sopenharmony_citheir *purpose* of opening the device is, is through the *flags*
63662306a36Sopenharmony_ciparameter (see `open(2)`). For CD-ROM devices, these flags aren't
63762306a36Sopenharmony_ciimplemented (some drivers implement checking for write-related flags,
63862306a36Sopenharmony_cibut this is not strictly necessary if the device file has correct
63962306a36Sopenharmony_cipermission flags). Most option flags simply don't make sense to
64062306a36Sopenharmony_ciCD-ROM devices: *O_CREAT*, *O_NOCTTY*, *O_TRUNC*, *O_APPEND*, and
64162306a36Sopenharmony_ci*O_SYNC* have no meaning to a CD-ROM.
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ciWe therefore propose to use the flag *O_NONBLOCK* to indicate
64462306a36Sopenharmony_cithat the device is opened just for issuing *ioctl*
64562306a36Sopenharmony_cicommands. Strictly, the meaning of *O_NONBLOCK* is that opening and
64662306a36Sopenharmony_cisubsequent calls to the device don't cause the calling process to
64762306a36Sopenharmony_ciwait. We could interpret this as don't wait until someone has
64862306a36Sopenharmony_ciinserted some valid data-CD-ROM. Thus, our proposal of the
64962306a36Sopenharmony_ciimplementation for the *open()* call for CD-ROM s is:
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci- If no other flags are set than *O_RDONLY*, the device is opened
65262306a36Sopenharmony_ci  for data transfer, and the return value will be 0 only upon successful
65362306a36Sopenharmony_ci  initialization of the transfer. The call may even induce some actions
65462306a36Sopenharmony_ci  on the CD-ROM, such as closing the tray.
65562306a36Sopenharmony_ci- If the option flag *O_NONBLOCK* is set, opening will always be
65662306a36Sopenharmony_ci  successful, unless the whole device doesn't exist. The drive will take
65762306a36Sopenharmony_ci  no actions whatsoever.
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ciAnd what about standards?
66062306a36Sopenharmony_ci-------------------------
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ciYou might hesitate to accept this proposal as it comes from the
66362306a36Sopenharmony_ciLinux community, and not from some standardizing institute. What
66462306a36Sopenharmony_ciabout SUN, SGI, HP and all those other Unix and hardware vendors?
66562306a36Sopenharmony_ciWell, these companies are in the lucky position that they generally
66662306a36Sopenharmony_cicontrol both the hardware and software of their supported products,
66762306a36Sopenharmony_ciand are large enough to set their own standard. They do not have to
66862306a36Sopenharmony_cideal with a dozen or more different, competing hardware
66962306a36Sopenharmony_ciconfigurations\ [#f3]_.
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci.. [#f3]
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci   Incidentally, I think that SUN's approach to mounting CD-ROM s is very
67462306a36Sopenharmony_ci   good in origin: under Solaris a volume-daemon automatically mounts a
67562306a36Sopenharmony_ci   newly inserted CD-ROM under `/cdrom/*<volume-name>*`.
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci   In my opinion they should have pushed this
67862306a36Sopenharmony_ci   further and have **every** CD-ROM on the local area network be
67962306a36Sopenharmony_ci   mounted at the similar location, i. e., no matter in which particular
68062306a36Sopenharmony_ci   machine you insert a CD-ROM, it will always appear at the same
68162306a36Sopenharmony_ci   position in the directory tree, on every system. When I wanted to
68262306a36Sopenharmony_ci   implement such a user-program for Linux, I came across the
68362306a36Sopenharmony_ci   differences in behavior of the various drivers, and the need for an
68462306a36Sopenharmony_ci   *ioctl* informing about media changes.
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ciWe believe that using *O_NONBLOCK* to indicate that a device is being opened
68762306a36Sopenharmony_cifor *ioctl* commands only can be easily introduced in the Linux
68862306a36Sopenharmony_cicommunity. All the CD-player authors will have to be informed, we can
68962306a36Sopenharmony_cieven send in our own patches to the programs. The use of *O_NONBLOCK*
69062306a36Sopenharmony_cihas most likely no influence on the behavior of the CD-players on
69162306a36Sopenharmony_ciother operating systems than Linux. Finally, a user can always revert
69262306a36Sopenharmony_cito old behavior by a call to
69362306a36Sopenharmony_ci*ioctl(file_descriptor, CDROM_CLEAR_OPTIONS, CDO_USE_FFLAGS)*.
69462306a36Sopenharmony_ci
69562306a36Sopenharmony_ciThe preferred strategy of *open()*
69662306a36Sopenharmony_ci----------------------------------
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ciThe routines in `cdrom.c` are designed in such a way that run-time
69962306a36Sopenharmony_ciconfiguration of the behavior of CD-ROM devices (of **any** type)
70062306a36Sopenharmony_cican be carried out, by the *CDROM_SET/CLEAR_OPTIONS* *ioctls*. Thus, various
70162306a36Sopenharmony_cimodes of operation can be set:
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci`CDO_AUTO_CLOSE | CDO_USE_FFLAGS | CDO_LOCK`
70462306a36Sopenharmony_ci   This is the default setting. (With *CDO_CHECK_TYPE* it will be better, in
70562306a36Sopenharmony_ci   the future.) If the device is not yet opened by any other process, and if
70662306a36Sopenharmony_ci   the device is being opened for data (*O_NONBLOCK* is not set) and the
70762306a36Sopenharmony_ci   tray is found to be open, an attempt to close the tray is made. Then,
70862306a36Sopenharmony_ci   it is verified that a disc is in the drive and, if *CDO_CHECK_TYPE* is
70962306a36Sopenharmony_ci   set, that it contains tracks of type `data mode 1`. Only if all tests
71062306a36Sopenharmony_ci   are passed is the return value zero. The door is locked to prevent file
71162306a36Sopenharmony_ci   system corruption. If the drive is opened for audio (*O_NONBLOCK* is
71262306a36Sopenharmony_ci   set), no actions are taken and a value of 0 will be returned.
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci`CDO_AUTO_CLOSE | CDO_AUTO_EJECT | CDO_LOCK`
71562306a36Sopenharmony_ci   This mimics the behavior of the current sbpcd-driver. The option flags are
71662306a36Sopenharmony_ci   ignored, the tray is closed on the first open, if necessary. Similarly,
71762306a36Sopenharmony_ci   the tray is opened on the last release, i. e., if a CD-ROM is unmounted,
71862306a36Sopenharmony_ci   it is automatically ejected, such that the user can replace it.
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ciWe hope that these option can convince everybody (both driver
72162306a36Sopenharmony_cimaintainers and user program developers) to adopt the new CD-ROM
72262306a36Sopenharmony_cidriver scheme and option flag interpretation.
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ciDescription of routines in `cdrom.c`
72562306a36Sopenharmony_ci====================================
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ciOnly a few routines in `cdrom.c` are exported to the drivers. In this
72862306a36Sopenharmony_cinew section we will discuss these, as well as the functions that `take
72962306a36Sopenharmony_ciover` the CD-ROM interface to the kernel. The header file belonging
73062306a36Sopenharmony_cito `cdrom.c` is called `cdrom.h`. Formerly, some of the contents of this
73162306a36Sopenharmony_cifile were placed in the file `ucdrom.h`, but this file has now been
73262306a36Sopenharmony_cimerged back into `cdrom.h`.
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci::
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci	struct file_operations cdrom_fops
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_ciThe contents of this structure were described in cdrom_api_.
73962306a36Sopenharmony_ciA pointer to this structure is assigned to the *fops* field
74062306a36Sopenharmony_ciof the *struct gendisk*.
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci::
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_ci	int register_cdrom(struct cdrom_device_info *cdi)
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ciThis function is used in about the same way one registers *cdrom_fops*
74762306a36Sopenharmony_ciwith the kernel, the device operations and information structures,
74862306a36Sopenharmony_cias described in cdrom_api_, should be registered with the
74962306a36Sopenharmony_ciUniform CD-ROM Driver::
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	register_cdrom(&<device>_info);
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ciThis function returns zero upon success, and non-zero upon
75562306a36Sopenharmony_cifailure. The structure *<device>_info* should have a pointer to the
75662306a36Sopenharmony_cidriver's *<device>_dops*, as in::
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_ci	struct cdrom_device_info <device>_info = {
75962306a36Sopenharmony_ci		<device>_dops;
76062306a36Sopenharmony_ci		...
76162306a36Sopenharmony_ci	}
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_ciNote that a driver must have one static structure, *<device>_dops*, while
76462306a36Sopenharmony_ciit may have as many structures *<device>_info* as there are minor devices
76562306a36Sopenharmony_ciactive. *Register_cdrom()* builds a linked list from these.
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_ci::
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ci	void unregister_cdrom(struct cdrom_device_info *cdi)
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ciUnregistering device *cdi* with minor number *MINOR(cdi->dev)* removes
77362306a36Sopenharmony_cithe minor device from the list. If it was the last registered minor for
77462306a36Sopenharmony_cithe low-level driver, this disconnects the registered device-operation
77562306a36Sopenharmony_ciroutines from the CD-ROM interface. This function returns zero upon
77662306a36Sopenharmony_cisuccess, and non-zero upon failure.
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_ci::
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci	int cdrom_open(struct inode * ip, struct file * fp)
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ciThis function is not called directly by the low-level drivers, it is
78362306a36Sopenharmony_cilisted in the standard *cdrom_fops*. If the VFS opens a file, this
78462306a36Sopenharmony_cifunction becomes active. A strategy is implemented in this routine,
78562306a36Sopenharmony_citaking care of all capabilities and options that are set in the
78662306a36Sopenharmony_ci*cdrom_device_ops* connected to the device. Then, the program flow is
78762306a36Sopenharmony_citransferred to the device_dependent *open()* call.
78862306a36Sopenharmony_ci
78962306a36Sopenharmony_ci::
79062306a36Sopenharmony_ci
79162306a36Sopenharmony_ci	void cdrom_release(struct inode *ip, struct file *fp)
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_ciThis function implements the reverse-logic of *cdrom_open()*, and then
79462306a36Sopenharmony_cicalls the device-dependent *release()* routine. When the use-count has
79562306a36Sopenharmony_cireached 0, the allocated buffers are flushed by calls to *sync_dev(dev)*
79662306a36Sopenharmony_ciand *invalidate_buffers(dev)*.
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci.. _cdrom_ioctl:
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_ci::
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci	int cdrom_ioctl(struct inode *ip, struct file *fp,
80462306a36Sopenharmony_ci			unsigned int cmd, unsigned long arg)
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ciThis function handles all the standard *ioctl* requests for CD-ROM
80762306a36Sopenharmony_cidevices in a uniform way. The different calls fall into three
80862306a36Sopenharmony_cicategories: *ioctl()'s* that can be directly implemented by device
80962306a36Sopenharmony_cioperations, ones that are routed through the call *audio_ioctl()*, and
81062306a36Sopenharmony_cithe remaining ones, that are presumable device-dependent. Generally, a
81162306a36Sopenharmony_cinegative return value indicates an error.
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_ciDirectly implemented *ioctl()'s*
81462306a36Sopenharmony_ci--------------------------------
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ciThe following `old` CD-ROM *ioctl()*\ 's are implemented by directly
81762306a36Sopenharmony_cicalling device-operations in *cdrom_device_ops*, if implemented and
81862306a36Sopenharmony_cinot masked:
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_ci`CDROMMULTISESSION`
82162306a36Sopenharmony_ci	Requests the last session on a CD-ROM.
82262306a36Sopenharmony_ci`CDROMEJECT`
82362306a36Sopenharmony_ci	Open tray.
82462306a36Sopenharmony_ci`CDROMCLOSETRAY`
82562306a36Sopenharmony_ci	Close tray.
82662306a36Sopenharmony_ci`CDROMEJECT_SW`
82762306a36Sopenharmony_ci	If *arg\not=0*, set behavior to auto-close (close
82862306a36Sopenharmony_ci	tray on first open) and auto-eject (eject on last release), otherwise
82962306a36Sopenharmony_ci	set behavior to non-moving on *open()* and *release()* calls.
83062306a36Sopenharmony_ci`CDROM_GET_MCN`
83162306a36Sopenharmony_ci	Get the Media Catalog Number from a CD.
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci*Ioctl*s routed through *audio_ioctl()*
83462306a36Sopenharmony_ci---------------------------------------
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ciThe following set of *ioctl()'s* are all implemented through a call to
83762306a36Sopenharmony_cithe *cdrom_fops* function *audio_ioctl()*. Memory checks and
83862306a36Sopenharmony_ciallocation are performed in *cdrom_ioctl()*, and also sanitization of
83962306a36Sopenharmony_ciaddress format (*CDROM_LBA*/*CDROM_MSF*) is done.
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci`CDROMSUBCHNL`
84262306a36Sopenharmony_ci	Get sub-channel data in argument *arg* of type
84362306a36Sopenharmony_ci	`struct cdrom_subchnl *`.
84462306a36Sopenharmony_ci`CDROMREADTOCHDR`
84562306a36Sopenharmony_ci	Read Table of Contents header, in *arg* of type
84662306a36Sopenharmony_ci	`struct cdrom_tochdr *`.
84762306a36Sopenharmony_ci`CDROMREADTOCENTRY`
84862306a36Sopenharmony_ci	Read a Table of Contents entry in *arg* and specified by *arg*
84962306a36Sopenharmony_ci	of type `struct cdrom_tocentry *`.
85062306a36Sopenharmony_ci`CDROMPLAYMSF`
85162306a36Sopenharmony_ci	Play audio fragment specified in Minute, Second, Frame format,
85262306a36Sopenharmony_ci	delimited by *arg* of type `struct cdrom_msf *`.
85362306a36Sopenharmony_ci`CDROMPLAYTRKIND`
85462306a36Sopenharmony_ci	Play audio fragment in track-index format delimited by *arg*
85562306a36Sopenharmony_ci	of type `struct cdrom_ti *`.
85662306a36Sopenharmony_ci`CDROMVOLCTRL`
85762306a36Sopenharmony_ci	Set volume specified by *arg* of type `struct cdrom_volctrl *`.
85862306a36Sopenharmony_ci`CDROMVOLREAD`
85962306a36Sopenharmony_ci	Read volume into by *arg* of type `struct cdrom_volctrl *`.
86062306a36Sopenharmony_ci`CDROMSTART`
86162306a36Sopenharmony_ci	Spin up disc.
86262306a36Sopenharmony_ci`CDROMSTOP`
86362306a36Sopenharmony_ci	Stop playback of audio fragment.
86462306a36Sopenharmony_ci`CDROMPAUSE`
86562306a36Sopenharmony_ci	Pause playback of audio fragment.
86662306a36Sopenharmony_ci`CDROMRESUME`
86762306a36Sopenharmony_ci	Resume playing.
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_ciNew *ioctl()'s* in `cdrom.c`
87062306a36Sopenharmony_ci----------------------------
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_ciThe following *ioctl()'s* have been introduced to allow user programs to
87362306a36Sopenharmony_cicontrol the behavior of individual CD-ROM devices. New *ioctl*
87462306a36Sopenharmony_cicommands can be identified by the underscores in their names.
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci`CDROM_SET_OPTIONS`
87762306a36Sopenharmony_ci	Set options specified by *arg*. Returns the option flag register
87862306a36Sopenharmony_ci	after modification. Use *arg = \rm0* for reading the current flags.
87962306a36Sopenharmony_ci`CDROM_CLEAR_OPTIONS`
88062306a36Sopenharmony_ci	Clear options specified by *arg*. Returns the option flag register
88162306a36Sopenharmony_ci	after modification.
88262306a36Sopenharmony_ci`CDROM_SELECT_SPEED`
88362306a36Sopenharmony_ci	Select head-rate speed of disc specified as by *arg* in units
88462306a36Sopenharmony_ci	of standard cdrom speed (176\,kB/sec raw data or
88562306a36Sopenharmony_ci	150kB/sec file system data). The value 0 means `auto-select`,
88662306a36Sopenharmony_ci	i. e., play audio discs at real time and data discs at maximum speed.
88762306a36Sopenharmony_ci	The value *arg* is checked against the maximum head rate of the
88862306a36Sopenharmony_ci	drive found in the *cdrom_dops*.
88962306a36Sopenharmony_ci`CDROM_SELECT_DISC`
89062306a36Sopenharmony_ci	Select disc numbered *arg* from a juke-box.
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_ci	First disc is numbered 0. The number *arg* is checked against the
89362306a36Sopenharmony_ci	maximum number of discs in the juke-box found in the *cdrom_dops*.
89462306a36Sopenharmony_ci`CDROM_MEDIA_CHANGED`
89562306a36Sopenharmony_ci	Returns 1 if a disc has been changed since the last call.
89662306a36Sopenharmony_ci	For juke-boxes, an extra argument *arg*
89762306a36Sopenharmony_ci	specifies the slot for which the information is given. The special
89862306a36Sopenharmony_ci	value *CDSL_CURRENT* requests that information about the currently
89962306a36Sopenharmony_ci	selected slot be returned.
90062306a36Sopenharmony_ci`CDROM_TIMED_MEDIA_CHANGE`
90162306a36Sopenharmony_ci	Checks whether the disc has been changed since a user supplied time
90262306a36Sopenharmony_ci	and returns the time of the last disc change.
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci	*arg* is a pointer to a *cdrom_timed_media_change_info* struct.
90562306a36Sopenharmony_ci	*arg->last_media_change* may be set by calling code to signal
90662306a36Sopenharmony_ci	the timestamp of the last known media change (by the caller).
90762306a36Sopenharmony_ci	Upon successful return, this ioctl call will set
90862306a36Sopenharmony_ci	*arg->last_media_change* to the latest media change timestamp (in ms)
90962306a36Sopenharmony_ci	known by the kernel/driver and set *arg->has_changed* to 1 if
91062306a36Sopenharmony_ci	that timestamp is more recent than the timestamp set by the caller.
91162306a36Sopenharmony_ci`CDROM_DRIVE_STATUS`
91262306a36Sopenharmony_ci	Returns the status of the drive by a call to
91362306a36Sopenharmony_ci	*drive_status()*. Return values are defined in cdrom_drive_status_.
91462306a36Sopenharmony_ci	Note that this call doesn't return information on the
91562306a36Sopenharmony_ci	current playing activity of the drive; this can be polled through
91662306a36Sopenharmony_ci	an *ioctl* call to *CDROMSUBCHNL*. For juke-boxes, an extra argument
91762306a36Sopenharmony_ci	*arg* specifies the slot for which (possibly limited) information is
91862306a36Sopenharmony_ci	given. The special value *CDSL_CURRENT* requests that information
91962306a36Sopenharmony_ci	about the currently selected slot be returned.
92062306a36Sopenharmony_ci`CDROM_DISC_STATUS`
92162306a36Sopenharmony_ci	Returns the type of the disc currently in the drive.
92262306a36Sopenharmony_ci	It should be viewed as a complement to *CDROM_DRIVE_STATUS*.
92362306a36Sopenharmony_ci	This *ioctl* can provide *some* information about the current
92462306a36Sopenharmony_ci	disc that is inserted in the drive. This functionality used to be
92562306a36Sopenharmony_ci	implemented in the low level drivers, but is now carried out
92662306a36Sopenharmony_ci	entirely in Uniform CD-ROM Driver.
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ci	The history of development of the CD's use as a carrier medium for
92962306a36Sopenharmony_ci	various digital information has lead to many different disc types.
93062306a36Sopenharmony_ci	This *ioctl* is useful only in the case that CDs have \emph {only
93162306a36Sopenharmony_ci	one} type of data on them. While this is often the case, it is
93262306a36Sopenharmony_ci	also very common for CDs to have some tracks with data, and some
93362306a36Sopenharmony_ci	tracks with audio. Because this is an existing interface, rather
93462306a36Sopenharmony_ci	than fixing this interface by changing the assumptions it was made
93562306a36Sopenharmony_ci	under, thereby breaking all user applications that use this
93662306a36Sopenharmony_ci	function, the Uniform CD-ROM Driver implements this *ioctl* as
93762306a36Sopenharmony_ci	follows: If the CD in question has audio tracks on it, and it has
93862306a36Sopenharmony_ci	absolutely no CD-I, XA, or data tracks on it, it will be reported
93962306a36Sopenharmony_ci	as *CDS_AUDIO*. If it has both audio and data tracks, it will
94062306a36Sopenharmony_ci	return *CDS_MIXED*. If there are no audio tracks on the disc, and
94162306a36Sopenharmony_ci	if the CD in question has any CD-I tracks on it, it will be
94262306a36Sopenharmony_ci	reported as *CDS_XA_2_2*. Failing that, if the CD in question
94362306a36Sopenharmony_ci	has any XA tracks on it, it will be reported as *CDS_XA_2_1*.
94462306a36Sopenharmony_ci	Finally, if the CD in question has any data tracks on it,
94562306a36Sopenharmony_ci	it will be reported as a data CD (*CDS_DATA_1*).
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci	This *ioctl* can return::
94862306a36Sopenharmony_ci
94962306a36Sopenharmony_ci		CDS_NO_INFO	/* no information available */
95062306a36Sopenharmony_ci		CDS_NO_DISC	/* no disc is inserted, or tray is opened */
95162306a36Sopenharmony_ci		CDS_AUDIO	/* Audio disc (2352 audio bytes/frame) */
95262306a36Sopenharmony_ci		CDS_DATA_1	/* data disc, mode 1 (2048 user bytes/frame) */
95362306a36Sopenharmony_ci		CDS_XA_2_1	/* mixed data (XA), mode 2, form 1 (2048 user bytes) */
95462306a36Sopenharmony_ci		CDS_XA_2_2	/* mixed data (XA), mode 2, form 1 (2324 user bytes) */
95562306a36Sopenharmony_ci		CDS_MIXED	/* mixed audio/data disc */
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_ci	For some information concerning frame layout of the various disc
95862306a36Sopenharmony_ci	types, see a recent version of `cdrom.h`.
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci`CDROM_CHANGER_NSLOTS`
96162306a36Sopenharmony_ci	Returns the number of slots in a juke-box.
96262306a36Sopenharmony_ci`CDROMRESET`
96362306a36Sopenharmony_ci	Reset the drive.
96462306a36Sopenharmony_ci`CDROM_GET_CAPABILITY`
96562306a36Sopenharmony_ci	Returns the *capability* flags for the drive. Refer to section
96662306a36Sopenharmony_ci	cdrom_capabilities_ for more information on these flags.
96762306a36Sopenharmony_ci`CDROM_LOCKDOOR`
96862306a36Sopenharmony_ci	 Locks the door of the drive. `arg == 0` unlocks the door,
96962306a36Sopenharmony_ci	 any other value locks it.
97062306a36Sopenharmony_ci`CDROM_DEBUG`
97162306a36Sopenharmony_ci	 Turns on debugging info. Only root is allowed to do this.
97262306a36Sopenharmony_ci	 Same semantics as CDROM_LOCKDOOR.
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ciDevice dependent *ioctl()'s*
97662306a36Sopenharmony_ci----------------------------
97762306a36Sopenharmony_ci
97862306a36Sopenharmony_ciFinally, all other *ioctl()'s* are passed to the function *dev_ioctl()*,
97962306a36Sopenharmony_ciif implemented. No memory allocation or verification is carried out.
98062306a36Sopenharmony_ci
98162306a36Sopenharmony_ciHow to update your driver
98262306a36Sopenharmony_ci=========================
98362306a36Sopenharmony_ci
98462306a36Sopenharmony_ci- Make a backup of your current driver.
98562306a36Sopenharmony_ci- Get hold of the files `cdrom.c` and `cdrom.h`, they should be in
98662306a36Sopenharmony_ci  the directory tree that came with this documentation.
98762306a36Sopenharmony_ci- Make sure you include `cdrom.h`.
98862306a36Sopenharmony_ci- Change the 3rd argument of *register_blkdev* from `&<your-drive>_fops`
98962306a36Sopenharmony_ci  to `&cdrom_fops`.
99062306a36Sopenharmony_ci- Just after that line, add the following to register with the Uniform
99162306a36Sopenharmony_ci  CD-ROM Driver::
99262306a36Sopenharmony_ci
99362306a36Sopenharmony_ci	register_cdrom(&<your-drive>_info);*
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_ci  Similarly, add a call to *unregister_cdrom()* at the appropriate place.
99662306a36Sopenharmony_ci- Copy an example of the device-operations *struct* to your
99762306a36Sopenharmony_ci  source, e. g., from `cm206.c` *cm206_dops*, and change all
99862306a36Sopenharmony_ci  entries to names corresponding to your driver, or names you just
99962306a36Sopenharmony_ci  happen to like. If your driver doesn't support a certain function,
100062306a36Sopenharmony_ci  make the entry *NULL*. At the entry *capability* you should list all
100162306a36Sopenharmony_ci  capabilities your driver currently supports. If your driver
100262306a36Sopenharmony_ci  has a capability that is not listed, please send me a message.
100362306a36Sopenharmony_ci- Copy the *cdrom_device_info* declaration from the same example
100462306a36Sopenharmony_ci  driver, and modify the entries according to your needs. If your
100562306a36Sopenharmony_ci  driver dynamically determines the capabilities of the hardware, this
100662306a36Sopenharmony_ci  structure should also be declared dynamically.
100762306a36Sopenharmony_ci- Implement all functions in your `<device>_dops` structure,
100862306a36Sopenharmony_ci  according to prototypes listed in  `cdrom.h`, and specifications given
100962306a36Sopenharmony_ci  in cdrom_api_. Most likely you have already implemented
101062306a36Sopenharmony_ci  the code in a large part, and you will almost certainly need to adapt the
101162306a36Sopenharmony_ci  prototype and return values.
101262306a36Sopenharmony_ci- Rename your `<device>_ioctl()` function to *audio_ioctl* and
101362306a36Sopenharmony_ci  change the prototype a little. Remove entries listed in the first
101462306a36Sopenharmony_ci  part in cdrom_ioctl_, if your code was OK, these are
101562306a36Sopenharmony_ci  just calls to the routines you adapted in the previous step.
101662306a36Sopenharmony_ci- You may remove all remaining memory checking code in the
101762306a36Sopenharmony_ci  *audio_ioctl()* function that deals with audio commands (these are
101862306a36Sopenharmony_ci  listed in the second part of cdrom_ioctl_. There is no
101962306a36Sopenharmony_ci  need for memory allocation either, so most *case*s in the *switch*
102062306a36Sopenharmony_ci  statement look similar to::
102162306a36Sopenharmony_ci
102262306a36Sopenharmony_ci	case CDROMREADTOCENTRY:
102362306a36Sopenharmony_ci		get_toc_entry\bigl((struct cdrom_tocentry *) arg);
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_ci- All remaining *ioctl* cases must be moved to a separate
102662306a36Sopenharmony_ci  function, *<device>_ioctl*, the device-dependent *ioctl()'s*. Note that
102762306a36Sopenharmony_ci  memory checking and allocation must be kept in this code!
102862306a36Sopenharmony_ci- Change the prototypes of *<device>_open()* and
102962306a36Sopenharmony_ci  *<device>_release()*, and remove any strategic code (i. e., tray
103062306a36Sopenharmony_ci  movement, door locking, etc.).
103162306a36Sopenharmony_ci- Try to recompile the drivers. We advise you to use modules, both
103262306a36Sopenharmony_ci  for `cdrom.o` and your driver, as debugging is much easier this
103362306a36Sopenharmony_ci  way.
103462306a36Sopenharmony_ci
103562306a36Sopenharmony_ciThanks
103662306a36Sopenharmony_ci======
103762306a36Sopenharmony_ci
103862306a36Sopenharmony_ciThanks to all the people involved. First, Erik Andersen, who has
103962306a36Sopenharmony_citaken over the torch in maintaining `cdrom.c` and integrating much
104062306a36Sopenharmony_ciCD-ROM-related code in the 2.1-kernel. Thanks to Scott Snyder and
104162306a36Sopenharmony_ciGerd Knorr, who were the first to implement this interface for SCSI
104262306a36Sopenharmony_ciand IDE-CD drivers and added many ideas for extension of the data
104362306a36Sopenharmony_cistructures relative to kernel~2.0. Further thanks to Heiko Eißfeldt,
104462306a36Sopenharmony_ciThomas Quinot, Jon Tombs, Ken Pizzini, Eberhard Mönkeberg and Andrew Kroll,
104562306a36Sopenharmony_cithe Linux CD-ROM device driver developers who were kind
104662306a36Sopenharmony_cienough to give suggestions and criticisms during the writing. Finally
104762306a36Sopenharmony_ciof course, I want to thank Linus Torvalds for making this possible in
104862306a36Sopenharmony_cithe first place.
1049