root/drivers/block/sbpcd.c

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

DEFINITIONS

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

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

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