| 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 |  | 
| Thadeu Lima de Souza Cascardo | 1c8a375 | 2009-12-13 20:41:53 -0800 | [diff] [blame] | 162 | 4. Common problems | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 163 | ------------------ | 
 | 164 |  | 
 | 165 | This section discusses some common problems encountered when trying to | 
 | 166 | use the driver, and some possible solutions.  Note that if you are | 
 | 167 | experiencing problems, you should probably also review | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 168 | Documentation/ide/ide.txt for current information about the underlying | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 169 | IDE support code.  Some of these items apply only to earlier versions | 
 | 170 | of the driver, but are mentioned here for completeness. | 
 | 171 |  | 
 | 172 | In most cases, you should probably check with `dmesg' for any errors | 
 | 173 | from the driver. | 
 | 174 |  | 
 | 175 | a. Drive is not detected during booting. | 
 | 176 |  | 
 | 177 |    - Review the configuration instructions above and in | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 178 |      Documentation/ide/ide.txt, and check how your hardware is | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 179 |      configured. | 
 | 180 |  | 
 | 181 |    - If your drive is the only device on an IDE interface, it should | 
 | 182 |      be jumpered as master, if at all possible. | 
 | 183 |  | 
 | 184 |    - If your IDE interface is not at the standard addresses of 0x170 | 
 | 185 |      or 0x1f0, you'll need to explicitly inform the driver using a | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 186 |      lilo option.  See Documentation/ide/ide.txt.  (This feature was | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 187 |      added around kernel version 1.3.30.) | 
 | 188 |  | 
 | 189 |    - If the autoprobing is not finding your drive, you can tell the | 
 | 190 |      driver to assume that one exists by using a lilo option of the | 
 | 191 |      form `hdX=cdrom', where X is the drive letter corresponding to | 
 | 192 |      where your drive is installed.  Note that if you do this and you  | 
 | 193 |      see a boot message like | 
 | 194 |  | 
 | 195 |        hdX: ATAPI cdrom (?) | 
 | 196 |  | 
 | 197 |      this does _not_ mean that the driver has successfully detected | 
 | 198 |      the drive; rather, it means that the driver has not detected a | 
 | 199 |      drive, but is assuming there's one there anyway because you told | 
 | 200 |      it so.  If you actually try to do I/O to a drive defined at a | 
 | 201 |      nonexistent or nonresponding I/O address, you'll probably get | 
 | 202 |      errors with a status value of 0xff. | 
 | 203 |  | 
 | 204 |    - Some IDE adapters require a nonstandard initialization sequence | 
 | 205 |      before they'll function properly.  (If this is the case, there | 
 | 206 |      will often be a separate MS-DOS driver just for the controller.) | 
 | 207 |      IDE interfaces on sound cards often fall into this category. | 
 | 208 |  | 
 | 209 |      Support for some interfaces needing extra initialization is | 
 | 210 |      provided in later 1.3.x kernels.  You may need to turn on | 
 | 211 |      additional kernel configuration options to get them to work; | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 212 |      see Documentation/ide/ide.txt. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 213 |  | 
 | 214 |      Even if support is not available for your interface, you may be | 
 | 215 |      able to get it to work with the following procedure.  First boot | 
 | 216 |      MS-DOS and load the appropriate drivers.  Then warm-boot linux | 
 | 217 |      (i.e., without powering off).  If this works, it can be automated | 
 | 218 |      by running loadlin from the MS-DOS autoexec. | 
 | 219 |  | 
 | 220 |  | 
 | 221 | b. Timeout/IRQ errors. | 
 | 222 |  | 
 | 223 |   - If you always get timeout errors, interrupts from the drive are | 
 | 224 |     probably not making it to the host. | 
 | 225 |  | 
 | 226 |   - IRQ problems may also be indicated by the message | 
 | 227 |     `IRQ probe failed (<n>)' while booting.  If <n> is zero, that | 
 | 228 |     means that the system did not see an interrupt from the drive when | 
 | 229 |     it was expecting one (on any feasible IRQ).  If <n> is negative, | 
 | 230 |     that means the system saw interrupts on multiple IRQ lines, when | 
 | 231 |     it was expecting to receive just one from the CDROM drive. | 
 | 232 |  | 
 | 233 |   - Double-check your hardware configuration to make sure that the IRQ | 
 | 234 |     number of your IDE interface matches what the driver expects. | 
 | 235 |     (The usual assignments are 14 for the primary (0x1f0) interface | 
 | 236 |     and 15 for the secondary (0x170) interface.)  Also be sure that | 
 | 237 |     you don't have some other hardware which might be conflicting with | 
 | 238 |     the IRQ you're using.  Also check the BIOS setup for your system; | 
 | 239 |     some have the ability to disable individual IRQ levels, and I've | 
 | 240 |     had one report of a system which was shipped with IRQ 15 disabled | 
 | 241 |     by default. | 
 | 242 |  | 
 | 243 |   - Note that many MS-DOS CDROM drivers will still function even if | 
 | 244 |     there are hardware problems with the interrupt setup; they | 
 | 245 |     apparently don't use interrupts. | 
 | 246 |  | 
 | 247 |   - If you own a Pioneer DR-A24X, you _will_ get nasty error messages  | 
 | 248 |     on boot such as "irq timeout: status=0x50 { DriveReady SeekComplete }" | 
 | 249 |     The Pioneer DR-A24X CDROM drives are fairly popular these days. | 
 | 250 |     Unfortunately, these drives seem to become very confused when we perform | 
 | 251 |     the standard Linux ATA disk drive probe. If you own one of these drives, | 
 | 252 |     you can bypass the ATA probing which confuses these CDROM drives, by  | 
 | 253 |     adding `append="hdX=noprobe hdX=cdrom"' to your lilo.conf file and running  | 
 | 254 |     lilo (again where X is the drive letter corresponding to where your drive  | 
 | 255 |     is installed.) | 
 | 256 |      | 
 | 257 | c. System hangups. | 
 | 258 |  | 
 | 259 |   - If the system locks up when you try to access the CDROM, the most | 
 | 260 |     likely cause is that you have a buggy IDE adapter which doesn't | 
 | 261 |     properly handle simultaneous transactions on multiple interfaces. | 
 | 262 |     The most notorious of these is the CMD640B chip.  This problem can | 
 | 263 |     be worked around by specifying the `serialize' option when | 
 | 264 |     booting.  Recent kernels should be able to detect the need for | 
 | 265 |     this automatically in most cases, but the detection is not | 
| Randy Dunlap | 1c10e93 | 2008-03-07 21:53:50 +0100 | [diff] [blame] | 266 |     foolproof.  See Documentation/ide/ide.txt for more information | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 267 |     about the `serialize' option and the CMD640B. | 
 | 268 |  | 
 | 269 |   - Note that many MS-DOS CDROM drivers will work with such buggy | 
 | 270 |     hardware, apparently because they never attempt to overlap CDROM | 
 | 271 |     operations with other disk activity. | 
 | 272 |  | 
 | 273 |  | 
 | 274 | d. Can't mount a CDROM. | 
 | 275 |  | 
 | 276 |   - If you get errors from mount, it may help to check `dmesg' to see | 
 | 277 |     if there are any more specific errors from the driver or from the | 
 | 278 |     filesystem. | 
 | 279 |  | 
 | 280 |   - Make sure there's a CDROM loaded in the drive, and that's it's an | 
 | 281 |     ISO 9660 disc.  You can't mount an audio CD. | 
 | 282 |  | 
 | 283 |   - With the CDROM in the drive and unmounted, try something like | 
 | 284 |  | 
 | 285 |       cat /dev/cdrom | od | more | 
 | 286 |  | 
 | 287 |     If you see a dump, then the drive and driver are probably working | 
 | 288 |     OK, and the problem is at the filesystem level (i.e., the CDROM is | 
 | 289 |     not ISO 9660 or has errors in the filesystem structure). | 
 | 290 |  | 
 | 291 |   - If you see `not a block device' errors, check that the definitions | 
 | 292 |     of the device special files are correct.  They should be as | 
 | 293 |     follows: | 
 | 294 |  | 
 | 295 |       brw-rw----   1 root     disk       3,   0 Nov 11 18:48 /dev/hda | 
 | 296 |       brw-rw----   1 root     disk       3,  64 Nov 11 18:48 /dev/hdb | 
 | 297 |       brw-rw----   1 root     disk      22,   0 Nov 11 18:48 /dev/hdc | 
 | 298 |       brw-rw----   1 root     disk      22,  64 Nov 11 18:48 /dev/hdd | 
 | 299 |  | 
 | 300 |     Some early Slackware releases had these defined incorrectly.  If | 
 | 301 |     these are wrong, you can remake them by running the script | 
 | 302 |     scripts/MAKEDEV.ide.  (You may have to make it executable | 
 | 303 |     with chmod first.) | 
 | 304 |  | 
 | 305 |     If you have a /dev/cdrom symbolic link, check that it is pointing | 
 | 306 |     to the correct device file. | 
 | 307 |  | 
 | 308 |     If you hear people talking of the devices `hd1a' and `hd1b', these | 
 | 309 |     were old names for what are now called hdc and hdd.  Those names | 
 | 310 |     should be considered obsolete. | 
 | 311 |  | 
 | 312 |   - If mount is complaining that the iso9660 filesystem is not | 
 | 313 |     available, but you know it is (check /proc/filesystems), you | 
 | 314 |     probably need a newer version of mount.  Early versions would not | 
 | 315 |     always give meaningful error messages. | 
 | 316 |  | 
 | 317 |  | 
 | 318 | e. Directory listings are unpredictably truncated, and `dmesg' shows | 
 | 319 |    `buffer botch' error messages from the driver. | 
 | 320 |  | 
 | 321 |   - There was a bug in the version of the driver in 1.2.x kernels | 
 | 322 |     which could cause this.  It was fixed in 1.3.0.  If you can't | 
 | 323 |     upgrade, you can probably work around the problem by specifying a | 
 | 324 |     blocksize of 2048 when mounting.  (Note that you won't be able to | 
 | 325 |     directly execute binaries off the CDROM in that case.) | 
 | 326 |  | 
 | 327 |     If you see this in kernels later than 1.3.0, please report it as a | 
 | 328 |     bug. | 
 | 329 |  | 
 | 330 |  | 
 | 331 | f. Data corruption. | 
 | 332 |  | 
 | 333 |   - Random data corruption was occasionally observed with the Hitachi | 
 | 334 |     CDR-7730 CDROM. If you experience data corruption, using "hdx=slow" | 
 | 335 |     as a command line parameter may work around the problem, at the | 
 | 336 |     expense of low system performance. | 
 | 337 |  | 
 | 338 |  | 
