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

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