docs: ioctl: convert to ReST
authorMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Thu, 18 Apr 2019 14:38:26 +0000 (11:38 -0300)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Mon, 15 Jul 2019 12:20:26 +0000 (09:20 -0300)
Rename the iio documentation files to ReST, add an
index for them and adjust in order to produce a nice html
output via the Sphinx build system.

The cdrom.txt and hdio.txt have their own particular syntax.
In order to speedup the conversion, I used a small ancillary
perl script:

my $d;
$d .= $_ while(<>);
$d =~ s/(\nCDROM\S+)\s+(\w[^\n]*)/$1\n\t$2\n/g;
$d =~ s/(\nHDIO\S+)\s+(\w[^\n]*)/$1\n\t$2\n/g;
$d =~ s/(\n\s*usage:)[\s\n]*(\w[^\n]*)/$1:\n\n\t  $2\n/g;
$d =~ s/(\n\s*)(E\w+[\s\n]*\w[^\n]*)/$1- $2/g;
$d =~ s/(\n\s*)(inputs|outputs|notes):\s*(\w[^\n]*)/$1$2:\n\t\t$3\n/g;
print $d;

It basically add blank lines on a few interesting places. The
script is not perfect: still several things require manual work,
but it saved quite some time doing some obvious stuff.

At its new index.rst, let's add a :orphan: while this is not linked to
the main index.rst file, in order to avoid build warnings.

Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Documentation/ioctl/botching-up-ioctls.rst [new file with mode: 0644]
Documentation/ioctl/botching-up-ioctls.txt [deleted file]
Documentation/ioctl/cdrom.rst [new file with mode: 0644]
Documentation/ioctl/cdrom.txt [deleted file]
Documentation/ioctl/hdio.rst [new file with mode: 0644]
Documentation/ioctl/hdio.txt [deleted file]
Documentation/ioctl/index.rst [new file with mode: 0644]
Documentation/ioctl/ioctl-decoding.rst [new file with mode: 0644]
Documentation/ioctl/ioctl-decoding.txt [deleted file]
drivers/gpu/drm/drm_ioctl.c

