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_drive
  55. find_teac_drives
  56. check_version
  57. switch_drive
  58. check_drives
  59. timewait
  60. obey_audio_state
  61. check_allowed1
  62. check_allowed2
  63. check_allowed3
  64. seek_pos_audio_end
  65. ReadToC
  66. DiskInfo
  67. prepare
  68. xx_PlayAudio
  69. sbp_status
  70. sbpcd_ioctl
  71. sbp_transfer
  72. DO_SBPCD_REQUEST
  73. sbp_read_cmd
  74. sbp_data
  75. sbpcd_open
  76. sbpcd_release
  77. sbpcd_setup
  78. config_spea
  79. SBPCD_INIT
  80. check_media_change

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

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