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

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