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

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