| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | IDE-CD driver documentation | 
|  | 2 | Originally by scott snyder  <snyder@fnald0.fnal.gov> (19 May 1996) | 
|  | 3 | Carrying on the torch is: Erik Andersen <andersee@debian.org> | 
|  | 4 | New maintainers (19 Oct 1998): Jens Axboe <axboe@image.dk> | 
|  | 5 |  | 
|  | 6 | 1. Introduction | 
|  | 7 | --------------- | 
|  | 8 |  | 
|  | 9 | The ide-cd driver should work with all ATAPI ver 1.2 to ATAPI 2.6 compliant | 
|  | 10 | CDROM drives which attach to an IDE interface.  Note that some CDROM vendors | 
|  | 11 | (including Mitsumi, Sony, Creative, Aztech, and Goldstar) have made | 
|  | 12 | both ATAPI-compliant drives and drives which use a proprietary | 
|  | 13 | interface.  If your drive uses one of those proprietary interfaces, | 
|  | 14 | this driver will not work with it (but one of the other CDROM drivers | 
|  | 15 | probably will).  This driver will not work with `ATAPI' drives which | 
|  | 16 | attach to the parallel port.  In addition, there is at least one drive | 
|  | 17 | (CyCDROM CR520ie) which attaches to the IDE port but is not ATAPI; | 
|  | 18 | this driver will not work with drives like that either (but see the | 
|  | 19 | aztcd driver). | 
|  | 20 |  | 
|  | 21 | This driver provides the following features: | 
|  | 22 |  | 
|  | 23 | - Reading from data tracks, and mounting ISO 9660 filesystems. | 
|  | 24 |  | 
|  | 25 | - Playing audio tracks.  Most of the CDROM player programs floating | 
|  | 26 | around should work; I usually use Workman. | 
|  | 27 |  | 
|  | 28 | - Multisession support. | 
|  | 29 |  | 
|  | 30 | - On drives which support it, reading digital audio data directly | 
|  | 31 | from audio tracks.  The program cdda2wav can be used for this. | 
|  | 32 | Note, however, that only some drives actually support this. | 
|  | 33 |  | 
|  | 34 | - There is now support for CDROM changers which comply with the | 
|  | 35 | ATAPI 2.6 draft standard (such as the NEC CDR-251).  This additional | 
|  | 36 | functionality includes a function call to query which slot is the | 
|  | 37 | currently selected slot, a function call to query which slots contain | 
|  | 38 | CDs, etc. A sample program which demonstrates this functionality is | 
|  | 39 | appended to the end of this file.  The Sanyo 3-disc changer | 
|  | 40 | (which does not conform to the standard) is also now supported. | 
|  | 41 | Please note the driver refers to the first CD as slot # 0. | 
|  | 42 |  | 
|  | 43 |  | 
|  | 44 | 2. Installation | 
|  | 45 | --------------- | 
|  | 46 |  | 
|  | 47 | 0. The ide-cd relies on the ide disk driver.  See | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 48 | Documentation/ide/ide.txt for up-to-date information on the ide | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 49 | driver. | 
|  | 50 |  | 
|  | 51 | 1. Make sure that the ide and ide-cd drivers are compiled into the | 
|  | 52 | kernel you're using.  When configuring the kernel, in the section | 
|  | 53 | entitled "Floppy, IDE, and other block devices", say either `Y' | 
|  | 54 | (which will compile the support directly into the kernel) or `M' | 
|  | 55 | (to compile support as a module which can be loaded and unloaded) | 
|  | 56 | to the options: | 
|  | 57 |  | 
|  | 58 | Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support | 
|  | 59 | Include IDE/ATAPI CDROM support | 
|  | 60 |  | 
|  | 61 | and `no' to | 
|  | 62 |  | 
|  | 63 | Use old disk-only driver on primary interface | 
|  | 64 |  | 
|  | 65 | Depending on what type of IDE interface you have, you may need to | 
|  | 66 | specify additional configuration options.  See | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 67 | Documentation/ide/ide.txt. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 68 |  | 
|  | 69 | 2. You should also ensure that the iso9660 filesystem is either | 
|  | 70 | compiled into the kernel or available as a loadable module.  You | 
|  | 71 | can see if a filesystem is known to the kernel by catting | 
|  | 72 | /proc/filesystems. | 
|  | 73 |  | 
|  | 74 | 3. The CDROM drive should be connected to the host on an IDE | 
|  | 75 | interface.  Each interface on a system is defined by an I/O port | 
|  | 76 | address and an IRQ number, the standard assignments being | 
|  | 77 | 0x1f0 and 14 for the primary interface and 0x170 and 15 for the | 
|  | 78 | secondary interface.  Each interface can control up to two devices, | 
|  | 79 | where each device can be a hard drive, a CDROM drive, a floppy drive, | 
|  | 80 | or a tape drive.  The two devices on an interface are called `master' | 
|  | 81 | and `slave'; this is usually selectable via a jumper on the drive. | 
|  | 82 |  | 
|  | 83 | Linux names these devices as follows.  The master and slave devices | 
|  | 84 | on the primary IDE interface are called `hda' and `hdb', | 
|  | 85 | respectively.  The drives on the secondary interface are called | 
|  | 86 | `hdc' and `hdd'.  (Interfaces at other locations get other letters | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 87 | in the third position; see Documentation/ide/ide.txt.) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 88 |  | 
|  | 89 | If you want your CDROM drive to be found automatically by the | 
|  | 90 | driver, you should make sure your IDE interface uses either the | 
|  | 91 | primary or secondary addresses mentioned above.  In addition, if | 
|  | 92 | the CDROM drive is the only device on the IDE interface, it should | 
|  | 93 | be jumpered as `master'.  (If for some reason you cannot configure | 
|  | 94 | your system in this manner, you can probably still use the driver. | 
|  | 95 | You may have to pass extra configuration information to the kernel | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 96 | when you boot, however.  See Documentation/ide/ide.txt for more | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 97 | information.) | 
|  | 98 |  | 
|  | 99 | 4. Boot the system.  If the drive is recognized, you should see a | 
|  | 100 | message which looks like | 
|  | 101 |  | 
|  | 102 | hdb: NEC CD-ROM DRIVE:260, ATAPI CDROM drive | 
|  | 103 |  | 
|  | 104 | If you do not see this, see section 5 below. | 
|  | 105 |  | 
|  | 106 | 5. You may want to create a symbolic link /dev/cdrom pointing to the | 
|  | 107 | actual device.  You can do this with the command | 
|  | 108 |  | 
|  | 109 | ln -s  /dev/hdX  /dev/cdrom | 
|  | 110 |  | 
|  | 111 | where X should be replaced by the letter indicating where your | 
|  | 112 | drive is installed. | 
|  | 113 |  | 
|  | 114 | 6. You should be able to see any error messages from the driver with | 
|  | 115 | the `dmesg' command. | 
|  | 116 |  | 
|  | 117 |  | 
|  | 118 | 3. Basic usage | 
|  | 119 | -------------- | 
|  | 120 |  | 
|  | 121 | An ISO 9660 CDROM can be mounted by putting the disc in the drive and | 
|  | 122 | typing (as root) | 
|  | 123 |  | 
|  | 124 | mount -t iso9660 /dev/cdrom /mnt/cdrom | 
|  | 125 |  | 
|  | 126 | where it is assumed that /dev/cdrom is a link pointing to the actual | 
|  | 127 | device (as described in step 5 of the last section) and /mnt/cdrom is | 
|  | 128 | an empty directory.  You should now be able to see the contents of the | 
|  | 129 | CDROM under the /mnt/cdrom directory.  If you want to eject the CDROM, | 
|  | 130 | you must first dismount it with a command like | 
|  | 131 |  | 
|  | 132 | umount /mnt/cdrom | 
|  | 133 |  | 
|  | 134 | Note that audio CDs cannot be mounted. | 
|  | 135 |  | 
|  | 136 | Some distributions set up /etc/fstab to always try to mount a CDROM | 
|  | 137 | filesystem on bootup.  It is not required to mount the CDROM in this | 
|  | 138 | manner, though, and it may be a nuisance if you change CDROMs often. | 
|  | 139 | You should feel free to remove the cdrom line from /etc/fstab and | 
|  | 140 | mount CDROMs manually if that suits you better. | 
|  | 141 |  | 
|  | 142 | Multisession and photocd discs should work with no special handling. | 
|  | 143 | The hpcdtoppm package (ftp.gwdg.de:/pub/linux/hpcdtoppm/) may be | 
|  | 144 | useful for reading photocds. | 
|  | 145 |  | 
|  | 146 | To play an audio CD, you should first unmount and remove any data | 
|  | 147 | CDROM.  Any of the CDROM player programs should then work (workman, | 
| Randy Dunlap | b911e47 | 2008-10-10 08:22:44 +0200 | [diff] [blame] | 148 | workbone, cdplayer, etc.). | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 149 |  | 
|  | 150 | On a few drives, you can read digital audio directly using a program | 
|  | 151 | such as cdda2wav.  The only types of drive which I've heard support | 
|  | 152 | this are Sony and Toshiba drives.  You will get errors if you try to | 
|  | 153 | use this function on a drive which does not support it. | 
|  | 154 |  | 
|  | 155 | For supported changers, you can use the `cdchange' program (appended to | 
|  | 156 | the end of this file) to switch between changer slots.  Note that the | 
|  | 157 | drive should be unmounted before attempting this.  The program takes | 
|  | 158 | two arguments:  the CDROM device, and the slot number to which you wish | 
|  | 159 | to change.  If the slot number is -1, the drive is unloaded. | 
|  | 160 |  | 
|  | 161 |  | 
|  | 162 | 4. Compilation options | 
|  | 163 | ---------------------- | 
|  | 164 |  | 
|  | 165 | There are a few additional options which can be set when compiling the | 
|  | 166 | driver.  Most people should not need to mess with any of these; they | 
|  | 167 | are listed here simply for completeness.  A compilation option can be | 
|  | 168 | enabled by adding a line of the form `#define <option> 1' to the top | 
|  | 169 | of ide-cd.c.  All these options are disabled by default. | 
|  | 170 |  | 
|  | 171 | VERBOSE_IDE_CD_ERRORS | 
|  | 172 | If this is set, ATAPI error codes will be translated into textual | 
|  | 173 | descriptions.  In addition, a dump is made of the command which | 
|  | 174 | provoked the error.  This is off by default to save the memory used | 
|  | 175 | by the (somewhat long) table of error descriptions. | 
|  | 176 |  | 
|  | 177 | STANDARD_ATAPI | 
|  | 178 | If this is set, the code needed to deal with certain drives which do | 
|  | 179 | not properly implement the ATAPI spec will be disabled.  If you know | 
|  | 180 | your drive implements ATAPI properly, you can turn this on to get a | 
|  | 181 | slightly smaller kernel. | 
|  | 182 |  | 
|  | 183 | NO_DOOR_LOCKING | 
|  | 184 | If this is set, the driver will never attempt to lock the door of | 
|  | 185 | the drive. | 
|  | 186 |  | 
|  | 187 | CDROM_NBLOCKS_BUFFER | 
|  | 188 | This sets the size of the buffer to be used for a CDROMREADAUDIO | 
|  | 189 | ioctl.  The default is 8. | 
|  | 190 |  | 
|  | 191 | TEST | 
|  | 192 | This currently enables an additional ioctl which enables a user-mode | 
|  | 193 | program to execute an arbitrary packet command.  See the source for | 
|  | 194 | details.  This should be left off unless you know what you're doing. | 
|  | 195 |  | 
|  | 196 |  | 
|  | 197 | 5. Common problems | 
|  | 198 | ------------------ | 
|  | 199 |  | 
|  | 200 | This section discusses some common problems encountered when trying to | 
|  | 201 | use the driver, and some possible solutions.  Note that if you are | 
|  | 202 | experiencing problems, you should probably also review | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 203 | Documentation/ide/ide.txt for current information about the underlying | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 204 | IDE support code.  Some of these items apply only to earlier versions | 
|  | 205 | of the driver, but are mentioned here for completeness. | 
|  | 206 |  | 
|  | 207 | In most cases, you should probably check with `dmesg' for any errors | 
|  | 208 | from the driver. | 
|  | 209 |  | 
|  | 210 | a. Drive is not detected during booting. | 
|  | 211 |  | 
|  | 212 | - Review the configuration instructions above and in | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 213 | Documentation/ide/ide.txt, and check how your hardware is | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 214 | configured. | 
|  | 215 |  | 
|  | 216 | - If your drive is the only device on an IDE interface, it should | 
|  | 217 | be jumpered as master, if at all possible. | 
|  | 218 |  | 
|  | 219 | - If your IDE interface is not at the standard addresses of 0x170 | 
|  | 220 | or 0x1f0, you'll need to explicitly inform the driver using a | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 221 | lilo option.  See Documentation/ide/ide.txt.  (This feature was | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 222 | added around kernel version 1.3.30.) | 
|  | 223 |  | 
|  | 224 | - If the autoprobing is not finding your drive, you can tell the | 
|  | 225 | driver to assume that one exists by using a lilo option of the | 
|  | 226 | form `hdX=cdrom', where X is the drive letter corresponding to | 
|  | 227 | where your drive is installed.  Note that if you do this and you | 
|  | 228 | see a boot message like | 
|  | 229 |  | 
|  | 230 | hdX: ATAPI cdrom (?) | 
|  | 231 |  | 
|  | 232 | this does _not_ mean that the driver has successfully detected | 
|  | 233 | the drive; rather, it means that the driver has not detected a | 
|  | 234 | drive, but is assuming there's one there anyway because you told | 
|  | 235 | it so.  If you actually try to do I/O to a drive defined at a | 
|  | 236 | nonexistent or nonresponding I/O address, you'll probably get | 
|  | 237 | errors with a status value of 0xff. | 
|  | 238 |  | 
|  | 239 | - Some IDE adapters require a nonstandard initialization sequence | 
|  | 240 | before they'll function properly.  (If this is the case, there | 
|  | 241 | will often be a separate MS-DOS driver just for the controller.) | 
|  | 242 | IDE interfaces on sound cards often fall into this category. | 
|  | 243 |  | 
|  | 244 | Support for some interfaces needing extra initialization is | 
|  | 245 | provided in later 1.3.x kernels.  You may need to turn on | 
|  | 246 | additional kernel configuration options to get them to work; | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 247 | see Documentation/ide/ide.txt. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 248 |  | 
|  | 249 | Even if support is not available for your interface, you may be | 
|  | 250 | able to get it to work with the following procedure.  First boot | 
|  | 251 | MS-DOS and load the appropriate drivers.  Then warm-boot linux | 
|  | 252 | (i.e., without powering off).  If this works, it can be automated | 
|  | 253 | by running loadlin from the MS-DOS autoexec. | 
|  | 254 |  | 
|  | 255 |  | 
|  | 256 | b. Timeout/IRQ errors. | 
|  | 257 |  | 
|  | 258 | - If you always get timeout errors, interrupts from the drive are | 
|  | 259 | probably not making it to the host. | 
|  | 260 |  | 
|  | 261 | - IRQ problems may also be indicated by the message | 
|  | 262 | `IRQ probe failed (<n>)' while booting.  If <n> is zero, that | 
|  | 263 | means that the system did not see an interrupt from the drive when | 
|  | 264 | it was expecting one (on any feasible IRQ).  If <n> is negative, | 
|  | 265 | that means the system saw interrupts on multiple IRQ lines, when | 
|  | 266 | it was expecting to receive just one from the CDROM drive. | 
|  | 267 |  | 
|  | 268 | - Double-check your hardware configuration to make sure that the IRQ | 
|  | 269 | number of your IDE interface matches what the driver expects. | 
|  | 270 | (The usual assignments are 14 for the primary (0x1f0) interface | 
|  | 271 | and 15 for the secondary (0x170) interface.)  Also be sure that | 
|  | 272 | you don't have some other hardware which might be conflicting with | 
|  | 273 | the IRQ you're using.  Also check the BIOS setup for your system; | 
|  | 274 | some have the ability to disable individual IRQ levels, and I've | 
|  | 275 | had one report of a system which was shipped with IRQ 15 disabled | 
|  | 276 | by default. | 
|  | 277 |  | 
|  | 278 | - Note that many MS-DOS CDROM drivers will still function even if | 
|  | 279 | there are hardware problems with the interrupt setup; they | 
|  | 280 | apparently don't use interrupts. | 
|  | 281 |  | 
|  | 282 | - If you own a Pioneer DR-A24X, you _will_ get nasty error messages | 
|  | 283 | on boot such as "irq timeout: status=0x50 { DriveReady SeekComplete }" | 
|  | 284 | The Pioneer DR-A24X CDROM drives are fairly popular these days. | 
|  | 285 | Unfortunately, these drives seem to become very confused when we perform | 
|  | 286 | the standard Linux ATA disk drive probe. If you own one of these drives, | 
|  | 287 | you can bypass the ATA probing which confuses these CDROM drives, by | 
|  | 288 | adding `append="hdX=noprobe hdX=cdrom"' to your lilo.conf file and running | 
|  | 289 | lilo (again where X is the drive letter corresponding to where your drive | 
|  | 290 | is installed.) | 
|  | 291 |  | 
|  | 292 | c. System hangups. | 
|  | 293 |  | 
|  | 294 | - If the system locks up when you try to access the CDROM, the most | 
|  | 295 | likely cause is that you have a buggy IDE adapter which doesn't | 
|  | 296 | properly handle simultaneous transactions on multiple interfaces. | 
|  | 297 | The most notorious of these is the CMD640B chip.  This problem can | 
|  | 298 | be worked around by specifying the `serialize' option when | 
|  | 299 | booting.  Recent kernels should be able to detect the need for | 
|  | 300 | this automatically in most cases, but the detection is not | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 301 | foolproof.  See Documentation/ide/ide.txt for more information | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 302 | about the `serialize' option and the CMD640B. | 
|  | 303 |  | 
|  | 304 | - Note that many MS-DOS CDROM drivers will work with such buggy | 
|  | 305 | hardware, apparently because they never attempt to overlap CDROM | 
|  | 306 | operations with other disk activity. | 
|  | 307 |  | 
|  | 308 |  | 
|  | 309 | d. Can't mount a CDROM. | 
|  | 310 |  | 
|  | 311 | - If you get errors from mount, it may help to check `dmesg' to see | 
|  | 312 | if there are any more specific errors from the driver or from the | 
|  | 313 | filesystem. | 
|  | 314 |  | 
|  | 315 | - Make sure there's a CDROM loaded in the drive, and that's it's an | 
|  | 316 | ISO 9660 disc.  You can't mount an audio CD. | 
|  | 317 |  | 
|  | 318 | - With the CDROM in the drive and unmounted, try something like | 
|  | 319 |  | 
|  | 320 | cat /dev/cdrom | od | more | 
|  | 321 |  | 
|  | 322 | If you see a dump, then the drive and driver are probably working | 
|  | 323 | OK, and the problem is at the filesystem level (i.e., the CDROM is | 
|  | 324 | not ISO 9660 or has errors in the filesystem structure). | 
|  | 325 |  | 
|  | 326 | - If you see `not a block device' errors, check that the definitions | 
|  | 327 | of the device special files are correct.  They should be as | 
|  | 328 | follows: | 
|  | 329 |  | 
|  | 330 | brw-rw----   1 root     disk       3,   0 Nov 11 18:48 /dev/hda | 
|  | 331 | brw-rw----   1 root     disk       3,  64 Nov 11 18:48 /dev/hdb | 
|  | 332 | brw-rw----   1 root     disk      22,   0 Nov 11 18:48 /dev/hdc | 
|  | 333 | brw-rw----   1 root     disk      22,  64 Nov 11 18:48 /dev/hdd | 
|  | 334 |  | 
|  | 335 | Some early Slackware releases had these defined incorrectly.  If | 
|  | 336 | these are wrong, you can remake them by running the script | 
|  | 337 | scripts/MAKEDEV.ide.  (You may have to make it executable | 
|  | 338 | with chmod first.) | 
|  | 339 |  | 
|  | 340 | If you have a /dev/cdrom symbolic link, check that it is pointing | 
|  | 341 | to the correct device file. | 
|  | 342 |  | 
|  | 343 | If you hear people talking of the devices `hd1a' and `hd1b', these | 
|  | 344 | were old names for what are now called hdc and hdd.  Those names | 
|  | 345 | should be considered obsolete. | 
|  | 346 |  | 
|  | 347 | - If mount is complaining that the iso9660 filesystem is not | 
|  | 348 | available, but you know it is (check /proc/filesystems), you | 
|  | 349 | probably need a newer version of mount.  Early versions would not | 
|  | 350 | always give meaningful error messages. | 
|  | 351 |  | 
|  | 352 |  | 
|  | 353 | e. Directory listings are unpredictably truncated, and `dmesg' shows | 
|  | 354 | `buffer botch' error messages from the driver. | 
|  | 355 |  | 
|  | 356 | - There was a bug in the version of the driver in 1.2.x kernels | 
|  | 357 | which could cause this.  It was fixed in 1.3.0.  If you can't | 
|  | 358 | upgrade, you can probably work around the problem by specifying a | 
|  | 359 | blocksize of 2048 when mounting.  (Note that you won't be able to | 
|  | 360 | directly execute binaries off the CDROM in that case.) | 
|  | 361 |  | 
|  | 362 | If you see this in kernels later than 1.3.0, please report it as a | 
|  | 363 | bug. | 
|  | 364 |  | 
|  | 365 |  | 
|  | 366 | f. Data corruption. | 
|  | 367 |  | 
|  | 368 | - Random data corruption was occasionally observed with the Hitachi | 
|  | 369 | CDR-7730 CDROM. If you experience data corruption, using "hdx=slow" | 
|  | 370 | as a command line parameter may work around the problem, at the | 
|  | 371 | expense of low system performance. | 
|  | 372 |  | 
|  | 373 |  | 
|  | 374 | 6. cdchange.c | 
|  | 375 | ------------- | 
|  | 376 |  | 
|  | 377 | /* | 
|  | 378 | * cdchange.c  [-v]  <device>  [<slot>] | 
|  | 379 | * | 
|  | 380 | * This loads a CDROM from a specified slot in a changer, and displays | 
|  | 381 | * information about the changer status.  The drive should be unmounted before | 
|  | 382 | * using this program. | 
|  | 383 | * | 
|  | 384 | * Changer information is displayed if either the -v flag is specified | 
|  | 385 | * or no slot was specified. | 
|  | 386 | * | 
|  | 387 | * Based on code originally from Gerhard Zuber <zuber@berlin.snafu.de>. | 
|  | 388 | * Changer status information, and rewrite for the new Uniform CDROM driver | 
|  | 389 | * interface by Erik Andersen <andersee@debian.org>. | 
|  | 390 | */ | 
|  | 391 |  | 
|  | 392 | #include <stdio.h> | 
|  | 393 | #include <stdlib.h> | 
|  | 394 | #include <errno.h> | 
|  | 395 | #include <string.h> | 
|  | 396 | #include <unistd.h> | 
|  | 397 | #include <fcntl.h> | 
|  | 398 | #include <sys/ioctl.h> | 
|  | 399 | #include <linux/cdrom.h> | 
|  | 400 |  | 
|  | 401 |  | 
|  | 402 | int | 
|  | 403 | main (int argc, char **argv) | 
|  | 404 | { | 
|  | 405 | char *program; | 
|  | 406 | char *device; | 
|  | 407 | int fd;           /* file descriptor for CD-ROM device */ | 
|  | 408 | int status;       /* return status for system calls */ | 
|  | 409 | int verbose = 0; | 
|  | 410 | int slot=-1, x_slot; | 
|  | 411 | int total_slots_available; | 
|  | 412 |  | 
|  | 413 | program = argv[0]; | 
|  | 414 |  | 
|  | 415 | ++argv; | 
|  | 416 | --argc; | 
|  | 417 |  | 
|  | 418 | if (argc < 1 || argc > 3) { | 
|  | 419 | fprintf (stderr, "usage: %s [-v] <device> [<slot>]\n", | 
|  | 420 | program); | 
|  | 421 | fprintf (stderr, "       Slots are numbered 1 -- n.\n"); | 
|  | 422 | exit (1); | 
|  | 423 | } | 
|  | 424 |  | 
|  | 425 | if (strcmp (argv[0], "-v") == 0) { | 
|  | 426 | verbose = 1; | 
|  | 427 | ++argv; | 
|  | 428 | --argc; | 
|  | 429 | } | 
|  | 430 |  | 
|  | 431 | device = argv[0]; | 
|  | 432 |  | 
|  | 433 | if (argc == 2) | 
|  | 434 | slot = atoi (argv[1]) - 1; | 
|  | 435 |  | 
|  | 436 | /* open device */ | 
|  | 437 | fd = open(device, O_RDONLY | O_NONBLOCK); | 
|  | 438 | if (fd < 0) { | 
|  | 439 | fprintf (stderr, "%s: open failed for `%s': %s\n", | 
|  | 440 | program, device, strerror (errno)); | 
|  | 441 | exit (1); | 
|  | 442 | } | 
|  | 443 |  | 
|  | 444 | /* Check CD player status */ | 
|  | 445 | total_slots_available = ioctl (fd, CDROM_CHANGER_NSLOTS); | 
|  | 446 | if (total_slots_available <= 1 ) { | 
|  | 447 | fprintf (stderr, "%s: Device `%s' is not an ATAPI " | 
|  | 448 | "compliant CD changer.\n", program, device); | 
|  | 449 | exit (1); | 
|  | 450 | } | 
|  | 451 |  | 
|  | 452 | if (slot >= 0) { | 
|  | 453 | if (slot >= total_slots_available) { | 
|  | 454 | fprintf (stderr, "Bad slot number.  " | 
|  | 455 | "Should be 1 -- %d.\n", | 
|  | 456 | total_slots_available); | 
|  | 457 | exit (1); | 
|  | 458 | } | 
|  | 459 |  | 
|  | 460 | /* load */ | 
|  | 461 | slot=ioctl (fd, CDROM_SELECT_DISC, slot); | 
|  | 462 | if (slot<0) { | 
|  | 463 | fflush(stdout); | 
|  | 464 | perror ("CDROM_SELECT_DISC "); | 
|  | 465 | exit(1); | 
|  | 466 | } | 
|  | 467 | } | 
|  | 468 |  | 
|  | 469 | if (slot < 0 || verbose) { | 
|  | 470 |  | 
|  | 471 | status=ioctl (fd, CDROM_SELECT_DISC, CDSL_CURRENT); | 
|  | 472 | if (status<0) { | 
|  | 473 | fflush(stdout); | 
|  | 474 | perror (" CDROM_SELECT_DISC"); | 
|  | 475 | exit(1); | 
|  | 476 | } | 
|  | 477 | slot=status; | 
|  | 478 |  | 
|  | 479 | printf ("Current slot: %d\n", slot+1); | 
|  | 480 | printf ("Total slots available: %d\n", | 
|  | 481 | total_slots_available); | 
|  | 482 |  | 
|  | 483 | printf ("Drive status: "); | 
|  | 484 | status = ioctl (fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); | 
|  | 485 | if (status<0) { | 
|  | 486 | perror(" CDROM_DRIVE_STATUS"); | 
|  | 487 | } else switch(status) { | 
|  | 488 | case CDS_DISC_OK: | 
|  | 489 | printf ("Ready.\n"); | 
|  | 490 | break; | 
|  | 491 | case CDS_TRAY_OPEN: | 
|  | 492 | printf ("Tray Open.\n"); | 
|  | 493 | break; | 
|  | 494 | case CDS_DRIVE_NOT_READY: | 
|  | 495 | printf ("Drive Not Ready.\n"); | 
|  | 496 | break; | 
|  | 497 | default: | 
|  | 498 | printf ("This Should not happen!\n"); | 
|  | 499 | break; | 
|  | 500 | } | 
|  | 501 |  | 
|  | 502 | for (x_slot=0; x_slot<total_slots_available; x_slot++) { | 
|  | 503 | printf ("Slot %2d: ", x_slot+1); | 
|  | 504 | status = ioctl (fd, CDROM_DRIVE_STATUS, x_slot); | 
|  | 505 | if (status<0) { | 
|  | 506 | perror(" CDROM_DRIVE_STATUS"); | 
|  | 507 | } else switch(status) { | 
|  | 508 | case CDS_DISC_OK: | 
|  | 509 | printf ("Disc present."); | 
|  | 510 | break; | 
|  | 511 | case CDS_NO_DISC: | 
|  | 512 | printf ("Empty slot."); | 
|  | 513 | break; | 
|  | 514 | case CDS_TRAY_OPEN: | 
|  | 515 | printf ("CD-ROM tray open.\n"); | 
|  | 516 | break; | 
|  | 517 | case CDS_DRIVE_NOT_READY: | 
|  | 518 | printf ("CD-ROM drive not ready.\n"); | 
|  | 519 | break; | 
|  | 520 | case CDS_NO_INFO: | 
|  | 521 | printf ("No Information available."); | 
|  | 522 | break; | 
|  | 523 | default: | 
|  | 524 | printf ("This Should not happen!\n"); | 
|  | 525 | break; | 
|  | 526 | } | 
|  | 527 | if (slot == x_slot) { | 
|  | 528 | status = ioctl (fd, CDROM_DISC_STATUS); | 
|  | 529 | if (status<0) { | 
|  | 530 | perror(" CDROM_DISC_STATUS"); | 
|  | 531 | } | 
|  | 532 | switch (status) { | 
|  | 533 | case CDS_AUDIO: | 
|  | 534 | printf ("\tAudio disc.\t"); | 
|  | 535 | break; | 
|  | 536 | case CDS_DATA_1: | 
|  | 537 | case CDS_DATA_2: | 
|  | 538 | printf ("\tData disc type %d.\t", status-CDS_DATA_1+1); | 
|  | 539 | break; | 
|  | 540 | case CDS_XA_2_1: | 
|  | 541 | case CDS_XA_2_2: | 
|  | 542 | printf ("\tXA data disc type %d.\t", status-CDS_XA_2_1+1); | 
|  | 543 | break; | 
|  | 544 | default: | 
|  | 545 | printf ("\tUnknown disc type 0x%x!\t", status); | 
|  | 546 | break; | 
|  | 547 | } | 
|  | 548 | } | 
|  | 549 | status = ioctl (fd, CDROM_MEDIA_CHANGED, x_slot); | 
|  | 550 | if (status<0) { | 
|  | 551 | perror(" CDROM_MEDIA_CHANGED"); | 
|  | 552 | } | 
|  | 553 | switch (status) { | 
|  | 554 | case 1: | 
|  | 555 | printf ("Changed.\n"); | 
|  | 556 | break; | 
|  | 557 | default: | 
|  | 558 | printf ("\n"); | 
|  | 559 | break; | 
|  | 560 | } | 
|  | 561 | } | 
|  | 562 | } | 
|  | 563 |  | 
|  | 564 | /* close device */ | 
|  | 565 | status = close (fd); | 
|  | 566 | if (status != 0) { | 
|  | 567 | fprintf (stderr, "%s: close failed for `%s': %s\n", | 
|  | 568 | program, device, strerror (errno)); | 
|  | 569 | exit (1); | 
|  | 570 | } | 
|  | 571 |  | 
|  | 572 | exit (0); | 
|  | 573 | } |