root/drivers/block/sbpcd.c

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

DEFINITIONS

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

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