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

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