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

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