linux-old/drivers/cdrom/sbpcd.c
<<
>>
Prefs
   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)
 442static 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
 486static int sbpcd[] = {CDROM_PORT, SBPRO}; /* probe with user's setup only */
 487#endif
 488MODULE_PARM(sbpcd, "2i");
 489MODULE_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
 499extern int sbpcd2_init(void);
 500#endif
 501#ifdef CONFIG_SBPCD3
 502extern int sbpcd3_init(void);
 503#endif
 504#ifdef CONFIG_SBPCD4
 505extern int sbpcd4_init(void);
 506#endif
 507#endif
 508
 509/*==========================================================================*/
 510
 511#define INLINE inline
 512
 513/*==========================================================================*/
 514/*
 515 * the forward references:
 516 */
 517static void sbp_sleep(u_int);
 518static void mark_timeout_delay(u_long);
 519static void mark_timeout_data(u_long);
 520#if 0
 521static void mark_timeout_audio(u_long);
 522#endif
 523static void sbp_read_cmd(struct request *req);
 524static int sbp_data(struct request *req);
 525static int cmd_out(void);
 526static int DiskInfo(void);
 527static 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
 567static int sbpcd_debug = (1<<DBG_INF);
 568#else
 569static int sbpcd_debug = 0 & ((1<<DBG_INF) |
 570                          (1<<DBG_TOC) |
 571                          (1<<DBG_MUL) |
 572                          (1<<DBG_UPC));
 573#endif /* DISTRIBUTION */
 574
 575static int sbpcd_ioaddr = CDROM_PORT;   /* default I/O base address */
 576static int sbpro_type = SBPRO;
 577static unsigned char f_16bit;
 578static unsigned char do_16bit;
 579static int CDo_command, CDo_reset;
 580static int CDo_sel_i_d, CDo_enable;
 581static int CDi_info, CDi_status, CDi_data;
 582static struct cdrom_msf msf;
 583static struct cdrom_ti ti;
 584static struct cdrom_tochdr tochdr;
 585static struct cdrom_tocentry tocentry;
 586static struct cdrom_subchnl SC;
 587static struct cdrom_volctrl volctrl;
 588static struct cdrom_read_audio read_audio;
 589
 590static unsigned char msgnum;
 591static char msgbuf[80];
 592
 593static int max_drives = MAX_DRIVES;
 594#ifndef MODULE
 595static unsigned char setup_done;
 596static const char *str_sb_l = "soundblaster";
 597static const char *str_sp_l = "spea";
 598static const char *str_ss_l = "soundscape";
 599static const char *str_t16_l = "teac16bit";
 600static const char *str_ss = "SoundScape";
 601#endif
 602static const char *str_sb = "SoundBlaster";
 603static const char *str_lm = "LaserMate";
 604static const char *str_sp = "SPEA";
 605static const char *str_t16 = "Teac16bit";
 606static const char *type;
 607
 608#if !(SBPCD_ISSUE-1)
 609static const char *major_name="sbpcd";
 610#endif
 611#if !(SBPCD_ISSUE-2)
 612static const char *major_name="sbpcd2";
 613#endif
 614#if !(SBPCD_ISSUE-3)
 615static const char *major_name="sbpcd3";
 616#endif
 617#if !(SBPCD_ISSUE-4)
 618static const char *major_name="sbpcd4";
 619#endif
 620
 621/*==========================================================================*/
 622
 623#if FUTURE
 624static DECLARE_WAIT_QUEUE_HEAD(sbp_waitq);
 625#endif /* FUTURE */
 626
 627static int teac=SBP_TEAC_SPEED;
 628static int buffers=SBP_BUFFER_FRAMES;
 629
 630static u_char family0[]="MATSHITA"; /* MKE CR-521, CR-522, CR-523 */
 631static u_char family1[]="CR-56";    /* MKE CR-562, CR-563 */
 632static u_char family2[]="CD200";    /* MKE CD200, Funai CD200F */
 633static u_char familyL[]="LCS-7260"; /* Longshine LCS-7260 */
 634static u_char familyT[]="CD-55";    /* TEAC CD-55A */
 635static u_char familyV[]="ECS-AT";   /* ECS Vertos 100 */
 636
 637static u_int recursion; /* internal testing only */
 638static u_int fatal_err; /* internal testing only */
 639static u_int response_count;
 640static u_int flags_cmd_out;
 641static u_char cmd_type;
 642static u_char drvcmd[10];
 643static u_char infobuf[20];
 644static u_char xa_head_buf[CD_XA_HEAD];
 645static u_char xa_tail_buf[CD_XA_TAIL];
 646
 647#if OLD_BUSY
 648static volatile u_char busy_data;
 649static volatile u_char busy_audio; /* true semaphores would be safer */
 650#endif /* OLD_BUSY */ 
 651static DECLARE_MUTEX(ioctl_read_sem);
 652static u_long timeout;
 653static volatile u_char timed_out_delay;
 654static volatile u_char timed_out_data;
 655#if 0
 656static volatile u_char timed_out_audio;
 657#endif
 658static u_int datarate= 1000000;
 659static u_int maxtim16=16000000;
 660static u_int maxtim04= 4000000;
 661static u_int maxtim02= 2000000;
 662static u_int maxtim_8=   30000;
 663#if LONG_TIMING
 664static u_int maxtim_data= 9000;
 665#else
 666static u_int maxtim_data= 3000;
 667#endif /* LONG_TIMING */ 
 668#if DISTRIBUTION
 669static int n_retries=6;
 670#else
 671static int n_retries=6;
 672#endif
 673/*==========================================================================*/
 674
 675static int ndrives;
 676static u_char drv_pattern[NR_SBPCD]={speed_auto,speed_auto,speed_auto,speed_auto};
 677static int sbpcd_blocksizes[NR_SBPCD];
 678
 679/*==========================================================================*/
 680/*
 681 * drive space begins here (needed separate for each unit) 
 682 */
 683static int d; /* DriveStruct index: drive number */
 684
 685static 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
 793unsigned long cli_sti; /* for saving the processor flags */
 794#endif
 795/*==========================================================================*/
 796static struct timer_list delay_timer = { function: mark_timeout_delay};
 797static struct timer_list data_timer = { function: mark_timeout_data};
 798#if 0
 799static struct timer_list audio_timer = { function: mark_timeout_audio};
 800#endif
 801/*==========================================================================*/
 802/*
 803 * DDI interface
 804 */
 805static 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 */
 834static 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/*==========================================================================*/
 849static 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/*==========================================================================*/
 857static 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
 866static 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 */
 878static 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 */
 891static 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 */
 904static INLINE void bin2bcdx(u_char *p)  /* must work only up to 75 or 99 */
 905{
 906        *p=((*p/10)<<4)|(*p%10);
 907}
 908/*==========================================================================*/
 909static 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/*==========================================================================*/
 922static INLINE u_int make16(u_char rh, u_char rl)
 923{
 924        return ((rh<<8)|rl);
 925}
 926/*==========================================================================*/
 927static INLINE u_int make32(u_int rh, u_int rl)
 928{
 929        return ((rh<<16)|rl);
 930}
 931/*==========================================================================*/
 932static INLINE u_char swap_nibbles(u_char i)
 933{
 934        return ((i<<4)|(i>>4));
 935}
 936/*==========================================================================*/
 937static INLINE u_char byt2bcd(u_char i)
 938{
 939        return (((i/10)<<4)+i%10);
 940}
 941/*==========================================================================*/
 942static INLINE u_char bcd2bin(u_char bcd)
 943{
 944        return ((bcd>>4)*10+(bcd&0x0F));
 945}
 946/*==========================================================================*/
 947static 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 */
 961static 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 */ 
 971static 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/*==========================================================================*/
