47efedf9194c2cffa33344a7eae550f0c16fa0be
[linux-flexiantxendom0-3.2.10.git] / Documentation / cdrom / sbpcd
1 This README belongs to release 4.2 or newer of the SoundBlaster Pro
2 (Matsushita, Kotobuki, Panasonic, CreativeLabs, Longshine and Teac)
3 CD-ROM driver for Linux.
4
5 sbpcd really, really is NOT for ANY IDE/ATAPI drive!
6 Not even if you have an "original" SoundBlaster card with an IDE interface!
7 So, you'd better have a look into README.ide if your port address is 0x1F0,
8 0x170, 0x1E8, 0x168 or similar.
9 I get tons of mails from IDE/ATAPI drive users - I really can't continue
10 any more to answer them all. So, if your drive/interface information sheets
11 mention "IDE" (primary, secondary, tertiary, quaternary) and the DOS driver
12 invoking line within your CONFIG.SYS is using an address below 0x230:
13 DON'T ROB MY LAST NERVE - jumper your interface to address 0x170 and IRQ 15
14 (that is the "secondary IDE" configuration), set your drive to "master" and
15 use ide-cd as your driver. If you do not have a second IDE hard disk, use the
16 LILO commands
17    hdb=noprobe hdc=cdrom
18 and get lucky.
19 To make it fully clear to you: if you mail me about IDE/ATAPI drive problems,
20 my answer is above, and I simply will discard your mail, hoping to stop the
21 flood and to find time to lead my 12-year old son towards happy computing.
22
23 The driver is able to drive the whole family of "traditional" AT-style (that
24 is NOT the new "Enhanced IDE" or "ATAPI" drive standard) Matsushita,
25 Kotobuki, Panasonic drives, sometimes labelled as "CreativeLabs". The
26 well-known drives are CR-521, CR-522, CR-523, CR-562, CR-563.
27 CR-574 is an IDE/ATAPI drive.
28
29 The Longshine LCS-7260 is a double-speed drive which uses the "old"
30 Matsushita command set. It is supported - with help by Serge Robyns.
31 Vertos ("Elitegroup Computer Systems", ECS) has a similar drive - support
32 has started; get in contact if you have such a "Vertos 100" or "ECS-AT"
33 drive.
34
35 There exists an "IBM External ISA CD-ROM Drive" which in fact is a CR-563
36 with a special controller board. This drive is supported (the interface is
37 of the "LaserMate" type), and it is possibly the best buy today (cheaper than
38 an internal drive, and you can use it as an internal, too - e.g. plug it into
39 a soundcard).
40
41 CreativeLabs has a new drive "CD200" and a similar drive "CD200F". The latter
42 is made by Funai and sometimes named "E2550UA", newer models may be named
43 "MK4015". The CD200F drives should fully work.
44 CD200 drives without "F" are still giving problems: drive detection and
45 playing audio should work, data access will result in errors. I need qualified
46 feedback about the bugs within the data functions or a drive (I never saw a
47 CD200).
48
49 The quad-speed Teac CD-55A drive is supported, but still does not reach "full
50 speed". The data rate already reaches 500 kB/sec if you set SBP_BUFFER_FRAMES
51 to 64 (it is not recommended to do that for normal "file access" usage, but it
52 can speed up things a lot if you use something like "dd" to read from the
53 drive; I use it for verifying self-written CDs this way).
54 The drive itself is able to deliver 600 kB/sec, so this needs
55 work; with the normal setup, the performance currently is not even as good as
56 double-speed.
57
58 This driver is NOT for Mitsumi or Sony or Aztech or Philips or XXX drives,
59 and again: this driver is in no way usable for any IDE/ATAPI drive. If you 
60 think your drive should work and it doesn't: send me the DOS driver for your
61 beast (gzipped + uuencoded) and your CONFIG.SYS if you want to ask me for help,
62 and include an original log message excerpt, and try to give all information
63 a complete idiot needs to understand your hassle already with your first
64 mail. And if you want to say "as I have mailed you before", be sure that I
65 don't remember your "case" by such remarks; at the moment, I have some 
66 hundreds of open correspondences about Linux CDROM questions (hope to reduce if
67 the IDE/ATAPI user questions disappear). 
68
69
70 This driver will work with the soundcard interfaces (SB Pro, SB 16, Galaxy,
71 SoundFX, Mozart, MAD16 ...) and with the "no-sound" cards (Panasonic CI-101P,
72 LaserMate, WDH-7001C, Longshine LCS-6853, Teac ...).
73
74 It works with the "configurable" interface "Sequoia S-1000", too, which is 
75 used on the Spea Media FX and Ensonic Soundscape sound cards. You have to
76 specify the type "SBPRO 2" and the true CDROM port address with it, not the
77 "configuration port" address.
78
79 If you have a sound card which needs a "configuration driver" instead of
80 jumpers for interface types and addresses (like Mozart cards) - those
81 drivers get invoked before the DOS CDROM driver in your CONFIG.SYS, typical
82 names are "cdsetup.sys" and "mztinit.sys" - let the sound driver do the
83 CDROM port configuration (the leading comments in linux/drivers/sound/mad16.c
84 are just for you!). Hannu Savolainen's mad16.c code is able to set up my
85 Mozart card - I simply had to add
86    #define MAD16_CONF 0x06
87    #define MAD16_CDSEL 0x03
88 to configure the CDROM interface for type "Panasonic" (LaserMate) and address
89 0x340.
90
91 The interface type has to get configured in linux/drivers/cdrom/sbpcd.h, 
92 because the register layout is different between the "SoundBlaster" and the
93 "LaserMate" type.
94
95 I got a report that the Teac interface card "I/F E117098" is of type
96 "SoundBlaster" (i.e. you have to set SBPRO to 1) even with the addresses
97 0x300 and above. This is unusual, and it can't get covered by the auto
98 probing scheme.
99 The Teac 16-bit interface cards (like P/N E950228-00A, default address 0x2C0)
100 need the SBPRO 3 setup.
101
102 If auto-probing found the drive, the address is correct. The reported type
103 may be wrong. A "mount" will give success only if the interface type is set
104 right. Playing audio should work with a wrong set interface type, too.
105
106 With some Teac and some CD200 drives I have seen interface cards which seem
107 to lack the "drive select" lines; always drive 0 gets addressed. To avoid
108 "mirror drives" (four drives detected where you only have one) with such
109 interface cards, set MAX_DRIVES to 1 and jumper your drive to ID 0 (if
110 possible).
111
112
113 Up to 4 drives per interface card, and up to 4 interface cards are supported.
114 All supported drive families can be mixed, but the CR-521 drives are 
115 hard-wired to drive ID 0. The drives have to use different drive IDs, and each
116 drive has to get a unique minor number (0...3), corresponding indirectly to 
117 its drive ID.
118 The drive IDs may be selected freely from 0 to 3 - they do not have to be in
119 consecutive order.
120
121 As Don Carroll, don@ds9.us.dell.com or FIDO 1:382/14, told me, it is possible
122 to change old drives to any ID, too. He writes in this sense:
123    "In order to be able to use more than one single speed drive
124    (they do not have the ID jumpers) you must add a DIP switch
125    and two resistors. The pads are already on the board next to
126    the power connector. You will see the silkscreen for the
127    switch if you remove the top cover.
128                     1 2 3 4
129              ID 0 = x F F x             O = "on"
130              ID 1 = x O F x             F = "off"
131              ID 2 = x F O x             x = "don't care"
132              ID 3 = x O O x
133    Next to the switch are the positions for R76 (7k) and R78
134    (12k). I had to play around with the resistor values - ID 3
135    did not work with other values. If the values are not good,
136    ID 3 behaves like ID 0."
137
138 To use more than 4 drives, you simply need a second controller card at a 
139 different address and a second cable.
140
141 The driver supports reading of data from the CD and playing of audio tracks.
142 The audio part should run with WorkMan, xcdplayer, with the "non-X11" products
143 CDplayer and WorkBone - tell me if it is not compatible with other software.
144 The only accepted measure for correctness with the audio functions is the
145 "cdtester" utility (appended) - most audio player programmers seem to be
146 better musicians than programmers. ;-)
147
148 With the CR-56x and the CD200 drives, the reading of audio frames is possible.
149 This is implemented by an IOCTL function which reads READ_AUDIO frames of
150 2352 bytes at once (configurable with the "READ_AUDIO" define, default is 0).
151 Reading the same frame a second time gives different data; the frame data 
152 start at a different position, but all read bytes are valid, and we always
153 read 98 consecutive chunks (of 24 Bytes) as a frame. Reading more than 1 frame
154 at once possibly misses some chunks at each frame boundary. This lack has to
155 get corrected by external, "higher level" software which reads the same frame 
156 again and tries to find and eliminate overlapping chunks (24-byte-pieces).
157
158 The transfer rate with reading audio (1-frame-pieces) currently is very slow.
159 This can be better reading bigger chunks, but the "missing" chunks possibly
160 occur at the beginning of each single frame.
161 The software interface possibly may change a bit the day the SCSI driver
162 supports it too.
163
164 With all but the CR-52x drives, MultiSession is supported.
165 Photo CDs work (the "old" drives like CR-521 can access only the first
166 session of a photoCD).
167 At ftp.gwdg.de:/pub/linux/hpcdtoppm/ you will find Hadmut Danisch's package to
168 convert photo CD image files and Gerd Knorr's viewing utility.
169
170 The transfer rate will reach 150 kB/sec with CR-52x drives, 300 kB/sec with
171 CR-56x drives, and currently not more than 500 kB/sec (usually less than
172 250 kB/sec) with the Teac quad speed drives.
173 XA (PhotoCD) disks with "old" drives give only 50 kB/sec.
174
175 This release consists of
176 - this README file
177 - the driver file linux/drivers/cdrom/sbpcd.c
178 - the stub files linux/drivers/cdrom/sbpcd[234].c
179 - the header file linux/drivers/cdrom/sbpcd.h.
180
181
182 To install:
183 -----------
184
185 1. Setup your hardware parameters. Though the driver does "auto-probing" at a
186    lot of (not all possible!) addresses, this step is recommended for
187    everyday use. You should let sbpcd auto-probe once and use the reported
188    address if a drive got found. The reported type may be incorrect; it is
189    correct if you can mount a data CD. There is no choice for you with the
190    type; only one is right, the others are deadly wrong.
191
192    a. Go into /usr/src/linux/drivers/cdrom/sbpcd.h and configure it for your
193       hardware (near the beginning):
194       a1. Set it up for the appropriate type of interface board.
195           "Original" CreativeLabs sound cards need "SBPRO 1".
196           Most "compatible" sound cards (almost all "non-CreativeLabs" cards)
197           need "SBPRO 0".
198           The "no-sound" board from OmniCd needs the "SBPRO 1" setup.
199           The Teac 8-bit "no-sound" boards need the "SBPRO 1" setup.
200           The Teac 16-bit "no-sound" boards need the "SBPRO 3" setup.
201           All other "no-sound" boards need the "SBPRO 0" setup.
202           The Spea Media FX and Ensoniq SoundScape cards need "SBPRO 2".
203           sbpcd.c holds some examples in its auto-probe list.
204           If you configure "SBPRO" wrong, the playing of audio CDs will work,
205           but you will not be able to mount a data CD.
206       a2. Tell the address of your CDROM_PORT (not of the sound port).
207       a3. If 4 drives get found, but you have only one, set MAX_DRIVES to 1.
208       a4. Set DISTRIBUTION to 0.
209    b. Additionally for 2.a1 and 2.a2, the setup may be done during
210       boot time (via the "kernel command line" or "LILO option"):
211           sbpcd=0x320,LaserMate
212       or
213           sbpcd=0x230,SoundBlaster
214       or
215           sbpcd=0x338,SoundScape
216       or
217           sbpcd=0x2C0,Teac16bit
218       This is especially useful if you install a fresh distribution.
219       If the second parameter is a number, it gets taken as the type
220       setting; 0 is "LaserMate", 1 is "SoundBlaster", 2 is "SoundScape",
221       3 is "Teac16bit".
222       So, for example
223           sbpcd=0x230,1
224       is equivalent to
225           sbpcd=0x230,SoundBlaster
226
227 2. "cd /usr/src/linux" and do a "make config" and select "y" for Matsushita
228    CD-ROM support and for ISO9660 FileSystem support. If you do not have a
229    second, third, or fourth controller installed, do not say "y" to the 
230    secondary Matsushita CD-ROM questions.
231
232 3. Then do a "make dep", then make the kernel image ("make zlilo" or similar).
233
234 4. Make the device file(s). This step usually already has been done by the
235    MAKEDEV script.
236    The driver uses MAJOR 25, so, if necessary, do
237         mknod /dev/sbpcd  b 25 0       (if you have only one drive)
238    and/or
239         mknod /dev/sbpcd0 b 25 0
240         mknod /dev/sbpcd1 b 25 1
241         mknod /dev/sbpcd2 b 25 2
242         mknod /dev/sbpcd3 b 25 3
243    to make the node(s).
244
245    The "first found" drive gets MINOR 0 (regardless of its jumpered ID), the
246    "next found" (at the same cable) gets MINOR 1, ...
247    
248    For a second interface board, you have to make nodes like
249         mknod /dev/sbpcd4 b 26 0
250         mknod /dev/sbpcd5 b 26 1
251    and so on. Use the MAJORs 26, 27, 28.
252
253    If you further make a link like
254         ln -s sbpcd /dev/cdrom
255    you can use the name /dev/cdrom, too.
256
257 5. Reboot with the new kernel.
258
259 You should now be able to do
260               mkdir /CD
261 and 
262               mount -rt iso9660 /dev/sbpcd /CD
263 or
264               mount -rt iso9660 -o block=2048 /dev/sbpcd /CD
265 and see the contents of your CD in the /CD directory.
266 To use audio CDs, a mounting is not recommended (and it would fail if the
267 first track is not a data track).
268
269
270 Using sbpcd as a "loadable module":
271 -----------------------------------
272
273 If you do NOT select "Matsushita/Panasonic CDROM driver support" during the
274 "make config" of your kernel, you can build the "loadable module" sbpcd.o.
275 Read /usr/src/linux/Documentation/modules.txt on this.
276
277 If sbpcd gets used as a module, the support of more than one interface
278 card (i.e. drives 4...15) is disabled.
279
280 You can specify interface address and type with the "insmod" command like:
281  # insmod /usr/src/linux/modules/sbpcd.o sbpcd=0x340,0
282 or
283  # insmod /usr/src/linux/modules/sbpcd.o sbpcd=0x230,1
284 or
285  # insmod /usr/src/linux/modules/sbpcd.o sbpcd=0x338,2
286 where the last number represents the SBPRO setting (no strings allowed here).
287
288
289 Things of interest:
290 -------------------
291
292 The driver is configured to try the LaserMate type of interface at I/O port
293 0x0340 first. If this is not appropriate, sbpcd.h should get changed
294 (you will find the right place - just at the beginning).
295
296 No DMA and no IRQ is used.
297
298 To reduce or increase the amount of kernel messages, edit sbpcd.c and play
299 with the "DBG_xxx" switches (initialization of the variable "sbpcd_debug").
300 Don't forget to reflect on what you do; enabling all DBG_xxx switches at once
301 may crash your system, and each message line is accompanied by a delay.
302
303 The driver uses the "variable BLOCK_SIZE" feature. To use it, you have to
304 specify "block=2048" as a mount option. Doing this will disable the direct
305 execution of a binary from the CD; you have to copy it to a device with the
306 standard BLOCK_SIZE (1024) first. So, do not use this if your system is
307 directly "running from the CDROM" (like some of Yggdrasil's installation
308 variants). There are CDs on the market (like the German "unifix" Linux
309 distribution) which MUST get handled with a block_size of 1024. Generally,
310 one can say all the CDs which hold files of the name YMTRANS.TBL are defective;
311 do not use block=2048 with those.
312
313 Within sbpcd.h, you will find some "#define"s (e.g. EJECT and JUKEBOX). With
314 these, you can configure the driver for some special things.
315 You can use the appended program "cdtester" to set the auto-eject feature
316 during runtime. Jeff Tranter's "eject" utility can do this, too (and more)
317 for you.
318
319 There is an ioctl CDROMMULTISESSION to obtain with a user program if
320 the CD is an XA disk and - if it is - where the last session starts. The
321 "cdtester" program illustrates how to call it.
322
323
324 Auto-probing at boot time:
325 --------------------------
326
327 The driver does auto-probing at many well-known interface card addresses,
328 but not all:
329 Some probings can cause a hang if an NE2000 ethernet card gets touched, because
330 SBPCD's auto-probing happens before the initialization of the net drivers.
331 Those "hazardous" addresses are excluded from auto-probing; the "kernel 
332 command line" feature has to be used during installation if you have your 
333 drive at those addresses. The "module" version is allowed to probe at those
334 addresses, too.
335
336 The auto-probing looks first at the configured address resp. the address
337 submitted by the kernel command line. With this, it is possible to use this
338 driver within installation boot floppies, and for any non-standard address,
339 too.
340
341 Auto-probing will make an assumption about the interface type ("SBPRO" or not),
342 based upon the address. That assumption may be wrong (initialization will be
343 o.k., but you will get I/O errors during mount). In that case, use the "kernel
344 command line" feature and specify address & type at boot time to find out the
345 right setup.
346
347 For everyday use, address and type should get configured within sbpcd.h. That
348 will stop the auto-probing due to success with the first try.
349
350 The kernel command "sbpcd=0" suppresses each auto-probing and causes
351 the driver not to find any drive; it is meant for people who love sbpcd
352 so much that they do not want to miss it, even if they miss the drives. ;-)  
353
354 If you configure "#define CDROM_PORT 0" in sbpcd.h, the auto-probing is
355 initially disabled and needs an explicit kernel command to get activated.
356 Once activated, it does not stop before success or end-of-list. This may be
357 useful within "universal" CDROM installation boot floppies (but using the 
358 loadable module would be better because it allows an "extended" auto-probing
359 without fearing NE2000 cards).
360
361 To shorten the auto-probing list to a single entry, set DISTRIBUTION 0 within
362 sbpcd.h.
363
364
365 Setting up address and interface type:
366 --------------------------------------
367
368 If your I/O port address is not 0x340, you have to look for the #defines near
369 the beginning of sbpcd.h and configure them: set SBPRO to 0 or 1 or 2, and
370 change CDROM_PORT to the address of your CDROM I/O port.
371
372 Almost all of the "SoundBlaster compatible" cards behave like the no-sound
373 interfaces, i.e. need SBPRO 0! 
374
375 With "original" SB Pro cards, an initial setting of CD_volume through the
376 sound card's MIXER register gets done.
377 If you are using a "compatible" sound card of types "LaserMate" or "SPEA",
378 you can set SOUND_BASE (in sbpcd.h) to get it done with your card, too...
379
380
381 Using audio CDs:
382 ----------------
383
384 Workman, WorkBone, xcdplayer, cdplayer and the nice little tool "cdplay" (see
385 README.aztcd from the Aztech driver package) should work.
386
387 The program CDplayer likes to talk to "/dev/mcd" only, xcdplayer wants
388 "/dev/rsr0", workman loves "/dev/sr0" or "/dev/cdrom" - so, make the 
389 appropriate links to use them without the need to supply parameters.
390
391
392 Copying audio tracks:
393 ---------------------
394
395 The following program will copy track 1 (or a piece of it) from an audio CD
396 into the file "track01":
397
398 /*=================== begin program ========================================*/
399 /*
400  * read an audio track from a CD
401  *
402  * (c) 1994 Eberhard Moenkeberg <emoenke@gwdg.de>
403  *          may be used & enhanced freely
404  *
405  * Due to non-existent sync bytes at the beginning of each audio frame (or due
406  * to a firmware bug within all known drives?), it is currently a kind of
407  * fortune if two consecutive frames fit together.
408  * Usually, they overlap, or a little piece is missing. This happens in units
409  * of 24-byte chunks. It has to get fixed by higher-level software (reading
410  * until an overlap occurs, and then eliminate the overlapping chunks). 
411  * ftp.gwdg.de:/pub/linux/misc/cdda2wav-sbpcd.*.tar.gz holds an example of
412  * such an algorithm.
413  * This example program further is missing to obtain the SubChannel data
414  * which belong to each frame.
415  *
416  * This is only an example of the low-level access routine. The read data are
417  * pure 16-bit CDDA values; they have to get converted to make sound out of
418  * them.
419  * It is no fun to listen to it without prior overlap/underlap correction!
420  */
421 #include <stdio.h>
422 #include <sys/ioctl.h>
423 #include <linux/cdrom.h>
424
425 static struct cdrom_tochdr hdr;
426 static struct cdrom_tocentry entry[101];
427 static struct cdrom_read_audio arg;
428 static u_char buffer[CD_FRAMESIZE_RAW];
429 static int datafile, drive;
430 static int i, j, limit, track, err;
431 static char filename[32];
432
433 main(int argc, char *argv[])
434 {
435 /*
436  * open /dev/cdrom
437  */
438   drive=open("/dev/cdrom", 0);
439   if (drive<0)
440     {
441       fprintf(stderr, "can't open drive.\n");
442       exit (-1);
443     }
444 /*
445  * get TocHeader
446  */
447   fprintf(stdout, "getting TocHeader...\n");
448   err=ioctl(drive, CDROMREADTOCHDR, &hdr);
449   if (err!=0)
450     {
451       fprintf(stderr, "can't get TocHeader (error %d).\n", err);
452       exit (-1);
453     }
454   else
455     fprintf(stdout, "TocHeader: %d %d\n", hdr.cdth_trk0, hdr.cdth_trk1);
456 /*
457  * get and display all TocEntries
458  */
459   fprintf(stdout, "getting TocEntries...\n");
460   for (i=1;i<=hdr.cdth_trk1+1;i++)
461     {
462       if (i!=hdr.cdth_trk1+1) entry[i].cdte_track = i;
463       else entry[i].cdte_track = CDROM_LEADOUT;
464       entry[i].cdte_format = CDROM_LBA;
465       err=ioctl(drive, CDROMREADTOCENTRY, &entry[i]);
466       if (err!=0)
467         {
468           fprintf(stderr, "can't get TocEntry #%d (error %d).\n", i, err);
469           exit (-1);
470         }
471       else
472         {
473           fprintf(stdout, "TocEntry #%d: %1X %1X %06X %02X\n",
474                  entry[i].cdte_track,
475                  entry[i].cdte_adr,
476                  entry[i].cdte_ctrl,
477                  entry[i].cdte_addr.lba,
478                  entry[i].cdte_datamode);
479         }
480     }
481   fprintf(stdout, "got all TocEntries.\n");
482 /*
483  * ask for track number (not implemented here)
484  */
485 track=1;
486 #if 0 /* just read a little piece (4 seconds) */
487 entry[track+1].cdte_addr.lba=entry[track].cdte_addr.lba+300;
488 #endif
489 /*
490  * read track into file
491  */
492   sprintf(filename, "track%02d\0", track);
493   datafile=creat(filename, 0755);
494   if (datafile<0)
495     {
496       fprintf(stderr, "can't open datafile %s.\n", filename);
497       exit (-1);
498     }
499   arg.addr.lba=entry[track].cdte_addr.lba;
500   arg.addr_format=CDROM_LBA; /* CDROM_MSF would be possible here, too. */
501   arg.nframes=1;
502   arg.buf=&buffer[0];
503   limit=entry[track+1].cdte_addr.lba;
504   for (;arg.addr.lba<limit;arg.addr.lba++)
505     {
506       err=ioctl(drive, CDROMREADAUDIO, &arg);
507       if (err!=0)
508         {
509           fprintf(stderr, "can't read abs. frame #%d (error %d).\n", 
510                  arg.addr.lba, err);
511         }
512       j=write(datafile, &buffer[0], CD_FRAMESIZE_RAW);
513       if (j!=CD_FRAMESIZE_RAW)
514         {
515           fprintf(stderr,"I/O error (datafile) at rel. frame %d\n",
516                          arg.addr.lba-entry[track].cdte_addr.lba);
517         }
518       arg.addr.lba++;
519     }
520 }
521 /*===================== end program ========================================*/
522
523 At ftp.gwdg.de:/pub/linux/misc/cdda2wav-sbpcd.*.tar.gz is an adapted version of
524 Heiko Eissfeldt's digital-audio to .WAV converter (the original is there, too).
525 This is preliminary, as Heiko himself will care about it.
526
527
528 Known problems:
529 ---------------
530
531 Currently, the detection of disk change or removal is actively disabled.
532
533 Most attempts to read the UPC/EAN code result in a stream of zeroes. All my
534 drives are mostly telling there is no UPC/EAN code on disk or there is, but it
535 is an all-zero number. I guess now almost no CD holds such a number.
536
537 Bug reports, comments, wishes, donations (technical information is a donation,
538 too :-) etc. to emoenke@gwdg.de.
539
540 SnailMail address, preferable for CD editors if they want to submit a free
541 "cooperation" copy:
542                          Eberhard Moenkeberg
543                          Reinholdstr. 14
544                          D-37083 Goettingen
545                          Germany
546 ---
547
548
549 Appendix -- the "cdtester" utility:
550
551 /*
552  * cdtester.c -- test the audio functions of a CD driver
553  *
554  * (c) 1995 Eberhard Moenkeberg <emoenke@gwdg.de>
555  *          published under the GPL
556  *
557  *          made under heavy use of the "Tiny Audio CD Player"
558  *          from Werner Zimmermann <zimmerma@rz.fht-esslingen.de>
559  *          (see linux/drivers/block/README.aztcd)
560  */
561 #undef AZT_PRIVATE_IOCTLS /* not supported by every CDROM driver */
562 #define SBP_PRIVATE_IOCTLS /* not supported by every CDROM driver */
563
564 #include <stdio.h>
565 #include <stdio.h>
566 #include <malloc.h>
567 #include <sys/ioctl.h>
568 #include <linux/cdrom.h>
569
570 #ifdef AZT_PRIVATE_IOCTLS
571 #include <linux/../../drivers/cdrom/aztcd.h>
572 #endif AZT_PRIVATE_IOCTLS
573 #ifdef SBP_PRIVATE_IOCTLS
574 #include <linux/../../drivers/cdrom/sbpcd.h>
575 #include <linux/fs.h>
576 #endif SBP_PRIVATE_IOCTLS
577
578 struct cdrom_tochdr hdr;
579 struct cdrom_tochdr tocHdr;
580 struct cdrom_tocentry TocEntry[101];
581 struct cdrom_tocentry entry;
582 struct cdrom_multisession ms_info;
583 struct cdrom_read_audio read_audio;
584 struct cdrom_ti ti;
585 struct cdrom_subchnl subchnl;
586 struct cdrom_msf msf;
587 struct cdrom_volctrl volctrl;
588 #ifdef AZT_PRIVATE_IOCTLS
589 union
590 {
591         struct cdrom_msf msf;
592         unsigned char buf[CD_FRAMESIZE_RAW];
593 } azt;
594 #endif AZT_PRIVATE_IOCTLS
595 int i, i1, i2, i3, j, k;
596 unsigned char sequence=0;
597 unsigned char command[80];
598 unsigned char first=1, last=1;
599 char *default_device="/dev/cdrom";
600 char dev[20];
601 char filename[20];
602 int drive;
603 int datafile;
604 int rc;
605
606 void help(void)
607 {
608         printf("Available Commands:\n");
609         printf("STOP          s      EJECT        e       QUIT         q\n");
610         printf("PLAY TRACK    t      PAUSE        p       RESUME       r\n");
611         printf("NEXT TRACK    n      REPEAT LAST  l       HELP         h\n");
612         printf("SUBCHANNEL_Q  c      TRACK INFO   i       PLAY AT      a\n");
613         printf("READ          d      READ RAW     w       READ AUDIO   A\n");
614         printf("MS-INFO       M      TOC          T       START        S\n");
615         printf("SET EJECTSW   X      DEVICE       D       DEBUG        Y\n");
616         printf("AUDIO_BUFSIZ  Z      RESET        R       SET VOLUME   v\n");
617         printf("GET VOLUME    V\n");
618 }
619
620 /*
621  *  convert MSF number (3 bytes only) to Logical_Block_Address 
622  */
623 int msf2lba(u_char *msf)
624 {
625         int i;
626         
627         i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_BLOCK_OFFSET;
628         if (i<0) return (0);
629         return (i);
630 }
631 /*
632  *  convert logical_block_address to m-s-f_number (3 bytes only)
633  */
634 void lba2msf(int lba, unsigned char *msf)
635 {
636         lba += CD_BLOCK_OFFSET;
637         msf[0] = lba / (CD_SECS*CD_FRAMES);
638         lba %= CD_SECS*CD_FRAMES;
639         msf[1] = lba / CD_FRAMES;
640         msf[2] = lba % CD_FRAMES;
641 }
642
643 int init_drive(char *dev)
644 {
645         unsigned char msf_ent[3];
646
647         /*
648          * open the device
649          */
650         drive=open(dev,0);
651         if (drive<0) return (-1);
652         /*
653          * get TocHeader
654          */
655         printf("getting TocHeader...\n");
656         rc=ioctl(drive,CDROMREADTOCHDR,&hdr);
657         if (rc!=0)
658         {
659                 printf("can't get TocHeader (error %d).\n",rc);
660                 return (-2);
661         }
662         else
663                 first=hdr.cdth_trk0;
664                 last=hdr.cdth_trk1;
665                 printf("TocHeader: %d %d\n",hdr.cdth_trk0,hdr.cdth_trk1);
666         /*
667          * get and display all TocEntries
668          */
669         printf("getting TocEntries...\n");
670         for (i=1;i<=hdr.cdth_trk1+1;i++)
671         {
672                 if (i!=hdr.cdth_trk1+1) TocEntry[i].cdte_track = i;
673                 else TocEntry[i].cdte_track = CDROM_LEADOUT;
674                 TocEntry[i].cdte_format = CDROM_LBA;
675                 rc=ioctl(drive,CDROMREADTOCENTRY,&TocEntry[i]);
676                 if (rc!=0)
677                 {
678                         printf("can't get TocEntry #%d (error %d).\n",i,rc);
679                 }
680                 else
681                 {
682                         lba2msf(TocEntry[i].cdte_addr.lba,&msf_ent[0]);
683                         if (TocEntry[i].cdte_track==CDROM_LEADOUT)
684                         {
685                                 printf("TocEntry #%02X: %1X %1X %02d:%02d:%02d (lba: 0x%06X) %02X\n",
686                                        TocEntry[i].cdte_track,
687                                        TocEntry[i].cdte_adr,
688                                        TocEntry[i].cdte_ctrl,
689                                        msf_ent[0],
690                                        msf_ent[1],
691                                        msf_ent[2],
692                                        TocEntry[i].cdte_addr.lba,
693                                        TocEntry[i].cdte_datamode);
694                         }
695                         else
696                         {
697                                 printf("TocEntry #%02d: %1X %1X %02d:%02d:%02d (lba: 0x%06X) %02X\n",
698                                        TocEntry[i].cdte_track,
699                                        TocEntry[i].cdte_adr,
700                                        TocEntry[i].cdte_ctrl,
701                                        msf_ent[0],
702                                        msf_ent[1],
703                                        msf_ent[2],
704                                        TocEntry[i].cdte_addr.lba,
705                                        TocEntry[i].cdte_datamode);
706                         }
707                 }
708         }
709         return (hdr.cdth_trk1); /* number of tracks */
710 }
711
712 void display(int size,unsigned char *buffer)
713 {
714         k=0;
715         getchar();
716         for (i=0;i<(size+1)/16;i++)
717         {
718                 printf("%4d:",i*16);
719                 for (j=0;j<16;j++)
720                 {
721                         printf(" %02X",buffer[i*16+j]);
722                 }
723                 printf("  ");
724                 for (j=0;j<16;j++)
725                 {
726                         if (isalnum(buffer[i*16+j])) 
727                                 printf("%c",buffer[i*16+j]);
728                         else
729                                 printf(".");
730                 }
731                 printf("\n"); 
732                 k++;
733                 if (k>=20)
734                 {
735                         printf("press ENTER to continue\n");
736                         getchar();
737                         k=0;
738                 }
739         } 
740
741
742 main(int argc, char *argv[])
743 {
744         printf("\nTesting tool for a CDROM driver's audio functions V0.1\n");
745         printf("(C) 1995 Eberhard Moenkeberg <emoenke@gwdg.de>\n");
746         printf("initializing...\n");
747         
748         rc=init_drive(default_device);
749         if (rc<0) printf("could not open %s (rc=%d).\n",default_device,rc);
750         help();
751         while (1)
752         {
753                 printf("Give a one-letter command (h = help): ");
754                 scanf("%s",command);
755                 command[1]=0;
756                 switch (command[0])
757                 {
758                 case 'D':
759                         printf("device name (f.e. /dev/sbpcd3): ? ");
760                         scanf("%s",&dev);
761                         close(drive);
762                         rc=init_drive(dev);
763                         if (rc<0) printf("could not open %s (rc %d).\n",dev,rc);
764                         break;
765                 case 'e':
766                         rc=ioctl(drive,CDROMEJECT);
767                         if (rc<0) printf("CDROMEJECT: rc=%d.\n",rc);
768                         break;
769                 case 'p':
770                         rc=ioctl(drive,CDROMPAUSE);
771                         if (rc<0) printf("CDROMPAUSE: rc=%d.\n",rc);
772                         break;
773                 case 'r':
774                         rc=ioctl(drive,CDROMRESUME);
775                         if (rc<0) printf("CDROMRESUME: rc=%d.\n",rc);
776                         break;
777                 case 's':
778                         rc=ioctl(drive,CDROMSTOP);
779                         if (rc<0) printf("CDROMSTOP: rc=%d.\n",rc);
780                         break;
781                 case 'S':
782                         rc=ioctl(drive,CDROMSTART);
783                         if (rc<0) printf("CDROMSTART: rc=%d.\n",rc);
784                         break;
785                 case 't':
786                         rc=ioctl(drive,CDROMREADTOCHDR,&tocHdr);
787                         if (rc<0)
788                         {
789                                 printf("CDROMREADTOCHDR: rc=%d.\n",rc);
790                                 break;
791                         }
792                         first=tocHdr.cdth_trk0;
793                         last= tocHdr.cdth_trk1;
794                         if ((first==0)||(first>last))
795                         {
796                                 printf ("--got invalid TOC data.\n");
797                         }
798                         else
799                         {
800                                 printf("--enter track number(first=%d, last=%d): ",first,last);
801                                 scanf("%d",&i1);
802                                 ti.cdti_trk0=i1;
803                                 if (ti.cdti_trk0<first) ti.cdti_trk0=first;
804                                 if (ti.cdti_trk0>last) ti.cdti_trk0=last;
805                                 ti.cdti_ind0=0;
806                                 ti.cdti_trk1=last;
807                                 ti.cdti_ind1=0;
808                                 rc=ioctl(drive,CDROMSTOP);
809                                 rc=ioctl(drive,CDROMPLAYTRKIND,&ti);
810                                 if (rc<0) printf("CDROMPLAYTRKIND: rc=%d.\n",rc);
811                         }
812                         break;
813                 case 'n':
814                         rc=ioctl(drive,CDROMSTOP);
815                         if (++ti.cdti_trk0>last) ti.cdti_trk0=last;
816                         ti.cdti_ind0=0;
817                         ti.cdti_trk1=last;
818                         ti.cdti_ind1=0;
819                         rc=ioctl(drive,CDROMPLAYTRKIND,&ti);
820                         if (rc<0) printf("CDROMPLAYTRKIND: rc=%d.\n",rc);
821                         break;
822                 case 'l':
823                         rc=ioctl(drive,CDROMSTOP);
824                         if (--ti.cdti_trk0<first) ti.cdti_trk0=first;
825                         ti.cdti_ind0=0;
826                         ti.cdti_trk1=last;
827                         ti.cdti_ind1=0;
828                         rc=ioctl(drive,CDROMPLAYTRKIND,&ti);
829                         if (rc<0) printf("CDROMPLAYTRKIND: rc=%d.\n",rc);
830                         break;
831                 case 'c':
832                         subchnl.cdsc_format=CDROM_MSF;
833                         rc=ioctl(drive,CDROMSUBCHNL,&subchnl);
834                         if (rc<0) printf("CDROMSUBCHNL: rc=%d.\n",rc);
835                         else
836                         {
837                                 printf("AudioStatus:%s  Track:%d  Mode:%d  MSF=%02d:%02d:%02d\n",
838                                        subchnl.cdsc_audiostatus==CDROM_AUDIO_PLAY ? "PLAYING":"NOT PLAYING",
839                                        subchnl.cdsc_trk,subchnl.cdsc_adr, 
840                                        subchnl.cdsc_absaddr.msf.minute,
841                                        subchnl.cdsc_absaddr.msf.second,
842                                        subchnl.cdsc_absaddr.msf.frame);
843                         }
844                         break;              
845                 case 'i':
846                         printf("Track No.: ");
847                         scanf("%d",&i1);
848                         entry.cdte_track=i1;
849                         if (entry.cdte_track<first) entry.cdte_track=first;
850                         if (entry.cdte_track>last)  entry.cdte_track=last;
851                         entry.cdte_format=CDROM_MSF;
852                         rc=ioctl(drive,CDROMREADTOCENTRY,&entry);
853                         if (rc<0) printf("CDROMREADTOCENTRY: rc=%d.\n",rc);
854                         else
855                         {
856                                 printf("Mode %d Track, starts at %02d:%02d:%02d\n",
857                                        entry.cdte_adr,
858                                        entry.cdte_addr.msf.minute,
859                                        entry.cdte_addr.msf.second,
860                                        entry.cdte_addr.msf.frame);
861                         }
862                         break;
863                 case 'a':
864                         printf("Address (min:sec:frm)  ");
865                         scanf("%d:%d:%d",&i1,&i2,&i3);
866                         msf.cdmsf_min0=i1;
867                         msf.cdmsf_sec0=i2;
868                         msf.cdmsf_frame0=i3;
869                         if (msf.cdmsf_sec0>59) msf.cdmsf_sec0=59;
870                         if (msf.cdmsf_frame0>74) msf.cdmsf_frame0=74;
871                         lba2msf(TocEntry[last+1].cdte_addr.lba-1,&msf.cdmsf_min1);
872                         rc=ioctl(drive,CDROMSTOP);
873                         rc=ioctl(drive,CDROMPLAYMSF,&msf);
874                         if (rc<0) printf("CDROMPLAYMSF: rc=%d.\n",rc);
875                         break;
876                 case 'V':
877                         rc=ioctl(drive,CDROMVOLREAD,&volctrl);
878                         if (rc<0) printf("CDROMVOLCTRL: rc=%d.\n",rc);
879                         printf("Volume: channel 0 (left) %d, channel 1 (right) %d\n",volctrl.channel0,volctrl.channel1);
880                         break;  
881                 case 'R':
882                         rc=ioctl(drive,CDROMRESET);
883                         if (rc<0) printf("CDROMRESET: rc=%d.\n",rc);
884                         break;
885 #ifdef AZT_PRIVATE_IOCTLS /*not supported by every CDROM driver*/
886                 case 'd':
887                         printf("Address (min:sec:frm)  ");
888                         scanf("%d:%d:%d",&i1,&i2,&i3);
889                         azt.msf.cdmsf_min0=i1;
890                         azt.msf.cdmsf_sec0=i2;
891                         azt.msf.cdmsf_frame0=i3;
892                         if (azt.msf.cdmsf_sec0>59) azt.msf.cdmsf_sec0=59;
893                         if (azt.msf.cdmsf_frame0>74) azt.msf.cdmsf_frame0=74;
894                         rc=ioctl(drive,CDROMREADMODE1,&azt.msf);
895                         if (rc<0) printf("CDROMREADMODE1: rc=%d.\n",rc);
896                         else display(CD_FRAMESIZE,azt.buf);
897                         break;
898                 case 'w':
899                         printf("Address (min:sec:frame)  ");
900                         scanf("%d:%d:%d",&i1,&i2,&i3);
901                         azt.msf.cdmsf_min0=i1;
902                         azt.msf.cdmsf_sec0=i2;
903                         azt.msf.cdmsf_frame0=i3;
904                         if (azt.msf.cdmsf_sec0>59) azt.msf.cdmsf_sec0=59;
905                         if (azt.msf.cdmsf_frame0>74) azt.msf.cdmsf_frame0=74;
906                         rc=ioctl(drive,CDROMREADMODE2,&azt.msf);
907                         if (rc<0) printf("CDROMREADMODE2: rc=%d.\n",rc);
908                         else display(CD_FRAMESIZE_RAW,azt.buf); /* currently only 2336 */
909                         break;  
910 #endif
911                 case 'v':
912                         printf("--Channel 0 (Left)  (0-255): ");
913                         scanf("%d",&i1);
914                         volctrl.channel0=i1;
915                         printf("--Channel 1 (Right) (0-255): ");
916                         scanf("%d",&i1);
917                         volctrl.channel1=i1;
918                         volctrl.channel2=0;
919                         volctrl.channel3=0;
920                         rc=ioctl(drive,CDROMVOLCTRL,&volctrl);
921                         if (rc<0) printf("CDROMVOLCTRL: rc=%d.\n",rc);
922                         break;  
923                 case 'q':
924                         close(drive);
925                         exit(0);
926                 case 'h':
927                         help();
928                         break;
929                 case 'T': /* display TOC entry - without involving the driver */
930                         scanf("%d",&i);
931                         if ((i<hdr.cdth_trk0)||(i>hdr.cdth_trk1))
932                                 printf("invalid track number.\n");
933                         else
934                                 printf("TocEntry %02d: adr=%01X ctrl=%01X msf=%02d:%02d:%02d mode=%02X\n",
935                                        TocEntry[i].cdte_track,
936                                        TocEntry[i].cdte_adr,
937                                        TocEntry[i].cdte_ctrl,
938                                        TocEntry[i].cdte_addr.msf.minute,
939                                        TocEntry[i].cdte_addr.msf.second,
940                                        TocEntry[i].cdte_addr.msf.frame,
941                                        TocEntry[i].cdte_datamode);
942                         break;
943                 case 'A': /* read audio data into file */
944                         printf("Address (min:sec:frm) ? ");
945                         scanf("%d:%d:%d",&i1,&i2,&i3);
946                         read_audio.addr.msf.minute=i1;
947                         read_audio.addr.msf.second=i2;
948                         read_audio.addr.msf.frame=i3;
949                         read_audio.addr_format=CDROM_MSF;
950                         printf("# of frames ? ");
951                         scanf("%d",&i1);
952                         read_audio.nframes=i1;
953                         k=read_audio.nframes*CD_FRAMESIZE_RAW;
954                         read_audio.buf=malloc(k);
955                         if (read_audio.buf==NULL)
956                         {
957                                 printf("can't malloc %d bytes.\n",k);
958                                 break;
959                         }
960                         sprintf(filename,"audio_%02d%02d%02d_%02d.%02d\0",
961                                 read_audio.addr.msf.minute,
962                                 read_audio.addr.msf.second,
963                                 read_audio.addr.msf.frame,
964                                 read_audio.nframes,
965                                 ++sequence);
966                         datafile=creat(filename, 0755);
967                         if (datafile<0)
968                         {
969                                 printf("can't open datafile %s.\n",filename);
970                                 break;
971                         }
972                         rc=ioctl(drive,CDROMREADAUDIO,&read_audio);
973                         if (rc!=0)
974                         {
975                                 printf("CDROMREADAUDIO: rc=%d.\n",rc);
976                         }
977                         else
978                         {
979                                 rc=write(datafile,&read_audio.buf,k);
980                                 if (rc!=k) printf("datafile I/O error (%d).\n",rc);
981                         }
982                         close(datafile);
983                         break;
984                 case 'X': /* set EJECT_SW (0: disable, 1: enable auto-ejecting) */
985                         scanf("%d",&i);
986                         rc=ioctl(drive,CDROMEJECT_SW,i);
987                         if (rc!=0)
988                                 printf("CDROMEJECT_SW: rc=%d.\n",rc);
989                         else
990                                 printf("EJECT_SW set to %d\n",i);
991                         break;
992                 case 'M': /* get the multisession redirection info */
993                         ms_info.addr_format=CDROM_LBA;
994                         rc=ioctl(drive,CDROMMULTISESSION,&ms_info);
995                         if (rc!=0)
996                         {
997                                 printf("CDROMMULTISESSION(lba): rc=%d.\n",rc);
998                         }
999                         else
1000                         {
1001                                 if (ms_info.xa_flag) printf("MultiSession offset (lba): %d (0x%06X)\n",ms_info.addr.lba,ms_info.addr.lba);
1002                                 else
1003                                 {
1004                                         printf("this CD is not an XA disk.\n");
1005                                         break;
1006                                 }
1007                         }
1008                         ms_info.addr_format=CDROM_MSF;
1009                         rc=ioctl(drive,CDROMMULTISESSION,&ms_info);
1010                         if (rc!=0)
1011                         {
1012                                 printf("CDROMMULTISESSION(msf): rc=%d.\n",rc);
1013                         }
1014                         else
1015                         {
1016                                 if (ms_info.xa_flag)
1017                                         printf("MultiSession offset (msf): %02d:%02d:%02d (0x%02X%02X%02X)\n",
1018                                                ms_info.addr.msf.minute,
1019                                                ms_info.addr.msf.second,
1020                                                ms_info.addr.msf.frame,
1021                                                ms_info.addr.msf.minute,
1022                                                ms_info.addr.msf.second,
1023                                                ms_info.addr.msf.frame);
1024                                 else printf("this CD is not an XA disk.\n");
1025                         }
1026                         break;
1027 #ifdef SBP_PRIVATE_IOCTLS
1028                 case 'Y': /* set the driver's message level */
1029 #if 0 /* not implemented yet */
1030                         printf("enter switch name (f.e. DBG_CMD): ");
1031                         scanf("%s",&dbg_switch);
1032                         j=get_dbg_num(dbg_switch);
1033 #else
1034                         printf("enter DDIOCSDBG switch number: ");
1035                         scanf("%d",&j);
1036 #endif
1037                         printf("enter 0 for \"off\", 1 for \"on\": ");
1038                         scanf("%d",&i);
1039                         if (i==0) j|=0x80;
1040                         printf("calling \"ioctl(drive,DDIOCSDBG,%d)\"\n",j);
1041                         rc=ioctl(drive,DDIOCSDBG,j);
1042                         printf("DDIOCSDBG: rc=%d.\n",rc);
1043                         break;
1044                 case 'Z': /* set the audio buffer size */
1045                         printf("# frames wanted: ? ");
1046                         scanf("%d",&j);
1047                         rc=ioctl(drive,CDROMAUDIOBUFSIZ,j);
1048                         printf("%d frames granted.\n",rc);
1049                         break;
1050 #endif SBP_PRIVATE_IOCTLS
1051                 default:
1052                         printf("unknown command: \"%s\".\n",command);
1053                         break;
1054                 }
1055         }
1056 }
1057 /*==========================================================================*/
1058