v2.5.0.7 -> v2.5.0.8
[opensuse:kernel.git] / drivers / cdrom / sbpcd.c
1
2
3 /*
4  *  sbpcd.c   CD-ROM device driver for the whole family of traditional,
5  *            non-ATAPI IDE-style Matsushita/Panasonic CR-5xx drives.
6  *            Works with SoundBlaster compatible cards and with "no-sound"
7  *            interface cards like Lasermate, Panasonic CI-101P, Teac, ...
8  *            Also for the Longshine LCS-7260 drive.
9  *            Also for the IBM "External ISA CD-Rom" drive.
10  *            Also for the CreativeLabs CD200 drive.
11  *            Also for the TEAC CD-55A drive.
12  *            Also for the ECS-AT "Vertos 100" drive.
13  *            Not for Sanyo drives (but for the H94A, sjcd is there...).
14  *            Not for any other Funai drives than the CD200 types (sometimes
15  *             labelled E2550UA or MK4015 or 2800F).
16  */
17
18 #define VERSION "v4.63 Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000"
19
20 /*   Copyright (C) 1993, 1994, 1995  Eberhard Moenkeberg <emoenke@gwdg.de>
21  *
22  *   This program is free software; you can redistribute it and/or modify
23  *   it under the terms of the GNU General Public License as published by
24  *   the Free Software Foundation; either version 2, or (at your option)
25  *   any later version.
26  *
27  *   You should have received a copy of the GNU General Public License
28  *   (for example /usr/src/linux/COPYING); if not, write to the Free
29  *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30  *
31  *   If you change this software, you should mail a .diff file with some
32  *   description lines to emoenke@gwdg.de. I want to know about it.
33  *
34  *   If you are the editor of a Linux CD, you should enable sbpcd.c within
35  *   your boot floppy kernel and send me one of your CDs for free.
36  *
37  *   If you would like to port the driver to an other operating system (f.e.
38  *   FreeBSD or NetBSD) or use it as an information source, you shall not be
39  *   restricted by the GPL under the following conditions:
40  *     a) the source code of your work is freely available
41  *     b) my part of the work gets mentioned at all places where your 
42  *        authorship gets mentioned
43  *     c) I receive a copy of your code together with a full installation
44  *        package of your operating system for free.
45  *
46  *
47  *  VERSION HISTORY
48  *
49  *  0.1  initial release, April/May 93, after mcd.c (Martin Harriss)
50  *
51  *  0.2  thek "repeat:"-loop in do_sbpcd_request did not check for
52  *       end-of-request_queue (resulting in kernel panic).
53  *       Flow control seems stable, but throughput is not better.  
54  *
55  *  0.3  interrupt locking totally eliminated (maybe "inb" and "outb"
56  *       are still locking) - 0.2 made keyboard-type-ahead losses.
57  *       check_sbpcd_media_change added (to use by isofs/inode.c)
58  *       - but it detects almost nothing.
59  *
60  *  0.4  use MAJOR 25 definitely.
61  *       Almost total re-design to support double-speed drives and
62  *       "naked" (no sound) interface cards ("LaserMate" interface type).
63  *       Flow control should be exact now.
64  *       Don't occupy the SbPro IRQ line (not needed either); will
65  *       live together with Hannu Savolainen's sndkit now.
66  *       Speeded up data transfer to 150 kB/sec, with help from Kai
67  *       Makisara, the "provider" of the "mt" tape utility.
68  *       Give "SpinUp" command if necessary.
69  *       First steps to support up to 4 drives (but currently only one).
70  *       Implemented audio capabilities - workman should work, xcdplayer
71  *       gives some problems.
72  *       This version is still consuming too much CPU time, and
73  *       sleeping still has to be worked on.
74  *       During "long" implied seeks, it seems possible that a 
75  *       ReadStatus command gets ignored. That gives the message
76  *       "ResponseStatus timed out" (happens about 6 times here during
77  *       a "ls -alR" of the YGGDRASIL LGX-Beta CD). Such a case is
78  *       handled without data error, but it should get done better.
79  *
80  *  0.5  Free CPU during waits (again with help from Kai Makisara).
81  *       Made it work together with the LILO/kernel setup standard.
82  *       Included auto-probing code, as suggested by YGGDRASIL.
83  *       Formal redesign to add DDI debugging.
84  *       There are still flaws in IOCTL (workman with double speed drive).
85  *
86  *  1.0  Added support for all drive IDs (0...3, no longer only 0)
87  *       and up to 4 drives on one controller.
88  *       Added "#define MANY_SESSION" for "old" multi session CDs.
89  *
90  *  1.1  Do SpinUp for new drives, too.
91  *       Revised for clean compile under "old" kernels (0.99pl9).
92  *
93  *  1.2  Found the "workman with double-speed drive" bug: use the driver's
94  *       audio_state, not what the drive is reporting with ReadSubQ.
95  *
96  *  1.3  Minor cleanups.
97  *       Refinements regarding Workman.
98  *
99  *  1.4  Read XA disks (PhotoCDs) with "old" drives, too (but only the first
100  *       session - no chance to fully access a "multi-session" CD).
101  *       This currently still is too slow (50 kB/sec) - but possibly
102  *       the old drives won't do it faster.
103  *       Implemented "door (un)lock" for new drives (still does not work
104  *       as wanted - no lock possible after an unlock).
105  *       Added some debugging printout for the UPC/EAN code - but my drives 
106  *       return only zeroes. Is there no UPC/EAN code written?
107  *
108  *  1.5  Laborate with UPC/EAN code (not better yet).
109  *       Adapt to kernel 1.1.8 change (have to explicitly include
110  *       <linux/string.h> now).
111  *
112  *  1.6  Trying to read audio frames as data. Impossible with the current
113  *       drive firmware levels, as it seems. Awaiting any hint. ;-)
114  *       Changed "door unlock": repeat it until success.
115  *       Changed CDROMSTOP routine (stop somewhat "softer" so that Workman
116  *       won't get confused).
117  *       Added a third interface type: Sequoia S-1000, as used with the SPEA
118  *       Media FX sound card. This interface (usable for Sony and Mitsumi 
119  *       drives, too) needs a special configuration setup and behaves like a 
120  *       LaserMate type after that. Still experimental - I do not have such
121  *       an interface.
122  *       Use the "variable BLOCK_SIZE" feature (2048). But it does only work
123  *       if you give the mount option "block=2048".
124  *       The media_check routine is currently disabled; now that it gets
125  *       called as it should I fear it must get synchronized for not to
126  *       disturb the normal driver's activity.
127  *
128  *  2.0  Version number bumped - two reasons:
129  *       - reading audio tracks as data works now with CR-562 and CR-563. We
130  *       currently do it by an IOCTL (yet has to get standardized), one frame
131  *       at a time; that is pretty slow. But it works.
132  *       - we are maintaining now up to 4 interfaces (each up to 4 drives):
133  *       did it the easy way - a different MAJOR (25, 26, ...) and a different
134  *       copy of the driver (sbpcd.c, sbpcd2.c, sbpcd3.c, sbpcd4.c - only
135  *       distinguished by the value of SBPCD_ISSUE and the driver's name),
136  *       and a common sbpcd.h file.
137  *       Bettered the "ReadCapacity error" problem with old CR-52x drives (the
138  *       drives sometimes need a manual "eject/insert" before work): just
139  *       reset the drive and do again. Needs lots of resets here and sometimes
140  *       that does not cure, so this can't be the solution.
141  *
142  *  2.1  Found bug with multisession CDs (accessing frame 16).
143  *       "read audio" works now with address type CDROM_MSF, too.
144  *       Bigger audio frame buffer: allows reading max. 4 frames at time; this
145  *       gives a significant speedup, but reading more than one frame at once
146  *       gives missing chunks at each single frame boundary.
147  *
148  *  2.2  Kernel interface cleanups: timers, init, setup, media check.
149  *
150  *  2.3  Let "door lock" and "eject" live together.
151  *       Implemented "close tray" (done automatically during open).
152  *
153  *  2.4  Use different names for device registering.
154  *
155  *  2.5  Added "#if EJECT" code (default: enabled) to automatically eject
156  *       the tray during last call to "sbpcd_release".
157  *       Added "#if JUKEBOX" code (default: disabled) to automatically eject
158  *       the tray during call to "sbpcd_open" if no disk is in.
159  *       Turn on the CD volume of "compatible" sound cards, too; just define
160  *       SOUND_BASE (in sbpcd.h) accordingly (default: disabled).
161  *
162  *  2.6  Nothing new.  
163  *
164  *  2.7  Added CDROMEJECT_SW ioctl to set the "EJECT" behavior on the fly:
165  *       0 disables, 1 enables auto-ejecting. Useful to keep the tray in
166  *       during shutdown.
167  *
168  *  2.8  Added first support (still BETA, I need feedback or a drive) for
169  *       the Longshine LCS-7260 drives. They appear as double-speed drives
170  *       using the "old" command scheme, extended by tray control and door
171  *       lock functions.
172  *       Found (and fixed preliminary) a flaw with some multisession CDs: we
173  *       have to re-direct not only the accesses to frame 16 (the isofs
174  *       routines drive it up to max. 100), but also those to the continuation
175  *       (repetition) frames (as far as they exist - currently set fix as
176  *       16..20).
177  *       Changed default of the "JUKEBOX" define. If you use this default,
178  *       your tray will eject if you try to mount without a disk in. Next
179  *       mount command will insert the tray - so, just fill in a disk. ;-)
180  *
181  *  2.9  Fulfilled the Longshine LCS-7260 support; with great help and
182  *       experiments by Serge Robyns.
183  *       First attempts to support the TEAC CD-55A drives; but still not
184  *       usable yet.
185  *       Implemented the CDROMMULTISESSION ioctl; this is an attempt to handle
186  *       multi session CDs more "transparent" (redirection handling has to be
187  *       done within the isofs routines, and only for the special purpose of
188  *       obtaining the "right" volume descriptor; accesses to the raw device
189  *       should not get redirected).
190  *
191  *  3.0  Just a "normal" increment, with some provisions to do it better. ;-)
192  *       Introduced "#define READ_AUDIO" to specify the maximum number of 
193  *       audio frames to grab with one request. This defines a buffer size
194  *       within kernel space; a value of 0 will reserve no such space and
195  *       disable the CDROMREADAUDIO ioctl. A value of 75 enables the reading
196  *       of a whole second with one command, but will use a buffer of more
197  *       than 172 kB.
198  *       Started CD200 support. Drive detection should work, but nothing
199  *       more.
200  *
201  *  3.1  Working to support the CD200 and the Teac CD-55A drives.
202  *       AT-BUS style device numbering no longer used: use SCSI style now.
203  *       So, the first "found" device has MINOR 0, regardless of the
204  *       jumpered drive ID. This implies modifications to the /dev/sbpcd*
205  *       entries for some people, but will help the DAU (german TLA, english:
206  *       "newbie", maybe ;-) to install his "first" system from a CD.
207  *
208  *  3.2  Still testing with CD200 and CD-55A drives.
209  *
210  *  3.3  Working with CD200 support.
211  *
212  *  3.4  Auto-probing stops if an address of 0 is seen (to be entered with
213  *       the kernel command line).
214  *       Made the driver "loadable". If used as a module, "audio copy" is
215  *       disabled, and the internal read ahead data buffer has a reduced size
216  *       of 4 kB; so, throughput may be reduced a little bit with slow CPUs.
217  *
218  *  3.5  Provisions to handle weird photoCDs which have an interrupted
219  *       "formatting" immediately after the last frames of some files: simply
220  *       never "read ahead" with MultiSession CDs. By this, CPU usage may be
221  *       increased with those CDs, and there may be a loss in speed.
222  *       Re-structured the messaging system.
223  *       The "loadable" version no longer has a limited READ_AUDIO buffer
224  *       size.
225  *       Removed "MANY_SESSION" handling for "old" multi session CDs.
226  *       Added "private" IOCTLs CDROMRESET and CDROMVOLREAD.
227  *       Started again to support the TEAC CD-55A drives, now that I found
228  *       the money for "my own" drive. ;-)
229  *       The TEAC CD-55A support is fairly working now.
230  *       I have measured that the drive "delivers" at 600 kB/sec (even with
231  *       bigger requests than the drive's 64 kB buffer can satisfy), but
232  *       the "real" rate does not exceed 520 kB/sec at the moment. 
233  *       Caused by the various changes to build in TEAC support, the timed
234  *       loops are de-optimized at the moment (less throughput with CR-52x
235  *       drives, and the TEAC will give speed only with SBP_BUFFER_FRAMES 64).
236  *
237  *  3.6  Fixed TEAC data read problems with SbPro interfaces.
238  *       Initial size of the READ_AUDIO buffer is 0. Can get set to any size
239  *       during runtime.
240  *
241  *  3.7  Introduced MAX_DRIVES for some poor interface cards (seen with TEAC
242  *       drives) which allow only one drive (ID 0); this avoids repetitive
243  *       detection under IDs 1..3. 
244  *       Elongated cmd_out_T response waiting; necessary for photo CDs with
245  *       a lot of sessions.
246  *       Bettered the sbpcd_open() behavior with TEAC drives.
247  *
248  *  3.8  Elongated max_latency for CR-56x drives.
249  *
250  *  3.9  Finally fixed the long-known SoundScape/SPEA/Sequoia S-1000 interface
251  *       configuration bug.
252  *       Now Corey, Heiko, Ken, Leo, Vadim/Eric & Werner are invited to copy
253  *       the config_spea() routine into their drivers. ;-)
254  *
255  *  4.0  No "big step" - normal version increment.
256  *       Adapted the benefits from 1.3.33.
257  *       Fiddled with CDROMREADAUDIO flaws.
258  *       Avoid ReadCapacity command with CD200 drives (the MKE 1.01 version
259  *       seems not to support it).
260  *       Fulfilled "read audio" for CD200 drives, with help of Pete Heist
261  *       (heistp@rpi.edu).
262  *
263  *  4.1  Use loglevel KERN_INFO with printk().
264  *       Added support for "Vertos 100" drive ("ECS-AT") - it is very similar
265  *       to the Longshine LCS-7260. Give feedback if you can - I never saw
266  *       such a drive, and I have no specs.
267  *
268  *  4.2  Support for Teac 16-bit interface cards. Can't get auto-detected,
269  *       so you have to jumper your card to 0x2C0. Still not 100% - come
270  *       in contact if you can give qualified feedback.
271  *       Use loglevel KERN_NOTICE with printk(). If you get annoyed by a
272  *       flood of unwanted messages and the accompanied delay, try to read
273  *       my documentation. Especially the Linux CDROM drivers have to do an
274  *       important job for the newcomers, so the "distributed" version has
275  *       to fit some special needs. Since generations, the flood of messages
276  *       is user-configurable (even at runtime), but to get aware of this, one
277  *       needs a special mental quality: the ability to read.
278  *       
279  *  4.3  CD200F does not like to receive a command while the drive is
280  *       reading the ToC; still trying to solve it.
281  *       Removed some redundant verify_area calls (yes, Heiko Eissfeldt
282  *       is visiting all the Linux CDROM drivers ;-).
283  *       
284  *  4.4  Adapted one idea from tiensivu@pilot.msu.edu's "stripping-down"
285  *       experiments: "KLOGD_PAUSE".
286  *       Inhibited "play audio" attempts with data CDs. Provisions for a
287  *       "data-safe" handling of "mixed" (data plus audio) Cds.
288  *
289  *  4.5  Meanwhile Gonzalo Tornaria <tornaria@cmat.edu.uy> (GTL) built a
290  *       special end_request routine: we seem to have to take care for not
291  *       to have two processes working at the request list. My understanding
292  *       was and is that ll_rw_blk should not call do_sbpcd_request as long
293  *       as there is still one call active (the first call will care for all
294  *       outstanding I/Os, and if a second call happens, that is a bug in
295  *       ll_rw_blk.c).
296  *       "Check media change" without touching any drive.
297  *
298  *  4.6  Use a semaphore to synchronize multi-activity; elaborated by Rob
299  *       Riggs <rriggs@tesser.com>. At the moment, we simply block "read"
300  *       against "ioctl" and vice versa. This could be refined further, but
301  *       I guess with almost no performance increase.
302  *       Experiments to speed up the CD-55A; again with help of Rob Riggs
303  *       (to be true, he gave both, idea & code. ;-)
304  *
305  *  4.61 Ported to Uniform CD-ROM driver by 
306  *       Heiko Eissfeldt <heiko@colossus.escape.de> with additional
307  *       changes by Erik Andersen <andersee@debian.org>
308  *
309  *  4.62 Fix a bug where playing audio left the drive in an unusable state.
310  *         Heiko Eissfeldt <heiko@colossus.escape.de>
311  *
312  *  November 1999 -- Make kernel-parameter implementation work with 2.3.x 
313  *                   Removed init_module & cleanup_module in favor of 
314  *                   module_init & module_exit.
315  *                   Torben Mathiasen <tmm@image.dk>
316  *
317  *  4.63 Bug fixes for audio annoyances, new legacy CDROM maintainer.
318  *              Annoying things fixed:
319  *              TOC reread on automated disk changes
320  *              TOC reread on manual cd changes
321  *              Play IOCTL tries to play CD before it's actually ready... sometimes.
322  *              CD_AUDIO_COMPLETED state so workman (and other playes) can repeat play.
323  *              Andrew J. Kroll <ag784@freenet.buffalo.edu> Wed Jul 26 04:24:10 EDT 2000
324  *
325  *  4.64 Fix module parameters - were being completely ignored.
326  *       Can also specify max_drives=N as a setup int to get rid of
327  *       "ghost" drives on crap hardware (aren't they all?)   Paul Gortmaker
328  *
329  *  TODO
330  *     implement "read all subchannel data" (96 bytes per frame)
331  *     remove alot of the virtual status bits and deal with hardware status
332  *     move the change of cd for audio to a better place
333  *     add debug levels to insmod parameters (trivial)
334  *
335  *     special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
336  *     elaborated speed-up experiments (and the fabulous results!), for
337  *     the "push" towards load-free wait loops, and for the extensive mail
338  *     thread which brought additional hints and bug fixes.
339  *
340  */
341
342 /*
343  * Trying to merge requests breaks this driver horribly (as in it goes
344  * boom and apparently has done so since 2.3.41).  As it is a legacy 
345  * driver for a horribly slow double speed CD on a hideous interface 
346  * designed for polled operation, I won't loose any sleep in simply 
347  * disallowing merging.                         Paul G.  02/2001
348  */
349 #define DONT_MERGE_REQUESTS
350
351 #ifndef SBPCD_ISSUE
352 #define SBPCD_ISSUE 1
353 #endif /* SBPCD_ISSUE */
354
355 #include <linux/module.h>
356
357 #include <linux/version.h>
358 #include <linux/errno.h>
359 #include <linux/sched.h>
360 #include <linux/mm.h>
361 #include <linux/timer.h>
362 #include <linux/fs.h>
363 #include <linux/kernel.h>
364 #include <linux/cdrom.h>
365 #include <linux/ioport.h>
366 #include <linux/devfs_fs_kernel.h>
367 #include <linux/major.h> 
368 #include <linux/string.h>
369 #include <linux/vmalloc.h>
370 #include <linux/init.h>
371 #include <linux/interrupt.h>
372
373 #include <asm/system.h>
374 #include <asm/io.h>
375 #include <asm/uaccess.h>
376 #include <stdarg.h>
377 #include <linux/config.h>
378 #include "sbpcd.h"
379
380 #if !(SBPCD_ISSUE-1)
381 #define MAJOR_NR MATSUSHITA_CDROM_MAJOR
382 #endif
383 #if !(SBPCD_ISSUE-2)
384 #define MAJOR_NR MATSUSHITA_CDROM2_MAJOR /* second driver issue */
385 #endif
386 #if !(SBPCD_ISSUE-3)
387 #define MAJOR_NR MATSUSHITA_CDROM3_MAJOR /* third driver issue */
388 #endif
389 #if !(SBPCD_ISSUE-4)
390 #define MAJOR_NR MATSUSHITA_CDROM4_MAJOR /* fourth driver issue */
391 #endif
392
393 #include <linux/blk.h>
394
395 /*==========================================================================*/
396 /*
397  * provisions for more than 1 driver issues
398  * currently up to 4 drivers, expandable
399  */
400 #if !(SBPCD_ISSUE-1)
401 #define DO_SBPCD_REQUEST(a) do_sbpcd_request(a)
402 #define SBPCD_INIT(a) sbpcd_init(a)
403 #endif
404 #if !(SBPCD_ISSUE-2)
405 #define DO_SBPCD_REQUEST(a) do_sbpcd2_request(a)
406 #define SBPCD_INIT(a) sbpcd2_init(a)
407 #endif
408 #if !(SBPCD_ISSUE-3)
409 #define DO_SBPCD_REQUEST(a) do_sbpcd3_request(a)
410 #define SBPCD_INIT(a) sbpcd3_init(a)
411 #endif
412 #if !(SBPCD_ISSUE-4)
413 #define DO_SBPCD_REQUEST(a) do_sbpcd4_request(a)
414 #define SBPCD_INIT(a) sbpcd4_init(a)
415 #endif
416 /*==========================================================================*/
417 #if SBPCD_DIS_IRQ
418 #define SBPCD_CLI cli()
419 #define SBPCD_STI sti()
420 #else
421 #define SBPCD_CLI
422 #define SBPCD_STI
423 #endif /* SBPCD_DIS_IRQ */
424 /*==========================================================================*/
425 /*
426  * auto-probing address list
427  * inspired by Adam J. Richter from Yggdrasil
428  *
429  * still not good enough - can cause a hang.
430  *   example: a NE 2000 ethernet card at 300 will cause a hang probing 310.
431  * if that happens, reboot and use the LILO (kernel) command line.
432  * The possibly conflicting ethernet card addresses get NOT probed 
433  * by default - to minimize the hang possibilities. 
434  *
435  * The SB Pro addresses get "mirrored" at 0x6xx and some more locations - to
436  * avoid a type error, the 0x2xx-addresses must get checked before 0x6xx.
437  *
438  * send mail to emoenke@gwdg.de if your interface card is not FULLY
439  * represented here.
440  */
441 #if !(SBPCD_ISSUE-1)
442 static int sbpcd[] = 
443 {
444         CDROM_PORT, SBPRO, /* probe with user's setup first */
445 #if DISTRIBUTION
446         0x230, 1, /* Soundblaster Pro and 16 (default) */
447 #if 0
448         0x300, 0, /* CI-101P (default), WDH-7001C (default),
449                      Galaxy (default), Reveal (one default) */
450         0x250, 1, /* OmniCD default, Soundblaster Pro and 16 */
451         0x2C0, 3, /* Teac 16-bit cards */
452         0x260, 1, /* OmniCD */
453         0x320, 0, /* Lasermate, CI-101P, WDH-7001C, Galaxy, Reveal (other default),
454                      Longshine LCS-6853 (default) */
455         0x338, 0, /* Reveal Sound Wave 32 card model #SC600 */
456         0x340, 0, /* Mozart sound card (default), Lasermate, CI-101P */
457         0x360, 0, /* Lasermate, CI-101P */
458         0x270, 1, /* Soundblaster 16 */
459         0x670, 0, /* "sound card #9" */
460         0x690, 0, /* "sound card #9" */
461         0x338, 2, /* SPEA Media FX, Ensonic SoundScape (default) */
462         0x328, 2, /* SPEA Media FX */
463         0x348, 2, /* SPEA Media FX */
464         0x634, 0, /* some newer sound cards */
465         0x638, 0, /* some newer sound cards */
466         0x230, 1, /* some newer sound cards */
467         /* due to incomplete address decoding of the SbPro card, these must be last */
468         0x630, 0, /* "sound card #9" (default) */
469         0x650, 0, /* "sound card #9" */
470 #ifdef MODULE
471         /*
472          * some "hazardous" locations (no harm with the loadable version)
473          * (will stop the bus if a NE2000 ethernet card resides at offset -0x10)
474          */
475         0x330, 0, /* Lasermate, CI-101P, WDH-7001C */
476         0x350, 0, /* Lasermate, CI-101P */
477         0x358, 2, /* SPEA Media FX */
478         0x370, 0, /* Lasermate, CI-101P */
479         0x290, 1, /* Soundblaster 16 */
480         0x310, 0, /* Lasermate, CI-101P, WDH-7001C */
481 #endif /* MODULE */
482 #endif
483 #endif /* DISTRIBUTION */
484 };
485 #else
486 static int sbpcd[] = {CDROM_PORT, SBPRO}; /* probe with user's setup only */
487 #endif
488 MODULE_PARM(sbpcd, "2i");
489 MODULE_PARM(max_drives, "i");
490
491 #define NUM_PROBE  (sizeof(sbpcd) / sizeof(int))
492
493 /*==========================================================================*/
494 /*
495  * the external references:
496  */
497 #if !(SBPCD_ISSUE-1)
498 #ifdef CONFIG_SBPCD2
499 extern int sbpcd2_init(void);
500 #endif
501 #ifdef CONFIG_SBPCD3
502 extern int sbpcd3_init(void);
503 #endif
504 #ifdef CONFIG_SBPCD4
505 extern int sbpcd4_init(void);
506 #endif
507 #endif
508
509 /*==========================================================================*/
510
511 #define INLINE inline
512
513 /*==========================================================================*/
514 /*
515  * the forward references:
516  */
517 static void sbp_sleep(u_int);
518 static void mark_timeout_delay(u_long);
519 static void mark_timeout_data(u_long);
520 #if 0
521 static void mark_timeout_audio(u_long);
522 #endif
523 static void sbp_read_cmd(struct request *req);
524 static int sbp_data(struct request *req);
525 static int cmd_out(void);
526 static int DiskInfo(void);
527 static int sbpcd_chk_disk_change(kdev_t);
528
529 /*==========================================================================*/
530
531 /*
532  * pattern for printk selection:
533  *
534  * (1<<DBG_INF)  necessary information
535  * (1<<DBG_BSZ)  BLOCK_SIZE trace
536  * (1<<DBG_REA)  "read" status trace
537  * (1<<DBG_CHK)  "media check" trace
538  * (1<<DBG_TIM)  datarate timer test
539  * (1<<DBG_INI)  initialization trace
540  * (1<<DBG_TOC)  tell TocEntry values
541  * (1<<DBG_IOC)  ioctl trace
542  * (1<<DBG_STA)  "ResponseStatus" trace
543  * (1<<DBG_ERR)  "cc_ReadError" trace
544  * (1<<DBG_CMD)  "cmd_out" trace
545  * (1<<DBG_WRN)  give explanation before auto-probing
546  * (1<<DBG_MUL)  multi session code test
547  * (1<<DBG_IDX)  "drive_id != 0" test code
548  * (1<<DBG_IOX)  some special information
549  * (1<<DBG_DID)  drive ID test
550  * (1<<DBG_RES)  drive reset info
551  * (1<<DBG_SPI)  SpinUp test info
552  * (1<<DBG_IOS)  ioctl trace: "subchannel"
553  * (1<<DBG_IO2)  ioctl trace: general
554  * (1<<DBG_UPC)  show UPC info
555  * (1<<DBG_XA1)  XA mode debugging
556  * (1<<DBG_LCK)  door (un)lock info
557  * (1<<DBG_SQ1)   dump SubQ frame
558  * (1<<DBG_AUD)  "read audio" debugging
559  * (1<<DBG_SEQ)  Sequoia interface configuration trace
560  * (1<<DBG_LCS)  Longshine LCS-7260 debugging trace
561  * (1<<DBG_CD2)  MKE/Funai CD200 debugging trace
562  * (1<<DBG_TEA)  TEAC CD-55A debugging trace
563  * (1<<DBG_ECS)  ECS-AT (Vertos-100) debugging trace
564  * (1<<DBG_000)  unnecessary information
565  */
566 #if DISTRIBUTION
567 static int sbpcd_debug = (1<<DBG_INF);
568 #else
569 static int sbpcd_debug = 0 & ((1<<DBG_INF) |
570                           (1<<DBG_TOC) |
571                           (1<<DBG_MUL) |
572                           (1<<DBG_UPC));
573 #endif /* DISTRIBUTION */
574
575 static int sbpcd_ioaddr = CDROM_PORT;   /* default I/O base address */
576 static int sbpro_type = SBPRO;
577 static unsigned char f_16bit;
578 static unsigned char do_16bit;
579 static int CDo_command, CDo_reset;
580 static int CDo_sel_i_d, CDo_enable;
581 static int CDi_info, CDi_status, CDi_data;
582 static struct cdrom_msf msf;
583 static struct cdrom_ti ti;
584 static struct cdrom_tochdr tochdr;
585 static struct cdrom_tocentry tocentry;
586 static struct cdrom_subchnl SC;
587 static struct cdrom_volctrl volctrl;
588 static struct cdrom_read_audio read_audio;
589
590 static unsigned char msgnum;
591 static char msgbuf[80];
592
593 static int max_drives = MAX_DRIVES;
594 #ifndef MODULE
595 static unsigned char setup_done;
596 static const char *str_sb_l = "soundblaster";
597 static const char *str_sp_l = "spea";
598 static const char *str_ss_l = "soundscape";
599 static const char *str_t16_l = "teac16bit";
600 static const char *str_ss = "SoundScape";
601 #endif
602 static const char *str_sb = "SoundBlaster";
603 static const char *str_lm = "LaserMate";
604 static const char *str_sp = "SPEA";
605 static const char *str_t16 = "Teac16bit";
606 static const char *type;
607
608 #if !(SBPCD_ISSUE-1)
609 static const char *major_name="sbpcd";
610 #endif
611 #if !(SBPCD_ISSUE-2)
612 static const char *major_name="sbpcd2";
613 #endif
614 #if !(SBPCD_ISSUE-3)
615 static const char *major_name="sbpcd3";
616 #endif
617 #if !(SBPCD_ISSUE-4)
618 static const char *major_name="sbpcd4";
619 #endif
620
621 /*==========================================================================*/
622
623 #if FUTURE
624 static DECLARE_WAIT_QUEUE_HEAD(sbp_waitq);
625 #endif /* FUTURE */
626
627 static int teac=SBP_TEAC_SPEED;
628 static int buffers=SBP_BUFFER_FRAMES;
629
630 static u_char family0[]="MATSHITA"; /* MKE CR-521, CR-522, CR-523 */
631 static u_char family1[]="CR-56";    /* MKE CR-562, CR-563 */
632 static u_char family2[]="CD200";    /* MKE CD200, Funai CD200F */
633 static u_char familyL[]="LCS-7260"; /* Longshine LCS-7260 */
634 static u_char familyT[]="CD-55";    /* TEAC CD-55A */
635 static u_char familyV[]="ECS-AT";   /* ECS Vertos 100 */
636
637 static u_int recursion; /* internal testing only */
638 static u_int fatal_err; /* internal testing only */
639 static u_int response_count;
640 static u_int flags_cmd_out;
641 static u_char cmd_type;
642 static u_char drvcmd[10];
643 static u_char infobuf[20];
644 static u_char xa_head_buf[CD_XA_HEAD];
645 static u_char xa_tail_buf[CD_XA_TAIL];
646
647 #if OLD_BUSY
648 static volatile u_char busy_data;
649 static volatile u_char busy_audio; /* true semaphores would be safer */
650 #endif /* OLD_BUSY */ 
651 static DECLARE_MUTEX(ioctl_read_sem);
652 static u_long timeout;
653 static volatile u_char timed_out_delay;
654 static volatile u_char timed_out_data;
655 #if 0
656 static volatile u_char timed_out_audio;
657 #endif
658 static u_int datarate= 1000000;
659 static u_int maxtim16=16000000;
660 static u_int maxtim04= 4000000;
661 static u_int maxtim02= 2000000;
662 static u_int maxtim_8=   30000;
663 #if LONG_TIMING
664 static u_int maxtim_data= 9000;
665 #else
666 static u_int maxtim_data= 3000;
667 #endif /* LONG_TIMING */ 
668 #if DISTRIBUTION
669 static int n_retries=6;
670 #else
671 static int n_retries=6;
672 #endif
673 /*==========================================================================*/
674
675 static int ndrives;
676 static u_char drv_pattern[NR_SBPCD]={speed_auto,speed_auto,speed_auto,speed_auto};
677 static int sbpcd_blocksizes[NR_SBPCD];
678
679 /*==========================================================================*/
680 /*
681  * drive space begins here (needed separate for each unit) 
682  */
683 static int d; /* DriveStruct index: drive number */
684
685 static struct {
686         char drv_id;           /* "jumpered" drive ID or -1 */
687         char drv_sel;          /* drive select lines bits */
688         
689         char drive_model[9];
690         u_char firmware_version[4];
691         char f_eject;          /* auto-eject flag: 0 or 1 */
692         u_char *sbp_buf;       /* Pointer to internal data buffer,
693                                   space allocated during sbpcd_init() */
694         u_int sbp_bufsiz;      /* size of sbp_buf (# of frames) */
695         int sbp_first_frame;   /* First frame in buffer */
696         int sbp_last_frame;    /* Last frame in buffer  */
697         int sbp_read_frames;   /* Number of frames being read to buffer */
698         int sbp_current;       /* Frame being currently read */
699         
700         u_char mode;           /* read_mode: READ_M1, READ_M2, READ_SC, READ_AU */
701         u_char *aud_buf;       /* Pointer to audio data buffer,
702                                   space allocated during sbpcd_init() */
703         u_int sbp_audsiz;      /* size of aud_buf (# of raw frames) */
704         u_int drv_type;
705         u_char drv_options;
706         int status_bits;
707         u_char diskstate_flags;
708         u_char sense_byte;
709         
710         u_char CD_changed;
711         char open_count;
712         u_char error_byte;
713         
714         u_char f_multisession;
715         u_int lba_multi;
716         int first_session;
717         int last_session;
718         int track_of_last_session;
719         
720         u_char audio_state;
721         u_int pos_audio_start;
722         u_int pos_audio_end;
723         char vol_chan0;
724         u_char vol_ctrl0;
725         char vol_chan1;
726         u_char vol_ctrl1;
727 #if 000 /* no supported drive has it */
728         char vol_chan2;
729         u_char vol_ctrl2;
730         char vol_chan3;
731         u_char vol_ctrl3;
732 #endif /*000 */
733         u_char volume_control; /* TEAC on/off bits */
734         
735         u_char SubQ_ctl_adr;
736         u_char SubQ_trk;
737         u_char SubQ_pnt_idx;
738         u_int SubQ_run_tot;
739         u_int SubQ_run_trk;
740         u_char SubQ_whatisthis;
741         
742         u_char UPC_ctl_adr;
743         u_char UPC_buf[7];
744         
745         int frame_size;
746         int CDsize_frm;
747         
748         u_char xa_byte; /* 0x20: XA capabilities */
749         u_char n_first_track; /* binary */
750         u_char n_last_track; /* binary (not bcd), 0x01...0x63 */
751         u_int size_msf; /* time of whole CD, position of LeadOut track */
752         u_int size_blk;
753         
754         u_char TocEnt_nixbyte; /* em */
755         u_char TocEnt_ctl_adr;
756         u_char TocEnt_number;
757         u_char TocEnt_format; /* em */
758         u_int TocEnt_address;
759 #if SAFE_MIXED
760         char has_data;
761 #endif /* SAFE_MIXED */ 
762         u_char ored_ctl_adr; /* to detect if CDROM contains data tracks */
763         
764         struct {
765                 u_char nixbyte; /* em */
766                 u_char ctl_adr; /* 0x4x: data, 0x0x: audio */
767                 u_char number;
768                 u_char format; /* em */ /* 0x00: lba, 0x01: msf */
769                 u_int address;
770         } TocBuffer[MAX_TRACKS+1]; /* last entry faked */ 
771         
772         int in_SpinUp; /* CR-52x test flag */
773         int n_bytes; /* TEAC awaited response count */
774         u_char error_state, b3, b4; /* TEAC command error state */
775         u_char f_drv_error; /* TEAC command error flag */
776         u_char speed_byte;
777         int frmsiz;
778         u_char f_XA; /* 1: XA */
779         u_char type_byte; /* 0, 1, 3 */
780         u_char mode_xb_6;
781         u_char mode_yb_7;
782         u_char mode_xb_8;
783         u_char delay;
784         struct cdrom_device_info *sbpcd_infop;
785
786 } D_S[NR_SBPCD];
787
788 /*
789  * drive space ends here (needed separate for each unit)
790  */
791 /*==========================================================================*/
792 #if 0
793 unsigned long cli_sti; /* for saving the processor flags */
794 #endif
795 /*==========================================================================*/
796 static struct timer_list delay_timer = { function: mark_timeout_delay};
797 static struct timer_list data_timer = { function: mark_timeout_data};
798 #if 0
799 static struct timer_list audio_timer = { function: mark_timeout_audio};
800 #endif
801 /*==========================================================================*/
802 /*
803  * DDI interface
804  */
805 static void msg(int level, const char *fmt, ...)
806 {
807 #if DISTRIBUTION
808 #define MSG_LEVEL KERN_NOTICE
809 #else
810 #define MSG_LEVEL KERN_INFO
811 #endif /* DISTRIBUTION */
812
813         char buf[256];
814         va_list args;
815         
816         if (!(sbpcd_debug&(1<<level))) return;
817         
818         msgnum++;
819         if (msgnum>99) msgnum=0;
820         sprintf(buf, MSG_LEVEL "%s-%d [%02d]:  ", major_name, d, msgnum);
821         va_start(args, fmt);
822         vsprintf(&buf[18], fmt, args);
823         va_end(args);
824         printk(buf);
825 #if KLOGD_PAUSE
826         sbp_sleep(KLOGD_PAUSE); /* else messages get lost */
827 #endif /* KLOGD_PAUSE */ 
828         return;
829 }
830 /*==========================================================================*/
831 /*
832  * DDI interface: runtime trace bit pattern maintenance
833  */
834 static int sbpcd_dbg_ioctl(unsigned long arg, int level)
835 {
836         switch(arg)
837         {
838         case 0: /* OFF */
839                 sbpcd_debug = DBG_INF;
840                 break;
841                 
842         default:
843                 if (arg>=128) sbpcd_debug &= ~(1<<(arg-128));
844                 else sbpcd_debug |= (1<<arg);
845         }
846         return (arg);
847 }
848 /*==========================================================================*/
849 static void mark_timeout_delay(u_long i)
850 {
851         timed_out_delay=1;
852 #if 0
853         msg(DBG_TIM,"delay timer expired.\n");
854 #endif
855 }
856 /*==========================================================================*/
857 static void mark_timeout_data(u_long i)
858 {
859         timed_out_data=1;
860 #if 0
861         msg(DBG_TIM,"data timer expired.\n");
862 #endif
863 }
864 /*==========================================================================*/
865 #if 0
866 static void mark_timeout_audio(u_long i)
867 {
868         timed_out_audio=1;
869 #if 0
870         msg(DBG_TIM,"audio timer expired.\n");
871 #endif
872 }
873 #endif
874 /*==========================================================================*/
875 /*
876  * Wait a little while (used for polling the drive).
877  */
878 static void sbp_sleep(u_int time)
879 {
880         sti();
881         current->state = TASK_INTERRUPTIBLE;
882         schedule_timeout(time);
883         sti();
884 }
885 /*==========================================================================*/
886 #define RETURN_UP(rc) {up(&ioctl_read_sem); return(rc);}
887 /*==========================================================================*/
888 /*
889  *  convert logical_block_address to m-s-f_number (3 bytes only)
890  */
891 static INLINE void lba2msf(int lba, u_char *msf)
892 {
893         lba += CD_MSF_OFFSET;
894         msf[0] = lba / (CD_SECS*CD_FRAMES);
895         lba %= CD_SECS*CD_FRAMES;
896         msf[1] = lba / CD_FRAMES;
897         msf[2] = lba % CD_FRAMES;
898 }
899 /*==========================================================================*/
900 /*==========================================================================*/
901 /*
902  *  convert msf-bin to msf-bcd
903  */
904 static INLINE void bin2bcdx(u_char *p)  /* must work only up to 75 or 99 */
905 {
906         *p=((*p/10)<<4)|(*p%10);
907 }
908 /*==========================================================================*/
909 static INLINE u_int blk2msf(u_int blk)
910 {
911         MSF msf;
912         u_int mm;
913         
914         msf.c[3] = 0;
915         msf.c[2] = (blk + CD_MSF_OFFSET) / (CD_SECS * CD_FRAMES);
916         mm = (blk + CD_MSF_OFFSET) % (CD_SECS * CD_FRAMES);
917         msf.c[1] = mm / CD_FRAMES;
918         msf.c[0] = mm % CD_FRAMES;
919         return (msf.n);
920 }
921 /*==========================================================================*/
922 static INLINE u_int make16(u_char rh, u_char rl)
923 {
924         return ((rh<<8)|rl);
925 }
926 /*==========================================================================*/
927 static INLINE u_int make32(u_int rh, u_int rl)
928 {
929         return ((rh<<16)|rl);
930 }
931 /*==========================================================================*/
932 static INLINE u_char swap_nibbles(u_char i)
933 {
934         return ((i<<4)|(i>>4));
935 }
936 /*==========================================================================*/
937 static INLINE u_char byt2bcd(u_char i)
938 {
939         return (((i/10)<<4)+i%10);
940 }
941 /*==========================================================================*/
942 static INLINE u_char bcd2bin(u_char bcd)
943 {
944         return ((bcd>>4)*10+(bcd&0x0F));
945 }
946 /*==========================================================================*/
947 static INLINE int msf2blk(int msfx)
948 {
949         MSF msf;
950         int i;
951         
952         msf.n=msfx;
953         i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_MSF_OFFSET;
954         if (i<0) return (0);
955         return (i);
956 }
957 /*==========================================================================*/
958 /*
959  *  convert m-s-f_number (3 bytes only) to logical_block_address 
960  */
961 static INLINE int msf2lba(u_char *msf)
962 {
963         int i;
964         
965         i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_MSF_OFFSET;
966         if (i<0) return (0);
967         return (i);
968 }
969 /*==========================================================================*/
970 /* evaluate cc_ReadError code */ 
971 static int sta2err(int sta)
972 {
973         if (famT_drive)
974         {
975                 if (sta==0x00) return (0);
976                 if (sta==0x01) return (-604); /* CRC error */
977                 if (sta==0x02) return (-602); /* drive not ready */
978                 if (sta==0x03) return (-607); /* unknown media */
979                 if (sta==0x04) return (-612); /* general failure */
980                 if (sta==0x05) return (0);
981                 if (sta==0x06) return (-ERR_DISKCHANGE); /* disk change */
982                 if (sta==0x0b) return (-612); /* general failure */
983                 if (sta==0xff) return (-612); /* general failure */
984                 return (0);
985         }
986         else
987         {
988                 if (sta<=2) return (sta);
989                 if (sta==0x05) return (-604); /* CRC error */
990                 if (sta==0x06) return (-606); /* seek error */
991                 if (sta==0x0d) return (-606); /* seek error */
992                 if (sta==0x0e) return (-603); /* unknown command */
993                 if (sta==0x14) return (-603); /* unknown command */
994                 if (sta==0x0c) return (-611); /* read fault */
995                 if (sta==0x0f) return (-611); /* read fault */
996                 if (sta==0x10) return (-611); /* read fault */
997                 if (sta>=0x16) return (-612); /* general failure */
998                 if (sta==0x11) return (-ERR_DISKCHANGE); /* disk change (LCS: removed) */
999                 if (famL_drive)
1000                         if (sta==0x12) return (-ERR_DISKCHANGE); /* disk change (inserted) */
1001                 return (-602); /* drive not ready */
1002         }
1003 }
1004 /*==========================================================================*/
1005 static INLINE void clr_cmdbuf(void)
1006 {
1007         int i;
1008         
1009         for (i=0;i<10;i++) drvcmd[i]=0;
1010         cmd_type=0;
1011 }
1012 /*==========================================================================*/
1013 static void flush_status(void)
1014 {
1015         int i;
1016         
1017         sbp_sleep(15*HZ/10);
1018         for (i=maxtim_data;i!=0;i--) inb(CDi_status);
1019 }
1020 /*====================================================================*/
1021 /*
1022  * CDi status loop for Teac CD-55A (Rob Riggs)
1023  *
1024  * This is needed because for some strange reason
1025  * the CD-55A can take a real long time to give a
1026  * status response. This seems to happen after we
1027  * issue a READ command where a long seek is involved.
1028  *
1029  * I tried to ensure that we get max throughput with
1030  * minimal busy waiting. We busy wait at first, then
1031  * "switch gears" and start sleeping. We sleep for
1032  * longer periods of time the longer we wait.
1033  *
1034  */
1035 static int CDi_stat_loop_T(void)
1036 {
1037         int     i, gear=1;
1038         u_long  timeout_1, timeout_2, timeout_3, timeout_4;
1039
1040         timeout_1 = jiffies + HZ / 50;  /* sbp_sleep(0) for a short period */
1041         timeout_2 = jiffies + HZ / 5;   /* nap for no more than 200ms */
1042         timeout_3 = jiffies + 5 * HZ;   /* sleep for up to 5s */
1043         timeout_4 = jiffies + 45 * HZ;  /* long sleep for up to 45s. */
1044         do
1045           {
1046             i = inb(CDi_status);
1047             if (!(i&s_not_data_ready)) return (i);
1048             if (!(i&s_not_result_ready)) return (i);
1049             switch(gear)
1050               {
1051               case 4:
1052                 sbp_sleep(HZ);
1053                 if (time_after(jiffies, timeout_4)) gear++;
1054                 msg(DBG_TEA, "CDi_stat_loop_T: long sleep active.\n");
1055                 break;
1056               case 3:
1057                 sbp_sleep(HZ/10);
1058                 if (time_after(jiffies, timeout_3)) gear++;
1059                 break;
1060               case 2:
1061                 sbp_sleep(HZ/100);
1062                 if (time_after(jiffies, timeout_2)) gear++;
1063                 break;
1064               case 1:
1065                 sbp_sleep(0);
1066                 if (time_after(jiffies, timeout_1)) gear++;
1067               }
1068           } while (gear < 5);
1069         return -1;
1070 }
1071 /*==========================================================================*/
1072 static int CDi_stat_loop(void)
1073 {
1074         int i,j;
1075         
1076         for(timeout = jiffies + 10*HZ, i=maxtim_data; time_before(jiffies, timeout); )
1077         {
1078                 for ( ;i!=0;i--)
1079                 {
1080                         j=inb(CDi_status);
1081                         if (!(j&s_not_data_ready)) return (j);
1082                         if (!(j&s_not_result_ready)) return (j);
1083                         if (fam0L_drive) if (j&s_attention) return (j);
1084                 }
1085                 sbp_sleep(1);
1086                 i = 1;
1087         }
1088         msg(DBG_LCS,"CDi_stat_loop failed in line %d\n", __LINE__);
1089         return (-1);
1090 }
1091 /*==========================================================================*/
1092 #if 00000
1093 /*==========================================================================*/
1094 static int tst_DataReady(void)
1095 {
1096         int i;
1097         
1098         i=inb(CDi_status);
1099         if (i&s_not_data_ready) return (0);
1100         return (1);
1101 }
1102 /*==========================================================================*/
1103 static int tst_ResultReady(void)
1104 {
1105         int i;
1106         
1107         i=inb(CDi_status);
1108         if (i&s_not_result_ready) return (0);
1109         return (1);
1110 }
1111 /*==========================================================================*/
1112 static int tst_Attention(void)
1113 {
1114         int i;
1115         
1116         i=inb(CDi_status);
1117         if (i&s_attention) return (1);
1118         return (0);
1119 }
1120 /*==========================================================================*/
1121 #endif
1122 /*==========================================================================*/
1123 static int ResponseInfo(void)
1124 {
1125         int i,j,st=0;
1126         u_long timeout;
1127         
1128         for (i=0,timeout=jiffies+HZ;i<response_count;i++) 
1129         {
1130                 for (j=maxtim_data; ; )
1131                 {
1132                         for ( ;j!=0;j-- )
1133                         {
1134                                 st=inb(CDi_status);
1135                                 if (!(st&s_not_result_ready)) break;
1136                         }
1137                         if ((j!=0)||time_after_eq(jiffies, timeout)) break;
1138                         sbp_sleep(1);
1139                         j = 1;
1140                 }
1141                 if (time_after_eq(jiffies, timeout)) break;
1142                 infobuf[i]=inb(CDi_info);
1143         }
1144 #if 000
1145         while (!(inb(CDi_status)&s_not_result_ready))
1146         {
1147                 infobuf[i++]=inb(CDi_info);
1148         }
1149         j=i-response_count;
1150         if (j>0) msg(DBG_INF,"ResponseInfo: got %d trailing bytes.\n",j);
1151 #endif /* 000 */
1152         for (j=0;j<i;j++)
1153                 sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
1154         msgbuf[j*3]=0;
1155         msg(DBG_CMD,"ResponseInfo:%s (%d,%d)\n",msgbuf,response_count,i);
1156         j=response_count-i;
1157         if (j>0) return (-j);
1158         else return (i);
1159 }
1160 /*==========================================================================*/
1161 static void EvaluateStatus(int st)
1162 {
1163         D_S[d].status_bits=0;
1164         if (fam1_drive) D_S[d].status_bits=st|p_success;
1165         else if (fam0_drive)
1166         {
1167                 if (st&p_caddin_old) D_S[d].status_bits |= p_door_closed|p_caddy_in;
1168                 if (st&p_spinning) D_S[d].status_bits |= p_spinning;
1169                 if (st&p_check) D_S[d].status_bits |= p_check;
1170                 if (st&p_success_old) D_S[d].status_bits |= p_success;
1171                 if (st&p_busy_old) D_S[d].status_bits |= p_busy_new;
1172                 if (st&p_disk_ok) D_S[d].status_bits |= p_disk_ok;
1173         }
1174         else if (famLV_drive)
1175         {
1176                 D_S[d].status_bits |= p_success;
1177                 if (st&p_caddin_old) D_S[d].status_bits |= p_disk_ok|p_caddy_in;
1178                 if (st&p_spinning) D_S[d].status_bits |= p_spinning;
1179                 if (st&p_check) D_S[d].status_bits |= p_check;
1180                 if (st&p_busy_old) D_S[d].status_bits |= p_busy_new;
1181                 if (st&p_lcs_door_closed) D_S[d].status_bits |= p_door_closed;
1182                 if (st&p_lcs_door_locked) D_S[d].status_bits |= p_door_locked;
1183         }
1184         else if (fam2_drive)
1185         {
1186                 D_S[d].status_bits |= p_success;
1187                 if (st&p2_check) D_S[d].status_bits |= p1_check;
1188                 if (st&p2_door_closed) D_S[d].status_bits |= p1_door_closed;
1189                 if (st&p2_disk_in) D_S[d].status_bits |= p1_disk_in;
1190                 if (st&p2_busy1) D_S[d].status_bits |= p1_busy;
1191                 if (st&p2_busy2) D_S[d].status_bits |= p1_busy;
1192                 if (st&p2_spinning) D_S[d].status_bits |= p1_spinning;
1193                 if (st&p2_door_locked) D_S[d].status_bits |= p1_door_locked;
1194                 if (st&p2_disk_ok) D_S[d].status_bits |= p1_disk_ok;
1195         }
1196         else if (famT_drive)
1197         {
1198                 return; /* still needs to get coded */
1199                 D_S[d].status_bits |= p_success;
1200                 if (st&p2_check) D_S[d].status_bits |= p1_check;
1201                 if (st&p2_door_closed) D_S[d].status_bits |= p1_door_closed;
1202                 if (st&p2_disk_in) D_S[d].status_bits |= p1_disk_in;
1203                 if (st&p2_busy1) D_S[d].status_bits |= p1_busy;
1204                 if (st&p2_busy2) D_S[d].status_bits |= p1_busy;
1205                 if (st&p2_spinning) D_S[d].status_bits |= p1_spinning;
1206                 if (st&p2_door_locked) D_S[d].status_bits |= p1_door_locked;
1207                 if (st&p2_disk_ok) D_S[d].status_bits |= p1_disk_ok;
1208         }
1209         return;
1210 }
1211 /*==========================================================================*/
1212 static int get_state_T(void)
1213 {
1214         int i;
1215         
1216         static int cmd_out_T(void);
1217
1218         clr_cmdbuf();
1219         D_S[d].n_bytes=1;
1220         drvcmd[0]=CMDT_STATUS;
1221         i=cmd_out_T();
1222         if (i>=0) i=infobuf[0];
1223         else
1224         {
1225                 msg(DBG_TEA,"get_state_T error %d\n", i);
1226                 return (i);
1227         }
1228         if (i>=0)
1229                 /* 2: closed, disk in */
1230                 D_S[d].status_bits=p1_door_closed|p1_disk_in|p1_spinning|p1_disk_ok;
1231         else if (D_S[d].error_state==6)
1232         {
1233                 /* 3: closed, disk in, changed ("06 xx xx") */
1234                 D_S[d].status_bits=p1_door_closed|p1_disk_in;
1235                 D_S[d].CD_changed=0xFF;
1236                 D_S[d].diskstate_flags &= ~toc_bit;
1237         }
1238         else if ((D_S[d].error_state!=2)||(D_S[d].b3!=0x3A)||(D_S[d].b4==0x00))
1239         {
1240                 /* 1: closed, no disk ("xx yy zz"or "02 3A 00") */
1241                 D_S[d].status_bits=p1_door_closed;
1242                 D_S[d].open_count=0;
1243         }
1244         else if (D_S[d].b4==0x01)
1245         {
1246                 /* 0: open ("02 3A 01") */
1247                 D_S[d].status_bits=0;
1248                 D_S[d].open_count=0;
1249         }
1250         else
1251         {
1252                 /* 1: closed, no disk ("02 3A xx") */
1253                 D_S[d].status_bits=p1_door_closed;
1254                 D_S[d].open_count=0;
1255         }
1256         return (D_S[d].status_bits);
1257 }
1258 /*==========================================================================*/
1259 static int ResponseStatus(void)
1260 {
1261         int i,j;
1262         u_long timeout;
1263         
1264         msg(DBG_STA,"doing ResponseStatus...\n");
1265         if (famT_drive) return (get_state_T());
1266         if (flags_cmd_out & f_respo3) timeout = jiffies;
1267         else if (flags_cmd_out & f_respo2) timeout = jiffies + 16*HZ;
1268         else timeout = jiffies + 4*HZ;
1269         j=maxtim_8;
1270         do
1271         {
1272                 for ( ;j!=0;j--)
1273                 { 
1274                         i=inb(CDi_status);
1275                         if (!(i&s_not_result_ready)) break;
1276                 }
1277                 if ((j!=0)||time_after(jiffies, timeout)) break;
1278                 sbp_sleep(1);
1279                 j = 1;
1280         }
1281         while (1);
1282         if (j==0) 
1283         {
1284                 if ((flags_cmd_out & f_respo3) == 0)
1285                         msg(DBG_STA,"ResponseStatus: timeout.\n");
1286                 D_S[d].status_bits=0;
1287                 return (-401);
1288         }
1289         i=inb(CDi_info);
1290         msg(DBG_STA,"ResponseStatus: response %02X.\n", i);
1291         EvaluateStatus(i);
1292         msg(DBG_STA,"status_bits=%02X, i=%02X\n",D_S[d].status_bits,i);
1293         return (D_S[d].status_bits);
1294 }
1295 /*==========================================================================*/
1296 static void cc_ReadStatus(void)
1297 {
1298         int i;
1299         
1300         msg(DBG_STA,"giving cc_ReadStatus command\n");
1301         if (famT_drive) return;
1302         SBPCD_CLI;
1303         if (fam0LV_drive) OUT(CDo_command,CMD0_STATUS);
1304         else if (fam1_drive) OUT(CDo_command,CMD1_STATUS);
1305         else if (fam2_drive) OUT(CDo_command,CMD2_STATUS);
1306         if (!fam0LV_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
1307         SBPCD_STI;
1308 }
1309 /*==========================================================================*/
1310 static int cc_ReadError(void)
1311 {
1312         int i;
1313
1314         clr_cmdbuf();
1315         msg(DBG_ERR,"giving cc_ReadError command.\n");
1316         if (fam1_drive)
1317         {
1318                 drvcmd[0]=CMD1_READ_ERR;
1319                 response_count=8;
1320                 flags_cmd_out=f_putcmd|f_ResponseStatus;
1321         }
1322         else if (fam0LV_drive)
1323         {
1324                 drvcmd[0]=CMD0_READ_ERR;
1325                 response_count=6;
1326                 if (famLV_drive)
1327                         flags_cmd_out=f_putcmd;
1328                 else
1329                         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
1330         }
1331         else if (fam2_drive)
1332         {
1333                 drvcmd[0]=CMD2_READ_ERR;
1334                 response_count=6;
1335                 flags_cmd_out=f_putcmd;
1336         }
1337         else if (famT_drive)
1338         {
1339                 response_count=5;
1340                 drvcmd[0]=CMDT_READ_ERR;
1341         }
1342         i=cmd_out();
1343         D_S[d].error_byte=0;
1344         msg(DBG_ERR,"cc_ReadError: cmd_out(CMDx_READ_ERR) returns %d (%02X)\n",i,i);
1345         if (i<0) return (i);
1346         if (fam0V_drive) i=1;
1347         else i=2;
1348         D_S[d].error_byte=infobuf[i];
1349         msg(DBG_ERR,"cc_ReadError: infobuf[%d] is %d (%02X)\n",i,D_S[d].error_byte,D_S[d].error_byte);
1350         i=sta2err(infobuf[i]);
1351         if (i==-ERR_DISKCHANGE)
1352         {
1353                 D_S[d].CD_changed=0xFF;
1354                 D_S[d].diskstate_flags &= ~toc_bit;
1355         }
1356         return (i);
1357 }
1358 /*==========================================================================*/
1359 static int cmd_out_T(void)
1360 {
1361 #undef CMDT_TRIES
1362 #define CMDT_TRIES 1000
1363 #define TEST_FALSE_FF 1
1364         
1365         static int cc_DriveReset(void);
1366         int i, j, l=0, m, ntries;
1367         long flags;
1368
1369         D_S[d].error_state=0;
1370         D_S[d].b3=0;
1371         D_S[d].b4=0;
1372         D_S[d].f_drv_error=0;
1373         for (i=0;i<10;i++) sprintf(&msgbuf[i*3]," %02X",drvcmd[i]);
1374         msgbuf[i*3]=0;
1375         msg(DBG_CMD,"cmd_out_T:%s\n",msgbuf);
1376
1377         OUT(CDo_sel_i_d,0);
1378         OUT(CDo_enable,D_S[d].drv_sel);
1379         i=inb(CDi_status);
1380         do_16bit=0;
1381         if ((f_16bit)&&(!(i&0x80)))
1382         {
1383                 do_16bit=1;
1384                 msg(DBG_TEA,"cmd_out_T: do_16bit set.\n");
1385         }
1386         if (!(i&s_not_result_ready))
1387         do
1388         {
1389                 j=inb(CDi_info);
1390                 i=inb(CDi_status);
1391                 sbp_sleep(0);
1392                 msg(DBG_TEA,"cmd_out_T: spurious !s_not_result_ready. (%02X)\n", j);
1393         }
1394         while (!(i&s_not_result_ready));
1395         save_flags(flags); cli();
1396         for (i=0;i<10;i++) OUT(CDo_command,drvcmd[i]);
1397         restore_flags(flags);
1398         for (ntries=CMDT_TRIES;ntries>0;ntries--)
1399         {
1400                 if (drvcmd[0]==CMDT_READ_VER) sbp_sleep(HZ); /* fixme */
1401 #if 01
1402                 OUT(CDo_sel_i_d,1);
1403 #endif /* 01 */
1404                 if (teac==2)
1405                   {
1406                     if ((i=CDi_stat_loop_T()) == -1) break;
1407                   }
1408                 else
1409                   {
1410 #if 0
1411                     OUT(CDo_sel_i_d,1);
1412 #endif /* 0 */ 
1413                     i=inb(CDi_status);
1414                   }
1415                 if (!(i&s_not_data_ready)) /* f.e. CMDT_DISKINFO */
1416                 {
1417                         OUT(CDo_sel_i_d,1);
1418                         if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
1419                         if (drvcmd[0]==CMDT_DISKINFO)
1420                         {
1421                                 l=0;
1422                                 do
1423                                 {
1424                                         if (do_16bit)
1425                                         {
1426                                                 i=inw(CDi_data);
1427                                                 infobuf[l++]=i&0x0ff;
1428                                                 infobuf[l++]=i>>8;
1429 #if TEST_FALSE_FF
1430                                                 if ((l==2)&&(infobuf[0]==0x0ff))
1431                                                 {
1432                                                         infobuf[0]=infobuf[1];
1433                                                         l=1;
1434                                                         msg(DBG_TEA,"cmd_out_T: do_16bit: false first byte!\n");
1435                                                 }
1436 #endif /* TEST_FALSE_FF */ 
1437                                         }
1438                                         else infobuf[l++]=inb(CDi_data);
1439                                         i=inb(CDi_status);
1440                                 }
1441                                 while (!(i&s_not_data_ready));
1442                                 for (j=0;j<l;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
1443                                 msgbuf[j*3]=0;
1444                                 msg(DBG_CMD,"cmd_out_T data response:%s\n", msgbuf);
1445                         }
1446                         else
1447                         {
1448                                 msg(DBG_TEA,"cmd_out_T: data response with cmd_%02X!\n",
1449                                     drvcmd[0]);
1450                                 j=0;
1451                                 do
1452                                 {
1453                                         if (do_16bit) i=inw(CDi_data);
1454                                         else i=inb(CDi_data);
1455                                         j++;
1456                                         i=inb(CDi_status);
1457                                 }
1458                                 while (!(i&s_not_data_ready));
1459                                 msg(DBG_TEA,"cmd_out_T: data response: discarded %d bytes/words.\n", j);
1460                                 fatal_err++;
1461                         }
1462                 }
1463                 i=inb(CDi_status);
1464                 if (!(i&s_not_result_ready))
1465                 {
1466                         OUT(CDo_sel_i_d,0);
1467                         if (drvcmd[0]==CMDT_DISKINFO) m=l;
1468                         else m=0;
1469                         do
1470                         {
1471                                 infobuf[m++]=inb(CDi_info);
1472                                 i=inb(CDi_status);
1473                         }
1474                         while (!(i&s_not_result_ready));
1475                         for (j=0;j<m;j++) sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
1476                         msgbuf[j*3]=0;
1477                         msg(DBG_CMD,"cmd_out_T info response:%s\n", msgbuf);
1478                         if (drvcmd[0]==CMDT_DISKINFO)
1479                         {
1480                                 infobuf[0]=infobuf[l];
1481                                 if (infobuf[0]!=0x02) return (l); /* data length */
1482                         }
1483                         else if (infobuf[0]!=0x02) return (m); /* info length */
1484                         do
1485                         {
1486                                 ++recursion;
1487                                 if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (%02X): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n", drvcmd[0], recursion);
1488                                 clr_cmdbuf();
1489                                 drvcmd[0]=CMDT_READ_ERR;
1490                                 j=cmd_out_T(); /* !!! recursive here !!! */
1491                                 --recursion;
1492                                 sbp_sleep(1);
1493                         }
1494                         while (j<0);
1495                         D_S[d].error_state=infobuf[2];
1496                         D_S[d].b3=infobuf[3];
1497                         D_S[d].b4=infobuf[4];
1498                         if (D_S[d].f_drv_error)
1499                         {
1500                                 D_S[d].f_drv_error=0;
1501                                 cc_DriveReset();
1502                                 D_S[d].error_state=2;
1503                         }
1504                         return (-D_S[d].error_state-400);
1505                 }
1506                 if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
1507                 if ((teac==0)||(ntries<(CMDT_TRIES-5))) sbp_sleep(HZ/10);
1508                 else sbp_sleep(HZ/100);
1509                 if (ntries>(CMDT_TRIES-50)) continue;
1510                 msg(DBG_TEA,"cmd_out_T: next CMDT_TRIES (%02X): %d.\n", drvcmd[0], ntries-1);
1511         }
1512         D_S[d].f_drv_error=1;
1513         cc_DriveReset();
1514         D_S[d].error_state=2;
1515         return (-99);
1516 }
1517 /*==========================================================================*/
1518 static int cmd_out(void)
1519 {
1520         int i=0;
1521         
1522         if (famT_drive) return(cmd_out_T());
1523         
1524         if (flags_cmd_out&f_putcmd)
1525         { 
1526                 unsigned long flags;
1527                 for (i=0;i<7;i++)
1528                         sprintf(&msgbuf[i*3], " %02X", drvcmd[i]);
1529                 msgbuf[i*3]=0;
1530                 msg(DBG_CMD,"cmd_out:%s\n", msgbuf);
1531                 save_flags(flags); cli();
1532                 for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
1533                 restore_flags(flags);
1534         }
1535         if (response_count!=0)
1536         {
1537                 if (cmd_type!=0)
1538                 {
1539                         if (sbpro_type==1) OUT(CDo_sel_i_d,1);
1540                         msg(DBG_INF,"misleaded to try ResponseData.\n");
1541                         if (sbpro_type==1) OUT(CDo_sel_i_d,0);
1542                         return (-22);
1543                 }
1544                 else i=ResponseInfo();
1545                 if (i<0) return (i);
1546         }
1547         if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to CDi_stat_loop.\n");
1548         if (flags_cmd_out&f_lopsta)
1549         {
1550                 i=CDi_stat_loop();
1551                 if ((i<0)||!(i&s_attention)) return (-8);
1552         }
1553         if (!(flags_cmd_out&f_getsta)) goto LOC_229;
1554         
1555  LOC_228:
1556         if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadStatus.\n");
1557         cc_ReadStatus();
1558         
1559  LOC_229:
1560         if (flags_cmd_out&f_ResponseStatus) 
1561         {
1562                 if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to ResponseStatus.\n");
1563                 i=ResponseStatus();
1564                 /* builds status_bits, returns orig. status or p_busy_new */
1565                 if (i<0) return (i);
1566                 if (flags_cmd_out&(f_bit1|f_wait_if_busy))
1567                 {
1568                         if (!st_check)
1569                         {
1570                                 if ((flags_cmd_out&f_bit1)&&(i&p_success)) goto LOC_232;
1571                                 if ((!(flags_cmd_out&f_wait_if_busy))||(!st_busy)) goto LOC_228;
1572                         }
1573                 }
1574         }
1575  LOC_232:
1576         if (!(flags_cmd_out&f_obey_p_check)) return (0);
1577         if (!st_check) return (0);
1578         if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cc_ReadError.\n");
1579         i=cc_ReadError();
1580         if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to cmd_out OK.\n");
1581         msg(DBG_000,"cmd_out: cc_ReadError=%d\n", i);
1582         return (i);
1583 }
1584 /*==========================================================================*/
1585 static int cc_Seek(u_int pos, char f_blk_msf)
1586 {
1587         int i;
1588         
1589   clr_cmdbuf();
1590         if (f_blk_msf>1) return (-3);
1591         if (fam0V_drive)
1592         {
1593                 drvcmd[0]=CMD0_SEEK;
1594                 if (f_blk_msf==1) pos=msf2blk(pos);
1595                 drvcmd[2]=(pos>>16)&0x00FF;
1596                 drvcmd[3]=(pos>>8)&0x00FF;
1597                 drvcmd[4]=pos&0x00FF;
1598                 if (fam0_drive)
1599                   flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
1600                         f_ResponseStatus | f_obey_p_check | f_bit1;
1601                 else
1602                   flags_cmd_out = f_putcmd;
1603         }
1604         else if (fam1L_drive)
1605         {
1606                 drvcmd[0]=CMD1_SEEK; /* same as CMD1_ and CMDL_ */
1607                 if (f_blk_msf==0) pos=blk2msf(pos);
1608                 drvcmd[1]=(pos>>16)&0x00FF;
1609                 drvcmd[2]=(pos>>8)&0x00FF;
1610                 drvcmd[3]=pos&0x00FF;
1611                 if (famL_drive)
1612                         flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1613                 else
1614                         flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1615         }
1616         else if (fam2_drive)
1617         {
1618                 drvcmd[0]=CMD2_SEEK;
1619                 if (f_blk_msf==0) pos=blk2msf(pos);
1620                 drvcmd[2]=(pos>>24)&0x00FF;
1621                 drvcmd[3]=(pos>>16)&0x00FF;
1622                 drvcmd[4]=(pos>>8)&0x00FF;
1623                 drvcmd[5]=pos&0x00FF;
1624                 flags_cmd_out=f_putcmd|f_ResponseStatus;
1625         }
1626         else if (famT_drive)
1627         {
1628                 drvcmd[0]=CMDT_SEEK;
1629                 if (f_blk_msf==1) pos=msf2blk(pos);
1630                 drvcmd[2]=(pos>>24)&0x00FF;
1631                 drvcmd[3]=(pos>>16)&0x00FF;
1632                 drvcmd[4]=(pos>>8)&0x00FF;
1633                 drvcmd[5]=pos&0x00FF;
1634                 D_S[d].n_bytes=1;
1635         }
1636         response_count=0;
1637         i=cmd_out();
1638         return (i);
1639 }
1640 /*==========================================================================*/
1641 static int cc_SpinUp(void)
1642 {
1643         int i;
1644         
1645         msg(DBG_SPI,"SpinUp.\n");
1646         D_S[d].in_SpinUp = 1;
1647         clr_cmdbuf();
1648         if (fam0LV_drive)
1649         {
1650                 drvcmd[0]=CMD0_SPINUP;
1651                 if (fam0L_drive)
1652                   flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
1653                     f_ResponseStatus|f_obey_p_check|f_bit1;
1654                 else
1655                   flags_cmd_out=f_putcmd;
1656         }
1657         else if (fam1_drive)
1658         {
1659                 drvcmd[0]=CMD1_SPINUP;
1660                 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1661         }
1662         else if (fam2_drive)
1663         {
1664                 drvcmd[0]=CMD2_TRAY_CTL;
1665                 drvcmd[4]=0x01; /* "spinup" */
1666                 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1667         }
1668         else if (famT_drive)
1669         {
1670                 drvcmd[0]=CMDT_TRAY_CTL;
1671                 drvcmd[4]=0x03; /* "insert", it hopefully spins the drive up */
1672         }
1673         response_count=0;
1674         i=cmd_out();
1675         D_S[d].in_SpinUp = 0;
1676         return (i);
1677 }
1678 /*==========================================================================*/
1679 static int cc_SpinDown(void)
1680 {
1681         int i;
1682         
1683         if (fam0_drive) return (0);
1684         clr_cmdbuf();
1685         response_count=0;
1686         if (fam1_drive)
1687         {
1688                 drvcmd[0]=CMD1_SPINDOWN;
1689                 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1690         }
1691         else if (fam2_drive)
1692         {
1693                 drvcmd[0]=CMD2_TRAY_CTL;
1694                 drvcmd[4]=0x02; /* "eject" */
1695                 flags_cmd_out=f_putcmd|f_ResponseStatus;
1696         }
1697         else if (famL_drive)
1698         {
1699                 drvcmd[0]=CMDL_SPINDOWN;
1700                 drvcmd[1]=1;
1701                 flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1702         }
1703         else if (famV_drive)
1704         {
1705                 drvcmd[0]=CMDV_SPINDOWN;
1706                 flags_cmd_out=f_putcmd;
1707         }
1708         else if (famT_drive)
1709         {
1710                 drvcmd[0]=CMDT_TRAY_CTL;
1711                 drvcmd[4]=0x02; /* "eject" */
1712         }
1713         i=cmd_out();
1714         return (i);
1715 }
1716 /*==========================================================================*/
1717 static int cc_get_mode_T(void)
1718 {
1719         int i;
1720         
1721         clr_cmdbuf();
1722         response_count=10;
1723         drvcmd[0]=CMDT_GETMODE;
1724         drvcmd[4]=response_count;
1725         i=cmd_out_T();
1726         return (i);
1727 }
1728 /*==========================================================================*/
1729 static int cc_set_mode_T(void)
1730 {
1731         int i;
1732         
1733         clr_cmdbuf();
1734         response_count=1;
1735         drvcmd[0]=CMDT_SETMODE;
1736         drvcmd[1]=D_S[d].speed_byte;
1737         drvcmd[2]=D_S[d].frmsiz>>8;
1738         drvcmd[3]=D_S[d].frmsiz&0x0FF;
1739         drvcmd[4]=D_S[d].f_XA; /* 1: XA */
1740         drvcmd[5]=D_S[d].type_byte; /* 0, 1, 3 */
1741         drvcmd[6]=D_S[d].mode_xb_6;
1742         drvcmd[7]=D_S[d].mode_yb_7|D_S[d].volume_control;
1743         drvcmd[8]=D_S[d].mode_xb_8;
1744         drvcmd[9]=D_S[d].delay;
1745         i=cmd_out_T();
1746         return (i);
1747 }
1748 /*==========================================================================*/
1749 static int cc_prep_mode_T(void)
1750 {
1751         int i, j;
1752         
1753         i=cc_get_mode_T();
1754         if (i<0) return (i);
1755         for (i=0;i<10;i++)
1756                 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
1757         msgbuf[i*3]=0;
1758         msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
1759         D_S[d].speed_byte=0x02; /* 0x02: auto quad, 0x82: quad, 0x81: double, 0x80: single */
1760         D_S[d].frmsiz=make16(infobuf[2],infobuf[3]);
1761         D_S[d].f_XA=infobuf[4];
1762         if (D_S[d].f_XA==0) D_S[d].type_byte=0;
1763         else D_S[d].type_byte=1;
1764         D_S[d].mode_xb_6=infobuf[6];
1765         D_S[d].mode_yb_7=1;
1766         D_S[d].mode_xb_8=infobuf[8];
1767         D_S[d].delay=0; /* 0, 1, 2, 3 */
1768         j=cc_set_mode_T();
1769         i=cc_get_mode_T();
1770         for (i=0;i<10;i++)
1771                 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
1772         msgbuf[i*3]=0;
1773         msg(DBG_TEA,"CMDT_GETMODE:%s\n", msgbuf);
1774         return (j);
1775 }
1776 /*==========================================================================*/
1777 static int cc_SetSpeed(u_char speed, u_char x1, u_char x2)
1778 {
1779         int i;
1780         
1781         if (fam0LV_drive) return (0);
1782         clr_cmdbuf();
1783         response_count=0;
1784         if (fam1_drive)
1785         {
1786                 drvcmd[0]=CMD1_SETMODE;
1787                 drvcmd[1]=0x03;
1788                 drvcmd[2]=speed;
1789                 drvcmd[3]=x1;
1790                 drvcmd[4]=x2;
1791                 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1792         }
1793         else if (fam2_drive)
1794         {
1795                 drvcmd[0]=CMD2_SETSPEED;
1796                 if (speed&speed_auto)
1797                 {
1798                         drvcmd[2]=0xFF;
1799                         drvcmd[3]=0xFF;
1800                 }
1801                 else
1802                 {
1803                         drvcmd[2]=0;
1804                         drvcmd[3]=150;
1805                 }
1806                 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1807         }
1808         else if (famT_drive)
1809         {
1810                 return (0);
1811         }
1812         i=cmd_out();
1813         return (i);
1814 }
1815 /*==========================================================================*/
1816 static int cc_SetVolume(void)
1817 {
1818         int i;
1819         u_char channel0,channel1,volume0,volume1;
1820         u_char control0,value0,control1,value1;
1821         
1822         D_S[d].diskstate_flags &= ~volume_bit;
1823         clr_cmdbuf();
1824         channel0=D_S[d].vol_chan0;
1825         volume0=D_S[d].vol_ctrl0;
1826         channel1=control1=D_S[d].vol_chan1;
1827         volume1=value1=D_S[d].vol_ctrl1;
1828         control0=value0=0;
1829         
1830         if (famV_drive) return (0);
1831
1832         if (((D_S[d].drv_options&audio_mono)!=0)&&(D_S[d].drv_type>=drv_211))
1833         {
1834                 if ((volume0!=0)&&(volume1==0))
1835                 {
1836                         volume1=volume0;
1837                         channel1=channel0;
1838                 }
1839                 else if ((volume0==0)&&(volume1!=0))
1840                 {
1841                         volume0=volume1;
1842                         channel0=channel1;
1843                 }
1844         }
1845         if (channel0>1)
1846         {
1847                 channel0=0;
1848                 volume0=0;
1849         }
1850         if (channel1>1)
1851         {
1852                 channel1=1;
1853                 volume1=0;
1854         }
1855         
1856         if (fam1_drive)
1857         {
1858                 control0=channel0+1;
1859                 control1=channel1+1;
1860                 value0=(volume0>volume1)?volume0:volume1;
1861                 value1=value0;
1862                 if (volume0==0) control0=0;
1863                 if (volume1==0) control1=0;
1864                 drvcmd[0]=CMD1_SETMODE;
1865                 drvcmd[1]=0x05;
1866                 drvcmd[3]=control0;
1867                 drvcmd[4]=value0;
1868                 drvcmd[5]=control1;
1869                 drvcmd[6]=value1;
1870                 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1871         }
1872         else if (fam2_drive)
1873         {
1874                 control0=channel0+1;
1875                 control1=channel1+1;
1876                 value0=(volume0>volume1)?volume0:volume1;
1877                 value1=value0;
1878                 if (volume0==0) control0=0;
1879                 if (volume1==0) control1=0;
1880                 drvcmd[0]=CMD2_SETMODE;
1881                 drvcmd[1]=0x0E;
1882                 drvcmd[3]=control0;
1883                 drvcmd[4]=value0;
1884                 drvcmd[5]=control1;
1885                 drvcmd[6]=value1;
1886                 flags_cmd_out=f_putcmd|f_ResponseStatus;
1887         }
1888         else if (famL_drive)
1889         {
1890                 if ((volume0==0)||(channel0!=0)) control0 |= 0x80;
1891                 if ((volume1==0)||(channel1!=1)) control0 |= 0x40;
1892                 if (volume0|volume1) value0=0x80;
1893                 drvcmd[0]=CMDL_SETMODE;
1894                 drvcmd[1]=0x03;
1895                 drvcmd[4]=control0;
1896                 drvcmd[5]=value0;
1897                 flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1898         }
1899         else if (fam0_drive) /* different firmware levels */
1900         {
1901                 if (D_S[d].drv_type>=drv_300)
1902                 {
1903                         control0=volume0&0xFC;
1904                         value0=volume1&0xFC;
1905                         if ((volume0!=0)&&(volume0<4)) control0 |= 0x04;
1906                         if ((volume1!=0)&&(volume1<4)) value0 |= 0x04;
1907                         if (channel0!=0) control0 |= 0x01;
1908                         if (channel1==1) value0 |= 0x01;
1909                 }
1910                 else
1911                 {
1912                         value0=(volume0>volume1)?volume0:volume1;
1913                         if (D_S[d].drv_type<drv_211)
1914                         {
1915                                 if (channel0!=0)
1916                                 {
1917                                         i=channel1;
1918                                         channel1=channel0;
1919                                         channel0=i;
1920                                         i=volume1;
1921                                         volume1=volume0;
1922                                         volume0=i;
1923                                 }
1924                                 if (channel0==channel1)
1925                                 {
1926                                         if (channel0==0)
1927                                         {
1928                                                 channel1=1;
1929                                                 volume1=0;
1930                                                 volume0=value0;
1931                                         }
1932                                         else
1933                                         {
1934                                                 channel0=0;
1935                                                 volume0=0;
1936                                                 volume1=value0;
1937                                         }
1938                                 }
1939                         }
1940                         
1941                         if ((volume0!=0)&&(volume1!=0))
1942                         {
1943                                 if (volume0==0xFF) volume1=0xFF;
1944                                 else if (volume1==0xFF) volume0=0xFF;
1945                         }
1946                         else if (D_S[d].drv_type<drv_201) volume0=volume1=value0;
1947                         
1948                         if (D_S[d].drv_type>=drv_201)
1949                         {
1950                                 if (volume0==0) control0 |= 0x80;
1951                                 if (volume1==0) control0 |= 0x40;
1952                         }
1953                         if (D_S[d].drv_type>=drv_211)
1954                         {
1955                                 if (channel0!=0) control0 |= 0x20;
1956                                 if (channel1!=1) control0 |= 0x10;
1957                         }
1958                 }
1959                 drvcmd[0]=CMD0_SETMODE;
1960                 drvcmd[1]=0x83;
1961                 drvcmd[4]=control0;
1962                 drvcmd[5]=value0;
1963                 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1964         }
1965         else if (famT_drive)
1966         {
1967                 D_S[d].volume_control=0;
1968                 if (!volume0) D_S[d].volume_control|=0x10;
1969                 if (!volume1) D_S[d].volume_control|=0x20;
1970                 i=cc_prep_mode_T();
1971                 if (i<0) return (i);
1972         }
1973         if (!famT_drive)
1974         {
1975                 response_count=0;
1976                 i=cmd_out();
1977                 if (i<0) return (i);
1978         }
1979         D_S[d].diskstate_flags |= volume_bit;
1980         return (0);
1981 }
1982 /*==========================================================================*/
1983 static int GetStatus(void)
1984 {
1985         int i;
1986         
1987         if (famT_drive) return (0);
1988         flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check;
1989         response_count=0;
1990         cmd_type=0;
1991         i=cmd_out();
1992         return (i);
1993 }
1994 /*==========================================================================*/
1995 static int cc_DriveReset(void)
1996 {
1997         int i;
1998         
1999         msg(DBG_RES,"cc_DriveReset called.\n");
2000         clr_cmdbuf();
2001         response_count=0;
2002         if (fam0LV_drive) OUT(CDo_reset,0x00);
2003         else if (fam1_drive)
2004         {
2005                 drvcmd[0]=CMD1_RESET;
2006                 flags_cmd_out=f_putcmd;
2007                 i=cmd_out();
2008         }
2009         else if (fam2_drive)
2010         {
2011                 drvcmd[0]=CMD2_RESET;
2012                 flags_cmd_out=f_putcmd;
2013                 i=cmd_out();
2014                 OUT(CDo_reset,0x00);
2015         }
2016         else if (famT_drive)
2017         {
2018                 OUT(CDo_sel_i_d,0);
2019                 OUT(CDo_enable,D_S[d].drv_sel);
2020                 OUT(CDo_command,CMDT_RESET);
2021                 for (i=1;i<10;i++) OUT(CDo_command,0);
2022         }
2023         if (fam0LV_drive) sbp_sleep(5*HZ); /* wait 5 seconds */
2024         else sbp_sleep(1*HZ); /* wait a second */
2025 #if 1
2026         if (famT_drive)
2027         {
2028                 msg(DBG_TEA, "================CMDT_RESET given=================.\n");
2029                 sbp_sleep(3*HZ);
2030         }
2031 #endif /* 1 */ 
2032         flush_status();
2033         i=GetStatus();
2034         if (i<0) return i;
2035         if (!famT_drive)
2036                 if (D_S[d].error_byte!=aud_12) return -501;
2037         return (0);
2038 }
2039
2040 /*==========================================================================*/
2041 static int SetSpeed(void)
2042 {
2043         int i, speed;
2044         
2045         if (!(D_S[d].drv_options&(speed_auto|speed_300|speed_150))) return (0);
2046         speed=speed_auto;
2047         if (!(D_S[d].drv_options&speed_auto))
2048         {
2049                 speed |= speed_300;
2050                 if (!(D_S[d].drv_options&speed_300)) speed=0;
2051         }
2052         i=cc_SetSpeed(speed,0,0);
2053         return (i);
2054 }
2055
2056 static void switch_drive(int i);
2057
2058 static int sbpcd_select_speed(struct cdrom_device_info *cdi, int speed)
2059 {
2060   int i = MINOR(cdi->dev);
2061
2062   if (i != d)
2063     switch_drive(i);
2064
2065   return cc_SetSpeed(speed == 2 ? speed_300 : speed_150, 0, 0);
2066 }
2067
2068 /*==========================================================================*/
2069 static int DriveReset(void)
2070 {
2071         int i;
2072         
2073         i=cc_DriveReset();
2074         if (i<0) return (-22);
2075         do
2076         {
2077                 i=GetStatus();
2078                 if ((i<0)&&(i!=-ERR_DISKCHANGE)) {
2079                         return (-2); /* from sta2err */
2080                 }
2081                 if (!st_caddy_in) break;
2082                 sbp_sleep(1);
2083         }
2084         while (!st_diskok);
2085 #if 000
2086         D_S[d].CD_changed=1;
2087 #endif
2088         if ((st_door_closed) && (st_caddy_in))
2089         {
2090                 i=DiskInfo();
2091                 if (i<0) return (-23);
2092         }
2093         return (0);
2094 }
2095
2096 static int sbpcd_reset(struct cdrom_device_info *cdi)
2097 {
2098   int i = MINOR(cdi->dev);
2099
2100   if (i != d)
2101     switch_drive(i);
2102
2103   return DriveReset();
2104 }
2105
2106 /*==========================================================================*/
2107 static int cc_PlayAudio(int pos_audio_start,int pos_audio_end)
2108 {
2109         int i, j, n;
2110         
2111         if (D_S[d].audio_state==audio_playing) return (-EINVAL);
2112         clr_cmdbuf();
2113         response_count=0;
2114         if (famLV_drive)
2115         {
2116                 drvcmd[0]=CMDL_PLAY;
2117                 i=msf2blk(pos_audio_start);
2118                 n=msf2blk(pos_audio_end)+1-i;
2119                 drvcmd[1]=(i>>16)&0x00FF;
2120                 drvcmd[2]=(i>>8)&0x00FF;
2121                 drvcmd[3]=i&0x00FF;
2122                 drvcmd[4]=(n>>16)&0x00FF;
2123                 drvcmd[5]=(n>>8)&0x00FF;
2124                 drvcmd[6]=n&0x00FF;
2125                 if (famL_drive)
2126                 flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
2127                         f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
2128                 else
2129                   flags_cmd_out = f_putcmd;
2130         }
2131         else
2132         {
2133                 j=1;
2134                 if (fam1_drive)
2135                 {
2136                         drvcmd[0]=CMD1_PLAY_MSF;
2137                         flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus |
2138                                 f_obey_p_check | f_wait_if_busy;
2139                 }
2140                 else if (fam2_drive)
2141                 {
2142                         drvcmd[0]=CMD2_PLAY_MSF;
2143                         flags_cmd_out = f_putcmd | f_ResponseStatus | f_obey_p_check;
2144                 }
2145                 else if (famT_drive)
2146                 {
2147                         drvcmd[0]=CMDT_PLAY_MSF;
2148                         j=3;
2149                         response_count=1;
2150                 }
2151                 else if (fam0_drive)
2152                 {
2153                         drvcmd[0]=CMD0_PLAY_MSF;
2154                         flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
2155                                 f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
2156                 }
2157                 drvcmd[j]=(pos_audio_start>>16)&0x00FF;
2158                 drvcmd[j+1]=(pos_audio_start>>8)&0x00FF;
2159                 drvcmd[j+2]=pos_audio_start&0x00FF;
2160                 drvcmd[j+3]=(pos_audio_end>>16)&0x00FF;
2161                 drvcmd[j+4]=(pos_audio_end>>8)&0x00FF;
2162                 drvcmd[j+5]=pos_audio_end&0x00FF;
2163         }
2164         i=cmd_out();
2165         return (i);
2166 }
2167 /*==========================================================================*/
2168 static int cc_Pause_Resume(int pau_res)
2169 {
2170         int i;
2171         
2172         clr_cmdbuf();
2173         response_count=0;
2174         if (fam1_drive)
2175         {
2176                 drvcmd[0]=CMD1_PAU_RES;
2177                 if (pau_res!=1) drvcmd[1]=0x80;
2178                 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
2179         }
2180         else if (fam2_drive)
2181         {
2182                 drvcmd[0]=CMD2_PAU_RES;
2183                 if (pau_res!=1) drvcmd[2]=0x01;
2184                 flags_cmd_out=f_putcmd|f_ResponseStatus;
2185         }
2186         else if (fam0LV_drive)
2187         {
2188                 drvcmd[0]=CMD0_PAU_RES;
2189                 if (pau_res!=1) drvcmd[1]=0x80;
2190                 if (famL_drive)
2191                         flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
2192                                 f_obey_p_check|f_bit1;
2193                 else if (famV_drive)
2194                   flags_cmd_out=f_putcmd;
2195                 else
2196                         flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
2197                                 f_obey_p_check;
2198         }
2199         else if (famT_drive)
2200         {
2201                 if (pau_res==3) return (cc_PlayAudio(D_S[d].pos_audio_start,D_S[d].pos_audio_end));
2202                 else if (pau_res==1) drvcmd[0]=CMDT_PAUSE;
2203                 else return (-56);
2204         }
2205         i=cmd_out();
2206         return (i);
2207 }
2208 /*==========================================================================*/
2209 static int cc_LockDoor(char lock)
2210 {
2211         int i;
2212         
2213         if (fam0_drive) return (0);
2214         msg(DBG_LCK,"cc_LockDoor: %d (drive %d)\n", lock, d);
2215         msg(DBG_LCS,"p_door_locked bit %d before\n", st_door_locked);
2216         clr_cmdbuf();
2217         response_count=0;
2218         if (fam1_drive)
2219         {
2220                 drvcmd[0]=CMD1_LOCK_CTL;
2221                 if (lock==1) drvcmd[1]=0x01;
2222                 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2223         }
2224         else if (fam2_drive)
2225         {
2226                 drvcmd[0]=CMD2_LOCK_CTL;
2227                 if (lock==1) drvcmd[4]=0x01;
2228                 flags_cmd_out=f_putcmd|f_ResponseStatus;
2229         }
2230         else if (famLV_drive)
2231         {
2232                 drvcmd[0]=CMDL_LOCK_CTL;
2233                 if (lock==1) drvcmd[1]=0x01;
2234                 if (famL_drive)
2235                   flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
2236                 else
2237                   flags_cmd_out=f_putcmd;
2238         }
2239         else if (famT_drive)
2240         {
2241                 drvcmd[0]=CMDT_LOCK_CTL;
2242                 if (lock==1) drvcmd[4]=0x01;
2243         }
2244         i=cmd_out();
2245         msg(DBG_LCS,"p_door_locked bit %d after\n", st_door_locked);
2246         return (i);
2247 }
2248 /*==========================================================================*/
2249 /*==========================================================================*/
2250 static int UnLockDoor(void)
2251 {
2252         int i,j;
2253         
2254         j=20;
2255         do
2256         {
2257                 i=cc_LockDoor(0);
2258                 --j;
2259                 sbp_sleep(1);
2260         }
2261         while ((i<0)&&(j));
2262         if (i<0)
2263         {
2264                 cc_DriveReset();
2265                 return -84;
2266         }
2267         return (0);
2268 }
2269 /*==========================================================================*/
2270 static int LockDoor(void)
2271 {
2272         int i,j;
2273         
2274         j=20;
2275         do
2276         {
2277                 i=cc_LockDoor(1);
2278                 --j;
2279                 sbp_sleep(1);
2280         }
2281         while ((i<0)&&(j));
2282         if (j==0)
2283         {               
2284                 cc_DriveReset();
2285                 j=20;
2286                 do
2287                 {
2288                         i=cc_LockDoor(1);
2289                         --j;
2290                         sbp_sleep(1);
2291                 }
2292                 while ((i<0)&&(j));
2293         }
2294         return (i);
2295 }
2296
2297 static int sbpcd_lock_door(struct cdrom_device_info *cdi, int lock)
2298 {
2299   return lock ? LockDoor() : UnLockDoor();
2300 }
2301
2302 /*==========================================================================*/
2303 static int cc_CloseTray(void)
2304 {
2305         int i;
2306         
2307         if (fam0_drive) return (0);
2308         msg(DBG_LCK,"cc_CloseTray (drive %d)\n", d);
2309         msg(DBG_LCS,"p_door_closed bit %d before\n", st_door_closed);
2310         
2311         clr_cmdbuf();
2312         response_count=0;
2313         if (fam1_drive)
2314         {
2315                 drvcmd[0]=CMD1_TRAY_CTL;
2316                 flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
2317         }
2318         else if (fam2_drive)
2319         {
2320                 drvcmd[0]=CMD2_TRAY_CTL;
2321                 drvcmd[1]=0x01;
2322                 drvcmd[4]=0x03; /* "insert" */
2323                 flags_cmd_out=f_putcmd|f_ResponseStatus;
2324         }
2325         else if (famLV_drive)
2326         {
2327                 drvcmd[0]=CMDL_TRAY_CTL;
2328                 if (famLV_drive)
2329                   flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
2330                         f_ResponseStatus|f_obey_p_check|f_bit1;
2331                 else
2332                   flags_cmd_out=f_putcmd;
2333         }
2334         else if (famT_drive)
2335         {
2336                 drvcmd[0]=CMDT_TRAY_CTL;
2337                 drvcmd[4]=0x03; /* "insert" */
2338         }
2339         i=cmd_out();
2340         msg(DBG_LCS,"p_door_closed bit %d after\n", st_door_closed);
2341
2342         i=cc_ReadError();
2343         flags_cmd_out |= f_respo2;
2344         cc_ReadStatus(); /* command: give 1-byte status */
2345         i=ResponseStatus();
2346         if (famT_drive&&(i<0))
2347         {
2348                 cc_DriveReset();
2349                 i=ResponseStatus();
2350 #if 0
2351                 sbp_sleep(HZ);
2352 #endif /* 0 */ 
2353                 i=ResponseStatus();
2354         }
2355         if (i<0)
2356         {
2357                 msg(DBG_INF,"sbpcd cc_CloseTray: ResponseStatus timed out (%d).\n",i);
2358         }
2359         if (!(famT_drive))
2360         {
2361                 if (!st_spinning)
2362                 {
2363                         cc_SpinUp();
2364                         if (st_check) i=cc_ReadError();
2365                         flags_cmd_out |= f_respo2;
2366                         cc_ReadStatus();
2367                         i=ResponseStatus();
2368                 } else {
2369                 }
2370         }
2371         i=DiskInfo();
2372         return (i);
2373 }
2374
2375 static int sbpcd_tray_move(struct cdrom_device_info *cdi, int position)
2376 {
2377         int i;
2378         int retval=0;
2379         i = MINOR(cdi->dev);
2380         switch_drive(i);
2381         /* DUH! --AJK */
2382         if(D_S[d].CD_changed != 0xFF) {
2383                 D_S[d].CD_changed=0xFF;
2384                 D_S[d].diskstate_flags &= ~cd_size_bit;
2385         }
2386         if (position == 1) {
2387                 cc_SpinDown();
2388         } else {
2389                 retval=cc_CloseTray();
2390         }
2391   return retval;
2392 }
2393
2394 /*==========================================================================*/
2395 static int cc_ReadSubQ(void)
2396 {
2397         int i,j;
2398
2399         D_S[d].diskstate_flags &= ~subq_bit;
2400         for (j=255;j>0;j--)
2401         {
2402                 clr_cmdbuf();
2403                 if (fam1_drive)
2404                 {
2405                         drvcmd[0]=CMD1_READSUBQ;
2406                         flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2407                         response_count=11;
2408                 }
2409                 else if (fam2_drive)
2410                 {
2411                         drvcmd[0]=CMD2_READSUBQ;
2412                         drvcmd[1]=0x02;
2413                         drvcmd[3]=0x01;
2414                         flags_cmd_out=f_putcmd;
2415                         response_count=10;
2416                 }
2417                 else if (fam0LV_drive)
2418                 {
2419                         drvcmd[0]=CMD0_READSUBQ;
2420                         drvcmd[1]=0x02;
2421                         if (famLV_drive)
2422                                 flags_cmd_out=f_putcmd;
2423                         else
2424                                 flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2425                         response_count=13;
2426                 }
2427                 else if (famT_drive)
2428                 {
2429                         response_count=12;
2430                         drvcmd[0]=CMDT_READSUBQ;
2431                         drvcmd[1]=0x02;
2432                         drvcmd[2]=0x40;
2433                         drvcmd[3]=0x01;
2434                         drvcmd[8]=response_count;
2435                 }
2436                 i=cmd_out();
2437                 if (i<0) return (i);
2438                 for (i=0;i<response_count;i++)
2439                 {
2440                         sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
2441                         msgbuf[i*3]=0;
2442                         msg(DBG_SQ1,"cc_ReadSubQ:%s\n", msgbuf);
2443                 }
2444                 if (famT_drive) break;
2445                 if (infobuf[0]!=0) break;
2446                 if ((!st_spinning) || (j==1))
2447                 {
2448                         D_S[d].SubQ_ctl_adr=D_S[d].SubQ_trk=D_S[d].SubQ_pnt_idx=D_S[d].SubQ_whatisthis=0;
2449                         D_S[d].SubQ_run_tot=D_S[d].SubQ_run_trk=0;
2450                         return (0);
2451                 }
2452         }
2453         if (famT_drive) D_S[d].SubQ_ctl_adr=infobuf[1];
2454         else D_S[d].SubQ_ctl_adr=swap_nibbles(infobuf[1]);
2455         D_S[d].SubQ_trk=byt2bcd(infobuf[2]);
2456         D_S[d].SubQ_pnt_idx=byt2bcd(infobuf[3]);
2457         if (fam0LV_drive) i=5;
2458         else if (fam12_drive) i=4;
2459         else if (famT_drive) i=8;
2460         D_S[d].SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
2461         i=7;
2462         if (fam0LV_drive) i=9;
2463         else if (fam12_drive) i=7;
2464         else if (famT_drive) i=4;
2465         D_S[d].SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
2466         D_S[d].SubQ_whatisthis=infobuf[i+3];
2467         D_S[d].diskstate_flags |= subq_bit;
2468         return (0);
2469 }
2470 /*==========================================================================*/
2471 static int cc_ModeSense(void)
2472 {
2473         int i;
2474         
2475         if (fam2_drive) return (0);
2476         if (famV_drive) return (0);
2477         D_S[d].diskstate_flags &= ~frame_size_bit;
2478         clr_cmdbuf();
2479         if (fam1_drive)
2480         {
2481                 response_count=5;
2482                 drvcmd[0]=CMD1_GETMODE;
2483                 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2484         }
2485         else if (fam0L_drive)
2486         {
2487                 response_count=2;
2488                 drvcmd[0]=CMD0_GETMODE;
2489                 if (famL_drive) flags_cmd_out=f_putcmd;
2490                 else flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2491         }
2492         else if (famT_drive)
2493         {
2494                 response_count=10;
2495                 drvcmd[0]=CMDT_GETMODE;
2496                 drvcmd[4]=response_count;
2497         }
2498         i=cmd_out();
2499         if (i<0) return (i);
2500         i=0;
2501         D_S[d].sense_byte=0;
2502         if (fam1_drive) D_S[d].sense_byte=infobuf[i++];
2503         else if (famT_drive)
2504         {
2505                 if (infobuf[4]==0x01) D_S[d].xa_byte=0x20;
2506                 else D_S[d].xa_byte=0;
2507                 i=2;
2508         }
2509         D_S[d].frame_size=make16(infobuf[i],infobuf[i+1]);
2510         for (i=0;i<response_count;i++)
2511                 sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
2512         msgbuf[i*3]=0;
2513         msg(DBG_XA1,"cc_ModeSense:%s\n", msgbuf);
2514         
2515         D_S[d].diskstate_flags |= frame_size_bit;
2516         return (0);
2517 }
2518 /*==========================================================================*/
2519 /*==========================================================================*/
2520 static int cc_ModeSelect(int framesize)
2521 {
2522         int i;
2523         
2524         if (fam2_drive) return (0);
2525         if (famV_drive) return (0);
2526         D_S[d].diskstate_flags &= ~frame_size_bit;
2527         clr_cmdbuf();
2528         D_S[d].frame_size=framesize;
2529         if (framesize==CD_FRAMESIZE_RAW) D_S[d].sense_byte=0x82;
2530         else D_S[d].sense_byte=0x00;
2531         
2532         msg(DBG_XA1,"cc_ModeSelect: %02X %04X\n",
2533             D_S[d].sense_byte, D_S[d].frame_size);
2534         
2535         if (fam1_drive)
2536         {
2537                 drvcmd[0]=CMD1_SETMODE;
2538                 drvcmd[1]=0x00;
2539                 drvcmd[2]=D_S[d].sense_byte;
2540                 drvcmd[3]=(D_S[d].frame_size>>8)&0xFF;
2541                 drvcmd[4]=D_S[d].frame_size&0xFF;
2542                 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2543         }
2544         else if (fam0L_drive)
2545         {
2546                 drvcmd[0]=CMD0_SETMODE;
2547                 drvcmd[1]=0x00;
2548                 drvcmd[2]=(D_S[d].frame_size>>8)&0xFF;
2549                 drvcmd[3]=D_S[d].frame_size&0xFF;
2550                 drvcmd[4]=0x00;
2551                 if(famL_drive)
2552                         flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check;
2553                 else
2554                         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2555         }
2556         else if (famT_drive)
2557         {
2558                 return (-1);
2559         }
2560         response_count=0;
2561         i=cmd_out();
2562         if (i<0) return (i);
2563         D_S[d].diskstate_flags |= frame_size_bit;
2564         return (0);
2565 }
2566 /*==========================================================================*/
2567 static int cc_GetVolume(void)
2568 {
2569         int i;
2570         u_char switches;
2571         u_char chan0=0;
2572         u_char vol0=0;
2573         u_char chan1=1;
2574         u_char vol1=0;
2575         
2576         if (famV_drive) return (0);
2577         D_S[d].diskstate_flags &= ~volume_bit;
2578         clr_cmdbuf();
2579         if (fam1_drive)
2580         {
2581                 drvcmd[0]=CMD1_GETMODE;
2582                 drvcmd[1]=0x05;
2583                 response_count=5;
2584                 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2585         }
2586         else if (fam2_drive)
2587         {
2588                 drvcmd[0]=CMD2_GETMODE;
2589                 drvcmd[1]=0x0E;
2590                 response_count=5;
2591                 flags_cmd_out=f_putcmd;
2592         }
2593         else if (fam0L_drive)
2594         {
2595                 drvcmd[0]=CMD0_GETMODE;
2596                 drvcmd[1]=0x03;
2597                 response_count=2;
2598                 if(famL_drive)
2599                         flags_cmd_out=f_putcmd;
2600                 else
2601                         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2602         }
2603         else if (famT_drive)
2604         {
2605                 i=cc_get_mode_T();
2606                 if (i<0) return (i);
2607         }
2608         if (!famT_drive)
2609         {
2610                 i=cmd_out();
2611                 if (i<0) return (i);
2612         }
2613         if (fam1_drive)
2614         {
2615                 chan0=infobuf[1]&0x0F;
2616                 vol0=infobuf[2];
2617                 chan1=infobuf[3]&0x0F;
2618                 vol1=infobuf[4];
2619                 if (chan0==0)
2620                 {
2621                         chan0=1;
2622                         vol0=0;
2623                 }
2624                 if (chan1==0)
2625                 {
2626                         chan1=2;
2627                         vol1=0;
2628                 }
2629                 chan0 >>= 1;
2630                 chan1 >>= 1;
2631         }
2632         else if (fam2_drive)
2633         {
2634                 chan0=infobuf[1];
2635                 vol0=infobuf[2];
2636                 chan1=infobuf[3];
2637                 vol1=infobuf[4];
2638         }
2639         else if (famL_drive)
2640         {
2641                 chan0=0;
2642                 chan1=1;
2643                 vol0=vol1=infobuf[1];
2644                 switches=infobuf[0];
2645                 if ((switches&0x80)!=0) chan0=1;
2646                 if ((switches&0x40)!=0) chan1=0;
2647         }
2648         else if (fam0_drive) /* different firmware levels */
2649         {
2650                 chan0=0;
2651                 chan1=1;
2652                 vol0=vol1=infobuf[1];
2653                 if (D_S[d].drv_type>=drv_201)
2654                 {
2655                         if (D_S[d].drv_type<drv_300)
2656                         {
2657                                 switches=infobuf[0];
2658                                 if ((switches&0x80)!=0) vol0=0;
2659                                 if ((switches&0x40)!=0) vol1=0;
2660                                 if (D_S[d].drv_type>=drv_211)
2661                                 {
2662                                         if ((switches&0x20)!=0) chan0=1;
2663                                         if ((switches&0x10)!=0) chan1=0;
2664                                 }
2665                         }
2666                         else
2667                         {
2668                                 vol0=infobuf[0];
2669                                 if ((vol0&0x01)!=0) chan0=1;
2670                                 if ((vol1&0x01)==0) chan1=0;
2671                                 vol0 &= 0xFC;
2672                                 vol1 &= 0xFC;
2673                                 if (vol0!=0) vol0 += 3;
2674                                 if (vol1!=0) vol1 += 3;
2675                         }
2676                 }
2677         }
2678         else if (famT_drive)
2679         {
2680                 D_S[d].volume_control=infobuf[7];
2681                 chan0=0;
2682                 chan1=1;
2683                 if (D_S[d].volume_control&0x10) vol0=0;
2684                 else vol0=0xff;
2685                 if (D_S[d].volume_control&0x20) vol1=0;
2686                 else vol1=0xff;
2687         }
2688         D_S[d].vol_chan0=chan0;
2689         D_S[d].vol_ctrl0=vol0;
2690         D_S[d].vol_chan1=chan1;
2691         D_S[d].vol_ctrl1=vol1;
2692 #if 000
2693         D_S[d].vol_chan2=2;
2694         D_S[d].vol_ctrl2=0xFF;
2695         D_S[d].vol_chan3=3;
2696         D_S[d].vol_ctrl3=0xFF;
2697 #endif /*  000 */
2698         D_S[d].diskstate_flags |= volume_bit;
2699         return (0);
2700 }
2701 /*==========================================================================*/
2702 static int cc_ReadCapacity(void)
2703 {
2704         int i, j;
2705         
2706         if (fam2_drive) return (0); /* some firmware lacks this command */
2707         if (famLV_drive) return (0); /* some firmware lacks this command */
2708         if (famT_drive) return (0); /* done with cc_ReadTocDescr() */
2709         D_S[d].diskstate_flags &= ~cd_size_bit;
2710         for (j=3;j>0;j--)
2711         {
2712                 clr_cmdbuf();
2713                 if (fam1_drive)
2714                 {
2715                         drvcmd[0]=CMD1_CAPACITY;
2716                         response_count=5;
2717                         flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2718                 }
2719 #if 00
2720                 else if (fam2_drive)
2721                 {
2722                         drvcmd[0]=CMD2_CAPACITY;
2723                         response_count=8;
2724                         flags_cmd_out=f_putcmd;
2725                 }
2726 #endif
2727                 else if (fam0_drive)
2728                 {
2729                         drvcmd[0]=CMD0_CAPACITY;
2730                         response_count=5;
2731                         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2732                 }
2733                 i=cmd_out();
2734                 if (i>=0) break;
2735                 msg(DBG_000,"cc_ReadCapacity: cmd_out: err %d\n", i);
2736                 cc_ReadError();
2737         }
2738         if (j==0) return (i);
2739         if (fam1_drive) D_S[d].CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_MSF_OFFSET;
2740         else if (fam0_drive) D_S[d].CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
2741 #if 00
2742         else if (fam2_drive) D_S[d].CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
2743 #endif
2744         D_S[d].diskstate_flags |= cd_size_bit;
2745         msg(DBG_000,"cc_ReadCapacity: %d frames.\n", D_S[d].CDsize_frm);
2746         return (0);
2747 }
2748 /*==========================================================================*/
2749 static int cc_ReadTocDescr(void)
2750 {
2751         int i;
2752         
2753         D_S[d].diskstate_flags &= ~toc_bit;
2754         clr_cmdbuf();
2755         if (fam1_drive)
2756         {
2757                 drvcmd[0]=CMD1_DISKINFO;
2758                 response_count=6;
2759                 flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2760         }
2761         else if (fam0LV_drive)
2762         {
2763                 drvcmd[0]=CMD0_DISKINFO;
2764                 response_count=6;
2765                 if(famLV_drive)
2766                         flags_cmd_out=f_putcmd;
2767                 else
2768                         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2769         }
2770         else if (fam2_drive)
2771         {
2772                 /* possibly longer timeout periods necessary */
2773                 D_S[d].f_multisession=0;
2774                 drvcmd[0]=CMD2_DISKINFO;
2775                 drvcmd[1]=0x02;
2776                 drvcmd[2]=0xAB;
2777                 drvcmd[3]=0xFF; /* session */
2778                 response_count=8;
2779                 flags_cmd_out=f_putcmd;
2780         }
2781         else if (famT_drive)
2782         {
2783                 D_S[d].f_multisession=0;
2784                 response_count=12;
2785                 drvcmd[0]=CMDT_DISKINFO;
2786                 drvcmd[1]=0x02;
2787