| Thadeu Lima de Souza Cascardo | 1c8a375 | 2009-12-13 20:41:53 -0800 | [diff] [blame] | 339 | 5. cdchange.c | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 340 | ------------- | 
 | 341 |  | 
 | 342 | /* | 
 | 343 |  * cdchange.c  [-v]  <device>  [<slot>] | 
 | 344 |  * | 
 | 345 |  * This loads a CDROM from a specified slot in a changer, and displays  | 
 | 346 |  * information about the changer status.  The drive should be unmounted before  | 
 | 347 |  * using this program. | 
 | 348 |  * | 
 | 349 |  * Changer information is displayed if either the -v flag is specified | 
 | 350 |  * or no slot was specified. | 
 | 351 |  * | 
 | 352 |  * Based on code originally from Gerhard Zuber <zuber@berlin.snafu.de>. | 
 | 353 |  * Changer status information, and rewrite for the new Uniform CDROM driver | 
 | 354 |  * interface by Erik Andersen <andersee@debian.org>. | 
 | 355 |  */ | 
 | 356 |  | 
 | 357 | #include <stdio.h> | 
 | 358 | #include <stdlib.h> | 
 | 359 | #include <errno.h> | 
 | 360 | #include <string.h> | 
 | 361 | #include <unistd.h> | 
 | 362 | #include <fcntl.h> | 
 | 363 | #include <sys/ioctl.h> | 
 | 364 | #include <linux/cdrom.h> | 
 | 365 |  | 
 | 366 |  | 
 | 367 | int | 
 | 368 | main (int argc, char **argv) | 
 | 369 | { | 
 | 370 | 	char *program; | 
 | 371 | 	char *device; | 
 | 372 | 	int fd;           /* file descriptor for CD-ROM device */ | 
 | 373 | 	int status;       /* return status for system calls */ | 
 | 374 | 	int verbose = 0; | 
 | 375 | 	int slot=-1, x_slot; | 
 | 376 | 	int total_slots_available; | 
 | 377 |  | 
 | 378 | 	program = argv[0]; | 
 | 379 |  | 
 | 380 | 	++argv; | 
 | 381 | 	--argc; | 
 | 382 |  | 
 | 383 | 	if (argc < 1 || argc > 3) { | 
 | 384 | 		fprintf (stderr, "usage: %s [-v] <device> [<slot>]\n", | 
 | 385 | 			 program); | 
 | 386 | 		fprintf (stderr, "       Slots are numbered 1 -- n.\n"); | 
 | 387 | 		exit (1); | 
 | 388 | 	} | 
 | 389 |   | 
 | 390 |        if (strcmp (argv[0], "-v") == 0) { | 
 | 391 |                 verbose = 1; | 
 | 392 |                 ++argv; | 
 | 393 |                 --argc; | 
 | 394 |         } | 
 | 395 |   | 
 | 396 | 	device = argv[0]; | 
 | 397 |   | 
 | 398 | 	if (argc == 2) | 
 | 399 | 		slot = atoi (argv[1]) - 1; | 
 | 400 |  | 
 | 401 | 	/* open device */  | 
 | 402 | 	fd = open(device, O_RDONLY | O_NONBLOCK); | 
 | 403 | 	if (fd < 0) { | 
 | 404 | 		fprintf (stderr, "%s: open failed for `%s': %s\n", | 
 | 405 | 			 program, device, strerror (errno)); | 
 | 406 | 		exit (1); | 
 | 407 | 	} | 
 | 408 |  | 
 | 409 | 	/* Check CD player status */  | 
 | 410 | 	total_slots_available = ioctl (fd, CDROM_CHANGER_NSLOTS); | 
 | 411 | 	if (total_slots_available <= 1 ) { | 
 | 412 | 		fprintf (stderr, "%s: Device `%s' is not an ATAPI " | 
 | 413 | 			"compliant CD changer.\n", program, device); | 
 | 414 | 		exit (1); | 
 | 415 | 	} | 
 | 416 |  | 
 | 417 | 	if (slot >= 0) { | 
 | 418 | 		if (slot >= total_slots_available) { | 
 | 419 | 			fprintf (stderr, "Bad slot number.  " | 
 | 420 | 				 "Should be 1 -- %d.\n", | 
 | 421 | 				 total_slots_available); | 
 | 422 | 			exit (1); | 
 | 423 | 		} | 
 | 424 |  | 
 | 425 | 		/* load */  | 
 | 426 | 		slot=ioctl (fd, CDROM_SELECT_DISC, slot); | 
 | 427 | 		if (slot<0) { | 
 | 428 | 			fflush(stdout); | 
 | 429 | 				perror ("CDROM_SELECT_DISC "); | 
 | 430 | 			exit(1); | 
 | 431 | 		} | 
 | 432 | 	} | 
 | 433 |  | 
 | 434 | 	if (slot < 0 || verbose) { | 
 | 435 |  | 
 | 436 | 		status=ioctl (fd, CDROM_SELECT_DISC, CDSL_CURRENT); | 
 | 437 | 		if (status<0) { | 
 | 438 | 			fflush(stdout); | 
 | 439 | 			perror (" CDROM_SELECT_DISC"); | 
 | 440 | 			exit(1); | 
 | 441 | 		} | 
 | 442 | 		slot=status; | 
 | 443 |  | 
 | 444 | 		printf ("Current slot: %d\n", slot+1); | 
 | 445 | 		printf ("Total slots available: %d\n", | 
 | 446 | 			total_slots_available); | 
 | 447 |  | 
 | 448 | 		printf ("Drive status: "); | 
 | 449 |                 status = ioctl (fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); | 
 | 450 |                 if (status<0) { | 
 | 451 |                   perror(" CDROM_DRIVE_STATUS"); | 
 | 452 |                 } else switch(status) { | 
 | 453 | 		case CDS_DISC_OK: | 
 | 454 | 			printf ("Ready.\n"); | 
 | 455 | 			break; | 
 | 456 | 		case CDS_TRAY_OPEN: | 
 | 457 | 			printf ("Tray Open.\n"); | 
 | 458 | 			break; | 
 | 459 | 		case CDS_DRIVE_NOT_READY: | 
 | 460 | 			printf ("Drive Not Ready.\n"); | 
 | 461 | 			break; | 
 | 462 | 		default: | 
 | 463 | 			printf ("This Should not happen!\n"); | 
 | 464 | 			break; | 
 | 465 | 		} | 
 | 466 |  | 
 | 467 | 		for (x_slot=0; x_slot<total_slots_available; x_slot++) { | 
 | 468 | 			printf ("Slot %2d: ", x_slot+1); | 
 | 469 |              		status = ioctl (fd, CDROM_DRIVE_STATUS, x_slot); | 
 | 470 |              		if (status<0) { | 
 | 471 |              		     perror(" CDROM_DRIVE_STATUS"); | 
 | 472 |              		} else switch(status) { | 
 | 473 | 			case CDS_DISC_OK: | 
 | 474 | 				printf ("Disc present."); | 
 | 475 | 				break; | 
 | 476 | 			case CDS_NO_DISC:  | 
 | 477 | 				printf ("Empty slot."); | 
 | 478 | 				break; | 
 | 479 | 			case CDS_TRAY_OPEN: | 
 | 480 | 				printf ("CD-ROM tray open.\n"); | 
 | 481 | 				break; | 
 | 482 | 			case CDS_DRIVE_NOT_READY: | 
 | 483 | 				printf ("CD-ROM drive not ready.\n"); | 
 | 484 | 				break; | 
 | 485 | 			case CDS_NO_INFO: | 
 | 486 | 				printf ("No Information available."); | 
 | 487 | 				break; | 
 | 488 | 			default: | 
 | 489 | 				printf ("This Should not happen!\n"); | 
 | 490 | 				break; | 
 | 491 | 			} | 
 | 492 | 		  if (slot == x_slot) { | 
 | 493 |                   status = ioctl (fd, CDROM_DISC_STATUS); | 
 | 494 |                   if (status<0) { | 
 | 495 | 			perror(" CDROM_DISC_STATUS"); | 
 | 496 |                   } | 
 | 497 | 		  switch (status) { | 
 | 498 | 			case CDS_AUDIO: | 
 | 499 | 				printf ("\tAudio disc.\t"); | 
 | 500 | 				break; | 
 | 501 | 			case CDS_DATA_1: | 
 | 502 | 			case CDS_DATA_2: | 
 | 503 | 				printf ("\tData disc type %d.\t", status-CDS_DATA_1+1); | 
 | 504 | 				break; | 
 | 505 | 			case CDS_XA_2_1: | 
 | 506 | 			case CDS_XA_2_2: | 
 | 507 | 				printf ("\tXA data disc type %d.\t", status-CDS_XA_2_1+1); | 
 | 508 | 				break; | 
 | 509 | 			default: | 
 | 510 | 				printf ("\tUnknown disc type 0x%x!\t", status); | 
 | 511 | 				break; | 
 | 512 | 			} | 
 | 513 | 			} | 
 | 514 |                   	status = ioctl (fd, CDROM_MEDIA_CHANGED, x_slot); | 
 | 515 |                   	if (status<0) { | 
 | 516 | 				perror(" CDROM_MEDIA_CHANGED"); | 
 | 517 |                   	} | 
 | 518 | 		  	switch (status) { | 
 | 519 | 			case 1: | 
 | 520 | 				printf ("Changed.\n"); | 
 | 521 | 				break; | 
 | 522 | 			default: | 
 | 523 | 				printf ("\n"); | 
 | 524 | 				break; | 
 | 525 | 			} | 
 | 526 | 		} | 
 | 527 | 	} | 
 | 528 |  | 
 | 529 | 	/* close device */ | 
 | 530 | 	status = close (fd); | 
 | 531 | 	if (status != 0) { | 
 | 532 | 		fprintf (stderr, "%s: close failed for `%s': %s\n", | 
 | 533 | 			 program, device, strerror (errno)); | 
 | 534 | 		exit (1); | 
 | 535 | 	} | 
 | 536 |   | 
 | 537 | 	exit (0); | 
 | 538 | } |