At the time this document is written, all drivers directly implement the ioctl () calls through their own routines, with the danger of forgetting calls to verifyarea() and the risk of divergence in implementation.
For this reason, we2 propose to define another software-level, that separates the ioctl () and open() implementation from the actual hardware implementation. Note that we do not wish to alter the existing application interface defined in cdrom.h, but rather want to re-root the hardware-implementation through some common code.
We believe that CDROM drives are specific enough (i.e., different from other block-devices such as floppy or hard disc drives), to define a set of CDROM device operations, < cdrom - device > dops. These are of a different nature than the classical block-device file operations < block - device > fops.
The extra interfacing level routines are implemented in a file cdrom.c, and a low-level CDROM driver hands over the interfacing to the kernel by registering the following general struct fileoperations:
Registration of the CDROM device driver should now be to the general routines in cdrom.c, not to the VFS any more. This is done though the call
The device operations structure lists the implemented routines for interfacing to the hardware, and some specifications of capabilities of the device, such as the maximum head-transfer rate. [It is impossible to come up with a complete list of all capabilities of (future) CDROM drives, as the developments in technology follow-up at an incredible rate. Maybe write-operation (WORM devices) will become very popular in the future.] The list now is:
& const int & capability; & capabilityflags
& int & mask; & maskofcapability:disablesthem
&
$const $int & speed; & maximumspeedforreadingdata
&
$const $int & minors; & numberofsupportedminordevices
&
$const $int & capacity; & numberofdiscsinjukebox
& int & options; & optionsflags & long & mcflags; & media-changebufferflags($2×16$)
}
Two registers contain variables local to the CDROM device. The flags options are used to specify how the general CDROM routines should behave. These various flags registers should provide enough flexibility to adapt to the different user's wishes (and not the `arbitrary' wishes of the author of the low-level device driver, as is the case in the old scheme). The register mcflags is used to buffer the information from mediachanged () to two separate queues.
Note that most functions have fewer parameters than their blkdevfops counterparts. This is because very little of the information in the structures inode and file are used, the main parameter is the device dev, from which the minor-number can be extracted. (Most low-level CDROM drivers don't even look at that value as only one device is supported.)
The intermediate software layer that cdrom.c forms will performs some additional bookkeeping. The minor number of the device is checked against the maximum registered in < device > dops. The function cdromioctl () will verify the appropriate user-memory regions for read and write, and in case a location on the CD is transferred, it will `sanitize' the format by making requests to the low-level drivers in a standard format, and translating all formats between the user-software and low level drivers. This relieves much of the drivers memory checking and format checking and translation. Also, the necessary structures will be declared on the program stack.
The implementation of the functions should be as defined in the following sections. Three functions must be implemented, namely open(), release() and openfiles(). Other functions may be omitted, their corresponding capability flags will be cleared upon registration. Generally, a function returns zero on success and negative on error. A function call should return only after the command has completed, but of course waiting for the device should not use processor time.