From: Mauro Carvalho Chehab Date: Thu, 18 Apr 2019 14:38:26 +0000 (-0300) Subject: docs: ioctl: convert to ReST X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=5c04dceaa152d9dd9fe94dec6594965069e19e9e;p=openwrt%2Fstaging%2Fblogic.git docs: ioctl: convert to ReST 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 --- diff --git a/Documentation/ioctl/botching-up-ioctls.rst b/Documentation/ioctl/botching-up-ioctls.rst new file mode 100644 index 000000000000..ac697fef3545 --- /dev/null +++ b/Documentation/ioctl/botching-up-ioctls.rst @@ -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 index 883fb034bd04..000000000000 --- a/Documentation/ioctl/botching-up-ioctls.txt +++ /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 index 000000000000..3b4c0506de46 --- /dev/null +++ b/Documentation/ioctl/cdrom.rst @@ -0,0 +1,1233 @@ +============================ +Summary of CDROM ioctl calls +============================ + +- Edward A. Falk + +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 . 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 + +------------------------------------------------------------------------------ + + +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 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 : + + =================== ========================== + 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 : + + - 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 + 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 + + + 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 index a4d62a9d6771..000000000000 --- a/Documentation/ioctl/cdrom.txt +++ /dev/null @@ -1,967 +0,0 @@ - Summary of CDROM ioctl calls. - ============================ - - Edward A. Falk - - 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 . 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 - - - - -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 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 : - - 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 : - 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 - 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 - - 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 index 000000000000..e822e3dff176 --- /dev/null +++ b/Documentation/ioctl/hdio.rst @@ -0,0 +1,1342 @@ +============================== +Summary of `HDIO_` ioctl calls +============================== + +- Edward A. Falk + +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 . 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 + +------------------------------------------------------------------------------ + +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 , 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 , 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 index 18eb98c44ffe..000000000000 --- a/Documentation/ioctl/hdio.txt +++ /dev/null @@ -1,1071 +0,0 @@ - Summary of HDIO_ ioctl calls. - ============================ - - Edward A. Falk - - 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 . 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 - - - -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 , 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 , 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 index 000000000000..1a6f437566e3 --- /dev/null +++ b/Documentation/ioctl/index.rst @@ -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 index 000000000000..380d6bb3e3ea --- /dev/null +++ b/Documentation/ioctl/ioctl-decoding.rst @@ -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 index e35efb0cec2e..000000000000 --- a/Documentation/ioctl/ioctl-decoding.txt +++ /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]) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 2263e3ddd822..42fb0d6d6034 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -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. *