root/drivers/block/sbpcd.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sbpcd_dprintf
  2. sbpcd_dbg_ioctl
  3. sbp_sleep
  4. lba2msf
  5. bin2bcdx
  6. blk2msf
  7. make16
  8. make32
  9. swap_nibbles
  10. byt2bcd
  11. bcd2bin
  12. msf2blk
  13. msf2lba
  14. sta2err
  15. clr_cmdbuf
  16. mark_timeout
  17. flush_status
  18. CDi_stat_loop
  19. ResponseInfo
  20. EvaluateStatus
  21. ResponseStatus
  22. xx_ReadStatus
  23. xx_ReadError
  24. cmd_out
  25. xx_Seek
  26. xx_SpinUp
  27. yy_SpinDown
  28. yy_SetSpeed
  29. xx_SetVolume
  30. GetStatus
  31. xy_DriveReset
  32. SetSpeed
  33. DriveReset
  34. xx_Pause_Resume
  35. yy_LockDoor
  36. yy_CloseTray
  37. xx_ReadSubQ
  38. xx_ModeSense
  39. xx_ModeSelect
  40. xx_TellVolume
  41. xx_ReadCapacity
  42. xx_ReadTocDescr
  43. xx_ReadTocEntry
  44. xx_ReadPacket
  45. convert_UPC
  46. xx_ReadUPC
  47. yy_CheckMultiSession
  48. yy_SubChanInfo
  49. check_datarate
  50. xx_ReadVersion
  51. yy_ReadError
  52. ask_mail
  53. check_version
  54. switch_drive
  55. check_drives
  56. timewait
  57. obey_audio_state
  58. check_allowed1
  59. check_allowed2
  60. check_allowed3
  61. seek_pos_audio_end
  62. ReadToC
  63. DiskInfo
  64. prepare
  65. xx_PlayAudio
  66. sbp_status
  67. sbpcd_ioctl
  68. sbp_transfer
  69. DO_SBPCD_REQUEST
  70. sbp_read_cmd
  71. sbp_data
  72. sbpcd_open
  73. sbpcd_release
  74. sbpcd_setup
  75. config_spea
  76. init_module
  77. cleanup_module
  78. sbpcd_chk_disk_change

   1 /*
   2  *  sbpcd.c   CD-ROM device driver for the whole family of IDE-style
   3  *            Kotobuki/Matsushita/Panasonic CR-5xx drives for
   4  *            SoundBlaster ("Pro" or "16 ASP" or compatible) cards
   5  *            and for "no-sound" interfaces like Lasermate and the
   6  *            Panasonic CI-101P.
   7  *            Also for the Longshine LCS-7260 drive.
   8  *            Also for the IBM "External ISA CD-Rom" drive.
   9  *            Still not for the CreativeLabs CD200 drive (but should work soon).
  10  *            Not for the TEAC CD-55A drive (separate project now).
  11  *            Not for Funai or Sanyo drives.
  12  *
  13  *  NOTE:     This is release 3.4.
  14  *            It works with my SbPro & drive CR-521 V2.11 from 2/92
  15  *            and with the CR-562-B V0.75 on a "naked" Panasonic
  16  *            CI-101P interface. And vice versa. 
  17  *  
  18  *
  19  *  VERSION HISTORY
  20  *
  21  *  0.1  initial release, April/May 93, after mcd.c (Martin Harriss)
  22  *
  23  *  0.2  the "repeat:"-loop in do_sbpcd_request did not check for
  24  *       end-of-request_queue (resulting in kernel panic).
  25  *       Flow control seems stable, but throughput is not better.  
  26  *
  27  *  0.3  interrupt locking totally eliminated (maybe "inb" and "outb"
  28  *       are still locking) - 0.2 made keyboard-type-ahead losses.
  29  *       check_sbpcd_media_change added (to use by isofs/inode.c)
  30  *       - but it detects almost nothing.
  31  *
  32  *  0.4  use MAJOR 25 definitely.
  33  *       Almost total re-design to support double-speed drives and
  34  *       "naked" (no sound) interface cards.
  35  *       Flow control should be exact now (tell me if not).
  36  *       Don't occupy the SbPro IRQ line (not needed either); will
  37  *       live together with Hannu Savolainen's sndkit now.
  38  *       Speeded up data transfer to 150 kB/sec, with help from Kai
  39  *       Makisara, the "provider" of the "mt" tape utility.
  40  *       Give "SpinUp" command if necessary.
  41  *       First steps to support up to 4 drives (but currently only one).
  42  *       Implemented audio capabilities - workman should work, xcdplayer
  43  *       gives some problems.
  44  *       This version is still consuming too much CPU time, and
  45  *       sleeping still has to be worked on.
  46  *       During "long" implied seeks, it seems possible that a 
  47  *       ReadStatus command gets ignored. That gives the message
  48  *       "ResponseStatus timed out" (happens about 6 times here during
  49  *       a "ls -alR" of the YGGDRASIL LGX-Beta CD). Such a case is
  50  *       handled without data error, but it should get done better.
  51  *
  52  *  0.5  Free CPU during waits (again with help from Kai Makisara).
  53  *       Made it work together with the LILO/kernel setup standard.
  54  *       Included auto-probing code, as suggested by YGGDRASIL.
  55  *       Formal redesign to add DDI debugging.
  56  *       There are still flaws in IOCTL (workman with double speed drive).
  57  *
  58  *  1.0  Added support for all drive ids (0...3, no longer only 0)
  59  *       and up to 4 drives on one controller.
  60  *       Added "#define MANY_SESSION" for "old" multi session CDs.
  61  *
  62  *  1.1  Do SpinUp for new drives, too.
  63  *       Revised for clean compile under "old" kernels (pl9).
  64  *
  65  *  1.2  Found the "workman with double-speed drive" bug: use the driver's
  66  *       audio_state, not what the drive is reporting with ReadSubQ.
  67  *
  68  *  1.3  Minor cleanups.
  69  *       Refinements regarding Workman.
  70  *
  71  *  1.4  Read XA disks (PhotoCDs) with "old" drives, too (but possibly only
  72  *       the first session - I could not try a "multi-session" CD yet).
  73  *       This currently still is too slow (50 kB/sec) - but possibly
  74  *       the old drives won't do it faster.
  75  *       Implemented "door (un)lock" for new drives (still does not work
  76  *       as wanted - no lock possible after an unlock).
  77  *       Added some debugging printout for the UPC/EAN code - but my drives 
  78  *       return only zeroes. Is there no UPC/EAN code written?
  79  *
  80  *  1.5  Laborate with UPC/EAN code (not better yet).
  81  *       Adapt to kernel 1.1.8 change (have to explicitly include
  82  *       <linux/string.h> now).
  83  *
  84  *  1.6  Trying to read audio frames as data. Impossible with the current
  85  *       drive firmware levels, as it seems. Awaiting any hint. ;-)
  86  *       Changed "door unlock": repeat it until success.
  87  *       Changed CDROMSTOP routine (stop somewhat "softer" so that Workman
  88  *       won't get confused).
  89  *       Added a third interface type: Sequoia S-1000, as used with the SPEA
  90  *       Media FX sound card. This interface (usable for Sony and Mitsumi 
  91  *       drives, too) needs a special configuration setup and behaves like a 
  92  *       LaserMate type after that. Still experimental - I do not have such
  93  *       an interface.
  94  *       Use the "variable BLOCK_SIZE" feature (2048). But it does only work
  95  *       if you give the mount option "block=2048".
  96  *       The media_check routine is currently disabled; now that it gets
  97  *       called as it should I fear it must get synchronized for not to
  98  *       disturb the normal driver's activity.
  99  *
 100  *  2.0  Version number bumped - two reasons:
 101  *       - reading audio tracks as data works now with CR-562 and CR-563. We
 102  *       currently do it by an IOCTL (yet has to get standardized), one frame
 103  *       at a time; that is pretty slow. But it works.
 104  *       - we are maintaining now up to 4 interfaces (each up to 4 drives):
 105  *       did it the easy way - a different MAJOR (25, 26, ...) and a different
 106  *       copy of the driver (sbpcd.c, sbpcd2.c, sbpcd3.c, sbpcd4.c - only
 107  *       distinguished by the value of SBPCD_ISSUE and the driver's name),
 108  *       and a common sbpcd.h file.
 109  *       Bettered the "ReadCapacity error" problem with old CR-52x drives (the
 110  *       drives sometimes need a manual "eject/insert" before work): just
 111  *       reset the drive and do again. Needs lots of resets here and sometimes
 112  *       that does not cure, so this can't be the solution.
 113  *
 114  *  2.1  Found bug with multisession CDs (accessing frame 16).
 115  *       "read audio" works now with address type CDROM_MSF, too.
 116  *       Bigger audio frame buffer: allows reading max. 4 frames at time; this
 117  *       gives a significant speedup, but reading more than one frame at once
 118  *       gives missing chunks at each single frame boundary.
 119  *
 120  *  2.2  Kernel interface cleanups: timers, init, setup, media check.
 121  *
 122  *  2.3  Let "door lock" and "eject" live together.
 123  *       Implemented "close tray" (done automatically during open).
 124  *
 125  *  2.4  Use different names for device registering.
 126  *       
 127  *  2.5  Added "#if EJECT" code (default: enabled) to automatically eject
 128  *       the tray during last call to "sbpcd_release".
 129  *       Added "#if JUKEBOX" code (default: disabled) to automatically eject
 130  *       the tray during call to "sbpcd_open" if no disk is in.
 131  *       Turn on the CD volume of "compatible" sound cards, too; just define
 132  *       SOUND_BASE (in sbpcd.h) accordingly (default: disabled).
 133  *
 134  *  2.6  Nothing new.  
 135  *       
 136  *  2.7  Added CDROMEJECT_SW ioctl to set the "EJECT" behavior on the fly:
 137  *       0 disables, 1 enables auto-ejecting. Useful to keep the tray in
 138  *       during shutdown.
 139  *       
 140  *  2.8  Added first support (still BETA, I need feedback or a drive) for
 141  *       the Longshine LCS-7260 drives. They appear as double-speed drives
 142  *       using the "old" command scheme, extended by tray control and door
 143  *       lock functions.
 144  *       Found (and fixed preliminary) a flaw with some multisession CDs: we
 145  *       have to re-direct not only the accesses to frame 16 (the isofs
 146  *       routines drive it up to max. 100), but also those to the continuation
 147  *       (repetition) frames (as far as they exist - currently set fix as
 148  *       16..20).
 149  *       Changed default of the "JUKEBOX" define. If you use this default,
 150  *       your tray will eject if you try to mount without a disk in. Next
 151  *       mount command will insert the tray - so, just insert a disk. ;-)
 152  *       
 153  *  2.9  Fulfilled the Longshine LCS-7260 support; with great help and
 154  *       experiments by Serge Robyns.
 155  *       First attempts to support the TEAC CD-55A drives; but still not
 156  *       usable yet.
 157  *       Implemented the CDROMMULTISESSION ioctl; this is an attempt to handle
 158  *       multi session CDs more "transparent" (redirection handling has to be
 159  *       done within the isofs routines, and only for the special purpose of
 160  *       obtaining the "right" volume descriptor; accesses to the raw device
 161  *       should not get redirected).
 162  *
 163  *  3.0  Just a "normal" increment, with some provisions to do it better. ;-)
 164  *       Introduced "#define READ_AUDIO" to specify the maximum number of 
 165  *       audio frames to grab with one request. This defines a buffer size
 166  *       within kernel space; a value of 0 will reserve no such space and
 167  *       disable the CDROMREADAUDIO ioctl. A value of 75 enables the reading
 168  *       of a whole second with one command, but will use a buffer of more
 169  *       than 172 kB.
 170  *       Started CD200 support. Drive detection should work, but nothing
 171  *       more.
 172  *
 173  *  3.1  Working to support the CD200 and the Teac CD-55A drives.
 174  *       AT-BUS style device numbering no longer used: use SCSI style now.
 175  *       So, the first "found" device has MINOR 0, regardless of the
 176  *       jumpered drive ID. This implies modifications to the /dev/sbpcd*
 177  *       entries for some people, but will help the DAU (german TLA, english:
 178  *       "newbie", maybe ;-) to install his "first" system from a CD.
 179  *     
 180  *  3.2  Still testing with CD200 and CD-55A drives.
 181  *
 182  *  3.3  Working with CD200 support. Maybe a simple read is already possible.
 183  *
 184  *  3.4  Auto-probing stops if an address of 0 is seen (to be entered with
 185  *       the kernel command line).
 186  *       Made the driver "loadable". If used as a module, "audio copy" is
 187  *       disabled, and the internal read ahead data buffer has a reduced size
 188  *       of 4 kB; so, throughput may be reduced a little bit with slow CPUs.
 189  *
 190  *  TODO
 191  *
 192  *     disk change detection
 193  *     allow & synchronize multi-activity
 194  *        (data + audio + ioctl + disk change, multiple drives)
 195  *     implement multi-controller-support with a single driver
 196  *     implement "read all subchannel data" (96 bytes per frame)
 197  *
 198  *
 199  *     special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
 200  *     elaborated speed-up experiments (and the fabulous results!), for
 201  *     the "push" towards load-free wait loops, and for the extensive mail
 202  *     thread which brought additional hints and bug fixes.
 203  * 
 204  *
 205  *   Copyright (C) 1993, 1994, 1995  Eberhard Moenkeberg <emoenke@gwdg.de>
 206  *
 207  *                  If you change this software, you should mail a .diff
 208  *                  file with some description lines to emoenke@gwdg.de.
 209  *                  I want to know about it.
 210  *
 211  *                  If you are the editor of a Linux CD, you should
 212  *                  enable sbpcd.c within your boot floppy kernel and
 213  *                  send me one of your CDs for free.
 214  *
 215  *   This program is free software; you can redistribute it and/or modify
 216  *   it under the terms of the GNU General Public License as published by
 217  *   the Free Software Foundation; either version 2, or (at your option)
 218  *   any later version.
 219  *
 220  *   You should have received a copy of the GNU General Public License
 221  *   (for example /usr/src/linux/COPYING); if not, write to the Free
 222  *   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 223  *
 224  */
 225 
 226 #ifndef SBPCD_ISSUE
 227 #define SBPCD_ISSUE 1
 228 #endif SBPCD_ISSUE
 229 
 230 #include <linux/config.h>
 231 
 232 #ifdef MODULE
 233 #include <linux/module.h>
 234 #include <linux/version.h>
 235 #include <linux/malloc.h>
 236 #ifndef CONFIG_MODVERSIONS
 237 char kernel_version[]=UTS_RELEASE;
 238 #endif
 239 #endif MODULE
 240 
 241 #include <linux/errno.h>
 242 #include <linux/sched.h>
 243 #include <linux/mm.h>
 244 #include <linux/timer.h>
 245 #include <linux/fs.h>
 246 #include <linux/kernel.h>
 247 #include <linux/cdrom.h>
 248 #include <linux/ioport.h>
 249 #include <linux/major.h> 
 250 #include <linux/sbpcd.h>
 251 #include <linux/string.h>
 252 #include <asm/system.h>
 253 #include <asm/io.h>
 254 #include <asm/segment.h>
 255 #include <stdarg.h>
 256 
 257 #if !(SBPCD_ISSUE-1)
 258 #define MAJOR_NR MATSUSHITA_CDROM_MAJOR
 259 #endif
 260 #if !(SBPCD_ISSUE-2)
 261 #define MAJOR_NR MATSUSHITA_CDROM2_MAJOR /* second driver issue */
 262 #endif
 263 #if !(SBPCD_ISSUE-3)
 264 #define MAJOR_NR MATSUSHITA_CDROM3_MAJOR /* third driver issue */
 265 #endif
 266 #if !(SBPCD_ISSUE-4)
 267 #define MAJOR_NR MATSUSHITA_CDROM4_MAJOR /* fourth driver issue */
 268 #endif
 269 
 270 #ifdef MODULE
 271 #include "/usr/src/linux/drivers/block/blk.h"
 272 #else
 273 #include "blk.h"
 274 #define MOD_INC_USE_COUNT
 275 #define MOD_DEC_USE_COUNT
 276 #endif MODULE
 277 
 278 #define VERSION "3.4 Eberhard Moenkeberg <emoenke@gwdg.de>"
 279 
 280 /*
 281  *
 282  */
 283 #define READ_AUDIO 4 /* max. number of audio frames to read with one */
 284                      /* request (allocates n* 2352 bytes kernel memory!) */
 285 #define JUKEBOX 1 /* tray control: eject tray if no disk is in */
 286 #define EJECT 1 /* tray control: eject tray after last use */
 287 #define LONG_TIMING 0 /* test against timeouts with "gold" CDs on CR-521 */
 288 #define MANY_SESSION 0 /* this will conflict with "true" multi-session! */
 289 #undef  FUTURE
 290 #define WORKMAN 1 /* some testing stuff to make it better */
 291 #define CDMKE /* makes timing independent of processor speed */
 292 
 293 #undef XA_TEST1
 294 #define XA_TEST2
 295 
 296 #define TEST_UPC 0
 297 #define SPEA_TEST 0
 298 #define PRINTK_BUG 0
 299 #define TEST_STI 0
 300 
 301 #define DISTRIBUTION 1 /* I use it with a 0 here */
 302 
 303 #if 0
 304 #define INLINE
 305 #else
 306 #define INLINE inline
 307 #endif
 308 
 309 /*==========================================================================*/
 310 /*
 311  * provisions for more than 1 driver issues
 312  * currently up to 4 drivers, expandable
 313  */
 314 #if !(SBPCD_ISSUE-1)
 315 #define DO_SBPCD_REQUEST(a) do_sbpcd_request(a)
 316 #define SBPCD_INIT(a,b) sbpcd_init(a,b)
 317 #endif
 318 #if !(SBPCD_ISSUE-2)
 319 #define DO_SBPCD_REQUEST(a) do_sbpcd2_request(a)
 320 #define SBPCD_INIT(a,b) sbpcd2_init(a,b)
 321 #endif
 322 #if !(SBPCD_ISSUE-3)
 323 #define DO_SBPCD_REQUEST(a) do_sbpcd3_request(a)
 324 #define SBPCD_INIT(a,b) sbpcd3_init(a,b)
 325 #endif
 326 #if !(SBPCD_ISSUE-4)
 327 #define DO_SBPCD_REQUEST(a) do_sbpcd4_request(a)
 328 #define SBPCD_INIT(a,b) sbpcd4_init(a,b)
 329 #endif
 330 /*==========================================================================*/
 331 #if MANY_SESSION
 332 #undef LONG_TIMING
 333 #define LONG_TIMING 1
 334 #endif
 335 /*==========================================================================*/
 336 #if SBPCD_DIS_IRQ
 337 #define SBPCD_CLI cli()
 338 #define SBPCD_STI sti()
 339 #else
 340 #define SBPCD_CLI
 341 #define SBPCD_STI
 342 #endif SBPCD_DIS_IRQ
 343 /*==========================================================================*/
 344 /*
 345  * auto-probing address list
 346  * inspired by Adam J. Richter from Yggdrasil
 347  *
 348  * still not good enough - can cause a hang.
 349  *   example: a NE 2000 ethernet card at 300 will cause a hang probing 310.
 350  * if that happens, reboot and use the LILO (kernel) command line.
 351  * The possibly conflicting ethernet card addresses get NOT probed 
 352  * by default - to minimize the hang possibilities. 
 353  *
 354  * The SB Pro addresses get "mirrored" at 0x6xx - to avoid a type error,
 355  * the 0x2xx-addresses must get checked before 0x6xx.
 356  *
 357  * send mail to emoenke@gwdg.de if your interface card is not FULLY
 358  * represented here.
 359  */
 360 #if !(SBPCD_ISSUE-1)
 361 static int sbpcd_probe[] = 
 362 {
 363   CDROM_PORT, SBPRO, /* probe with user's setup first */
 364 #if DISTRIBUTION
 365   0x230, 1, /* Soundblaster Pro and 16 (default) */
 366   0x300, 0, /* CI-101P (default), WDH-7001C (default),
 367                Galaxy (default), Reveal (one default) */
 368   0x250, 1, /* OmniCD default, Soundblaster Pro and 16 */
 369   0x260, 1, /* OmniCD */
 370   0x320, 0, /* Lasermate, CI-101P, WDH-7001C, Galaxy, Reveal (other default),
 371                Longshine LCS-6853 (default) */
 372   0x338, 0, /* Reveal Sound Wave 32 card model #SC600 */
 373   0x340, 0, /* Mozart sound card (default), Lasermate, CI-101P */
 374   0x360, 0, /* Lasermate, CI-101P */
 375   0x270, 1, /* Soundblaster 16 */
 376   0x670, 0, /* "sound card #9" */
 377   0x690, 0, /* "sound card #9" */
 378   0x330, 2, /* SPEA Media FX (default) */
 379   0x320, 2, /* SPEA Media FX */
 380   0x340, 2, /* SPEA Media FX */
 381   0x634, 0, /* some newer sound cards */
 382   0x638, 0, /* some newer sound cards */
 383 /* due to incomplete address decoding of the SbPro card, these must be last */
 384   0x630, 0, /* "sound card #9" (default) */
 385   0x650, 0, /* "sound card #9" */
 386 #ifdef MODULE
 387 /*
 388  * some "hazardous" locations (no harm with the loadable version)
 389  * (will stop the bus if a NE2000 ethernet card resides at offset -0x10)
 390  */
 391   0x330, 0, /* Lasermate, CI-101P, WDH-7001C */
 392   0x350, 0, /* Lasermate, CI-101P */
 393   0x350, 2, /* SPEA Media FX */
 394   0x370, 0, /* Lasermate, CI-101P */
 395   0x290, 1, /* Soundblaster 16 */
 396   0x310, 0, /* Lasermate, CI-101P, WDH-7001C */
 397 #endif MODULE
 398 #endif DISTRIBUTION
 399 };
 400 #else
 401 static int sbpcd_probe[] = {CDROM_PORT, SBPRO}; /* probe with user's setup only */
 402 #endif
 403 
 404 #define NUM_PROBE  (sizeof(sbpcd_probe) / sizeof(int))
 405 
 406 
 407 /*==========================================================================*/
 408 /*
 409  * the external references:
 410  */
 411 #if !(SBPCD_ISSUE-1)
 412 #ifdef CONFIG_SBPCD2
 413 extern unsigned long sbpcd2_init(unsigned long, unsigned long);
 414 #endif
 415 #ifdef CONFIG_SBPCD3
 416 extern unsigned long sbpcd3_init(unsigned long, unsigned long);
 417 #endif
 418 #ifdef CONFIG_SBPCD4
 419 extern unsigned long sbpcd4_init(unsigned long, unsigned long);
 420 #endif
 421 #endif
 422 
 423 /*==========================================================================*/
 424 /*==========================================================================*/
 425 /*
 426  * the forward references:
 427  */
 428 static void sbp_read_cmd(void);
 429 static int sbp_data(void);
 430 static int cmd_out(int);
 431 static int DiskInfo(void);
 432 static int sbpcd_chk_disk_change(dev_t);
 433 
 434 /*==========================================================================*/
 435 
 436 /*
 437  * pattern for printk selection:
 438  *
 439  * (1<<DBG_INF)  necessary information
 440  * (1<<DBG_BSZ)  BLOCK_SIZE trace
 441  * (1<<DBG_REA)  "read" status trace
 442  * (1<<DBG_CHK)  "media check" trace
 443  * (1<<DBG_TIM)  datarate timer test
 444  * (1<<DBG_INI)  initialization trace
 445  * (1<<DBG_TOC)  tell TocEntry values
 446  * (1<<DBG_IOC)  ioctl trace
 447  * (1<<DBG_STA)  "ResponseStatus" trace
 448  * (1<<DBG_ERR)  "xx_ReadError" trace
 449  * (1<<DBG_CMD)  "cmd_out" trace
 450  * (1<<DBG_WRN)  give explanation before auto-probing
 451  * (1<<DBG_MUL)  multi session code test
 452  * (1<<DBG_ID)   "drive_id != 0" test code
 453  * (1<<DBG_IOX)  some special information
 454  * (1<<DBG_DID)  drive ID test
 455  * (1<<DBG_RES)  drive reset info
 456  * (1<<DBG_SPI)  SpinUp test info
 457  * (1<<DBG_IOS)  ioctl trace: "subchannel"
 458  * (1<<DBG_IO2)  ioctl trace: general
 459  * (1<<DBG_UPC)  show UPC info
 460  * (1<<DBG_XA)   XA mode debugging
 461  * (1<<DBG_LCK)  door (un)lock info
 462  * (1<<DBG_SQ)   dump SubQ frame
 463  * (1<<DBG_AUD)  "read audio" debugging
 464  * (1<<DBG_SEQ)  Sequoia interface configuration trace
 465  * (1<<DBG_LCS)  Longshine LCS-7260 debugging trace
 466  * (1<<DBG_CD2)  MKE CD200 debugging trace
 467  * (1<<DBG_000)  unnecessary information
 468  */
 469 #if DISTRIBUTION
 470 static int sbpcd_debug =  (1<<DBG_INF) |
 471                           (1<<DBG_WRN) |
 472                           (1<<DBG_MUL);
 473 #else
 474 static int sbpcd_debug =  (1<<DBG_INF) |
 475                           (1<<DBG_TOC) |
 476                           (1<<DBG_MUL) |
 477                           (1<<DBG_UPC);
 478 #endif DISTRIBUTION
 479 
 480 static int sbpcd_ioaddr = CDROM_PORT;   /* default I/O base address */
 481 static int sbpro_type = SBPRO;
 482 static unsigned char setup_done = 0;
 483 static int CDo_command, CDo_reset;
 484 static int CDo_sel_i_d, CDo_enable;
 485 static int CDi_info, CDi_status, CDi_data;
 486 static int MIXER_addr, MIXER_data;
 487 static struct cdrom_msf msf;
 488 static struct cdrom_ti ti;
 489 static struct cdrom_tochdr tochdr;
 490 static struct cdrom_tocentry tocentry;
 491 static struct cdrom_subchnl SC;
 492 static struct cdrom_volctrl volctrl;
 493 static struct cdrom_read_audio read_audio;
 494 static struct cdrom_multisession ms_info;
 495 
 496 static char *str_sb = "SoundBlaster";
 497 static char *str_sb_l = "soundblaster";
 498 static char *str_lm = "LaserMate";
 499 static char *str_sp = "SPEA";
 500 static char *str_sp_l = "spea";
 501 char *type;
 502 #if !(SBPCD_ISSUE-1)
 503 static char *major_name="sbpcd";
 504 #endif
 505 #if !(SBPCD_ISSUE-2)
 506 static char *major_name="sbpcd2";
 507 #endif
 508 #if !(SBPCD_ISSUE-3)
 509 static char *major_name="sbpcd3";
 510 #endif
 511 #if !(SBPCD_ISSUE-4)
 512 static char *major_name="sbpcd4";
 513 #endif
 514 
 515 /*==========================================================================*/
 516 
 517 #if FUTURE
 518 static struct wait_queue *sbp_waitq = NULL;
 519 #endif FUTURE
 520 
 521 /*==========================================================================*/
 522 #ifdef MODULE
 523 /* some restrictions for the "loadable" version */
 524 #define SBP_BUFFER_FRAMES 2 /* kmalloc() limit */
 525 #define SBP_BUFFER_AUDIO_FRAMES 0
 526 #else
 527 #define SBP_BUFFER_FRAMES 4 /* driver's own read_ahead, data mode */
 528 #define SBP_BUFFER_AUDIO_FRAMES READ_AUDIO /* buffer for read audio mode */
 529 #endif MODULE
 530 /*==========================================================================*/
 531 
 532 static u_char family0[]="MATSHITA"; /* MKE CR-52x */
 533 static u_char family1[]="CR-56"; /* MKE CR-56x */
 534 static u_char family2[]="CD200"; /* MKE CD200 */
 535 static u_char familyL[]="LCS-7260"; /* Longshine LCS-7260 */
 536 
 537 static u_int response_count=0;
 538 static u_int flags_cmd_out;
 539 static u_char cmd_type=0;
 540 static u_char drvcmd[10];
 541 static u_char infobuf[20];
 542 static u_char xa_head_buf[CD_XA_HEAD];
 543 static u_char xa_tail_buf[CD_XA_TAIL];
 544 
 545 static u_char busy_data=0, busy_audio=0; /* true semaphores would be safer */
 546 static u_char timed_out=0;
 547 static u_int datarate= 1000000;
 548 static u_int maxtim16=16000000;
 549 static u_int maxtim04= 4000000;
 550 static u_int maxtim02= 2000000;
 551 static u_int maxtim_8=   30000;
 552 #if LONG_TIMING
 553 static u_int maxtim_data= 9000;
 554 #else
 555 static u_int maxtim_data= 3000;
 556 #endif LONG_TIMING
 557 #if DISTRIBUTION
 558 static int n_retries=3;
 559 #else
 560 static int n_retries=1;
 561 #endif
 562 /*==========================================================================*/
 563 
 564 static int ndrives=0;
 565 static u_char drv_pattern[4]={speed_auto,speed_auto,speed_auto,speed_auto};
 566 static int sbpcd_blocksizes[NR_SBPCD] = {0, };
 567 
 568 /*==========================================================================*/
 569 /*
 570  * drive space begins here (needed separate for each unit) 
 571  */
 572 static int d=0; /* DriveStruct index: drive number */
 573 
 574 static struct {
 575   char drv_id; /* "jumpered" drive ID or -1 */
 576   char drv_sel; /* drive select lines bits */
 577 
 578   char drive_model[9];
 579   u_char firmware_version[4];
 580   char f_eject; /* auto-eject flag: 0 or 1 */
 581   u_char *sbp_buf; /* Pointer to internal data buffer,
 582                            space allocated during sbpcd_init() */
 583   int sbp_first_frame;  /* First frame in buffer */
 584   int sbp_last_frame;   /* Last frame in buffer  */
 585   int sbp_read_frames;   /* Number of frames being read to buffer */
 586   int sbp_current;       /* Frame being currently read */
 587 
 588   u_char mode;           /* read_mode: READ_M1, READ_M2, READ_SC, READ_AU */
 589   u_char *aud_buf;                  /* Pointer to audio data buffer,
 590                                  space allocated during sbpcd_init() */
 591   u_char drv_type;
 592   u_char drv_options;
 593   u_char status_byte;
 594   u_char diskstate_flags;
 595   u_char sense_byte;
 596   
 597   u_char CD_changed;
 598   u_char open_count;
 599   u_char error_byte;
 600   
 601   u_char f_multisession;
 602   u_int lba_multi;
 603   int first_session;
 604   int last_session;
 605   
 606   u_char audio_state;
 607   u_int pos_audio_start;
 608   u_int pos_audio_end;
 609   char vol_chan0;
 610   u_char vol_ctrl0;
 611   char vol_chan1;
 612   u_char vol_ctrl1;
 613 #if 000 /* no supported drive has it */
 614   char vol_chan2;
 615   u_char vol_ctrl2;
 616   char vol_chan3;
 617   u_char vol_ctrl3;
 618 #endif 000
 619   
 620   u_char SubQ_ctl_adr;
 621   u_char SubQ_trk;
 622   u_char SubQ_pnt_idx;
 623   u_int SubQ_run_tot;
 624   u_int SubQ_run_trk;
 625   u_char SubQ_whatisthis;
 626   
 627   u_char UPC_ctl_adr;
 628   u_char UPC_buf[7];
 629   
 630   int CDsize_blk;
 631   int frame_size;
 632   int CDsize_frm;
 633   
 634   u_char xa_byte; /* 0x20: XA capabilities */
 635   u_char n_first_track; /* binary */
 636   u_char n_last_track; /* binary (not bcd), 0x01...0x63 */
 637   u_int size_msf; /* time of whole CD, position of LeadOut track */
 638   u_int size_blk;
 639   
 640   u_char TocEnt_nixbyte; /* em */
 641   u_char TocEnt_ctl_adr;
 642   u_char TocEnt_number;
 643   u_char TocEnt_format; /* em */
 644   u_int TocEnt_address;
 645   u_char ored_ctl_adr; /* to detect if CDROM contains data tracks */
 646   
 647   struct {
 648     u_char nixbyte; /* em */
 649     u_char ctl_adr; /* 0x4x: data, 0x0x: audio */
 650     u_char number;
 651     u_char format; /* em */ /* 0x00: lba, 0x01: msf */
 652     u_int address;
 653   } TocBuffer[MAX_TRACKS+1]; /* last entry faked */ 
 654   
 655   int in_SpinUp;
 656   
 657 } DriveStruct[NR_SBPCD];
 658 
 659 /*
 660  * drive space ends here (needed separate for each unit)
 661  */
 662 /*==========================================================================*/
 663 /*==========================================================================*/
 664 /*
 665  * DDI interface
 666  */
 667 static void sbpcd_dprintf(int level, char *fmt, ...)
     /* [previous][next][first][last][top][bottom][index][help] */
 668 {
 669   char buff[256];
 670   va_list args;
 671   extern int vsprintf(char *buf, const char *fmt, va_list args);
 672 
 673   if (! (sbpcd_debug & (1 << level))) return;
 674 
 675   va_start(args, fmt);
 676   vsprintf(buff, fmt, args);
 677   va_end(args);
 678   printk(buff);
 679 #if PRINTK_BUG
 680   sti(); /* to avoid possible "printk" bug */
 681 #endif
 682 }
 683 
 684 /*
 685  * DDI interface: runtime trace bit pattern maintenance
 686  */
 687 static int sbpcd_dbg_ioctl(unsigned long arg, int level)
     /* [previous][next][first][last][top][bottom][index][help] */
 688 {
 689   int val;
 690 
 691   val = get_fs_long((int *) arg);
 692   switch(val)
 693     {
 694     case 0:     /* OFF */
 695       sbpcd_debug = 0;
 696       break;
 697 
 698     default:
 699       if (val >= 128) sbpcd_debug &= ~(1 << (val - 128));
 700       else sbpcd_debug |= (1 << val);
 701     }
 702   return(0);
 703 }
 704 
 705 /*==========================================================================*/
 706 /*==========================================================================*/
 707 /*
 708  * Wait a little while (used for polling the drive).  If in initialization,
 709  * setting a timeout doesn't work, so just loop for a while.
 710  */
 711 static INLINE void sbp_sleep(u_int jifs)
     /* [previous][next][first][last][top][bottom][index][help] */
 712 {
 713   sti();
 714   current->state = TASK_INTERRUPTIBLE;
 715   current->timeout = jiffies + jifs;
 716   schedule();
 717   sti();
 718 }
 719 
 720 /*==========================================================================*/
 721 /*==========================================================================*/
 722 /*
 723  *  convert logical_block_address to m-s-f_number (3 bytes only)
 724  */
 725 static INLINE void lba2msf(int lba, u_char *msf)
     /* [previous][next][first][last][top][bottom][index][help] */
 726 {
 727   lba += CD_BLOCK_OFFSET;
 728   msf[0] = lba / (CD_SECS*CD_FRAMES);
 729   lba %= CD_SECS*CD_FRAMES;
 730   msf[1] = lba / CD_FRAMES;
 731   msf[2] = lba % CD_FRAMES;
 732 }
 733 /*==========================================================================*/
 734 /*==========================================================================*/
 735 /*
 736  *  convert msf-bin to msf-bcd
 737  */
 738 static INLINE void bin2bcdx(u_char *p)  /* must work only up to 75 or 99 */
     /* [previous][next][first][last][top][bottom][index][help] */
 739 {
 740   *p=((*p/10)<<4)|(*p%10);
 741 }
 742 /*==========================================================================*/
 743 static INLINE u_int blk2msf(u_int blk)
     /* [previous][next][first][last][top][bottom][index][help] */
 744 {
 745   MSF msf;
 746   u_int mm;
 747 
 748   msf.c[3] = 0;
 749   msf.c[2] = (blk + CD_BLOCK_OFFSET) / (CD_SECS * CD_FRAMES);
 750   mm = (blk + CD_BLOCK_OFFSET) % (CD_SECS * CD_FRAMES);
 751   msf.c[1] = mm / CD_FRAMES;
 752   msf.c[0] = mm % CD_FRAMES;
 753   return (msf.n);
 754 }
 755 /*==========================================================================*/
 756 static INLINE u_int make16(u_char rh, u_char rl)
     /* [previous][next][first][last][top][bottom][index][help] */
 757 {
 758   return ((rh<<8)|rl);
 759 }
 760 /*==========================================================================*/
 761 static INLINE u_int make32(u_int rh, u_int rl)
     /* [previous][next][first][last][top][bottom][index][help] */
 762 {
 763   return ((rh<<16)|rl);
 764 }
 765 /*==========================================================================*/
 766 static INLINE u_char swap_nibbles(u_char i)
     /* [previous][next][first][last][top][bottom][index][help] */
 767 {
 768   return ((i<<4)|(i>>4));
 769 }
 770 /*==========================================================================*/
 771 static INLINE u_char byt2bcd(u_char i)
     /* [previous][next][first][last][top][bottom][index][help] */
 772 {
 773   return (((i/10)<<4)+i%10);
 774 }
 775 /*==========================================================================*/
 776 static INLINE u_char bcd2bin(u_char bcd)
     /* [previous][next][first][last][top][bottom][index][help] */
 777 {
 778   return ((bcd>>4)*10+(bcd&0x0F));
 779 }
 780 /*==========================================================================*/
 781 static INLINE int msf2blk(int msfx)
     /* [previous][next][first][last][top][bottom][index][help] */
 782 {
 783   MSF msf;
 784   int i;
 785 
 786   msf.n=msfx;
 787   i=(msf.c[2] * CD_SECS + msf.c[1]) * CD_FRAMES + msf.c[0] - CD_BLOCK_OFFSET;
 788   if (i<0) return (0);
 789   return (i);
 790 }
 791 /*==========================================================================*/
 792 /*
 793  *  convert m-s-f_number (3 bytes only) to logical_block_address 
 794  */
 795 static INLINE int msf2lba(u_char *msf)
     /* [previous][next][first][last][top][bottom][index][help] */
 796 {
 797   int i;
 798 
 799   i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_BLOCK_OFFSET;
 800   if (i<0) return (0);
 801   return (i);
 802 }
 803 /*==========================================================================*/
 804 /* evaluate xx_ReadError code (still mysterious) */ 
 805 static int sta2err(int sta)
     /* [previous][next][first][last][top][bottom][index][help] */
 806 {
 807   if (sta<=2) return (sta);
 808   if (sta==0x05) return (-4); /* CRC error */
 809   if (sta==0x06) return (-6); /* seek error */
 810   if (sta==0x0d) return (-6); /* seek error */
 811   if (sta==0x0e) return (-3); /* unknown command */
 812   if (sta==0x14) return (-3); /* unknown command */
 813   if (sta==0x0c) return (-11); /* read fault */
 814   if (sta==0x0f) return (-11); /* read fault */
 815   if (sta==0x10) return (-11); /* read fault */
 816   if (sta>=0x16) return (-12); /* general failure */
 817   DriveStruct[d].CD_changed=0xFF;
 818   if (sta==0x11) return (-15); /* invalid disk change (LCS: removed) */
 819   if (famL_drive)
 820     if (sta==0x12) return (-15); /* invalid disk change (inserted) */
 821   return (-2); /* drive not ready */
 822 }
 823 /*==========================================================================*/
 824 static INLINE void clr_cmdbuf(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 825 {
 826   int i;
 827 
 828   for (i=0;i<10;i++) drvcmd[i]=0;
 829   cmd_type=0;
 830 }
 831 /*==========================================================================*/
 832 static void mark_timeout(unsigned long i)
     /* [previous][next][first][last][top][bottom][index][help] */
 833 {
 834   timed_out=1;
 835   DPRINTF((DBG_TIM,"SBPCD: timer expired.\n"));
 836 }
 837 /*==========================================================================*/
 838 static struct timer_list delay_timer = { NULL, NULL, 0, 0, mark_timeout};
 839 #if 0
 840 static struct timer_list data_timer = { NULL, NULL, 0, 0, mark_timeout};
 841 static struct timer_list audio_timer = { NULL, NULL, 0, 0, mark_timeout};
 842 #endif
 843 /*==========================================================================*/
 844 static void flush_status(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 845 {
 846 #ifdef CDMKE
 847   int i;
 848 
 849 #ifdef MODULE
 850   sbp_sleep(150);
 851   for (i=maxtim_data;i!=0;i--) inb(CDi_status);
 852 #else
 853   if (current == task[0])
 854     for (i=maxtim02;i!=0;i--) inb(CDi_status);
 855   else 
 856     {
 857       sbp_sleep(150);
 858       for (i=maxtim_data;i!=0;i--) inb(CDi_status);
 859     }
 860 #endif MODULE
 861 #else
 862   timed_out=0;
 863 #if 0
 864   del_timer(&delay_timer);
 865 #endif
 866   delay_timer.expires = 150;
 867   add_timer(&delay_timer);
 868   do { }
 869   while (!timed_out);
 870 #if 0
 871   del_timer(&delay_timer);
 872 #endif 0
 873   inb(CDi_status);
 874 #endif CDMKE
 875 }
 876 /*==========================================================================*/
 877 static int CDi_stat_loop(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 878 {
 879   int i,j;
 880   u_long timeout;
 881   
 882 #ifdef MODULE
 883     for(timeout = jiffies + 1000, i=maxtim_data; timeout > jiffies; )
 884       {
 885         for ( ;i!=0;i--)
 886           {
 887             j=inb(CDi_status);
 888             if (!(j&s_not_data_ready)) return (j);
 889             if (!(j&s_not_result_ready)) return (j);
 890             if (fam0L_drive) if (j&s_attention) return (j);
 891           }
 892         sbp_sleep(1);
 893         i = 1;
 894       }
 895 #else
 896   if (current == task[0])
 897     for(i=maxtim16;i!=0;i--)
 898       {
 899         j=inb(CDi_status);
 900         if (!(j&s_not_data_ready)) return (j);
 901         if (!(j&s_not_result_ready)) return (j);
 902         if (fam0L_drive) if (j&s_attention) return (j);
 903       }
 904   else
 905     for(timeout = jiffies + 1000, i=maxtim_data; timeout > jiffies; )
 906       {
 907         for ( ;i!=0;i--)
 908           {
 909             j=inb(CDi_status);
 910             if (!(j&s_not_data_ready)) return (j);
 911             if (!(j&s_not_result_ready)) return (j);
 912             if (fam0L_drive) if (j&s_attention) return (j);
 913           }
 914         sbp_sleep(1);
 915         i = 1;
 916       }
 917 #endif MODULE
 918   DPRINTF((DBG_LCS,"SBPCD: CDi_stat_loop failed\n"));
 919   return (-1);
 920 }
 921 /*==========================================================================*/
 922 static int ResponseInfo(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 923 {
 924   int i,j, st=0;
 925   u_long timeout;
 926 
 927   DPRINTF((DBG_000,"SBPCD: ResponseInfo entered.\n"));
 928 #ifdef MODULE
 929   for (i=0, timeout = jiffies + 100; i < response_count; i++) 
 930     {
 931       for (j=maxtim_data; ; )
 932         {
 933           for ( ;j!=0;j-- )
 934             {
 935               st=inb(CDi_status);
 936               if (!(st&s_not_result_ready)) break;
 937             }
 938           if (j != 0 || timeout <= jiffies) break;
 939           sbp_sleep(0);
 940           j = 1;
 941         }
 942       if (timeout <= jiffies) return (-1);
 943       infobuf[i]=inb(CDi_info);
 944     }
 945 #else
 946   if (current == task[0])
 947     for (i=0;i<response_count;i++)
 948       {
 949         for (j=maxtim_8;j!=0;j--)
 950           {
 951             st=inb(CDi_status);
 952             if (!(st&s_not_result_ready)) break;
 953           }
 954         if (j==0)
 955           {
 956             DPRINTF((DBG_SEQ,"SBPCD: ResponseInfo: not_result_ready (got %d of %d bytes).\n", i, response_count));
 957             return (-1);
 958           }
 959         infobuf[i]=inb(CDi_info);
 960       }
 961   else 
 962     {
 963       for (i=0, timeout = jiffies + 100; i < response_count; i++) 
 964         {
 965           for (j=maxtim_data; ; )
 966             {
 967               for ( ;j!=0;j-- )
 968                 {
 969                   st=inb(CDi_status);
 970                   if (!(st&s_not_result_ready)) break;
 971                 }
 972               if (j != 0 || timeout <= jiffies) break;
 973               sbp_sleep(0);
 974               j = 1;
 975             }
 976           if (timeout <= jiffies) return (-1);
 977           infobuf[i]=inb(CDi_info);
 978         }
 979     }
 980 #endif MODULE
 981   DPRINTF((DBG_000,"SBPCD: ResponseInfo: done.\n"));
 982   return (0);
 983 }
 984 /*==========================================================================*/
 985 static void EvaluateStatus(int st)
     /* [previous][next][first][last][top][bottom][index][help] */
 986 {
 987   DriveStruct[d].status_byte=0;
 988   if (fam0_drive)
 989     {
 990       if (st&p_caddin_old) DriveStruct[d].status_byte |= p_door_closed|p_caddy_in;
 991       if (st&p_spinning) DriveStruct[d].status_byte |= p_spinning;
 992       if (st&p_check) DriveStruct[d].status_byte |= p_check;
 993       if (st&p_busy_old) DriveStruct[d].status_byte |= p_busy_new;
 994       if (st&p_disk_ok) DriveStruct[d].status_byte |= p_disk_ok;
 995     }
 996   else if (famL_drive)
 997     {
 998       if (st&p_caddin_old) DriveStruct[d].status_byte |= p_disk_ok|p_caddy_in;
 999       if (st&p_spinning) DriveStruct[d].status_byte |= p_spinning;
1000       if (st&p_check) DriveStruct[d].status_byte |= p_check;
1001       if (st&p_busy_old) DriveStruct[d].status_byte |= p_busy_new;
1002       if (st&p_lcs_door_closed) DriveStruct[d].status_byte |= p_door_closed;
1003       if (st&p_lcs_door_locked) DriveStruct[d].status_byte |= p_door_locked;
1004     }
1005   else if (fam2_drive)
1006     {
1007       if (st&p2_check) DriveStruct[d].status_byte |= p1_check;
1008       if (st&p2_door_closed) DriveStruct[d].status_byte |= p1_door_closed;
1009       if (st&p2_disk_in) DriveStruct[d].status_byte |= p1_disk_in;
1010       if (st&p2_busy1) DriveStruct[d].status_byte |= p1_busy;
1011       if (st&p2_busy2) DriveStruct[d].status_byte |= p1_busy;
1012       if (st&p2_spinning) DriveStruct[d].status_byte |= p1_spinning;
1013       if (st&p2_door_locked) DriveStruct[d].status_byte |= p1_door_locked;
1014       if (st&p2_disk_ok) DriveStruct[d].status_byte |= p1_disk_ok;
1015     }
1016   else if (fam1_drive) DriveStruct[d].status_byte=st;
1017   return;
1018 }
1019 /*==========================================================================*/
1020 static int ResponseStatus(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1021 {
1022   int i,j;
1023   u_long timeout;
1024 
1025   DPRINTF((DBG_STA,"SBPCD: doing ResponseStatus...\n"));
1026 #ifdef MODULE
1027   if (flags_cmd_out & f_respo3) timeout = jiffies;
1028   else if (flags_cmd_out & f_respo2) timeout = jiffies + 1600;
1029   else timeout = jiffies + 400;
1030   j=maxtim_8;
1031   do
1032     {
1033       for ( ;j!=0;j--)
1034         { 
1035           i=inb(CDi_status);
1036           if (!(i&s_not_result_ready)) break;
1037         }
1038       if (j != 0 || timeout <= jiffies) break;
1039       sbp_sleep(0);
1040       j = 1;
1041     }
1042   while (1);
1043 #else
1044   if (current == task[0])
1045     {
1046       if (flags_cmd_out & f_respo3) j = maxtim_8;
1047       else if (flags_cmd_out&f_respo2) j=maxtim16;
1048       else j=maxtim04;
1049       for (;j!=0;j--)
1050         {
1051           i=inb(CDi_status);
1052           if (!(i&s_not_result_ready)) break;
1053         }
1054     }
1055   else
1056     {
1057       if (flags_cmd_out & f_respo3) timeout = jiffies;
1058       else if (flags_cmd_out & f_respo2) timeout = jiffies + 1600;
1059       else timeout = jiffies + 400;
1060       j=maxtim_8;
1061       do
1062         {
1063           for ( ;j!=0;j--)
1064             { 
1065               i=inb(CDi_status);
1066               if (!(i&s_not_result_ready)) break;
1067             }
1068           if (j != 0 || timeout <= jiffies) break;
1069           sbp_sleep(0);
1070           j = 1;
1071         }
1072       while (1);
1073     }
1074 #endif MODULE
1075   if (j==0) 
1076     { if ((flags_cmd_out & f_respo3) == 0)
1077         DPRINTF((DBG_STA,"SBPCD: ResponseStatus: timeout.\n"));
1078       DriveStruct[d].status_byte=0;
1079       return (-1);
1080     }
1081   i=inb(CDi_info);
1082   DPRINTF((DBG_STA,"SBPCD: ResponseStatus: response %2X.\n", i));
1083   EvaluateStatus(i);
1084   return (i);
1085 }
1086 /*==========================================================================*/
1087 static void xx_ReadStatus(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1088 {
1089   int i;
1090 
1091   DPRINTF((DBG_STA,"SBPCD: giving xx_ReadStatus command\n"));
1092   SBPCD_CLI;
1093   if (fam0L_drive) OUT(CDo_command,CMD0_STATUS);
1094   else if (fam1_drive) OUT(CDo_command,CMD1_STATUS);
1095   else if (fam2_drive) OUT(CDo_command,CMD2_STATUS);
1096   if (!fam0L_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
1097   SBPCD_STI;
1098 }
1099 /*==========================================================================*/
1100 static int xx_ReadError(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1101 {
1102   int i;
1103 
1104   clr_cmdbuf();
1105   DPRINTF((DBG_ERR,"SBPCD: giving xx_ReadError command.\n"));
1106   if (fam1_drive)
1107     {
1108       drvcmd[0]=CMD1_READ_ERR;
1109       response_count=8;
1110       flags_cmd_out=f_putcmd|f_ResponseStatus;
1111     }
1112   else if (fam0L_drive)
1113     {
1114       drvcmd[0]=CMD0_READ_ERR;
1115       response_count=6;
1116       if (famL_drive)
1117         flags_cmd_out=f_putcmd;
1118       else
1119         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
1120     }
1121   else if (fam2_drive)
1122     {
1123       drvcmd[0]=CMD2_READ_ERR;
1124       response_count=6;
1125       flags_cmd_out=f_putcmd;
1126     }
1127   i=cmd_out(7);
1128   DriveStruct[d].error_byte=0;
1129   DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: cmd_out(82) returns %d (%02X)\n",i,i));
1130   if (i<0) return (i);
1131   if (fam0_drive) i=1;
1132   else i=2;
1133   DriveStruct[d].error_byte=infobuf[i];
1134   DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: infobuf[%d] is %d (%02X)\n",i,DriveStruct[d].error_byte,DriveStruct[d].error_byte));
1135   i=sta2err(infobuf[i]);
1136   return (i);
1137 }
1138 /*==========================================================================*/
1139 static int cmd_out(int len)
     /* [previous][next][first][last][top][bottom][index][help] */
1140 {
1141   int i=0;
1142 
1143   if (flags_cmd_out&f_putcmd)
1144     { 
1145       DPRINTF((DBG_CMD,"SBPCD: cmd_out: put"));
1146       for (i=0;i<len;i++) DPRINTF((DBG_CMD," %02X",drvcmd[i]));
1147       DPRINTF((DBG_CMD,"\n"));
1148 
1149       cli();
1150       for (i=0;i<len;i++) OUT(CDo_command,drvcmd[i]);
1151       sti();
1152     }
1153   if (response_count!=0)
1154     {
1155       if (cmd_type!=0)
1156         {
1157           if (sbpro_type==1) OUT(CDo_sel_i_d,1);
1158           DPRINTF((DBG_INF,"SBPCD: misleaded to try ResponseData.\n"));
1159           if (sbpro_type==1) OUT(CDo_sel_i_d,0);
1160           return (-22);
1161         }
1162       else i=ResponseInfo();
1163       if (i<0) return (-9);
1164     }
1165   if (DriveStruct[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to CDi_stat_loop.\n"));
1166   if (flags_cmd_out&f_lopsta)
1167     {
1168       i=CDi_stat_loop();
1169       if ((i<0)||!(i&s_attention)) return (-9);
1170     }
1171   if (!(flags_cmd_out&f_getsta)) goto LOC_229;
1172   
1173 LOC_228:
1174   if (DriveStruct[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to xx_ReadStatus.\n"));
1175   xx_ReadStatus();
1176 
1177 LOC_229:
1178   if (flags_cmd_out&f_ResponseStatus) 
1179     {
1180       if (DriveStruct[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to ResponseStatus.\n"));
1181       i=ResponseStatus();
1182                    /* builds status_byte, returns orig. status or p_busy_new */
1183       if (i<0) return (-9);
1184       if (flags_cmd_out&(f_bit1|f_wait_if_busy))
1185         {
1186           if (!st_check)
1187             {
1188               if (flags_cmd_out&f_bit1) if (i&p_success_old) goto LOC_232;
1189               if (!(flags_cmd_out&f_wait_if_busy)) goto LOC_228;
1190               if (!st_busy) goto LOC_228;
1191             }
1192         }
1193     }
1194 LOC_232:
1195   if (!(flags_cmd_out&f_obey_p_check)) return (0);
1196   if (!st_check) return (0);
1197   if (DriveStruct[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to xx_ReadError.\n"));
1198   i=xx_ReadError();
1199   if (DriveStruct[d].in_SpinUp != 0) DPRINTF((DBG_SPI,"SBPCD: to cmd_out OK.\n"));
1200   return (i);
1201 }
1202 /*==========================================================================*/
1203 static int xx_Seek(u_int pos, char f_blk_msf)
     /* [previous][next][first][last][top][bottom][index][help] */
1204 {
1205   int i;
1206 
1207   clr_cmdbuf();
1208   if (f_blk_msf>1) return (-3);
1209   if (fam0_drive)
1210     {
1211       drvcmd[0]=CMD0_SEEK;
1212       if (f_blk_msf==1) pos=msf2blk(pos);
1213       drvcmd[2]=(pos>>16)&0x00FF;
1214       drvcmd[3]=(pos>>8)&0x00FF;
1215       drvcmd[4]=pos&0x00FF;
1216       flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
1217                       f_ResponseStatus | f_obey_p_check | f_bit1;
1218     }
1219   else if (fam1L_drive)
1220     {
1221       drvcmd[0]=CMD1_SEEK; /* same as CMD1_ and CMDL_ */
1222       if (f_blk_msf==0) pos=blk2msf(pos);
1223       drvcmd[1]=(pos>>16)&0x00FF;
1224       drvcmd[2]=(pos>>8)&0x00FF;
1225       drvcmd[3]=pos&0x00FF;
1226       if (famL_drive)
1227         flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1228       else
1229         flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1230     }
1231   else if (fam2_drive)
1232     {
1233       drvcmd[0]=CMD2_SEEK;
1234       if (f_blk_msf==0) pos=blk2msf(pos);
1235       drvcmd[2]=(pos>>16)&0x00FF;
1236       drvcmd[3]=(pos>>16)&0x00FF;
1237       drvcmd[4]=(pos>>8)&0x00FF;
1238       drvcmd[5]=pos&0x00FF;
1239       flags_cmd_out=f_putcmd|f_ResponseStatus;
1240     }
1241   response_count=0;
1242   i=cmd_out(7);
1243   return (i);
1244 }
1245 /*==========================================================================*/
1246 static int xx_SpinUp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1247 {
1248   int i;
1249 
1250   DPRINTF((DBG_SPI,"SBPCD: SpinUp.\n"));
1251   DriveStruct[d].in_SpinUp = 1;
1252   clr_cmdbuf();
1253   if (fam0L_drive)
1254     {
1255       drvcmd[0]=CMD0_SPINUP;
1256       flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
1257         f_ResponseStatus|f_obey_p_check|f_bit1;
1258     }
1259   else if (fam1_drive)
1260     {
1261       drvcmd[0]=CMD1_SPINUP;
1262       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1263     }
1264   else if (fam2_drive)
1265     {
1266       drvcmd[0]=CMD2_TRAY_CTL;
1267       drvcmd[4]=0x01;
1268       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1269     }
1270   response_count=0;
1271   i=cmd_out(7);
1272   DriveStruct[d].in_SpinUp = 0;
1273   return (i);
1274 }
1275 /*==========================================================================*/
1276 static int yy_SpinDown(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1277 {
1278   int i;
1279 
1280   if (fam0_drive) return (-3);
1281   clr_cmdbuf();
1282   response_count=0;
1283   if (fam1_drive)
1284     {
1285       drvcmd[0]=CMD1_SPINDOWN;
1286       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1287     }
1288   else if (fam2_drive)
1289     {
1290       drvcmd[0]=CMD2_TRAY_CTL;
1291       drvcmd[4]=0x02; /* "eject" */
1292       flags_cmd_out=f_putcmd|f_ResponseStatus;
1293     }
1294   else if (famL_drive)
1295     {
1296       drvcmd[0]=CMDL_SPINDOWN;
1297       drvcmd[1]=1;
1298       flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1299     }
1300   i=cmd_out(7);
1301   return (i);
1302 }
1303 /*==========================================================================*/
1304 static int yy_SetSpeed(u_char speed, u_char x1, u_char x2)
     /* [previous][next][first][last][top][bottom][index][help] */
1305 {
1306   int i;
1307 
1308   if (fam0L_drive) return (-3);
1309   clr_cmdbuf();
1310   response_count=0;
1311   if (fam1_drive)
1312     {
1313       drvcmd[0]=CMD1_SETMODE;
1314       drvcmd[1]=0x03;
1315       drvcmd[2]=speed;
1316       drvcmd[3]=x1;
1317       drvcmd[4]=x2;
1318       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1319     }
1320   else if (fam2_drive)
1321     {
1322       drvcmd[0]=CMD2_SETSPEED;
1323       if (speed&speed_auto)
1324         {
1325           drvcmd[2]=0xFF;
1326           drvcmd[3]=0xFF;
1327         }
1328       else
1329         {
1330           drvcmd[2]=0;
1331           drvcmd[3]=150;
1332         }
1333       flags_cmd_out=f_putcmd|f_ResponseStatus;
1334     }
1335   i=cmd_out(7);
1336   return (i);
1337 }
1338 /*==========================================================================*/
1339 static int xx_SetVolume(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1340 {
1341   int i;
1342   u_char channel0,channel1,volume0,volume1;
1343   u_char control0,value0,control1,value1;
1344 
1345   DriveStruct[d].diskstate_flags &= ~volume_bit;
1346   clr_cmdbuf();
1347   channel0=DriveStruct[d].vol_chan0;
1348   volume0=DriveStruct[d].vol_ctrl0;
1349   channel1=control1=DriveStruct[d].vol_chan1;
1350   volume1=value1=DriveStruct[d].vol_ctrl1;
1351   control0=value0=0;
1352 
1353   if (((DriveStruct[d].drv_options&audio_mono)!=0)&&(DriveStruct[d].drv_type>=drv_211))
1354     {
1355       if ((volume0!=0)&&(volume1==0))
1356         {
1357           volume1=volume0;
1358           channel1=channel0;
1359         }
1360       else if ((volume0==0)&&(volume1!=0))
1361         {
1362           volume0=volume1;
1363           channel0=channel1;
1364         }
1365     }
1366   if (channel0>1)
1367     {
1368       channel0=0;
1369       volume0=0;
1370     }
1371   if (channel1>1)
1372     {
1373       channel1=1;
1374       volume1=0;
1375     }
1376   
1377   if (fam1_drive)
1378     {
1379       control0=channel0+1;
1380       control1=channel1+1;
1381       value0=(volume0>volume1)?volume0:volume1;
1382       value1=value0;
1383       if (volume0==0) control0=0;
1384       if (volume1==0) control1=0;
1385       drvcmd[0]=CMD1_SETMODE;
1386       drvcmd[1]=0x05;
1387       drvcmd[3]=control0;
1388       drvcmd[4]=value0;
1389       drvcmd[5]=control1;
1390       drvcmd[6]=value1;
1391       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1392     }
1393   else if (fam2_drive)
1394     {
1395       control0=channel0+1;
1396       control1=channel1+1;
1397       value0=(volume0>volume1)?volume0:volume1;
1398       value1=value0;
1399       if (volume0==0) control0=0;
1400       if (volume1==0) control1=0;
1401       drvcmd[0]=CMD2_SETMODE;
1402       drvcmd[1]=0x0E;
1403       drvcmd[3]=control0;
1404       drvcmd[4]=value0;
1405       drvcmd[5]=control1;
1406       drvcmd[6]=value1;
1407       flags_cmd_out=f_putcmd|f_ResponseStatus;
1408     }
1409   else if (famL_drive)
1410     {
1411       if ((volume0==0)||(channel0!=0)) control0 |= 0x80;
1412       if ((volume1==0)||(channel1!=1)) control0 |= 0x40;
1413       if (volume0|volume1) value0=0x80;
1414       drvcmd[0]=CMDL_SETMODE;
1415       drvcmd[1]=0x03;
1416       drvcmd[4]=control0;
1417       drvcmd[5]=value0;
1418       flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1419     }
1420   else if (fam0_drive) /* different firmware levels */
1421     {
1422       if (DriveStruct[d].drv_type>=drv_300)
1423         {
1424           control0=volume0&0xFC;
1425           value0=volume1&0xFC;
1426           if ((volume0!=0)&&(volume0<4)) control0 |= 0x04;
1427           if ((volume1!=0)&&(volume1<4)) value0 |= 0x04;
1428           if (channel0!=0) control0 |= 0x01;
1429           if (channel1==1) value0 |= 0x01;
1430         }
1431       else
1432         {
1433           value0=(volume0>volume1)?volume0:volume1;
1434           if (DriveStruct[d].drv_type<drv_211)
1435             {
1436               if (channel0!=0)
1437                 {
1438                   i=channel1;
1439                   channel1=channel0;
1440                   channel0=i;
1441                   i=volume1;
1442                   volume1=volume0;
1443                   volume0=i;
1444                 }
1445               if (channel0==channel1)
1446                 {
1447                   if (channel0==0)
1448                     {
1449                       channel1=1;
1450                       volume1=0;
1451                       volume0=value0;
1452                     }
1453                   else
1454                     {
1455                       channel0=0;
1456                       volume0=0;
1457                       volume1=value0;
1458                     }
1459                 }
1460             }
1461 
1462           if ((volume0!=0)&&(volume1!=0))
1463             {
1464               if (volume0==0xFF) volume1=0xFF;
1465               else if (volume1==0xFF) volume0=0xFF;
1466             }
1467           else if (DriveStruct[d].drv_type<drv_201) volume0=volume1=value0;
1468 
1469           if (DriveStruct[d].drv_type>=drv_201)
1470             {
1471               if (volume0==0) control0 |= 0x80;
1472               if (volume1==0) control0 |= 0x40;
1473             }
1474           if (DriveStruct[d].drv_type>=drv_211)
1475             {
1476               if (channel0!=0) control0 |= 0x20;
1477               if (channel1!=1) control0 |= 0x10;
1478             }
1479         }
1480       drvcmd[0]=CMD0_SETMODE;
1481       drvcmd[1]=0x83;
1482       drvcmd[4]=control0;
1483       drvcmd[5]=value0;
1484       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1485     }
1486   response_count=0;
1487   i=cmd_out(7);
1488   if (i>0) return (i);
1489   DriveStruct[d].diskstate_flags |= volume_bit;
1490   return (0);
1491 }
1492 /*==========================================================================*/
1493 static int GetStatus(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1494 {
1495   int i;
1496 
1497   flags_cmd_out=f_getsta|f_ResponseStatus|f_obey_p_check;
1498   response_count=0;
1499   cmd_type=0;
1500   i=cmd_out(7);
1501   return (i);
1502 }
1503 /*==========================================================================*/
1504 static int xy_DriveReset(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1505 {
1506   int i;
1507 
1508   DPRINTF((DBG_RES,"SBPCD: xy_DriveReset called.\n"));
1509   clr_cmdbuf();
1510   response_count=0;
1511   if (fam0L_drive) OUT(CDo_reset,0x00);
1512   else if (fam1_drive)
1513     {
1514       drvcmd[0]=CMD1_RESET;
1515       flags_cmd_out=f_putcmd;
1516       i=cmd_out(7);
1517     }
1518   else if (fam2_drive)
1519     {
1520       drvcmd[0]=CMD2_RESET;
1521       flags_cmd_out=f_putcmd;
1522       i=cmd_out(7);
1523       OUT(CDo_reset,0x00);
1524     }
1525   if (famL_drive) sbp_sleep(500); /* wait 5 seconds */
1526   else sbp_sleep(100); /* wait a second */
1527   flush_status();
1528   i=GetStatus();
1529   if (i>=0) return -1;
1530   if (DriveStruct[d].error_byte!=aud_12) return -1;
1531   return (0);
1532 }
1533 /*==========================================================================*/
1534 static int SetSpeed(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1535 {
1536   int i, speed;
1537 
1538   if (!(DriveStruct[d].drv_options&(speed_auto|speed_300|speed_150))) return (0);
1539   speed=speed_auto;
1540   if (!(DriveStruct[d].drv_options&speed_auto))
1541     {
1542       speed |= speed_300;
1543       if (!(DriveStruct[d].drv_options&speed_300)) speed=0;
1544     }
1545   i=yy_SetSpeed(speed,0,0);
1546   return (i);
1547 }
1548 /*==========================================================================*/
1549 static int DriveReset(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1550 {
1551   int i;
1552 
1553   i=xy_DriveReset();
1554   if (i<0) return (-2);
1555   do
1556     {
1557       i=GetStatus();
1558       if ((i<0)&&(i!=-15)) return (-2); /* i!=-15 is from sta2err */
1559       if (!st_caddy_in) break;
1560     }
1561   while (!st_diskok);
1562 #if 000
1563   DriveStruct[d].CD_changed=1;
1564 #endif
1565   if ((st_door_closed) && (st_caddy_in))
1566     {
1567       i=DiskInfo();
1568       if (i<0) return (-2);
1569     }
1570   return (0);
1571 }
1572 /*==========================================================================*/
1573 static int xx_Pause_Resume(int pau_res)
     /* [previous][next][first][last][top][bottom][index][help] */
1574 {
1575   int i;
1576 
1577   clr_cmdbuf();
1578   response_count=0;
1579   if (fam1_drive)
1580     {
1581       drvcmd[0]=CMD1_PAU_RES;
1582       if (pau_res!=1) drvcmd[1]=0x80;
1583       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1584     }
1585   else if (fam2_drive)
1586     {
1587       drvcmd[0]=CMD2_PAU_RES;
1588       if (pau_res!=1) drvcmd[2]=0x01;
1589       flags_cmd_out=f_putcmd|f_ResponseStatus;
1590     }
1591   else if (fam0L_drive)
1592     {
1593       drvcmd[0]=CMD0_PAU_RES;
1594       if (pau_res!=1) drvcmd[1]=0x80;
1595       if (famL_drive)
1596         flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
1597           f_obey_p_check|f_bit1;
1598       else
1599         flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
1600           f_obey_p_check;
1601     }
1602   i=cmd_out(7);
1603   return (i);
1604 }
1605 /*==========================================================================*/
1606 static int yy_LockDoor(char lock)
     /* [previous][next][first][last][top][bottom][index][help] */
1607 {
1608   int i;
1609 
1610   if (fam0_drive) return (0);
1611   DPRINTF((DBG_LCK,"SBPCD: yy_LockDoor: %d (drive %d)\n", lock, d));
1612   DPRINTF((DBG_LCS,"SBPCD: p_door_locked bit %d before\n", st_door_locked));
1613   clr_cmdbuf();
1614   response_count=0;
1615   if (fam1_drive)
1616     {
1617       drvcmd[0]=CMD1_LOCK_CTL;
1618       if (lock==1) drvcmd[1]=0x01;
1619       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1620     }
1621   else if (fam2_drive)
1622     {
1623       drvcmd[0]=CMD2_LOCK_CTL;
1624       if (lock==1) drvcmd[4]=0x01;
1625       flags_cmd_out=f_putcmd|f_ResponseStatus;
1626     }
1627   else if (famL_drive)
1628     {
1629       drvcmd[0]=CMDL_LOCK_CTL;
1630       if (lock==1) drvcmd[1]=0x01;
1631       flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
1632     }
1633   i=cmd_out(7);
1634   DPRINTF((DBG_LCS,"SBPCD: p_door_locked bit %d after\n", st_door_locked));
1635   return (i);
1636 }
1637 /*==========================================================================*/
1638 static int yy_CloseTray(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1639 {
1640   int i;
1641 
1642   if (fam0_drive) return (0);
1643   DPRINTF((DBG_LCK,"SBPCD: yy_CloseTray (drive %d)\n", d));
1644   DPRINTF((DBG_LCS,"SBPCD: p_door_closed bit %d before\n", st_door_closed));
1645 
1646   clr_cmdbuf();
1647   response_count=0;
1648   if (fam1_drive)
1649     {
1650       drvcmd[0]=CMD1_TRAY_CTL;
1651       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
1652     }
1653   else if (fam2_drive)
1654     {
1655       drvcmd[0]=CMD2_TRAY_CTL;
1656       drvcmd[1]=0x01;
1657       drvcmd[4]=0x03; /* "insert" */
1658       flags_cmd_out=f_putcmd|f_ResponseStatus;
1659     }
1660   else if (famL_drive)
1661     {
1662       drvcmd[0]=CMDL_TRAY_CTL;
1663       flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
1664         f_ResponseStatus|f_obey_p_check|f_bit1;
1665     }
1666   i=cmd_out(7);
1667   DPRINTF((DBG_LCS,"SBPCD: p_door_closed bit %d after\n", st_door_closed));
1668   return (i);
1669 }
1670 /*==========================================================================*/
1671 static int xx_ReadSubQ(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1672 {
1673   int i,j;
1674 
1675   DriveStruct[d].diskstate_flags &= ~subq_bit;
1676   for (j=255;j>0;j--)
1677     {
1678       clr_cmdbuf();
1679       if (fam1_drive)
1680         {
1681           drvcmd[0]=CMD1_READSUBQ;
1682           flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1683           response_count=11;
1684         }
1685       else if (fam2_drive)
1686         {
1687           drvcmd[0]=CMD2_READSUBQ;
1688           drvcmd[1]=0x02;
1689           drvcmd[3]=0x01;
1690           flags_cmd_out=f_putcmd;
1691           response_count=10;
1692         }
1693       else if (fam0L_drive)
1694         {
1695           drvcmd[0]=CMD0_READSUBQ;
1696           drvcmd[1]=0x02;
1697           if (famL_drive)
1698             flags_cmd_out=f_putcmd;
1699           else
1700             flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1701           response_count=13;
1702         }
1703       i=cmd_out(7);
1704       if (i<0) return (i);
1705       DPRINTF((DBG_SQ,"SBPCD: xx_ReadSubQ:"));
1706       for (i=0;i<response_count;i++)
1707         {
1708           DPRINTF((DBG_SQ," %02X", infobuf[i]));
1709         }
1710       DPRINTF((DBG_SQ,"\n"));
1711       if (infobuf[0]!=0) break;
1712       if ((!st_spinning) || (j==1))
1713         {
1714           DriveStruct[d].SubQ_ctl_adr=DriveStruct[d].SubQ_trk=DriveStruct[d].SubQ_pnt_idx=DriveStruct[d].SubQ_whatisthis=0;
1715           DriveStruct[d].SubQ_run_tot=DriveStruct[d].SubQ_run_trk=0;
1716           return (0);
1717         }
1718     }
1719   DriveStruct[d].SubQ_ctl_adr=swap_nibbles(infobuf[1]);
1720   DriveStruct[d].SubQ_trk=byt2bcd(infobuf[2]);
1721   DriveStruct[d].SubQ_pnt_idx=byt2bcd(infobuf[3]);
1722   i=4;
1723   if (fam0L_drive) i=5;
1724   DriveStruct[d].SubQ_run_tot=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
1725   i=7;
1726   if (fam0L_drive) i=9;
1727   DriveStruct[d].SubQ_run_trk=make32(make16(0,infobuf[i]),make16(infobuf[i+1],infobuf[i+2])); /* msf-bin */
1728   DriveStruct[d].SubQ_whatisthis=infobuf[i+3];
1729   DriveStruct[d].diskstate_flags |= subq_bit;
1730   return (0);
1731 }
1732 /*==========================================================================*/
1733 static int xx_ModeSense(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1734 {
1735   int i;
1736 
1737   if (fam2_drive) return (0);
1738   DriveStruct[d].diskstate_flags &= ~frame_size_bit;
1739   clr_cmdbuf();
1740   if (fam1_drive)
1741     {
1742       drvcmd[0]=CMD1_GETMODE;
1743       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1744       response_count=5;
1745     }
1746   else if (fam0L_drive)
1747     {
1748       drvcmd[0]=CMD0_GETMODE;
1749       if (famL_drive)
1750         flags_cmd_out=f_putcmd;
1751       else
1752         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1753       response_count=2;
1754     }
1755   i=cmd_out(7);
1756   if (i<0) return (i);
1757   i=0;
1758   if (fam1_drive) DriveStruct[d].sense_byte=infobuf[i++];
1759   else if (fam0L_drive) DriveStruct[d].sense_byte=0;
1760   DriveStruct[d].frame_size=make16(infobuf[i],infobuf[i+1]);
1761 
1762   DPRINTF((DBG_XA,"SBPCD: xx_ModeSense: "));
1763   for (i=0;i<(fam1_drive?5:2);i++)
1764     {
1765       DPRINTF((DBG_XA,"%02X ", infobuf[i]));
1766     }
1767   DPRINTF((DBG_XA,"\n"));
1768 
1769   DriveStruct[d].diskstate_flags |= frame_size_bit;
1770   return (0);
1771 }
1772 /*==========================================================================*/
1773 /*==========================================================================*/
1774 static int xx_ModeSelect(int framesize)
     /* [previous][next][first][last][top][bottom][index][help] */
1775 {
1776   int i;
1777 
1778   if (fam2_drive) return (0);
1779   DriveStruct[d].diskstate_flags &= ~frame_size_bit;
1780   clr_cmdbuf();
1781   DriveStruct[d].frame_size=framesize;
1782   if (framesize==CD_FRAMESIZE_RAW) DriveStruct[d].sense_byte=0x82;
1783   else DriveStruct[d].sense_byte=0x00;
1784 
1785   DPRINTF((DBG_XA,"SBPCD: xx_ModeSelect: %02X %04X\n",
1786            DriveStruct[d].sense_byte, DriveStruct[d].frame_size));
1787 
1788   if (fam1_drive)
1789     {
1790       drvcmd[0]=CMD1_SETMODE;
1791       drvcmd[1]=0x00;
1792       drvcmd[2]=DriveStruct[d].sense_byte;
1793       drvcmd[3]=(DriveStruct[d].frame_size>>8)&0xFF;
1794       drvcmd[4]=DriveStruct[d].frame_size&0xFF;
1795       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1796     }
1797   else if (fam0L_drive)
1798     {
1799       drvcmd[0]=CMD0_SETMODE;
1800       drvcmd[1]=0x00;
1801       drvcmd[2]=(DriveStruct[d].frame_size>>8)&0xFF;
1802       drvcmd[3]=DriveStruct[d].frame_size&0xFF;
1803       drvcmd[4]=0x00;
1804       if(famL_drive)
1805         flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check;
1806       else
1807         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1808     }
1809   response_count=0;
1810   i=cmd_out(7);
1811   if (i<0) return (i);
1812   DriveStruct[d].diskstate_flags |= frame_size_bit;
1813   return (0);
1814 }
1815 /*==========================================================================*/
1816 #if 0000
1817 static int xx_TellVolume(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1818 {
1819   int i;
1820   u_char switches;
1821   u_char chan0,vol0,chan1,vol1;
1822 
1823   DriveStruct[d].diskstate_flags &= ~volume_bit;
1824   clr_cmdbuf();
1825   if (fam1_drive)
1826     {
1827       drvcmd[0]=CMD1_GETMODE;
1828       drvcmd[1]=0x05;
1829       response_count=5;
1830       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1831     }
1832   else if (fam2_drive)
1833     {
1834       drvcmd[0]=CMD2_GETMODE;
1835       drvcmd[1]=0x0E;
1836       response_count=5;
1837       flags_cmd_out=f_putcmd;
1838     }
1839   else if (fam0L_drive)
1840     {
1841       drvcmd[0]=CMD0_GETMODE;
1842       drvcmd[1]=0x03;
1843       response_count=2;
1844       if(famL_drive)
1845         flags_cmd_out=f_putcmd;
1846       else
1847         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1848     }
1849   i=cmd_out(7);
1850   if (i<0) return (i);
1851   if (fam1_drive)
1852     {
1853       chan0=infobuf[1]&0x0F;
1854       vol0=infobuf[2];
1855       chan1=infobuf[3]&0x0F;
1856       vol1=infobuf[4];
1857       if (chan0==0)
1858         {
1859           chan0=1;
1860           vol0=0;
1861         }
1862       if (chan1==0)
1863         {
1864           chan1=2;
1865           vol1=0;
1866         }
1867       chan0 >>= 1;
1868       chan1 >>= 1;
1869     }
1870   else if (fam2_drive)
1871     {
1872       chan0=infobuf[1];
1873       vol0=infobuf[2];
1874       chan1=infobuf[3];
1875       vol1=infobuf[4];
1876     }
1877   else if (famL_drive)
1878     {
1879       chan0=0;
1880       chan1=1;
1881       vol0=vol1=infobuf[1];
1882       switches=infobuf[0];
1883       if ((switches&0x80)!=0) chan0=1;
1884       if ((switches&0x40)!=0) chan1=0;
1885     }
1886   else if (fam0_drive) /* different firmware levels */
1887     {
1888       chan0=0;
1889       chan1=1;
1890       vol0=vol1=infobuf[1];
1891       if (DriveStruct[d].drv_type>=drv_201)
1892         {
1893           if (DriveStruct[d].drv_type<drv_300)
1894             {
1895               switches=infobuf[0];
1896               if ((switches&0x80)!=0) vol0=0;
1897               if ((switches&0x40)!=0) vol1=0;
1898               if (DriveStruct[d].drv_type>=drv_211)
1899                 {
1900                   if ((switches&0x20)!=0) chan0=1;
1901                   if ((switches&0x10)!=0) chan1=0;
1902                 }
1903             }
1904           else
1905             {
1906               vol0=infobuf[0];
1907               if ((vol0&0x01)!=0) chan0=1;
1908               if ((vol1&0x01)==0) chan1=0;
1909               vol0 &= 0xFC;
1910               vol1 &= 0xFC;
1911               if (vol0!=0) vol0 += 3;
1912               if (vol1!=0) vol1 += 3;
1913             }
1914         }
1915     }
1916   DriveStruct[d].vol_chan0=chan0;
1917   DriveStruct[d].vol_ctrl0=vol0;
1918   DriveStruct[d].vol_chan1=chan1;
1919   DriveStruct[d].vol_ctrl1=vol1;
1920   DriveStruct[d].vol_chan2=2;
1921   DriveStruct[d].vol_ctrl2=0xFF;
1922   DriveStruct[d].vol_chan3=3;
1923   DriveStruct[d].vol_ctrl3=0xFF;
1924   DriveStruct[d].diskstate_flags |= volume_bit;
1925   return (0);
1926 }
1927 #endif
1928 /*==========================================================================*/
1929 static int xx_ReadCapacity(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1930 {
1931   int i;
1932 
1933   if (famL_drive) return (0);
1934   DriveStruct[d].diskstate_flags &= ~cd_size_bit;
1935   clr_cmdbuf();
1936   if (fam1_drive)
1937     {
1938       drvcmd[0]=CMD1_CAPACITY;
1939       response_count=5;
1940       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1941     }
1942   else if (fam2_drive)
1943     {
1944       drvcmd[0]=CMD2_CAPACITY;
1945       response_count=8;
1946       flags_cmd_out=f_putcmd;
1947     }
1948   else if (fam0_drive)
1949     {
1950       drvcmd[0]=CMD0_CAPACITY;
1951       response_count=5;
1952       if(famL_drive)
1953         flags_cmd_out=f_putcmd;
1954       else
1955         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1956     }
1957   i=cmd_out(7);
1958   if (i<0) return (i);
1959   if (fam1_drive) DriveStruct[d].CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_BLOCK_OFFSET;
1960   else if (fam0_drive) DriveStruct[d].CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
1961   else if (fam2_drive) DriveStruct[d].CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
1962   DriveStruct[d].diskstate_flags |= cd_size_bit;
1963   return (0);
1964 }
1965 /*==========================================================================*/
1966 static int xx_ReadTocDescr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1967 {
1968   int i;
1969 
1970   DriveStruct[d].diskstate_flags &= ~toc_bit;
1971   clr_cmdbuf();
1972   if (fam1_drive)
1973     {
1974       drvcmd[0]=CMD1_DISKINFO;
1975       response_count=6;
1976       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
1977     }
1978   else if (fam0L_drive)
1979     {
1980       drvcmd[0]=CMD0_DISKINFO;
1981       response_count=6;
1982       if(famL_drive)
1983         flags_cmd_out=f_putcmd;
1984       else
1985         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
1986     }
1987   else if (fam2_drive)
1988     {
1989       /* possibly longer timeout periods necessary */
1990       DriveStruct[d].f_multisession=0;
1991       drvcmd[0]=CMD2_DISKINFO;
1992       drvcmd[1]=0x02;
1993       drvcmd[2]=0xAB;
1994       drvcmd[3]=0xFF; /* session */
1995       response_count=8;
1996       flags_cmd_out=f_putcmd;
1997     }
1998   i=cmd_out(7);
1999   if (i<0) return (i);
2000   DriveStruct[d].xa_byte=infobuf[0];
2001   if (fam2_drive)
2002     {
2003       DriveStruct[d].first_session=infobuf[1];
2004       DriveStruct[d].last_session=infobuf[2];
2005       DriveStruct[d].n_first_track=infobuf[3];
2006       DriveStruct[d].n_last_track=infobuf[4];
2007       if (DriveStruct[d].first_session!=DriveStruct[d].last_session)
2008         {
2009           DriveStruct[d].f_multisession=1;
2010           DriveStruct[d].lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])));
2011         }
2012 #if 0
2013       if (DriveStruct[d].first_session!=DriveStruct[d].last_session)
2014         {
2015           if (DriveStruct[d].last_session<=20)
2016             zwanzig=DriveStruct[d].last_session+1;
2017           else zwanzig=20;
2018           for (count=DriveStruct[d].first_session;count<zwanzig;count++)
2019             {
2020               drvcmd[0]=CMD2_DISKINFO;
2021               drvcmd[1]=0x02;
2022               drvcmd[2]=0xAB;
2023               drvcmd[3]=count;
2024               response_count=8;
2025               flags_cmd_out=f_putcmd;
2026               i=cmd_out(7);
2027               if (i<0) return (i);
2028               DriveStruct[d].msf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]));
2029             }
2030           DriveStruct[d].diskstate_flags |= multisession_bit;
2031         }
2032 #endif
2033       drvcmd[0]=CMD2_DISKINFO;
2034       drvcmd[1]=0x02;
2035       drvcmd[2]=0xAA;
2036       drvcmd[3]=0xFF;
2037       response_count=5;
2038       flags_cmd_out=f_putcmd;
2039       i=cmd_out(7);
2040       if (i<0) return (i);
2041       DriveStruct[d].size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
2042       DriveStruct[d].size_blk=msf2blk(DriveStruct[d].size_msf);
2043     }
2044   else
2045     {
2046       DriveStruct[d].n_first_track=infobuf[1];
2047       DriveStruct[d].n_last_track=infobuf[2];
2048       DriveStruct[d].size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
2049       DriveStruct[d].size_blk=msf2blk(DriveStruct[d].size_msf);
2050       if (famL_drive) DriveStruct[d].CDsize_frm=DriveStruct[d].size_blk+1;
2051     }
2052   DriveStruct[d].diskstate_flags |= toc_bit;
2053   DPRINTF((DBG_TOC,"SBPCD: TocDesc: %02X %02X %02X %08X\n",
2054            DriveStruct[d].xa_byte,
2055            DriveStruct[d].n_first_track,
2056            DriveStruct[d].n_last_track,
2057            DriveStruct[d].size_msf));
2058   return (0);
2059 }
2060 /*==========================================================================*/
2061 static int xx_ReadTocEntry(int num)
     /* [previous][next][first][last][top][bottom][index][help] */
2062 {
2063   int i;
2064 
2065   clr_cmdbuf();
2066   if (fam1_drive)
2067     {
2068       drvcmd[0]=CMD1_READTOC;
2069       response_count=8;
2070       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2071     }
2072   else if (fam2_drive)
2073     {
2074       /* possibly longer timeout periods necessary */
2075       drvcmd[0]=CMD2_DISKINFO;
2076       drvcmd[1]=0x02;
2077       response_count=5;
2078       flags_cmd_out=f_putcmd;
2079     }
2080   else if (fam0L_drive)
2081     {
2082       drvcmd[0]=CMD0_READTOC;
2083       drvcmd[1]=0x02;
2084       response_count=8;
2085       if(famL_drive)
2086         flags_cmd_out=f_putcmd;
2087       else
2088         flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2089     }
2090   drvcmd[2]=num;
2091   i=cmd_out(7);
2092   if (i<0) return (i);
2093   if (fam2_drive) i=0;
2094   else
2095     {
2096       DriveStruct[d].TocEnt_nixbyte=infobuf[0];
2097       i=1;
2098     }
2099   DriveStruct[d].TocEnt_ctl_adr=swap_nibbles(infobuf[i++]);
2100   if (!(fam2_drive))
2101     {
2102       DriveStruct[d].TocEnt_number=infobuf[i++];
2103       DriveStruct[d].TocEnt_format=infobuf[i];
2104     }
2105   if (fam1_drive) i=4;
2106   else if (fam0L_drive) i=5;
2107   else if (fam2_drive) i=2;
2108   DriveStruct[d].TocEnt_address=make32(make16(0,infobuf[i]),
2109                                        make16(infobuf[i+1],infobuf[i+2]));
2110   DPRINTF((DBG_TOC,"SBPCD: TocEntry: %02X %02X %02X %02X %08X\n",
2111            DriveStruct[d].TocEnt_nixbyte, DriveStruct[d].TocEnt_ctl_adr,
2112            DriveStruct[d].TocEnt_number, DriveStruct[d].TocEnt_format,
2113            DriveStruct[d].TocEnt_address));
2114   return (0);
2115 }
2116 /*==========================================================================*/
2117 static int xx_ReadPacket(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2118 {
2119   int i;
2120 
2121   clr_cmdbuf();
2122   drvcmd[0]=CMD0_PACKET;
2123   drvcmd[1]=response_count;
2124   if(famL_drive)
2125     flags_cmd_out=f_putcmd;
2126   else if (fam01_drive)
2127     flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
2128   else if (fam2_drive) return (-1); /* not implemented yet */
2129   i=cmd_out(7);
2130   return (i);
2131 }
2132 /*==========================================================================*/
2133 static int convert_UPC(u_char *p)
     /* [previous][next][first][last][top][bottom][index][help] */
2134 {
2135   int i;
2136 
2137   p++;
2138   if (fam0L_drive) p[13]=0;
2139   for (i=0;i<7;i++)
2140     {
2141       if (fam1_drive) DriveStruct[d].UPC_buf[i]=swap_nibbles(*p++);
2142       else if (fam0L_drive)
2143         {
2144           DriveStruct[d].UPC_buf[i]=((*p++)<<4)&0xFF;
2145           DriveStruct[d].UPC_buf[i] |= *p++;
2146         }
2147       else /* CD200 */
2148         {
2149           return (-1);
2150         }
2151     }
2152   DriveStruct[d].UPC_buf[6] &= 0xF0;
2153   return (0);
2154 }
2155 /*==========================================================================*/
2156 static int xx_ReadUPC(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2157 {
2158   int i;
2159 #if TEST_UPC
2160   int block, checksum;
2161 #endif TEST_UPC
2162 
2163   if (fam2_drive) return (0); /* not implemented yet */
2164 
2165   DriveStruct[d].diskstate_flags &= ~upc_bit;
2166 #if TEST_UPC
2167   for (block=CD_BLOCK_OFFSET+1;block<CD_BLOCK_OFFSET+200;block++)
2168     {
2169 #endif TEST_UPC
2170       clr_cmdbuf();
2171       if (fam1_drive)
2172         {
2173           drvcmd[0]=CMD1_READ_UPC;
2174 #if TEST_UPC
2175           drvcmd[1]=(block>>16)&0xFF;
2176           drvcmd[2]=(block>>8)&0xFF;
2177           drvcmd[3]=block&0xFF;
2178 #endif TEST_UPC
2179           response_count=8;
2180           flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2181         }
2182       else if (fam0L_drive)
2183         {
2184           drvcmd[0]=CMD0_READ_UPC;
2185 #if TEST_UPC
2186           drvcmd[2]=(block>>16)&0xFF;
2187           drvcmd[3]=(block>>8)&0xFF;
2188           drvcmd[4]=block&0xFF;
2189 #endif TEST_UPC
2190           response_count=0;
2191           flags_cmd_out=f_putcmd|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
2192         }
2193       else /* CD200 */
2194         {
2195           return (-1);
2196         }
2197       i=cmd_out(7);
2198       if (i<0) return (i);
2199       if (fam0L_drive)
2200         {
2201           response_count=16;
2202           if (famL_drive) flags_cmd_out=f_putcmd;
2203           i=xx_ReadPacket();
2204           if (i<0) return (i);
2205         }
2206 #if TEST_UPC
2207       checksum=0;
2208 #endif TEST_UPC
2209       DPRINTF((DBG_UPC,"SBPCD: UPC info: "));
2210       for (i=0;i<(fam1_drive?8:16);i++)
2211         {
2212 #if TEST_UPC
2213           checksum |= infobuf[i];
2214 #endif TEST_UPC
2215           DPRINTF((DBG_UPC,"%02X ", infobuf[i]));
2216         }
2217       DPRINTF((DBG_UPC,"\n"));
2218 #if TEST_UPC
2219       if ((checksum&0x7F)!=0) break;
2220     }
2221 #endif TEST_UPC
2222   DriveStruct[d].UPC_ctl_adr=0;
2223   if (fam1_drive) i=0;
2224   else i=2;
2225   if ((infobuf[i]&0x80)!=0)
2226     {
2227       convert_UPC(&infobuf[i]);
2228       DriveStruct[d].UPC_ctl_adr = (DriveStruct[d].TocEnt_ctl_adr & 0xF0) | 0x02;
2229     }
2230 
2231   DPRINTF((DBG_UPC,"SBPCD: UPC code: "));
2232   DPRINTF((DBG_UPC,"(%02X) ", DriveStruct[d].UPC_ctl_adr));
2233   for (i=0;i<7;i++)
2234     {
2235       DPRINTF((DBG_UPC,"%02X ", DriveStruct[d].UPC_buf[i]));
2236     }
2237   DPRINTF((DBG_UPC,"\n"));
2238 
2239   DriveStruct[d].diskstate_flags |= upc_bit;
2240   return (0);
2241 }
2242 /*==========================================================================*/
2243 static int yy_CheckMultiSession(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2244 {
2245   int i;
2246 
2247   if (fam2_drive) return (0);
2248   DriveStruct[d].f_multisession=0;
2249   DriveStruct[d].lba_multi=0;
2250   if (fam0_drive) return (0);
2251   clr_cmdbuf();
2252   if (fam1_drive)
2253     {
2254       drvcmd[0]=CMD1_MULTISESS;
2255       response_count=6;
2256       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
2257       i=cmd_out(7);
2258       if (i<0) return (i);
2259       if ((infobuf[0]&0x80)!=0)
2260         {
2261           DriveStruct[d].f_multisession=1;
2262           DriveStruct[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]),
2263                                                   make16(infobuf[2],infobuf[3])));
2264           DPRINTF((DBG_MUL,"SBPCD: MultiSession CD detected: %02X %02X %02X %02X %02X %02X (%d)\n",
2265                    infobuf[0], infobuf[1], infobuf[2],
2266                    infobuf[3], infobuf[4], infobuf[5],
2267                    DriveStruct[d].lba_multi));
2268         }
2269     }
2270   else if (famL_drive)
2271     {
2272       drvcmd[0]=CMDL_MULTISESS;
2273       drvcmd[1]=3;
2274       drvcmd[2]=1;
2275       response_count=8;
2276       flags_cmd_out=f_putcmd;
2277       i=cmd_out(7);
2278       if (i<0) return (i);
2279       DriveStruct[d].lba_multi=msf2blk(make32(make16(0,infobuf[5]),
2280                                               make16(infobuf[6],infobuf[7])));
2281       DPRINTF((DBG_MUL,"SBPCD: MultiSession Info: %02X %02X %02X %02X %02X %02X %02X %02X (%d)\n",
2282                infobuf[0], infobuf[1], infobuf[2], infobuf[3],
2283                infobuf[4], infobuf[5], infobuf[6], infobuf[7],
2284                DriveStruct[d].lba_multi));
2285       if (DriveStruct[d].lba_multi>200)
2286         {
2287           DPRINTF((DBG_MUL,"SBPCD: MultiSession base: %06X\n", DriveStruct[d].lba_multi));
2288           DriveStruct[d].f_multisession=1;
2289         }
2290     }
2291   return (0);
2292 }
2293 /*==========================================================================*/
2294 #if FUTURE
2295 static int yy_SubChanInfo(int frame, int count, u_char *buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
2296 /* "frame" is a RED BOOK (msf-bin) address */
2297 {
2298   int i;
2299 
2300   if (fam0L_drive) return (-ENOSYS); /* drive firmware lacks it */
2301 #if 0
2302   if (DriveStruct[d].audio_state!=audio_playing) return (-ENODATA);
2303 #endif
2304   clr_cmdbuf();
2305   drvcmd[0]=CMD1_SUBCHANINF;
2306   drvcmd[1]=(frame>>16)&0xFF;
2307   drvcmd[2]=(frame>>8)&0xFF;
2308   drvcmd[3]=frame&0xFF;
2309   drvcmd[5]=(count>>8)&0xFF;
2310   drvcmd[6]=count&0xFF;
2311   flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
2312   cmd_type=READ_SC;
2313   DriveStruct[d].frame_size=CD_FRAMESIZE_SUB;
2314   i=cmd_out(7); /* which buffer to use? */
2315   return (i);
2316 }
2317 #endif FUTURE
2318 /*==========================================================================*/
2319 static void check_datarate(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2320 {
2321 #ifdef CDMKE
2322   int i=0;
2323 
2324   DPRINTF((DBG_IOX,"SBPCD: check_datarate entered.\n"));
2325   datarate=0;
2326 #if TEST_STI
2327   for (i=0;i<=1000;i++) printk(".");
2328 #endif
2329   /* set a timer to make (timed_out!=0) after 1.1 seconds */
2330 #if 0
2331   del_timer(&delay_timer);
2332 #endif
2333   delay_timer.expires = 110;
2334   timed_out=0;
2335   add_timer(&delay_timer);
2336   DPRINTF((DBG_TIM,"SBPCD: timer started (110).\n"));
2337   do
2338     {
2339       i=inb(CDi_status);
2340       datarate++;
2341 #if 00000
2342       if (datarate>0x0FFFFFFF) break;
2343 #endif 00000
2344     }
2345   while (!timed_out); /* originally looping for 1.1 seconds */
2346 #if 0
2347   del_timer(&delay_timer);
2348 #endif 0
2349   DPRINTF((DBG_TIM,"SBPCD: datarate: %d\n", datarate));
2350   if (datarate<65536) datarate=65536;
2351 
2352   maxtim16=datarate*16;
2353   maxtim04=datarate*4;
2354   maxtim02=datarate*2;
2355   maxtim_8=datarate/32;
2356 #if LONG_TIMING
2357   maxtim_data=datarate/100;
2358 #else
2359   maxtim_data=datarate/300;
2360 #endif LONG_TIMING
2361   DPRINTF((DBG_TIM,"SBPCD: maxtim_8 %d, maxtim_data %d.\n",
2362            maxtim_8, maxtim_data));
2363 #endif CDMKE
2364 }
2365 /*==========================================================================*/
2366 #ifdef CD200
2367 
2368 #if 0
2369 
2370 static int xx_ReadVersion(int fam)
     /* [previous][next][first][last][top][bottom][index][help] */
2371 {
2372   int i;
2373 
2374   clr_cmdbuf();
2375   clear_response_buffer(13);
2376   if (fam==1)
2377     {
2378       drvcmd[0]=CMD0_READ_VER; /* same as CMD1_ and CMDL_ */
2379       response_count=13;
2380       i=do_cmd(f_putcmd|f_lopsta|f_getsta|f_ResponseStatus);
2381     }
2382   else if (fam==2)
2383     {
2384       drvcmd[0]=CMD2_READ_VER;
2385       response_count=12;
2386       i=do_cmd(f_putcmd);
2387     }
2388   else return (-1);
2389   return (i);
2390 }
2391 
2392 static int yy_ReadError(int fam)
     /* [previous][next][first][last][top][bottom][index][help] */
2393 {
2394   int i;
2395 
2396   clr_cmdbuf();
2397   response_count=9;
2398   clr_respo_buf(9);
2399   if (fam==1)
2400     {
2401       drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
2402       i=do_cmd(f_putcmd|f_lopsta|f_getsta|f_ResponseStatus);
2403     }
2404   else if (fam==2)
2405     {
2406       drvcmd[0]=CMD2_READ_ERR;
2407       i=do_cmd(f_putcmd);
2408     }
2409   else return (-1);
2410   return (i);
2411 }
2412 #endif
2413 
2414 #endif CD200
2415 /*==========================================================================*/
2416 static void ask_mail(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2417 {
2418   int i;
2419 
2420   printk("SBPCD: please mail the following lines to emoenke@gwdg.de:\n");
2421   printk("SBPCD: address %03X, type %s, drive ID %d\n", CDo_command, type, DriveStruct[d].drv_id);
2422   printk("SBPCD: infobuf = \"");
2423   for (i=0;i<12;i++) printk("%02X ",infobuf[i]);
2424   printk("\"\nSBPCD: infobuf = \"");
2425   for (i=0;i<12;i++) printk("%c",infobuf[i]);
2426   printk("\"\n");
2427 }
2428 /*==========================================================================*/
2429 static int check_version(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2430 {
2431   int i, j;
2432   u_char lcs_firm[][4]={"A4F4","A E1"};
2433 
2434   DPRINTF((DBG_INI,"SBPCD: check_version entered.\n"));
2435   DriveStruct[d].drv_type=0;
2436 
2437   /* check for CD200 */
2438   clr_cmdbuf();
2439   drvcmd[0]=CMD2_READ_ERR;
2440   response_count=9;
2441   flags_cmd_out=f_putcmd;
2442   i=cmd_out(7);
2443   if (i<0) DPRINTF((DBG_INI,"SBPCD: CMD2_READERR returns %d (ok anyway).\n",i));
2444   /* read drive version */
2445   clr_cmdbuf();
2446   for (i=0;i<12;i++) infobuf[i]=0;
2447   if (sbpro_type==1) OUT(CDo_sel_i_d,0);
2448 #if 0
2449   OUT(CDo_reset,0);
2450   sbp_sleep(600);
2451   OUT(CDo_enable,DriveStruct[d].drv_sel);
2452 #endif
2453   drvcmd[0]=CMD2_READ_VER;
2454   response_count=12;
2455   flags_cmd_out=f_putcmd;
2456   i=cmd_out(7);
2457   if (i<0) DPRINTF((DBG_INI,"SBPCD: CMD2_READ_VER returns %d\n",i));
2458   if (i>=0) /* from CD200 */
2459     {
2460       for (i=0, j=0;i<12;i++) j+=infobuf[i];
2461       if (j)
2462         {
2463           DPRINTF((DBG_ID,"SBPCD: infobuf = \""));
2464           for (i=0;i<12;i++) DPRINTF((DBG_ID,"%02X ",infobuf[i]));
2465           for (i=0;i<12;i++) DPRINTF((DBG_ID,"%c",infobuf[i]));
2466           DPRINTF((DBG_ID,"\"\n"));
2467         }
2468       for (i=0;i<5;i++) if (infobuf[i]!=family2[i]) break;
2469       if (i==5)
2470         {
2471           DriveStruct[d].drive_model[0]='C';
2472           DriveStruct[d].drive_model[1]='D';
2473           DriveStruct[d].drive_model[2]='2';
2474           DriveStruct[d].drive_model[3]='0';
2475           DriveStruct[d].drive_model[4]='0';
2476           DriveStruct[d].drive_model[5]=infobuf[i++];
2477           DriveStruct[d].drive_model[6]=infobuf[i++];
2478           DriveStruct[d].drive_model[7]=0;
2479           DriveStruct[d].drv_type=drv_fam2;
2480         }
2481     }
2482 
2483   if (!DriveStruct[d].drv_type)
2484     {
2485       /* check for CR-52x, CR-56x and LCS-7260 */
2486       /* clear any pending error state */
2487       clr_cmdbuf();
2488       drvcmd[0]=CMD0_READ_ERR; /* same as CMD1_ and CMDL_ */
2489       response_count=9;
2490       flags_cmd_out=f_putcmd;
2491       i=cmd_out(7);
2492       if (i<0) DPRINTF((DBG_INI,"SBPCD: CMD0_READERR returns %d (ok anyway).\n",i));
2493       /* read drive version */
2494       clr_cmdbuf();
2495       for (i=0;i<12;i++) infobuf[i]=0;
2496       drvcmd[0]=CMD0_READ_VER; /* same as CMD1_ and CMDL_ */
2497       response_count=12;
2498       flags_cmd_out=f_putcmd;
2499       i=cmd_out(7);
2500       if (i<0) DPRINTF((DBG_INI,"SBPCD: CMD0_READ_VER returns %d\n",i));
2501 
2502       for (i=0, j=0;i<12;i++) j+=infobuf[i];
2503       if (j)
2504         {
2505           DPRINTF((DBG_ID,"SBPCD: infobuf = \""));
2506           for (i=0;i<12;i++) DPRINTF((DBG_ID,"%02X ",infobuf[i]));
2507           for (i=0;i<12;i++) DPRINTF((DBG_ID,"%c",infobuf[i]));
2508           DPRINTF((DBG_ID,"\"\n"));
2509         }
2510 
2511       for (i=0;i<4;i++) if (infobuf[i]!=family1[i]) break;
2512       if (i==4)
2513         {
2514           DriveStruct[d].drive_model[0]='C';
2515           DriveStruct[d].drive_model[1]='R';
2516           DriveStruct[d].drive_model[2]='-';
2517           DriveStruct[d].drive_model[3]='5';
2518           DriveStruct[d].drive_model[4]=infobuf[i++];
2519           DriveStruct[d].drive_model[5]=infobuf[i++];
2520           DriveStruct[d].drive_model[6]=0;
2521           DriveStruct[d].drv_type=drv_fam1;
2522         }
2523       if (!DriveStruct[d].drv_type)
2524         {
2525           for (i=0;i<8;i++) if (infobuf[i]!=family0[i]) break;
2526           if (i==8)
2527             {
2528               DriveStruct[d].drive_model[0]='C';
2529               DriveStruct[d].drive_model[1]='R';
2530               DriveStruct[d].drive_model[2]='-';
2531               DriveStruct[d].drive_model[3]='5';
2532               DriveStruct[d].drive_model[4]='2';
2533               DriveStruct[d].drive_model[5]='x';
2534               DriveStruct[d].drive_model[6]=0;
2535               DriveStruct[d].drv_type=drv_fam0;
2536             }
2537         }
2538       if (!DriveStruct[d].drv_type)
2539         {
2540           for (i=0;i<8;i++) if (infobuf[i]!=familyL[i]) break;
2541           if (i==8)
2542             {
2543               for (j=0;j<8;j++)
2544                 DriveStruct[d].drive_model[j]=infobuf[j];
2545               DriveStruct[d].drive_model[8]=0;
2546               DriveStruct[d].drv_type=drv_famL;
2547             }
2548         }
2549     }
2550   if (!DriveStruct[d].drv_type)
2551     {
2552       DPRINTF((DBG_INI,"SBPCD: check_version: error.\n"));
2553       return (-1);
2554     }
2555   for (j=0;j<4;j++) DriveStruct[d].firmware_version[j]=infobuf[i+j];
2556   if (famL_drive)
2557     {
2558       for (i=0;i<2;i++)
2559         {
2560           for (j=0;j<4;j++)
2561             if (DriveStruct[d].firmware_version[j]!=lcs_firm[i][j]) break;
2562           if (j==4) break;
2563         }
2564       if (j!=4) ask_mail();
2565       DriveStruct[d].drv_type=drv_260;
2566     }
2567   else
2568     {
2569       j = (DriveStruct[d].firmware_version[0] & 0x0F) * 100 +
2570         (DriveStruct[d].firmware_version[2] & 0x0F) *10 +
2571           (DriveStruct[d].firmware_version[3] & 0x0F);
2572       if (fam0_drive)
2573         {
2574           if (j<200) DriveStruct[d].drv_type=drv_199;
2575           else if (j<201) DriveStruct[d].drv_type=drv_200;
2576           else if (j<210) DriveStruct[d].drv_type=drv_201;
2577           else if (j<211) DriveStruct[d].drv_type=drv_210;
2578           else if (j<300) DriveStruct[d].drv_type=drv_211;
2579           else if (j>=300) DriveStruct[d].drv_type=drv_300;
2580         }
2581       else if (fam1_drive)
2582         {
2583           if (j<100) DriveStruct[d].drv_type=drv_099;
2584           else
2585             {
2586               DriveStruct[d].drv_type=drv_100;
2587               ask_mail();
2588             }
2589         }
2590       else if (fam2_drive)
2591         {
2592           printk("\n\nSBPCD: new drive CD200 (%s)detected.\n",
2593                  DriveStruct[d].firmware_version);
2594           printk("SBPCD: support is not fulfilled yet.\n");
2595           if (j!=101) ask_mail(); /* only 1.01 known at time */
2596         }
2597     }
2598   DPRINTF((DBG_LCS,"SBPCD: drive type %02X\n",DriveStruct[d].drv_type));
2599   DPRINTF((DBG_INI,"SBPCD: check_version done.\n"));
2600   return (0);
2601 }
2602 /*==========================================================================*/
2603 static int switch_drive(int i)
     /* [previous][next][first][last][top][bottom][index][help] */
2604 {
2605   d=i;
2606   if (DriveStruct[d].drv_id!=-1)
2607     {
2608       OUT(CDo_enable,DriveStruct[d].drv_sel);
2609       DPRINTF((DBG_DID,"SBPCD: drive %d (ID=%d) activated.\n", i, DriveStruct[d].drv_id));
2610       return (0);
2611     }
2612   else return (-1);
2613 }
2614 /*==========================================================================*/
2615 /*
2616  * probe for the presence of drives on the selected controller
2617  */
2618 static int check_drives(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2619 {
2620   int i, j;
2621   char *printk_header="";
2622 
2623   DPRINTF((DBG_INI,"SBPCD: check_drives entered.\n"));
2624 
2625   ndrives=0;
2626   for (j=0;j<NR_SBPCD;j++)
2627     {
2628       DriveStruct[ndrives].drv_id=j;
2629       if (sbpro_type==1) DriveStruct[ndrives].drv_sel=(j&0x01)<<1|(j&0x02)>>1;
2630       else DriveStruct[ndrives].drv_sel=j;
2631       switch_drive(ndrives);
2632       DPRINTF((DBG_INI,"SBPCD: check_drives: drive %d (ID=%d) activated.\n",ndrives,j));
2633       i=check_version();
2634       if (i<0) DPRINTF((DBG_INI,"SBPCD: check_version returns %d.\n",i));
2635       else
2636         {
2637           DriveStruct[d].drv_options=drv_pattern[j];
2638           if (fam0L_drive) DriveStruct[d].drv_options&=~(speed_auto|speed_300|speed_150);
2639           printk("%sDrive %d (ID=%d): %.9s (%.4s)\n", printk_header, d,
2640                  DriveStruct[d].drv_id,
2641                  DriveStruct[d].drive_model,
2642                  DriveStruct[d].firmware_version);
2643           printk_header="       - ";
2644           ndrives++;
2645         }
2646 
2647     }
2648   for (j=ndrives;j<NR_SBPCD;j++) DriveStruct[j].drv_id=-1;
2649   if (ndrives==0) return (-1);
2650   return (0);
2651 }
2652 /*==========================================================================*/
2653 #if 000
2654 static void timewait(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2655 {
2656   int i;
2657   for (i=0; i<65500; i++);
2658 }
2659 #endif 000
2660 /*==========================================================================*/
2661 #if FUTURE
2662 /*
2663  *  obtain if requested service disturbs current audio state
2664  */            
2665 static int obey_audio_state(u_char audio_state, u_char func,u_char subfunc)
     /* [previous][next][first][last][top][bottom][index][help] */
2666 {
2667   switch (audio_state)                   /* audio status from controller  */
2668     {
2669     case aud_11: /* "audio play in progress" */
2670     case audx11:
2671       switch (func)                      /* DOS command code */
2672         {
2673         case cmd_07: /* input flush  */
2674         case cmd_0d: /* open device  */
2675         case cmd_0e: /* close device */
2676         case cmd_0c: /* ioctl output */
2677           return (1);
2678         case cmd_03: /* ioctl input  */
2679           switch (subfunc)
2680             /* DOS ioctl input subfunction */
2681             {
2682             case cxi_00:
2683             case cxi_06:
2684             case cxi_09:
2685               return (1);
2686             default:
2687               return (ERROR15);
2688             }
2689           return (1);
2690         default:
2691           return (ERROR15);
2692         }
2693       return (1);
2694     case aud_12:                  /* "audio play paused"      */
2695     case audx12:
2696       return (1);
2697     default:
2698       return (2);
2699     }
2700 }
2701 #endif FUTURE
2702 /*==========================================================================*/
2703 /* allowed is only
2704  * ioctl_o, flush_input, open_device, close_device, 
2705  * tell_address, tell_volume, tell_capabiliti,
2706  * tell_framesize, tell_CD_changed, tell_audio_posi
2707  */
2708 static int check_allowed1(u_char func1, u_char func2)
     /* [previous][next][first][last][top][bottom][index][help] */
2709 {
2710 #if 000
2711   if (func1==ioctl_o) return (0);
2712   if (func1==read_long) return (-1);
2713   if (func1==read_long_prefetch) return (-1);
2714   if (func1==seek) return (-1);
2715   if (func1==audio_play) return (-1);
2716   if (func1==audio_pause) return (-1);
2717   if (func1==audio_resume) return (-1);
2718   if (func1!=ioctl_i) return (0);
2719   if (func2==tell_SubQ_run_tot) return (-1);
2720   if (func2==tell_cdsize) return (-1);
2721   if (func2==tell_TocDescrip) return (-1);
2722   if (func2==tell_TocEntry) return (-1);
2723   if (func2==tell_subQ_info) return (-1);
2724   if (fam1_drive) if (func2==tell_SubChanInfo) return (-1);
2725   if (func2==tell_UPC) return (-1);
2726 #else
2727   return (0);
2728 #endif 000
2729 }
2730 /*==========================================================================*/
2731 static int check_allowed2(u_char func1, u_char func2)
     /* [previous][next][first][last][top][bottom][index][help] */
2732 {
2733 #if 000
2734   if (func1==read_long) return (-1);
2735   if (func1==read_long_prefetch) return (-1);
2736   if (func1==seek) return (-1);
2737   if (func1==audio_play) return (-1);
2738   if (func1!=ioctl_o) return (0);
2739   if (fam1_drive)
2740     {
2741       if (func2==EjectDisk) return (-1);
2742       if (func2==CloseTray) return (-1);
2743     }
2744 #else
2745   return (0);
2746 #endif 000
2747 }
2748 /*==========================================================================*/
2749 static int check_allowed3(u_char func1, u_char func2)
     /* [previous][next][first][last][top][bottom][index][help] */
2750 {
2751 #if 000
2752   if (func1==ioctl_i)
2753     {
2754       if (func2==tell_address) return (0);
2755       if (func2==tell_capabiliti) return (0);
2756       if (func2==tell_CD_changed) return (0);
2757       if (fam0L_drive) if (func2==tell_SubChanInfo) return (0);
2758       return (-1);
2759     }
2760   if (func1==ioctl_o)
2761     {
2762       if (func2==DriveReset) return (0);
2763       if (fam0L_drive)
2764         {
2765           if (func2==EjectDisk) return (0);
2766           if (func2==LockDoor) return (0);
2767           if (func2==CloseTray) return (0);
2768         }
2769       return (-1);
2770     }
2771   if (func1==flush_input) return (-1);
2772   if (func1==read_long) return (-1);
2773   if (func1==read_long_prefetch) return (-1);
2774   if (func1==seek) return (-1);
2775   if (func1==audio_play) return (-1);
2776   if (func1==audio_pause) return (-1);
2777   if (func1==audio_resume) return (-1);
2778 #else
2779   return (0);
2780 #endif 000
2781 }
2782 /*==========================================================================*/
2783 static int seek_pos_audio_end(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2784 {
2785   int i;
2786 
2787   i=msf2blk(DriveStruct[d].pos_audio_end)-1;
2788   if (i<0) return (-1);
2789   i=xx_Seek(i,0);
2790   return (i);
2791 }
2792 /*==========================================================================*/
2793 static int ReadToC(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2794 {
2795   int i, j;
2796   DriveStruct[d].diskstate_flags &= ~toc_bit;
2797   DriveStruct[d].ored_ctl_adr=0;
2798   for (j=DriveStruct[d].n_first_track;j<=DriveStruct[d].n_last_track;j++)
2799     {
2800       i=xx_ReadTocEntry(j);
2801       if (i<0) return (i);
2802       DriveStruct[d].TocBuffer[j].nixbyte=DriveStruct[d].TocEnt_nixbyte;
2803       DriveStruct[d].TocBuffer[j].ctl_adr=DriveStruct[d].TocEnt_ctl_adr;
2804       DriveStruct[d].TocBuffer[j].number=DriveStruct[d].TocEnt_number;
2805       DriveStruct[d].TocBuffer[j].format=DriveStruct[d].TocEnt_format;
2806       DriveStruct[d].TocBuffer[j].address=DriveStruct[d].TocEnt_address;
2807       DriveStruct[d].ored_ctl_adr |= DriveStruct[d].TocEnt_ctl_adr;
2808     }
2809 /* fake entry for LeadOut Track */
2810   DriveStruct[d].TocBuffer[j].nixbyte=0;
2811   DriveStruct[d].TocBuffer[j].ctl_adr=0;
2812   DriveStruct[d].TocBuffer[j].number=CDROM_LEADOUT;
2813   DriveStruct[d].TocBuffer[j].format=0;
2814   DriveStruct[d].TocBuffer[j].address=DriveStruct[d].size_msf;
2815 
2816   DriveStruct[d].diskstate_flags |= toc_bit;
2817   return (0);
2818 }
2819 /*==========================================================================*/
2820 static int DiskInfo(void)
     /* [previous][next][first][last][top][bottom][index][help] */
2821 {
2822   int i, j;
2823 
2824       DriveStruct[d].mode=READ_M1;
2825 
2826 #undef LOOP_COUNT
2827 #define LOOP_COUNT 20 /* needed for some "old" drives */
2828 
2829   for (j=1;j<LOOP_COUNT;j++)
2830     {
2831       i=SetSpeed();
2832       if (i<0)
2833         {
2834           DPRINTF((DBG_INF,"SBPCD: DiskInfo: SetSpeed returns %d\n", i));
2835           continue;
2836         }
2837       i=xx_ModeSense();
2838       if (i<0)
2839         {
2840           DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ModeSense returns %d\n", i));
2841           continue;
2842         }
2843       i=xx_ReadCapacity();
2844       if (i>=0) break;
2845       DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadCapacity #%d returns %d\n", j, i));
2846       i=DriveReset();
2847     }
2848   if (j==LOOP_COUNT) return (-2); /* give up */
2849 
2850   i=xx_ReadTocDescr();
2851   if (i<0)
2852     {
2853       DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadTocDescr returns %d\n", i));
2854       return (i);
2855     }
2856   i=ReadToC();
2857   if (i<0)
2858     {
2859       DPRINTF((DBG_INF,"SBPCD: DiskInfo: ReadToC returns %d\n", i));
2860       return (i);
2861     }
2862   i=yy_CheckMultiSession();
2863   if (i<0)
2864     {
2865       DPRINTF((DBG_INF,"SBPCD: DiskInfo: yy_CheckMultiSession returns %d\n", i));
2866       return (i);
2867     }
2868   i=xx_ReadTocEntry(DriveStruct[d].n_first_track);
2869   if (i<0)
2870     {
2871       DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ReadTocEntry(1) returns %d\n", i));
2872       return (i);
2873     }
2874   i=xx_ReadUPC();
2875   if (i<0)
2876     {
2877       DPRINTF((DBG_INF,"SBPCD: DiskInfo: xx_ReadUPC returns %d\n", i));
2878       return (i);
2879     }
2880 #ifdef XA_TEST2
2881   if ((fam0L_drive) && (DriveStruct[d].xa_byte==0x20)) /* XA disk with old drive */
2882       {
2883         xx_ModeSelect(CD_FRAMESIZE_XA);
2884         xx_ModeSense();
2885       }
2886 #endif XA_TEST2
2887 
2888   return (0);
2889 }
2890 /*==========================================================================*/
2891 /*
2892  *  called always if driver gets entered
2893  *  returns 0 or ERROR2 or ERROR15
2894  */
2895 static int prepare(u_char func, u_char subfunc)
     /* [previous][next][first][last][top][bottom][index][help] */
2896 {
2897   int i;
2898 
2899   if (fam0L_drive)
2900     {
2901       i=inb(CDi_status);
2902       if (i&s_attention) GetStatus();
2903     }
2904   else if (fam1_drive) GetStatus();
2905   else if (fam2_drive) GetStatus();
2906   if (DriveStruct[d].CD_changed==0xFF)
2907     {
2908 #if MANY_SESSION
2909 #else
2910       DriveStruct[d].diskstate_flags=0;
2911 #endif MANY_SESSION
2912       DriveStruct[d].audio_state=0;
2913       if (!st_diskok)
2914         {
2915           i=check_allowed1(func,subfunc);
2916           if (i<0) return (-2);
2917         }
2918       else 
2919         {
2920           i=check_allowed3(func,subfunc);
2921           if (i<0)
2922             {
2923               DriveStruct[d].CD_changed=1;
2924               return (-15);
2925             }
2926         }
2927     }
2928   else
2929     {
2930       if (!st_diskok)
2931         {
2932 #if MANY_SESSION
2933 #else
2934           DriveStruct[d].diskstate_flags=0;
2935 #endif MANY_SESSION
2936           DriveStruct[d].audio_state=0;
2937           i=check_allowed1(func,subfunc);
2938           if (i<0) return (-2);
2939         }
2940       else
2941         { 
2942           if (st_busy)
2943             {
2944               if (DriveStruct[d].audio_state!=audio_pausing)
2945                 {
2946                   i=check_allowed2(func,subfunc);
2947                   if (i<0) return (-2);
2948                 }
2949             }
2950           else
2951             {
2952               if (DriveStruct[d].audio_state==audio_playing) seek_pos_audio_end();
2953               DriveStruct[d].audio_state=0;
2954             }
2955           if (!frame_size_valid)
2956             {
2957               i=DiskInfo();
2958               if (i<0)
2959                 {
2960 #if MANY_SESSION
2961 #else
2962                   DriveStruct[d].diskstate_flags=0;
2963 #endif MANY_SESSION
2964                   DriveStruct[d].audio_state=0;
2965                   i=check_allowed1(func,subfunc);
2966                   if (i<0) return (-2);
2967                 }
2968             }
2969         }
2970     }
2971   return (0);
2972 }
2973 /*==========================================================================*/
2974 static int xx_PlayAudio(int pos_audio_start,int pos_audio_end)
     /* [previous][next][first][last][top][bottom][index][help] */
2975 {
2976   int i, n;
2977 
2978   if (DriveStruct[d].audio_state==audio_playing) return (-EINVAL);
2979   clr_cmdbuf();
2980   if (famL_drive)
2981     {
2982       drvcmd[0]=CMDL_PLAY;
2983       i=msf2blk(pos_audio_start);
2984       n=msf2blk(pos_audio_end)+1-i;
2985       drvcmd[1]=(i>>16)&0x00FF;
2986       drvcmd[2]=(i>>8)&0x00FF;
2987       drvcmd[3]=i&0x00FF;
2988       drvcmd[4]=(n>>16)&0x00FF;
2989       drvcmd[5]=(n>>8)&0x00FF;
2990       drvcmd[6]=n&0x00FF;
2991       flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
2992         f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
2993     }
2994   else
2995     {
2996       if (fam1_drive)
2997         {
2998           drvcmd[0]=CMD1_PLAY_MSF;
2999           flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus |
3000             f_obey_p_check | f_wait_if_busy;
3001         }
3002       else if (fam2_drive)
3003         {
3004           drvcmd[0]=CMD2_PLAY_MSF;
3005           flags_cmd_out = f_putcmd | f_ResponseStatus;
3006         }
3007       else if (fam0_drive)
3008         {
3009           drvcmd[0]=CMD0_PLAY_MSF;
3010           flags_cmd_out = f_putcmd | f_respo2 | f_lopsta | f_getsta |
3011             f_ResponseStatus | f_obey_p_check | f_wait_if_busy;
3012         }
3013       drvcmd[1]=(pos_audio_start>>16)&0x00FF;
3014       drvcmd[2]=(pos_audio_start>>8)&0x00FF;
3015       drvcmd[3]=pos_audio_start&0x00FF;
3016       drvcmd[4]=(pos_audio_end>>16)&0x00FF;
3017       drvcmd[5]=(pos_audio_end>>8)&0x00FF;
3018       drvcmd[6]=pos_audio_end&0x00FF;
3019     }
3020   response_count=0;
3021   i=cmd_out(7);
3022   return (i);
3023 }
3024 /*==========================================================================*/
3025 /*==========================================================================*/
3026 /*==========================================================================*/
3027 /*
3028  * Check the results of the "get status" command.
3029  */
3030 static int sbp_status(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3031 {
3032   int st;
3033 
3034   st=ResponseStatus();
3035   if (st<0)
3036     {
3037       DPRINTF((DBG_INF,"SBPCD: sbp_status: timeout.\n"));
3038       return (0);
3039     }
3040 
3041   if (!st_spinning) DPRINTF((DBG_SPI,"SBPCD: motor got off - ignoring.\n"));
3042 
3043   if (st_check) 
3044     {
3045       DPRINTF((DBG_INF,"SBPCD: st_check detected - retrying.\n"));
3046       return (0);
3047     }
3048   if (!st_door_closed)
3049     {
3050       DPRINTF((DBG_INF,"SBPCD: door is open - retrying.\n"));
3051       return (0);
3052     }
3053   if (!st_caddy_in)
3054     {
3055       DPRINTF((DBG_INF,"SBPCD: disk removed - retrying.\n"));
3056       return (0);
3057     }
3058   if (!st_diskok) 
3059     {
3060       DPRINTF((DBG_INF,"SBPCD: !st_diskok detected - retrying.\n"));
3061       return (0);
3062     }
3063   if (st_busy) 
3064     {
3065       DPRINTF((DBG_INF,"SBPCD: st_busy detected - retrying.\n"));
3066       return (0);
3067     }
3068   return (1);
3069 }
3070 /*==========================================================================*/
3071 
3072 /*==========================================================================*/
3073 /*==========================================================================*/
3074 /*
3075  * ioctl support
3076  */
3077 static int sbpcd_ioctl(struct inode *inode, struct file *file, u_int cmd,
     /* [previous][next][first][last][top][bottom][index][help] */
3078                        u_long arg)
3079 {
3080   int i, st;
3081 
3082   DPRINTF((DBG_IO2,"SBPCD: ioctl(%d, 0x%08lX, 0x%08lX)\n",
3083                                 MINOR(inode->i_rdev), cmd, arg));
3084   if (!inode) return (-EINVAL);
3085   i=MINOR(inode->i_rdev);
3086   if ((i<0) || (i>=NR_SBPCD) || (DriveStruct[i].drv_id==-1))
3087     {
3088       printk("SBPCD: ioctl: bad device: %04X\n", inode->i_rdev);
3089       return (-ENXIO);             /* no such drive */
3090     }
3091   switch_drive(i);
3092 
3093   st=GetStatus();
3094   if (st<0) return (-EIO);
3095   
3096   if (!toc_valid)
3097     {
3098       i=DiskInfo();
3099       if (i<0) return (-EIO);   /* error reading TOC */
3100     }
3101   
3102   DPRINTF((DBG_IO2,"SBPCD: ioctl: device %d, request %04X\n",i,cmd));
3103   switch (cmd)          /* Sun-compatible */
3104     {
3105     case DDIOCSDBG:             /* DDI Debug */
3106       if (! suser()) return (-EPERM);
3107       i = verify_area(VERIFY_READ, (int *) arg, sizeof(int));
3108       if (i>=0) i=sbpcd_dbg_ioctl(arg,1);
3109       return (i);
3110 
3111     case CDROMPAUSE:     /* Pause the drive */
3112       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPAUSE entered.\n"));
3113       /* pause the drive unit when it is currently in PLAY mode,         */
3114       /* or reset the starting and ending locations when in PAUSED mode. */
3115       /* If applicable, at the next stopping point it reaches            */
3116       /* the drive will discontinue playing.                             */
3117       switch (DriveStruct[d].audio_state)
3118         {
3119         case audio_playing:
3120           if (famL_drive) i=xx_ReadSubQ();
3121           else i=xx_Pause_Resume(1);
3122           if (i<0) return (-EIO);
3123           if (famL_drive) i=xx_Pause_Resume(1);
3124           else i=xx_ReadSubQ();
3125           if (i<0) return (-EIO);
3126           DriveStruct[d].pos_audio_start=DriveStruct[d].SubQ_run_tot;
3127           DriveStruct[d].audio_state=audio_pausing;
3128           return (0);
3129         case audio_pausing:
3130           i=xx_Seek(DriveStruct[d].pos_audio_start,1);
3131           if (i<0) return (-EIO);
3132           return (0);
3133         default:
3134           return (-EINVAL);
3135         }
3136       
3137     case CDROMRESUME: /* resume paused audio play */
3138       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMRESUME entered.\n"));
3139       /* resume playing audio tracks when a previous PLAY AUDIO call has  */
3140       /* been paused with a PAUSE command.                                */
3141       /* It will resume playing from the location saved in SubQ_run_tot.  */
3142       if (DriveStruct[d].audio_state!=audio_pausing) return -EINVAL;
3143       if (famL_drive)
3144         i=xx_PlayAudio(DriveStruct[d].pos_audio_start,
3145                        DriveStruct[d].pos_audio_end);
3146       else i=xx_Pause_Resume(3);
3147       if (i<0) return (-EIO);
3148       DriveStruct[d].audio_state=audio_playing;
3149       return (0);
3150 
3151     case CDROMPLAYMSF:
3152       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPLAYMSF entered.\n"));
3153       if (DriveStruct[d].audio_state==audio_playing)
3154         {
3155           i=xx_Pause_Resume(1);
3156           if (i<0) return (-EIO);
3157           i=xx_ReadSubQ();
3158           if (i<0) return (-EIO);
3159           DriveStruct[d].pos_audio_start=DriveStruct[d].SubQ_run_tot;
3160           i=xx_Seek(DriveStruct[d].pos_audio_start,1);
3161         }
3162       st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_msf));
3163       if (st) return (st);
3164       memcpy_fromfs(&msf, (void *) arg, sizeof(struct cdrom_msf));
3165       /* values come as msf-bin */
3166       DriveStruct[d].pos_audio_start = (msf.cdmsf_min0<<16) |
3167                         (msf.cdmsf_sec0<<8) |
3168                         msf.cdmsf_frame0;
3169       DriveStruct[d].pos_audio_end = (msf.cdmsf_min1<<16) |
3170                       (msf.cdmsf_sec1<<8) |
3171                       msf.cdmsf_frame1;
3172       DPRINTF((DBG_IOX,"SBPCD: ioctl: CDROMPLAYMSF %08X %08X\n",
3173                                DriveStruct[d].pos_audio_start,DriveStruct[d].pos_audio_end));
3174       i=xx_PlayAudio(DriveStruct[d].pos_audio_start,DriveStruct[d].pos_audio_end);
3175       DPRINTF((DBG_IOC,"SBPCD: ioctl: xx_PlayAudio returns %d\n",i));
3176 #if 0
3177       if (i<0) return (-EIO);
3178 #endif 0
3179       DriveStruct[d].audio_state=audio_playing;
3180       return (0);
3181 
3182     case CDROMPLAYTRKIND: /* Play a track.  This currently ignores index. */
3183       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMPLAYTRKIND entered.\n"));
3184       if (DriveStruct[d].audio_state==audio_playing)
3185         {
3186           DPRINTF((DBG_IOX,"SBPCD: CDROMPLAYTRKIND: already audio_playing.\n"));
3187           return (0);
3188           return (-EINVAL);
3189         }
3190       st=verify_area(VERIFY_READ,(void *) arg,sizeof(struct cdrom_ti));
3191       if (st<0)
3192         {
3193           DPRINTF((DBG_IOX,"SBPCD: CDROMPLAYTRKIND: verify_area error.\n"));
3194           return (st);
3195         }
3196       memcpy_fromfs(&ti,(void *) arg,sizeof(struct cdrom_ti));
3197       DPRINTF((DBG_IOX,"SBPCD: ioctl: trk0: %d, ind0: %d, trk1:%d, ind1:%d\n",
3198              ti.cdti_trk0,ti.cdti_ind0,ti.cdti_trk1,ti.cdti_ind1));
3199       if (ti.cdti_trk0<DriveStruct[d].n_first_track) return (-EINVAL);
3200       if (ti.cdti_trk0>DriveStruct[d].n_last_track) return (-EINVAL);
3201       if (ti.cdti_trk1<ti.cdti_trk0) ti.cdti_trk1=ti.cdti_trk0;
3202       if (ti.cdti_trk1>DriveStruct[d].n_last_track) ti.cdti_trk1=DriveStruct[d].n_last_track;
3203       DriveStruct[d].pos_audio_start=DriveStruct[d].TocBuffer[ti.cdti_trk0].address;
3204       DriveStruct[d].pos_audio_end=DriveStruct[d].TocBuffer[ti.cdti_trk1+1].address;
3205       i=xx_PlayAudio(DriveStruct[d].pos_audio_start,DriveStruct[d].pos_audio_end);
3206 #if 0
3207       if (i<0) return (-EIO);
3208 #endif 0
3209       DriveStruct[d].audio_state=audio_playing;
3210       return (0);
3211             
3212     case CDROMREADTOCHDR:        /* Read the table of contents header */
3213       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADTOCHDR entered.\n"));
3214       tochdr.cdth_trk0=DriveStruct[d].n_first_track;
3215       tochdr.cdth_trk1=DriveStruct[d].n_last_track;
3216       st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_tochdr));
3217       if (st) return (st);
3218       memcpy_tofs((void *) arg, &tochdr, sizeof(struct cdrom_tochdr));
3219       return (0);
3220 
3221     case CDROMREADTOCENTRY:      /* Read an entry in the table of contents */
3222       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADTOCENTRY entered.\n"));
3223       st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_tocentry));
3224       if (st) return (st);
3225       memcpy_fromfs(&tocentry, (void *) arg, sizeof(struct cdrom_tocentry));
3226       i=tocentry.cdte_track;
3227       if (i==CDROM_LEADOUT) i=DriveStruct[d].n_last_track+1;
3228       else if (i<DriveStruct[d].n_first_track||i>DriveStruct[d].n_last_track) return (-EINVAL);
3229       tocentry.cdte_adr=DriveStruct[d].TocBuffer[i].ctl_adr&0x0F;
3230       tocentry.cdte_ctrl=(DriveStruct[d].TocBuffer[i].ctl_adr>>4)&0x0F;
3231       tocentry.cdte_datamode=DriveStruct[d].TocBuffer[i].format;
3232       if (tocentry.cdte_format==CDROM_MSF) /* MSF-bin required */
3233         { tocentry.cdte_addr.msf.minute=(DriveStruct[d].TocBuffer[i].address>>16)&0x00FF;
3234           tocentry.cdte_addr.msf.second=(DriveStruct[d].TocBuffer[i].address>>8)&0x00FF;
3235           tocentry.cdte_addr.msf.frame=DriveStruct[d].TocBuffer[i].address&0x00FF;
3236         }
3237       else if (tocentry.cdte_format==CDROM_LBA) /* blk required */
3238         tocentry.cdte_addr.lba=msf2blk(DriveStruct[d].TocBuffer[i].address);
3239       else return (-EINVAL);
3240       st=verify_area(VERIFY_WRITE,(void *) arg, sizeof(struct cdrom_tocentry));
3241       if (st) return (st);
3242       memcpy_tofs((void *) arg, &tocentry, sizeof(struct cdrom_tocentry));
3243       return (0);
3244 
3245     case CDROMSTOP:      /* Spin down the drive */
3246       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMSTOP entered.\n"));
3247       i=xx_Pause_Resume(1);
3248       DriveStruct[d].audio_state=0;
3249       return (0);
3250 
3251     case CDROMSTART:  /* Spin up the drive */
3252       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMSTART entered.\n"));
3253       xx_SpinUp();
3254       DriveStruct[d].audio_state=0;
3255       return (0);
3256       
3257     case CDROMEJECT:
3258       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMEJECT entered.\n"));
3259       if (fam0_drive) return (0);
3260       do i=yy_LockDoor(0);
3261       while (i!=0);
3262       DriveStruct[d].open_count=0; /* to get it locked next time again */
3263       i=yy_SpinDown();
3264       DPRINTF((DBG_IOX,"SBPCD: ioctl: yy_SpinDown returned %d.\n", i));
3265       if (i<0) return (-EIO);
3266       DriveStruct[d].CD_changed=0xFF;
3267       DriveStruct[d].diskstate_flags=0;
3268       DriveStruct[d].audio_state=0;
3269       return (0);
3270       
3271     case CDROMEJECT_SW:
3272       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMEJECT_SW entered.\n"));
3273       if (fam0_drive) return (0);
3274       DriveStruct[d].f_eject=arg;
3275       return (0);
3276       
3277     case CDROMVOLCTRL:   /* Volume control */
3278       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMVOLCTRL entered.\n"));
3279       st=verify_area(VERIFY_READ,(void *) arg,sizeof(volctrl));
3280       if (st) return (st);
3281       memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl));
3282       DriveStruct[d].vol_chan0=0;
3283       DriveStruct[d].vol_ctrl0=volctrl.channel0;
3284       DriveStruct[d].vol_chan1=1;
3285       DriveStruct[d].vol_ctrl1=volctrl.channel1;
3286       i=xx_SetVolume();
3287       return (0);
3288 
3289     case CDROMSUBCHNL:   /* Get subchannel info */
3290       DPRINTF((DBG_IOS,"SBPCD: ioctl: CDROMSUBCHNL entered.\n"));
3291       if ((st_spinning)||(!subq_valid)) { i=xx_ReadSubQ();
3292                                           if (i<0) return (-EIO);
3293                                         }
3294       st=verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_subchnl));
3295       if (st)   return (st);
3296       memcpy_fromfs(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
3297       switch (DriveStruct[d].audio_state)
3298         {
3299         case audio_playing:
3300           SC.cdsc_audiostatus=CDROM_AUDIO_PLAY;
3301           break;
3302         case audio_pausing:
3303           SC.cdsc_audiostatus=CDROM_AUDIO_PAUSED;
3304           break;
3305         default:
3306           SC.cdsc_audiostatus=CDROM_AUDIO_NO_STATUS;
3307           break;
3308         }
3309       SC.cdsc_adr=DriveStruct[d].SubQ_ctl_adr;
3310       SC.cdsc_ctrl=DriveStruct[d].SubQ_ctl_adr>>4;
3311       SC.cdsc_trk=bcd2bin(DriveStruct[d].SubQ_trk);
3312       SC.cdsc_ind=bcd2bin(DriveStruct[d].SubQ_pnt_idx);
3313       if (SC.cdsc_format==CDROM_LBA)
3314         {
3315           SC.cdsc_absaddr.lba=msf2blk(DriveStruct[d].SubQ_run_tot);
3316           SC.cdsc_reladdr.lba=msf2blk(DriveStruct[d].SubQ_run_trk);
3317         }
3318       else /* not only if (SC.cdsc_format==CDROM_MSF) */
3319         {
3320           SC.cdsc_absaddr.msf.minute=(DriveStruct[d].SubQ_run_tot>>16)&0x00FF;
3321           SC.cdsc_absaddr.msf.second=(DriveStruct[d].SubQ_run_tot>>8)&0x00FF;
3322           SC.cdsc_absaddr.msf.frame=DriveStruct[d].SubQ_run_tot&0x00FF;
3323           SC.cdsc_reladdr.msf.minute=(DriveStruct[d].SubQ_run_trk>>16)&0x00FF;
3324           SC.cdsc_reladdr.msf.second=(DriveStruct[d].SubQ_run_trk>>8)&0x00FF;
3325           SC.cdsc_reladdr.msf.frame=DriveStruct[d].SubQ_run_trk&0x00FF;
3326         }
3327       memcpy_tofs((void *) arg, &SC, sizeof(struct cdrom_subchnl));
3328       DPRINTF((DBG_IOS,"SBPCD: CDROMSUBCHNL: %1X %02X %08X %08X %02X %02X %06X %06X\n",
3329                SC.cdsc_format,SC.cdsc_audiostatus,
3330                SC.cdsc_adr,SC.cdsc_ctrl,
3331                SC.cdsc_trk,SC.cdsc_ind,
3332                SC.cdsc_absaddr,SC.cdsc_reladdr));
3333       return (0);
3334 
3335     case CDROMREADMODE1:
3336       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADMODE1 requested.\n"));
3337       xx_ModeSelect(CD_FRAMESIZE);
3338       xx_ModeSense();
3339       DriveStruct[d].mode=READ_M1;
3340       return (0);
3341 
3342     case CDROMREADMODE2: /* not usable at the moment */
3343       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADMODE2 requested.\n"));
3344       xx_ModeSelect(CD_FRAMESIZE_XA);
3345       xx_ModeSense();
3346       DriveStruct[d].mode=READ_M2;
3347       return (0);
3348 
3349     case CDROMREADAUDIO:
3350       { /* start of CDROMREADAUDIO */
3351         int i=0, j=0, frame, block;
3352         u_int try=0;
3353         u_long timeout;
3354         u_char *p;
3355         u_int data_tries = 0;
3356         u_int data_waits = 0;
3357         u_int data_retrying = 0;
3358         int status_tries;
3359         int error_flag;
3360 
3361         DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADAUDIO requested.\n"));
3362         if (fam0_drive) return (-EINVAL);
3363         if (famL_drive) return (-EINVAL);
3364         if (fam2_drive) return (-EINVAL);
3365         if (DriveStruct[d].aud_buf==NULL) return (-EINVAL);
3366         i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio));
3367         if (i) return (i);
3368         memcpy_fromfs(&read_audio, (void *) arg, sizeof(struct cdrom_read_audio));
3369         if (read_audio.nframes>SBP_BUFFER_AUDIO_FRAMES) return (-EINVAL);
3370         i=verify_area(VERIFY_WRITE, read_audio.buf,
3371                       read_audio.nframes*CD_FRAMESIZE_RAW);
3372         if (i) return (i);
3373 
3374         if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
3375           block=msf2lba(&read_audio.addr.msf.minute);
3376         else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
3377           block=read_audio.addr.lba;
3378         else return (-EINVAL);
3379         i=yy_SetSpeed(speed_150,0,0);
3380         if (i) DPRINTF((DBG_AUD,"SBPCD: read_audio: SetSpeed error %d\n", i));
3381         DPRINTF((DBG_AUD,"SBPCD: read_audio: lba: %d, msf: %06X\n",
3382                  block, blk2msf(block)));
3383         DPRINTF((DBG_AUD,"SBPCD: read_audio: before xx_ReadStatus.\n"));
3384         while (busy_data) sbp_sleep(10); /* wait a bit */
3385         busy_audio=1;
3386         error_flag=0;
3387         for (data_tries=5; data_tries>0; data_tries--)
3388           {
3389             DPRINTF((DBG_AUD,"SBPCD: data_tries=%d ...\n", data_tries));
3390             DriveStruct[d].mode=READ_AU;
3391             xx_ModeSelect(CD_FRAMESIZE_RAW);
3392             xx_ModeSense();
3393             for (status_tries=3; status_tries > 0; status_tries--)
3394               {
3395                 flags_cmd_out |= f_respo3;
3396                 xx_ReadStatus();
3397                 if (sbp_status() != 0) break;
3398                 sbp_sleep(1);    /* wait a bit, try again */
3399               }
3400             if (status_tries == 0)
3401               {
3402                 DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: failed after 3 tries.\n"));
3403                 continue;
3404               }
3405             DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_status: ok.\n"));
3406             
3407             flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
3408             if (fam0L_drive)
3409               {
3410                 flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
3411                 cmd_type=READ_M2;
3412                 drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
3413                 drvcmd[1]=(block>>16)&0x000000ff;
3414                 drvcmd[2]=(block>>8)&0x000000ff;
3415                 drvcmd[3]=block&0x000000ff;
3416                 drvcmd[4]=0;
3417                 drvcmd[5]=read_audio.nframes; /* # of frames */
3418                 drvcmd[6]=0;
3419               }
3420             else if (fam1_drive)
3421               {
3422                 drvcmd[0]=CMD1_READ; /* "read frames", new drives */
3423                 lba2msf(block,&drvcmd[1]); /* msf-bin format required */
3424                 drvcmd[4]=0;
3425                 drvcmd[5]=0;
3426                 drvcmd[6]=read_audio.nframes; /* # of frames */
3427               }
3428             else if (fam2_drive) /* CD200: not implemented yet */
3429               {
3430               }
3431             DPRINTF((DBG_AUD,"SBPCD: read_audio: before giving \"read\" command.\n"));
3432             for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
3433             sbp_sleep(0);
3434             DPRINTF((DBG_AUD,"SBPCD: read_audio: after giving \"read\" command.\n"));
3435             for (frame=1;frame<2 && !error_flag; frame++)
3436               {
3437                 try=maxtim_data;
3438                 for (timeout=jiffies+900; ; )
3439                   {
3440                     for ( ; try!=0;try--)
3441                       {
3442                         j=inb(CDi_status);
3443                         if (!(j&s_not_data_ready)) break;
3444                         if (!(j&s_not_result_ready)) break;
3445                         if (fam0L_drive) if (j&s_attention) break;
3446                       }
3447                     if (try != 0 || timeout <= jiffies) break;
3448                     if (data_retrying == 0) data_waits++;
3449                     data_retrying = 1;
3450                     sbp_sleep(1);
3451                     try = 1;
3452                   }
3453                 if (try==0)
3454                   {
3455                     DPRINTF((DBG_INF,"SBPCD: read_audio: sbp_data: CDi_status timeout.\n"));
3456                     error_flag++;
3457                     break;
3458                   }
3459                 DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_data: CDi_status ok.\n"));
3460                 if (j&s_not_data_ready)
3461                   {
3462                     printk("SBPCD: read_audio: sbp_data: DATA_READY timeout.\n");
3463                     error_flag++;
3464                     break;
3465                   }
3466                 DPRINTF((DBG_AUD,"SBPCD: read_audio: before reading data.\n"));
3467                 error_flag=0;
3468                 p = DriveStruct[d].aud_buf;
3469                 if (sbpro_type==1) OUT(CDo_sel_i_d,1);
3470 #if 0
3471                 cli();
3472 #endif
3473                 READ_DATA(CDi_data, p, read_audio.nframes*CD_FRAMESIZE_RAW);
3474 #if 0
3475                 sti();
3476 #endif
3477                 if (sbpro_type==1) OUT(CDo_sel_i_d,0);
3478                 data_retrying = 0;
3479               }
3480             DPRINTF((DBG_AUD,"SBPCD: read_audio: after reading data.\n"));
3481             if (error_flag)    /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
3482               {
3483                 DPRINTF((DBG_AUD,"SBPCD: read_audio: read aborted by drive\n"));
3484 #if 0000
3485                 i=DriveReset();                /* ugly fix to prevent a hang */
3486 #else
3487                 i=xx_ReadError();
3488 #endif 0000
3489                 continue;
3490               }
3491             if (fam0L_drive)
3492               {
3493                 i=maxtim_data;
3494                 for (timeout=jiffies+900; timeout > jiffies; timeout--)
3495                   {
3496                     for ( ;i!=0;i--)
3497                       {
3498                         j=inb(CDi_status);
3499                         if (!(j&s_not_data_ready)) break;
3500                         if (!(j&s_not_result_ready)) break;
3501                         if (j&s_attention) break;
3502                       }
3503                     if (i != 0 || timeout <= jiffies) break;
3504                     sbp_sleep(0);
3505                     i = 1;
3506                   }
3507                 if (i==0) { DPRINTF((DBG_AUD,"SBPCD: read_audio: STATUS TIMEOUT AFTER READ")); }
3508                 if (!(j&s_attention))
3509                   {
3510                     DPRINTF((DBG_AUD,"SBPCD: read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n"));
3511                     i=DriveReset();  /* ugly fix to prevent a hang */
3512                   continue;
3513                   }
3514               }
3515             do
3516               {
3517                 if (fam0L_drive) xx_ReadStatus();
3518                 i=ResponseStatus();  /* builds status_byte, returns orig. status (old) or faked p_success_old (new) */
3519                 if (i<0) { DPRINTF((DBG_AUD,
3520                                     "SBPCD: read_audio: xx_ReadStatus error after read: %02X\n",
3521                                     DriveStruct[d].status_byte));
3522                            continue; /* FIXME */
3523                          }
3524               }
3525             while ((fam0L_drive)&&(!st_check)&&(!(i&p_success_old)));
3526             if (st_check)
3527               {
3528                 i=xx_ReadError();
3529                 DPRINTF((DBG_AUD,"SBPCD: read_audio: xx_ReadError was necessary after read: %02X\n",i));
3530                 continue;
3531               }
3532             memcpy_tofs((u_char *) read_audio.buf,
3533                         (u_char *) DriveStruct[d].aud_buf,
3534                         read_audio.nframes*CD_FRAMESIZE_RAW);
3535             DPRINTF((DBG_AUD,"SBPCD: read_audio: memcpy_tofs done.\n"));
3536             break;
3537           }
3538         xx_ModeSelect(CD_FRAMESIZE);
3539         xx_ModeSense();
3540         DriveStruct[d].mode=READ_M1;
3541         busy_audio=0;
3542         if (data_tries == 0)
3543           {
3544             DPRINTF((DBG_AUD,"SBPCD: read_audio: failed after 5 tries.\n"));
3545             return (-8);
3546           }
3547         DPRINTF((DBG_AUD,"SBPCD: read_audio: successful return.\n"));
3548         return (0);
3549       } /* end of CDROMREADAUDIO */
3550 
3551     case CDROMMULTISESSION: /* tell start-of-last-session */
3552       DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMMULTISESSION entered.\n"));
3553       st=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_multisession));
3554       if (st) return (st);
3555       memcpy_fromfs(&ms_info, (void *) arg, sizeof(struct cdrom_multisession));
3556       if (ms_info.addr_format==CDROM_MSF) /* MSF-bin requested */
3557         lba2msf(DriveStruct[d].lba_multi,&ms_info.addr.msf.minute);
3558       else if (ms_info.addr_format==CDROM_LBA) /* lba requested */
3559         ms_info.addr.lba=DriveStruct[d].lba_multi;
3560       else return (-EINVAL);
3561       if (DriveStruct[d].f_multisession) ms_info.xa_flag=1; /* valid redirection address */
3562       else ms_info.xa_flag=0; /* invalid redirection address */
3563       st=verify_area(VERIFY_WRITE,(void *) arg, sizeof(struct cdrom_multisession));
3564       if (st) return (st);
3565       memcpy_tofs((void *) arg, &ms_info, sizeof(struct cdrom_multisession));
3566       DPRINTF((DBG_MUL,"SBPCD: ioctl: CDROMMULTISESSION done (%d, %08X).\n",
3567                ms_info.xa_flag, ms_info.addr.lba));
3568       return (0);
3569 
3570     case BLKRASET:
3571       if(!suser())  return -EACCES;
3572       if(!inode->i_rdev) return -EINVAL;
3573       if(arg > 0xff) return -EINVAL;
3574       read_ahead[MAJOR(inode->i_rdev)] = arg;
3575       return (0);
3576 
3577     default:
3578       DPRINTF((DBG_IOC,"SBPCD: ioctl: unknown function request %04X\n", cmd));
3579       return (-EINVAL);
3580     } /* end switch(cmd) */
3581 }
3582 /*==========================================================================*/
3583 /*
3584  *  Take care of the different block sizes between cdrom and Linux.
3585  */
3586 static void sbp_transfer(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3587 {
3588   long offs;
3589   
3590   while ( (CURRENT->nr_sectors > 0) &&
3591           (CURRENT->sector/4 >= DriveStruct[d].sbp_first_frame) &&
3592           (CURRENT->sector/4 <= DriveStruct[d].sbp_last_frame) )
3593     {
3594       offs = (CURRENT->sector - DriveStruct[d].sbp_first_frame * 4) * 512;
3595       memcpy(CURRENT->buffer, DriveStruct[d].sbp_buf + offs, 512);
3596       CURRENT->nr_sectors--;
3597       CURRENT->sector++;
3598       CURRENT->buffer += 512;
3599     }
3600 }
3601 /*==========================================================================*/
3602 /*
3603  *  I/O request routine, called from Linux kernel.
3604  */
3605 static void DO_SBPCD_REQUEST(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3606 {
3607   u_int block;
3608   u_int nsect;
3609   int i, status_tries, data_tries;
3610   
3611 request_loop:
3612   INIT_REQUEST;
3613   sti();
3614 
3615   if ((CURRENT==NULL)||(CURRENT->dev<0)) goto err_done;
3616   if (CURRENT -> sector == -1) goto err_done;
3617   if (CURRENT->cmd != READ)
3618     {
3619       printk("SBPCD: bad cmd %d\n", CURRENT->cmd);
3620       goto err_done;
3621     }
3622   i = MINOR(CURRENT->dev);
3623   if ( (i<0) || (i>=NR_SBPCD) || (DriveStruct[i].drv_id==-1))
3624     {
3625       printk("SBPCD: do_request: bad device: %04X\n", CURRENT->dev);
3626       goto err_done;
3627     }
3628   switch_drive(i);
3629 
3630   block = CURRENT->sector; /* always numbered as 512-byte-pieces */
3631   nsect = CURRENT->nr_sectors; /* always counted as 512-byte-pieces */
3632 
3633   DPRINTF((DBG_BSZ,"SBPCD: read sector %d (%d sectors)\n", block, nsect));
3634 #if 0
3635   DPRINTF((DBG_MUL,"SBPCD: read LBA %d\n", block/4));
3636 #endif
3637 
3638   sbp_transfer();
3639   /* if we satisfied the request from the buffer, we're done. */
3640   if (CURRENT->nr_sectors == 0)
3641     {
3642       end_request(1);
3643       goto request_loop;
3644     }
3645 
3646   i=prepare(0,0); /* at moment not really a hassle check, but ... */
3647   if (i!=0)
3648     DPRINTF((DBG_INF,"SBPCD: \"prepare\" tells error %d -- ignored\n", i));
3649 
3650   while (busy_audio) sbp_sleep(100); /* wait a bit */
3651   busy_data=1;
3652 
3653   if (!st_spinning) xx_SpinUp();
3654 
3655 #ifdef XA_TEST1
3656   if ((fam0L_drive) && (DriveStruct[d].xa_byte==0x20)) /* XA disk with old drive */
3657       {
3658         xx_ModeSelect(CD_FRAMESIZE_XA);
3659         xx_ModeSense();
3660       }
3661 #endif XA_TEST1
3662 
3663   for (data_tries=n_retries; data_tries > 0; data_tries--)
3664     {
3665       for (status_tries=3; status_tries > 0; status_tries--)
3666         {
3667           flags_cmd_out |= f_respo3;
3668           xx_ReadStatus();
3669           if (sbp_status() != 0) break;
3670           if (st_check) xx_ReadError();
3671           sbp_sleep(1);    /* wait a bit, try again */
3672         }
3673       if (status_tries == 0)
3674         {
3675           DPRINTF((DBG_INF,"SBPCD: sbp_status: failed after 3 tries\n"));
3676           break;
3677         }
3678 
3679       sbp_read_cmd();
3680       sbp_sleep(0);
3681       if (sbp_data() != 0)
3682         {
3683           end_request(1);
3684           goto request_loop;
3685         }
3686     }
3687   
3688 err_done:
3689   busy_data=0;
3690   end_request(0);
3691   sbp_sleep(10);    /* wait a bit, try again */
3692   goto request_loop;
3693 }
3694 /*==========================================================================*/
3695 /*
3696  *  build and send the READ command.
3697  *  Maybe it would be better to "set mode1" before ...
3698  */
3699 static void sbp_read_cmd(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3700 {
3701   int i;
3702   int block;
3703 
3704   DriveStruct[d].sbp_first_frame=DriveStruct[d].sbp_last_frame=-1;      /* purge buffer */
3705   block=CURRENT->sector/4;
3706   if (block+SBP_BUFFER_FRAMES <= DriveStruct[d].CDsize_frm)
3707     DriveStruct[d].sbp_read_frames = SBP_BUFFER_FRAMES;
3708   else
3709     {
3710       DriveStruct[d].sbp_read_frames=DriveStruct[d].CDsize_frm-block;
3711                                       /* avoid reading past end of data */
3712       if (DriveStruct[d].sbp_read_frames < 1)
3713         {
3714           DPRINTF((DBG_INF,"SBPCD: requested frame %d, CD size %d ???\n",
3715                         block, DriveStruct[d].CDsize_frm));
3716           DriveStruct[d].sbp_read_frames=1;
3717         }
3718     }
3719   DriveStruct[d].sbp_current = 0;
3720 
3721   flags_cmd_out = f_putcmd |
3722                   f_respo2 |
3723                   f_ResponseStatus |
3724                   f_obey_p_check;
3725 
3726   if (fam0L_drive)
3727     {
3728       flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
3729       if (DriveStruct[d].xa_byte==0x20)
3730         {
3731           cmd_type=READ_M2;
3732           drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
3733           drvcmd[1]=(block>>16)&0x000000ff;
3734           drvcmd[2]=(block>>8)&0x000000ff;
3735           drvcmd[3]=block&0x000000ff;
3736           drvcmd[4]=0;
3737           drvcmd[5]=DriveStruct[d].sbp_read_frames;
3738           drvcmd[6]=0;
3739         }
3740       else
3741         {
3742           drvcmd[0]=CMD0_READ; /* "read frames", old drives */
3743           
3744           if (DriveStruct[d].drv_type>=drv_201)
3745             {
3746               lba2msf(block,&drvcmd[1]); /* msf-bcd format required */
3747               bin2bcdx(&drvcmd[1]);
3748               bin2bcdx(&drvcmd[2]);
3749               bin2bcdx(&drvcmd[3]);
3750             }
3751           else
3752             {
3753               drvcmd[1]=(block>>16)&0x000000ff;
3754               drvcmd[2]=(block>>8)&0x000000ff;
3755               drvcmd[3]=block&0x000000ff;
3756             }
3757           drvcmd[4]=0;
3758           drvcmd[5]=DriveStruct[d].sbp_read_frames;
3759           drvcmd[6]=(DriveStruct[d].drv_type<drv_201)?0:2; /* flag "lba or msf-bcd format" */
3760         }
3761     }
3762   else if (fam1_drive)
3763     {
3764       drvcmd[0]=CMD1_READ;
3765       lba2msf(block,&drvcmd[1]); /* msf-bin format required */
3766       drvcmd[4]=0;
3767       drvcmd[5]=0;
3768       drvcmd[6]=DriveStruct[d].sbp_read_frames;
3769     }
3770   else if (fam2_drive)
3771     {
3772       drvcmd[0]=CMD2_READ;
3773       lba2msf(block,&drvcmd[1]); /* msf-bin format required */
3774       drvcmd[4]=0;
3775       drvcmd[5]=DriveStruct[d].sbp_read_frames;
3776       drvcmd[6]=0x02;
3777     }
3778   SBPCD_CLI;
3779   for (i=0;i<7;i++) OUT(CDo_command,drvcmd[i]);
3780   SBPCD_STI;
3781 
3782   return;
3783 }
3784 /*==========================================================================*/
3785 /*
3786  *  Check the completion of the read-data command.  On success, read
3787  *  the SBP_BUFFER_FRAMES * 2048 bytes of data from the disk into buffer.
3788  */
3789 static int sbp_data(void)
     /* [previous][next][first][last][top][bottom][index][help] */
3790 {
3791   int i=0, j=0, frame;
3792   u_int try=0;
3793   u_long timeout;
3794   u_char *p;
3795   u_int data_tries = 0;
3796   u_int data_waits = 0;
3797   u_int data_retrying = 0;
3798   int error_flag;
3799   int xa_count;
3800   error_flag=0;
3801 
3802   for (frame=DriveStruct[d].sbp_current;frame<DriveStruct[d].sbp_read_frames&&!error_flag; frame++)
3803     {
3804       SBPCD_CLI;
3805       try=maxtim_data;
3806 #if LONG_TIMING
3807       for (timeout=jiffies+900; ; )
3808 #else
3809       for (timeout=jiffies+ ( (famL_drive)? 300:100 ); ; )
3810 #endif
3811         {
3812           for ( ; try!=0;try--)
3813             {
3814               j=inb(CDi_status);
3815               if (!(j&s_not_data_ready)) break;
3816               if (!(j&s_not_result_ready)) break;
3817               if (fam0L_drive) if (j&s_attention) break;
3818             }
3819           if (try != 0 || timeout <= jiffies) break;
3820           if (data_retrying == 0) data_waits++;
3821           data_retrying = 1;
3822           sbp_sleep(1);
3823           try = 1;
3824         }
3825       if (try==0)
3826         {
3827           DPRINTF((DBG_INF,"SBPCD: sbp_data: CDi_status timeout.\n"));
3828           error_flag++;
3829           break;
3830         }
3831 
3832       if (j&s_not_data_ready)
3833         {
3834           if ((DriveStruct[d].ored_ctl_adr&0x40)==0)
3835             printk("SBPCD: CD contains no data tracks.\n");
3836           else printk("SBPCD: sbp_data: DATA_READY timeout.\n");
3837           error_flag++;
3838           break;
3839         }
3840 
3841       SBPCD_STI;
3842       error_flag=0;
3843       p = DriveStruct[d].sbp_buf + frame *  CD_FRAMESIZE;
3844 
3845       if (sbpro_type==1) OUT(CDo_sel_i_d,1);
3846       if (cmd_type==READ_M2) READ_DATA(CDi_data, xa_head_buf, CD_XA_HEAD);
3847       READ_DATA(CDi_data, p, CD_FRAMESIZE);
3848       if (cmd_type==READ_M2) READ_DATA(CDi_data, xa_tail_buf, CD_XA_TAIL);
3849       if (sbpro_type==1) OUT(CDo_sel_i_d,0);
3850       DriveStruct[d].sbp_current++;
3851       if (cmd_type==READ_M2)
3852         {
3853           DPRINTF((DBG_XA,"SBPCD: xa_head:"));
3854           for (xa_count=0;xa_count<CD_XA_HEAD;xa_count++)
3855             DPRINTF((DBG_XA," %02X", xa_head_buf[xa_count]));
3856           DPRINTF((DBG_XA,"\n"));
3857         }
3858       data_tries++;
3859       data_retrying = 0;
3860       if (data_tries >= 1000)
3861         {
3862           DPRINTF((DBG_INF,"SBPCD: info: %d waits in %d frames.\n",
3863                         data_waits, data_tries));
3864           data_waits = data_tries = 0;
3865         }
3866     }
3867   SBPCD_STI;
3868   
3869   if (error_flag)    /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
3870     {
3871       DPRINTF((DBG_INF,"SBPCD: read aborted by drive\n"));
3872 #if 0
3873       i=DriveReset();                /* ugly fix to prevent a hang */
3874 #else
3875       i=xx_ReadError();
3876 #endif
3877       return (0);
3878     }
3879 
3880   if (fam0L_drive)
3881     {
3882       SBPCD_CLI;
3883       i=maxtim_data;
3884       for (timeout=jiffies+100; timeout > jiffies; timeout--)
3885         {
3886           for ( ;i!=0;i--)
3887             {
3888               j=inb(CDi_status);
3889               if (!(j&s_not_data_ready)) break;
3890               if (!(j&s_not_result_ready)) break;
3891               if (j&s_attention) break;
3892             }
3893           if (i != 0 || timeout <= jiffies) break;
3894           sbp_sleep(0);
3895           i = 1;
3896         }
3897       if (i==0) { DPRINTF((DBG_INF,"SBPCD: STATUS TIMEOUT AFTER READ")); }
3898       if (!(j&s_attention))
3899         {
3900           DPRINTF((DBG_INF,"SBPCD: sbp_data: timeout waiting DRV_ATTN - retrying\n"));
3901           i=DriveReset();  /* ugly fix to prevent a hang */
3902           SBPCD_STI;
3903           return (0);
3904         }
3905       SBPCD_STI;
3906     }
3907 
3908   do
3909     {
3910       if (fam0L_drive) xx_ReadStatus();
3911       i=ResponseStatus();  /* builds status_byte, returns orig. status (old) or faked p_success_old (new) */
3912       if (i<0) { DPRINTF((DBG_INF,"SBPCD: xx_ReadStatus error after read: %02X\n",
3913                                DriveStruct[d].status_byte));
3914                  return (0);
3915                }
3916     }
3917   while ((fam0L_drive)&&(!st_check)&&(!(i&p_success_old)));
3918   if (st_check)
3919     {
3920       i=xx_ReadError();
3921       DPRINTF((DBG_INF,"SBPCD: xx_ReadError was necessary after read: %02X\n",i));
3922       return (0);
3923     }
3924 
3925   DriveStruct[d].sbp_first_frame = CURRENT -> sector / 4;
3926   DriveStruct[d].sbp_last_frame = DriveStruct[d].sbp_first_frame + DriveStruct[d].sbp_read_frames - 1;
3927   sbp_transfer();
3928   return (1);
3929 }
3930 /*==========================================================================*/
3931 /*==========================================================================*/
3932 /*
3933  *  Open the device special file.  Check that a disk is in. Read TOC.
3934  */
3935 static int sbpcd_open(struct inode *ip, struct file *fp)
     /* [previous][next][first][last][top][bottom][index][help] */
3936 {
3937   int i;
3938 
3939   i = MINOR(ip->i_rdev);
3940   if ((i<0) || (i>=NR_SBPCD) || (DriveStruct[i].drv_id==-1))
3941     {
3942       printk("SBPCD: open: bad device: %04X\n", ip->i_rdev);
3943       return (-ENXIO);             /* no such drive */
3944     }
3945   if (fp->f_mode & 2)
3946           return -EROFS;
3947   
3948   switch_drive(i);
3949 
3950   flags_cmd_out |= f_respo2;
3951   xx_ReadStatus();                         /* command: give 1-byte status */
3952   i=ResponseStatus();
3953   if (!st_door_closed)
3954     {
3955       yy_CloseTray();
3956       flags_cmd_out |= f_respo2;
3957       xx_ReadStatus();
3958       i=ResponseStatus();
3959     }
3960   if (!st_spinning)
3961     {
3962       xx_SpinUp();
3963       flags_cmd_out |= f_respo2;
3964       xx_ReadStatus();
3965       i=ResponseStatus();
3966     }
3967   if (i<0)
3968     {
3969       DPRINTF((DBG_INF,"SBPCD: sbpcd_open: xx_ReadStatus timed out\n"));
3970       return (-EIO);                  /* drive doesn't respond */
3971     }
3972   DPRINTF((DBG_STA,"SBPCD: sbpcd_open: status %02X\n", DriveStruct[d].status_byte));
3973   if (!st_door_closed||!st_caddy_in)
3974     {
3975       printk("SBPCD: sbpcd_open: no disk in drive\n");
3976 #if JUKEBOX
3977       do
3978         i=yy_LockDoor(0);
3979       while (i!=0);
3980       if (!fam0_drive) yy_SpinDown(); /* eject tray */
3981 #endif
3982       return (-ENXIO);
3983     }
3984 /*
3985  * try to keep an "open" counter here and lock the door if 0->1.
3986  */
3987   MOD_INC_USE_COUNT;
3988   DPRINTF((DBG_LCK,"SBPCD: open_count: %d -> %d\n",
3989            DriveStruct[d].open_count,DriveStruct[d].open_count+1));
3990   if (++DriveStruct[d].open_count==1)
3991     {
3992       do
3993         i=yy_LockDoor(1);
3994       while (i!=0);
3995     }
3996   if (!st_spinning) xx_SpinUp();
3997 
3998   i=DiskInfo();
3999   if ((DriveStruct[d].ored_ctl_adr&0x40)==0)
4000     DPRINTF((DBG_INF,"SBPCD: CD contains no data tracks.\n"));
4001   return (0);
4002 }
4003 /*==========================================================================*/
4004 /*
4005  *  On close, we flush all sbp blocks from the buffer cache.
4006  */
4007 static void sbpcd_release(struct inode * ip, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
4008 {
4009   int i;
4010 
4011   i = MINOR(ip->i_rdev);
4012   if ((i<0) || (i>=NR_SBPCD) || (DriveStruct[i].drv_id==-1))
4013     {
4014       printk("SBPCD: release: bad device: %04X\n", ip->i_rdev);
4015       return;
4016     }
4017   switch_drive(i);
4018 
4019   DriveStruct[d].sbp_first_frame=DriveStruct[d].sbp_last_frame=-1;
4020   sync_dev(ip->i_rdev);                   /* nonsense if read only device? */
4021   invalidate_buffers(ip->i_rdev);
4022 
4023 /*
4024  * try to keep an "open" counter here and unlock the door if 1->0.
4025  */
4026   MOD_DEC_USE_COUNT;
4027   DPRINTF((DBG_LCK,"SBPCD: open_count: %d -> %d\n",
4028            DriveStruct[d].open_count,DriveStruct[d].open_count-1));
4029   if (DriveStruct[d].open_count!=0) /* CDROMEJECT may have been done */
4030     {
4031       if (--DriveStruct[d].open_count==0) 
4032         {
4033           do
4034             i=yy_LockDoor(0);
4035           while (i!=0);
4036           if (DriveStruct[d].f_eject) yy_SpinDown();
4037           DriveStruct[d].diskstate_flags &= ~cd_size_bit;
4038         }
4039     }
4040 }
4041 /*==========================================================================*/
4042 /*
4043  *
4044  */
4045 static struct file_operations sbpcd_fops =
4046 {
4047   NULL,                   /* lseek - default */
4048   block_read,             /* read - general block-dev read */
4049   block_write,            /* write - general block-dev write */
4050   NULL,                   /* readdir - bad */
4051   NULL,                   /* select */
4052   sbpcd_ioctl,            /* ioctl */
4053   NULL,                   /* mmap */
4054   sbpcd_open,             /* open */
4055   sbpcd_release,          /* release */
4056   NULL,                   /* fsync */
4057   NULL,                   /* fasync */
4058   sbpcd_chk_disk_change,  /* media_change */
4059   NULL                    /* revalidate */
4060 };
4061 /*==========================================================================*/
4062 /*
4063  * accept "kernel command line" parameters 
4064  * (suggested by Peter MacDonald with SLS 1.03)
4065  *
4066  * This is only implemented for the first controller. Should be enough to
4067  * allow installing with a "strange" distribution kernel.
4068  *
4069  * use: tell LILO:
4070  *                 sbpcd=0x230,SoundBlaster
4071  *             or
4072  *                 sbpcd=0x300,LaserMate
4073  *             or
4074  *                 sbpcd=0x330,SPEA
4075  *
4076  * (upper/lower case sensitive here!!!).
4077  *
4078  * the address value has to be the TRUE CDROM PORT ADDRESS -
4079  * not the soundcard base address.
4080  *
4081  */
4082 #if (SBPCD_ISSUE-1)
4083 static
4084 #endif
4085 void sbpcd_setup(char *s, int *p)
     /* [previous][next][first][last][top][bottom][index][help] */
4086 {
4087   setup_done++;
4088   DPRINTF((DBG_INI,"SBPCD: sbpcd_setup called with %04X,%s\n",p[1], s));
4089   sbpro_type=0;
4090   if (!strcmp(s,str_sb)) sbpro_type=1;
4091   else if (!strcmp(s,str_sb_l)) sbpro_type=1;
4092   else if (!strcmp(s,str_sp)) sbpro_type=2;
4093   else if (!strcmp(s,str_sp_l)) sbpro_type=2;
4094   if (p[0]>0) sbpcd_ioaddr=p[1];
4095 
4096   CDo_command=sbpcd_ioaddr;
4097   CDi_info=sbpcd_ioaddr;
4098   CDi_status=sbpcd_ioaddr+1;
4099   CDo_sel_i_d=sbpcd_ioaddr+1;
4100   CDo_reset=sbpcd_ioaddr+2;
4101   CDo_enable=sbpcd_ioaddr+3; 
4102   if (sbpro_type==1)
4103     {
4104       MIXER_addr=sbpcd_ioaddr-0x10+0x04;
4105       MIXER_data=sbpcd_ioaddr-0x10+0x05;
4106       CDi_data=sbpcd_ioaddr;
4107     }
4108   else CDi_data=sbpcd_ioaddr+2;
4109 }
4110 /*==========================================================================*/
4111 /*
4112  * Sequoia S-1000 CD-ROM Interface Configuration
4113  * as used within SPEA Media FX card
4114  * The SPEA soundcard has to get jumpered for 
4115  *     -> interface type "Matsushita/Panasonic" (not Sony or Mitsumi)
4116  *     -> I/O base address (0x320, 0x330, 0x340, 0x350)
4117  */
4118 static int config_spea(void)
     /* [previous][next][first][last][top][bottom][index][help] */
4119 {
4120   int n_ports=0x10; /* 2:0x00, 8:0x10, 16:0x20, 32:0x30 */
4121 /* What is n_ports? Number of addresses or base address offset? */
4122   int irq_number=0; /* 2:0x01, 7:0x03, 12:0x05, 15:0x07, OFF:0x00 */
4123   int dma_channel=0; /* 0:0x08, 1:0x18, 3:0x38, 5:0x58, 6:0x68, 7:0x78, OFF: 0x00 */
4124   int dack_polarity=0; /* L:0x00, H:0x80 */
4125   int drq_polarity=0x40; /* L:0x00, H:0x40 */
4126 
4127   int i;
4128 
4129 #define SPEA_REG_1 sbpcd_ioaddr+4
4130 #define SPEA_REG_2 sbpcd_ioaddr+5
4131 
4132   OUT(SPEA_REG_1,0xFF);
4133   i=inb(SPEA_REG_1);
4134   if (i!=0x0F)
4135     {
4136       DPRINTF((DBG_SEQ,"SBPCD: no SPEA interface at %04X present.\n",
4137                sbpcd_ioaddr));
4138       return (-1); /* no interface found */
4139     }
4140   OUT(SPEA_REG_1,0x04);
4141   OUT(SPEA_REG_2,0xC0);
4142 
4143   OUT(SPEA_REG_1,0x05);
4144   OUT(SPEA_REG_2,0x10|drq_polarity|dack_polarity);
4145 
4146 #if 1
4147 #define SPEA_PATTERN 0x80
4148 #else
4149 #define SPEA_PATTERN 0x00
4150 #endif
4151   OUT(SPEA_REG_1,0x06);
4152   OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
4153   OUT(SPEA_REG_2,dma_channel|irq_number|SPEA_PATTERN);
4154 
4155   OUT(SPEA_REG_1,0x09);
4156   i=(inb(SPEA_REG_2)&0xCF)|n_ports;
4157   OUT(SPEA_REG_2,i);
4158 
4159   sbpro_type = 0; /* acts like a LaserMate interface now */
4160   DPRINTF((DBG_SEQ,"SBPCD: found SPEA interface at %04X.\n",
4161            sbpcd_ioaddr));
4162   return (0);
4163 }
4164 /*==========================================================================*/
4165 /*
4166  *  Test for presence of drive and initialize it.  Called at boot time.
4167  */
4168 #ifdef MODULE
4169 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
4170 #else
4171 unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end)
4172 #endif MODULE
4173 {
4174   int i=0, j=0;
4175   int addr[2]={1, CDROM_PORT};
4176   int port_index;
4177    
4178   sti(); /* necessary, has consequences for other drivers' init routines */
4179 
4180   DPRINTF((DBG_INF,"SBPCD version %s\n", VERSION));
4181 
4182 #ifndef MODULE
4183   if (!setup_done)
4184     {
4185       DPRINTF((DBG_INF,"SBPCD: Looking for Matsushita, Panasonic, CreativeLabs, IBM, Longshine CD-ROM drives\n"));
4186       DPRINTF((DBG_WRN,"SBPCD: \n"));
4187       DPRINTF((DBG_WRN,"SBPCD: = = = = = = = = = = W A R N I N G = = = = = = = = = =\n"));
4188       DPRINTF((DBG_WRN,"SBPCD: Auto-Probing can cause a hang (f.e. touching an ethernet card).\n"));
4189       DPRINTF((DBG_WRN,"SBPCD: If that happens, you have to reboot and use the\n"));
4190       DPRINTF((DBG_WRN,"SBPCD: LILO (kernel) command line feature like:\n"));
4191       DPRINTF((DBG_WRN,"SBPCD: \n"));
4192       DPRINTF((DBG_WRN,"SBPCD:    LILO boot: linux sbpcd=0x230,SoundBlaster\n"));
4193       DPRINTF((DBG_WRN,"SBPCD: or like:\n"));
4194       DPRINTF((DBG_WRN,"SBPCD:    LILO boot: linux sbpcd=0x300,LaserMate\n"));
4195       DPRINTF((DBG_WRN,"SBPCD: or like:\n"));
4196       DPRINTF((DBG_WRN,"SBPCD:    LILO boot: linux sbpcd=0x330,SPEA\n"));
4197       DPRINTF((DBG_WRN,"SBPCD: \n"));
4198       DPRINTF((DBG_WRN,"SBPCD: with your REAL address.\n"));
4199       DPRINTF((DBG_WRN,"SBPCD: = = = = = = = = = = END of WARNING = = = = = = = = = =\n"));
4200       DPRINTF((DBG_WRN,"SBPCD: \n"));
4201     }
4202 #endif MODULE
4203   sbpcd_probe[0]=sbpcd_ioaddr; /* possibly changed by kernel command line */
4204   sbpcd_probe[1]=sbpro_type; /* possibly changed by kernel command line */
4205 
4206   for (port_index=0;port_index<NUM_PROBE;port_index+=2)
4207     {
4208       addr[1]=sbpcd_probe[port_index];
4209       if (addr[1]==0) break;
4210       if (check_region(addr[1],4))
4211         {
4212           DPRINTF((DBG_INI,"SBPCD: check_region: %03X is not free.\n",addr[1]));
4213           continue;
4214         }
4215       if (sbpcd_probe[port_index+1]==0) type=str_lm;
4216       else if (sbpcd_probe[port_index+1]==1) type=str_sb;
4217       else type=str_sp;
4218       sbpcd_setup(type, addr);
4219       DPRINTF((DBG_INF,"SBPCD: Trying to detect a %s CD-ROM drive at 0x%X.\n", type, CDo_command));
4220       DPRINTF((DBG_INF,"SBPCD: - "));
4221       if (sbpcd_probe[port_index+1]==2)
4222         {
4223           i=config_spea();
4224           if (i<0)
4225             {
4226               DPRINTF((DBG_INF,"\n"));
4227               continue;
4228             }
4229         }
4230       i=check_drives();
4231       DPRINTF((DBG_INI,"SBPCD: check_drives done.\n"));
4232       if (i>=0) break; /* drive found */
4233       DPRINTF((DBG_INF,"\n"));
4234     } /* end of cycling through the set of possible I/O port addresses */
4235 
4236   if (ndrives==0)
4237     {
4238       printk("SBPCD: No drive found.\n");
4239 #if PRINTK_BUG
4240       sti(); /* to avoid possible "printk" bug */
4241 #endif
4242 #ifdef MODULE
4243       return -EIO;
4244 #else
4245       goto init_done;
4246 #endif MODULE
4247     }
4248 
4249   if (port_index>0)
4250     {
4251       printk("SBPCD: You should configure sbpcd.h for your hardware.\n");
4252 #if PRINTK_BUG
4253       sti(); /* to avoid possible "printk" bug */
4254 #endif
4255     }
4256 
4257   printk("SBPCD: %d %s CD-ROM drive(s) at 0x%04X.\n",
4258            ndrives, type, CDo_command);
4259 #if PRINTK_BUG
4260   sti(); /* to avoid possible "printk" bug */
4261 #endif
4262   check_datarate();
4263   DPRINTF((DBG_INI,"SBPCD: check_datarate done.\n"));
4264 
4265    if (!famL_drive)
4266    {
4267      OUT(CDo_reset,0);
4268      sbp_sleep(100);
4269    }
4270 
4271   for (j=0;j<NR_SBPCD;j++)
4272     {
4273       if (DriveStruct[j].drv_id==-1) continue;
4274       switch_drive(j);
4275       if (!famL_drive) xy_DriveReset();
4276       if (!st_spinning) xx_SpinUp();
4277       DriveStruct[d].sbp_first_frame = -1;  /* First frame in buffer */
4278       DriveStruct[d].sbp_last_frame = -1;   /* Last frame in buffer  */
4279       DriveStruct[d].sbp_read_frames = 0;   /* Number of frames being read to buffer */
4280       DriveStruct[d].sbp_current = 0;       /* Frame being currently read */
4281       DriveStruct[d].CD_changed=1;
4282       DriveStruct[d].frame_size=CD_FRAMESIZE;
4283 #if EJECT
4284       if (!fam0_drive) DriveStruct[d].f_eject=1;
4285       else DriveStruct[d].f_eject=0;
4286 #else
4287       DriveStruct[d].f_eject=0;
4288 #endif
4289 
4290       xx_ReadStatus();
4291       i=ResponseStatus();  /* returns orig. status or p_busy_new */
4292       if (i<0)
4293         DPRINTF((DBG_INF,"SBPCD: init: ResponseStatus returns %02X\n",i));
4294       else
4295         {
4296           if (st_check)
4297             {
4298               i=xx_ReadError();
4299               DPRINTF((DBG_INI,"SBPCD: init: xx_ReadError returns %d\n",i));
4300             }
4301         }
4302       DPRINTF((DBG_INI,"SBPCD: init: first GetStatus: %d\n",i));
4303       DPRINTF((DBG_LCS,"SBPCD: init: first GetStatus: error_byte=%d\n",
4304                DriveStruct[d].error_byte));
4305       if (DriveStruct[d].error_byte==aud_12)
4306         {
4307           do { i=GetStatus();
4308                DPRINTF((DBG_INI,"SBPCD: init: second GetStatus: %02X\n",i));
4309                DPRINTF((DBG_LCS,
4310                         "SBPCD: init: second GetStatus: error_byte=%d\n",
4311                         DriveStruct[d].error_byte));
4312                if (i<0) break;
4313                if (!st_caddy_in) break;
4314              }
4315           while (!st_diskok);
4316         }
4317       i=SetSpeed();
4318       if (i>=0) DriveStruct[d].CD_changed=1;
4319     }
4320 
4321 /*
4322  * Turn on the CD audio channels.
4323  * For "compatible" soundcards (with "SBPRO 0" or "SBPRO 2"), the addresses
4324  * are obtained from SOUND_BASE (see sbpcd.h).
4325  */
4326   if ((sbpro_type==1) || (SOUND_BASE))
4327     {
4328       if (sbpro_type!=1)
4329         {
4330           MIXER_addr=SOUND_BASE+0x04; /* sound card's address register */
4331           MIXER_data=SOUND_BASE+0x05; /* sound card's data register */
4332         }
4333       OUT(MIXER_addr,MIXER_CD_Volume); /* select SB Pro mixer register */
4334       OUT(MIXER_data,0xCC); /* one nibble per channel, max. value: 0xFF */
4335     }
4336 
4337   if (register_blkdev(MAJOR_NR, major_name, &sbpcd_fops) != 0)
4338     {
4339       printk("SBPCD: Can't get MAJOR %d for Matsushita CDROM\n", MAJOR_NR);
4340 #if PRINTK_BUG
4341       sti(); /* to avoid possible "printk" bug */
4342 #endif
4343 #ifdef MODULE
4344       return -EIO;
4345 #else
4346       goto init_done;
4347 #endif MODULE
4348     }
4349   blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
4350   read_ahead[MAJOR_NR] = SBP_BUFFER_FRAMES * (CD_FRAMESIZE / 512);
4351   
4352   request_region(CDo_command,4,major_name);
4353 
4354   for (j=0;j<NR_SBPCD;j++)
4355     {
4356       if (DriveStruct[j].drv_id==-1) continue;
4357       switch_drive(j);
4358 /*
4359  * allocate memory for the frame buffers
4360  */
4361 #ifdef MODULE
4362       DriveStruct[j].sbp_buf=(u_char *) kmalloc(SBP_BUFFER_FRAMES*CD_FRAMESIZE, GFP_KERNEL);
4363       DriveStruct[j].aud_buf=NULL;
4364 #else
4365       DriveStruct[j].sbp_buf=(u_char *)mem_start;
4366       mem_start += SBP_BUFFER_FRAMES*CD_FRAMESIZE;
4367       if ((fam1_drive) && (SBP_BUFFER_AUDIO_FRAMES>0))
4368         {
4369           DriveStruct[j].aud_buf=(u_char *)mem_start;
4370           mem_start += SBP_BUFFER_AUDIO_FRAMES*CD_FRAMESIZE_RAW;
4371         }
4372       else DriveStruct[j].aud_buf=NULL;
4373 #endif MODULE
4374 /*
4375  * set the block size
4376  */
4377       sbpcd_blocksizes[j]=CD_FRAMESIZE;
4378     }
4379   blksize_size[MAJOR_NR]=sbpcd_blocksizes;
4380 
4381 #ifdef MODULE
4382 return (0);
4383 #else
4384 init_done:
4385 #if !(SBPCD_ISSUE-1)
4386 #ifdef CONFIG_SBPCD2
4387   mem_start=sbpcd2_init(mem_start, mem_end);
4388 #endif
4389 #ifdef CONFIG_SBPCD3
4390   mem_start=sbpcd3_init(mem_start, mem_end);
4391 #endif
4392 #ifdef CONFIG_SBPCD4
4393   mem_start=sbpcd4_init(mem_start, mem_end);
4394 #endif
4395 #endif
4396 #if !(SBPCD_ISSUE-1)
4397   DPRINTF((DBG_INF,"SBPCD: init done.\n"));
4398 #endif
4399   return (mem_start);
4400 #endif MODULE
4401 }
4402 /*==========================================================================*/
4403 #ifdef MODULE
4404 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
4405 {
4406   int j;
4407 
4408   if (MOD_IN_USE)
4409     {
4410       printk("%s module in use - can't remove it.\n", major_name);
4411       return;
4412     }
4413   if ((unregister_blkdev(MAJOR_NR, major_name) == -EINVAL))
4414     {
4415       printk("What's that: can't unregister %s\n", major_name);
4416       return;
4417     }
4418   release_region(CDo_command,4);
4419 
4420   for (j=0;j<NR_SBPCD;j++)
4421     {
4422       if (DriveStruct[j].drv_id==-1) continue;
4423       kfree_s(DriveStruct[j].sbp_buf, SBP_BUFFER_FRAMES*CD_FRAMESIZE);
4424     }
4425   printk("%s module released.\n", major_name);
4426 }
4427 #endif MODULE
4428 /*==========================================================================*/
4429 /*
4430  * Check if the media has changed in the CD-ROM drive.
4431  * used externally (isofs/inode.c, fs/buffer.c)
4432  * Currently disabled (has to get "synchronized").
4433  */
4434 static int sbpcd_chk_disk_change(dev_t full_dev)
     /* [previous][next][first][last][top][bottom][index][help] */
4435 {
4436   int i, st;
4437 
4438   DPRINTF((DBG_CHK,"SBPCD: media_check (%d) called\n", MINOR(full_dev)));
4439   return (0); /* "busy" test necessary before we really can check */
4440 
4441   i=MINOR(full_dev);
4442   if ( (i<0) || (i>=NR_SBPCD) || (DriveStruct[i].drv_id==-1) )
4443     {
4444       printk("SBPCD: media_check: invalid device %04X.\n", full_dev);
4445       return (-1);
4446     }
4447 
4448   switch_drive(i);
4449   
4450   xx_ReadStatus();                         /* command: give 1-byte status */
4451   st=ResponseStatus();
4452   DPRINTF((DBG_CHK,"SBPCD: media_check: %02X\n",DriveStruct[d].status_byte));
4453   if (st<0)
4454     {
4455       DPRINTF((DBG_INF,"SBPCD: media_check: ResponseStatus error.\n"));
4456       return (1); /* status not obtainable */
4457     }
4458   if (DriveStruct[d].CD_changed==0xFF) DPRINTF((DBG_CHK,"SBPCD: media_check: \"changed\" assumed.\n"));
4459   if (!st_spinning) DPRINTF((DBG_CHK,"SBPCD: media_check: motor off.\n"));
4460   if (!st_door_closed)
4461     {
4462       DPRINTF((DBG_CHK,"SBPCD: media_check: door open.\n"));
4463       DriveStruct[d].CD_changed=0xFF;
4464     }
4465   if (!st_caddy_in)
4466     {
4467       DPRINTF((DBG_CHK,"SBPCD: media_check: no disk in drive.\n"));
4468       DriveStruct[d].CD_changed=0xFF;
4469     }
4470   if (!st_diskok) DPRINTF((DBG_CHK,"SBPCD: media_check: !st_diskok.\n"));
4471   
4472 #if 0000
4473   if (DriveStruct[d].CD_changed==0xFF)
4474     {
4475       DriveStruct[d].CD_changed=1;
4476       return (1); /* driver had a change detected before */
4477     }
4478 #endif 0000 /* seems to give additional errors at the moment */
4479 
4480   if (!st_diskok) return (1); /* disk not o.k. */
4481   if (!st_caddy_in) return (1); /* disk removed */
4482   if (!st_door_closed) return (1); /* door open */
4483   return (0);
4484 }
4485 /*==========================================================================*/

/* [previous][next][first][last][top][bottom][index][help] */