diff --git a/Documentation/ioctl/botching-up-ioctls.rst b/Documentation/ioctl/botching-up-ioctls.rst
new file mode 100644 (file)
index 0000000..ac697fe
--- /dev/null
@@ -0,0 +1,225 @@
+=================================
+(How to avoid) Botching up ioctls
+=================================
+
+From: http://blog.ffwll.ch/2013/11/botching-up-ioctls.html
+
+By: Daniel Vetter, Copyright © 2013 Intel Corporation
+
+One clear insight kernel graphics hackers gained in the past few years is that
+trying to come up with a unified interface to manage the execution units and
+memory on completely different GPUs is a futile effort. So nowadays every
+driver has its own set of ioctls to allocate memory and submit work to the GPU.
+Which is nice, since there's no more insanity in the form of fake-generic, but
+actually only used once interfaces. But the clear downside is that there's much
+more potential to screw things up.
+
+To avoid repeating all the same mistakes again I've written up some of the
+lessons learned while botching the job for the drm/i915 driver. Most of these
+only cover technicalities and not the big-picture issues like what the command
+submission ioctl exactly should look like. Learning these lessons is probably
+something every GPU driver has to do on its own.
+
+
+Prerequisites
+-------------
+
+First the prerequisites. Without these you have already failed, because you
+will need to add a 32-bit compat layer:
+
+ * Only use fixed sized integers. To avoid conflicts with typedefs in userspace
+   the kernel has special types like __u32, __s64. Use them.
+
+ * Align everything to the natural size and use explicit padding. 32-bit
+   platforms don't necessarily align 64-bit values to 64-bit boundaries, but
+   64-bit platforms do. So we always need padding to the natural size to get
+   this right.
+
+ * Pad the entire struct to a multiple of 64-bits if the structure contains
+   64-bit types - the structure size will otherwise differ on 32-bit versus
+   64-bit. Having a different structure size hurts when passing arrays of
+   structures to the kernel, or if the kernel checks the structure size, which
+   e.g. the drm core does.
+
+ * Pointers are __u64, cast from/to a uintprt_t on the userspace side and
+   from/to a void __user * in the kernel. Try really hard not to delay this
+   conversion or worse, fiddle the raw __u64 through your code since that
+   diminishes the checking tools like sparse can provide. The macro
+   u64_to_user_ptr can be used in the kernel to avoid warnings about integers
+   and pointres of different sizes.
+
+
+Basics
+------
+
+With the joys of writing a compat layer avoided we can take a look at the basic
+fumbles. Neglecting these will make backward and forward compatibility a real
+pain. And since getting things wrong on the first attempt is guaranteed you
+will have a second iteration or at least an extension for any given interface.
+
+ * Have a clear way for userspace to figure out whether your new ioctl or ioctl
+   extension is supported on a given kernel. If you can't rely on old kernels
+   rejecting the new flags/modes or ioctls (since doing that was botched in the
+   past) then you need a driver feature flag or revision number somewhere.
+
+ * Have a plan for extending ioctls with new flags or new fields at the end of
+   the structure. The drm core checks the passed-in size for each ioctl call
+   and zero-extends any mismatches between kernel and userspace. That helps,
+   but isn't a complete solution since newer userspace on older kernels won't
+   notice that the newly added fields at the end get ignored. So this still
+   needs a new driver feature flags.
+
+ * Check all unused fields and flags and all the padding for whether it's 0,
+   and reject the ioctl if that's not the case. Otherwise your nice plan for
+   future extensions is going right down the gutters since someone will submit
+   an ioctl struct with random stack garbage in the yet unused parts. Which
+   then bakes in the ABI that those fields can never be used for anything else
+   but garbage. This is also the reason why you must explicitly pad all
+   structures, even if you never use them in an array - the padding the compiler
+   might insert could contain garbage.
+
+ * Have simple testcases for all of the above.
+
+
+Fun with Error Paths
+--------------------
+
+Nowadays we don't have any excuse left any more for drm drivers being neat
+little root exploits. This means we both need full input validation and solid
+error handling paths - GPUs will die eventually in the oddmost corner cases
+anyway:
+
+ * The ioctl must check for array overflows. Also it needs to check for
+   over/underflows and clamping issues of integer values in general. The usual
+   example is sprite positioning values fed directly into the hardware with the
+   hardware just having 12 bits or so. Works nicely until some odd display
+   server doesn't bother with clamping itself and the cursor wraps around the
+   screen.
+
+ * Have simple testcases for every input validation failure case in your ioctl.
+   Check that the error code matches your expectations. And finally make sure
+   that you only test for one single error path in each subtest by submitting
+   otherwise perfectly valid data. Without this an earlier check might reject
+   the ioctl already and shadow the codepath you actually want to test, hiding
+   bugs and regressions.
+
+ * Make all your ioctls restartable. First X really loves signals and second
+   this will allow you to test 90% of all error handling paths by just
+   interrupting your main test suite constantly with signals. Thanks to X's
+   love for signal you'll get an excellent base coverage of all your error
+   paths pretty much for free for graphics drivers. Also, be consistent with
+   how you handle ioctl restarting - e.g. drm has a tiny drmIoctl helper in its
+   userspace library. The i915 driver botched this with the set_tiling ioctl,
+   now we're stuck forever with some arcane semantics in both the kernel and
+   userspace.
+
+ * If you can't make a given codepath restartable make a stuck task at least
+   killable. GPUs just die and your users won't like you more if you hang their
+   entire box (by means of an unkillable X process). If the state recovery is
+   still too tricky have a timeout or hangcheck safety net as a last-ditch
+   effort in case the hardware has gone bananas.
+
+ * Have testcases for the really tricky corner cases in your error recovery code
+   - it's way too easy to create a deadlock between your hangcheck code and
+   waiters.
+
+
+Time, Waiting and Missing it
+----------------------------
+
+GPUs do most everything asynchronously, so we have a need to time operations and
+wait for outstanding ones. This is really tricky business; at the moment none of
+the ioctls supported by the drm/i915 get this fully right, which means there's
+still tons more lessons to learn here.
+
+ * Use CLOCK_MONOTONIC as your reference time, always. It's what alsa, drm and
+   v4l use by default nowadays. But let userspace know which timestamps are
+   derived from different clock domains like your main system clock (provided
+   by the kernel) or some independent hardware counter somewhere else. Clocks
+   will mismatch if you look close enough, but if performance measuring tools
+   have this information they can at least compensate. If your userspace can
+   get at the raw values of some clocks (e.g. through in-command-stream
+   performance counter sampling instructions) consider exposing those also.
+
+ * Use __s64 seconds plus __u64 nanoseconds to specify time. It's not the most
+   convenient time specification, but it's mostly the standard.
+
+ * Check that input time values are normalized and reject them if not. Note
+   that the kernel native struct ktime has a signed integer for both seconds
+   and nanoseconds, so beware here.
+
+ * For timeouts, use absolute times. If you're a good fellow and made your
+   ioctl restartable relative timeouts tend to be too coarse and can
+   indefinitely extend your wait time due to rounding on each restart.
+   Especially if your reference clock is something really slow like the display
+   frame counter. With a spec lawyer hat on this isn't a bug since timeouts can
+   always be extended - but users will surely hate you if their neat animations
+   starts to stutter due to this.
+
+ * Consider ditching any synchronous wait ioctls with timeouts and just deliver
+   an asynchronous event on a pollable file descriptor. It fits much better
+   into event driven applications' main loop.
+
+ * Have testcases for corner-cases, especially whether the return values for
+   already-completed events, successful waits and timed-out waits are all sane
+   and suiting to your needs.
+
+
+Leaking Resources, Not
+----------------------
+
+A full-blown drm driver essentially implements a little OS, but specialized to
+the given GPU platforms. This means a driver needs to expose tons of handles
+for different objects and other resources to userspace. Doing that right
+entails its own little set of pitfalls:
+
+ * Always attach the lifetime of your dynamically created resources to the
+   lifetime of a file descriptor. Consider using a 1:1 mapping if your resource
+   needs to be shared across processes -  fd-passing over unix domain sockets
+   also simplifies lifetime management for userspace.
+
+ * Always have O_CLOEXEC support.
+
+ * Ensure that you have sufficient insulation between different clients. By
+   default pick a private per-fd namespace which forces any sharing to be done
+   explicitly. Only go with a more global per-device namespace if the objects
+   are truly device-unique. One counterexample in the drm modeset interfaces is
+   that the per-device modeset objects like connectors share a namespace with
+   framebuffer objects, which mostly are not shared at all. A separate
+   namespace, private by default, for framebuffers would have been more
+   suitable.
+
+ * Think about uniqueness requirements for userspace handles. E.g. for most drm
+   drivers it's a userspace bug to submit the same object twice in the same
+   command submission ioctl. But then if objects are shareable userspace needs
+   to know whether it has seen an imported object from a different process
+   already or not. I haven't tried this myself yet due to lack of a new class
+   of objects, but consider using inode numbers on your shared file descriptors
+   as unique identifiers - it's how real files are told apart, too.
+   Unfortunately this requires a full-blown virtual filesystem in the kernel.
+
+
+Last, but not Least
+-------------------
+
+Not every problem needs a new ioctl:
+
+ * Think hard whether you really want a driver-private interface. Of course
+   it's much quicker to push a driver-private interface than engaging in
+   lengthy discussions for a more generic solution. And occasionally doing a
+   private interface to spearhead a new concept is what's required. But in the
+   end, once the generic interface comes around you'll end up maintainer two
+   interfaces. Indefinitely.
+
+ * Consider other interfaces than ioctls. A sysfs attribute is much better for
+   per-device settings, or for child objects with fairly static lifetimes (like
+   output connectors in drm with all the detection override attributes). Or
+   maybe only your testsuite needs this interface, and then debugfs with its
+   disclaimer of not having a stable ABI would be better.
+
+Finally, the name of the game is to get it right on the first attempt, since if
+your driver proves popular and your hardware platforms long-lived then you'll
+be stuck with a given ioctl essentially forever. You can try to deprecate
+horrible ioctls on newer iterations of your hardware, but generally it takes
+years to accomplish this. And then again years until the last user able to
+complain about regressions disappears, too.
diff --git a/Documentation/ioctl/botching-up-ioctls.txt b/Documentation/ioctl/botching-up-ioctls.txt
deleted file mode 100644 (file)
index 883fb03..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-(How to avoid) Botching up ioctls
-=================================
-
-From: http://blog.ffwll.ch/2013/11/botching-up-ioctls.html
-
-By: Daniel Vetter, Copyright © 2013 Intel Corporation
-
-One clear insight kernel graphics hackers gained in the past few years is that
-trying to come up with a unified interface to manage the execution units and
-memory on completely different GPUs is a futile effort. So nowadays every
-driver has its own set of ioctls to allocate memory and submit work to the GPU.
-Which is nice, since there's no more insanity in the form of fake-generic, but
-actually only used once interfaces. But the clear downside is that there's much
-more potential to screw things up.
-
-To avoid repeating all the same mistakes again I've written up some of the
-lessons learned while botching the job for the drm/i915 driver. Most of these
-only cover technicalities and not the big-picture issues like what the command
-submission ioctl exactly should look like. Learning these lessons is probably
-something every GPU driver has to do on its own.
-
-
-Prerequisites
--------------
-
-First the prerequisites. Without these you have already failed, because you
-will need to add a 32-bit compat layer:
-
- * Only use fixed sized integers. To avoid conflicts with typedefs in userspace
-   the kernel has special types like __u32, __s64. Use them.
-
- * Align everything to the natural size and use explicit padding. 32-bit
-   platforms don't necessarily align 64-bit values to 64-bit boundaries, but
-   64-bit platforms do. So we always need padding to the natural size to get
-   this right.
-
- * Pad the entire struct to a multiple of 64-bits if the structure contains
-   64-bit types - the structure size will otherwise differ on 32-bit versus
-   64-bit. Having a different structure size hurts when passing arrays of
-   structures to the kernel, or if the kernel checks the structure size, which
-   e.g. the drm core does.
-
- * Pointers are __u64, cast from/to a uintprt_t on the userspace side and
-   from/to a void __user * in the kernel. Try really hard not to delay this
-   conversion or worse, fiddle the raw __u64 through your code since that
-   diminishes the checking tools like sparse can provide. The macro
-   u64_to_user_ptr can be used in the kernel to avoid warnings about integers
-   and pointres of different sizes.
-
-
-Basics
-------
-
-With the joys of writing a compat layer avoided we can take a look at the basic
-fumbles. Neglecting these will make backward and forward compatibility a real
-pain. And since getting things wrong on the first attempt is guaranteed you
-will have a second iteration or at least an extension for any given interface.
-
- * Have a clear way for userspace to figure out whether your new ioctl or ioctl
-   extension is supported on a given kernel. If you can't rely on old kernels
-   rejecting the new flags/modes or ioctls (since doing that was botched in the
-   past) then you need a driver feature flag or revision number somewhere.
-
- * Have a plan for extending ioctls with new flags or new fields at the end of
-   the structure. The drm core checks the passed-in size for each ioctl call
-   and zero-extends any mismatches between kernel and userspace. That helps,
-   but isn't a complete solution since newer userspace on older kernels won't
-   notice that the newly added fields at the end get ignored. So this still
-   needs a new driver feature flags.
-
- * Check all unused fields and flags and all the padding for whether it's 0,
-   and reject the ioctl if that's not the case. Otherwise your nice plan for
-   future extensions is going right down the gutters since someone will submit
-   an ioctl struct with random stack garbage in the yet unused parts. Which
-   then bakes in the ABI that those fields can never be used for anything else
-   but garbage. This is also the reason why you must explicitly pad all
-   structures, even if you never use them in an array - the padding the compiler
-   might insert could contain garbage.
-
- * Have simple testcases for all of the above.
-
-
-Fun with Error Paths
---------------------
-
-Nowadays we don't have any excuse left any more for drm drivers being neat
-little root exploits. This means we both need full input validation and solid
-error handling paths - GPUs will die eventually in the oddmost corner cases
-anyway:
-
- * The ioctl must check for array overflows. Also it needs to check for
-   over/underflows and clamping issues of integer values in general. The usual
-   example is sprite positioning values fed directly into the hardware with the
-   hardware just having 12 bits or so. Works nicely until some odd display
-   server doesn't bother with clamping itself and the cursor wraps around the
-   screen.
-
- * Have simple testcases for every input validation failure case in your ioctl.
-   Check that the error code matches your expectations. And finally make sure
-   that you only test for one single error path in each subtest by submitting
-   otherwise perfectly valid data. Without this an earlier check might reject
-   the ioctl already and shadow the codepath you actually want to test, hiding
-   bugs and regressions.
-
- * Make all your ioctls restartable. First X really loves signals and second
-   this will allow you to test 90% of all error handling paths by just
-   interrupting your main test suite constantly with signals. Thanks to X's
-   love for signal you'll get an excellent base coverage of all your error
-   paths pretty much for free for graphics drivers. Also, be consistent with
-   how you handle ioctl restarting - e.g. drm has a tiny drmIoctl helper in its
-   userspace library. The i915 driver botched this with the set_tiling ioctl,
-   now we're stuck forever with some arcane semantics in both the kernel and
-   userspace.
-
- * If you can't make a given codepath restartable make a stuck task at least
-   killable. GPUs just die and your users won't like you more if you hang their
-   entire box (by means of an unkillable X process). If the state recovery is
-   still too tricky have a timeout or hangcheck safety net as a last-ditch
-   effort in case the hardware has gone bananas.
-
- * Have testcases for the really tricky corner cases in your error recovery code
-   - it's way too easy to create a deadlock between your hangcheck code and
-   waiters.
-
-
-Time, Waiting and Missing it
-----------------------------
-
-GPUs do most everything asynchronously, so we have a need to time operations and
-wait for outstanding ones. This is really tricky business; at the moment none of
-the ioctls supported by the drm/i915 get this fully right, which means there's
-still tons more lessons to learn here.
-
- * Use CLOCK_MONOTONIC as your reference time, always. It's what alsa, drm and
-   v4l use by default nowadays. But let userspace know which timestamps are
-   derived from different clock domains like your main system clock (provided
-   by the kernel) or some independent hardware counter somewhere else. Clocks
-   will mismatch if you look close enough, but if performance measuring tools
-   have this information they can at least compensate. If your userspace can
-   get at the raw values of some clocks (e.g. through in-command-stream
-   performance counter sampling instructions) consider exposing those also.
-
- * Use __s64 seconds plus __u64 nanoseconds to specify time. It's not the most
-   convenient time specification, but it's mostly the standard.
-
- * Check that input time values are normalized and reject them if not. Note
-   that the kernel native struct ktime has a signed integer for both seconds
-   and nanoseconds, so beware here.
-
- * For timeouts, use absolute times. If you're a good fellow and made your
-   ioctl restartable relative timeouts tend to be too coarse and can
-   indefinitely extend your wait time due to rounding on each restart.
-   Especially if your reference clock is something really slow like the display
-   frame counter. With a spec lawyer hat on this isn't a bug since timeouts can
-   always be extended - but users will surely hate you if their neat animations
-   starts to stutter due to this.
-
- * Consider ditching any synchronous wait ioctls with timeouts and just deliver
-   an asynchronous event on a pollable file descriptor. It fits much better
-   into event driven applications' main loop.
-
- * Have testcases for corner-cases, especially whether the return values for
-   already-completed events, successful waits and timed-out waits are all sane
-   and suiting to your needs.
-
-
-Leaking Resources, Not
-----------------------
-
-A full-blown drm driver essentially implements a little OS, but specialized to
-the given GPU platforms. This means a driver needs to expose tons of handles
-for different objects and other resources to userspace. Doing that right
-entails its own little set of pitfalls:
-
- * Always attach the lifetime of your dynamically created resources to the
-   lifetime of a file descriptor. Consider using a 1:1 mapping if your resource
-   needs to be shared across processes -  fd-passing over unix domain sockets
-   also simplifies lifetime management for userspace.
-
- * Always have O_CLOEXEC support.
-
- * Ensure that you have sufficient insulation between different clients. By
-   default pick a private per-fd namespace which forces any sharing to be done
-   explicitly. Only go with a more global per-device namespace if the objects
-   are truly device-unique. One counterexample in the drm modeset interfaces is
-   that the per-device modeset objects like connectors share a namespace with
-   framebuffer objects, which mostly are not shared at all. A separate
-   namespace, private by default, for framebuffers would have been more
-   suitable.
-
- * Think about uniqueness requirements for userspace handles. E.g. for most drm
-   drivers it's a userspace bug to submit the same object twice in the same
-   command submission ioctl. But then if objects are shareable userspace needs
-   to know whether it has seen an imported object from a different process
-   already or not. I haven't tried this myself yet due to lack of a new class
-   of objects, but consider using inode numbers on your shared file descriptors
-   as unique identifiers - it's how real files are told apart, too.
-   Unfortunately this requires a full-blown virtual filesystem in the kernel.
-
-
-Last, but not Least
--------------------
-
-Not every problem needs a new ioctl:
-
- * Think hard whether you really want a driver-private interface. Of course
-   it's much quicker to push a driver-private interface than engaging in
-   lengthy discussions for a more generic solution. And occasionally doing a
-   private interface to spearhead a new concept is what's required. But in the
-   end, once the generic interface comes around you'll end up maintainer two
-   interfaces. Indefinitely.
-
- * Consider other interfaces than ioctls. A sysfs attribute is much better for
-   per-device settings, or for child objects with fairly static lifetimes (like
-   output connectors in drm with all the detection override attributes). Or
-   maybe only your testsuite needs this interface, and then debugfs with its
-   disclaimer of not having a stable ABI would be better.
-
-Finally, the name of the game is to get it right on the first attempt, since if
-your driver proves popular and your hardware platforms long-lived then you'll
-be stuck with a given ioctl essentially forever. You can try to deprecate
-horrible ioctls on newer iterations of your hardware, but generally it takes
-years to accomplish this. And then again years until the last user able to
-complain about regressions disappears, too.
diff --git a/Documentation/ioctl/cdrom.rst b/Documentation/ioctl/cdrom.rst
new file mode 100644 (file)
index 0000000..3b4c050
--- /dev/null
@@ -0,0 +1,1233 @@
+============================
+Summary of CDROM ioctl calls
+============================
+
+- Edward A. Falk <efalk@google.com>
+
+November, 2004
+
+This document attempts to describe the ioctl(2) calls supported by
+the CDROM layer.  These are by-and-large implemented (as of Linux 2.6)
+in drivers/cdrom/cdrom.c and drivers/block/scsi_ioctl.c
+
+ioctl values are listed in <linux/cdrom.h>.  As of this writing, they
+are as follows:
+
+       ======================  ===============================================
+       CDROMPAUSE              Pause Audio Operation
+       CDROMRESUME             Resume paused Audio Operation
+       CDROMPLAYMSF            Play Audio MSF (struct cdrom_msf)
+       CDROMPLAYTRKIND         Play Audio Track/index (struct cdrom_ti)
+       CDROMREADTOCHDR         Read TOC header (struct cdrom_tochdr)
+       CDROMREADTOCENTRY       Read TOC entry (struct cdrom_tocentry)
+       CDROMSTOP               Stop the cdrom drive
+       CDROMSTART              Start the cdrom drive
+       CDROMEJECT              Ejects the cdrom media
+       CDROMVOLCTRL            Control output volume (struct cdrom_volctrl)
+       CDROMSUBCHNL            Read subchannel data (struct cdrom_subchnl)
+       CDROMREADMODE2          Read CDROM mode 2 data (2336 Bytes)
+                               (struct cdrom_read)
+       CDROMREADMODE1          Read CDROM mode 1 data (2048 Bytes)
+                               (struct cdrom_read)
+       CDROMREADAUDIO          (struct cdrom_read_audio)
+       CDROMEJECT_SW           enable(1)/disable(0) auto-ejecting
+       CDROMMULTISESSION       Obtain the start-of-last-session
+                               address of multi session disks
+                               (struct cdrom_multisession)
+       CDROM_GET_MCN           Obtain the "Universal Product Code"
+                               if available (struct cdrom_mcn)
+       CDROM_GET_UPC           Deprecated, use CDROM_GET_MCN instead.
+       CDROMRESET              hard-reset the drive
+       CDROMVOLREAD            Get the drive's volume setting
+                               (struct cdrom_volctrl)
+       CDROMREADRAW            read data in raw mode (2352 Bytes)
+                               (struct cdrom_read)
+       CDROMREADCOOKED         read data in cooked mode
+       CDROMSEEK               seek msf address
+       CDROMPLAYBLK            scsi-cd only, (struct cdrom_blk)
+       CDROMREADALL            read all 2646 bytes
+       CDROMGETSPINDOWN        return 4-bit spindown value
+       CDROMSETSPINDOWN        set 4-bit spindown value
+       CDROMCLOSETRAY          pendant of CDROMEJECT
+       CDROM_SET_OPTIONS       Set behavior options
+       CDROM_CLEAR_OPTIONS     Clear behavior options
+       CDROM_SELECT_SPEED      Set the CD-ROM speed
+       CDROM_SELECT_DISC       Select disc (for juke-boxes)
+       CDROM_MEDIA_CHANGED     Check is media changed
+       CDROM_DRIVE_STATUS      Get tray position, etc.
+       CDROM_DISC_STATUS       Get disc type, etc.
+       CDROM_CHANGER_NSLOTS    Get number of slots
+       CDROM_LOCKDOOR          lock or unlock door
+       CDROM_DEBUG             Turn debug messages on/off
+       CDROM_GET_CAPABILITY    get capabilities
+       CDROMAUDIOBUFSIZ        set the audio buffer size
+       DVD_READ_STRUCT         Read structure
+       DVD_WRITE_STRUCT        Write structure
+       DVD_AUTH                Authentication
+       CDROM_SEND_PACKET       send a packet to the drive
+       CDROM_NEXT_WRITABLE     get next writable block
+       CDROM_LAST_WRITTEN      get last block written on disc
+       ======================  ===============================================
+
+
+The information that follows was determined from reading kernel source
+code.  It is likely that some corrections will be made over time.
+
+------------------------------------------------------------------------------
+
+General:
+
+       Unless otherwise specified, all ioctl calls return 0 on success
+       and -1 with errno set to an appropriate value on error.  (Some
+       ioctls return non-negative data values.)
+
+       Unless otherwise specified, all ioctl calls return -1 and set
+       errno to EFAULT on a failed attempt to copy data to or from user
+       address space.
+
+       Individual drivers may return error codes not listed here.
+
+       Unless otherwise specified, all data structures and constants
+       are defined in <linux/cdrom.h>
+
+------------------------------------------------------------------------------
+
+
+CDROMPAUSE
+       Pause Audio Operation
+
+
+       usage::
+
+         ioctl(fd, CDROMPAUSE, 0);
+
+
+       inputs:
+               none
+
+
+       outputs:
+               none
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+
+
+CDROMRESUME
+       Resume paused Audio Operation
+
+
+       usage::
+
+         ioctl(fd, CDROMRESUME, 0);
+
+
+       inputs:
+               none
+
+
+       outputs:
+               none
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+
+
+CDROMPLAYMSF
+       Play Audio MSF
+
+       (struct cdrom_msf)
+
+
+       usage::
+
+         struct cdrom_msf msf;
+
+         ioctl(fd, CDROMPLAYMSF, &msf);
+
+       inputs:
+               cdrom_msf structure, describing a segment of music to play
+
+
+       outputs:
+               none
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+
+       notes:
+               - MSF stands for minutes-seconds-frames
+               - LBA stands for logical block address
+               - Segment is described as start and end times, where each time
+                 is described as minutes:seconds:frames.
+                 A frame is 1/75 of a second.
+
+
+CDROMPLAYTRKIND
+       Play Audio Track/index
+
+       (struct cdrom_ti)
+
+
+       usage::
+
+         struct cdrom_ti ti;
+
+         ioctl(fd, CDROMPLAYTRKIND, &ti);
+
+       inputs:
+               cdrom_ti structure, describing a segment of music to play
+
+
+       outputs:
+               none
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+
+       notes:
+               - Segment is described as start and end times, where each time
+                 is described as a track and an index.
+
+
+
+CDROMREADTOCHDR
+       Read TOC header
+
+       (struct cdrom_tochdr)
+
+
+       usage::
+
+         cdrom_tochdr header;
+
+         ioctl(fd, CDROMREADTOCHDR, &header);
+
+       inputs:
+               cdrom_tochdr structure
+
+
+       outputs:
+               cdrom_tochdr structure
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+
+
+
+CDROMREADTOCENTRY
+       Read TOC entry
+
+       (struct cdrom_tocentry)
+
+
+       usage::
+
+         struct cdrom_tocentry entry;
+
+         ioctl(fd, CDROMREADTOCENTRY, &entry);
+
+       inputs:
+               cdrom_tocentry structure
+
+
+       outputs:
+               cdrom_tocentry structure
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+         - EINVAL      entry.cdte_format not CDROM_MSF or CDROM_LBA
+         - EINVAL      requested track out of bounds
+         - EIO         I/O error reading TOC
+
+       notes:
+               - TOC stands for Table Of Contents
+               - MSF stands for minutes-seconds-frames
+               - LBA stands for logical block address
+
+
+
+CDROMSTOP
+       Stop the cdrom drive
+
+
+       usage::
+
+         ioctl(fd, CDROMSTOP, 0);
+
+
+       inputs:
+               none
+
+
+       outputs:
+               none
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+
+       notes:
+         - Exact interpretation of this ioctl depends on the device,
+           but most seem to spin the drive down.
+
+
+CDROMSTART
+       Start the cdrom drive
+
+
+       usage::
+
+         ioctl(fd, CDROMSTART, 0);
+
+
+       inputs:
+               none
+
+
+       outputs:
+               none
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+
+       notes:
+         - Exact interpretation of this ioctl depends on the device,
+           but most seem to spin the drive up and/or close the tray.
+           Other devices ignore the ioctl completely.
+
+
+CDROMEJECT
+       - Ejects the cdrom media
+
+
+       usage::
+
+         ioctl(fd, CDROMEJECT, 0);
+
+
+       inputs:
+               none
+
+
+       outputs:
+               none
+
+
+       error returns:
+         - ENOSYS      cd drive not capable of ejecting
+         - EBUSY       other processes are accessing drive, or door is locked
+
+       notes:
+               - See CDROM_LOCKDOOR, below.
+
+
+
+
+CDROMCLOSETRAY
+       pendant of CDROMEJECT
+
+
+       usage::
+
+         ioctl(fd, CDROMCLOSETRAY, 0);
+
+
+       inputs:
+               none
+
+
+       outputs:
+               none
+
+
+       error returns:
+         - ENOSYS      cd drive not capable of closing the tray
+         - EBUSY       other processes are accessing drive, or door is locked
+
+       notes:
+               - See CDROM_LOCKDOOR, below.
+
+
+
+
+CDROMVOLCTRL
+       Control output volume (struct cdrom_volctrl)
+
+
+       usage::
+
+         struct cdrom_volctrl volume;
+
+         ioctl(fd, CDROMVOLCTRL, &volume);
+
+       inputs:
+               cdrom_volctrl structure containing volumes for up to 4
+               channels.
+
+       outputs:
+               none
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+
+
+
+CDROMVOLREAD
+       Get the drive's volume setting
+
+       (struct cdrom_volctrl)
+
+
+       usage::
+
+         struct cdrom_volctrl volume;
+
+         ioctl(fd, CDROMVOLREAD, &volume);
+
+       inputs:
+               none
+
+
+       outputs:
+               The current volume settings.
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+
+
+
+CDROMSUBCHNL
+       Read subchannel data
+
+       (struct cdrom_subchnl)
+
+
+       usage::
+
+         struct cdrom_subchnl q;
+
+         ioctl(fd, CDROMSUBCHNL, &q);
+
+       inputs:
+               cdrom_subchnl structure
+
+
+       outputs:
+               cdrom_subchnl structure
+
+
+       error return:
+         - ENOSYS      cd drive not audio-capable.
+         - EINVAL      format not CDROM_MSF or CDROM_LBA
+
+       notes:
+               - Format is converted to CDROM_MSF or CDROM_LBA
+                 as per user request on return
+
+
+
+CDROMREADRAW
+       read data in raw mode (2352 Bytes)
+
+       (struct cdrom_read)
+
+       usage::
+
+         union {
+
+           struct cdrom_msf msf;               /* input */
+           char buffer[CD_FRAMESIZE_RAW];      /* return */
+         } arg;
+         ioctl(fd, CDROMREADRAW, &arg);
+
+       inputs:
+               cdrom_msf structure indicating an address to read.
+
+               Only the start values are significant.
+
+       outputs:
+               Data written to address provided by user.
+
+
+       error return:
+         - EINVAL      address less than 0, or msf less than 0:2:0
+         - ENOMEM      out of memory
+
+       notes:
+               - As of 2.6.8.1, comments in <linux/cdrom.h> indicate that this
+                 ioctl accepts a cdrom_read structure, but actual source code
+                 reads a cdrom_msf structure and writes a buffer of data to
+                 the same address.
+
+               - MSF values are converted to LBA values via this formula::
+
+                   lba = (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
+
+
+
+
+CDROMREADMODE1
+       Read CDROM mode 1 data (2048 Bytes)
+
+       (struct cdrom_read)
+
+       notes:
+               Identical to CDROMREADRAW except that block size is
+               CD_FRAMESIZE (2048) bytes
+
+
+
+CDROMREADMODE2
+       Read CDROM mode 2 data (2336 Bytes)
+
+       (struct cdrom_read)
+
+       notes:
+               Identical to CDROMREADRAW except that block size is
+               CD_FRAMESIZE_RAW0 (2336) bytes
+
+
+
+CDROMREADAUDIO
+       (struct cdrom_read_audio)
+
+       usage::
+
+         struct cdrom_read_audio ra;
+
+         ioctl(fd, CDROMREADAUDIO, &ra);
+
+       inputs:
+               cdrom_read_audio structure containing read start
+               point and length
+
+       outputs:
+               audio data, returned to buffer indicated by ra
+
+
+       error return:
+         - EINVAL      format not CDROM_MSF or CDROM_LBA
+         - EINVAL      nframes not in range [1 75]
+         - ENXIO       drive has no queue (probably means invalid fd)
+         - ENOMEM      out of memory
+
+
+CDROMEJECT_SW
+       enable(1)/disable(0) auto-ejecting
+
+
+       usage::
+
+         int val;
+
+         ioctl(fd, CDROMEJECT_SW, val);
+
+       inputs:
+               Flag specifying auto-eject flag.
+
+
+       outputs:
+               none
+
+
+       error return:
+         - ENOSYS      Drive is not capable of ejecting.
+         - EBUSY       Door is locked
+
+
+
+
+CDROMMULTISESSION
+       Obtain the start-of-last-session address of multi session disks
+
+       (struct cdrom_multisession)
+
+       usage::
+
+         struct cdrom_multisession ms_info;
+
+         ioctl(fd, CDROMMULTISESSION, &ms_info);
+
+       inputs:
+               cdrom_multisession structure containing desired
+
+         format.
+
+       outputs:
+               cdrom_multisession structure is filled with last_session
+               information.
+
+       error return:
+         - EINVAL      format not CDROM_MSF or CDROM_LBA
+
+
+CDROM_GET_MCN
+       Obtain the "Universal Product Code"
+       if available
+
+       (struct cdrom_mcn)
+
+
+       usage::
+
+         struct cdrom_mcn mcn;
+
+         ioctl(fd, CDROM_GET_MCN, &mcn);
+
+       inputs:
+               none
+
+
+       outputs:
+               Universal Product Code
+
+
+       error return:
+         - ENOSYS      Drive is not capable of reading MCN data.
+
+       notes:
+               - Source code comments state::
+
+                   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!
+
+
+
+
+CDROM_GET_UPC
+       CDROM_GET_MCN  (deprecated)
+
+
+       Not implemented, as of 2.6.8.1
+
+
+
+CDROMRESET
+       hard-reset the drive
+
+
+       usage::
+
+         ioctl(fd, CDROMRESET, 0);
+
+
+       inputs:
+               none
+
+
+       outputs:
+               none
+
+
+       error return:
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - ENOSYS      Drive is not capable of resetting.
+
+
+
+
+CDROMREADCOOKED
+       read data in cooked mode
+
+
+       usage::
+
+         u8 buffer[CD_FRAMESIZE]
+
+         ioctl(fd, CDROMREADCOOKED, buffer);
+
+       inputs:
+               none
+
+
+       outputs:
+               2048 bytes of data, "cooked" mode.
+
+
+       notes:
+               Not implemented on all drives.
+
+
+
+
+
+CDROMREADALL
+       read all 2646 bytes
+
+
+       Same as CDROMREADCOOKED, but reads 2646 bytes.
+
+
+
+CDROMSEEK
+       seek msf address
+
+
+       usage::
+
+         struct cdrom_msf msf;
+
+         ioctl(fd, CDROMSEEK, &msf);
+
+       inputs:
+               MSF address to seek to.
+
+
+       outputs:
+               none
+
+
+
+
+CDROMPLAYBLK
+       scsi-cd only
+
+       (struct cdrom_blk)
+
+
+       usage::
+
+         struct cdrom_blk blk;
+
+         ioctl(fd, CDROMPLAYBLK, &blk);
+
+       inputs:
+               Region to play
+
+
+       outputs:
+               none
+
+
+
+
+CDROMGETSPINDOWN
+       usage::
+
+         char spindown;
+
+         ioctl(fd, CDROMGETSPINDOWN, &spindown);
+
+       inputs:
+               none
+
+
+       outputs:
+               The value of the current 4-bit spindown value.
+
+
+
+
+
+CDROMSETSPINDOWN
+       usage::
+
+         char spindown
+
+         ioctl(fd, CDROMSETSPINDOWN, &spindown);
+
+       inputs:
+               4-bit value used to control spindown (TODO: more detail here)
+
+
+       outputs:
+               none
+
+
+
+
+
+
+CDROM_SET_OPTIONS
+       Set behavior options
+
+
+       usage::
+
+         int options;
+
+         ioctl(fd, CDROM_SET_OPTIONS, options);
+
+       inputs:
+               New values for drive options.  The logical 'or' of:
+
+           ==============      ==================================
+           CDO_AUTO_CLOSE      close tray on first open(2)
+           CDO_AUTO_EJECT      open tray on last release
+           CDO_USE_FFLAGS      use O_NONBLOCK information on open
+           CDO_LOCK            lock tray on open files
+           CDO_CHECK_TYPE      check type on open for data
+           ==============      ==================================
+
+       outputs:
+               Returns the resulting options settings in the
+               ioctl return value.  Returns -1 on error.
+
+       error return:
+         - ENOSYS      selected option(s) not supported by drive.
+
+
+
+
+CDROM_CLEAR_OPTIONS
+       Clear behavior options
+
+
+       Same as CDROM_SET_OPTIONS, except that selected options are
+       turned off.
+
+
+
+CDROM_SELECT_SPEED
+       Set the CD-ROM speed
+
+
+       usage::
+
+         int speed;
+
+         ioctl(fd, CDROM_SELECT_SPEED, speed);
+
+       inputs:
+               New drive speed.
+
+
+       outputs:
+               none
+
+
+       error return:
+         - ENOSYS      speed selection not supported by drive.
+
+
+
+CDROM_SELECT_DISC
+       Select disc (for juke-boxes)
+
+
+       usage::
+
+         int disk;
+
+         ioctl(fd, CDROM_SELECT_DISC, disk);
+
+       inputs:
+               Disk to load into drive.
+
+
+       outputs:
+               none
+
+
+       error return:
+         - EINVAL      Disk number beyond capacity of drive
+
+
+
+CDROM_MEDIA_CHANGED
+       Check is media changed
+
+
+       usage::
+
+         int slot;
+
+         ioctl(fd, CDROM_MEDIA_CHANGED, slot);
+
+       inputs:
+               Slot number to be tested, always zero except for jukeboxes.
+
+               May also be special values CDSL_NONE or CDSL_CURRENT
+
+       outputs:
+               Ioctl return value is 0 or 1 depending on whether the media
+
+         has been changed, or -1 on error.
+
+       error returns:
+         - ENOSYS      Drive can't detect media change
+         - EINVAL      Slot number beyond capacity of drive
+         - ENOMEM      Out of memory
+
+
+
+CDROM_DRIVE_STATUS
+       Get tray position, etc.
+
+
+       usage::
+
+         int slot;
+
+         ioctl(fd, CDROM_DRIVE_STATUS, slot);
+
+       inputs:
+               Slot number to be tested, always zero except for jukeboxes.
+
+               May also be special values CDSL_NONE or CDSL_CURRENT
+
+       outputs:
+               Ioctl return value will be one of the following values
+
+         from <linux/cdrom.h>:
+
+           =================== ==========================
+           CDS_NO_INFO         Information not available.
+           CDS_NO_DISC
+           CDS_TRAY_OPEN
+           CDS_DRIVE_NOT_READY
+           CDS_DISC_OK
+           -1                  error
+           =================== ==========================
+
+       error returns:
+         - ENOSYS      Drive can't detect drive status
+         - EINVAL      Slot number beyond capacity of drive
+         - ENOMEM      Out of memory
+
+
+
+
+CDROM_DISC_STATUS
+       Get disc type, etc.
+
+
+       usage::
+
+         ioctl(fd, CDROM_DISC_STATUS, 0);
+
+
+       inputs:
+               none
+
+
+       outputs:
+               Ioctl return value will be one of the following values
+
+         from <linux/cdrom.h>:
+
+           - CDS_NO_INFO
+           - CDS_AUDIO
+           - CDS_MIXED
+           - CDS_XA_2_2
+           - CDS_XA_2_1
+           - CDS_DATA_1
+
+       error returns:
+               none at present
+
+       notes:
+           - Source code comments state::
+
+
+               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
+
+
+
+
+CDROM_CHANGER_NSLOTS
+       Get number of slots
+
+
+       usage::
+
+         ioctl(fd, CDROM_CHANGER_NSLOTS, 0);
+
+
+       inputs:
+               none
+
+
+       outputs:
+               The ioctl return value will be the number of slots in a
+               CD changer.  Typically 1 for non-multi-disk devices.
+
+       error returns:
+               none
+
+
+
+CDROM_LOCKDOOR
+       lock or unlock door
+
+
+       usage::
+
+         int lock;
+
+         ioctl(fd, CDROM_LOCKDOOR, lock);
+
+       inputs:
+               Door lock flag, 1=lock, 0=unlock
+
+
+       outputs:
+               none
+
+
+       error returns:
+         - EDRIVE_CANT_DO_THIS
+
+                               Door lock function not supported.
+         - EBUSY
+
+                               Attempt to unlock when multiple users
+                               have the drive open and not CAP_SYS_ADMIN
+
+       notes:
+               As of 2.6.8.1, the lock flag is a global lock, meaning that
+               all CD drives will be locked or unlocked together.  This is
+               probably a bug.
+
+               The EDRIVE_CANT_DO_THIS value is defined in <linux/cdrom.h>
+               and is currently (2.6.8.1) the same as EOPNOTSUPP
+
+
+
+CDROM_DEBUG
+       Turn debug messages on/off
+
+
+       usage::
+
+         int debug;
+
+         ioctl(fd, CDROM_DEBUG, debug);
+
+       inputs:
+               Cdrom debug flag, 0=disable, 1=enable
+
+
+       outputs:
+               The ioctl return value will be the new debug flag.
+
+
+       error return:
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+
+
+
+CDROM_GET_CAPABILITY
+       get capabilities
+
+
+       usage::
+
+         ioctl(fd, CDROM_GET_CAPABILITY, 0);
+
+
+       inputs:
+               none
+
+
+       outputs:
+               The ioctl return value is the current device capability
+               flags.  See CDC_CLOSE_TRAY, CDC_OPEN_TRAY, etc.
+
+
+
+CDROMAUDIOBUFSIZ
+       set the audio buffer size
+
+
+       usage::
+
+         int arg;
+
+         ioctl(fd, CDROMAUDIOBUFSIZ, val);
+
+       inputs:
+               New audio buffer size
+
+
+       outputs:
+               The ioctl return value is the new audio buffer size, or -1
+               on error.
+
+       error return:
+         - ENOSYS      Not supported by this driver.
+
+       notes:
+               Not supported by all drivers.
+
+
+
+
+DVD_READ_STRUCT                        Read structure
+
+       usage::
+
+         dvd_struct s;
+
+         ioctl(fd, DVD_READ_STRUCT, &s);
+
+       inputs:
+               dvd_struct structure, containing:
+
+           =================== ==========================================
+           type                specifies the information desired, one of
+                               DVD_STRUCT_PHYSICAL, DVD_STRUCT_COPYRIGHT,
+                               DVD_STRUCT_DISCKEY, DVD_STRUCT_BCA,
+                               DVD_STRUCT_MANUFACT
+           physical.layer_num  desired layer, indexed from 0
+           copyright.layer_num desired layer, indexed from 0
+           disckey.agid
+           =================== ==========================================
+
+       outputs:
+               dvd_struct structure, containing:
+
+           =================== ================================
+           physical            for type == DVD_STRUCT_PHYSICAL
+           copyright           for type == DVD_STRUCT_COPYRIGHT
+           disckey.value       for type == DVD_STRUCT_DISCKEY
+           bca.{len,value}     for type == DVD_STRUCT_BCA
+           manufact.{len,valu} for type == DVD_STRUCT_MANUFACT
+           =================== ================================
+
+       error returns:
+         - EINVAL      physical.layer_num exceeds number of layers
+         - EIO         Received invalid response from drive
+
+
+
+DVD_WRITE_STRUCT               Write structure
+
+       Not implemented, as of 2.6.8.1
+
+
+
+DVD_AUTH                       Authentication
+
+       usage::
+
+         dvd_authinfo ai;
+
+         ioctl(fd, DVD_AUTH, &ai);
+
+       inputs:
+               dvd_authinfo structure.  See <linux/cdrom.h>
+
+
+       outputs:
+               dvd_authinfo structure.
+
+
+       error return:
+         - ENOTTY      ai.type not recognized.
+
+
+
+CDROM_SEND_PACKET
+       send a packet to the drive
+
+
+       usage::
+
+         struct cdrom_generic_command cgc;
+
+         ioctl(fd, CDROM_SEND_PACKET, &cgc);
+
+       inputs:
+               cdrom_generic_command structure containing the packet to send.
+
+
+       outputs:
+               none
+
+         cdrom_generic_command structure containing results.
+
+       error return:
+         - EIO
+
+                       command failed.
+         - EPERM
+
+                       Operation not permitted, either because a
+                       write command was attempted on a drive which
+                       is opened read-only, or because the command
+                       requires CAP_SYS_RAWIO
+         - EINVAL
+
+                       cgc.data_direction not set
+
+
+
+CDROM_NEXT_WRITABLE
+       get next writable block
+
+
+       usage::
+
+         long next;
+
+         ioctl(fd, CDROM_NEXT_WRITABLE, &next);
+
+       inputs:
+               none
+
+
+       outputs:
+               The next writable block.
+
+
+       notes:
+               If the device does not support this ioctl directly, the
+
+         ioctl will return CDROM_LAST_WRITTEN + 7.
+
+
+
+CDROM_LAST_WRITTEN
+       get last block written on disc
+
+
+       usage::
+
+         long last;
+
+         ioctl(fd, CDROM_LAST_WRITTEN, &last);
+
+       inputs:
+               none
+
+
+       outputs:
+               The last block written on disc
+
+
+       notes:
+               If the device does not support this ioctl directly, the
+               result is derived from the disc's table of contents.  If the
+               table of contents can't be read, this ioctl returns an
+               error.
diff --git a/Documentation/ioctl/cdrom.txt b/Documentation/ioctl/cdrom.txt
deleted file mode 100644 (file)
index a4d62a9..0000000
+++ /dev/null
@@ -1,967 +0,0 @@
-               Summary of CDROM ioctl calls.
-               ============================
-
-               Edward A. Falk <efalk@google.com>
-
-               November, 2004
-
-This document attempts to describe the ioctl(2) calls supported by
-the CDROM layer.  These are by-and-large implemented (as of Linux 2.6)
-in drivers/cdrom/cdrom.c and drivers/block/scsi_ioctl.c
-
-ioctl values are listed in <linux/cdrom.h>.  As of this writing, they
-are as follows:
-
-       CDROMPAUSE              Pause Audio Operation
-       CDROMRESUME             Resume paused Audio Operation
-       CDROMPLAYMSF            Play Audio MSF (struct cdrom_msf)
-       CDROMPLAYTRKIND         Play Audio Track/index (struct cdrom_ti)
-       CDROMREADTOCHDR         Read TOC header (struct cdrom_tochdr)
-       CDROMREADTOCENTRY       Read TOC entry (struct cdrom_tocentry)
-       CDROMSTOP               Stop the cdrom drive
-       CDROMSTART              Start the cdrom drive
-       CDROMEJECT              Ejects the cdrom media
-       CDROMVOLCTRL            Control output volume (struct cdrom_volctrl)
-       CDROMSUBCHNL            Read subchannel data (struct cdrom_subchnl)
-       CDROMREADMODE2          Read CDROM mode 2 data (2336 Bytes)
-                                          (struct cdrom_read)
-       CDROMREADMODE1          Read CDROM mode 1 data (2048 Bytes)
-                                          (struct cdrom_read)
-       CDROMREADAUDIO          (struct cdrom_read_audio)
-       CDROMEJECT_SW           enable(1)/disable(0) auto-ejecting
-       CDROMMULTISESSION       Obtain the start-of-last-session
-                                 address of multi session disks
-                                 (struct cdrom_multisession)
-       CDROM_GET_MCN           Obtain the "Universal Product Code"
-                                  if available (struct cdrom_mcn)
-       CDROM_GET_UPC           Deprecated, use CDROM_GET_MCN instead.
-       CDROMRESET              hard-reset the drive
-       CDROMVOLREAD            Get the drive's volume setting
-                                         (struct cdrom_volctrl)
-       CDROMREADRAW            read data in raw mode (2352 Bytes)
-                                          (struct cdrom_read)
-       CDROMREADCOOKED         read data in cooked mode
-       CDROMSEEK               seek msf address
-       CDROMPLAYBLK            scsi-cd only, (struct cdrom_blk)
-       CDROMREADALL            read all 2646 bytes
-       CDROMGETSPINDOWN        return 4-bit spindown value
-       CDROMSETSPINDOWN        set 4-bit spindown value
-       CDROMCLOSETRAY          pendant of CDROMEJECT
-       CDROM_SET_OPTIONS       Set behavior options
-       CDROM_CLEAR_OPTIONS     Clear behavior options
-       CDROM_SELECT_SPEED      Set the CD-ROM speed
-       CDROM_SELECT_DISC       Select disc (for juke-boxes)
-       CDROM_MEDIA_CHANGED     Check is media changed
-       CDROM_DRIVE_STATUS      Get tray position, etc.
-       CDROM_DISC_STATUS       Get disc type, etc.
-       CDROM_CHANGER_NSLOTS    Get number of slots
-       CDROM_LOCKDOOR          lock or unlock door
-       CDROM_DEBUG             Turn debug messages on/off
-       CDROM_GET_CAPABILITY    get capabilities
-       CDROMAUDIOBUFSIZ        set the audio buffer size
-       DVD_READ_STRUCT         Read structure
-       DVD_WRITE_STRUCT        Write structure
-       DVD_AUTH                Authentication
-       CDROM_SEND_PACKET       send a packet to the drive
-       CDROM_NEXT_WRITABLE     get next writable block
-       CDROM_LAST_WRITTEN      get last block written on disc
-
-
-The information that follows was determined from reading kernel source
-code.  It is likely that some corrections will be made over time.
-
-
-
-
-
-
-
-General:
-
-       Unless otherwise specified, all ioctl calls return 0 on success
-       and -1 with errno set to an appropriate value on error.  (Some
-       ioctls return non-negative data values.)
-
-       Unless otherwise specified, all ioctl calls return -1 and set
-       errno to EFAULT on a failed attempt to copy data to or from user
-       address space.
-
-       Individual drivers may return error codes not listed here.
-
-       Unless otherwise specified, all data structures and constants
-       are defined in <linux/cdrom.h>
-
-
-
-
-CDROMPAUSE                     Pause Audio Operation
-
-       usage:
-
-         ioctl(fd, CDROMPAUSE, 0);
-
-       inputs:         none
-
-       outputs:        none
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-
-
-CDROMRESUME                    Resume paused Audio Operation
-
-       usage:
-
-         ioctl(fd, CDROMRESUME, 0);
-
-       inputs:         none
-
-       outputs:        none
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-
-
-CDROMPLAYMSF                   Play Audio MSF (struct cdrom_msf)
-
-       usage:
-
-         struct cdrom_msf msf;
-         ioctl(fd, CDROMPLAYMSF, &msf);
-
-       inputs:
-         cdrom_msf structure, describing a segment of music to play
-
-       outputs:        none
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-
-       notes:
-         MSF stands for minutes-seconds-frames
-         LBA stands for logical block address
-
-         Segment is described as start and end times, where each time
-         is described as minutes:seconds:frames.  A frame is 1/75 of
-         a second.
-
-
-CDROMPLAYTRKIND                        Play Audio Track/index (struct cdrom_ti)
-
-       usage:
-
-         struct cdrom_ti ti;
-         ioctl(fd, CDROMPLAYTRKIND, &ti);
-
-       inputs:
-         cdrom_ti structure, describing a segment of music to play
-
-       outputs:        none
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-
-       notes:
-         Segment is described as start and end times, where each time
-         is described as a track and an index.
-
-
-
-CDROMREADTOCHDR                        Read TOC header (struct cdrom_tochdr)
-
-       usage:
-
-         cdrom_tochdr header;
-         ioctl(fd, CDROMREADTOCHDR, &header);
-
-       inputs:
-         cdrom_tochdr structure
-
-       outputs:
-         cdrom_tochdr structure
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-
-
-
-CDROMREADTOCENTRY              Read TOC entry (struct cdrom_tocentry)
-
-       usage:
-
-         struct cdrom_tocentry entry;
-         ioctl(fd, CDROMREADTOCENTRY, &entry);
-
-       inputs:
-         cdrom_tocentry structure
-
-       outputs:
-         cdrom_tocentry structure
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-         EINVAL        entry.cdte_format not CDROM_MSF or CDROM_LBA
-         EINVAL        requested track out of bounds
-         EIO           I/O error reading TOC
-
-       notes:
-         TOC stands for Table Of Contents
-         MSF stands for minutes-seconds-frames
-         LBA stands for logical block address
-
-
-
-CDROMSTOP                      Stop the cdrom drive
-
-       usage:
-
-         ioctl(fd, CDROMSTOP, 0);
-
-       inputs:         none
-
-       outputs:        none
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-
-       notes:
-         Exact interpretation of this ioctl depends on the device,
-         but most seem to spin the drive down.
-
-
-CDROMSTART                     Start the cdrom drive
-
-       usage:
-
-         ioctl(fd, CDROMSTART, 0);
-
-       inputs:         none
-
-       outputs:        none
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-
-       notes:
-         Exact interpretation of this ioctl depends on the device,
-         but most seem to spin the drive up and/or close the tray.
-         Other devices ignore the ioctl completely.
-
-
-CDROMEJECT                     Ejects the cdrom media
-
-       usage:
-
-         ioctl(fd, CDROMEJECT, 0);
-
-       inputs:         none
-
-       outputs:        none
-
-       error returns:
-         ENOSYS        cd drive not capable of ejecting
-         EBUSY         other processes are accessing drive, or door is locked
-
-       notes:
-         See CDROM_LOCKDOOR, below.
-
-
-
-CDROMCLOSETRAY                 pendant of CDROMEJECT
-
-       usage:
-
-         ioctl(fd, CDROMCLOSETRAY, 0);
-
-       inputs:         none
-
-       outputs:        none
-
-       error returns:
-         ENOSYS        cd drive not capable of closing the tray
-         EBUSY         other processes are accessing drive, or door is locked
-
-       notes:
-         See CDROM_LOCKDOOR, below.
-
-
-
-CDROMVOLCTRL                   Control output volume (struct cdrom_volctrl)
-
-       usage:
-
-         struct cdrom_volctrl volume;
-         ioctl(fd, CDROMVOLCTRL, &volume);
-
-       inputs:
-         cdrom_volctrl structure containing volumes for up to 4
-         channels.
-
-       outputs:        none
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-
-
-
-CDROMVOLREAD                   Get the drive's volume setting
-                                         (struct cdrom_volctrl)
-
-       usage:
-
-         struct cdrom_volctrl volume;
-         ioctl(fd, CDROMVOLREAD, &volume);
-
-       inputs:         none
-
-       outputs:
-         The current volume settings.
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-
-
-
-CDROMSUBCHNL                   Read subchannel data (struct cdrom_subchnl)
-
-       usage:
-
-         struct cdrom_subchnl q;
-         ioctl(fd, CDROMSUBCHNL, &q);
-
-       inputs:
-         cdrom_subchnl structure
-
-       outputs:
-         cdrom_subchnl structure
-
-       error return:
-         ENOSYS        cd drive not audio-capable.
-         EINVAL        format not CDROM_MSF or CDROM_LBA
-
-       notes:
-         Format is converted to CDROM_MSF or CDROM_LBA
-         as per user request on return
-
-
-
-CDROMREADRAW                   read data in raw mode (2352 Bytes)
-                                          (struct cdrom_read)
-
-       usage:
-
-         union {
-           struct cdrom_msf msf;               /* input */
-           char buffer[CD_FRAMESIZE_RAW];      /* return */
-         } arg;
-         ioctl(fd, CDROMREADRAW, &arg);
-
-       inputs:
-         cdrom_msf structure indicating an address to read.
-         Only the start values are significant.
-
-       outputs:
-         Data written to address provided by user.
-
-       error return:
-         EINVAL        address less than 0, or msf less than 0:2:0
-         ENOMEM        out of memory
-
-       notes:
-         As of 2.6.8.1, comments in <linux/cdrom.h> indicate that this
-         ioctl accepts a cdrom_read structure, but actual source code
-         reads a cdrom_msf structure and writes a buffer of data to
-         the same address.
-
-         MSF values are converted to LBA values via this formula:
-
-           lba = (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
-
-
-
-
-CDROMREADMODE1                 Read CDROM mode 1 data (2048 Bytes)
-                                          (struct cdrom_read)
-
-       notes:
-         Identical to CDROMREADRAW except that block size is
-         CD_FRAMESIZE (2048) bytes
-
-
-
-CDROMREADMODE2                 Read CDROM mode 2 data (2336 Bytes)
-                                          (struct cdrom_read)
-
-       notes:
-         Identical to CDROMREADRAW except that block size is
-         CD_FRAMESIZE_RAW0 (2336) bytes
-
-
-
-CDROMREADAUDIO                 (struct cdrom_read_audio)
-
-       usage:
-
-         struct cdrom_read_audio ra;
-         ioctl(fd, CDROMREADAUDIO, &ra);
-
-       inputs:
-         cdrom_read_audio structure containing read start
-         point and length
-
-       outputs:
-         audio data, returned to buffer indicated by ra
-
-       error return:
-         EINVAL        format not CDROM_MSF or CDROM_LBA
-         EINVAL        nframes not in range [1 75]
-         ENXIO         drive has no queue (probably means invalid fd)
-         ENOMEM        out of memory
-
-
-CDROMEJECT_SW                  enable(1)/disable(0) auto-ejecting
-
-       usage:
-
-         int val;
-         ioctl(fd, CDROMEJECT_SW, val);
-
-       inputs:
-         Flag specifying auto-eject flag.
-
-       outputs:        none
-
-       error return:
-         ENOSYS        Drive is not capable of ejecting.
-         EBUSY         Door is locked
-
-
-
-
-CDROMMULTISESSION              Obtain the start-of-last-session
-                                 address of multi session disks
-                                 (struct cdrom_multisession)
-       usage:
-
-         struct cdrom_multisession ms_info;
-         ioctl(fd, CDROMMULTISESSION, &ms_info);
-
-       inputs:
-         cdrom_multisession structure containing desired
-         format.
-
-       outputs:
-         cdrom_multisession structure is filled with last_session
-         information.
-
-       error return:
-         EINVAL        format not CDROM_MSF or CDROM_LBA
-
-
-CDROM_GET_MCN                  Obtain the "Universal Product Code"
-                                  if available (struct cdrom_mcn)
-
-       usage:
-
-         struct cdrom_mcn mcn;
-         ioctl(fd, CDROM_GET_MCN, &mcn);
-
-       inputs:         none
-
-       outputs:
-         Universal Product Code
-
-       error return:
-         ENOSYS        Drive is not capable of reading MCN data.
-
-       notes:
-         Source code comments state:
-
-           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!
-
-
-
-
-CDROM_GET_UPC                  CDROM_GET_MCN  (deprecated)
-
-       Not implemented, as of 2.6.8.1
-
-
-
-CDROMRESET                     hard-reset the drive
-
-       usage:
-
-         ioctl(fd, CDROMRESET, 0);
-
-       inputs:         none
-
-       outputs:        none
-
-       error return:
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         ENOSYS        Drive is not capable of resetting.
-
-
-
-
-CDROMREADCOOKED                        read data in cooked mode
-
-       usage:
-
-         u8 buffer[CD_FRAMESIZE]
-         ioctl(fd, CDROMREADCOOKED, buffer);
-
-       inputs:         none
-
-       outputs:
-         2048 bytes of data, "cooked" mode.
-
-       notes:
-         Not implemented on all drives.
-
-
-
-
-CDROMREADALL                   read all 2646 bytes
-
-       Same as CDROMREADCOOKED, but reads 2646 bytes.
-
-
-
-CDROMSEEK                      seek msf address
-
-       usage:
-
-         struct cdrom_msf msf;
-         ioctl(fd, CDROMSEEK, &msf);
-
-       inputs:
-         MSF address to seek to.
-
-       outputs:        none
-
-
-
-CDROMPLAYBLK                   scsi-cd only, (struct cdrom_blk)
-
-       usage:
-
-         struct cdrom_blk blk;
-         ioctl(fd, CDROMPLAYBLK, &blk);
-
-       inputs:
-         Region to play
-
-       outputs:        none
-
-
-
-CDROMGETSPINDOWN
-
-       usage:
-
-         char spindown;
-         ioctl(fd, CDROMGETSPINDOWN, &spindown);
-
-       inputs:         none
-
-       outputs:
-         The value of the current 4-bit spindown value.
-
-
-
-
-CDROMSETSPINDOWN
-
-       usage:
-
-         char spindown
-         ioctl(fd, CDROMSETSPINDOWN, &spindown);
-
-       inputs:
-         4-bit value used to control spindown (TODO: more detail here)
-
-       outputs:        none
-
-
-
-
-
-CDROM_SET_OPTIONS              Set behavior options
-
-       usage:
-
-         int options;
-         ioctl(fd, CDROM_SET_OPTIONS, options);
-
-       inputs:
-         New values for drive options.  The logical 'or' of:
-           CDO_AUTO_CLOSE      close tray on first open(2)
-           CDO_AUTO_EJECT      open tray on last release
-           CDO_USE_FFLAGS      use O_NONBLOCK information on open
-           CDO_LOCK            lock tray on open files
-           CDO_CHECK_TYPE      check type on open for data
-
-       outputs:
-         Returns the resulting options settings in the
-         ioctl return value.  Returns -1 on error.
-
-       error return:
-         ENOSYS        selected option(s) not supported by drive.
-
-
-
-
-CDROM_CLEAR_OPTIONS            Clear behavior options
-
-       Same as CDROM_SET_OPTIONS, except that selected options are
-       turned off.
-
-
-
-CDROM_SELECT_SPEED             Set the CD-ROM speed
-
-       usage:
-
-         int speed;
-         ioctl(fd, CDROM_SELECT_SPEED, speed);
-
-       inputs:
-         New drive speed.
-
-       outputs:        none
-
-       error return:
-         ENOSYS        speed selection not supported by drive.
-
-
-
-CDROM_SELECT_DISC              Select disc (for juke-boxes)
-
-       usage:
-
-         int disk;
-         ioctl(fd, CDROM_SELECT_DISC, disk);
-
-       inputs:
-         Disk to load into drive.
-
-       outputs:        none
-
-       error return:
-         EINVAL        Disk number beyond capacity of drive
-
-
-
-CDROM_MEDIA_CHANGED            Check is media changed
-
-       usage:
-
-         int slot;
-         ioctl(fd, CDROM_MEDIA_CHANGED, slot);
-
-       inputs:
-         Slot number to be tested, always zero except for jukeboxes.
-         May also be special values CDSL_NONE or CDSL_CURRENT
-
-       outputs:
-         Ioctl return value is 0 or 1 depending on whether the media
-         has been changed, or -1 on error.
-
-       error returns:
-         ENOSYS        Drive can't detect media change
-         EINVAL        Slot number beyond capacity of drive
-         ENOMEM        Out of memory
-
-
-
-CDROM_DRIVE_STATUS             Get tray position, etc.
-
-       usage:
-
-         int slot;
-         ioctl(fd, CDROM_DRIVE_STATUS, slot);
-
-       inputs:
-         Slot number to be tested, always zero except for jukeboxes.
-         May also be special values CDSL_NONE or CDSL_CURRENT
-
-       outputs:
-         Ioctl return value will be one of the following values
-         from <linux/cdrom.h>:
-
-           CDS_NO_INFO         Information not available.
-           CDS_NO_DISC
-           CDS_TRAY_OPEN
-           CDS_DRIVE_NOT_READY
-           CDS_DISC_OK
-           -1                  error
-
-       error returns:
-         ENOSYS        Drive can't detect drive status
-         EINVAL        Slot number beyond capacity of drive
-         ENOMEM        Out of memory
-
-
-
-
-CDROM_DISC_STATUS              Get disc type, etc.
-
-       usage:
-
-         ioctl(fd, CDROM_DISC_STATUS, 0);
-
-       inputs:         none
-
-       outputs:
-         Ioctl return value will be one of the following values
-         from <linux/cdrom.h>:
-           CDS_NO_INFO
-           CDS_AUDIO
-           CDS_MIXED
-           CDS_XA_2_2
-           CDS_XA_2_1
-           CDS_DATA_1
-
-       error returns:  none at present
-
-       notes:
-         Source code comments state:
-
-           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
-
-
-
-
-CDROM_CHANGER_NSLOTS           Get number of slots
-
-       usage:
-
-         ioctl(fd, CDROM_CHANGER_NSLOTS, 0);
-
-       inputs:         none
-
-       outputs:
-         The ioctl return value will be the number of slots in a
-         CD changer.  Typically 1 for non-multi-disk devices.
-
-       error returns:  none
-
-
-
-CDROM_LOCKDOOR                 lock or unlock door
-
-       usage:
-
-         int lock;
-         ioctl(fd, CDROM_LOCKDOOR, lock);
-
-       inputs:
-         Door lock flag, 1=lock, 0=unlock
-
-       outputs:        none
-
-       error returns:
-         EDRIVE_CANT_DO_THIS   Door lock function not supported.
-         EBUSY                 Attempt to unlock when multiple users
-                               have the drive open and not CAP_SYS_ADMIN
-
-       notes:
-         As of 2.6.8.1, the lock flag is a global lock, meaning that
-         all CD drives will be locked or unlocked together.  This is
-         probably a bug.
-
-         The EDRIVE_CANT_DO_THIS value is defined in <linux/cdrom.h>
-         and is currently (2.6.8.1) the same as EOPNOTSUPP
-
-
-
-CDROM_DEBUG                    Turn debug messages on/off
-
-       usage:
-
-         int debug;
-         ioctl(fd, CDROM_DEBUG, debug);
-
-       inputs:
-         Cdrom debug flag, 0=disable, 1=enable
-
-       outputs:
-         The ioctl return value will be the new debug flag.
-
-       error return:
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-
-
-
-CDROM_GET_CAPABILITY           get capabilities
-
-       usage:
-
-         ioctl(fd, CDROM_GET_CAPABILITY, 0);
-
-       inputs:         none
-
-       outputs:
-         The ioctl return value is the current device capability
-         flags.  See CDC_CLOSE_TRAY, CDC_OPEN_TRAY, etc.
-
-
-
-CDROMAUDIOBUFSIZ               set the audio buffer size
-
-       usage:
-
-         int arg;
-         ioctl(fd, CDROMAUDIOBUFSIZ, val);
-
-       inputs:
-         New audio buffer size
-
-       outputs:
-         The ioctl return value is the new audio buffer size, or -1
-         on error.
-
-       error return:
-         ENOSYS        Not supported by this driver.
-
-       notes:
-         Not supported by all drivers.
-
-
-
-DVD_READ_STRUCT                        Read structure
-
-       usage:
-
-         dvd_struct s;
-         ioctl(fd, DVD_READ_STRUCT, &s);
-
-       inputs:
-         dvd_struct structure, containing:
-           type                specifies the information desired, one of
-                               DVD_STRUCT_PHYSICAL, DVD_STRUCT_COPYRIGHT,
-                               DVD_STRUCT_DISCKEY, DVD_STRUCT_BCA,
-                               DVD_STRUCT_MANUFACT
-           physical.layer_num  desired layer, indexed from 0
-           copyright.layer_num desired layer, indexed from 0
-           disckey.agid
-
-       outputs:
-         dvd_struct structure, containing:
-           physical            for type == DVD_STRUCT_PHYSICAL
-           copyright           for type == DVD_STRUCT_COPYRIGHT
-           disckey.value       for type == DVD_STRUCT_DISCKEY
-           bca.{len,value}     for type == DVD_STRUCT_BCA
-           manufact.{len,valu} for type == DVD_STRUCT_MANUFACT
-
-       error returns:
-         EINVAL        physical.layer_num exceeds number of layers
-         EIO           Received invalid response from drive
-
-
-
-DVD_WRITE_STRUCT               Write structure
-
-       Not implemented, as of 2.6.8.1
-
-
-
-DVD_AUTH                       Authentication
-
-       usage:
-
-         dvd_authinfo ai;
-         ioctl(fd, DVD_AUTH, &ai);
-
-       inputs:
-         dvd_authinfo structure.  See <linux/cdrom.h>
-
-       outputs:
-         dvd_authinfo structure.
-
-       error return:
-         ENOTTY        ai.type not recognized.
-
-
-
-CDROM_SEND_PACKET              send a packet to the drive
-
-       usage:
-
-         struct cdrom_generic_command cgc;
-         ioctl(fd, CDROM_SEND_PACKET, &cgc);
-
-       inputs:
-         cdrom_generic_command structure containing the packet to send.
-
-       outputs:        none
-         cdrom_generic_command structure containing results.
-
-       error return:
-         EIO           command failed.
-         EPERM         Operation not permitted, either because a
-                       write command was attempted on a drive which
-                       is opened read-only, or because the command
-                       requires CAP_SYS_RAWIO
-         EINVAL        cgc.data_direction not set
-
-
-
-CDROM_NEXT_WRITABLE            get next writable block
-
-       usage:
-
-         long next;
-         ioctl(fd, CDROM_NEXT_WRITABLE, &next);
-
-       inputs:         none
-
-       outputs:
-         The next writable block.
-
-       notes:
-         If the device does not support this ioctl directly, the
-         ioctl will return CDROM_LAST_WRITTEN + 7.
-
-
-
-CDROM_LAST_WRITTEN             get last block written on disc
-
-       usage:
-
-         long last;
-         ioctl(fd, CDROM_LAST_WRITTEN, &last);
-
-       inputs:         none
-
-       outputs:
-         The last block written on disc
-
-       notes:
-         If the device does not support this ioctl directly, the
-         result is derived from the disc's table of contents.  If the
-         table of contents can't be read, this ioctl returns an
-         error.
diff --git a/Documentation/ioctl/hdio.rst b/Documentation/ioctl/hdio.rst
new file mode 100644 (file)
index 0000000..e822e3d
--- /dev/null
@@ -0,0 +1,1342 @@
+==============================
+Summary of `HDIO_` ioctl calls
+==============================
+
+- Edward A. Falk <efalk@google.com>
+
+November, 2004
+
+This document attempts to describe the ioctl(2) calls supported by
+the HD/IDE layer.  These are by-and-large implemented (as of Linux 2.6)
+in drivers/ide/ide.c and drivers/block/scsi_ioctl.c
+
+ioctl values are listed in <linux/hdreg.h>.  As of this writing, they
+are as follows:
+
+    ioctls that pass argument pointers to user space:
+
+       ======================= =======================================
+       HDIO_GETGEO             get device geometry
+       HDIO_GET_UNMASKINTR     get current unmask setting
+       HDIO_GET_MULTCOUNT      get current IDE blockmode setting
+       HDIO_GET_QDMA           get use-qdma flag
+       HDIO_SET_XFER           set transfer rate via proc
+       HDIO_OBSOLETE_IDENTITY  OBSOLETE, DO NOT USE
+       HDIO_GET_KEEPSETTINGS   get keep-settings-on-reset flag
+       HDIO_GET_32BIT          get current io_32bit setting
+       HDIO_GET_NOWERR         get ignore-write-error flag
+       HDIO_GET_DMA            get use-dma flag
+       HDIO_GET_NICE           get nice flags
+       HDIO_GET_IDENTITY       get IDE identification info
+       HDIO_GET_WCACHE         get write cache mode on|off
+       HDIO_GET_ACOUSTIC       get acoustic value
+       HDIO_GET_ADDRESS        get sector addressing mode
+       HDIO_GET_BUSSTATE       get the bus state of the hwif
+       HDIO_TRISTATE_HWIF      execute a channel tristate
+       HDIO_DRIVE_RESET        execute a device reset
+       HDIO_DRIVE_TASKFILE     execute raw taskfile
+       HDIO_DRIVE_TASK         execute task and special drive command
+       HDIO_DRIVE_CMD          execute a special drive command
+       HDIO_DRIVE_CMD_AEB      HDIO_DRIVE_TASK
+       ======================= =======================================
+
+    ioctls that pass non-pointer values:
+
+       ======================= =======================================
+       HDIO_SET_MULTCOUNT      change IDE blockmode
+       HDIO_SET_UNMASKINTR     permit other irqs during I/O
+       HDIO_SET_KEEPSETTINGS   keep ioctl settings on reset
+       HDIO_SET_32BIT          change io_32bit flags
+       HDIO_SET_NOWERR         change ignore-write-error flag
+       HDIO_SET_DMA            change use-dma flag
+       HDIO_SET_PIO_MODE       reconfig interface to new speed
+       HDIO_SCAN_HWIF          register and (re)scan interface
+       HDIO_SET_NICE           set nice flags
+       HDIO_UNREGISTER_HWIF    unregister interface
+       HDIO_SET_WCACHE         change write cache enable-disable
+       HDIO_SET_ACOUSTIC       change acoustic behavior
+       HDIO_SET_BUSSTATE       set the bus state of the hwif
+       HDIO_SET_QDMA           change use-qdma flag
+       HDIO_SET_ADDRESS        change lba addressing modes
+
+       HDIO_SET_IDE_SCSI       Set scsi emulation mode on/off
+       HDIO_SET_SCSI_IDE       not implemented yet
+       ======================= =======================================
+
+
+The information that follows was determined from reading kernel source
+code.  It is likely that some corrections will be made over time.
+
+------------------------------------------------------------------------------
+
+General:
+
+       Unless otherwise specified, all ioctl calls return 0 on success
+       and -1 with errno set to an appropriate value on error.
+
+       Unless otherwise specified, all ioctl calls return -1 and set
+       errno to EFAULT on a failed attempt to copy data to or from user
+       address space.
+
+       Unless otherwise specified, all data structures and constants
+       are defined in <linux/hdreg.h>
+
+------------------------------------------------------------------------------
+
+HDIO_GETGEO
+       get device geometry
+
+
+       usage::
+
+         struct hd_geometry geom;
+
+         ioctl(fd, HDIO_GETGEO, &geom);
+
+
+       inputs:
+               none
+
+
+
+       outputs:
+               hd_geometry structure containing:
+
+
+           =========   ==================================
+           heads       number of heads
+           sectors     number of sectors/track
+           cylinders   number of cylinders, mod 65536
+           start       starting sector of this partition.
+           =========   ==================================
+
+
+       error returns:
+         - EINVAL
+
+                       if the device is not a disk drive or floppy drive,
+                       or if the user passes a null pointer
+
+
+       notes:
+               Not particularly useful with modern disk drives, whose geometry
+               is a polite fiction anyway.  Modern drives are addressed
+               purely by sector number nowadays (lba addressing), and the
+               drive geometry is an abstraction which is actually subject
+               to change.  Currently (as of Nov 2004), the geometry values
+               are the "bios" values -- presumably the values the drive had
+               when Linux first booted.
+
+               In addition, the cylinders field of the hd_geometry is an
+               unsigned short, meaning that on most architectures, this
+               ioctl will not return a meaningful value on drives with more
+               than 65535 tracks.
+
+               The start field is unsigned long, meaning that it will not
+               contain a meaningful value for disks over 219 Gb in size.
+
+
+
+
+HDIO_GET_UNMASKINTR
+       get current unmask setting
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_GET_UNMASKINTR, &val);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               The value of the drive's current unmask setting
+
+
+
+
+
+HDIO_SET_UNMASKINTR
+       permit other irqs during I/O
+
+
+       usage::
+
+         unsigned long val;
+
+         ioctl(fd, HDIO_SET_UNMASKINTR, val);
+
+       inputs:
+               New value for unmask flag
+
+
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range [0 1]
+         - EBUSY       Controller busy
+
+
+
+
+HDIO_GET_MULTCOUNT
+       get current IDE blockmode setting
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_GET_MULTCOUNT, &val);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               The value of the current IDE block mode setting.  This
+               controls how many sectors the drive will transfer per
+               interrupt.
+
+
+
+HDIO_SET_MULTCOUNT
+       change IDE blockmode
+
+
+       usage::
+
+         int val;
+
+         ioctl(fd, HDIO_SET_MULTCOUNT, val);
+
+       inputs:
+               New value for IDE block mode setting.  This controls how many
+               sectors the drive will transfer per interrupt.
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range supported by disk.
+         - EBUSY       Controller busy or blockmode already set.
+         - EIO         Drive did not accept new block mode.
+
+       notes:
+         Source code comments read::
+
+           This is tightly woven into the driver->do_special cannot
+           touch.  DON'T do it again until a total personality rewrite
+           is committed.
+
+         If blockmode has already been set, this ioctl will fail with
+         -EBUSY
+
+
+
+HDIO_GET_QDMA
+       get use-qdma flag
+
+
+       Not implemented, as of 2.6.8.1
+
+
+
+HDIO_SET_XFER
+       set transfer rate via proc
+
+
+       Not implemented, as of 2.6.8.1
+
+
+
+HDIO_OBSOLETE_IDENTITY
+       OBSOLETE, DO NOT USE
+
+
+       Same as HDIO_GET_IDENTITY (see below), except that it only
+       returns the first 142 bytes of drive identity information.
+
+
+
+HDIO_GET_IDENTITY
+       get IDE identification info
+
+
+       usage::
+
+         unsigned char identity[512];
+
+         ioctl(fd, HDIO_GET_IDENTITY, identity);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               ATA drive identity information.  For full description, see
+               the IDENTIFY DEVICE and IDENTIFY PACKET DEVICE commands in
+               the ATA specification.
+
+       error returns:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - ENOMSG      IDENTIFY DEVICE information not available
+
+       notes:
+               Returns information that was obtained when the drive was
+               probed.  Some of this information is subject to change, and
+               this ioctl does not re-probe the drive to update the
+               information.
+
+               This information is also available from /proc/ide/hdX/identify
+
+
+
+HDIO_GET_KEEPSETTINGS
+       get keep-settings-on-reset flag
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_GET_KEEPSETTINGS, &val);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               The value of the current "keep settings" flag
+
+
+
+       notes:
+               When set, indicates that kernel should restore settings
+               after a drive reset.
+
+
+
+HDIO_SET_KEEPSETTINGS
+       keep ioctl settings on reset
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_SET_KEEPSETTINGS, val);
+
+       inputs:
+               New value for keep_settings flag
+
+
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range [0 1]
+         - EBUSY               Controller busy
+
+
+
+HDIO_GET_32BIT
+       get current io_32bit setting
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_GET_32BIT, &val);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               The value of the current io_32bit setting
+
+
+
+       notes:
+               0=16-bit, 1=32-bit, 2,3 = 32bit+sync
+
+
+
+
+
+HDIO_GET_NOWERR
+       get ignore-write-error flag
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_GET_NOWERR, &val);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               The value of the current ignore-write-error flag
+
+
+
+
+
+HDIO_GET_DMA
+       get use-dma flag
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_GET_DMA, &val);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               The value of the current use-dma flag
+
+
+
+
+
+HDIO_GET_NICE
+       get nice flags
+
+
+       usage::
+
+         long nice;
+
+         ioctl(fd, HDIO_GET_NICE, &nice);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               The drive's "nice" values.
+
+
+
+       notes:
+               Per-drive flags which determine when the system will give more
+               bandwidth to other devices sharing the same IDE bus.
+
+               See <linux/hdreg.h>, near symbol IDE_NICE_DSC_OVERLAP.
+
+
+
+
+HDIO_SET_NICE
+       set nice flags
+
+
+       usage::
+
+         unsigned long nice;
+
+         ...
+         ioctl(fd, HDIO_SET_NICE, nice);
+
+       inputs:
+               bitmask of nice flags.
+
+
+
+       outputs:
+               none
+
+
+
+       error returns:
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EPERM       Flags other than DSC_OVERLAP and NICE_1 set.
+         - EPERM       DSC_OVERLAP specified but not supported by drive
+
+       notes:
+               This ioctl sets the DSC_OVERLAP and NICE_1 flags from values
+               provided by the user.
+
+               Nice flags are listed in <linux/hdreg.h>, starting with
+               IDE_NICE_DSC_OVERLAP.  These values represent shifts.
+
+
+
+
+
+HDIO_GET_WCACHE
+       get write cache mode on|off
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_GET_WCACHE, &val);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               The value of the current write cache mode
+
+
+
+
+
+HDIO_GET_ACOUSTIC
+       get acoustic value
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_GET_ACOUSTIC, &val);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               The value of the current acoustic settings
+
+
+
+       notes:
+               See HDIO_SET_ACOUSTIC
+
+
+
+
+
+HDIO_GET_ADDRESS
+       usage::
+
+
+         long val;
+
+         ioctl(fd, HDIO_GET_ADDRESS, &val);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               The value of the current addressing mode:
+
+           =  ===================
+           0  28-bit
+           1  48-bit
+           2  48-bit doing 28-bit
+           3  64-bit
+           =  ===================
+
+
+
+HDIO_GET_BUSSTATE
+       get the bus state of the hwif
+
+
+       usage::
+
+         long state;
+
+         ioctl(fd, HDIO_SCAN_HWIF, &state);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               Current power state of the IDE bus.  One of BUSSTATE_OFF,
+               BUSSTATE_ON, or BUSSTATE_TRISTATE
+
+       error returns:
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+
+
+
+
+HDIO_SET_BUSSTATE
+       set the bus state of the hwif
+
+
+       usage::
+
+         int state;
+
+         ...
+         ioctl(fd, HDIO_SCAN_HWIF, state);
+
+       inputs:
+               Desired IDE power state.  One of BUSSTATE_OFF, BUSSTATE_ON,
+               or BUSSTATE_TRISTATE
+
+       outputs:
+               none
+
+
+
+       error returns:
+         - EACCES      Access denied:  requires CAP_SYS_RAWIO
+         - EOPNOTSUPP  Hardware interface does not support bus power control
+
+
+
+
+HDIO_TRISTATE_HWIF
+       execute a channel tristate
+
+
+       Not implemented, as of 2.6.8.1.  See HDIO_SET_BUSSTATE
+
+
+
+HDIO_DRIVE_RESET
+       execute a device reset
+
+
+       usage::
+
+         int args[3]
+
+         ...
+         ioctl(fd, HDIO_DRIVE_RESET, args);
+
+       inputs:
+               none
+
+
+
+       outputs:
+               none
+
+
+
+       error returns:
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - ENXIO       No such device: phy dead or ctl_addr == 0
+         - EIO         I/O error:      reset timed out or hardware error
+
+       notes:
+
+         - Execute a reset on the device as soon as the current IO
+           operation has completed.
+
+         - Executes an ATAPI soft reset if applicable, otherwise
+           executes an ATA soft reset on the controller.
+
+
+
+HDIO_DRIVE_TASKFILE
+       execute raw taskfile
+
+
+       Note:
+               If you don't have a copy of the ANSI ATA specification
+               handy, you should probably ignore this ioctl.
+
+       - Execute an ATA disk command directly by writing the "taskfile"
+         registers of the drive.  Requires ADMIN and RAWIO access
+         privileges.
+
+       usage::
+
+         struct {
+
+           ide_task_request_t req_task;
+           u8 outbuf[OUTPUT_SIZE];
+           u8 inbuf[INPUT_SIZE];
+         } task;
+         memset(&task.req_task, 0, sizeof(task.req_task));
+         task.req_task.out_size = sizeof(task.outbuf);
+         task.req_task.in_size = sizeof(task.inbuf);
+         ...
+         ioctl(fd, HDIO_DRIVE_TASKFILE, &task);
+         ...
+
+       inputs:
+
+         (See below for details on memory area passed to ioctl.)
+
+         ============  ===================================================
+         io_ports[8]   values to be written to taskfile registers
+         hob_ports[8]  high-order bytes, for extended commands.
+         out_flags     flags indicating which registers are valid
+         in_flags      flags indicating which registers should be returned
+         data_phase    see below
+         req_cmd       command type to be executed
+         out_size      size of output buffer
+         outbuf        buffer of data to be transmitted to disk
+         inbuf         buffer of data to be received from disk (see [1])
+         ============  ===================================================
+
+       outputs:
+
+         ===========   ====================================================
+         io_ports[]    values returned in the taskfile registers
+         hob_ports[]   high-order bytes, for extended commands.
+         out_flags     flags indicating which registers are valid (see [2])
+         in_flags      flags indicating which registers should be returned
+         outbuf        buffer of data to be transmitted to disk (see [1])
+         inbuf         buffer of data to be received from disk
+         ===========   ====================================================
+
+       error returns:
+         - EACCES      CAP_SYS_ADMIN or CAP_SYS_RAWIO privilege not set.
+         - ENOMSG      Device is not a disk drive.
+         - ENOMEM      Unable to allocate memory for task
+         - EFAULT      req_cmd == TASKFILE_IN_OUT (not implemented as of 2.6.8)
+         - EPERM
+
+                       req_cmd == TASKFILE_MULTI_OUT and drive
+                       multi-count not yet set.
+         - EIO         Drive failed the command.
+
+       notes:
+
+         [1] READ THE FOLLOWING NOTES *CAREFULLY*.  THIS IOCTL IS
+         FULL OF GOTCHAS.  Extreme caution should be used with using
+         this ioctl.  A mistake can easily corrupt data or hang the
+         system.
+
+         [2] Both the input and output buffers are copied from the
+         user and written back to the user, even when not used.
+
+         [3] If one or more bits are set in out_flags and in_flags is
+         zero, the following values are used for in_flags.all and
+         written back into in_flags on completion.
+
+          * IDE_TASKFILE_STD_IN_FLAGS | (IDE_HOB_STD_IN_FLAGS << 8)
+            if LBA48 addressing is enabled for the drive
+          * IDE_TASKFILE_STD_IN_FLAGS
+            if CHS/LBA28
+
+         The association between in_flags.all and each enable
+         bitfield flips depending on endianness; fortunately, TASKFILE
+         only uses inflags.b.data bit and ignores all other bits.
+         The end result is that, on any endian machines, it has no
+         effect other than modifying in_flags on completion.
+
+         [4] The default value of SELECT is (0xa0|DEV_bit|LBA_bit)
+         except for four drives per port chipsets.  For four drives
+         per port chipsets, it's (0xa0|DEV_bit|LBA_bit) for the first
+         pair and (0x80|DEV_bit|LBA_bit) for the second pair.
+
+         [5] The argument to the ioctl is a pointer to a region of
+         memory containing a ide_task_request_t structure, followed
+         by an optional buffer of data to be transmitted to the
+         drive, followed by an optional buffer to receive data from
+         the drive.
+
+         Command is passed to the disk drive via the ide_task_request_t
+         structure, which contains these fields:
+
+           ============        ===============================================
+           io_ports[8]         values for the taskfile registers
+           hob_ports[8]        high-order bytes, for extended commands
+           out_flags           flags indicating which entries in the
+                               io_ports[] and hob_ports[] arrays
+                               contain valid values.  Type ide_reg_valid_t.
+           in_flags            flags indicating which entries in the
+                               io_ports[] and hob_ports[] arrays
+                               are expected to contain valid values
+                               on return.
+           data_phase          See below
+           req_cmd             Command type, see below
+           out_size            output (user->drive) buffer size, bytes
+           in_size             input (drive->user) buffer size, bytes
+           ============        ===============================================
+
+         When out_flags is zero, the following registers are loaded.
+
+           ============        ===============================================
+           HOB_FEATURE         If the drive supports LBA48
+           HOB_NSECTOR         If the drive supports LBA48
+           HOB_SECTOR          If the drive supports LBA48
+           HOB_LCYL            If the drive supports LBA48
+           HOB_HCYL            If the drive supports LBA48
+           FEATURE
+           NSECTOR
+           SECTOR
+           LCYL
+           HCYL
+           SELECT              First, masked with 0xE0 if LBA48, 0xEF
+                               otherwise; then, or'ed with the default
+                               value of SELECT.
+           ============        ===============================================
+
+         If any bit in out_flags is set, the following registers are loaded.
+
+           ============        ===============================================
+           HOB_DATA            If out_flags.b.data is set.  HOB_DATA will
+                               travel on DD8-DD15 on little endian machines
+                               and on DD0-DD7 on big endian machines.
+           DATA                If out_flags.b.data is set.  DATA will
+                               travel on DD0-DD7 on little endian machines
+                               and on DD8-DD15 on big endian machines.
+           HOB_NSECTOR         If out_flags.b.nsector_hob is set
+           HOB_SECTOR          If out_flags.b.sector_hob is set
+           HOB_LCYL            If out_flags.b.lcyl_hob is set
+           HOB_HCYL            If out_flags.b.hcyl_hob is set
+           FEATURE             If out_flags.b.feature is set
+           NSECTOR             If out_flags.b.nsector is set
+           SECTOR              If out_flags.b.sector is set
+           LCYL                If out_flags.b.lcyl is set
+           HCYL                If out_flags.b.hcyl is set
+           SELECT              Or'ed with the default value of SELECT and
+                               loaded regardless of out_flags.b.select.
+           ============        ===============================================
+
+         Taskfile registers are read back from the drive into
+         {io|hob}_ports[] after the command completes iff one of the
+         following conditions is met; otherwise, the original values
+         will be written back, unchanged.
+
+           1. The drive fails the command (EIO).
+           2. One or more than one bits are set in out_flags.
+           3. The requested data_phase is TASKFILE_NO_DATA.
+
+           ============        ===============================================
+           HOB_DATA            If in_flags.b.data is set.  It will contain
+                               DD8-DD15 on little endian machines and
+                               DD0-DD7 on big endian machines.
+           DATA                If in_flags.b.data is set.  It will contain
+                               DD0-DD7 on little endian machines and
+                               DD8-DD15 on big endian machines.
+           HOB_FEATURE         If the drive supports LBA48
+           HOB_NSECTOR         If the drive supports LBA48
+           HOB_SECTOR          If the drive supports LBA48
+           HOB_LCYL            If the drive supports LBA48
+           HOB_HCYL            If the drive supports LBA48
+           NSECTOR
+           SECTOR
+           LCYL
+           HCYL
+           ============        ===============================================
+
+         The data_phase field describes the data transfer to be
+         performed.  Value is one of:
+
+           ===================        ========================================
+           TASKFILE_IN
+           TASKFILE_MULTI_IN
+           TASKFILE_OUT
+           TASKFILE_MULTI_OUT
+           TASKFILE_IN_OUT
+           TASKFILE_IN_DMA
+           TASKFILE_IN_DMAQ            == IN_DMA (queueing not supported)
+           TASKFILE_OUT_DMA
+           TASKFILE_OUT_DMAQ           == OUT_DMA (queueing not supported)
+           TASKFILE_P_IN               unimplemented
+           TASKFILE_P_IN_DMA           unimplemented
+           TASKFILE_P_IN_DMAQ          unimplemented
+           TASKFILE_P_OUT              unimplemented
+           TASKFILE_P_OUT_DMA          unimplemented
+           TASKFILE_P_OUT_DMAQ         unimplemented
+           ===================        ========================================
+
+         The req_cmd field classifies the command type.  It may be
+         one of:
+
+           ========================    =======================================
+           IDE_DRIVE_TASK_NO_DATA
+           IDE_DRIVE_TASK_SET_XFER     unimplemented
+           IDE_DRIVE_TASK_IN
+           IDE_DRIVE_TASK_OUT          unimplemented
+           IDE_DRIVE_TASK_RAW_WRITE
+           ========================    =======================================
+
+         [6] Do not access {in|out}_flags->all except for resetting
+         all the bits.  Always access individual bit fields.  ->all
+         value will flip depending on endianness.  For the same
+         reason, do not use IDE_{TASKFILE|HOB}_STD_{OUT|IN}_FLAGS
+         constants defined in hdreg.h.
+
+
+
+HDIO_DRIVE_CMD
+       execute a special drive command
+
+
+       Note:  If you don't have a copy of the ANSI ATA specification
+       handy, you should probably ignore this ioctl.
+
+       usage::
+
+         u8 args[4+XFER_SIZE];
+
+         ...
+         ioctl(fd, HDIO_DRIVE_CMD, args);
+
+       inputs:
+           Commands other than WIN_SMART:
+
+           =======     =======
+           args[0]     COMMAND
+           args[1]     NSECTOR
+           args[2]     FEATURE
+           args[3]     NSECTOR
+           =======     =======
+
+           WIN_SMART:
+
+           =======     =======
+           args[0]     COMMAND
+           args[1]     SECTOR
+           args[2]     FEATURE
+           args[3]     NSECTOR
+           =======     =======
+
+       outputs:
+               args[] buffer is filled with register values followed by any
+
+
+         data returned by the disk.
+
+           ========    ====================================================
+           args[0]     status
+           args[1]     error
+           args[2]     NSECTOR
+           args[3]     undefined
+           args[4+]    NSECTOR * 512 bytes of data returned by the command.
+           ========    ====================================================
+
+       error returns:
+         - EACCES      Access denied:  requires CAP_SYS_RAWIO
+         - ENOMEM      Unable to allocate memory for task
+         - EIO         Drive reports error
+
+       notes:
+
+         [1] For commands other than WIN_SMART, args[1] should equal
+         args[3].  SECTOR, LCYL and HCYL are undefined.  For
+         WIN_SMART, 0x4f and 0xc2 are loaded into LCYL and HCYL
+         respectively.  In both cases SELECT will contain the default
+         value for the drive.  Please refer to HDIO_DRIVE_TASKFILE
+         notes for the default value of SELECT.
+
+         [2] If NSECTOR value is greater than zero and the drive sets
+         DRQ when interrupting for the command, NSECTOR * 512 bytes
+         are read from the device into the area following NSECTOR.
+         In the above example, the area would be
+         args[4..4+XFER_SIZE].  16bit PIO is used regardless of
+         HDIO_SET_32BIT setting.
+
+         [3] If COMMAND == WIN_SETFEATURES && FEATURE == SETFEATURES_XFER
+         && NSECTOR >= XFER_SW_DMA_0 && the drive supports any DMA
+         mode, IDE driver will try to tune the transfer mode of the
+         drive accordingly.
+
+
+
+HDIO_DRIVE_TASK
+       execute task and special drive command
+
+
+       Note:  If you don't have a copy of the ANSI ATA specification
+       handy, you should probably ignore this ioctl.
+
+       usage::
+
+         u8 args[7];
+
+         ...
+         ioctl(fd, HDIO_DRIVE_TASK, args);
+
+       inputs:
+           Taskfile register values:
+
+           =======     =======
+           args[0]     COMMAND
+           args[1]     FEATURE
+           args[2]     NSECTOR
+           args[3]     SECTOR
+           args[4]     LCYL
+           args[5]     HCYL
+           args[6]     SELECT
+           =======     =======
+
+       outputs:
+           Taskfile register values:
+
+
+           =======     =======
+           args[0]     status
+           args[1]     error
+           args[2]     NSECTOR
+           args[3]     SECTOR
+           args[4]     LCYL
+           args[5]     HCYL
+           args[6]     SELECT
+           =======     =======
+
+       error returns:
+         - EACCES      Access denied:  requires CAP_SYS_RAWIO
+         - ENOMEM      Unable to allocate memory for task
+         - ENOMSG      Device is not a disk drive.
+         - EIO         Drive failed the command.
+
+       notes:
+
+         [1] DEV bit (0x10) of SELECT register is ignored and the
+         appropriate value for the drive is used.  All other bits
+         are used unaltered.
+
+
+
+HDIO_DRIVE_CMD_AEB
+       HDIO_DRIVE_TASK
+
+
+       Not implemented, as of 2.6.8.1
+
+
+
+HDIO_SET_32BIT
+       change io_32bit flags
+
+
+       usage::
+
+         int val;
+
+         ioctl(fd, HDIO_SET_32BIT, val);
+
+       inputs:
+               New value for io_32bit flag
+
+
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range [0 3]
+         - EBUSY       Controller busy
+
+
+
+
+HDIO_SET_NOWERR
+       change ignore-write-error flag
+
+
+       usage::
+
+         int val;
+
+         ioctl(fd, HDIO_SET_NOWERR, val);
+
+       inputs:
+               New value for ignore-write-error flag.  Used for ignoring
+
+
+         WRERR_STAT
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range [0 1]
+         - EBUSY               Controller busy
+
+
+
+HDIO_SET_DMA
+       change use-dma flag
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_SET_DMA, val);
+
+       inputs:
+               New value for use-dma flag
+
+
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range [0 1]
+         - EBUSY       Controller busy
+
+
+
+HDIO_SET_PIO_MODE
+       reconfig interface to new speed
+
+
+       usage::
+
+         long val;
+
+         ioctl(fd, HDIO_SET_PIO_MODE, val);
+
+       inputs:
+               New interface speed.
+
+
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range [0 255]
+         - EBUSY       Controller busy
+
+
+
+HDIO_SCAN_HWIF
+       register and (re)scan interface
+
+
+       usage::
+
+         int args[3]
+
+         ...
+         ioctl(fd, HDIO_SCAN_HWIF, args);
+
+       inputs:
+
+         =======       =========================
+         args[0]       io address to probe
+
+
+         args[1]       control address to probe
+         args[2]       irq number
+         =======       =========================
+
+       outputs:
+               none
+
+
+
+       error returns:
+         - EACCES      Access denied:  requires CAP_SYS_RAWIO
+         - EIO         Probe failed.
+
+       notes:
+               This ioctl initializes the addresses and irq for a disk
+               controller, probes for drives, and creates /proc/ide
+               interfaces as appropriate.
+
+
+
+HDIO_UNREGISTER_HWIF
+       unregister interface
+
+
+       usage::
+
+         int index;
+
+         ioctl(fd, HDIO_UNREGISTER_HWIF, index);
+
+       inputs:
+               index           index of hardware interface to unregister
+
+
+
+       outputs:
+               none
+
+
+
+       error returns:
+         - EACCES      Access denied:  requires CAP_SYS_RAWIO
+
+       notes:
+               This ioctl removes a hardware interface from the kernel.
+
+               Currently (2.6.8) this ioctl silently fails if any drive on
+               the interface is busy.
+
+
+
+HDIO_SET_WCACHE
+       change write cache enable-disable
+
+
+       usage::
+
+         int val;
+
+         ioctl(fd, HDIO_SET_WCACHE, val);
+
+       inputs:
+               New value for write cache enable
+
+
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range [0 1]
+         - EBUSY       Controller busy
+
+
+
+HDIO_SET_ACOUSTIC
+       change acoustic behavior
+
+
+       usage::
+
+         int val;
+
+         ioctl(fd, HDIO_SET_ACOUSTIC, val);
+
+       inputs:
+               New value for drive acoustic settings
+
+
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range [0 254]
+         - EBUSY       Controller busy
+
+
+
+HDIO_SET_QDMA
+       change use-qdma flag
+
+
+       Not implemented, as of 2.6.8.1
+
+
+
+HDIO_SET_ADDRESS
+       change lba addressing modes
+
+
+       usage::
+
+         int val;
+
+         ioctl(fd, HDIO_SET_ADDRESS, val);
+
+       inputs:
+               New value for addressing mode
+
+           =   ===================
+           0   28-bit
+           1   48-bit
+           2   48-bit doing 28-bit
+           =   ===================
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range [0 2]
+         - EBUSY               Controller busy
+         - EIO         Drive does not support lba48 mode.
+
+
+HDIO_SET_IDE_SCSI
+       usage::
+
+
+         long val;
+
+         ioctl(fd, HDIO_SET_IDE_SCSI, val);
+
+       inputs:
+               New value for scsi emulation mode (?)
+
+
+
+       outputs:
+               none
+
+
+
+       error return:
+         - EINVAL      (bdev != bdev->bd_contains) (not sure what this means)
+         - EACCES      Access denied:  requires CAP_SYS_ADMIN
+         - EINVAL      value out of range [0 1]
+         - EBUSY       Controller busy
+
+
+
+HDIO_SET_SCSI_IDE
+       Not implemented, as of 2.6.8.1
diff --git a/Documentation/ioctl/hdio.txt b/Documentation/ioctl/hdio.txt
deleted file mode 100644 (file)
index 18eb98c..0000000
+++ /dev/null
@@ -1,1071 +0,0 @@
-               Summary of HDIO_ ioctl calls.
-               ============================
-
-               Edward A. Falk <efalk@google.com>
-
-               November, 2004
-
-This document attempts to describe the ioctl(2) calls supported by
-the HD/IDE layer.  These are by-and-large implemented (as of Linux 2.6)
-in drivers/ide/ide.c and drivers/block/scsi_ioctl.c
-
-ioctl values are listed in <linux/hdreg.h>.  As of this writing, they
-are as follows:
-
-    ioctls that pass argument pointers to user space:
-
-       HDIO_GETGEO             get device geometry
-       HDIO_GET_UNMASKINTR     get current unmask setting
-       HDIO_GET_MULTCOUNT      get current IDE blockmode setting
-       HDIO_GET_QDMA           get use-qdma flag
-       HDIO_SET_XFER           set transfer rate via proc
-       HDIO_OBSOLETE_IDENTITY  OBSOLETE, DO NOT USE
-       HDIO_GET_KEEPSETTINGS   get keep-settings-on-reset flag
-       HDIO_GET_32BIT          get current io_32bit setting
-       HDIO_GET_NOWERR         get ignore-write-error flag
-       HDIO_GET_DMA            get use-dma flag
-       HDIO_GET_NICE           get nice flags
-       HDIO_GET_IDENTITY       get IDE identification info
-       HDIO_GET_WCACHE         get write cache mode on|off
-       HDIO_GET_ACOUSTIC       get acoustic value
-       HDIO_GET_ADDRESS        get sector addressing mode
-       HDIO_GET_BUSSTATE       get the bus state of the hwif
-       HDIO_TRISTATE_HWIF      execute a channel tristate
-       HDIO_DRIVE_RESET        execute a device reset
-       HDIO_DRIVE_TASKFILE     execute raw taskfile
-       HDIO_DRIVE_TASK         execute task and special drive command
-       HDIO_DRIVE_CMD          execute a special drive command
-       HDIO_DRIVE_CMD_AEB      HDIO_DRIVE_TASK
-
-    ioctls that pass non-pointer values:
-
-       HDIO_SET_MULTCOUNT      change IDE blockmode
-       HDIO_SET_UNMASKINTR     permit other irqs during I/O
-       HDIO_SET_KEEPSETTINGS   keep ioctl settings on reset
-       HDIO_SET_32BIT          change io_32bit flags
-       HDIO_SET_NOWERR         change ignore-write-error flag
-       HDIO_SET_DMA            change use-dma flag
-       HDIO_SET_PIO_MODE       reconfig interface to new speed
-       HDIO_SCAN_HWIF          register and (re)scan interface
-       HDIO_SET_NICE           set nice flags
-       HDIO_UNREGISTER_HWIF    unregister interface
-       HDIO_SET_WCACHE         change write cache enable-disable
-       HDIO_SET_ACOUSTIC       change acoustic behavior
-       HDIO_SET_BUSSTATE       set the bus state of the hwif
-       HDIO_SET_QDMA           change use-qdma flag
-       HDIO_SET_ADDRESS        change lba addressing modes
-
-       HDIO_SET_IDE_SCSI       Set scsi emulation mode on/off
-       HDIO_SET_SCSI_IDE       not implemented yet
-
-
-The information that follows was determined from reading kernel source
-code.  It is likely that some corrections will be made over time.
-
-
-
-
-
-
-
-General:
-
-       Unless otherwise specified, all ioctl calls return 0 on success
-       and -1 with errno set to an appropriate value on error.
-
-       Unless otherwise specified, all ioctl calls return -1 and set
-       errno to EFAULT on a failed attempt to copy data to or from user
-       address space.
-
-       Unless otherwise specified, all data structures and constants
-       are defined in <linux/hdreg.h>
-
-
-
-HDIO_GETGEO                    get device geometry
-
-       usage:
-
-         struct hd_geometry geom;
-         ioctl(fd, HDIO_GETGEO, &geom);
-
-
-       inputs:         none
-
-       outputs:
-
-         hd_geometry structure containing:
-
-           heads       number of heads
-           sectors     number of sectors/track
-           cylinders   number of cylinders, mod 65536
-           start       starting sector of this partition.
-
-
-       error returns:
-         EINVAL        if the device is not a disk drive or floppy drive,
-                       or if the user passes a null pointer
-
-
-       notes:
-
-         Not particularly useful with modern disk drives, whose geometry
-         is a polite fiction anyway.  Modern drives are addressed
-         purely by sector number nowadays (lba addressing), and the
-         drive geometry is an abstraction which is actually subject
-         to change.  Currently (as of Nov 2004), the geometry values
-         are the "bios" values -- presumably the values the drive had
-         when Linux first booted.
-
-         In addition, the cylinders field of the hd_geometry is an
-         unsigned short, meaning that on most architectures, this
-         ioctl will not return a meaningful value on drives with more
-         than 65535 tracks.
-
-         The start field is unsigned long, meaning that it will not
-         contain a meaningful value for disks over 219 Gb in size.
-
-
-
-
-HDIO_GET_UNMASKINTR            get current unmask setting
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_GET_UNMASKINTR, &val);
-
-       inputs:         none
-
-       outputs:
-         The value of the drive's current unmask setting
-
-
-
-HDIO_SET_UNMASKINTR            permit other irqs during I/O
-
-       usage:
-
-         unsigned long val;
-         ioctl(fd, HDIO_SET_UNMASKINTR, val);
-
-       inputs:
-         New value for unmask flag
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range [0 1]
-         EBUSY         Controller busy
-
-
-
-
-HDIO_GET_MULTCOUNT             get current IDE blockmode setting
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_GET_MULTCOUNT, &val);
-
-       inputs:         none
-
-       outputs:
-         The value of the current IDE block mode setting.  This
-         controls how many sectors the drive will transfer per
-         interrupt.
-
-
-
-HDIO_SET_MULTCOUNT             change IDE blockmode
-
-       usage:
-
-         int val;
-         ioctl(fd, HDIO_SET_MULTCOUNT, val);
-
-       inputs:
-         New value for IDE block mode setting.  This controls how many
-         sectors the drive will transfer per interrupt.
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range supported by disk.
-         EBUSY         Controller busy or blockmode already set.
-         EIO           Drive did not accept new block mode.
-
-       notes:
-
-         Source code comments read:
-
-           This is tightly woven into the driver->do_special cannot
-           touch.  DON'T do it again until a total personality rewrite
-           is committed.
-
-         If blockmode has already been set, this ioctl will fail with
-         EBUSY
-
-
-
-HDIO_GET_QDMA                  get use-qdma flag
-
-       Not implemented, as of 2.6.8.1
-
-
-
-HDIO_SET_XFER                  set transfer rate via proc
-
-       Not implemented, as of 2.6.8.1
-
-
-
-HDIO_OBSOLETE_IDENTITY         OBSOLETE, DO NOT USE
-
-       Same as HDIO_GET_IDENTITY (see below), except that it only
-       returns the first 142 bytes of drive identity information.
-
-
-
-HDIO_GET_IDENTITY              get IDE identification info
-
-       usage:
-
-         unsigned char identity[512];
-         ioctl(fd, HDIO_GET_IDENTITY, identity);
-
-       inputs:         none
-
-       outputs:
-
-         ATA drive identity information.  For full description, see
-         the IDENTIFY DEVICE and IDENTIFY PACKET DEVICE commands in
-         the ATA specification.
-
-       error returns:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         ENOMSG        IDENTIFY DEVICE information not available
-
-       notes:
-
-         Returns information that was obtained when the drive was
-         probed.  Some of this information is subject to change, and
-         this ioctl does not re-probe the drive to update the
-         information.
-
-         This information is also available from /proc/ide/hdX/identify
-
-
-
-HDIO_GET_KEEPSETTINGS          get keep-settings-on-reset flag
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_GET_KEEPSETTINGS, &val);
-
-       inputs:         none
-
-       outputs:
-         The value of the current "keep settings" flag
-
-       notes:
-
-         When set, indicates that kernel should restore settings
-         after a drive reset.
-
-
-
-HDIO_SET_KEEPSETTINGS          keep ioctl settings on reset
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_SET_KEEPSETTINGS, val);
-
-       inputs:
-         New value for keep_settings flag
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range [0 1]
-         EBUSY         Controller busy
-
-
-
-HDIO_GET_32BIT                 get current io_32bit setting
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_GET_32BIT, &val);
-
-       inputs:         none
-
-       outputs:
-         The value of the current io_32bit setting
-
-       notes:
-
-         0=16-bit, 1=32-bit, 2,3 = 32bit+sync
-
-
-
-HDIO_GET_NOWERR                        get ignore-write-error flag
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_GET_NOWERR, &val);
-
-       inputs:         none
-
-       outputs:
-         The value of the current ignore-write-error flag
-
-
-
-HDIO_GET_DMA                   get use-dma flag
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_GET_DMA, &val);
-
-       inputs:         none
-
-       outputs:
-         The value of the current use-dma flag
-
-
-
-HDIO_GET_NICE                  get nice flags
-
-       usage:
-
-         long nice;
-         ioctl(fd, HDIO_GET_NICE, &nice);
-
-       inputs:         none
-
-       outputs:
-
-         The drive's "nice" values.
-
-       notes:
-
-         Per-drive flags which determine when the system will give more
-         bandwidth to other devices sharing the same IDE bus.
-         See <linux/hdreg.h>, near symbol IDE_NICE_DSC_OVERLAP.
-
-
-
-
-HDIO_SET_NICE                  set nice flags
-
-       usage:
-
-         unsigned long nice;
-         ...
-         ioctl(fd, HDIO_SET_NICE, nice);
-
-       inputs:
-         bitmask of nice flags.
-
-       outputs:        none
-
-       error returns:
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EPERM         Flags other than DSC_OVERLAP and NICE_1 set.
-         EPERM         DSC_OVERLAP specified but not supported by drive
-
-       notes:
-
-         This ioctl sets the DSC_OVERLAP and NICE_1 flags from values
-         provided by the user.
-
-         Nice flags are listed in <linux/hdreg.h>, starting with
-         IDE_NICE_DSC_OVERLAP.  These values represent shifts.
-
-
-
-
-
-HDIO_GET_WCACHE                        get write cache mode on|off
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_GET_WCACHE, &val);
-
-       inputs:         none
-
-       outputs:
-         The value of the current write cache mode
-
-
-
-HDIO_GET_ACOUSTIC              get acoustic value
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_GET_ACOUSTIC, &val);
-
-       inputs:         none
-
-       outputs:
-         The value of the current acoustic settings
-
-       notes:
-
-         See HDIO_SET_ACOUSTIC
-
-
-
-HDIO_GET_ADDRESS
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_GET_ADDRESS, &val);
-
-       inputs:         none
-
-       outputs:
-         The value of the current addressing mode:
-           0 = 28-bit
-           1 = 48-bit
-           2 = 48-bit doing 28-bit
-           3 = 64-bit
-
-
-
-HDIO_GET_BUSSTATE              get the bus state of the hwif
-
-       usage:
-
-         long state;
-         ioctl(fd, HDIO_SCAN_HWIF, &state);
-
-       inputs:         none
-
-       outputs:
-         Current power state of the IDE bus.  One of BUSSTATE_OFF,
-         BUSSTATE_ON, or BUSSTATE_TRISTATE
-
-       error returns:
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-
-
-
-
-HDIO_SET_BUSSTATE              set the bus state of the hwif
-
-       usage:
-
-         int state;
-         ...
-         ioctl(fd, HDIO_SCAN_HWIF, state);
-
-       inputs:
-         Desired IDE power state.  One of BUSSTATE_OFF, BUSSTATE_ON,
-         or BUSSTATE_TRISTATE
-
-       outputs:        none
-
-       error returns:
-         EACCES        Access denied:  requires CAP_SYS_RAWIO
-         EOPNOTSUPP    Hardware interface does not support bus power control
-
-
-
-
-HDIO_TRISTATE_HWIF             execute a channel tristate
-
-       Not implemented, as of 2.6.8.1.  See HDIO_SET_BUSSTATE
-
-
-
-HDIO_DRIVE_RESET               execute a device reset
-
-       usage:
-
-         int args[3]
-         ...
-         ioctl(fd, HDIO_DRIVE_RESET, args);
-
-       inputs:         none
-
-       outputs:        none
-
-       error returns:
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         ENXIO         No such device: phy dead or ctl_addr == 0
-         EIO           I/O error:      reset timed out or hardware error
-
-       notes:
-
-         Execute a reset on the device as soon as the current IO
-         operation has completed.
-
-         Executes an ATAPI soft reset if applicable, otherwise
-         executes an ATA soft reset on the controller.
-
-
-
-HDIO_DRIVE_TASKFILE            execute raw taskfile
-
-       Note:  If you don't have a copy of the ANSI ATA specification
-       handy, you should probably ignore this ioctl.
-
-       Execute an ATA disk command directly by writing the "taskfile"
-       registers of the drive.  Requires ADMIN and RAWIO access
-       privileges.
-
-       usage:
-
-         struct {
-           ide_task_request_t req_task;
-           u8 outbuf[OUTPUT_SIZE];
-           u8 inbuf[INPUT_SIZE];
-         } task;
-         memset(&task.req_task, 0, sizeof(task.req_task));
-         task.req_task.out_size = sizeof(task.outbuf);
-         task.req_task.in_size = sizeof(task.inbuf);
-         ...
-         ioctl(fd, HDIO_DRIVE_TASKFILE, &task);
-         ...
-
-       inputs:
-
-         (See below for details on memory area passed to ioctl.)
-
-         io_ports[8]   values to be written to taskfile registers
-         hob_ports[8]  high-order bytes, for extended commands.
-         out_flags     flags indicating which registers are valid
-         in_flags      flags indicating which registers should be returned
-         data_phase    see below
-         req_cmd       command type to be executed
-         out_size      size of output buffer
-         outbuf        buffer of data to be transmitted to disk
-         inbuf         buffer of data to be received from disk (see [1])
-
-       outputs:
-
-         io_ports[]    values returned in the taskfile registers
-         hob_ports[]   high-order bytes, for extended commands.
-         out_flags     flags indicating which registers are valid (see [2])
-         in_flags      flags indicating which registers should be returned
-         outbuf        buffer of data to be transmitted to disk (see [1])
-         inbuf         buffer of data to be received from disk
-
-       error returns:
-         EACCES        CAP_SYS_ADMIN or CAP_SYS_RAWIO privilege not set.
-         ENOMSG        Device is not a disk drive.
-         ENOMEM        Unable to allocate memory for task
-         EFAULT        req_cmd == TASKFILE_IN_OUT (not implemented as of 2.6.8)
-         EPERM         req_cmd == TASKFILE_MULTI_OUT and drive
-                       multi-count not yet set.
-         EIO           Drive failed the command.
-
-       notes:
-
-         [1] READ THE FOLLOWING NOTES *CAREFULLY*.  THIS IOCTL IS
-         FULL OF GOTCHAS.  Extreme caution should be used with using
-         this ioctl.  A mistake can easily corrupt data or hang the
-         system.
-
-         [2] Both the input and output buffers are copied from the
-         user and written back to the user, even when not used.
-
-         [3] If one or more bits are set in out_flags and in_flags is
-         zero, the following values are used for in_flags.all and
-         written back into in_flags on completion.
-
-          * IDE_TASKFILE_STD_IN_FLAGS | (IDE_HOB_STD_IN_FLAGS << 8)
-            if LBA48 addressing is enabled for the drive
-          * IDE_TASKFILE_STD_IN_FLAGS
-            if CHS/LBA28
-
-         The association between in_flags.all and each enable
-         bitfield flips depending on endianness; fortunately, TASKFILE
-         only uses inflags.b.data bit and ignores all other bits.
-         The end result is that, on any endian machines, it has no
-         effect other than modifying in_flags on completion.
-
-         [4] The default value of SELECT is (0xa0|DEV_bit|LBA_bit)
-         except for four drives per port chipsets.  For four drives
-         per port chipsets, it's (0xa0|DEV_bit|LBA_bit) for the first
-         pair and (0x80|DEV_bit|LBA_bit) for the second pair.
-
-         [5] The argument to the ioctl is a pointer to a region of
-         memory containing a ide_task_request_t structure, followed
-         by an optional buffer of data to be transmitted to the
-         drive, followed by an optional buffer to receive data from
-         the drive.
-
-         Command is passed to the disk drive via the ide_task_request_t
-         structure, which contains these fields:
-
-           io_ports[8]         values for the taskfile registers
-           hob_ports[8]        high-order bytes, for extended commands
-           out_flags           flags indicating which entries in the
-                               io_ports[] and hob_ports[] arrays
-                               contain valid values.  Type ide_reg_valid_t.
-           in_flags            flags indicating which entries in the
-                               io_ports[] and hob_ports[] arrays
-                               are expected to contain valid values
-                               on return.
-           data_phase          See below
-           req_cmd             Command type, see below
-           out_size            output (user->drive) buffer size, bytes
-           in_size             input (drive->user) buffer size, bytes
-
-         When out_flags is zero, the following registers are loaded.
-
-           HOB_FEATURE         If the drive supports LBA48
-           HOB_NSECTOR         If the drive supports LBA48
-           HOB_SECTOR          If the drive supports LBA48
-           HOB_LCYL            If the drive supports LBA48
-           HOB_HCYL            If the drive supports LBA48
-           FEATURE
-           NSECTOR
-           SECTOR
-           LCYL
-           HCYL
-           SELECT              First, masked with 0xE0 if LBA48, 0xEF
-                               otherwise; then, or'ed with the default
-                               value of SELECT.
-
-         If any bit in out_flags is set, the following registers are loaded.
-
-           HOB_DATA            If out_flags.b.data is set.  HOB_DATA will
-                               travel on DD8-DD15 on little endian machines
-                               and on DD0-DD7 on big endian machines.
-           DATA                If out_flags.b.data is set.  DATA will
-                               travel on DD0-DD7 on little endian machines
-                               and on DD8-DD15 on big endian machines.
-           HOB_NSECTOR         If out_flags.b.nsector_hob is set
-           HOB_SECTOR          If out_flags.b.sector_hob is set
-           HOB_LCYL            If out_flags.b.lcyl_hob is set
-           HOB_HCYL            If out_flags.b.hcyl_hob is set
-           FEATURE             If out_flags.b.feature is set
-           NSECTOR             If out_flags.b.nsector is set
-           SECTOR              If out_flags.b.sector is set
-           LCYL                If out_flags.b.lcyl is set
-           HCYL                If out_flags.b.hcyl is set
-           SELECT              Or'ed with the default value of SELECT and
-                               loaded regardless of out_flags.b.select.
-
-         Taskfile registers are read back from the drive into
-         {io|hob}_ports[] after the command completes iff one of the
-         following conditions is met; otherwise, the original values
-         will be written back, unchanged.
-
-           1. The drive fails the command (EIO).
-           2. One or more than one bits are set in out_flags.
-           3. The requested data_phase is TASKFILE_NO_DATA.
-
-           HOB_DATA            If in_flags.b.data is set.  It will contain
-                               DD8-DD15 on little endian machines and
-                               DD0-DD7 on big endian machines.
-           DATA                If in_flags.b.data is set.  It will contain
-                               DD0-DD7 on little endian machines and
-                               DD8-DD15 on big endian machines.
-           HOB_FEATURE         If the drive supports LBA48
-           HOB_NSECTOR         If the drive supports LBA48
-           HOB_SECTOR          If the drive supports LBA48
-           HOB_LCYL            If the drive supports LBA48
-           HOB_HCYL            If the drive supports LBA48
-           NSECTOR
-           SECTOR
-           LCYL
-           HCYL
-
-         The data_phase field describes the data transfer to be
-         performed.  Value is one of:
-
-           TASKFILE_IN
-           TASKFILE_MULTI_IN
-           TASKFILE_OUT
-           TASKFILE_MULTI_OUT
-           TASKFILE_IN_OUT
-           TASKFILE_IN_DMA
-           TASKFILE_IN_DMAQ            == IN_DMA (queueing not supported)
-           TASKFILE_OUT_DMA
-           TASKFILE_OUT_DMAQ           == OUT_DMA (queueing not supported)
-           TASKFILE_P_IN               unimplemented
-           TASKFILE_P_IN_DMA           unimplemented
-           TASKFILE_P_IN_DMAQ          unimplemented
-           TASKFILE_P_OUT              unimplemented
-           TASKFILE_P_OUT_DMA          unimplemented
-           TASKFILE_P_OUT_DMAQ         unimplemented
-
-         The req_cmd field classifies the command type.  It may be
-         one of:
-
-           IDE_DRIVE_TASK_NO_DATA
-           IDE_DRIVE_TASK_SET_XFER     unimplemented
-           IDE_DRIVE_TASK_IN
-           IDE_DRIVE_TASK_OUT          unimplemented
-           IDE_DRIVE_TASK_RAW_WRITE
-
-         [6] Do not access {in|out}_flags->all except for resetting
-         all the bits.  Always access individual bit fields.  ->all
-         value will flip depending on endianness.  For the same
-         reason, do not use IDE_{TASKFILE|HOB}_STD_{OUT|IN}_FLAGS
-         constants defined in hdreg.h.
-
-
-
-HDIO_DRIVE_CMD                 execute a special drive command
-
-       Note:  If you don't have a copy of the ANSI ATA specification
-       handy, you should probably ignore this ioctl.
-
-       usage:
-
-         u8 args[4+XFER_SIZE];
-         ...
-         ioctl(fd, HDIO_DRIVE_CMD, args);
-
-       inputs:
-
-         Commands other than WIN_SMART
-           args[0]     COMMAND
-           args[1]     NSECTOR
-           args[2]     FEATURE
-           args[3]     NSECTOR
-
-         WIN_SMART
-           args[0]     COMMAND
-           args[1]     SECTOR
-           args[2]     FEATURE
-           args[3]     NSECTOR
-
-       outputs:
-
-         args[] buffer is filled with register values followed by any
-         data returned by the disk.
-           args[0]     status
-           args[1]     error
-           args[2]     NSECTOR
-           args[3]     undefined
-           args[4+]    NSECTOR * 512 bytes of data returned by the command.
-
-       error returns:
-         EACCES        Access denied:  requires CAP_SYS_RAWIO
-         ENOMEM        Unable to allocate memory for task
-         EIO           Drive reports error
-
-       notes:
-
-         [1] For commands other than WIN_SMART, args[1] should equal
-         args[3].  SECTOR, LCYL and HCYL are undefined.  For
-         WIN_SMART, 0x4f and 0xc2 are loaded into LCYL and HCYL
-         respectively.  In both cases SELECT will contain the default
-         value for the drive.  Please refer to HDIO_DRIVE_TASKFILE
-         notes for the default value of SELECT.
-
-         [2] If NSECTOR value is greater than zero and the drive sets
-         DRQ when interrupting for the command, NSECTOR * 512 bytes
-         are read from the device into the area following NSECTOR.
-         In the above example, the area would be
-         args[4..4+XFER_SIZE].  16bit PIO is used regardless of
-         HDIO_SET_32BIT setting.
-
-         [3] If COMMAND == WIN_SETFEATURES && FEATURE == SETFEATURES_XFER
-         && NSECTOR >= XFER_SW_DMA_0 && the drive supports any DMA
-         mode, IDE driver will try to tune the transfer mode of the
-         drive accordingly.
-
-
-
-HDIO_DRIVE_TASK                        execute task and special drive command
-
-       Note:  If you don't have a copy of the ANSI ATA specification
-       handy, you should probably ignore this ioctl.
-
-       usage:
-
-         u8 args[7];
-         ...
-         ioctl(fd, HDIO_DRIVE_TASK, args);
-
-       inputs:
-
-         Taskfile register values:
-           args[0]     COMMAND
-           args[1]     FEATURE
-           args[2]     NSECTOR
-           args[3]     SECTOR
-           args[4]     LCYL
-           args[5]     HCYL
-           args[6]     SELECT
-
-       outputs:
-
-         Taskfile register values:
-           args[0]     status
-           args[1]     error
-           args[2]     NSECTOR
-           args[3]     SECTOR
-           args[4]     LCYL
-           args[5]     HCYL
-           args[6]     SELECT
-
-       error returns:
-         EACCES        Access denied:  requires CAP_SYS_RAWIO
-         ENOMEM        Unable to allocate memory for task
-         ENOMSG        Device is not a disk drive.
-         EIO           Drive failed the command.
-
-       notes:
-
-         [1] DEV bit (0x10) of SELECT register is ignored and the
-         appropriate value for the drive is used.  All other bits
-         are used unaltered.
-
-
-
-HDIO_DRIVE_CMD_AEB             HDIO_DRIVE_TASK
-
-       Not implemented, as of 2.6.8.1
-
-
-
-HDIO_SET_32BIT                 change io_32bit flags
-
-       usage:
-
-         int val;
-         ioctl(fd, HDIO_SET_32BIT, val);
-
-       inputs:
-         New value for io_32bit flag
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range [0 3]
-         EBUSY         Controller busy
-
-
-
-
-HDIO_SET_NOWERR                        change ignore-write-error flag
-
-       usage:
-
-         int val;
-         ioctl(fd, HDIO_SET_NOWERR, val);
-
-       inputs:
-         New value for ignore-write-error flag.  Used for ignoring
-         WRERR_STAT
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range [0 1]
-         EBUSY         Controller busy
-
-
-
-HDIO_SET_DMA                   change use-dma flag
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_SET_DMA, val);
-
-       inputs:
-         New value for use-dma flag
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range [0 1]
-         EBUSY         Controller busy
-
-
-
-HDIO_SET_PIO_MODE              reconfig interface to new speed
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_SET_PIO_MODE, val);
-
-       inputs:
-         New interface speed.
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range [0 255]
-         EBUSY         Controller busy
-
-
-
-HDIO_SCAN_HWIF                 register and (re)scan interface
-
-       usage:
-
-         int args[3]
-         ...
-         ioctl(fd, HDIO_SCAN_HWIF, args);
-
-       inputs:
-         args[0]       io address to probe
-         args[1]       control address to probe
-         args[2]       irq number
-
-       outputs:        none
-
-       error returns:
-         EACCES        Access denied:  requires CAP_SYS_RAWIO
-         EIO           Probe failed.
-
-       notes:
-
-         This ioctl initializes the addresses and irq for a disk
-         controller, probes for drives, and creates /proc/ide
-         interfaces as appropriate.
-
-
-
-HDIO_UNREGISTER_HWIF           unregister interface
-
-       usage:
-
-         int index;
-         ioctl(fd, HDIO_UNREGISTER_HWIF, index);
-
-       inputs:
-         index         index of hardware interface to unregister
-
-       outputs:        none
-
-       error returns:
-         EACCES        Access denied:  requires CAP_SYS_RAWIO
-
-       notes:
-
-         This ioctl removes a hardware interface from the kernel.
-
-         Currently (2.6.8) this ioctl silently fails if any drive on
-         the interface is busy.
-
-
-
-HDIO_SET_WCACHE                        change write cache enable-disable
-
-       usage:
-
-         int val;
-         ioctl(fd, HDIO_SET_WCACHE, val);
-
-       inputs:
-         New value for write cache enable
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range [0 1]
-         EBUSY         Controller busy
-
-
-
-HDIO_SET_ACOUSTIC              change acoustic behavior
-
-       usage:
-
-         int val;
-         ioctl(fd, HDIO_SET_ACOUSTIC, val);
-
-       inputs:
-         New value for drive acoustic settings
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range [0 254]
-         EBUSY         Controller busy
-
-
-
-HDIO_SET_QDMA                  change use-qdma flag
-
-       Not implemented, as of 2.6.8.1
-
-
-
-HDIO_SET_ADDRESS               change lba addressing modes
-
-       usage:
-
-         int val;
-         ioctl(fd, HDIO_SET_ADDRESS, val);
-
-       inputs:
-         New value for addressing mode
-           0 = 28-bit
-           1 = 48-bit
-           2 = 48-bit doing 28-bit
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range [0 2]
-         EBUSY         Controller busy
-         EIO           Drive does not support lba48 mode.
-
-
-HDIO_SET_IDE_SCSI
-
-       usage:
-
-         long val;
-         ioctl(fd, HDIO_SET_IDE_SCSI, val);
-
-       inputs:
-         New value for scsi emulation mode (?)
-
-       outputs:        none
-
-       error return:
-         EINVAL        (bdev != bdev->bd_contains) (not sure what this means)
-         EACCES        Access denied:  requires CAP_SYS_ADMIN
-         EINVAL        value out of range [0 1]
-         EBUSY         Controller busy
-
-
-
-HDIO_SET_SCSI_IDE
-
-       Not implemented, as of 2.6.8.1
-
-
diff --git a/Documentation/ioctl/index.rst b/Documentation/ioctl/index.rst
new file mode 100644 (file)
index 0000000..1a6f437
--- /dev/null
@@ -0,0 +1,16 @@
+:orphan:
+
+======
+IOCTLs
+======
+
+.. toctree::
+   :maxdepth: 1
+
+   ioctl-number
+
+   botching-up-ioctls
+   ioctl-decoding
+
+   cdrom
+   hdio
diff --git a/Documentation/ioctl/ioctl-decoding.rst b/Documentation/ioctl/ioctl-decoding.rst
new file mode 100644 (file)
index 0000000..380d6bb
--- /dev/null
@@ -0,0 +1,31 @@
+==============================
+Decoding an IOCTL Magic Number
+==============================
+
+To decode a hex IOCTL code:
+
+Most architectures use this generic format, but check
+include/ARCH/ioctl.h for specifics, e.g. powerpc
+uses 3 bits to encode read/write and 13 bits for size.
+
+ ====== ==================================
+ bits   meaning
+ ====== ==================================
+ 31-30 00 - no parameters: uses _IO macro
+       10 - read: _IOR
+       01 - write: _IOW
+       11 - read/write: _IOWR
+
+ 29-16 size of arguments
+
+ 15-8  ascii character supposedly
+       unique to each driver
+
+ 7-0   function #
+ ====== ==================================
+
+
+So for example 0x82187201 is a read with arg length of 0x218,
+character 'r' function 1. Grepping the source reveals this is::
+
+       #define VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct dirent [2])
diff --git a/Documentation/ioctl/ioctl-decoding.txt b/Documentation/ioctl/ioctl-decoding.txt
deleted file mode 100644 (file)
index e35efb0..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-To decode a hex IOCTL code:
-
-Most architectures use this generic format, but check
-include/ARCH/ioctl.h for specifics, e.g. powerpc
-uses 3 bits to encode read/write and 13 bits for size.
-
- bits    meaning
- 31-30 00 - no parameters: uses _IO macro
-       10 - read: _IOR
-       01 - write: _IOW
-       11 - read/write: _IOWR
-
- 29-16 size of arguments
-
- 15-8  ascii character supposedly
-       unique to each driver
-
- 7-0   function #
-
-
-So for example 0x82187201 is a read with arg length of 0x218,
-character 'r' function 1. Grepping the source reveals this is:
-
-#define VFAT_IOCTL_READDIR_BOTH         _IOR('r', 1, struct dirent [2])
index 2263e3ddd8222bbc2732a2d93328edcd99de8842..42fb0d6d6034d80b4fc45394f5d95ceefa962f0d 100644 (file)
@@ -730,7 +730,7 @@ static const struct drm_ioctl_desc drm_ioctls[] = {
  *     };
  *
  * Please make sure that you follow all the best practices from
- * ``Documentation/ioctl/botching-up-ioctls.txt``. Note that drm_ioctl()
+ * ``Documentation/ioctl/botching-up-ioctls.rst``. Note that drm_ioctl()
  * automatically zero-extends structures, hence make sure you can add more stuff
  * at the end, i.e. don't put a variable sized array there.
  *