1005static 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/*==========================================================================*/
1013static 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 */
1035static 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/*==========================================================================*/
1072static 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/*==========================================================================*/
1094static 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/*==========================================================================*/
1103static 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/*==========================================================================*/
1112static 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/*==========================================================================*/
1123static 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/*==========================================================================*/
1161static 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/*==========================================================================*/
1212static 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/*==========================================================================*/
1259static 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/*==========================================================================*/
1296static 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/*==========================================================================*/
1310static 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/*==========================================================================*/
1359static 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/*==========================================================================*/
1518static 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/*==========================================================================*/
1585static 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/*==========================================================================*/
1641static 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/*==========================================================================*/
1679static 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/*==========================================================================*/
1717static 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/*==========================================================================*/
1729static 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/*==========================================================================*/
1749static 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/*==========================================================================*/
1777static 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/*==========================================================================*/
1816static 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/*==========================================================================*/
1983static 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/*==========================================================================*/
1995static 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/*==========================================================================*/
2041static 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
2056static void switch_drive(int i);
2057
2058static 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/*==========================================================================*/
2069static 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
2096static 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/*==========================================================================*/
2107static 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/*==========================================================================*/
2168static 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/*==========================================================================*/
2209static 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/*==========================================================================*/
2250static 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/*==========================================================================*/
2270static 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
2297static int sbpcd_lock_door(struct cdrom_device_info *cdi, int lock)
2298{
2299  return lock ? LockDoor() : UnLockDoor();
2300}
2301
2302/*==========================================================================*/
2303static 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
2375static 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/*==========================================================================*/
2395static 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/*==========================================================================*/
2471static 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/*==========================================================================*/
2520static 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/*==========================================================================*/
2567static 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/*==========================================================================*/
2702static 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/*==========================================================================*/
2749static 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                drvcmd[6]=CDROM_LEADOUT;
2788                drvcmd[8]=response_count;
2789                drvcmd[9]=0x00;
2790        }
2791        i=cmd_out();
2792        if (i<0) return (i);
2793        if ((famT_drive)&&(i<response_count)) return (-100-i);
2794        if ((fam1_drive)||(fam2_drive)||(fam0LV_drive))
2795                D_S[d].xa_byte=infobuf[0];
2796        if (fam2_drive)
2797        {
2798                D_S[d].first_session=infobuf[1];
2799                D_S[d].last_session=infobuf[2];
2800                D_S[d].n_first_track=infobuf[3];
2801                D_S[d].n_last_track=infobuf[4];
2802                if (D_S[d].first_session!=D_S[d].last_session)
2803                {
2804                        D_S[d].f_multisession=1;
2805                        D_S[d].lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])));
2806                }
2807#if 0
2808                if (D_S[d].first_session!=D_S[d].last_session)
2809                {
2810                        if (D_S[d].last_session<=20)
2811                                zwanzig=D_S[d].last_session+1;
2812                        else zwanzig=20;
2813                        for (count=D_S[d].first_session;count<zwanzig;count++)
2814                        {
2815                                drvcmd[0]=CMD2_DISKINFO;
2816                                drvcmd[1]=0x02;
2817                                drvcmd[2]=0xAB;
2818                                drvcmd[3]=count;
2819                                response_count=8;
2820                                flags_cmd_out=f_putcmd;
2821                                i=cmd_out();
2822                                if (i<0) return (i);
2823                                D_S[d].msf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]));
2824                        }
2825                        D_S[d].diskstate_flags |= multisession_bit;
2826                }
2827#endif
2828                drvcmd[0]=CMD2_DISKINFO;
2829                drvcmd[1]=0x02;
2830                drvcmd[2]=0xAA;
2831                drvcmd[3]=0xFF;
2832                response_count=5;
2833                flags_cmd_out=f_putcmd;
2834                i=cmd_out();
2835                if (i<0) return (i);
2836                D_S[d].size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
2837                D_S[d].size_blk=msf2blk(D_S[d].size_msf);
2838                D_S[d].CDsize_frm=D_S[d].size_blk+1;
2839        }
2840        else if (famT_drive)
2841        {
2842                D_S[d].size_msf=make32(make16(infobuf[8],infobuf[9]),make16(infobuf[10],infobuf[11]));
2843                D_S[d].size_blk=msf2blk(D_S[d].size_msf);
2844                D_S[d].CDsize_frm=D_S[d].size_blk+1;
2845                D_S[d].n_first_track=infobuf[2];
2846                D_S[d].n_last_track=infobuf[3];
2847        }
2848        else
2849        {
2850                D_S[d].n_first_track=infobuf[1];
2851                D_S[d].n_last_track=infobuf[2];
2852                D_S[d].size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
2853                D_S[d].size_blk=msf2blk(D_S[d].size_msf);
2854                if (famLV_drive) D_S[d].CDsize_frm=D_S[d].size_blk+1;
2855        }
2856        D_S[d].diskstate_flags |= toc_bit;
2857        msg(DBG_TOC,"TocDesc: xa %02X firstt %02X lastt %02X size %08X firstses %02X lastsess %02X\n",
2858            D_S[d].xa_byte,
2859            D_S[d].n_first_track,
2860            D_S[d].n_last_track,
2861            D_S[d].size_msf,
2862            D_S[d].first_session,
2863            D_S[d].last_session);
2864        return (0);
2865}
2866/*==========================================================================*/
2867static int cc_ReadTocEntry(int num)
2868{
2869        int i;
2870        
2871        clr_cmdbuf();
2872        if (fam1_drive)
2873        {
2874                drvcmd[0]=CMD1_READTOC;
2875                drvcmd[2]=num;
2876                response_count=8;
2877                flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2878        }
2879        else if (fam2_drive)
2880        {
2881                /* possibly longer timeout periods necessary */
2882                drvcmd[0]=CMD2_DISKINFO;
2883                drvcmd[1]=0x02;
2884                drvcmd[2]=num;
2885                response_count=5;
2886                flags_cmd_out=f_putcmd;
2887        }
2888        else if (fam0LV_drive)
2889        {
2890                drvcmd[0]=CMD0_READTOC;
2891                drvcmd[1]=0x02;
2892                drvcmd[2]=num;
2893                response_count=8;
2894                if (famLV_drive)
2895                        flags_cmd_out=f_putcmd;
2896                else
2897                  flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2898        }
2899        else if (famT_drive)
2900        {
2901                response_count=12;
2902                drvcmd[0]=CMDT_DISKINFO;
2903                drvcmd[1]=0x02;
2904                drvcmd[6]=num;
2905                drvcmd[8]=response_count;
2906                drvcmd[9]=0x00;
2907        }
2908        i=cmd_out();
2909        if (i<0) return (i);
2910        if ((famT_drive)&&(i<response_count)) return (-100-i);
2911        if ((fam1_drive)||(fam0LV_drive))
2912        {
2913                D_S[d].TocEnt_nixbyte=infobuf[0];
2914                i=1;
2915        }
2916        else if (fam2_drive) i=0;
2917        else if (famT_drive) i=5;
2918        D_S[d].TocEnt_ctl_adr=swap_nibbles(infobuf[i++]);
2919        if ((fam1_drive)||(fam0L_drive))
2920        {
2921                D_S[d].TocEnt_number=infobuf[i++];
2922                D_S[d].TocEnt_format=infobuf[i];
2923        }
2924        else
2925          {
2926            D_S[d].TocEnt_number=num;
2927            D_S[d].TocEnt_format=0;
2928          }
2929        if (fam1_drive) i=4;
2930        else if (fam0LV_drive) i=5;
2931        else if (fam2_drive) i=2;
2932        else if (famT_drive) i=9;
2933        D_S[d].TocEnt_address=make32(make16(0,infobuf[i]),
2934                                     make16(infobuf[i+1],infobuf[i+2]));
2935        for (i=0;i<response_count;i++)
2936                sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
2937        msgbuf[i*3]=0;
2938        msg(DBG_ECS,"TocEntry:%s\n", msgbuf);
2939        msg(DBG_TOC,"TocEntry: %02X %02X %02X %02X %08X\n",
2940            D_S[d].TocEnt_nixbyte, D_S[d].TocEnt_ctl_adr,
2941            D_S[d].TocEnt_number, D_S[d].TocEnt_format,
2942            D_S[d].TocEnt_address);
2943        return (0);
2944}
2945/*==========================================================================*/
2946static int cc_ReadPacket(void)
2947{
2948        int i;
2949        
2950        clr_cmdbuf();
2951        drvcmd[0]=CMD0_PACKET;
2952        drvcmd[1]=response_count;
2953        if(famL_drive) flags_cmd_out=f_putcmd;
2954        else if (fam01_drive)
2955                flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2956        else if (fam2_drive) return (-1); /* not implemented yet */
2957        else if (famT_drive)
2958        {
2959                return (-1);
2960        }
2961        i=cmd_out();
2962        return (i);
2963}
2964/*==========================================================================*/
2965static int convert_UPC(u_char *p)
2966{
2967        int i;
2968        
2969        p++;
2970        if (fam0L_drive) p[13]=0;
2971        for (i=0;i<7;i++)
2972        {
2973                if (fam1_drive) D_S[d].UPC_buf[i]=swap_nibbles(*p++);
2974                else if (fam0L_drive)
2975                {
2976                        D_S[d].UPC_buf[i]=((*p++)<<4)&0xFF;
2977                        D_S[d].UPC_buf[i] |= *p++;
2978                }
2979                else if (famT_drive)
2980                {
2981                        return (-1);
2982                }
2983                else /* CD200 */
2984                {
2985                        return (-1);
2986                }
2987        }
2988        D_S[d].UPC_buf[6] &= 0xF0;
2989        return (0);
2990}
2991/*==========================================================================*/
2992static int cc_ReadUPC(void)
2993{
2994        int i;
2995#if TEST_UPC
2996        int block, checksum;
2997#endif /* TEST_UPC */ 
2998        
2999        if (fam2_drive) return (0); /* not implemented yet */
3000        if (famT_drive) return (0); /* not implemented yet */
3001        if (famV_drive) return (0); /* not implemented yet */
3002#if 1
3003        if (fam0_drive) return (0); /* but it should work */
3004#endif
3005        
3006        D_S[d].diskstate_flags &= ~upc_bit;
3007#if TEST_UPC
3008        for (block=CD_MSF_OFFSET+1;block<CD_MSF_OFFSET+200;block++)
3009        {
3010#endif /* TEST_UPC */ 
3011                clr_cmdbuf();
3012                if (fam1_drive)
3013                {
3014                        drvcmd[0]=CMD1_READ_UPC;
3015#if TEST_UPC
3016                        drvcmd[1]=(block>>16)&0xFF;
3017                        drvcmd[2]=(block>>8)&0xFF;
3018                        drvcmd[3]=block&0xFF;
3019#endif /* TEST_UPC */ 
3020                        response_count=8;
3021                        flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
3022                }
3023                else if (fam0L_drive)
3024                {
3025                        drvcmd[0]=CMD0_READ_UPC;
3026#if TEST_UPC
3027                        drvcmd[2]=(block>>16)&0xFF;
3028                        drvcmd[3]=(block>>8)&0xFF;
3029                        drvcmd[4]=block&0xFF;
3030#endif /* TEST_UPC */ 
3031                        response_count=0;
3032                        flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
3033                }
3034                else if (fam2_drive)
3035                {
3036                        return (-1);
3037                }
3038                else if (famT_drive)
3039                {
3040                        return (-1);
3041                }
3042                i=cmd_out();
3043                if (i<0)
3044                {
3045                        msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i);
3046                        return (i);
3047                }
3048                if (fam0L_drive)
3049                {
3050                        response_count=16;
3051                        if (famL_drive) flags_cmd_out=f_putcmd;
3052                        i=cc_ReadPacket();
3053                        if (i<0)
3054                        {
3055                                msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i);
3056                                return (i);
3057                        }
3058                }
3059#if TEST_UPC
3060                checksum=0;
3061#endif /* TEST_UPC */ 
3062                for (i=0;i<(fam1_drive?8:16);i++)
3063                {
3064#if TEST_UPC
3065                        checksum |= infobuf[i];
3066#endif /* TEST_UPC */ 
3067                        sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3068                }
3069                msgbuf[i*3]=0;
3070                msg(DBG_UPC,"UPC info:%s\n", msgbuf);
3071#if TEST_UPC
3072                if ((checksum&0x7F)!=0) break;
3073        }
3074#endif /* TEST_UPC */ 
3075        D_S[d].UPC_ctl_adr=0;
3076        if (fam1_drive) i=0;
3077        else i=2;
3078        if ((infobuf[i]&0x80)!=0)
3079        {
3080                convert_UPC(&infobuf[i]);
3081                D_S[d].UPC_ctl_adr = (D_S[d].TocEnt_ctl_adr & 0xF0) | 0x02;
3082        }
3083        for (i=0;i<7;i++)
3084                sprintf(&msgbuf[i*3], " %02X", D_S[d].UPC_buf[i]);
3085        sprintf(&msgbuf[i*3], " (%02X)", D_S[d].UPC_ctl_adr);
3086        msgbuf[i*3+5]=0;
3087        msg(DBG_UPC,"UPC code:%s\n", msgbuf);
3088        D_S[d].diskstate_flags |= upc_bit;
3089        return (0);
3090}
3091
3092static int sbpcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
3093{
3094        int i;
3095        unsigned char *mcnp = mcn->medium_catalog_number;
3096        unsigned char *resp;
3097
3098        D_S[d].diskstate_flags &= ~upc_bit;
3099        clr_cmdbuf();
3100        if (fam1_drive)
3101        {
3102                drvcmd[0]=CMD1_READ_UPC;
3103                response_count=8;
3104                flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
3105        }
3106        else if (fam0L_drive)
3107        {
3108                drvcmd[0]=CMD0_READ_UPC;
3109                response_count=0;
3110                flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
3111        }
3112        else if (fam2_drive)
3113        {
3114                return (-1);
3115        }
3116        else if (famT_drive)
3117        {
3118                return (-1);
3119        }
3120        i=cmd_out();
3121        if (i<0)
3122        {
3123                msg(DBG_000,"cc_ReadUPC cmd_out: err %d\n", i);
3124                return (i);
3125        }
3126        if (fam0L_drive)
3127        {
3128                response_count=16;
3129                if (famL_drive) flags_cmd_out=f_putcmd;
3130                i=cc_ReadPacket();
3131                if (i<0)
3132                {
3133                        msg(DBG_000,"cc_ReadUPC ReadPacket: err %d\n", i);
3134                        return (i);
3135                }
3136        }
3137        D_S[d].UPC_ctl_adr=0;
3138        if (fam1_drive) i=0;
3139        else i=2;
3140
3141        resp = infobuf + i;
3142        if (*resp++ == 0x80) {
3143                /* packed bcd to single ASCII digits */
3144                *mcnp++ = (*resp >> 4)     + '0';
3145                *mcnp++ = (*resp++ & 0x0f) + '0';
3146                *mcnp++ = (*resp >> 4)     + '0';
3147                *mcnp++ = (*resp++ & 0x0f) + '0';
3148                *mcnp++ = (*resp >> 4)     + '0';
3149                *mcnp++ = (*resp++ & 0x0f) + '0';
3150                *mcnp++ = (*resp >> 4)     + '0';
3151                *mcnp++ = (*resp++ & 0x0f) + '0';
3152                *mcnp++ = (*resp >> 4)     + '0';
3153                *mcnp++ = (*resp++ & 0x0f) + '0';
3154                *mcnp++ = (*resp >> 4)     + '0';
3155                *mcnp++ = (*resp++ & 0x0f) + '0';
3156                *mcnp++ = (*resp >> 4)     + '0';
3157        }
3158        *mcnp = '\0';
3159
3160        D_S[d].diskstate_flags |= upc_bit;
3161        return (0);
3162}
3163
3164/*==========================================================================*/
3165static int cc_CheckMultiSession(void)
3166{
3167        int i;
3168        
3169        if (fam2_drive) return (0);
3170        D_S[d].f_multisession=0;
3171        D_S[d].lba_multi=0;
3172        if (fam0_drive) return (0);
3173        clr_cmdbuf();
3174        if (fam1_drive)
3175        {
3176                drvcmd[0]=CMD1_MULTISESS;
3177                response_count=6;
3178                flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
3179                i=cmd_out();
3180                if (i<0) return (i);
3181                if ((infobuf[0]&0x80)!=0)
3182                {
3183                        D_S[d].f_multisession=1;
3184                        D_S[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]),
3185                                                        make16(infobuf[2],infobuf[3])));
3186                }
3187        }
3188        else if (famLV_drive)
3189        {
3190                drvcmd[0]=CMDL_MULTISESS;
3191                drvcmd[1]=3;
3192                drvcmd[2]=1;
3193                response_count=8;
3194                flags_cmd_out=f_putcmd;
3195                i=cmd_out();
3196                if (i<0) return (i);
3197                D_S[d].lba_multi=msf2blk(make32(make16(0,infobuf[5]),
3198                                                make16(infobuf[6],infobuf[7])));
3199        }
3200        else if (famT_drive)
3201        {
3202                response_count=12;
3203                drvcmd[0]=CMDT_DISKINFO;
3204                drvcmd[1]=0x02;
3205                drvcmd[6]=0;
3206                drvcmd[8]=response_count;
3207                drvcmd[9]=0x40;
3208                i=cmd_out();
3209                if (i<0) return (i);
3210                if (i<response_count) return (-100-i);
3211                D_S[d].first_session=infobuf[2];
3212                D_S[d].last_session=infobuf[3];
3213                D_S[d].track_of_last_session=infobuf[6];
3214                if (D_S[d].first_session!=D_S[d].last_session)
3215                {
3216                        D_S[d].f_multisession=1;
3217                        D_S[d].lba_multi=msf2blk(make32(make16(0,infobuf[9]),make16(infobuf[10],infobuf[11])));
3218                }
3219        }
3220        for (i=0;i<response_count;i++)
3221                sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3222        msgbuf[i*3]=0;
3223        msg(DBG_MUL,"MultiSession Info:%s (%d)\n", msgbuf, D_S[d].lba_multi);
3224        if (D_S[d].lba_multi>200)
3225        {
3226                D_S[d].f_multisession=1;
3227                msg(DBG_MUL,"MultiSession base: %06X\n", D_S[d].lba_multi);
3228        }
3229        return (0);
3230}
3231/*==========================================================================*/
3232#if FUTURE
3233static int cc_SubChanInfo(int frame, int count, u_char *buffer)
3234        /* "frame" is a RED BOOK (msf-bin) address */
3235{
3236        int i;
3237        
3238        if (fam0LV_drive) return (-ENOSYS); /* drive firmware lacks it */
3239        if (famT_drive)
3240        {
3241                return (-1);
3242        }
3243#if 0
3244        if (D_S[d].audio_state!=audio_playing) return (-ENODATA);
3245#endif
3246        clr_cmdbuf();
3247        drvcmd[0]=CMD1_SUBCHANINF;
3248        drvcmd[1]=(frame>>16)&0xFF;
3249        drvcmd[2]=(frame>>8)&0xFF;
3250        drvcmd[3]=frame&0xFF;
3251        drvcmd[5]=(count>>8)&0xFF;
3252        drvcmd[6]=count&0xFF;
3253        flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
3254        cmd_type=READ_SC;
3255        D_S[d].frame_size=CD_FRAMESIZE_SUB;
3256        i=cmd_out(); /* which buffer to use? */
3257        return (i);
3258}
3259#endif /* FUTURE */ 
3260/*==========================================================================*/
3261static void __init check_datarate(void)
3262{
3263        int i=0;
3264        
3265        msg(DBG_IOX,"check_datarate entered.\n");
3266        datarate=0;
3267#if TEST_STI
3268        for (i=0;i<=1000;i++) printk(".");
3269#endif
3270        /* set a timer to make (timed_out_delay!=0) after 1.1 seconds */
3271#if 1
3272        del_timer(&delay_timer);
3273#endif
3274        delay_timer.expires=jiffies+11*HZ/10;
3275        timed_out_delay=0;
3276        add_timer(&delay_timer);
3277#if 0
3278        msg(DBG_TIM,"delay timer started (11*HZ/10).\n");
3279#endif
3280        do
3281        {
3282                i=inb(CDi_status);
3283                datarate++;
3284#if 1
3285                if (datarate>0x6FFFFFFF) break;
3286#endif 
3287        }
3288        while (!timed_out_delay);
3289        del_timer(&delay_timer);
3290#if 0
3291        msg(DBG_TIM,"datarate: %04X\n", datarate);
3292#endif
3293        if (datarate<65536) datarate=65536;
3294        maxtim16=datarate*16;
3295        maxtim04=datarate*4;
3296        maxtim02=datarate*2;
3297        maxtim_8=datarate/32;
3298#if LONG_TIMING
3299        maxtim_data=datarate/100;
3300#else
3301        maxtim_data=datarate/300;
3302#endif /* LONG_TIMING */ 
3303#if 0
3304        msg(DBG_TIM,"maxtim_8 %d, maxtim_data %d.\n", maxtim_8, maxtim_data);
3305#endif
3306}
3307/*==========================================================================*/
3308#if 0
3309static int c2_ReadError(int fam)
3310{
3311        int i;
3312        
3313        clr_cmdbuf();
3314        response_count=9;
3315        clr_respo_buf(9);
3316        if (fam==1)
3317        {
3318                drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
3319                i=do_cmd(f_putcmd|f_lopsta|f_getsta|f_ResponseStatus);
3320        }
3321        else if (fam==2)
3322        {
3323                drvcmd[0]=CMD2_READ_ERR;
3324                i=do_cmd(f_putcmd);
3325        }
3326        else return (-1);
3327        return (i);
3328}
3329#endif
3330/*==========================================================================*/
3331static void __init ask_mail(void)
3332{
3333        int i;
3334        
3335        msg(DBG_INF, "please mail the following lines to emoenke@gwdg.de\n");
3336        msg(DBG_INF, "(don't mail if you are not using the actual kernel):\n");
3337        msg(DBG_INF, "%s\n", VERSION);
3338        msg(DBG_INF, "address %03X, type %s, drive %s (ID %d)\n",
3339            CDo_command, type, D_S[d].drive_model, D_S[d].drv_id);
3340        for (i=0;i<12;i++)
3341                sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3342        msgbuf[i*3]=0;
3343        msg(DBG_INF,"infobuf =%s\n", msgbuf);
3344        for (i=0;i<12;i++)
3345                sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
3346        msgbuf[i*3]=0;
3347        msg(DBG_INF,"infobuf =%s\n", msgbuf);
3348}
3349/*==========================================================================*/
3350static int __init check_version(void)
3351{
3352        int i, j, l;
3353        int teac_possible=0;
3354        
3355        msg(DBG_INI,"check_version: id=%d, d=%d.\n", D_S[d].drv_id, d);
3356        D_S[d].drv_type=0;
3357
3358        /* check for CR-52x, CR-56x, LCS-7260 and ECS-AT */
3359        /* clear any pending error state */
3360        clr_cmdbuf();
3361        drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
3362        response_count=9;
3363        flags_cmd_out=f_putcmd;
3364        i=cmd_out();
3365        if (i<0) msg(DBG_INI,"CMD0_READ_ERR returns %d (ok anyway).\n",i);
3366        /* read drive version */
3367        clr_cmdbuf();
3368        for (i=0;i<12;i++) infobuf[i]=0;
3369        drvcmd[0]=CMD0_READ_VER; /* same as CMD1_ and CMDL_ */
3370        response_count=12; /* fam1: only 11 */
3371        flags_cmd_out=f_putcmd;
3372        i=cmd_out();
3373        if (i<-1) msg(DBG_INI,"CMD0_READ_VER returns %d\n",i);
3374        if (i==-11) teac_possible++;
3375        j=0;
3376        for (i=0;i<12;i++) j+=infobuf[i];
3377        if (j)
3378        {
3379                for (i=0;i<12;i++)
3380                        sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3381                msgbuf[i*3]=0;
3382                msg(DBG_ECS,"infobuf =%s\n", msgbuf);
3383                for (i=0;i<12;i++)
3384                        sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
3385                msgbuf[i*3]=0;
3386                msg(DBG_ECS,"infobuf =%s\n", msgbuf);
3387        }
3388        for (i=0;i<4;i++) if (infobuf[i]!=family1[i]) break;
3389        if (i==4)
3390        {
3391                D_S[d].drive_model[0]='C';
3392                D_S[d].drive_model[1]='R';
3393                D_S[d].drive_model[2]='-';
3394                D_S[d].drive_model[3]='5';
3395                D_S[d].drive_model[4]=infobuf[i++];
3396                D_S[d].drive_model[5]=infobuf[i++];
3397                D_S[d].drive_model[6]=0;
3398                D_S[d].drv_type=drv_fam1;
3399        }
3400        if (!D_S[d].drv_type)
3401        {
3402                for (i=0;i<8;i++) if (infobuf[i]!=family0[i]) break;
3403                if (i==8)
3404                {
3405                        D_S[d].drive_model[0]='C';
3406                        D_S[d].drive_model[1]='R';
3407                        D_S[d].drive_model[2]='-';
3408                        D_S[d].drive_model[3]='5';
3409                        D_S[d].drive_model[4]='2';
3410                        D_S[d].drive_model[5]='x';
3411                        D_S[d].drive_model[6]=0;
3412                        D_S[d].drv_type=drv_fam0;
3413                }
3414        }
3415        if (!D_S[d].drv_type)
3416        {
3417                for (i=0;i<8;i++) if (infobuf[i]!=familyL[i]) break;
3418                if (i==8)
3419                {
3420                        for (j=0;j<8;j++)
3421                                D_S[d].drive_model[j]=infobuf[j];
3422                        D_S[d].drive_model[8]=0;
3423                        D_S[d].drv_type=drv_famL;
3424                }
3425        }
3426        if (!D_S[d].drv_type)
3427        {
3428                for (i=0;i<6;i++) if (infobuf[i]!=familyV[i]) break;
3429                if (i==6)
3430                {
3431                        for (j=0;j<6;j++)
3432                                D_S[d].drive_model[j]=infobuf[j];
3433                        D_S[d].drive_model[6]=0;
3434                        D_S[d].drv_type=drv_famV;
3435                        i+=2; /* 2 blanks before version */
3436                }
3437        }
3438        if (!D_S[d].drv_type)
3439        {
3440                /* check for CD200 */
3441                clr_cmdbuf();
3442                drvcmd[0]=CMD2_READ_ERR;
3443                response_count=9;
3444                flags_cmd_out=f_putcmd;
3445                i=cmd_out();
3446                if (i<0) msg(DBG_INI,"CMD2_READERR returns %d (ok anyway).\n",i);
3447                if (i<0) msg(DBG_000,"CMD2_READERR returns %d (ok anyway).\n",i);
3448                /* read drive version */
3449                clr_cmdbuf();
3450                for (i=0;i<12;i++) infobuf[i]=0;
3451                if (sbpro_type==1) OUT(CDo_sel_i_d,0);
3452#if 0
3453                OUT(CDo_reset,0);
3454                sbp_sleep(6*HZ);
3455                OUT(CDo_enable,D_S[d].drv_sel);
3456#endif
3457                drvcmd[0]=CMD2_READ_VER;
3458                response_count=12;
3459                flags_cmd_out=f_putcmd;
3460                i=cmd_out();
3461                if (i<0) msg(DBG_INI,"CMD2_READ_VER returns %d\n",i);
3462                if (i==-7) teac_possible++;
3463                j=0;
3464                for (i=0;i<12;i++) j+=infobuf[i];
3465                if (j)
3466                {
3467                        for (i=0;i<12;i++)
3468                                sprintf(&msgbuf[i*3], " %02X", infobuf[i]);
3469                        msgbuf[i*3]=0;
3470                        msg(DBG_IDX,"infobuf =%s\n", msgbuf);
3471                        for (i=0;i<12;i++)
3472                                sprintf(&msgbuf[i*3], " %c ", infobuf[i]);
3473                        msgbuf[i*3]=0;
3474                        msg(DBG_IDX,"infobuf =%s\n", msgbuf);
3475                }
3476                if (i>=0)
3477                {
3478                        for (i=0;i<5;i++) if (infobuf[i]!=family2[i]) break;
3479                        if (i==5)
3480                        {
3481                                D_S[d].drive_model[0]='C';
3482                                D_S[d].drive_model[1]='D';
3483                                D_S[d].drive_model[2]='2';
3484                                D_S[d].drive_model[3]='0';
3485                                D_S[d].drive_model[4]='0';
3486                                D_S[d].drive_model[5]=infobuf[i++];
3487                                D_S[d].drive_model[6]=infobuf[i++];
3488                                D_S[d].drive_model[7]=0;
3489                                D_S[d].drv_type=drv_fam2;
3490                        }
3491                }
3492        }
3493        if (!D_S[d].drv_type)
3494        {
3495                /* check for TEAC CD-55A */
3496                msg(DBG_TEA,"teac_possible: %d\n",teac_possible);
3497                for (j=1;j<=((D_S[d].drv_id==0)?3:1);j++)
3498                {
3499                        for (l=1;l<=((D_S[d].drv_id==0)?10:1);l++)
3500                        {
3501                                msg(DBG_TEA,"TEAC reset #%d-%d.\n", j, l);
3502                                if (sbpro_type==1) OUT(CDo_reset,0);
3503                                else
3504                                {
3505                                        OUT(CDo_enable,D_S[d].drv_sel);
3506                                        OUT(CDo_sel_i_d,0);
3507                                        OUT(CDo_command,CMDT_RESET);
3508                                        for (i=0;i<9;i++) OUT(CDo_command,0);
3509                                }
3510                                sbp_sleep(5*HZ/10);
3511                                OUT(CDo_enable,D_S[d].drv_sel);
3512                                OUT(CDo_sel_i_d,0);
3513                                i=inb(CDi_status);
3514                                msg(DBG_TEA,"TEAC CDi_status: %02X.\n",i);
3515#if 0
3516                                if (i&s_not_result_ready) continue; /* drive not present or ready */
3517#endif
3518                                i=inb(CDi_info);
3519                                msg(DBG_TEA,"TEAC CDi_info: %02X.\n",i);
3520                                if (i==0x55) break; /* drive found */
3521                        }
3522                        if (i==0x55) break; /* drive found */
3523                }
3524                if (i==0x55) /* drive found */
3525                {
3526                        msg(DBG_TEA,"TEAC drive found.\n");
3527                        clr_cmdbuf();
3528                        flags_cmd_out=f_putcmd;
3529                        response_count=12;
3530                        drvcmd[0]=CMDT_READ_VER;
3531                        drvcmd[4]=response_count;
3532                        for (i=0;i<12;i++) infobuf[i]=0;
3533                        i=cmd_out_T();
3534                        if (i!=0) msg(DBG_TEA,"cmd_out_T(CMDT_READ_VER) returns %d.\n",i);
3535                        for (i=1;i<6;i++) if (infobuf[i]!=familyT[i-1]) break;
3536                        if (i==6)
3537                        {
3538                                D_S[d].drive_model[0]='C';
3539                                D_S[d].drive_model[1]='D';
3540                                D_S[d].drive_model[2]='-';
3541                                D_S[d].drive_model[3]='5';
3542                                D_S[d].drive_model[4]='5';
3543                                D_S[d].drive_model[5]=0;
3544                                D_S[d].drv_type=drv_famT;
3545                        }
3546                }
3547        }
3548        if (!D_S[d].drv_type)
3549        {
3550                msg(DBG_TEA,"no drive found at address %03X under ID %d.\n",CDo_command,D_S[d].drv_id);
3551                return (-522);
3552        }
3553        for (j=0;j<4;j++) D_S[d].firmware_version[j]=infobuf[i+j];
3554        if (famL_drive)
3555        {
3556          u_char lcs_firm_e1[]="A E1";
3557          u_char lcs_firm_f4[]="A4F4";
3558                
3559          for (j=0;j<4;j++)
3560            if (D_S[d].firmware_version[j]!=lcs_firm_e1[j]) break;
3561          if (j==4) D_S[d].drv_type=drv_e1;
3562          
3563          for (j=0;j<4;j++)
3564            if (D_S[d].firmware_version[j]!=lcs_firm_f4[j]) break;
3565          if (j==4) D_S[d].drv_type=drv_f4;
3566
3567          if (D_S[d].drv_type==drv_famL) ask_mail();
3568        }
3569        else if (famT_drive)
3570        {
3571                j=infobuf[4]; /* one-byte version??? - here: 0x15 */
3572                if (j=='5')
3573                {
3574                        D_S[d].firmware_version[0]=infobuf[7];
3575                        D_S[d].firmware_version[1]=infobuf[8];
3576                        D_S[d].firmware_version[2]=infobuf[10];
3577                        D_S[d].firmware_version[3]=infobuf[11];
3578                }
3579                else
3580                {
3581                        if (j!=0x15) ask_mail();
3582                        D_S[d].firmware_version[0]='0';
3583                        D_S[d].firmware_version[1]='.';
3584                        D_S[d].firmware_version[2]='0'+(j>>4);
3585                        D_S[d].firmware_version[3]='0'+(j&0x0f);
3586                }
3587        }
3588        else /* CR-52x, CR-56x, CD200, ECS-AT */
3589        {
3590                j = (D_S[d].firmware_version[0] & 0x0F) * 100 +
3591                        (D_S[d].firmware_version[2] & 0x0F) *10 +
3592                                (D_S[d].firmware_version[3] & 0x0F);
3593                if (fam0_drive)
3594                {
3595                        if (j<200) D_S[d].drv_type=drv_199;
3596                        else if (j<201) D_S[d].drv_type=drv_200;
3597                        else if (j<210) D_S[d].drv_type=drv_201;
3598                        else if (j<211) D_S[d].drv_type=drv_210;
3599                        else if (j<300) D_S[d].drv_type=drv_211;
3600                        else if (j>=300) D_S[d].drv_type=drv_300;
3601                }
3602                else if (fam1_drive)
3603                {
3604                        if (j<100) D_S[d].drv_type=drv_099;
3605                        else
3606                        {
3607                                D_S[d].drv_type=drv_100;
3608                                if ((j!=500)&&(j!=102)) ask_mail();
3609                        }
3610                }
3611                else if (fam2_drive)
3612                {
3613                        if (D_S[d].drive_model[5]=='F')
3614                        {
3615                                if ((j!=1)&&(j!=35)&&(j!=200)&&(j!=210))
3616                                  ask_mail(); /* unknown version at time */
3617                        }
3618                        else
3619                        {
3620                                msg(DBG_INF,"this CD200 drive is not fully supported yet - only audio will work.\n");
3621                                if ((j!=101)&&(j!=35))
3622                                  ask_mail(); /* unknown version at time */
3623                        }
3624                }
3625                else if (famV_drive)
3626                  {
3627                    if ((j==100)||(j==150)) D_S[d].drv_type=drv_at;
3628                    ask_mail(); /* hopefully we get some feedback by this */
3629                  }
3630        }
3631        msg(DBG_LCS,"drive type %02X\n",D_S[d].drv_type);
3632        msg(DBG_INI,"check_version done.\n");
3633        return (0);
3634}
3635/*==========================================================================*/
3636static void switch_drive(int i)
3637{
3638        d=i;
3639        OUT(CDo_enable,D_S[d].drv_sel);
3640        msg(DBG_DID,"drive %d (ID=%d) activated.\n", i, D_S[d].drv_id);
3641        return;
3642}
3643/*==========================================================================*/
3644#ifdef PATH_CHECK
3645/*
3646 * probe for the presence of an interface card
3647 */
3648static int __init check_card(int port)
3649{
3650#undef N_RESPO
3651#define N_RESPO 20
3652        int i, j, k;
3653        u_char response[N_RESPO];
3654        u_char save_port0;
3655        u_char save_port3;
3656        
3657        msg(DBG_INI,"check_card entered.\n");
3658        save_port0=inb(port+0);
3659        save_port3=inb(port+3);
3660        
3661        for (j=0;j<NR_SBPCD;j++)
3662        {
3663                OUT(port+3,j) ; /* enable drive #j */
3664                OUT(port+0,CMD0_PATH_CHECK);
3665                for (i=10;i>0;i--) OUT(port+0,0);
3666                for (k=0;k<N_RESPO;k++) response[k]=0;
3667                for (k=0;k<N_RESPO;k++)
3668                {
3669                        for (i=10000;i>0;i--)
3670                        {
3671                                if (inb(port+1)&s_not_result_ready) continue;
3672                                response[k]=inb(port+0);
3673                                break;
3674                        }
3675                }
3676                for (i=0;i<N_RESPO;i++)
3677                        sprintf(&msgbuf[i*3], " %02X", response[i]);
3678                msgbuf[i*3]=0;
3679                msg(DBG_TEA,"path check 00 (%d): %s\n", j, msgbuf);
3680                OUT(port+0,CMD0_PATH_CHECK);
3681                for (i=10;i>0;i--) OUT(port+0,0);
3682                for (k=0;k<N_RESPO;k++) response[k]=0xFF;
3683                for (k=0;k<N_RESPO;k++)
3684                {
3685                        for (i=10000;i>0;i--)
3686                        {
3687                                if (inb(port+1)&s_not_result_ready) continue;
3688                                response[k]=inb(port+0);
3689                                break;
3690                        }
3691                }
3692                for (i=0;i<N_RESPO;i++)
3693                        sprintf(&msgbuf[i*3], " %02X", response[i]);
3694                msgbuf[i*3]=0;
3695                msg(DBG_TEA,"path check 00 (%d): %s\n", j, msgbuf);
3696
3697                if (response[0]==0xAA)
3698                        if (response[1]==0x55)
3699                                return (0);
3700        }
3701        for (j=0;j<NR_SBPCD;j++)
3702        {
3703                OUT(port+3,j) ; /* enable drive #j */
3704                OUT(port+0,CMD2_READ_VER);
3705                for (i=10;i>0;i--) OUT(port+0,0);
3706                for (k=0;k<N_RESPO;k++) response[k]=0;
3707                for (k=0;k<N_RESPO;k++)
3708                {
3709                        for (i=1000000;i>0;i--)
3710                        {
3711                                if (inb(port+1)&s_not_result_ready) continue;
3712                                response[k]=inb(port+0);
3713                                break;
3714                        }
3715                }
3716                for (i=0;i<N_RESPO;i++)
3717                        sprintf(&msgbuf[i*3], " %02X", response[i]);
3718                msgbuf[i*3]=0;
3719                msg(DBG_TEA,"path check 12 (%d): %s\n", j, msgbuf);
3720
3721                OUT(port+0,CMD2_READ_VER);
3722                for (i=10;i>0;i--) OUT(port+0,0);
3723                for (k=0;k<N_RESPO;k++) response[k]=0xFF;
3724                for (k=0;k<N_RESPO;k++)
3725                {
3726                        for (i=1000000;i>0;i--)
3727                        {
3728                                if (inb(port+1)&s_not_result_ready) continue;
3729                                response[k]=inb(port+0);
3730                                break;
3731                        }
3732                }
3733                for (i=0;i<N_RESPO;i++)
3734                        sprintf(&msgbuf[i*3], " %02X", response[i]);
3735                msgbuf[i*3]=0;
3736                msg(DBG_TEA,"path check 12 (%d): %s\n", j, msgbuf);
3737
3738                if (response[0]==0xAA)
3739                        if (response[1]==0x55)
3740                                return (0);
3741        }
3742        OUT(port+0,save_port0);
3743        OUT(port+3,save_port3);
3744        return (0); /* in any case - no real "function" at time */
3745}
3746#endif /* PATH_CHECK */ 
3747/*==========================================================================*/
3748/*==========================================================================*/
3749/*
3750 * probe for the presence of drives on the selected controller
3751 */
3752static int __init check_drives(void)
3753{
3754        int i, j;
3755        
3756        msg(DBG_INI,"check_drives entered.\n");
3757        ndrives=0;
3758        for (j=0;j<max_drives;j++)
3759        {
3760                D_S[ndrives].drv_id=j;
3761                if (sbpro_type==1) D_S[ndrives].drv_sel=(j&0x01)<<1|(j&0x02)>>1;
3762                else D_S[ndrives].drv_sel=j;
3763                switch_drive(ndrives);
3764                msg(DBG_INI,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
3765                msg(DBG_000,"check_drives: drive %d (ID=%d) activated.\n",ndrives,j);
3766                i=check_version();
3767                if (i<0) msg(DBG_INI,"check_version returns %d.\n",i);
3768                else
3769                {
3770                        D_S[d].drv_options=drv_pattern[j];
3771                        if (fam0L_drive) D_S[d].drv_options&=~(speed_auto|speed_300|speed_150);
3772                        msg(DBG_INF, "Drive %d (ID=%d): %.9s (%.4s) at 0x%03X (type %d)\n",
3773                            d,
3774                            D_S[d].drv_id,
3775                            D_S[d].drive_model,
3776                            D_S[d].firmware_version,
3777                            CDo_command,
3778                            sbpro_type);
3779                        ndrives++;
3780                }
3781        }
3782        for (j=ndrives;j<NR_SBPCD;j++) D_S[j].drv_id=-1;
3783        if (ndrives==0) return (-1);
3784        return (0);
3785}
3786/*==========================================================================*/
3787#if FUTURE
3788/*
3789 *  obtain if requested service disturbs current audio state
3790 */            
3791static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc)
3792{
3793        switch (audio_state)                   /* audio status from controller  */
3794        {
3795        case aud_11: /* "audio play in progress" */
3796        case audx11:
3797                switch (func)                      /* DOS command code */
3798                {
3799                case cmd_07: /* input flush  */
3800                case cmd_0d: /* open device  */
3801                case cmd_0e: /* close device */
3802                case cmd_0c: /* ioctl output */
3803                        return (1);
3804                case cmd_03: /* ioctl input  */
3805                        switch (subfunc)
3806                                /* DOS ioctl input subfunction */
3807                        {
3808                        case cxi_00:
3809                        case cxi_06:
3810                        case cxi_09:
3811                                return (1);
3812                        default:
3813                                return (ERROR15);
3814                        }
3815                        return (1);
3816                default:
3817                        return (ERROR15);
3818                }
3819                return (1);
3820        case aud_12:                  /* "audio play paused"      */
3821        case audx12:
3822                return (1);
3823        default:
3824                return (2);
3825        }
3826}
3827/*==========================================================================*/
3828/* allowed is only
3829 * ioctl_o, flush_input, open_device, close_device, 
3830 * tell_address, tell_volume, tell_capabiliti,
3831 * tell_framesize, tell_CD_changed, tell_audio_posi
3832 */
3833static int check_allowed1(u_char func1, u_char func2)
3834{
3835#if 000
3836        if (func1==ioctl_o) return (0);
3837        if (func1==read_long) return (-1);
3838        if (func1==read_long_prefetch) return (-1);
3839        if (func1==seek) return (-1);
3840        if (func1==audio_play) return (-1);
3841        if (func1==audio_pause) return (-1);
3842        if (func1==audio_resume) return (-1);
3843        if (func1!=ioctl_i) return (0);
3844        if (func2==tell_SubQ_run_tot) return (-1);
3845        if (func2==tell_cdsize) return (-1);
3846        if (func2==tell_TocDescrip) return (-1);
3847        if (func2==tell_TocEntry) return (-1);
3848        if (func2==tell_subQ_info) return (-1);
3849        if (fam1_drive) if (func2==tell_SubChanInfo) return (-1);
3850        if (func2==tell_UPC) return (-1);
3851#else
3852        return (0);
3853#endif
3854}
3855/*==========================================================================*/
3856static int check_allowed2(u_char func1, u_char func2)
3857{
3858#if 000
3859        if (func1==read_long) return (-1);
3860        if (func1==read_long_prefetch) return (-1);
3861        if (func1==seek) return (-1);
3862        if (func1==audio_play) return (-1);
3863  if (func1!=ioctl_o) return (0);
3864        if (fam1_drive)
3865        {
3866                if (func2==EjectDisk) return (-1);
3867                if (func2==CloseTray) return (-1);
3868        }
3869#else
3870        return (0);
3871#endif
3872}
3873/*==========================================================================*/
3874static int check_allowed3(u_char func1, u_char func2)
3875{
3876#if 000
3877        if (func1==ioctl_i)
3878        {
3879                if (func2==tell_address) return (0);
3880                if (func2==tell_capabiliti) return (0);
3881                if (func2==tell_CD_changed) return (0);
3882                if (fam0L_drive) if (func2==tell_SubChanInfo) return (0);
3883                return (-1);
3884        }
3885        if (func1==ioctl_o)
3886        {
3887                if (func2==DriveReset) return (0);
3888                if (fam0L_drive)
3889                {
3890                        if (func2==EjectDisk) return (0);
3891                        if (func2==LockDoor) return (0);
3892          if (func2==CloseTray) return (0);
3893                }
3894                return (-1);
3895    }
3896        if (func1==flush_input) return (-1);
3897        if (func1==read_long) return (-1);
3898        if (func1==read_long_prefetch) return (-1);
3899        if (func1==seek) return (-1);
3900        if (func1==audio_play) return (-1);
3901        if (func1==audio_pause) return (-1);
3902        if (func1==audio_resume) return (-1);
3903#else
3904        return (0);
3905#endif
3906}
3907/*==========================================================================*/
3908static int seek_pos_audio_end(void)
3909{
3910        int i;
3911
3912        i=msf2blk(D_S[d].pos_audio_end)-1;
3913        if (i<0) return (-1);
3914        i=cc_Seek(i,0);
3915        return (i);
3916}
3917#endif /* FUTURE */ 
3918/*==========================================================================*/
3919static int ReadToC(void)
3920{
3921        int i, j;
3922        D_S[d].diskstate_flags &= ~toc_bit;
3923        D_S[d].ored_ctl_adr=0;
3924        /* special handling of CD-I HE */
3925        if ((D_S[d].n_first_track == 2 && D_S[d].n_last_track == 2) ||
3926             D_S[d].xa_byte == 0x10)
3927        {
3928                D_S[d].TocBuffer[1].nixbyte=0;
3929                D_S[d].TocBuffer[1].ctl_adr=0x40;
3930                D_S[d].TocBuffer[1].number=1;
3931                D_S[d].TocBuffer[1].format=0;
3932                D_S[d].TocBuffer[1].address=blk2msf(0);
3933                D_S[d].ored_ctl_adr |= 0x40;
3934                D_S[d].n_first_track = 1;
3935                D_S[d].n_last_track = 1;
3936                D_S[d].xa_byte = 0x10;
3937                j = 2;
3938        } else
3939        for (j=D_S[d].n_first_track;j<=D_S[d].n_last_track;j++)
3940        {
3941                i=cc_ReadTocEntry(j);
3942                if (i<0)
3943                {
3944                        msg(DBG_INF,"cc_ReadTocEntry(%d) returns %d.\n",j,i);
3945                        return (i);
3946                }
3947                D_S[d].TocBuffer[j].nixbyte=D_S[d].TocEnt_nixbyte;
3948                D_S[d].TocBuffer[j].ctl_adr=D_S[d].TocEnt_ctl_adr;
3949                D_S[d].TocBuffer[j].number=D_S[d].TocEnt_number;
3950                D_S[d].TocBuffer[j].format=D_S[d].TocEnt_format;
3951                D_S[d].TocBuffer[j].address=D_S[d].TocEnt_address;
3952                D_S[d].ored_ctl_adr |= D_S[d].TocEnt_ctl_adr;
3953        }
3954        /* fake entry for LeadOut Track */
3955        D_S[d].TocBuffer[j].nixbyte=0;
3956        D_S[d].TocBuffer[j].ctl_adr=0;
3957        D_S[d].TocBuffer[j].number=CDROM_LEADOUT;
3958        D_S[d].TocBuffer[j].format=0;
3959        D_S[d].TocBuffer[j].address=D_S[d].size_msf;
3960        
3961        D_S[d].diskstate_flags |= toc_bit;
3962        return (0);
3963}
3964/*==========================================================================*/
3965static int DiskInfo(void)
3966{
3967        int i, j;
3968        
3969        D_S[d].mode=READ_M1;
3970        
3971#undef LOOP_COUNT
3972#define LOOP_COUNT 10 /* needed for some "old" drives */
3973        
3974        msg(DBG_000,"DiskInfo entered.\n");
3975        for (j=1;j<LOOP_COUNT;j++)
3976        {
3977#if 0
3978                i=SetSpeed();
3979                if (i<0)
3980                {
3981                        msg(DBG_INF,"DiskInfo: SetSpeed returns %d\n", i);
3982                        continue;
3983                }
3984                i=cc_ModeSense();
3985                if (i<0)
3986                {
3987                        msg(DBG_INF,"DiskInfo: cc_ModeSense returns %d\n", i);
3988                        continue;
3989                }
3990#endif
3991                i=cc_ReadCapacity();
3992                if (i>=0) break;
3993                msg(DBG_INF,"DiskInfo: ReadCapacity #%d returns %d\n", j, i);
3994#if 0
3995                i=cc_DriveReset();
3996#endif
3997                if (!fam0_drive && j == 2) break;
3998        }
3999        if (j==LOOP_COUNT) return (-33); /* give up */
4000        
4001        i=cc_ReadTocDescr();
4002        if (i<0)
4003        {
4004                msg(DBG_INF,"DiskInfo: ReadTocDescr returns %d\n", i);
4005                return (i);
4006        }
4007        i=ReadToC();
4008        if (i<0)
4009        {
4010                msg(DBG_INF,"DiskInfo: ReadToC returns %d\n", i);
4011                return (i);
4012        }
4013        i=cc_CheckMultiSession();
4014        if (i<0)
4015        {
4016                msg(DBG_INF,"DiskInfo: cc_CheckMultiSession returns %d\n", i);
4017                return (i);
4018        }
4019        if (D_S[d].f_multisession) D_S[d].sbp_bufsiz=1;  /* possibly a weird PhotoCD */
4020        else D_S[d].sbp_bufsiz=buffers;
4021        i=cc_ReadTocEntry(D_S[d].n_first_track);
4022        if (i<0)
4023        {
4024                msg(DBG_INF,"DiskInfo: cc_ReadTocEntry(1) returns %d\n", i);
4025                return (i);
4026        }
4027        i=cc_ReadUPC();
4028        if (i<0) msg(DBG_INF,"DiskInfo: cc_ReadUPC returns %d\n", i);
4029        if ((fam0L_drive) && (D_S[d].xa_byte==0x20 || D_S[d].xa_byte == 0x10))
4030        {
4031                /* XA disk with old drive */
4032                cc_ModeSelect(CD_FRAMESIZE_RAW1);
4033                cc_ModeSense();
4034        }
4035        if (famT_drive) cc_prep_mode_T();
4036        msg(DBG_000,"DiskInfo done.\n");
4037        return (0);
4038}
4039
4040static int sbpcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
4041{
4042        int st;
4043
4044        if (CDSL_CURRENT != slot_nr) {
4045                 /* we have no changer support */
4046                 return -EINVAL;
4047        }
4048
4049        cc_ReadStatus();
4050        st=ResponseStatus();
4051        if (st<0)
4052        {
4053                msg(DBG_INF,"sbpcd_drive_status: timeout.\n");
4054                return (0);
4055        }
4056        msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked);
4057        msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed);
4058        msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in);
4059        msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok);
4060        msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
4061        msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
4062
4063#if 0
4064  if (!(D_S[MINOR(cdi->dev)].status_bits & p_door_closed)) return CDS_TRAY_OPEN;
4065  if (D_S[MINOR(cdi->dev)].status_bits & p_disk_ok) return CDS_DISC_OK;
4066  if (D_S[MINOR(cdi->dev)].status_bits & p_disk_in) return CDS_DRIVE_NOT_READY;
4067
4068  return CDS_NO_DISC;
4069#else
4070  if (D_S[MINOR(cdi->dev)].status_bits & p_spinning) return CDS_DISC_OK;
4071/*  return CDS_TRAY_OPEN; */
4072  return CDS_NO_DISC;
4073  
4074#endif
4075
4076}
4077
4078
4079/*==========================================================================*/
4080#if FUTURE
4081/*
4082 *  called always if driver gets entered
4083 *  returns 0 or ERROR2 or ERROR15
4084 */
4085static int prepare(u_char func, u_char subfunc)
4086{
4087        int i;
4088        
4089        if (fam0L_drive)
4090        {
4091                i=inb(CDi_status);
4092                if (i&s_attention) GetStatus();
4093        }
4094        else if (fam1_drive) GetStatus();
4095        else if (fam2_drive) GetStatus();
4096        else if (famT_drive) GetStatus();
4097        if (D_S[d].CD_changed==0xFF)
4098        {
4099                D_S[d].diskstate_flags=0;
4100                D_S[d].audio_state=0;
4101                if (!st_diskok)
4102                {
4103                        i=check_allowed1(func,subfunc);
4104                        if (i<0) return (-2);
4105                }
4106                else 
4107                {
4108                        i=check_allowed3(func,subfunc);
4109                        if (i<0)
4110                        {
4111                                D_S[d].CD_changed=1;
4112                                return (-15);
4113                        }
4114                }
4115        }
4116        else
4117        {
4118                if (!st_diskok)
4119                {
4120                        D_S[d].diskstate_flags=0;
4121                        D_S[d].audio_state=0;
4122                        i=check_allowed1(func,subfunc);
4123                        if (i<0) return (-2);
4124                }
4125                else
4126                { 
4127                        if (st_busy)
4128                        {
4129                                if (D_S[d].audio_state!=audio_pausing)
4130                                {
4131                                        i=check_allowed2(func,subfunc);
4132                                        if (i<0) return (-2);
4133                                }
4134                        }
4135                        else
4136                        {
4137                                if (D_S[d].audio_state==audio_playing) seek_pos_audio_end();
4138                                D_S[d].audio_state=0;
4139                        }
4140                        if (!frame_size_valid)
4141                        {
4142                                i=DiskInfo();
4143                                if (i<0)
4144                                {
4145                                        D_S[d].diskstate_flags=0;
4146                                        D_S[d].audio_state=0;
4147                                        i=check_allowed1(func,subfunc);
4148                                        if (i<0) return (-2);
4149                                }
4150                        }
4151                }
4152    }
4153        return (0);
4154}
4155#endif /* FUTURE */ 
4156/*==========================================================================*/
4157/*==========================================================================*/
4158/*
4159 * Check the results of the "get status" command.
4160 */
4161static int sbp_status(void)
4162{
4163        int st;
4164        
4165        st=ResponseStatus();
4166        if (st<0)
4167        {
4168                msg(DBG_INF,"sbp_status: timeout.\n");
4169                return (0);
4170        }
4171        
4172        if (!st_spinning) msg(DBG_SPI,"motor got off - ignoring.\n");
4173        
4174        if (st_check) 
4175        {
4176                msg(DBG_INF,"st_check detected - retrying.\n");
4177                return (0);
4178        }
4179        if (!st_door_closed)
4180        {
4181                msg(DBG_INF,"door is open - retrying.\n");
4182                return (0);
4183        }
4184        if (!st_caddy_in)
4185        {
4186                msg(DBG_INF,"disk removed - retrying.\n");
4187                return (0);
4188        }
4189        if (!st_diskok) 
4190        {
4191                msg(DBG_INF,"!st_diskok detected - retrying.\n");
4192                return (0);
4193        }
4194        if (st_busy) 
4195        {
4196                msg(DBG_INF,"st_busy detected - retrying.\n");
4197                return (0);
4198        }
4199        return (1);
4200}
4201/*==========================================================================*/
4202                
4203static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_multisession *ms_infp)
4204{
4205        ms_infp->addr_format = CDROM_LBA;
4206        ms_infp->addr.lba    = D_S[MINOR(cdi->dev)].lba_multi;
4207        if (D_S[MINOR(cdi->dev)].f_multisession)
4208                ms_infp->xa_flag=1; /* valid redirection address */
4209        else
4210                ms_infp->xa_flag=0; /* invalid redirection address */
4211
4212        return  0;
4213}
4214
4215/*==========================================================================*/
4216/*==========================================================================*/
4217/*
4218 * ioctl support
4219 */
4220static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
4221                      u_long arg)
4222{
4223        int i;
4224        
4225        msg(DBG_IO2,"ioctl(%d, 0x%08lX, 0x%08lX)\n",
4226            MINOR(cdi->dev), cmd, arg);
4227        i=MINOR(cdi->dev);
4228        if ((i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1))
4229        {
4230                msg(DBG_INF, "ioctl: bad device: %04X\n", cdi->dev);
4231                return (-ENXIO);             /* no such drive */
4232        }
4233        down(&ioctl_read_sem);
4234        if (d!=i) switch_drive(i);
4235        
4236        msg(DBG_IO2,"ioctl: device %d, request %04X\n",i,cmd);
4237        switch (cmd)            /* Sun-compatible */
4238        {
4239        case DDIOCSDBG:         /* DDI Debug */
4240                if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);
4241                i=sbpcd_dbg_ioctl(arg,1);
4242                RETURN_UP(i);
4243        case CDROMRESET:      /* hard reset the drive */
4244                msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");
4245                i=DriveReset();
4246                D_S[d].audio_state=0;
4247                RETURN_UP(i);
4248                
4249        case CDROMREADMODE1:
4250                msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
4251#if SAFE_MIXED
4252                if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
4253#endif /* SAFE_MIXED */
4254                cc_ModeSelect(CD_FRAMESIZE);
4255                cc_ModeSense();
4256                D_S[d].mode=READ_M1;
4257                RETURN_UP(0);
4258                
4259        case CDROMREADMODE2: /* not usable at the moment */
4260                msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
4261#if SAFE_MIXED
4262                if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
4263#endif /* SAFE_MIXED */
4264                cc_ModeSelect(CD_FRAMESIZE_RAW1);
4265                cc_ModeSense();
4266                D_S[d].mode=READ_M2;
4267                RETURN_UP(0);
4268                
4269        case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
4270                msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
4271                if (D_S[d].sbp_audsiz>0) vfree(D_S[d].aud_buf);
4272                D_S[d].aud_buf=NULL;
4273                D_S[d].sbp_audsiz=arg;
4274                
4275                if (D_S[d].sbp_audsiz>16)
4276                {
4277                        D_S[d].sbp_audsiz = 0;
4278                        RETURN_UP(D_S[d].sbp_audsiz);
4279                }
4280        
4281                if (D_S[d].sbp_audsiz>0)
4282                {
4283                        D_S[d].aud_buf=(u_char *) vmalloc(D_S[d].sbp_audsiz*CD_FRAMESIZE_RAW);
4284                        if (D_S[d].aud_buf==NULL)
4285                        {
4286                                msg(DBG_INF,"audio buffer (%d frames) not available.\n",D_S[d].sbp_audsiz);
4287                                D_S[d].sbp_audsiz=0;
4288                        }
4289                        else msg(DBG_INF,"audio buffer size: %d frames.\n",D_S[d].sbp_audsiz);
4290                }
4291                RETURN_UP(D_S[d].sbp_audsiz);
4292
4293        case CDROMREADAUDIO:
4294        { /* start of CDROMREADAUDIO */
4295                int i=0, j=0, frame, block=0;
4296                u_int try=0;
4297                u_long timeout;
4298                u_char *p;
4299                u_int data_tries = 0;
4300                u_int data_waits = 0;
4301                u_int data_retrying = 0;
4302                int status_tries;
4303                int error_flag;
4304                
4305                msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
4306                if (fam0_drive) RETURN_UP(-EINVAL);
4307                if (famL_drive) RETURN_UP(-EINVAL);
4308                if (famV_drive) RETURN_UP(-EINVAL);
4309                if (famT_drive) RETURN_UP(-EINVAL);
4310#if SAFE_MIXED
4311                if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
4312#endif /* SAFE_MIXED */ 
4313                if (D_S[d].aud_buf==NULL) RETURN_UP(-EINVAL);
4314                i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio));
4315                if (i) RETURN_UP(i);
4316                copy_from_user(&read_audio, (void *) arg, sizeof(struct cdrom_read_audio));
4317                if (read_audio.nframes < 0 || read_audio.nframes>D_S[d].sbp_audsiz) RETURN_UP(-EINVAL);
4318                i=verify_area(VERIFY_WRITE, read_audio.buf,
4319                              read_audio.nframes*CD_FRAMESIZE_RAW);
4320                if (i) RETURN_UP(i);
4321                
4322                if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
4323                        block=msf2lba(&read_audio.addr.msf.minute);
4324                else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
4325                        block=read_audio.addr.lba;
4326                else RETURN_UP(-EINVAL);
4327#if 000
4328                i=cc_SetSpeed(speed_150,0,0);
4329                if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
4330#endif
4331                msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
4332                    block, blk2msf(block));
4333                msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
4334#if OLD_BUSY
4335                while (busy_data) sbp_sleep(HZ/10); /* wait a bit */
4336                busy_audio=1;
4337#endif /* OLD_BUSY */ 
4338                error_flag=0;
4339                for (data_tries=5; data_tries>0; data_tries--)
4340                {
4341                        msg(DBG_AUD,"data_tries=%d ...\n", data_tries);
4342                        D_S[d].mode=READ_AU;
4343                        cc_ModeSelect(CD_FRAMESIZE_RAW);
4344                        cc_ModeSense();
4345                        for (status_tries=3; status_tries > 0; status_tries--)
4346                        {
4347                                flags_cmd_out |= f_respo3;
4348                                cc_ReadStatus();
4349                                if (sbp_status() != 0) break;
4350                                if (st_check) cc_ReadError();
4351                                sbp_sleep(1);    /* wait a bit, try again */
4352                        }
4353                        if (status_tries == 0)
4354                        {
4355                                msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__);
4356                                continue;
4357                        }
4358                        msg(DBG_AUD,"read_audio: sbp_status: ok.\n");
4359                        
4360                        flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
4361                        if (fam0L_drive)
4362                        {
4363                                flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
4364                                cmd_type=READ_M2;
4365                                drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
4366                                drvcmd[1]=(block>>16)&0x000000ff;
4367                                drvcmd[2]=(block>>8)&0x000000ff;
4368                                drvcmd[3]=block&0x000000ff;
4369                                drvcmd[4]=0;
4370                                drvcmd[5]=read_audio.nframes; /* # of frames */
4371                                drvcmd[6]=0;
4372                        }
4373                        else if (fam1_drive)
4374                        {
4375                                drvcmd[0]=CMD1_READ; /* "read frames", new drives */
4376                                lba2msf(block,&drvcmd[1]); /* msf-bin format required */
4377                                drvcmd[4]=0;
4378                                drvcmd[5]=0;
4379                                drvcmd[6]=read_audio.nframes; /* # of frames */
4380                        }
4381                        else if (fam2_drive)
4382                        {
4383                                drvcmd[0]=CMD2_READ_XA2;
4384                                lba2msf(block,&drvcmd[1]); /* msf-bin format required */
4385                                drvcmd[4]=0;
4386                                drvcmd[5]=read_audio.nframes; /* # of frames */
4387                                drvcmd[6]=0x11; /* raw mode */
4388                        }
4389                        else if (famT_drive) /* CD-55A: not tested yet */
4390                        {
4391                        }
4392                        msg(DBG_AUD,"read_audio: before giving \"read\" command.\n");
4393                        flags_cmd_out=f_putcmd;
4394                        response_count=0;
4395                        i=cmd_out();
4396                        if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i);
4397                        sbp_sleep(0);
4398                        msg(DBG_AUD,"read_audio: after giving \"read\" command.\n");
4399                        for (frame=1;frame<2 && !error_flag; frame++)
4400                        {
4401                                try=maxtim_data;
4402                                for (timeout=jiffies+9*HZ; ; )
4403                                {
4404                                        for ( ; try!=0;try--)
4405                                        {
4406                                                j=inb(CDi_status);
4407                                                if (!(j&s_not_data_ready)) break;
4408                                                if (!(j&s_not_result_ready)) break;
4409                                                if (fam0L_drive) if (j&s_attention) break;
4410                                        }
4411                                        if (try != 0 || time_after_eq(jiffies, timeout)) break;
4412                                        if (data_retrying == 0) data_waits++;
4413                                        data_retrying = 1;
4414                                        sbp_sleep(1);
4415                                        try = 1;
4416                                }
4417                                if (try==0)
4418                                {
4419                                        msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n");
4420                                        error_flag++;
4421                                        break;
4422                                }
4423                                msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n");
4424                                if (j&s_not_data_ready)
4425                                {
4426                                        msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n");
4427                                        error_flag++;
4428                                        break;
4429                                }
4430                                msg(DBG_AUD,"read_audio: before reading data.\n");
4431                                error_flag=0;
4432                                p = D_S[d].aud_buf;
4433                                if (sbpro_type==1) OUT(CDo_sel_i_d,1);
4434                                if (do_16bit)
4435                                {
4436                                        u_short *p2 = (u_short *) p;
4437
4438                                        for (; (u_char *) p2 < D_S[d].aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
4439                                        {
4440                                                if ((inb_p(CDi_status)&s_not_data_ready)) continue;
4441
4442                                                /* get one sample */
4443                                                *p2++ = inw_p(CDi_data);
4444                                                *p2++ = inw_p(CDi_data);
4445                                        }
4446                                } else {
4447                                        for (; p < D_S[d].aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
4448                                        {
4449                                                if ((inb_p(CDi_status)&s_not_data_ready)) continue;
4450
4451                                                /* get one sample */
4452                                                *p++ = inb_p(CDi_data);
4453                                                *p++ = inb_p(CDi_data);
4454                                                *p++ = inb_p(CDi_data);
4455                                                *p++ = inb_p(CDi_data);
4456                                        }
4457                                }
4458                                if (sbpro_type==1) OUT(CDo_sel_i_d,0);
4459                                data_retrying = 0;
4460                        }
4461                        msg(DBG_AUD,"read_audio: after reading data.\n");
4462                        if (error_flag)    /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
4463                        {
4464                                msg(DBG_AUD,"read_audio: read aborted by drive\n");
4465#if 0000
4466                                i=cc_DriveReset();                /* ugly fix to prevent a hang */
4467#else
4468                                i=cc_ReadError();
4469#endif
4470                                continue;
4471                        }
4472                        if (fam0L_drive)
4473                        {
4474                                i=maxtim_data;
4475                                for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--)
4476                                {
4477                                        for ( ;i!=0;i--)
4478                                        {
4479                                                j=inb(CDi_status);
4480                                                if (!(j&s_not_data_ready)) break;
4481                                                if (!(j&s_not_result_ready)) break;
4482                                                if (j&s_attention) break;
4483                                        }
4484                                        if (i != 0 || time_after_eq(jiffies, timeout)) break;
4485                                        sbp_sleep(0);
4486                                        i = 1;
4487                                }
4488                                if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ");
4489                                if (!(j&s_attention))
4490                                {
4491                                        msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n");
4492                                        i=cc_DriveReset();  /* ugly fix to prevent a hang */
4493                                        continue;
4494                                }
4495                        }
4496                        do
4497                        {
4498                                if (fam0L_drive) cc_ReadStatus();
4499                                i=ResponseStatus();  /* builds status_bits, returns orig. status (old) or faked p_success (new) */
4500                                if (i<0) { msg(DBG_AUD,
4501                                               "read_audio: cc_ReadStatus error after read: %02X\n",
4502                                               D_S[d].status_bits);
4503                                           continue; /* FIXME */
4504                                   }
4505                        }
4506                        while ((fam0L_drive)&&(!st_check)&&(!(i&p_success)));
4507                        if (st_check)
4508                        {
4509                                i=cc_ReadError();
4510                                msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i);
4511                                continue;
4512                        }
4513                        copy_to_user((u_char *) read_audio.buf,
4514                                    (u_char *) D_S[d].aud_buf,
4515                                    read_audio.nframes*CD_FRAMESIZE_RAW);
4516                        msg(DBG_AUD,"read_audio: copy_to_user done.\n");
4517                        break;
4518                }
4519                cc_ModeSelect(CD_FRAMESIZE);
4520                cc_ModeSense();
4521                D_S[d].mode=READ_M1;
4522#if OLD_BUSY
4523                busy_audio=0;
4524#endif /* OLD_BUSY */ 
4525                if (data_tries == 0)
4526                {
4527                        msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);
4528                        RETURN_UP(-EIO);
4529                }
4530                msg(DBG_AUD,"read_audio: successful return.\n");
4531                RETURN_UP(0);
4532        } /* end of CDROMREADAUDIO */
4533                
4534        case BLKRASET:
4535                if(!capable(CAP_SYS_ADMIN)) RETURN_UP(-EACCES);
4536                if(!(cdi->dev)) RETURN_UP(-EINVAL);
4537                if(arg > 0xff) RETURN_UP(-EINVAL);
4538                read_ahead[MAJOR(cdi->dev)] = arg;
4539                RETURN_UP(0);
4540        default:
4541                msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
4542                RETURN_UP(-EINVAL);
4543        } /* end switch(cmd) */
4544}
4545
4546static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
4547                       void * arg)
4548{
4549        int i, st, j;
4550        
4551        msg(DBG_IO2,"ioctl(%d, 0x%08lX, 0x%08p)\n",
4552            MINOR(cdi->dev), cmd, arg);
4553        i=MINOR(cdi->dev);
4554        if ((i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1))
4555        {
4556                msg(DBG_INF, "ioctl: bad device: %04X\n", cdi->dev);
4557                return (-ENXIO);             /* no such drive */
4558        }
4559        down(&ioctl_read_sem);
4560        if (d!=i) switch_drive(i);
4561        
4562        msg(DBG_IO2,"ioctl: device %d, request %04X\n",i,cmd);
4563        switch (cmd)            /* Sun-compatible */
4564        {
4565                
4566        case CDROMPAUSE:     /* Pause the drive */
4567                msg(DBG_IOC,"ioctl: CDROMPAUSE entered.\n");
4568                /* pause the drive unit when it is currently in PLAY mode,         */
4569                /* or reset the starting and ending locations when in PAUSED mode. */
4570                /* If applicable, at the next stopping point it reaches            */
4571                /* the drive will discontinue playing.                             */
4572                switch (D_S[d].audio_state)
4573                {
4574                case audio_playing:
4575                        if (famL_drive) i=cc_ReadSubQ();
4576                        else i=cc_Pause_Resume(1);
4577                        if (i<0) RETURN_UP(-EIO);
4578                        if (famL_drive) i=cc_Pause_Resume(1);
4579                        else i=cc_ReadSubQ();
4580                        if (i<0) RETURN_UP(-EIO);
4581                        D_S[d].pos_audio_start=D_S[d].SubQ_run_tot;
4582                        D_S[d].audio_state=audio_pausing;
4583                        RETURN_UP(0);
4584                case audio_pausing:
4585                        i=cc_Seek(D_S[d].pos_audio_start,1);
4586                        if (i<0) RETURN_UP(-EIO);
4587                        RETURN_UP(0);
4588                default:
4589                        RETURN_UP(-EINVAL);
4590                }
4591                
4592        case CDROMRESUME: /* resume paused audio play */
4593                msg(DBG_IOC,"ioctl: CDROMRESUME entered.\n");
4594                /* resume playing audio tracks when a previous PLAY AUDIO call has  */
4595                /* been paused with a PAUSE command.                                */
4596                /* It will resume playing from the location saved in SubQ_run_tot.  */
4597                if (D_S[d].audio_state!=audio_pausing) RETURN_UP(-EINVAL);
4598                if (famL_drive)
4599                        i=cc_PlayAudio(D_S[d].pos_audio_start,
4600                                       D_S[d].pos_audio_end);
4601                else i=cc_Pause_Resume(3);
4602                if (i<0) RETURN_UP(-EIO);
4603                D_S[d].audio_state=audio_playing;
4604                RETURN_UP(0);
4605                
4606        case CDROMPLAYMSF:
4607                msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n");
4608#if SAFE_MIXED
4609                if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
4610#endif /* SAFE_MIXED */ 
4611                if (D_S[d].audio_state==audio_playing)
4612                {
4613                        i=cc_Pause_Resume(1);
4614                        if (i<0) RETURN_UP(-EIO);
4615                        i=cc_ReadSubQ();
4616                        if (i<0) RETURN_UP(-EIO);
4617                        D_S[d].pos_audio_start=D_S[d].SubQ_run_tot;
4618                        i=cc_Seek(D_S[d].pos_audio_start,1);
4619                }
4620                memcpy(&msf, (void *) arg, sizeof(struct cdrom_msf));
4621                /* values come as msf-bin */
4622                D_S[d].pos_audio_start = (msf.cdmsf_min0<<16) |
4623                        (msf.cdmsf_sec0<<8) |
4624                                msf.cdmsf_frame0;
4625                D_S[d].pos_audio_end = (msf.cdmsf_min1<<16) |
4626                        (msf.cdmsf_sec1<<8) |
4627                                msf.cdmsf_frame1;
4628                msg(DBG_IOX,"ioctl: CDROMPLAYMSF %08X %08X\n",
4629                    D_S[d].pos_audio_start,D_S[d].pos_audio_end);
4630                i=cc_PlayAudio(D_S[d].pos_audio_start,D_S[d].pos_audio_end);
4631                if (i<0)
4632                {
4633                        msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
4634                        DriveReset();
4635                        D_S[d].audio_state=0;
4636                        RETURN_UP(-EIO);
4637                }
4638                D_S[d].audio_state=audio_playing;
4639                RETURN_UP(0);
4640                
4641        case CDROMPLAYTRKIND: /* Play a track.  This currently ignores index. */
4642                msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n");
4643#if SAFE_MIXED
4644                if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
4645#endif /* SAFE_MIXED */ 
4646                if (D_S[d].audio_state==audio_playing)
4647                {
4648                        msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n");
4649#if 1
4650                        RETURN_UP(0); /* just let us play on */
4651#else
4652                        RETURN_UP(-EINVAL); /* play on, but say "error" */
4653#endif
4654                }
4655                memcpy(&ti,(void *) arg,sizeof(struct cdrom_ti));
4656                msg(DBG_IOX,"ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n",
4657                    ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1);
4658                if (ti.cdti_trk0<D_S[d].n_first_track) RETURN_UP(-EINVAL);
4659                if (ti.cdti_trk0>D_S[d].n_last_track) RETURN_UP(-EINVAL);
4660                if (ti.cdti_trk1<ti.cdti_trk0) ti.cdti_trk1=ti.cdti_trk0;
4661                if (ti.cdti_trk1>D_S[d].n_last_track) ti.cdti_trk1=D_S[d].n_last_track;
4662                D_S[d].pos_audio_start=D_S[d].TocBuffer[ti.cdti_trk0].address;
4663                D_S[d].pos_audio_end=D_S[d].TocBuffer[ti.cdti_trk1+1].address;
4664                i=cc_PlayAudio(D_S[d].pos_audio_start,D_S[d].pos_audio_end);
4665                if (i<0)
4666                {
4667                        msg(DBG_INF,"ioctl: cc_PlayAudio returns %d\n",i);
4668                        DriveReset();
4669                        D_S[d].audio_state=0;
4670                        RETURN_UP(-EIO);
4671                }
4672                D_S[d].audio_state=audio_playing;
4673                RETURN_UP(0);
4674                
4675        case CDROMREADTOCHDR:        /* Read the table of contents header */
4676                msg(DBG_IOC,"ioctl: CDROMREADTOCHDR entered.\n");
4677                tochdr.cdth_trk0=D_S[d].n_first_track;
4678                tochdr.cdth_trk1=D_S[d].n_last_track;
4679                memcpy((void *) arg, &tochdr, sizeof(struct cdrom_tochdr));
4680                RETURN_UP(0);
4681                
4682        case CDROMREADTOCENTRY:      /* Read an entry in the table of contents */
4683                msg(DBG_IOC,"ioctl: CDROMREADTOCENTRY entered.\n");
4684                memcpy(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry));
4685                i=tocentry.cdte_track;
4686                if (i==CDROM_LEADOUT) i=D_S[d].n_last_track+1;
4687                else if (i<D_S[d].n_first_track||i>D_S[d].n_last_track)
4688                  RETURN_UP(-EINVAL);
4689                tocentry.cdte_adr=D_S[d].TocBuffer[i].ctl_adr&0x0F;
4690                tocentry.cdte_ctrl=(D_S[d].TocBuffer[i].ctl_adr>>4)&0x0F;
4691                tocentry.cdte_datamode=D_S[d].TocBuffer[i].format;
4692                if (tocentry.cdte_format==CDROM_MSF) /* MSF-bin required */
4693                {
4694                        tocentry.cdte_addr.msf.minute=(D_S[d].TocBuffer[i].address>>16)&0x00FF;
4695                        tocentry.cdte_addr.msf.second=(D_S[d].TocBuffer[i].address>>8)&0x00FF;
4696                        tocentry.cdte_addr.msf.frame=D_S[d].TocBuffer[i].address&0x00FF;
4697                }
4698                else if (tocentry.cdte_format==CDROM_LBA) /* blk required */
4699                        tocentry.cdte_addr.lba=msf2blk(D_S[d].TocBuffer[i].address);
4700                else RETURN_UP(-EINVAL);
4701                memcpy((void *) arg, &tocentry, sizeof(struct cdrom_tocentry));
4702                RETURN_UP(0);
4703                
4704        case CDROMSTOP:      /* Spin down the drive */
4705                msg(DBG_IOC,"ioctl: CDROMSTOP entered.\n");
4706#if SAFE_MIXED
4707                if (D_S[d].has_data>1) RETURN_UP(-EBUSY);
4708#endif /* SAFE_MIXED */ 
4709                i=cc_Pause_Resume(1);
4710                D_S[d].audio_state=0;
4711#if 0
4712                cc_DriveReset();
4713#endif
4714                RETURN_UP(i);
4715                
4716        case CDROMSTART:  /* Spin up the drive */
4717                msg(DBG_IOC,"ioctl: CDROMSTART entered.\n");
4718                cc_SpinUp();
4719                D_S[d].audio_state=0;
4720                RETURN_UP(0);
4721                
4722        case CDROMVOLCTRL:   /* Volume control */
4723                msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n");
4724                memcpy(&volctrl,(char *) arg,sizeof(volctrl));
4725                D_S[d].vol_chan0=0;
4726                D_S[d].vol_ctrl0=volctrl.channel0;
4727                D_S[d].vol_chan1=1;
4728                D_S[d].vol_ctrl1=volctrl.channel1;
4729                i=cc_SetVolume();
4730                RETURN_UP(0);
4731                
4732        case CDROMVOLREAD:   /* read Volume settings from drive */
4733                msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n");
4734                st=cc_GetVolume();
4735                if (st<0) RETURN_UP(st);
4736                volctrl.channel0=D_S[d].vol_ctrl0;
4737                volctrl.channel1=D_S[d].vol_ctrl1;
4738                volctrl.channel2=0;
4739                volctrl.channel2=0;
4740                memcpy((void *)arg,&volctrl,sizeof(volctrl));
4741                RETURN_UP(0);
4742
4743        case CDROMSUBCHNL:   /* Get subchannel info */
4744                msg(DBG_IOS,"ioctl: CDROMSUBCHNL entered.\n");
4745                /* Bogus, I can do better than this! --AJK
4746                if ((st_spinning)||(!subq_valid)) {
4747                        i=cc_ReadSubQ();
4748                        if (i<0) RETURN_UP(-EIO);
4749                }
4750                */
4751                i=cc_ReadSubQ();
4752                if (i<0) {
4753                        j=cc_ReadError(); /* clear out error status from drive */
4754                        D_S[d].audio_state=CDROM_AUDIO_NO_STATUS;
4755                        /* get and set the disk state here, 
4756                        probably not the right place, but who cares!
4757                        It makes it work properly! --AJK */
4758                        if (D_S[d].CD_changed==0xFF) {
4759                                msg(DBG_000,"Disk changed detect\n");
4760                                D_S[d].diskstate_flags &= ~cd_size_bit;
4761                        }
4762                        RETURN_UP(-EIO);
4763                }
4764                if (D_S[d].CD_changed==0xFF) {
4765                        /* reread the TOC because the disk has changed! --AJK */
4766                        msg(DBG_000,"Disk changed STILL detected, rereading TOC!\n");
4767                        i=DiskInfo();
4768                        if(i==0) {
4769                                D_S[d].CD_changed=0x00; /* cd has changed, procede, */
4770                                RETURN_UP(-EIO); /* and get TOC, etc on next try! --AJK */
4771                        } else {
4772                                RETURN_UP(-EIO); /* we weren't ready yet! --AJK */
4773                        }
4774                }
4775                memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
4776                /* 
4777                        This virtual crap is very bogus! 
4778                        It doesn't detect when the cd is done playing audio!
4779                        Lets do this right with proper hardware register reading!
4780                */
4781                cc_ReadStatus();
4782                i=ResponseStatus();
4783                msg(DBG_000,"Drive Status: door_locked =%d.\n", st_door_locked);
4784                msg(DBG_000,"Drive Status: door_closed =%d.\n", st_door_closed);
4785                msg(DBG_000,"Drive Status: caddy_in =%d.\n", st_caddy_in);
4786                msg(DBG_000,"Drive Status: disk_ok =%d.\n", st_diskok);
4787                msg(DBG_000,"Drive Status: spinning =%d.\n", st_spinning);
4788                msg(DBG_000,"Drive Status: busy =%d.\n", st_busy);
4789                /* st_busy indicates if it's _ACTUALLY_ playing audio */
4790                switch (D_S[d].audio_state)
4791                {
4792                case audio_playing:
4793                        if(st_busy==0) {
4794                                /* CD has stopped playing audio --AJK */
4795                                D_S[d].audio_state=audio_completed;
4796                                SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
4797                        } else {
4798                                SC.cdsc_audiostatus=CDROM_AUDIO_PLAY;
4799                        }
4800                        break;
4801                case audio_pausing:
4802                        SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED;
4803                        break;
4804                case audio_completed:
4805                        SC.cdsc_audiostatus=CDROM_AUDIO_COMPLETED;
4806                        break;
4807                default:
4808                        SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS;
4809                        break;
4810                }
4811                SC.cdsc_adr=D_S[d].SubQ_ctl_adr;
4812                SC.cdsc_ctrl=D_S[d].SubQ_ctl_adr>>4;
4813                SC.cdsc_trk=bcd2bin(D_S[d].SubQ_trk);
4814                SC.cdsc_ind=bcd2bin(D_S[d].SubQ_pnt_idx);
4815                if (SC.cdsc_format==CDROM_LBA)
4816                {
4817                        SC.cdsc_absaddr.lba=msf2blk(D_S[d].SubQ_run_tot);
4818                        SC.cdsc_reladdr.lba=msf2blk(D_S[d].SubQ_run_trk);
4819                }
4820                else /* not only if (SC.cdsc_format==CDROM_MSF) */
4821                {
4822                        SC.cdsc_absaddr.msf.minute=(D_S[d].SubQ_run_tot>>16)&0x00FF;
4823                        SC.cdsc_absaddr.msf.second=(D_S[d].SubQ_run_tot>>8)&0x00FF;
4824                        SC.cdsc_absaddr.msf.frame=D_S[d].SubQ_run_tot&0x00FF;
4825                        SC.cdsc_reladdr.msf.minute=(D_S[d].SubQ_run_trk>>16)&0x00FF;
4826                        SC.cdsc_reladdr.msf.second=(D_S[d].SubQ_run_trk>>8)&0x00FF;
4827                        SC.cdsc_reladdr.msf.frame=D_S[d].SubQ_run_trk&0x00FF;
4828                }
4829                memcpy((void *) arg, &SC, sizeof(struct cdrom_subchnl));
4830                msg(DBG_IOS,"CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
4831                    SC.cdsc_format,SC.cdsc_audiostatus,
4832                    SC.cdsc_adr,SC.cdsc_ctrl,
4833                    SC.cdsc_trk,SC.cdsc_ind,
4834                    SC.cdsc_absaddr,SC.cdsc_reladdr);
4835                RETURN_UP(0);
4836                
4837        default:
4838                msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
4839                RETURN_UP(-EINVAL);
4840        } /* end switch(cmd) */
4841}
4842/*==========================================================================*/
4843/*
4844 *  Take care of the different block sizes between cdrom and Linux.
4845 */
4846static void sbp_transfer(struct request *req)
4847{
4848        long offs;
4849        
4850        while ( (req->nr_sectors > 0) &&
4851               (req->sector/4 >= D_S[d].sbp_first_frame) &&
4852               (req->sector/4 <= D_S[d].sbp_last_frame) )
4853        {
4854                offs = (req->sector - D_S[d].sbp_first_frame * 4) * 512;
4855                memcpy(req->buffer, D_S[d].sbp_buf + offs, 512);
4856                req->nr_sectors--;
4857                req->sector++;
4858                req->buffer += 512;
4859        }
4860}
4861/*==========================================================================*/
4862/*
4863 *  special end_request for sbpcd to solve CURRENT==NULL bug. (GTL)
4864 *  GTL = Gonzalo Tornaria <tornaria@cmat.edu.uy>
4865 *
4866 *  This is a kludge so we don't need to modify end_request.
4867 *  We put the req we take out after INIT_REQUEST in the requests list,
4868 *  so that end_request will discard it. 
4869 *
4870 *  The bug could be present in other block devices, perhaps we
4871 *  should modify INIT_REQUEST and end_request instead, and
4872 *  change every block device.. 
4873 *
4874 *  Could be a race here?? Could e.g. a timer interrupt schedule() us?
4875 *  If so, we should copy end_request here, and do it right.. (or
4876 *  modify end_request and the block devices).
4877 *
4878 *  In any case, the race here would be much small than it was, and
4879 *  I couldn't reproduce..
4880 *
4881 *  The race could be: suppose CURRENT==NULL. We put our req in the list,
4882 *  and we are scheduled. Other process takes over, and gets into
4883 *  do_sbpcd_request. It sees CURRENT!=NULL (it is == to our req), so
4884 *  proceeds. It ends, so CURRENT is now NULL.. Now we awake somewhere in
4885 *  end_request, but now CURRENT==NULL... oops!
4886 *
4887 */
4888#undef DEBUG_GTL
4889static inline void sbpcd_end_request(struct request *req, int uptodate) {
4890        list_add(&req->queue, &req->q->queue_head);
4891        end_request(uptodate);
4892}
4893/*==========================================================================*/
4894/*
4895 *  I/O request routine, called from Linux kernel.
4896 */
4897static void DO_SBPCD_REQUEST(request_queue_t * q)
4898{
4899        u_int block;
4900        u_int nsect;
4901        int i, status_tries, data_tries;
4902        struct request *req;
4903#ifdef DEBUG_GTL
4904        static int xx_nr=0;
4905        int xnr;
4906#endif
4907
4908 request_loop:
4909#ifdef DEBUG_GTL
4910        xnr=++xx_nr;
4911
4912        if(QUEUE_EMPTY)
4913        {
4914                printk( "do_sbpcd_request[%di](NULL), Pid:%d, Time:%li\n",
4915                        xnr, current->pid, jiffies);
4916                printk( "do_sbpcd_request[%do](NULL) end 0 (null), Time:%li\n",
4917                        xnr, jiffies);
4918                CLEAR_INTR;
4919                return;
4920        }
4921
4922        printk(" do_sbpcd_request[%di](%p:%ld+%ld), Pid:%d, Time:%li\n",
4923                xnr, CURRENT, CURRENT->sector, CURRENT->nr_sectors, current->pid, jiffies);
4924#endif
4925        INIT_REQUEST;
4926        req=CURRENT;            /* take out our request so no other */
4927        blkdev_dequeue_request(req);    /* task can fuck it up         GTL  */
4928        
4929        if (req->rq_status == RQ_INACTIVE)
4930                sbpcd_end_request(req, 0);
4931        if (req -> sector == -1)
4932                sbpcd_end_request(req, 0);
4933        spin_unlock_irq(&io_request_lock);
4934
4935        down(&ioctl_read_sem);
4936        if (req->cmd != READ)
4937        {
4938                msg(DBG_INF, "bad cmd %d\n", req->cmd);
4939                goto err_done;
4940        }
4941        i = MINOR(req->rq_dev);
4942        if ( (i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1))
4943        {
4944                msg(DBG_INF, "do_request: bad device: %s\n",
4945                        kdevname(req->rq_dev));
4946                goto err_done;
4947        }
4948#if OLD_BUSY
4949        while (busy_audio) sbp_sleep(HZ); /* wait a bit */
4950        busy_data=1;
4951#endif /* OLD_BUSY */
4952        
4953        if (D_S[i].audio_state==audio_playing) goto err_done;
4954        if (d!=i) switch_drive(i);
4955        
4956        block = req->sector; /* always numbered as 512-byte-pieces */
4957        nsect = req->nr_sectors; /* always counted as 512-byte-pieces */
4958        
4959        msg(DBG_BSZ,"read sector %d (%d sectors)\n", block, nsect);
4960#if 0
4961        msg(DBG_MUL,"read LBA %d\n", block/4);
4962#endif
4963        
4964        sbp_transfer(req);
4965        /* if we satisfied the request from the buffer, we're done. */
4966        if (req->nr_sectors == 0)
4967        {
4968#ifdef DEBUG_GTL
4969                printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 2, Time:%li\n",
4970                        xnr, req, req->sector, req->nr_sectors, jiffies);
4971#endif
4972                up(&ioctl_read_sem);
4973                spin_lock_irq(&io_request_lock);
4974                sbpcd_end_request(req, 1);
4975                goto request_loop;
4976        }
4977
4978#if FUTURE
4979        i=prepare(0,0); /* at moment not really a hassle check, but ... */
4980        if (i!=0)
4981                msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i);
4982#endif /* FUTURE */ 
4983        
4984        if (!st_spinning) cc_SpinUp();
4985        
4986        for (data_tries=n_retries; data_tries > 0; data_tries--)
4987        {
4988                for (status_tries=3; status_tries > 0; status_tries--)
4989                {
4990                        flags_cmd_out |= f_respo3;
4991                        cc_ReadStatus();
4992                        if (sbp_status() != 0) break;
4993                        if (st_check) cc_ReadError();
4994                        sbp_sleep(1);    /* wait a bit, try again */
4995                }
4996                if (status_tries == 0)
4997                {
4998                        msg(DBG_INF,"sbp_status: failed after 3 tries in line %d\n", __LINE__);
4999                        break;
5000                }
5001                
5002                sbp_read_cmd(req);
5003                sbp_sleep(0);
5004                if (sbp_data(req) != 0)
5005                {
5006#if SAFE_MIXED
5007                        D_S[d].has_data=2; /* is really a data disk */
5008#endif /* SAFE_MIXED */ 
5009#ifdef DEBUG_GTL
5010                        printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n",
5011                                xnr, req, req->sector, req->nr_sectors, jiffies);
5012#endif
5013                        up(&ioctl_read_sem);
5014                        spin_lock_irq(&io_request_lock);
5015                        sbpcd_end_request(req, 1);
5016                        goto request_loop;
5017                }
5018        }
5019        
5020 err_done:
5021#if OLD_BUSY
5022        busy_data=0;
5023#endif /* OLD_BUSY */
5024#ifdef DEBUG_GTL
5025        printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 4 (error), Time:%li\n",
5026                xnr, req, req->sector, req->nr_sectors, jiffies);
5027#endif
5028        up(&ioctl_read_sem);
5029        sbp_sleep(0);    /* wait a bit, try again */
5030        spin_lock_irq(&io_request_lock);
5031        sbpcd_end_request(req, 0);
5032        goto request_loop;
5033}
5034/*==========================================================================*/
5035/*
5036 *  build and send the READ command.
5037 */
5038static void sbp_read_cmd(struct request *req)
5039{
5040#undef OLD
5041
5042        int i;
5043        int block;
5044        
5045        D_S[d].sbp_first_frame=D_S[d].sbp_last_frame=-1;      /* purge buffer */
5046        D_S[d].sbp_current = 0;
5047        block=req->sector/4;
5048        if (block+D_S[d].sbp_bufsiz <= D_S[d].CDsize_frm)
5049                D_S[d].sbp_read_frames = D_S[d].sbp_bufsiz;
5050        else
5051        {
5052                D_S[d].sbp_read_frames=D_S[d].CDsize_frm-block;
5053                /* avoid reading past end of data */
5054                if (D_S[d].sbp_read_frames < 1)
5055                {
5056                        msg(DBG_INF,"requested frame %d, CD size %d ???\n",
5057                            block, D_S[d].CDsize_frm);
5058                        D_S[d].sbp_read_frames=1;
5059                }
5060        }
5061        
5062        flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
5063        clr_cmdbuf();
5064        if (famV_drive)
5065          {
5066            drvcmd[0]=CMDV_READ;
5067            lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
5068            bin2bcdx(&drvcmd[1]);
5069            bin2bcdx(&drvcmd[2]);
5070            bin2bcdx(&drvcmd[3]);
5071            drvcmd[4]=D_S[d].sbp_read_frames>>8;
5072            drvcmd[5]=D_S[d].sbp_read_frames&0xff;
5073            drvcmd[6]=0x02; /* flag "msf-bcd" */
5074        }
5075        else if (fam0L_drive)
5076        {
5077                flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
5078                if (D_S[d].xa_byte==0x20)
5079                {
5080                        cmd_type=READ_M2;
5081                        drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
5082                        drvcmd[1]=(block>>16)&0x0ff;
5083                        drvcmd[2]=(block>>8)&0x0ff;
5084                        drvcmd[3]=block&0x0ff;
5085                        drvcmd[4]=(D_S[d].sbp_read_frames>>8)&0x0ff;
5086                        drvcmd[5]=D_S[d].sbp_read_frames&0x0ff;
5087                }
5088                else
5089                {
5090                        drvcmd[0]=CMD0_READ; /* "read frames", old drives */
5091                        if (D_S[d].drv_type>=drv_201)
5092                        {
5093                                lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
5094                                bin2bcdx(&drvcmd[1]);
5095                                bin2bcdx(&drvcmd[2]);
5096                                bin2bcdx(&drvcmd[3]);
5097                        }
5098                        else
5099                        {
5100                                drvcmd[1]=(block>>16)&0x0ff;
5101                                drvcmd[2]=(block>>8)&0x0ff;
5102                                drvcmd[3]=block&0x0ff;
5103                        }
5104                        drvcmd[4]=(D_S[d].sbp_read_frames>>8)&0x0ff;
5105                        drvcmd[5]=D_S[d].sbp_read_frames&0x0ff;
5106                        drvcmd[6]=(D_S[d].drv_type<drv_201)?0:2; /* flag "lba or msf-bcd format" */
5107                }
5108        }
5109        else if (fam1_drive)
5110        {
5111                drvcmd[0]=CMD1_READ;
5112                lba2msf(block,&drvcmd[1]); /* msf-bin format required */
5113                drvcmd[5]=(D_S[d].sbp_read_frames>>8)&0x0ff;
5114                drvcmd[6]=D_S[d].sbp_read_frames&0x0ff;
5115        }
5116        else if (fam2_drive)
5117        {
5118                drvcmd[0]=CMD2_READ;
5119                lba2msf(block,&drvcmd[1]); /* msf-bin format required */
5120                drvcmd[4]=(D_S[d].sbp_read_frames>>8)&0x0ff;
5121                drvcmd[5]=D_S[d].sbp_read_frames&0x0ff;
5122                drvcmd[6]=0x02;
5123        }
5124        else if (famT_drive)
5125        {
5126                drvcmd[0]=CMDT_READ;
5127                drvcmd[2]=(block>>24)&0x0ff;
5128                drvcmd[3]=(block>>16)&0x0ff;
5129                drvcmd[4]=(block>>8)&0x0ff;
5130                drvcmd[5]=block&0x0ff;
5131                drvcmd[7]=(D_S[d].sbp_read_frames>>8)&0x0ff;
5132                drvcmd[8]=D_S[d].sbp_read_frames&0x0ff;
5133        }
5134        flags_cmd_out=f_putcmd;
5135        response_count=0;
5136        i=cmd_out();
5137        if (i<0) msg(DBG_INF,"error giving READ command: %0d\n", i);
5138        return;
5139}
5140/*==========================================================================*/
5141/*
5142 *  Check the completion of the read-data command.  On success, read
5143 *  the D_S[d].sbp_bufsiz * 2048 bytes of data from the disk into buffer.
5144 */
5145static int sbp_data(struct request *req)
5146{
5147        int i=0, j=0, l, frame;
5148        u_int try=0;
5149        u_long timeout;
5150        u_char *p;
5151        u_int data_tries = 0;
5152        u_int data_waits = 0;
5153        u_int data_retrying = 0;
5154        int error_flag;
5155        int xa_count;
5156        int max_latency;
5157        int success;
5158        int wait;
5159        int duration;
5160        
5161        error_flag=0;
5162        success=0;
5163#if LONG_TIMING
5164        max_latency=9*HZ;
5165#else
5166        if (D_S[d].f_multisession) max_latency=15*HZ;
5167        else max_latency=5*HZ;
5168#endif
5169        duration=jiffies;
5170        for (frame=0;frame<D_S[d].sbp_read_frames&&!error_flag; frame++)
5171        {
5172                SBPCD_CLI;
5173                
5174                del_timer(&data_timer);
5175                data_timer.expires=jiffies+max_latency;
5176                timed_out_data=0;
5177                add_timer(&data_timer);
5178                while (!timed_out_data) 
5179                {
5180                        if (D_S[d].f_multisession) try=maxtim_data*4;
5181                        else try=maxtim_data;
5182                        msg(DBG_000,"sbp_data: CDi_status loop: try=%d.\n",try);
5183                        for ( ; try!=0;try--)
5184                        {
5185                                j=inb(CDi_status);
5186                                if (!(j&s_not_data_ready)) break;;
5187                                if (!(j&s_not_result_ready)) break;
5188                                if (fam0LV_drive) if (j&s_attention) break;
5189                        }
5190                        if (!(j&s_not_data_ready)) goto data_ready;
5191                        if (try==0)
5192                        {
5193                                if (data_retrying == 0) data_waits++;
5194                                data_retrying = 1;
5195                                msg(DBG_000,"sbp_data: CDi_status loop: sleeping.\n");
5196                                sbp_sleep(1);
5197                                try = 1;
5198                        }
5199                }
5200                msg(DBG_INF,"sbp_data: CDi_status loop expired.\n");
5201        data_ready:
5202                del_timer(&data_timer);
5203
5204                if (timed_out_data)
5205                {
5206                        msg(DBG_INF,"sbp_data: CDi_status timeout (timed_out_data) (%02X).\n", j);
5207                        error_flag++;
5208                }
5209                if (try==0)
5210                {
5211                        msg(DBG_INF,"sbp_data: CDi_status timeout (try=0) (%02X).\n", j);
5212                        error_flag++;
5213                }
5214                if (!(j&s_not_result_ready))
5215                {
5216                        msg(DBG_INF, "sbp_data: RESULT_READY where DATA_READY awaited (%02X).\n", j);
5217                        response_count=20;
5218                        j=ResponseInfo();
5219                        j=inb(CDi_status);
5220                }
5221                if (j&s_not_data_ready)
5222                {
5223                        if ((D_S[d].ored_ctl_adr&0x40)==0)
5224                                msg(DBG_INF, "CD contains no data tracks.\n");
5225                        else msg(DBG_INF, "sbp_data: DATA_READY timeout (%02X).\n", j);
5226                        error_flag++;
5227                }
5228                SBPCD_STI;
5229                if (error_flag) break;
5230
5231                msg(DBG_000, "sbp_data: beginning to read.\n");
5232                p = D_S[d].sbp_buf + frame *  CD_FRAMESIZE;
5233                if (sbpro_type==1) OUT(CDo_sel_i_d,1);
5234                if (cmd_type==READ_M2) {
5235                        if (do_16bit) insw(CDi_data, xa_head_buf, CD_XA_HEAD>>1);
5236                        else insb(CDi_data, xa_head_buf, CD_XA_HEAD);
5237                }
5238                if (do_16bit) insw(CDi_data, p, CD_FRAMESIZE>>1);
5239                else insb(CDi_data, p, CD_FRAMESIZE);
5240                if (cmd_type==READ_M2) {
5241                        if (do_16bit) insw(CDi_data, xa_tail_buf, CD_XA_TAIL>>1);
5242                        else insb(CDi_data, xa_tail_buf, CD_XA_TAIL);
5243                }
5244                D_S[d].sbp_current++;
5245                if (sbpro_type==1) OUT(CDo_sel_i_d,0);
5246                if (cmd_type==READ_M2)
5247                {
5248                        for (xa_count=0;xa_count<CD_XA_HEAD;xa_count++)
5249                                sprintf(&msgbuf[xa_count*3], " %02X", xa_head_buf[xa_count]);
5250                        msgbuf[xa_count*3]=0;
5251                        msg(DBG_XA1,"xa head:%s\n", msgbuf);
5252                }
5253                data_retrying = 0;
5254                data_tries++;
5255                if (data_tries >= 1000)
5256                {
5257                        msg(DBG_INF,"sbp_data() statistics: %d waits in %d frames.\n", data_waits, data_tries);
5258                        data_waits = data_tries = 0;
5259                }
5260        }
5261        duration=jiffies-duration;
5262        msg(DBG_TEA,"time to read %d frames: %d jiffies .\n",frame,duration);
5263        if (famT_drive)
5264        {
5265                wait=8;
5266                do
5267                {
5268                        if (teac==2)
5269                          {
5270                            if ((i=CDi_stat_loop_T()) == -1) break;
5271                          }
5272                        else
5273                          {
5274                            sbp_sleep(1);
5275                            OUT(CDo_sel_i_d,0); 
5276                            i=inb(CDi_status);
5277                          } 
5278                        if (!(i&s_not_data_ready))
5279                        {
5280                                OUT(CDo_sel_i_d,1);
5281                                j=0;
5282                                do
5283                                {
5284                                        if (do_16bit) i=inw(CDi_data);
5285                                        else i=inb(CDi_data);
5286                                        j++;
5287                                        i=inb(CDi_status);
5288                                }
5289                                while (!(i&s_not_data_ready));
5290                                msg(DBG_TEA, "==========too much data (%d bytes/words)==============.\n", j);
5291                        }
5292                        if (!(i&s_not_result_ready))
5293                        {
5294                                OUT(CDo_sel_i_d,0);
5295                                l=0;
5296                                do
5297                                {
5298                                        infobuf[l++]=inb(CDi_info);
5299                                        i=inb(CDi_status);
5300                                }
5301                                while (!(i&s_not_result_ready));
5302                                if (infobuf[0]==0x00) success=1;
5303#if 1
5304                                for (j=0;j<l;j++) sprintf(&msgbuf[j*3], " %02X", infobuf[j]);
5305                                msgbuf[j*3]=0;
5306                                msg(DBG_TEA,"sbp_data info response:%s\n", msgbuf);
5307#endif
5308                                if (infobuf[0]==0x02)
5309                                {
5310                                        error_flag++;
5311                                        do
5312                                        {
5313                                                ++recursion;
5314                                                if (recursion>1) msg(DBG_TEA,"cmd_out_T READ_ERR recursion (sbp_data): %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",recursion);
5315                                                else msg(DBG_TEA,"sbp_data: CMDT_READ_ERR necessary.\n");
5316                                                clr_cmdbuf();
5317                                                drvcmd[0]=CMDT_READ_ERR;
5318                                                j=cmd_out_T(); /* !!! recursive here !!! */
5319                                                --recursion;
5320                                                sbp_sleep(1);
5321                                        }
5322                                        while (j<0);
5323                                        D_S[d].error_state=infobuf[2];
5324                                        D_S[d].b3=infobuf[3];
5325                                        D_S[d].b4=infobuf[4];
5326                                }
5327                                break;
5328                        }
5329                        else
5330                        {
5331#if 0
5332                                msg(DBG_TEA, "============= waiting for result=================.\n");
5333                                sbp_sleep(1);
5334#endif
5335                        }
5336                }
5337                while (wait--);
5338        }
5339
5340        if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
5341        {
5342                msg(DBG_TEA, "================error flag: %d=================.\n", error_flag);
5343                msg(DBG_INF,"sbp_data: read aborted by drive.\n");
5344#if 1
5345                i=cc_DriveReset(); /* ugly fix to prevent a hang */
5346#else
5347                i=cc_ReadError();
5348#endif
5349                return (0);
5350        }
5351        
5352        if (fam0LV_drive)
5353        {
5354                SBPCD_CLI;
5355                i=maxtim_data;
5356                for (timeout=jiffies+HZ; time_before(jiffies, timeout); timeout--)
5357                {
5358                        for ( ;i!=0;i--)
5359                        {
5360                                j=inb(CDi_status);
5361                                if (!(j&s_not_data_ready)) break;
5362                                if (!(j&s_not_result_ready)) break;
5363                                if (j&s_attention) break;
5364                        }
5365                        if (i != 0 || time_after_eq(jiffies, timeout)) break;
5366                        sbp_sleep(0);
5367                        i = 1;
5368                }
5369                if (i==0) msg(DBG_INF,"status timeout after READ.\n");
5370                if (!(j&s_attention))
5371                {
5372                        msg(DBG_INF,"sbp_data: timeout waiting DRV_ATTN - retrying.\n");
5373                        i=cc_DriveReset();  /* ugly fix to prevent a hang */
5374                        SBPCD_STI;
5375                        return (0);
5376                }
5377                SBPCD_STI;
5378        }
5379        
5380#if 0
5381        if (!success)
5382#endif
5383                do
5384                {
5385                        if (fam0LV_drive) cc_ReadStatus();
5386#if 1
5387                        if (famT_drive) msg(DBG_TEA, "================before ResponseStatus=================.\n", i);
5388#endif
5389                        i=ResponseStatus();  /* builds status_bits, returns orig. status (old) or faked p_success (new) */
5390#if 1
5391                        if (famT_drive) msg(DBG_TEA, "================ResponseStatus: %d=================.\n", i);
5392#endif
5393                        if (i<0)
5394                        {
5395                                msg(DBG_INF,"bad cc_ReadStatus after read: %02X\n", D_S[d].status_bits);
5396                                return (0);
5397                        }
5398                }
5399                while ((fam0LV_drive)&&(!st_check)&&(!(i&p_success)));
5400        if (st_check)
5401        {
5402                i=cc_ReadError();
5403                msg(DBG_INF,"cc_ReadError was necessary after read: %d\n",i);
5404                return (0);
5405        }
5406        if (fatal_err)
5407        {
5408                fatal_err=0;
5409                D_S[d].sbp_first_frame=D_S[d].sbp_last_frame=-1;      /* purge buffer */
5410                D_S[d].sbp_current = 0;
5411                msg(DBG_INF,"sbp_data: fatal_err - retrying.\n");
5412                return (0);
5413        }
5414        
5415        D_S[d].sbp_first_frame = req -> sector / 4;
5416        D_S[d].sbp_last_frame = D_S[d].sbp_first_frame + D_S[d].sbp_read_frames - 1;
5417        sbp_transfer(req);
5418        return (1);
5419}
5420/*==========================================================================*/
5421
5422static struct block_device_operations sbpcd_bdops =
5423{
5424        owner:                  THIS_MODULE,
5425        open:                   cdrom_open,
5426        release:                cdrom_release,
5427        ioctl:                  cdrom_ioctl,
5428        check_media_change:     cdrom_media_changed,
5429};
5430/*==========================================================================*/
5431/*
5432 *  Open the device special file.  Check that a disk is in. Read TOC.
5433 */
5434static int sbpcd_open(struct cdrom_device_info *cdi, int purpose)
5435{
5436        int i;
5437
5438        i = MINOR(cdi->dev);
5439
5440        down(&ioctl_read_sem);
5441        switch_drive(i);
5442
5443        /*
5444         * try to keep an "open" counter here and lock the door if 0->1.
5445         */
5446        msg(DBG_LCK,"open_count: %d -> %d\n",
5447            D_S[d].open_count,D_S[d].open_count+1);
5448        if (++D_S[d].open_count<=1)
5449        {
5450                i=LockDoor();
5451                D_S[d].open_count=1;
5452                if (famT_drive) msg(DBG_TEA,"sbpcd_open: before i=DiskInfo();.\n");
5453                i=DiskInfo();
5454                if (famT_drive) msg(DBG_TEA,"sbpcd_open: after i=DiskInfo();.\n");
5455                if ((D_S[d].ored_ctl_adr&0x40)==0)
5456                {               
5457                        msg(DBG_INF,"CD contains no data tracks.\n");
5458#if SAFE_MIXED
5459                        D_S[d].has_data=0;
5460#endif /* SAFE_MIXED */
5461                }
5462#if SAFE_MIXED
5463                else if (D_S[d].has_data<1) D_S[d].has_data=1;
5464#endif /* SAFE_MIXED */ 
5465        }
5466        if (!st_spinning) cc_SpinUp();
5467        RETURN_UP(0);
5468}
5469/*==========================================================================*/
5470/*
5471 *  On close, we flush all sbp blocks from the buffer cache.
5472 */
5473static void sbpcd_release(struct cdrom_device_info * cdi)
5474{
5475        int i;
5476        
5477        i = MINOR(cdi->dev);
5478        if ((i<0) || (i>=NR_SBPCD) || (D_S[i].drv_id==-1))
5479        {
5480                msg(DBG_INF, "release: bad device: %04X\n", cdi->dev);
5481                return ;
5482        }
5483        down(&ioctl_read_sem);
5484        switch_drive(i);
5485        /*
5486         * try to keep an "open" counter here and unlock the door if 1->0.
5487         */
5488        msg(DBG_LCK,"open_count: %d -> %d\n",
5489            D_S[d].open_count,D_S[d].open_count-1);
5490        if (D_S[d].open_count>-2) /* CDROMEJECT may have been done */
5491        {
5492                if (--D_S[d].open_count<=0) 
5493                {
5494                        D_S[d].sbp_first_frame=D_S[d].sbp_last_frame=-1;
5495                        invalidate_buffers(cdi->dev);
5496                        if (D_S[d].audio_state!=audio_playing)
5497                                if (D_S[d].f_eject) cc_SpinDown();
5498                        D_S[d].diskstate_flags &= ~cd_size_bit;
5499                        D_S[d].open_count=0; 
5500#if SAFE_MIXED
5501                        D_S[d].has_data=0;
5502#endif /* SAFE_MIXED */ 
5503                }
5504        }
5505        up(&ioctl_read_sem);
5506        return ;
5507}
5508/*==========================================================================*/
5509/*
5510 *
5511 */
5512static int sbpcd_media_changed( struct cdrom_device_info *cdi, int disc_nr);
5513static struct cdrom_device_ops sbpcd_dops = {
5514        open:                   sbpcd_open,
5515        release:                sbpcd_release,
5516        drive_status:           sbpcd_drive_status,
5517        media_changed:          sbpcd_media_changed,
5518        tray_move:              sbpcd_tray_move,
5519        lock_door:              sbpcd_lock_door,
5520        select_speed:           sbpcd_select_speed,
5521        get_last_session:       sbpcd_get_last_session,
5522        get_mcn:                sbpcd_get_mcn,
5523        reset:                  sbpcd_reset,
5524        audio_ioctl:            sbpcd_audio_ioctl,
5525        dev_ioctl:              sbpcd_dev_ioctl,
5526        capability:             CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
5527                                CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
5528                                CDC_MCN | CDC_PLAY_AUDIO | CDC_IOCTLS,
5529        n_minors:               1,
5530};
5531
5532static struct cdrom_device_info sbpcd_info = {
5533        ops:                    &sbpcd_dops,
5534        speed:                  2,
5535        capacity:               1,
5536        name:                   "sbpcd",
5537};
5538
5539/*==========================================================================*/
5540/*
5541 * accept "kernel command line" parameters 
5542 * (suggested by Peter MacDonald with SLS 1.03)
5543 *
5544 * This is only implemented for the first controller. Should be enough to
5545 * allow installing with a "strange" distribution kernel.
5546 *
5547 * use: tell LILO:
5548 *                 sbpcd=0x230,SoundBlaster
5549 *             or
5550 *                 sbpcd=0x300,LaserMate
5551 *             or
5552 *                 sbpcd=0x338,SoundScape
5553 *             or
5554 *                 sbpcd=0x2C0,Teac16bit
5555 *
5556 * (upper/lower case sensitive here - but all-lowercase is ok!!!).
5557 *
5558 * the address value has to be the CDROM PORT ADDRESS -
5559 * not the soundcard base address.
5560 * For the SPEA/SoundScape setup, DO NOT specify the "configuration port"
5561 * address, but the address which is really used for the CDROM (usually 8
5562 * bytes above).
5563 *
5564 */
5565
5566#if (SBPCD_ISSUE-1)
5567static int sbpcd_setup(char *s)
5568#else
5569int sbpcd_setup(char *s)
5570#endif
5571{
5572#ifndef MODULE
5573        int p[4];
5574        (void)get_options(s, ARRAY_SIZE(p), p);
5575        setup_done++;
5576        msg(DBG_INI,"sbpcd_setup called with %04X,%s\n",p[1], s);
5577        sbpro_type=0; /* default: "LaserMate" */
5578        if (p[0]>1) sbpro_type=p[2];
5579        else if (!strcmp(s,str_sb)) sbpro_type=1;
5580        else if (!strcmp(s,str_sb_l)) sbpro_type=1;
5581        else if (!strcmp(s,str_sp)) sbpro_type=2;
5582        else if (!strcmp(s,str_sp_l)) sbpro_type=2;
5583        else if (!strcmp(s,str_ss)) sbpro_type=2;
5584        else if (!strcmp(s,str_ss_l)) sbpro_type=2;
5585        else if (!strcmp(s,str_t16)) sbpro_type=3;
5586        else if (!strcmp(s,str_t16_l)) sbpro_type=3;
5587        if (p[0]>0) sbpcd_ioaddr=p[1];
5588        if (p[0]>2) max_drives=p[3];
5589#else
5590        sbpcd_ioaddr = sbpcd[0];
5591        sbpro_type = sbpcd[1];
5592#endif
5593        
5594        CDo_command=sbpcd_ioaddr;
5595        CDi_info=sbpcd_ioaddr;
5596        CDi_status=sbpcd_ioaddr+1;
5597        CDo_sel_i_d=sbpcd_ioaddr+1;
5598        CDo_reset=sbpcd_ioaddr+2;
5599        CDo_enable=sbpcd_ioaddr+3; 
5600        f_16bit=0;
5601        if ((sbpro_type==1)||(sbpro_type==3))
5602        {
5603                CDi_data=sbpcd_ioaddr;
5604                if (sbpro_type==3)
5605                {
5606                        f_16bit=1;
5607                        sbpro_type=1;
5608                }
5609        }
5610        else CDi_data=sbpcd_ioaddr+2;
5611
5612        return 1;
5613}
5614
5615__setup("sbpcd=", sbpcd_setup);
5616
5617
5618/*==========================================================================*/
5619/*
5620 * Sequoia S-1000 CD-ROM Interface Configuration
5621 * as used within SPEA Media FX, Ensonic SoundScape and some Reveal cards
5622 * The soundcard has to get jumpered for the interface type "Panasonic"
5623 * (not Sony or Mitsumi) and to get soft-configured for
5624 *     -> configuration port address
5625 *     -> CDROM port offset (num_ports): has to be 8 here. Possibly this
5626 *        offset value determines the interface type (none, Panasonic,
5627 *        Mitsumi, Sony).
5628 *        The interface uses a configuration port (0x320, 0x330, 0x340, 0x350)
5629 *        some bytes below the real CDROM address.
5630 *         
5631 *        For the Panasonic style (LaserMate) interface and the configuration
5632 *        port 0x330, we have to use an offset of 8; so, the real CDROM port
5633 *        address is 0x338.
5634 */
5635static int __init config_spea(void)
5636{
5637        /*
5638         * base address offset between configuration port and CDROM port,
5639         * this probably defines the interface type
5640         *   2 (type=??): 0x00
5641         *   8 (type=LaserMate):0x10
5642         *  16 (type=??):0x20
5643         *  32 (type=??):0x30
5644         */
5645        int n_ports=0x10;
5646
5647        int irq_number=0; /* off:0x00, 2/9:0x01, 7:0x03, 12:0x05, 15:0x07 */
5648        int dma_channel=0; /* off: 0x00, 0:0x08, 1:0x18, 3:0x38, 5:0x58, 6:0x68 */
5649        int dack_polarity=0; /* L:0x00, H:0x80 */
5650        int drq_polarity=0x40; /* L:0x00, H:0x40 */
5651        int i;
5652
5653#define SPEA_REG_1 sbpcd_ioaddr-0x08+4
5654#define SPEA_REG_2 sbpcd_ioaddr-0x08+5
5655        
5656        OUT(SPEA_REG_1,0xFF);
5657        i=inb(SPEA_REG_1);
5658        if (i!=0x0F)
5659        {
5660                msg(DBG_SEQ,"no SPEA interface at %04X present.\n", sbpcd_ioaddr);
5661                return (-1); /* no interface found */
5662        }
5663        OUT(SPEA_REG_1,0x04);
5664        OUT(SPEA_REG_2,0xC0);
5665        
5666        OUT(SPEA_REG_1,0x05);
5667        OUT(SPEA_REG_2,0x10|drq_polarity|dack_polarity);
5668        
5669#if 1
5670#define SPEA_PATTERN 0x80
5671#else
5672#define SPEA_PATTERN 0x00
5673#endif
5674        OUT(SPEA_REG_1,0x06);
5675        OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
5676        OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
5677        
5678        OUT(SPEA_REG_1,0x09);
5679        i=(inb(SPEA_REG_2)&0xCF)|n_ports;
5680        OUT(SPEA_REG_2,i);
5681        
5682        sbpro_type = 0; /* acts like a LaserMate interface now */
5683        msg(DBG_SEQ,"found SoundScape interface at %04X.\n", sbpcd_ioaddr);
5684        return (0);
5685}
5686
5687#ifdef DONT_MERGE_REQUESTS
5688static int dont_merge_requests_fn(request_queue_t *q, struct request *req,
5689                                struct request *next, int max_segments)
5690{
5691        return 0;
5692}
5693
5694static int dont_bh_merge_fn(request_queue_t *q, struct request *req,
5695                            struct buffer_head *bh, int max_segments)
5696{
5697        return 0;
5698}
5699#endif
5700
5701/*==========================================================================*/
5702/*
5703 *  Test for presence of drive and initialize it.
5704 *  Called once at boot or load time.
5705 */
5706
5707static devfs_handle_t devfs_handle;
5708
5709#ifdef MODULE
5710int __init __SBPCD_INIT(void)
5711#else
5712int __init SBPCD_INIT(void)
5713#endif /* MODULE */ 
5714{
5715        char nbuff[16];
5716        int i=0, j=0;
5717        int addr[2]={1, CDROM_PORT};
5718        int port_index;
5719
5720        sti();
5721        
5722        msg(DBG_INF,"sbpcd.c %s\n", VERSION);
5723#ifndef MODULE
5724#if DISTRIBUTION
5725        if (!setup_done)
5726        {
5727                msg(DBG_INF,"Looking for Matsushita/Panasonic, CreativeLabs, Longshine, TEAC CD-ROM drives\n");
5728                msg(DBG_INF,"= = = = = = = = = = W A R N I N G = = = = = = = = = =\n");
5729                msg(DBG_INF,"Auto-Probing can cause a hang (f.e. touching an NE2000 card).\n");
5730                msg(DBG_INF,"If that happens, you have to reboot and use the\n");
5731                msg(DBG_INF,"LILO (kernel) command line feature like:\n");
5732                msg(DBG_INF,"   LILO boot: ... sbpcd=0x230,SoundBlaster\n");
5733                msg(DBG_INF,"or like:\n");
5734                msg(DBG_INF,"   LILO boot: ... sbpcd=0x300,LaserMate\n");
5735                msg(DBG_INF,"or like:\n");
5736                msg(DBG_INF,"   LILO boot: ... sbpcd=0x338,SoundScape\n");
5737                msg(DBG_INF,"with your REAL address.\n");
5738                msg(DBG_INF,"= = = = = = = = = = END of WARNING = = = = = == = = =\n");
5739        }
5740#endif /* DISTRIBUTION */
5741        sbpcd[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */
5742        sbpcd[1]=sbpro_type; /* possibly changed by kernel command line */
5743#endif /* MODULE */
5744        
5745        for (port_index=0;port_index<NUM_PROBE;port_index+=2)
5746        {
5747                addr[1]=sbpcd[port_index];
5748                if (addr[1]==0) break;
5749                if (check_region(addr[1],4))
5750                {
5751                        msg(DBG_INF,"check_region: %03X is not free.\n",addr[1]);
5752                        continue;
5753                }
5754                if (sbpcd[port_index+1]==2) type=str_sp;
5755                else if (sbpcd[port_index+1]==1) type=str_sb;
5756                else if (sbpcd[port_index+1]==3) type=str_t16;
5757                else type=str_lm;
5758                sbpcd_setup((char *)type);
5759#if DISTRIBUTION
5760                msg(DBG_INF,"Scanning 0x%X (%s)...\n", CDo_command, type);
5761#endif /* DISTRIBUTION */
5762                if (sbpcd[port_index+1]==2)
5763                {
5764                        i=config_spea();
5765                        if (i<0) continue;
5766                }
5767#ifdef PATH_CHECK
5768                if (check_card(addr[1])) continue;
5769#endif /* PATH_CHECK */ 
5770                i=check_drives();
5771                msg(DBG_INI,"check_drives done.\n");
5772                if (i>=0) break; /* drive found */
5773        } /* end of cycling through the set of possible I/O port addresses */
5774        
5775        if (ndrives==0)
5776        {
5777                msg(DBG_INF, "No drive found.\n");
5778#ifdef MODULE
5779                return -EIO;
5780#else
5781                goto init_done;
5782#endif /* MODULE */
5783        }
5784        
5785        if (port_index>0)
5786          {
5787            msg(DBG_INF, "You should read linux/Documentation/cdrom/sbpcd\n");
5788            msg(DBG_INF, "and then configure sbpcd.h for your hardware.\n");
5789          }
5790        check_datarate();
5791        msg(DBG_INI,"check_datarate done.\n");
5792        
5793        for (j=0;j<NR_SBPCD;j++)
5794        {
5795                if (D_S[j].drv_id==-1) continue;
5796                switch_drive(j);
5797#if 1
5798                if (!famL_drive) cc_DriveReset();
5799#endif
5800                if (!st_spinning) cc_SpinUp();
5801                D_S[j].sbp_first_frame = -1;  /* First frame in buffer */
5802                D_S[j].sbp_last_frame = -1;   /* Last frame in buffer  */
5803                D_S[j].sbp_read_frames = 0;   /* Number of frames being read to buffer */
5804                D_S[j].sbp_current = 0;       /* Frame being currently read */
5805                D_S[j].CD_changed=1;
5806                D_S[j].frame_size=CD_FRAMESIZE;
5807                D_S[j].f_eject=0;
5808#if EJECT
5809                if (!fam0_drive) D_S[j].f_eject=1;
5810#endif /* EJECT */ 
5811                cc_ReadStatus();
5812                i=ResponseStatus();  /* returns orig. status or p_busy_new */
5813                if (famT_drive) i=ResponseStatus();  /* returns orig. status or p_busy_new */
5814                if (i<0)
5815                {
5816                        if (i!=-402)
5817                                msg(DBG_INF,"init: ResponseStatus returns %d.\n",i);
5818                }
5819                else
5820                {
5821                        if (st_check)
5822                        {
5823                                i=cc_ReadError();
5824                                msg(DBG_INI,"init: cc_ReadError returns %d\n",i);
5825                        }
5826                }
5827                msg(DBG_INI,"init: first GetStatus: %d\n",i);
5828                msg(DBG_LCS,"init: first GetStatus: error_byte=%d\n",
5829                    D_S[j].error_byte);
5830                if (D_S[j].error_byte==aud_12)
5831                {
5832                        timeout=jiffies+2*HZ;
5833                        do
5834                        {
5835                                i=GetStatus();
5836                                msg(DBG_INI,"init: second GetStatus: %02X\n",i);
5837                                msg(DBG_LCS,
5838                                    "init: second GetStatus: error_byte=%d\n",
5839                                    D_S[j].error_byte);
5840                                if (i<0) break;
5841                                if (!st_caddy_in) break;
5842                                }
5843                        while ((!st_diskok)||time_after(jiffies, timeout));
5844                }
5845                i=SetSpeed();
5846                if (i>=0) D_S[j].CD_changed=1;
5847        }
5848        
5849        /*
5850         * Turn on the CD audio channels.
5851         * The addresses are obtained from SOUND_BASE (see sbpcd.h).
5852         */
5853#if SOUND_BASE
5854        OUT(MIXER_addr,MIXER_CD_Volume); /* select SB Pro mixer register */
5855        OUT(MIXER_data,0xCC); /* one nibble per channel, max. value: 0xFF */
5856#endif /* SOUND_BASE */ 
5857        
5858        if (devfs_register_blkdev(MAJOR_NR, major_name, &sbpcd_bdops) != 0)
5859        {
5860                msg(DBG_INF, "Can't get MAJOR %d for Matsushita CDROM\n", MAJOR_NR);
5861#ifdef MODULE
5862                return -EIO;
5863#else
5864                goto init_done;
5865#endif /* MODULE */
5866        }
5867        blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
5868#ifdef DONT_MERGE_REQUESTS
5869        (BLK_DEFAULT_QUEUE(MAJOR_NR))->back_merge_fn = dont_bh_merge_fn;
5870        (BLK_DEFAULT_QUEUE(MAJOR_NR))->front_merge_fn = dont_bh_merge_fn;
5871        (BLK_DEFAULT_QUEUE(MAJOR_NR))->merge_requests_fn = dont_merge_requests_fn;
5872#endif
5873        blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR), 0);
5874        read_ahead[MAJOR_NR] = buffers * (CD_FRAMESIZE / 512);
5875        
5876        request_region(CDo_command,4,major_name);
5877        
5878        devfs_handle = devfs_mk_dir (NULL, "sbp", NULL);
5879        for (j=0;j<NR_SBPCD;j++)
5880        {
5881                struct cdrom_device_info * sbpcd_infop;
5882
5883                if (D_S[j].drv_id==-1) continue;
5884                switch_drive(j);
5885#if SAFE_MIXED
5886                D_S[j].has_data=0;
5887#endif /* SAFE_MIXED */ 
5888                /*
5889                 * allocate memory for the frame buffers
5890                 */
5891                D_S[j].aud_buf=NULL;
5892                D_S[j].sbp_audsiz=0;
5893                D_S[j].sbp_bufsiz=buffers;
5894                if (D_S[j].drv_type&drv_fam1)
5895                        if (READ_AUDIO>0) D_S[j].sbp_audsiz=READ_AUDIO;
5896                D_S[j].sbp_buf=(u_char *) vmalloc(D_S[j].sbp_bufsiz*CD_FRAMESIZE);
5897                if (D_S[j].sbp_buf==NULL)
5898                {
5899                        msg(DBG_INF,"data buffer (%d frames) not available.\n",D_S[j].sbp_bufsiz);
5900                        if ((devfs_unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
5901                        {
5902                                printk("Can't unregister %s\n", major_name);
5903                        }
5904                        release_region(CDo_command,4);
5905                        blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
5906                        return -EIO;
5907                }
5908#ifdef MODULE
5909                msg(DBG_INF,"data buffer size: %d frames.\n",buffers);
5910#endif /* MODULE */
5911                if (D_S[j].sbp_audsiz>0)
5912                {
5913                        D_S[j].aud_buf=(u_char *) vmalloc(D_S[j].sbp_audsiz*CD_FRAMESIZE_RAW);
5914                        if (D_S[j].aud_buf==NULL) msg(DBG_INF,"audio buffer (%d frames) not available.\n",D_S[j].sbp_audsiz);
5915                        else msg(DBG_INF,"audio buffer size: %d frames.\n",D_S[j].sbp_audsiz);
5916                }
5917                sbpcd_infop = vmalloc(sizeof (struct cdrom_device_info));
5918                if (sbpcd_infop == NULL)
5919                {
5920                        release_region(CDo_command,4);
5921                        blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
5922                        return -ENOMEM;
5923                }
5924                D_S[j].sbpcd_infop = sbpcd_infop;
5925                memcpy (sbpcd_infop, &sbpcd_info, sizeof(struct cdrom_device_info));
5926                sbpcd_infop->dev = MKDEV(MAJOR_NR, j);
5927                strncpy(sbpcd_infop->name,major_name, sizeof(sbpcd_infop->name)); 
5928
5929                sprintf (nbuff, "c%dt%d/cd", SBPCD_ISSUE - 1, D_S[j].drv_id);
5930                sbpcd_infop->de =
5931                    devfs_register (devfs_handle, nbuff, DEVFS_FL_DEFAULT,
5932                                    MAJOR_NR, j, S_IFBLK | S_IRUGO | S_IWUGO,
5933                                    &sbpcd_bdops, NULL);
5934                if (register_cdrom(sbpcd_infop))
5935                {
5936                        printk(" sbpcd: Unable to register with Uniform CD-ROm driver\n");
5937                }
5938                /*
5939                 * set the block size
5940                 */
5941                sbpcd_blocksizes[j]=CD_FRAMESIZE;
5942        }
5943        blksize_size[MAJOR_NR]=sbpcd_blocksizes;
5944
5945#ifndef MODULE
5946 init_done:
5947#if !(SBPCD_ISSUE-1)
5948#ifdef CONFIG_SBPCD2
5949        sbpcd2_init();
5950#endif /* CONFIG_SBPCD2 */
5951#ifdef CONFIG_SBPCD3
5952        sbpcd3_init();
5953#endif /* CONFIG_SBPCD3 */ 
5954#ifdef CONFIG_SBPCD4
5955        sbpcd4_init();
5956#endif /* CONFIG_SBPCD4 */ 
5957#endif /* !(SBPCD_ISSUE-1) */ 
5958#endif /* MODULE */
5959        return 0;
5960}
5961/*==========================================================================*/
5962#ifdef MODULE
5963void sbpcd_exit(void)
5964{
5965        int j;
5966        
5967        if ((devfs_unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
5968        {
5969                msg(DBG_INF, "What's that: can't unregister %s.\n", major_name);
5970                return;
5971        }
5972        release_region(CDo_command,4);
5973        blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
5974        devfs_unregister (devfs_handle);
5975        for (j=0;j<NR_SBPCD;j++)
5976        {
5977                if (D_S[j].drv_id==-1) continue;
5978                vfree(D_S[j].sbp_buf);
5979                if (D_S[j].sbp_audsiz>0) vfree(D_S[j].aud_buf);
5980                if ((unregister_cdrom(D_S[j].sbpcd_infop) == -EINVAL))
5981                {
5982                        msg(DBG_INF, "What's that: can't unregister info %s.\n", major_name);
5983                        return;
5984                }
5985                vfree(D_S[j].sbpcd_infop);
5986        }
5987        msg(DBG_INF, "%s module released.\n", major_name);
5988}
5989
5990
5991#ifdef MODULE
5992module_init(__SBPCD_INIT) /*HACK!*/;
5993#endif
5994module_exit(sbpcd_exit);
5995
5996
5997#endif /* MODULE */ 
5998/*==========================================================================*/
5999/*
6000 * Check if the media has changed in the CD-ROM drive.
6001 * used externally (isofs/inode.c, fs/buffer.c)
6002 */
6003static int sbpcd_chk_disk_change(kdev_t full_dev)
6004{
6005        int i;
6006        
6007        msg(DBG_CHK,"media_check (%d) called\n", MINOR(full_dev));
6008        i=MINOR(full_dev);
6009        
6010        if (D_S[i].CD_changed==0xFF)
6011        {
6012                D_S[i].CD_changed=0;
6013                msg(DBG_CHK,"medium changed (drive %d)\n", i);
6014                /* BUG! Should invalidate buffers! --AJK */
6015                invalidate_buffers(full_dev);
6016                D_S[d].diskstate_flags &= ~toc_bit;
6017                D_S[d].diskstate_flags &= ~cd_size_bit;
6018#if SAFE_MIXED
6019                D_S[d].has_data=0;
6020#endif /* SAFE_MIXED */ 
6021
6022                return (1);
6023        }
6024        else
6025                return (0);
6026}
6027
6028static int sbpcd_media_changed( struct cdrom_device_info *cdi, int disc_nr)
6029{
6030   return sbpcd_chk_disk_change(cdi->dev);
6031}
6032
6033MODULE_LICENSE("GPL");
6034
6035/*==========================================================================*/
6036/*
6037 * Overrides for Emacs so that we follow Linus's tabbing style.
6038 * Emacs will notice this stuff at the end of the file and automatically
6039 * adjust the settings for this buffer only.  This must remain at the end
6040 * of the file. 
6041 * ---------------------------------------------------------------------------
6042 * Local variables:
6043 * c-indent-level: 8
6044 * c-brace-imaginary-offset: 0
6045 * c-brace-offset: -8
6046 * c-argdecl-indent: 8
6047 * c-label-offset: -8
6048 * c-continued-statement-offset: 8
6049 * c-continued-brace-offset: 0
6050 * End:
6051 */
6052
6053
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.