root/drivers/block/aztcd.c

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

DEFINITIONS

This source file includes following definitions.
  1. op_ok
  2. pa_ok
  3. sten_low
  4. dten_low
  5. statusAzt
  6. aztStatTimer
  7. aztcd_setup
  8. aztCloseDoor
  9. aztLockDoor
  10. aztUnlockDoor
  11. aztSendCmd
  12. sendAztCmd
  13. check_aztcd_media_change
  14. aztStatus
  15. getAztStatus
  16. aztPlay
  17. azt_msf2hsg
  18. aztcd_ioctl
  19. azt_transfer
  20. do_aztcd_request
  21. azt_poll
  22. azt_invalidate_buffers
  23. aztcd_open
  24. aztcd_release
  25. aztcd_init
  26. azt_hsg2msf
  27. azt_bin2bcd
  28. azt_bcd2bin
  29. aztGetValue
  30. aztGetQChannelInfo
  31. aztUpdateToc
  32. aztGetDiskInfo
  33. aztGetToc
  34. cleanup_module

   1 #define AZT_VERSION "V1.0"
   2 /*      $Id: aztcd.c,v 1.0 1995/03/25 08:27:11 root Exp $
   3         linux/drivers/block/aztcd.c - AztechCD268 CDROM driver
   4 
   5         Copyright (C) 1994,1995 Werner Zimmermann (zimmerma@rz.fht-esslingen.de)
   6 
   7         based on Mitsumi CDROM driver by  Martin Hariss and preworks by
   8         Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby 
   9         Schirmer.
  10 
  11         This program is free software; you can redistribute it and/or modify
  12         it under the terms of the GNU General Public License as published by
  13         the Free Software Foundation; either version 2, or (at your option)
  14         any later version.
  15 
  16         This program is distributed in the hope that it will be useful,
  17         but WITHOUT ANY WARRANTY; without even the implied warranty of
  18         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19         GNU General Public License for more details.
  20 
  21         You should have received a copy of the GNU General Public License
  22         along with this program; if not, write to the Free Software
  23         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24 
  25         HISTORY
  26         V0.0    Adaption to Adaptec CD268-01A Version 1.3
  27                 Version is PRE_ALPHA, unresolved points:
  28                 1. I use busy wait instead of timer wait in STEN_LOW,DTEN_LOW
  29                    thus driver causes CPU overhead and is very slow 
  30                 2. could not find a way to stop the drive, when it is
  31                    in data read mode, therefore I had to set
  32                    msf.end.min/sec/frame to 0:0:1 (in azt_poll); so only one
  33                    frame can be read in sequence, this is also the reason for
  34                 3. getting 'timeout in state 4' messages, but nevertheless
  35                    it works
  36                 W.Zimmermann, Oct. 31, 1994
  37         V0.1    Version is ALPHA, problems #2 and #3 resolved.  
  38                 W.Zimmermann, Nov. 3, 1994
  39         V0.2    Modification to some comments, debugging aids for partial test
  40                 with Borland C under DOS eliminated. Timer interrupt wait 
  41                 STEN_LOW_WAIT additionally to busy wait for STEN_LOW implemented; 
  42                 use it only for the 'slow' commands (ACMD_GET_Q_CHANNEL, ACMD_
  43                 SEEK_TO_LEAD_IN), all other commands are so 'fast', that busy 
  44                 waiting seems better to me than interrupt rescheduling.
  45                 Besides that, when used in the wrong place, STEN_LOW_WAIT causes
  46                 kernel panic.
  47                 In function aztPlay command ACMD_PLAY_AUDIO added, should make
  48                 audio functions work. The Aztech drive needs different commands
  49                 to read data tracks and play audio tracks.
  50                 W.Zimmermann, Nov. 8, 1994
  51         V0.3    Recognition of missing drive during boot up improved (speeded up).
  52                 W.Zimmermann, Nov. 13, 1994
  53         V0.35   Rewrote the control mechanism in azt_poll (formerly mcd_poll) 
  54                 including removal of all 'goto' commands. :-); 
  55                 J. Nardone, Nov. 14, 1994
  56         V0.4    Renamed variables and constants to 'azt' instead of 'mcd'; had
  57                 to make some "compatibility" defines in azt.h; please note,
  58                 that the source file was renamed to azt.c, the include file to
  59                 azt.h                
  60                 Speeded up drive recognition during init (will be a little bit 
  61                 slower than before if no drive is installed!); suggested by
  62                 Robby Schirmer.
  63                 read_count declared volatile and set to AZT_BUF_SIZ to make
  64                 drive faster (now 300kB/sec, was 60kB/sec before, measured
  65                 by 'time dd if=/dev/cdrom of=/dev/null bs=2048 count=4096';
  66                 different AZT_BUF_SIZes were test, above 16 no further im-
  67                 provement seems to be possible; suggested by E.Moenkeberg.
  68                 W.Zimmermann, Nov. 18, 1994
  69         V0.42   Included getAztStatus command in GetQChannelInfo() to allow
  70                 reading Q-channel info on audio disks, if drive is stopped, 
  71                 and some other bug fixes in the audio stuff, suggested by 
  72                 Robby Schirmer.
  73                 Added more ioctls (reading data in mode 1 and mode 2).
  74                 Completely removed the old azt_poll() routine.
  75                 Detection of ORCHID CDS-3110 in aztcd_init implemented.
  76                 Additional debugging aids (see the readme file).
  77                 W.Zimmermann, Dec. 9, 1994  
  78         V0.50   Autodetection of drives implemented.
  79                 W.Zimmermann, Dec. 12, 1994
  80         V0.52   Prepared for including in the standard kernel, renamed most
  81                 variables to contain 'azt', included autoconf.h
  82                 W.Zimmermann, Dec. 16, 1994        
  83         V0.6    Version for being included in the standard Linux kernel.
  84                 Renamed source and header file to aztcd.c and aztcd.h
  85                 W.Zimmermann, Dec. 24, 1994
  86         V0.7    Changed VERIFY_READ to VERIFY_WRITE in aztcd_ioctl, case
  87                 CDROMREADMODE1 and CDROMREADMODE2; bug fix in the ioctl,
  88                 which causes kernel crashes when playing audio, changed 
  89                 include-files (config.h instead of autoconf.h, removed
  90                 delay.h)
  91                 W.Zimmermann, Jan. 8, 1995
  92         V0.72   Some more modifications for adaption to the standard kernel.
  93                 W.Zimmermann, Jan. 16, 1995
  94         V0.80   aztcd is now part of the standard kernel since version 1.1.83.
  95                 Modified the SET_TIMER and CLEAR_TIMER macros to comply with
  96                 the new timer scheme.
  97                 W.Zimmermann, Jan. 21, 1995
  98         V0.90   Included CDROMVOLCTRL, but with my Aztech drive I can only turn
  99                 the channels on and off. If it works better with your drive, 
 100                 please mail me. Also implemented ACMD_CLOSE for CDROMSTART.
 101                 W.Zimmermann, Jan. 24, 1995
 102         V1.00   Implemented close and lock tray commands. Patches supplied by
 103                 Frank Racis        
 104                 Added support for loadable MODULEs, so aztcd can now also be
 105                 loaded by insmod and removed by rmmod during run time
 106                 Werner Zimmermann, Mar. 24, 95
 107         NOTE: 
 108         Points marked with ??? are questionable !
 109 */
 110 #include <linux/major.h>
 111 #include <linux/config.h>
 112 
 113 #ifdef MODULE
 114 # include <linux/module.h>
 115 # include <linux/version.h>
 116 # ifndef CONFIG_MODVERSIONS
 117     char kernel_version[]= UTS_RELEASE;
 118 # endif
 119 #endif
 120 
 121 #include <linux/errno.h>
 122 #include <linux/sched.h>
 123 #include <linux/mm.h>
 124 #include <linux/timer.h>
 125 #include <linux/fs.h>
 126 #include <linux/kernel.h>
 127 #include <linux/cdrom.h>
 128 #include <linux/ioport.h>
 129 #include <linux/string.h>
 130 
 131 #include <asm/system.h>
 132 #include <asm/io.h>
 133 #include <asm/segment.h>
 134 
 135 #define MAJOR_NR AZTECH_CDROM_MAJOR 
 136 
 137 #ifdef MODULE
 138 # include "/usr/src/linux/drivers/block/blk.h"
 139 #else
 140 # include "blk.h"
 141 # define MOD_INC_USE_COUNT
 142 # define MOD_DEC_USE_COUNT
 143 #endif
 144 
 145 #include <linux/aztcd.h>
 146 
 147 static int aztPresent = 0;
 148 
 149 #if 0
 150 #define AZT_TEST1 /* <int-..> */
 151 #define AZT_TEST2 /* do_aztcd_request */
 152 #define AZT_TEST3 /* AZT_S_state */
 153 #define AZT_TEST4 /* QUICK_LOOP-counter */
 154 #define AZT_TEST5 /* port(1) state */
 155 #define AZT_DEBUG
 156 #endif
 157 
 158 #define CURRENT_VALID \
 159   (CURRENT && MAJOR(CURRENT -> dev) == MAJOR_NR && CURRENT -> cmd == READ \
 160    && CURRENT -> sector != -1)
 161 
 162 #define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
 163 #define AZT_BUF_SIZ 16
 164 
 165 static volatile int azt_transfer_is_active=0;
 166 
 167 static char azt_buf[2048*AZT_BUF_SIZ];  /*buffer for block size conversion*/
 168 #ifdef AZT_PRIVATE_IOCTLS
 169 static char buf[2336];                  /*separate buffer for the ioctls*/
 170 #endif
 171 
 172 static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
 173 static volatile int azt_buf_in, azt_buf_out = -1;
 174 static volatile int azt_error=0;
 175 static int azt_open_count=0;
 176 enum azt_state_e {
 177   AZT_S_IDLE,    /* 0 */
 178   AZT_S_START,   /* 1 */
 179   AZT_S_MODE,    /* 2 */
 180   AZT_S_READ,    /* 3 */
 181   AZT_S_DATA,    /* 4 */
 182   AZT_S_STOP,    /* 5 */
 183   AZT_S_STOPPING /* 6 */
 184 };
 185 static volatile enum azt_state_e azt_state = AZT_S_IDLE;
 186 #ifdef AZT_TEST3
 187 static volatile enum azt_state_e azt_state_old = AZT_S_STOP;  
 188 static volatile int azt_st_old = 0;
 189 #endif
 190 
 191 static int azt_mode = -1;
 192 static int ACMD_DATA_READ= ACMD_PLAY_READ;
 193 static volatile int azt_read_count = 1;
 194 
 195 #define READ_TIMEOUT 3000
 196 
 197 #define azt_port aztcd  /*needed for the modutils*/
 198 static short azt_port = AZT_BASE_ADDR;
 199 
 200 static char  azt_cont = 0;
 201 static char  azt_init_end = 0;
 202 
 203 static int AztTimeout, AztTries;
 204 static struct wait_queue *azt_waitq = NULL; 
 205 static struct timer_list delay_timer = { NULL, NULL, 0, 0, NULL };
 206 
 207 static struct azt_DiskInfo DiskInfo;
 208 static struct azt_Toc Toc[MAX_TRACKS];
 209 static struct azt_Play_msf azt_Play;
 210 
 211 static int  aztAudioStatus = CDROM_AUDIO_NO_STATUS;
 212 static char aztDiskChanged = 1;
 213 static char aztTocUpToDate = 0;
 214 
 215 
 216 static void azt_transfer(void);
 217 static void azt_poll(void);
 218 static void azt_invalidate_buffers(void);
 219 static void do_aztcd_request(void);
 220 static void azt_hsg2msf(long hsg, struct msf *msf);
 221 static void azt_bin2bcd(unsigned char *p);
 222 static int  azt_bcd2bin(unsigned char bcd);
 223 static int  aztStatus(void);
 224 static int  getAztStatus(void);
 225 static int  aztSendCmd(int cmd);
 226 static int  sendAztCmd(int cmd, struct azt_Play_msf *params);
 227 static int  aztGetQChannelInfo(struct azt_Toc *qp);
 228 static int  aztUpdateToc(void);
 229 static int  aztGetDiskInfo(void);
 230 static int  aztGetToc(void);
 231 static int  aztGetValue(unsigned char *result);
 232 static void aztStatTimer(void);
 233 static void aztCloseDoor(void);
 234 static void aztLockDoor(void);
 235 static void aztUnlockDoor(void);
 236 
 237 static unsigned char aztIndatum;
 238 static unsigned long aztTimeOutCount;
 239 
 240 /* Macros for the drive hardware interface handshake, these macros use
 241    busy waiting */
 242 /* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
 243 # define OP_OK op_ok()
 244 void op_ok(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 245 { aztTimeOutCount=0; 
 246   do { aztIndatum=inb(DATA_PORT);
 247        aztTimeOutCount++;
 248        if (aztTimeOutCount>=AZT_TIMEOUT)
 249         { printk("aztcd: Error Wait OP_OK\n");
 250           break;
 251         }
 252      } while (aztIndatum!=AFL_OP_OK);
 253 }
 254 
 255 /* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
 256 # define PA_OK pa_ok()
 257 void pa_ok(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 258 { aztTimeOutCount=0; 
 259   do { aztIndatum=inb(DATA_PORT);
 260        aztTimeOutCount++;
 261        if (aztTimeOutCount>=AZT_TIMEOUT)
 262         { printk("aztcd: Error Wait PA_OK\n");
 263           break;
 264         }
 265      } while (aztIndatum!=AFL_PA_OK);
 266 }
 267      
 268 /* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
 269 # define STEN_LOW  sten_low()
 270 void sten_low(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 271 { aztTimeOutCount=0; 
 272   do { aztIndatum=inb(STATUS_PORT);
 273        aztTimeOutCount++;
 274        if (aztTimeOutCount>=AZT_TIMEOUT)
 275         { if (azt_init_end) printk("aztcd: Error Wait STEN_LOW\n");
 276           break;
 277         }
 278      } while (aztIndatum&AFL_STATUS);
 279 }
 280 
 281 /* Wait for DTEN=Low = handshake signal 'Data available'*/
 282 # define DTEN_LOW dten_low()
 283 void dten_low(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 284 { aztTimeOutCount=0; 
 285   do { aztIndatum=inb(STATUS_PORT);
 286        aztTimeOutCount++;
 287        if (aztTimeOutCount>=AZT_TIMEOUT)
 288         { printk("aztcd: Error Wait DTEN_OK\n");
 289           break;
 290         }
 291      } while (aztIndatum&AFL_DATA);
 292 }
 293 
 294 /* 
 295  * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
 296  * may cause kernel panic when used in the wrong place
 297 */
 298 #define STEN_LOW_WAIT   statusAzt()
 299 void statusAzt(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 300 { AztTimeout = AZT_STATUS_DELAY;
 301   SET_TIMER(aztStatTimer, 1); 
 302   sleep_on(&azt_waitq);    
 303   if (AztTimeout <= 0) printk("aztcd: Error Wait STEN_LOW_WAIT\n");
 304   return;
 305 }
 306 
 307 static void aztStatTimer(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 308 {       if (!(inb(STATUS_PORT) & AFL_STATUS))
 309         {       wake_up(&azt_waitq);
 310                 return;
 311         }
 312         AztTimeout--;
 313         if (AztTimeout <= 0)
 314         {       wake_up(&azt_waitq);
 315                 return;
 316         }
 317         SET_TIMER(aztStatTimer, 1);
 318 }
 319 
 320 
 321 void aztcd_setup(char *str, int *ints)
     /* [previous][next][first][last][top][bottom][index][help] */
 322 {  if (ints[0] > 0)
 323       azt_port = ints[1];
 324    if (ints[0] > 1)
 325       azt_cont = ints[2];
 326 }
 327 
 328 /*
 329  * Subroutines to automatically close the door (tray) and 
 330  * lock it closed when the cd is mounted.  Leave the tray
 331  * locking as an option
 332  */
 333 static void aztCloseDoor(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 334 {
 335   aztSendCmd(ACMD_CLOSE);
 336   STEN_LOW;
 337   return;
 338 }
 339 
 340 static void aztLockDoor(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 341 {
 342 #ifdef AZT_ALLOW_TRAY_LOCK
 343   aztSendCmd(ACMD_LOCK);
 344   STEN_LOW;
 345 #endif
 346   return;
 347 }
 348 
 349 static void aztUnlockDoor(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 350 {
 351 #ifdef AZT_ALLOW_TRAY_LOCK
 352   aztSendCmd(ACMD_UNLOCK);
 353   STEN_LOW;
 354 #endif
 355   return;
 356 }
 357 
 358 /* 
 359  * Send a single command, return -1 on error, else 0
 360 */
 361 static int aztSendCmd(int cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
 362 {  unsigned char data;
 363    int retry;
 364 
 365 #ifdef AZT_DEBUG
 366    printk("aztcd: Executing command %x\n",cmd);
 367 #endif
 368    outb(POLLED,MODE_PORT);
 369    do { if (inb(STATUS_PORT)&AFL_STATUS) break;
 370         inb(DATA_PORT);    /* if status left from last command, read and */
 371       } while (1);         /* discard it */
 372    do { if (inb(STATUS_PORT)&AFL_DATA) break;
 373         inb(DATA_PORT);    /* if data left from last command, read and */
 374       } while (1);         /* discard it */
 375    for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
 376      { outb((unsigned char) cmd,CMD_PORT);
 377        STEN_LOW;
 378        data=inb(DATA_PORT);
 379        if (data==AFL_OP_OK)
 380          { return 0;}           /*OP_OK?*/
 381        if (data==AFL_OP_ERR)
 382          { STEN_LOW;
 383            data=inb(DATA_PORT);
 384            printk("### Error 1 aztcd: aztSendCmd %x  Error Code %x\n",cmd,data);
 385          }
 386      }
 387    if (retry>=AZT_RETRY_ATTEMPTS)
 388      { printk("### Error 2 aztcd: aztSendCmd %x \n",cmd);
 389        azt_error=0xA5;
 390      }
 391    return -1;
 392 }
 393 
 394 /*
 395  * Send a play or read command to the drive, return -1 on error, else 0
 396 */
 397 static int sendAztCmd(int cmd, struct azt_Play_msf *params)
     /* [previous][next][first][last][top][bottom][index][help] */
 398 {  unsigned char data;
 399    int retry;
 400 
 401 #ifdef AZT_DEBUG
 402    printk("start=%02x:%02x:%02x  end=%02x:%02x:%02x\n", \
 403            params->start.min, params->start.sec, params->start.frame, \
 404            params->end.min,   params->end.sec,   params->end.frame);
 405 #endif   
 406    for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
 407      { aztSendCmd(cmd);
 408        outb(params -> start.min,CMD_PORT);
 409        outb(params -> start.sec,CMD_PORT);
 410        outb(params -> start.frame,CMD_PORT);
 411        outb(params -> end.min,CMD_PORT);
 412        outb(params -> end.sec,CMD_PORT);
 413        outb(params -> end.frame,CMD_PORT);
 414        STEN_LOW;
 415        data=inb(DATA_PORT);
 416        if (data==AFL_PA_OK)
 417          { return 0;}           /*PA_OK ?*/
 418        if (data==AFL_PA_ERR)
 419          { STEN_LOW;
 420            data=inb(DATA_PORT);
 421            printk("### Error 1 aztcd: sendAztCmd %x  Error Code %x\n",cmd,data);
 422          }
 423      }
 424    if (retry>=AZT_RETRY_ATTEMPTS)
 425      { printk("### Error 2 aztcd: sendAztCmd %x\n ",cmd);
 426        azt_error=0xA5;
 427      }
 428    return -1;
 429 }
 430 
 431 
 432 /* 
 433  * Checking if the media has been changed not yet implemented
 434 */
 435 static int check_aztcd_media_change(dev_t full_dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 436 { return 0;
 437 }
 438 
 439 
 440 /* used in azt_poll to poll the status, expects another program to issue a 
 441  * ACMD_GET_STATUS directly before 
 442  */
 443 static int aztStatus(void)  
     /* [previous][next][first][last][top][bottom][index][help] */
 444 {       int st;
 445         int i;
 446 
 447         i = inb(STATUS_PORT) & AFL_STATUS;   /* is STEN=0?    ???*/
 448         if (!i)
 449         {
 450                 st = inb(DATA_PORT) & 0xFF;
 451                 return st;
 452         }
 453         else
 454                 return -1;
 455 }
 456 
 457 /*
 458  * Get the drive status
 459  */
 460 static int getAztStatus(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 461 {       int st;
 462 
 463         if (aztSendCmd(ACMD_GET_STATUS)) return -1;
 464         STEN_LOW;
 465         st = inb(DATA_PORT) & 0xFF;
 466 #ifdef AZT_DEBUG
 467         printk("aztcd: Status = %x\n",st);
 468 #endif
 469         if ((st == 0xFF)||(st&AST_CMD_CHECK))
 470          { printk("aztcd: AST_CMD_CHECK error or no status available\n");
 471            return -1;
 472          }
 473 
 474         if (((st&AST_MODE_BITS)!=AST_BUSY) && (aztAudioStatus == CDROM_AUDIO_PLAY))
 475                 /* XXX might be an error? look at q-channel? */
 476                 aztAudioStatus = CDROM_AUDIO_COMPLETED;
 477 
 478         if (st & AST_DSK_CHG)
 479         {
 480                 aztDiskChanged = 1;
 481                 aztTocUpToDate = 0;
 482                 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
 483         }
 484         return st;
 485 }
 486 
 487 
 488 /*
 489  * Send a 'Play' command and get the status.  Use only from the top half.
 490  */
 491 static int aztPlay(struct azt_Play_msf *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 492 {       if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0) return -1;
 493         return 0;
 494 }
 495 
 496 
 497 long azt_msf2hsg(struct msf *mp)
     /* [previous][next][first][last][top][bottom][index][help] */
 498 {
 499 #ifdef AZT_DEBUG
 500         if (mp->min  >=70) printk("aztcd: Error msf2hsg address Minutes\n");
 501         if (mp->sec  >=60) printk("aztcd: Error msf2hsg address Seconds\n");
 502         if (mp->frame>=75) printk("aztcd: Error msf2hsg address Frames\n");
 503 #endif
 504         return azt_bcd2bin(mp -> frame)
 505                 + azt_bcd2bin(mp -> sec) * 75
 506                 + azt_bcd2bin(mp -> min) * 4500
 507                 - 150;
 508 }
 509 
 510 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 511 {       int i, st;
 512         struct azt_Toc qInfo;
 513         struct cdrom_ti ti;
 514         struct cdrom_tochdr tocHdr;
 515         struct cdrom_msf msf;
 516         struct cdrom_tocentry entry;
 517         struct azt_Toc *tocPtr;            
 518         struct cdrom_subchnl subchnl;
 519         struct cdrom_volctrl volctrl;
 520 
 521 #ifdef AZT_DEBUG
 522         printk("aztcd: starting aztcd_ioctl - Command:%x\n",cmd);
 523 #endif
 524         if (!ip) return -EINVAL;
 525         if (getAztStatus()<0) return -EIO;
 526         if (!aztTocUpToDate)
 527         { if ((i=aztUpdateToc())<0) return i; /* error reading TOC */
 528         }
 529 
 530         switch (cmd)
 531         {
 532         case CDROMSTART:     /* Spin up the drive. Don't know, what to do,
 533                                 at least close the tray */
 534 #ifdef AZT_PRIVATE_IOCTLS 
 535                 if (aztSendCmd(ACMD_CLOSE)) return -1;
 536                 STEN_LOW_WAIT;
 537 #endif
 538                 break;
 539         case CDROMSTOP:      /* Spin down the drive */
 540                 if (aztSendCmd(ACMD_STOP)) return -1;
 541                 STEN_LOW_WAIT;
 542                 /* should we do anything if it fails? */
 543                 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
 544                 break;
 545         case CDROMPAUSE:     /* Pause the drive */
 546                 if (aztAudioStatus != CDROM_AUDIO_PLAY) return -EINVAL; 
 547 
 548                 if (aztGetQChannelInfo(&qInfo) < 0)
 549                 { /* didn't get q channel info */
 550                   aztAudioStatus = CDROM_AUDIO_NO_STATUS;
 551                   return 0;
 552                 }
 553                 azt_Play.start = qInfo.diskTime;        /* remember restart point */
 554                 if (aztSendCmd(ACMD_PAUSE)) return -1;
 555                 STEN_LOW_WAIT;
 556                 aztAudioStatus = CDROM_AUDIO_PAUSED;
 557                 break;
 558         case CDROMRESUME:    /* Play it again, Sam */
 559                 if (aztAudioStatus != CDROM_AUDIO_PAUSED) return -EINVAL;
 560                 /* restart the drive at the saved position. */
 561                 i = aztPlay(&azt_Play);
 562                 if (i < 0)
 563                 { aztAudioStatus = CDROM_AUDIO_ERROR;
 564                   return -EIO;
 565                 }
 566                 aztAudioStatus = CDROM_AUDIO_PLAY;
 567                 break;
 568         case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
 569                 st = verify_area(VERIFY_READ, (void *) arg, sizeof ti);
 570                 if (st) return st;
 571                 memcpy_fromfs(&ti, (void *) arg, sizeof ti);
 572                 if (ti.cdti_trk0 < DiskInfo.first
 573                         || ti.cdti_trk0 > DiskInfo.last
 574                         || ti.cdti_trk1 < ti.cdti_trk0)
 575                 { return -EINVAL;
 576                 }
 577                 if (ti.cdti_trk1 > DiskInfo.last)
 578                    ti. cdti_trk1 = DiskInfo.last;
 579                 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
 580                 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
 581 #ifdef AZT_DEBUG
 582 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
 583         azt_Play.start.min, azt_Play.start.sec, azt_Play.start.frame,
 584         azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
 585 #endif
 586                 i = aztPlay(&azt_Play);
 587                 if (i < 0)
 588                 { aztAudioStatus = CDROM_AUDIO_ERROR;
 589                   return -EIO;
 590                 }
 591                 aztAudioStatus = CDROM_AUDIO_PLAY;
 592                 break;
 593         case CDROMPLAYMSF:   /* Play starting at the given MSF address. */
 594 /*              if (aztAudioStatus == CDROM_AUDIO_PLAY) 
 595                 { if (aztSendCmd(ACMD_STOP)) return -1;
 596                   STEN_LOW;
 597                   aztAudioStatus = CDROM_AUDIO_NO_STATUS;
 598                 }
 599 */
 600                 st = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
 601                 if (st) return st;
 602                 memcpy_fromfs(&msf, (void *) arg, sizeof msf);
 603                 /* convert to bcd */
 604                 azt_bin2bcd(&msf.cdmsf_min0);
 605                 azt_bin2bcd(&msf.cdmsf_sec0);
 606                 azt_bin2bcd(&msf.cdmsf_frame0);
 607                 azt_bin2bcd(&msf.cdmsf_min1);
 608                 azt_bin2bcd(&msf.cdmsf_sec1);
 609                 azt_bin2bcd(&msf.cdmsf_frame1);
 610                 azt_Play.start.min = msf.cdmsf_min0;
 611                 azt_Play.start.sec = msf.cdmsf_sec0;
 612                 azt_Play.start.frame = msf.cdmsf_frame0;
 613                 azt_Play.end.min = msf.cdmsf_min1;
 614                 azt_Play.end.sec = msf.cdmsf_sec1;
 615                 azt_Play.end.frame = msf.cdmsf_frame1;
 616 #ifdef AZT_DEBUG
 617 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
 618 azt_Play.start.min, azt_Play.start.sec, azt_Play.start.frame,
 619 azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
 620 #endif
 621                 i = aztPlay(&azt_Play);
 622                 if (i < 0)
 623                 { aztAudioStatus = CDROM_AUDIO_ERROR;
 624                   return -EIO;
 625                 }
 626                 aztAudioStatus = CDROM_AUDIO_PLAY;
 627                 break;
 628 
 629         case CDROMREADTOCHDR:        /* Read the table of contents header */
 630                 st = verify_area(VERIFY_WRITE, (void *) arg, sizeof tocHdr);
 631                 if (st) return st;
 632                 tocHdr.cdth_trk0 = DiskInfo.first;
 633                 tocHdr.cdth_trk1 = DiskInfo.last;
 634                 memcpy_tofs((void *) arg, &tocHdr, sizeof tocHdr);
 635                 break;
 636         case CDROMREADTOCENTRY:      /* Read an entry in the table of contents */
 637                 st = verify_area(VERIFY_READ, (void *) arg, sizeof entry);
 638                 if (st) return st;
 639                 st = verify_area(VERIFY_WRITE, (void *) arg, sizeof entry);
 640                 if (st) return st;
 641                 memcpy_fromfs(&entry, (void *) arg, sizeof entry);
 642                 if (!aztTocUpToDate) aztGetDiskInfo();
 643                 if (entry.cdte_track == CDROM_LEADOUT)
 644                   tocPtr = &Toc[DiskInfo.last + 1];   /* ??? */
 645                 else if (entry.cdte_track > DiskInfo.last
 646                                 || entry.cdte_track < DiskInfo.first)
 647                 { return -EINVAL;
 648                 }
 649                 else 
 650                   tocPtr = &Toc[entry.cdte_track];
 651                 entry.cdte_adr = tocPtr -> ctrl_addr;
 652                 entry.cdte_ctrl = tocPtr -> ctrl_addr >> 4;
 653                 if (entry.cdte_format == CDROM_LBA)
 654                   entry.cdte_addr.lba = azt_msf2hsg(&tocPtr -> diskTime);
 655                 else if (entry.cdte_format == CDROM_MSF)
 656                 { entry.cdte_addr.msf.minute = azt_bcd2bin(tocPtr -> diskTime.min);
 657                   entry.cdte_addr.msf.second = azt_bcd2bin(tocPtr -> diskTime.sec);
 658                   entry.cdte_addr.msf.frame  = azt_bcd2bin(tocPtr -> diskTime.frame);
 659                 }
 660                 else
 661                 { return -EINVAL;
 662                 }
 663                 memcpy_tofs((void *) arg, &entry, sizeof entry);
 664                 break;
 665         case CDROMSUBCHNL:   /* Get subchannel info */
 666                 st = verify_area(VERIFY_READ, (void *) arg, sizeof subchnl);
 667                 if (st) return st;
 668                 st = verify_area(VERIFY_WRITE, (void *) arg, sizeof subchnl);
 669                 if (st) return st;
 670                 memcpy_fromfs(&subchnl, (void *) arg, sizeof subchnl);
 671                 if (aztGetQChannelInfo(&qInfo) < 0)
 672                   return -EIO;
 673                 subchnl.cdsc_audiostatus = aztAudioStatus;
 674                 subchnl.cdsc_adr = qInfo.ctrl_addr;
 675                 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
 676                 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
 677                 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
 678                 if (subchnl.cdsc_format == CDROM_LBA)
 679                 { subchnl.cdsc_absaddr.lba = azt_msf2hsg(&qInfo.diskTime);
 680                   subchnl.cdsc_reladdr.lba = azt_msf2hsg(&qInfo.trackTime);
 681                 }
 682                 else if (subchnl.cdsc_format == CDROM_MSF)
 683                 { subchnl.cdsc_absaddr.msf.minute = azt_bcd2bin(qInfo.diskTime.min);
 684                   subchnl.cdsc_absaddr.msf.second = azt_bcd2bin(qInfo.diskTime.sec);
 685                   subchnl.cdsc_absaddr.msf.frame = azt_bcd2bin(qInfo.diskTime.frame);
 686                   subchnl.cdsc_reladdr.msf.minute = azt_bcd2bin(qInfo.trackTime.min);
 687                   subchnl.cdsc_reladdr.msf.second = azt_bcd2bin(qInfo.trackTime.sec);
 688                   subchnl.cdsc_reladdr.msf.frame  = azt_bcd2bin(qInfo.trackTime.frame);
 689                 }
 690                 else
 691                   return -EINVAL;
 692                 memcpy_tofs((void *) arg, &subchnl, sizeof subchnl);
 693                 break;
 694         case CDROMVOLCTRL:   /* Volume control 
 695          * With my Aztech CD268-01A volume control does not work, I can only
 696            turn the channels on (any value !=0) or off (value==0). Maybe it
 697            works better with your drive */
 698                 st=verify_area(VERIFY_READ,(void *) arg, sizeof(volctrl));
 699                 if (st) return (st);
 700                 memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl));
 701                 azt_Play.start.min = 0x21;
 702                 azt_Play.start.sec = 0x84;
 703                 azt_Play.start.frame = volctrl.channel0;
 704                 azt_Play.end.min =     volctrl.channel1;
 705                 azt_Play.end.sec =     volctrl.channel2;
 706                 azt_Play.end.frame =   volctrl.channel3;
 707                 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
 708                 STEN_LOW_WAIT;
 709                 break;
 710         case CDROMEJECT:
 711                 aztUnlockDoor(); /* Assume user knows what they're doing */
 712                /* all drives can at least stop! */
 713                 if (aztAudioStatus == CDROM_AUDIO_PLAY) 
 714                 { if (aztSendCmd(ACMD_STOP)) return -1;
 715                   STEN_LOW_WAIT;
 716                 }
 717                 if (aztSendCmd(ACMD_EJECT)) return -1;
 718                 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
 719                 break;
 720         case CDROMREADMODE1: /*read data in mode 1 (2048 Bytes)*/
 721         case CDROMREADMODE2: /*read data in mode 2 (2336 Bytes)*/
 722 /*Take care, the following code is not compatible with other CD-ROM drivers,
 723   use it at your own risk with cdplay.c. Normally it is not activated, as 
 724   AZT_PRIVATE_IOCTLS is not defined
 725 */                  
 726 #ifdef AZT_PRIVATE_IOCTLS 
 727                 { st = verify_area(VERIFY_READ,  (void *) arg, sizeof msf);
 728                   if (st) return st;
 729                   st = verify_area(VERIFY_WRITE, (void *) arg, sizeof buf);
 730                   if (st) return st;
 731                   memcpy_fromfs(&msf, (void *) arg, sizeof msf);
 732                   /* convert to bcd */
 733                   azt_bin2bcd(&msf.cdmsf_min0);
 734                   azt_bin2bcd(&msf.cdmsf_sec0);
 735                   azt_bin2bcd(&msf.cdmsf_frame0);
 736                   msf.cdmsf_min1=0;
 737                   msf.cdmsf_sec1=0;
 738                   msf.cdmsf_frame1=1; /*read only one frame*/
 739                   azt_Play.start.min = msf.cdmsf_min0;
 740                   azt_Play.start.sec = msf.cdmsf_sec0;
 741                   azt_Play.start.frame = msf.cdmsf_frame0;
 742                   azt_Play.end.min = msf.cdmsf_min1;
 743                   azt_Play.end.sec = msf.cdmsf_sec1;
 744                   azt_Play.end.frame = msf.cdmsf_frame1;
 745                   if (cmd==CDROMREADMODE1)
 746                   { sendAztCmd(ACMD_DATA_READ, &azt_Play);
 747                     DTEN_LOW;
 748                     insb(DATA_PORT,buf,2048);
 749                     memcpy_tofs((void *) arg, &buf, 2048);
 750                   }
 751                   else /*CDROMREADMODE2*/
 752                   { sendAztCmd(ACMD_DATA_READ_RAW, &azt_Play);
 753                     DTEN_LOW;
 754                     insb(DATA_PORT,buf,2336);
 755                     memcpy_tofs((void *) arg, &buf, 2336);
 756                   }
 757                  } 
 758 #endif  /*end of incompatible code*/               
 759                 break;
 760         default:
 761                 return -EINVAL;
 762         }
 763 #ifdef AZT_DEBUG
 764         printk("aztcd: exiting aztcd_ioctl\n");
 765 #endif
 766         return 0;
 767 }
 768 
 769 
 770 /*
 771  * Take care of the different block sizes between cdrom and Linux.
 772  * When Linux gets variable block sizes this will probably go away.
 773  */
 774 static void azt_transfer(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 775 { 
 776 #ifdef AZT_TEST
 777   printk("aztcd: executing azt_transfer\n");
 778 #endif
 779   if (CURRENT_VALID) {
 780     while (CURRENT -> nr_sectors) {
 781       int bn = CURRENT -> sector / 4;
 782       int i;
 783       for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i)
 784         ;
 785       if (i < AZT_BUF_SIZ) {
 786         int offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
 787         int nr_sectors = 4 - (CURRENT -> sector & 3);
 788         if (azt_buf_out != i) {
 789           azt_buf_out = i;
 790           if (azt_buf_bn[i] != bn) {
 791             azt_buf_out = -1;
 792             continue;
 793           }
 794         }
 795         if (nr_sectors > CURRENT -> nr_sectors)
 796           nr_sectors = CURRENT -> nr_sectors;
 797         memcpy(CURRENT -> buffer, azt_buf + offs, nr_sectors * 512);
 798         CURRENT -> nr_sectors -= nr_sectors;
 799         CURRENT -> sector += nr_sectors;
 800         CURRENT -> buffer += nr_sectors * 512;
 801       } else {
 802         azt_buf_out = -1;
 803         break;
 804       }
 805     }
 806   }
 807 }
 808 
 809 
 810 static void do_aztcd_request(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 811 {
 812 #ifdef AZT_TEST
 813   printk(" do_aztcd_request(%ld+%ld)\n", CURRENT -> sector, CURRENT -> nr_sectors);
 814 #endif
 815   azt_transfer_is_active = 1;
 816   while (CURRENT_VALID) {
 817     if (CURRENT->bh) {
 818       if (!CURRENT->bh->b_lock)
 819         panic(DEVICE_NAME ": block not locked");
 820     }
 821     azt_transfer();
 822     if (CURRENT -> nr_sectors == 0) {
 823       end_request(1);
 824     } else {
 825       azt_buf_out = -1;         /* Want to read a block not in buffer */
 826       if (azt_state == AZT_S_IDLE) {
 827         if (!aztTocUpToDate) {
 828           if (aztUpdateToc() < 0) {
 829             while (CURRENT_VALID)
 830               end_request(0);
 831             break;
 832           }
 833         }
 834         azt_state = AZT_S_START;
 835         AztTries = 5;
 836         SET_TIMER(azt_poll, 1);
 837       }
 838       break;
 839     }
 840   }
 841   azt_transfer_is_active = 0;
 842 #ifdef AZT_TEST2
 843   printk("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n", \
 844           azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
 845   printk(" do_aztcd_request ends\n");
 846 #endif
 847 
 848 }
 849 
 850 static void azt_poll(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 851 {
 852     int st = 0;
 853     int loop_ctl = 1;
 854     int skip = 0;
 855 
 856     if (azt_error) {                             /* ???*/
 857         if (aztSendCmd(ACMD_GET_ERROR)) return;
 858         STEN_LOW;
 859         azt_error=inb(DATA_PORT)&0xFF;
 860         printk("aztcd: I/O error 0x%02x\n", azt_error);
 861         azt_invalidate_buffers();
 862 #ifdef WARN_IF_READ_FAILURE
 863         if (AztTries == 5)
 864           printk("aztcd: read of block %d failed - maybe audio disk?\n", azt_next_bn);
 865 #endif
 866         if (!AztTries--) {
 867           printk("aztcd: read of block %d failed, maybe audio disk? Giving up\n", azt_next_bn);
 868           if (azt_transfer_is_active) {
 869             AztTries = 0;
 870             loop_ctl = 0;
 871           }
 872           if (CURRENT_VALID)
 873             end_request(0);
 874           AztTries = 5;
 875         }
 876     azt_error = 0;
 877     azt_state = AZT_S_STOP;
 878     }
 879 
 880     while (loop_ctl)
 881     {
 882       loop_ctl = 0;   /* each case must flip this back to 1 if we want
 883                          to come back up here */
 884       switch (azt_state) {
 885 
 886         case AZT_S_IDLE:
 887 #ifdef AZT_TEST3
 888           if (azt_state!=azt_state_old) {
 889             azt_state_old=azt_state;
 890             printk("AZT_S_IDLE\n");
 891             }
 892 #endif
 893           return;
 894 
 895         case AZT_S_START:
 896 #ifdef AZT_TEST3
 897           if (azt_state!=azt_state_old) {
 898             azt_state_old=azt_state;
 899             printk("AZT_S_START\n");
 900           }
 901 #endif
 902 
 903           if(aztSendCmd(ACMD_GET_STATUS)) return;  /*result will be checked by aztStatus() */
 904           azt_state = azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
 905           AztTimeout = 3000;
 906           break;
 907 
 908         case AZT_S_MODE:
 909 #ifdef AZT_TEST3
 910           if (azt_state!=azt_state_old) {
 911             azt_state_old=azt_state;
 912             printk("AZT_S_MODE\n");
 913           }
 914 #endif
 915           if (!skip) {
 916             if ((st = aztStatus()) != -1) {
 917               if (st & AST_DSK_CHG) {
 918                 aztDiskChanged = 1;
 919                 aztTocUpToDate = 0;
 920                 azt_invalidate_buffers();
 921               }
 922             } else break;
 923           }
 924           skip = 0;
 925 
 926           if ((st & AST_DOOR_OPEN)||(st & AST_NOT_READY)) {
 927             aztDiskChanged = 1;
 928             aztTocUpToDate = 0;
 929             printk((st & AST_DOOR_OPEN) ? "aztcd: door open\n" : "aztcd: disk removed\n");
 930             if (azt_transfer_is_active) {
 931               azt_state = AZT_S_START;
 932               loop_ctl = 1;   /* goto immediately */
 933               break;
 934             }
 935             azt_state = AZT_S_IDLE;
 936             while (CURRENT_VALID)
 937               end_request(0);
 938             return;
 939           }
 940                                         /*???*/
 941           if (aztSendCmd(ACMD_SET_MODE)) return;
 942           outb(0x01, DATA_PORT);            /*Mode 1*/
 943           PA_OK;
 944           STEN_LOW;
 945           if (aztSendCmd(ACMD_GET_STATUS)) return;
 946           azt_mode = 1;
 947           azt_state = AZT_S_READ;
 948           AztTimeout = 3000;
 949 
 950           break;
 951 
 952 
 953         case AZT_S_READ:
 954 #ifdef AZT_TEST3
 955           if (azt_state!=azt_state_old)  {
 956             azt_state_old=azt_state;
 957             printk("AZT_S_READ\n");
 958           }
 959 #endif
 960           if (!skip) {
 961               if ((st = aztStatus()) != -1) {
 962                 if (st & AST_DSK_CHG) {
 963                 aztDiskChanged = 1;
 964                 aztTocUpToDate = 0;
 965                 azt_invalidate_buffers();
 966                 }
 967               } else break;
 968           } 
 969             
 970           skip = 0;
 971           if ((st & AST_DOOR_OPEN)||(st & AST_NOT_READY)) {
 972             aztDiskChanged = 1;
 973             aztTocUpToDate = 0;
 974             printk((st & AST_DOOR_OPEN) ? "aztcd: door open\n" : "aztcd: disk removed\n");
 975             if (azt_transfer_is_active) {
 976               azt_state = AZT_S_START;
 977               loop_ctl = 1;
 978               break;
 979             }
 980             azt_state = AZT_S_IDLE;
 981             while (CURRENT_VALID)
 982             end_request(0);
 983             return;
 984           }
 985 
 986           if (CURRENT_VALID) {
 987             struct azt_Play_msf msf;
 988             azt_next_bn = CURRENT -> sector / 4;
 989             azt_hsg2msf(azt_next_bn, &msf.start);
 990             azt_read_count=AZT_BUF_SIZ;    /*??? fast, because we read ahead*/
 991 /*          azt_read_count= CURRENT->nr_sectors;      slow
 992 */
 993             msf.end.min = 0;
 994             msf.end.sec = 0;            
 995             msf.end.frame = azt_read_count ;/*Mitsumi here reads 0xffffff sectors*/
 996 #ifdef AZT_TEST3
 997             printk("---reading msf-address %x:%x:%x  %x:%x:%x\n",msf.start.min,msf.start.sec,msf.start.frame,msf.end.min,msf.end.sec,msf.end.frame);
 998             printk("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n", \
 999                     azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1000 #endif 
1001             sendAztCmd(ACMD_DATA_READ, &msf);
1002             azt_state = AZT_S_DATA;
1003             AztTimeout = READ_TIMEOUT;
1004           } else {
1005             azt_state = AZT_S_STOP;
1006             loop_ctl = 1;
1007             break;
1008           }
1009 
1010           break;
1011 
1012 
1013         case AZT_S_DATA:
1014 #ifdef AZT_TEST3
1015           if (azt_state!=azt_state_old)  {
1016             azt_state_old=azt_state;
1017             printk("AZT_S_DATA\n");
1018           }
1019 #endif
1020 
1021           st = inb(STATUS_PORT) & AFL_STATUSorDATA;   /*???*/
1022 
1023           switch (st) {
1024 
1025             case AFL_DATA:
1026 #ifdef AZT_TEST3
1027               if (st!=azt_st_old)  {
1028                 azt_st_old=st; 
1029                 printk("---AFL_DATA st:%x\n",st);
1030               }
1031 #endif
1032 #ifdef WARN_IF_READ_FAILURE
1033               if (AztTries == 5)
1034                 printk("aztcd: read of block %d failed - maybe audio disk?\n", azt_next_bn);
1035 #endif
1036               if (!AztTries--) {
1037                 printk("aztcd: read of block %d failed, maybe audio disk ? Giving up\n", azt_next_bn);
1038                 if (azt_transfer_is_active) {
1039                   AztTries = 0;
1040                   break;
1041                 }
1042                 if (CURRENT_VALID)
1043                   end_request(0);
1044                 AztTries = 5;
1045               }
1046               azt_state = AZT_S_START;
1047               AztTimeout = READ_TIMEOUT;
1048               loop_ctl = 1;
1049               break;
1050 
1051             case AFL_STATUSorDATA:
1052 #ifdef AZT_TEST3
1053               if (st!=azt_st_old)  {
1054                 azt_st_old=st;
1055                 printk("---AFL_STATUSorDATA st:%x\n",st);
1056               }
1057 #endif
1058               break;
1059 
1060             default:
1061 #ifdef AZT_TEST3
1062               if (st!=azt_st_old)  {
1063                 azt_st_old=st;
1064                 printk("---default: st:%x\n",st);
1065               }
1066 #endif
1067               AztTries = 5;
1068               if (!CURRENT_VALID && azt_buf_in == azt_buf_out) {
1069                 azt_state = AZT_S_STOP;
1070                 loop_ctl = 1;
1071                 break;
1072               }
1073               if (azt_read_count<=0)
1074                 printk("aztcd: warning - try to read 0 frames\n");
1075               while (azt_read_count)      /*??? fast read ahead loop*/
1076                { azt_buf_bn[azt_buf_in] = -1;
1077                  DTEN_LOW;                      /*??? unsolved problem, very
1078                                                       seldom we get timeouts
1079                                                       here, don't now the real
1080                                                       reason. With my drive this
1081                                                       sometimes also happens with
1082                                                       Aztech's original driver under
1083                                                       DOS. Is it a hardware bug? 
1084                                                       I tried to recover from such
1085                                                       situations here. Zimmermann*/
1086                  if (aztTimeOutCount>=AZT_TIMEOUT) 
1087                   { printk("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n", azt_read_count,CURRENT->nr_sectors,azt_buf_in);
1088                     printk("azt_transfer_is_active:%x\n",azt_transfer_is_active);
1089                     azt_read_count=0;
1090                     azt_state = AZT_S_STOP;
1091                     loop_ctl = 1;
1092                     end_request(1);  /*should we have here (1) or (0)? */
1093                   }
1094                  else
1095                   { insb(DATA_PORT, azt_buf + 2048 * azt_buf_in, 2048);
1096                     azt_read_count--;
1097 #ifdef AZT_TEST3
1098                     printk("AZT_S_DATA; ---I've read data- read_count: %d\n",azt_read_count);
1099                     printk("azt_next_bn:%d  azt_buf_in:%d azt_buf_out:%d  azt_buf_bn:%d\n", \
1100                          azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1101 #endif
1102                     azt_buf_bn[azt_buf_in] = azt_next_bn++;
1103                     if (azt_buf_out == -1)
1104                       azt_buf_out = azt_buf_in;
1105                     azt_buf_in = azt_buf_in + 1 == AZT_BUF_SIZ ? 0 : azt_buf_in + 1;
1106                   }
1107                }
1108               if (!azt_transfer_is_active) {
1109                 while (CURRENT_VALID) {
1110                   azt_transfer();
1111                   if (CURRENT -> nr_sectors == 0)
1112                     end_request(1);
1113                   else
1114                     break;
1115                 }
1116               }
1117 
1118               if (CURRENT_VALID
1119                 && (CURRENT -> sector / 4 < azt_next_bn ||
1120                 CURRENT -> sector / 4 > azt_next_bn + AZT_BUF_SIZ)) {
1121                 azt_state = AZT_S_STOP;
1122                 loop_ctl = 1;
1123                 break;
1124               }
1125               AztTimeout = READ_TIMEOUT;   
1126               if (azt_read_count==0) {
1127                 azt_state = AZT_S_STOP;   /*???*/
1128                 loop_ctl = 1;
1129                 break;           
1130               } 
1131               break;
1132             }
1133     break;
1134 
1135 
1136         case AZT_S_STOP:
1137 #ifdef AZT_TEST3
1138           if (azt_state!=azt_state_old) {
1139             azt_state_old=azt_state;
1140             printk("AZT_S_STOP\n");
1141           }
1142 #endif
1143           if (azt_read_count!=0) printk("aztcd: discard data=%x frames\n",azt_read_count);  /*???*/
1144           while (azt_read_count!=0) {
1145             int i;
1146             if ( !(inb(STATUS_PORT) & AFL_DATA) ) {
1147               for (i=0; i<2048; i++) {
1148                 inb(DATA_PORT);
1149               }
1150             }
1151             azt_read_count--;
1152           }  
1153           if (aztSendCmd(ACMD_GET_STATUS)) return;
1154           azt_state = AZT_S_STOPPING;
1155           AztTimeout = 1000;
1156           break;
1157 
1158         case AZT_S_STOPPING:
1159 #ifdef AZT_TEST3
1160           if (azt_state!=azt_state_old) {
1161             azt_state_old=azt_state;
1162             printk("AZT_S_STOPPING\n");
1163           }
1164 #endif
1165 
1166           if ((st = aztStatus()) == -1 && AztTimeout)
1167             break;
1168 
1169           if ((st != -1) && (st & AST_DSK_CHG)) {
1170             aztDiskChanged = 1;
1171             aztTocUpToDate = 0;
1172             azt_invalidate_buffers();
1173           }
1174 
1175 
1176 #ifdef AZT_TEST3
1177           printk("CURRENT_VALID %d azt_mode %d\n",
1178              CURRENT_VALID, azt_mode);
1179 #endif
1180 
1181           if (CURRENT_VALID) {
1182             if (st != -1) {
1183               if (azt_mode == 1) {
1184                 azt_state = AZT_S_READ;
1185                 loop_ctl = 1;
1186                 skip = 1;
1187                 break;
1188               } else {
1189                 azt_state = AZT_S_MODE;
1190                 loop_ctl = 1;
1191                 skip = 1;
1192                 break;
1193               }
1194             } else {
1195               azt_state = AZT_S_START;
1196               AztTimeout = 1;
1197             }
1198           } else {
1199             azt_state = AZT_S_IDLE;
1200             return;
1201           }
1202           break;
1203 
1204         default:
1205           printk("aztcd: invalid state %d\n", azt_state);
1206           return;
1207       }  /* case */
1208     } /* while */
1209   
1210 
1211    if (!AztTimeout--) 
1212     { printk("aztcd: timeout in state %d\n", azt_state);
1213       azt_state = AZT_S_STOP;
1214       if (aztSendCmd(ACMD_STOP)) return; 
1215       STEN_LOW_WAIT;    
1216     };
1217 
1218   SET_TIMER(azt_poll, 1);
1219 }
1220 
1221 static void azt_invalidate_buffers(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1222 { int i;
1223 
1224 #ifdef AZT_DEBUG
1225   printk("aztcd: executing azt_invalidate_buffers\n");
1226 #endif
1227   for (i = 0; i < AZT_BUF_SIZ; ++i)
1228     azt_buf_bn[i] = -1;
1229   azt_buf_out = -1;
1230 }
1231 
1232 /*
1233  * Open the device special file.  Check that a disk is in.
1234  */
1235 int aztcd_open(struct inode *ip, struct file *fp)
     /* [previous][next][first][last][top][bottom][index][help] */
1236 {       int st;
1237 
1238 #ifdef AZT_DEBUG
1239         printk("aztcd: starting aztcd_open\n");
1240 #endif
1241         if (aztPresent == 0)
1242                 return -ENXIO;                  /* no hardware */
1243 
1244         if (!azt_open_count && azt_state == AZT_S_IDLE) {
1245 
1246         azt_invalidate_buffers();
1247 
1248         st = getAztStatus();                       /* check drive status */
1249         if (st == -1)
1250                 return -EIO;                    /* drive doesn't respond */
1251 
1252         if (st&AST_DOOR_OPEN)
1253           {
1254             /* close door, then get the status again. */
1255             aztCloseDoor();     
1256             st = getAztStatus();
1257           }        
1258 
1259         if ((st&AST_DOOR_OPEN)||(st&AST_NOT_READY)) /* no disk in drive or door open*/
1260         {       /* Door should be closed, probably no disk in drive */
1261                 printk("aztcd: no disk in drive or door open\n");
1262                 return -EIO;
1263         }
1264 
1265         if (aztUpdateToc() < 0)
1266                 return -EIO;
1267 
1268         }
1269         ++azt_open_count;
1270         MOD_INC_USE_COUNT;
1271         aztLockDoor();
1272 #ifdef AZT_DEBUG
1273         printk("aztcd: exiting aztcd_open\n");
1274 #endif
1275         return 0;
1276 }
1277 
1278 
1279 /*
1280  * On close, we flush all azt blocks from the buffer cache.
1281  */
1282 static void aztcd_release(struct inode * inode, struct file * file)
     /* [previous][next][first][last][top][bottom][index][help] */
1283 { 
1284 #ifdef AZT_DEBUG
1285   printk("aztcd: executing aztcd_release\n");
1286   printk("inode: %p, inode->i_rdev: %x    file: %p\n",inode,inode->i_rdev,file);
1287 #endif
1288   MOD_DEC_USE_COUNT;
1289   if (!--azt_open_count) {
1290         azt_invalidate_buffers();
1291         sync_dev(inode->i_rdev);             /*??? isn't it a read only dev?*/
1292         invalidate_buffers(inode -> i_rdev);
1293         aztUnlockDoor();
1294         CLEAR_TIMER;
1295   }
1296   return;
1297 }
1298 
1299 
1300 static struct file_operations azt_fops = {
1301         NULL,                   /* lseek - default */
1302         block_read,             /* read - general block-dev read */
1303         block_write,            /* write - general block-dev write */
1304         NULL,                   /* readdir - bad */
1305         NULL,                   /* select */
1306         aztcd_ioctl,            /* ioctl */
1307         NULL,                   /* mmap */
1308         aztcd_open,             /* open */
1309         aztcd_release,          /* release */
1310         NULL,                   /* fsync */
1311         NULL,                   /* fasync*/
1312         check_aztcd_media_change, /*media change*/
1313         NULL                    /* revalidate*/
1314 };
1315 
1316 /*
1317  * Test for presence of drive and initialize it.  Called at boot time.
1318  */
1319 #ifndef MODULE 
1320 unsigned long aztcd_init(unsigned long mem_start, unsigned long mem_end)
     /* [previous][next][first][last][top][bottom][index][help] */
1321 #else
1322 int init_module(void)
1323 #endif
1324 {       long int count, max_count;
1325         unsigned char result[50];
1326         int st;
1327 
1328         if (azt_port <= 0) {
1329           printk("aztcd: no Aztech CD-ROM Initialization");
1330 #ifndef MODULE
1331           return (mem_start);
1332 #else
1333           return -EIO;
1334 #endif    
1335         }
1336         printk("Aztech CD-ROM Init: Aztech, Orchid, Okano, Wearnes CD-ROM Driver\n");
1337         printk("Aztech CD-ROM Init: (C) 1994,1995 Werner Zimmermann\n");
1338         printk("Aztech CD-ROM Init: DriverVersion=%s  BaseAddress=0x%x \n",AZT_VERSION,azt_port);
1339 
1340         if (check_region(azt_port, 4)) {
1341           printk("aztcd: conflict, I/O port (%X) already used\n",
1342                  azt_port);
1343 #ifndef MODULE
1344           return (mem_start);
1345 #else
1346           return -EIO;
1347 #endif    
1348         }
1349 
1350         /* check for card */
1351         outb(POLLED,MODE_PORT);                 /*???*/
1352         inb(CMD_PORT);
1353         inb(CMD_PORT);
1354         outb(ACMD_GET_VERSION,CMD_PORT); /*Try to get version info*/
1355         STEN_LOW;
1356         if (inb(DATA_PORT)!=AFL_OP_OK)   /*OP_OK? If not, reset and try again*/
1357          { printk("aztcd: drive reset - please wait\n");
1358            for (count=0;count<50;count++)
1359              { inb(STATUS_PORT);    /*removing all data from earlier tries*/
1360                inb(DATA_PORT);
1361              }
1362            outb(POLLED,MODE_PORT);              /*???*/
1363            inb(CMD_PORT);
1364            inb(CMD_PORT);
1365            outb(ACMD_SOFT_RESET,CMD_PORT);   /*send reset*/
1366            STEN_LOW;
1367            if (inb(DATA_PORT)!=AFL_OP_OK)    /*OP_OK?*/
1368             { printk("aztcd: no AZTECH CD-ROM drive found\n");
1369 #ifndef MODULE
1370               return (mem_start);
1371 #else
1372               return -EIO;
1373 #endif       
1374             } 
1375            for (count = 0; count < AZT_TIMEOUT; count++);  /* delay a bit */
1376            if ((st=getAztStatus())==-1)
1377             { printk("aztcd: Drive Status Error Status=%x\n",st);
1378 #ifndef MODULE
1379               return (mem_start);
1380 #else
1381               return -EIO;
1382 #endif        
1383             }
1384 #ifdef AZT_DEBUG
1385            printk("aztcd: Status = %x\n",st);
1386 #endif
1387            outb(POLLED,MODE_PORT);              /*???*/
1388            inb(CMD_PORT);
1389            inb(CMD_PORT);
1390            outb(ACMD_GET_VERSION,CMD_PORT); /*GetVersion*/
1391            STEN_LOW;
1392            OP_OK;
1393          } 
1394         azt_init_end=1;
1395         STEN_LOW;
1396         result[0]=inb(DATA_PORT);        /*reading in a null byte???*/
1397         for (count=1;count<50;count++)   /*Reading version string*/
1398          { aztTimeOutCount=0;            /*here we must implement STEN_LOW differently*/
1399            do { aztIndatum=inb(STATUS_PORT);/*because we want to exit by timeout*/
1400                 aztTimeOutCount++; 
1401                 if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break; 
1402               } while (aztIndatum&AFL_STATUS); 
1403            if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break;  /*all chars read?*/
1404            result[count]=inb(DATA_PORT);
1405          }
1406         if (count>30) max_count=30;  /*print max.30 chars of the version string*/
1407         else          max_count=count;
1408         printk("Aztech CD-ROM Init: FirmwareVersion=");
1409         for (count=1;count<max_count;count++) printk("%c",result[count]);
1410         printk("<<<\n");
1411 
1412         if ((result[1]=='A')&&(result[2]=='Z')&&(result[3]=='T'))
1413          { printk("Aztech CD-ROM Init: AZTECH drive detected\n"); /*AZTECH*/    
1414          }
1415         else if ((result[2]=='C')&&(result[3]=='D')&&(result[4]=='D'))
1416          { printk("Aztech CD-ROM Init: ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES*/
1417          }
1418         else                                               /*OTHERS or none*/
1419          { printk("Aztech CD-ROM Init: : unknown drive or firmware version detected\n");
1420            printk("                      azt may not run stable, if you want to try anyhow,\n");
1421            printk("                      boot with: aztcd=base_address,0x79\n");
1422            if ((azt_cont!=0x79))     
1423              { printk("Aztech CD-ROM Init: FirmwareVersion=");
1424                for (count=1;count<5;count++) printk("%c",result[count]);
1425                printk("\n");
1426                printk("Aztech CD-ROM Init: Aborted\n");
1427 #ifndef MODULE
1428                return (mem_start);
1429 #else
1430                return -EIO;
1431 #endif            
1432              }
1433          }
1434         if (register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0)
1435         {
1436                 printk("aztcd: Unable to get major %d for Aztech CD-ROM\n",
1437                        MAJOR_NR);
1438 #ifndef MODULE                 
1439                 return (mem_start);
1440 #else
1441                 return -EIO;
1442 #endif          
1443         }
1444         blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1445         read_ahead[MAJOR_NR] = 4;
1446 
1447         request_region(azt_port, 4, "aztcd");
1448 
1449         azt_invalidate_buffers();
1450         aztPresent = 1;
1451         aztCloseDoor();
1452         printk("Aztech CD-ROM Init: End\n");
1453 #ifndef MODULE
1454         return (mem_start);
1455 #else
1456         return (0);
1457 #endif
1458 }
1459 
1460 
1461 static void azt_hsg2msf(long hsg, struct msf *msf)
     /* [previous][next][first][last][top][bottom][index][help] */
1462 {       hsg += 150;
1463         msf -> min = hsg / 4500;
1464         hsg %= 4500;
1465         msf -> sec = hsg / 75;
1466         msf -> frame = hsg % 75;
1467 #ifdef AZT_DEBUG
1468         if (msf->min  >=70) printk("aztcd: Error hsg2msf address Minutes\n");
1469         if (msf->sec  >=60) printk("aztcd: Error hsg2msf address Seconds\n");
1470         if (msf->frame>=75) printk("aztcd: Error hsg2msf address Frames\n");
1471 #endif
1472         azt_bin2bcd(&msf -> min);           /* convert to BCD */
1473         azt_bin2bcd(&msf -> sec);
1474         azt_bin2bcd(&msf -> frame);
1475 }
1476 
1477 
1478 static void azt_bin2bcd(unsigned char *p)
     /* [previous][next][first][last][top][bottom][index][help] */
1479 {       int u, t;
1480 
1481         u = *p % 10;
1482         t = *p / 10;
1483         *p = u | (t << 4);
1484 }
1485 
1486 static int azt_bcd2bin(unsigned char bcd)
     /* [previous][next][first][last][top][bottom][index][help] */
1487 {       return (bcd >> 4) * 10 + (bcd & 0xF);
1488 }
1489 
1490 
1491 
1492 /*
1493  * Read a value from the drive.  Should return quickly, so a busy wait
1494  * is used to avoid excessive rescheduling. The read command itself must
1495  * be issued with aztSendCmd() directly before
1496  */
1497 static int aztGetValue(unsigned char *result)
     /* [previous][next][first][last][top][bottom][index][help] */
1498 {       int s;
1499 
1500         STEN_LOW;
1501         if (aztTimeOutCount>=AZT_TIMEOUT)
1502         {       printk("aztcd: aztGetValue timeout\n");
1503                 return -1;
1504         }
1505         s = inb(DATA_PORT) & 0xFF;
1506         *result = (unsigned char) s;
1507         return 0;
1508 }
1509 
1510 
1511 /*
1512  * Read the current Q-channel info.  Also used for reading the
1513  * table of contents.
1514  */
1515 int aztGetQChannelInfo(struct azt_Toc *qp)
     /* [previous][next][first][last][top][bottom][index][help] */
1516 {       unsigned char notUsed;
1517         int st;
1518 
1519 #ifdef AZT_DEBUG
1520         printk("aztcd: starting aztGetQChannelInfo\n");
1521 #endif
1522         if ((st=getAztStatus())==-1) return -1;
1523         if (aztSendCmd(ACMD_GET_Q_CHANNEL))          return -1;
1524         STEN_LOW_WAIT;
1525         if (aztGetValue(&notUsed) <0)                return -1; /*Nullbyte ein-*/
1526                                                              /*lesen ???*/
1527         if ((st&AST_MODE_BITS)==AST_INITIAL)
1528          { qp->ctrl_addr=0;      /* when audio stop ACMD_GET_Q_CHANNEL returns */
1529            qp->track=0;          /* only one byte with Aztech drives */
1530            qp->pointIndex=0;
1531            qp->trackTime.min=0;
1532            qp->trackTime.sec=0;
1533            qp->trackTime.frame=0;
1534            qp->diskTime.min=0;
1535            qp->diskTime.sec=0;
1536            qp->diskTime.frame=0;
1537            return 0;  
1538          }
1539         else
1540          { if (aztGetValue(&qp -> ctrl_addr) < 0)       return -1;
1541            if (aztGetValue(&qp -> track) < 0)           return -1;
1542            if (aztGetValue(&qp -> pointIndex) < 0)      return -1;
1543            if (aztGetValue(&qp -> trackTime.min) < 0)   return -1;
1544            if (aztGetValue(&qp -> trackTime.sec) < 0)   return -1;
1545            if (aztGetValue(&qp -> trackTime.frame) < 0) return -1;
1546            if (aztGetValue(&notUsed) < 0)               return -1;
1547            if (aztGetValue(&qp -> diskTime.min) < 0)    return -1;
1548            if (aztGetValue(&qp -> diskTime.sec) < 0)    return -1;
1549            if (aztGetValue(&qp -> diskTime.frame) < 0)  return -1;
1550          }
1551 #ifdef AZT_DEBUG
1552         printk("aztcd: exiting aztGetQChannelInfo\n");
1553 #endif
1554         return 0;
1555 }
1556 
1557 /*
1558  * Read the table of contents (TOC) and TOC header if necessary
1559  */
1560 static int aztUpdateToc()
     /* [previous][next][first][last][top][bottom][index][help] */
1561 {
1562 #ifdef AZT_DEBUG
1563         printk("aztcd: starting aztUpdateToc\n");
1564 #endif  
1565         if (aztTocUpToDate)
1566                 return 0;
1567 
1568         if (aztGetDiskInfo() < 0)
1569                 return -EIO;
1570 
1571         if (aztGetToc() < 0)
1572                 return -EIO;
1573 
1574         aztTocUpToDate = 1;
1575 #ifdef AZT_DEBUG
1576         printk("aztcd: exiting aztUpdateToc\n");
1577 #endif
1578         return 0;
1579 }
1580 
1581 
1582 /*
1583  * Read the table of contents header
1584  */
1585 static int aztGetDiskInfo()
     /* [previous][next][first][last][top][bottom][index][help] */
1586 { int limit;
1587   unsigned char test;
1588   struct azt_Toc qInfo;
1589 
1590 #ifdef AZT_DEBUG
1591   printk("aztcd: starting aztGetDiskInfo\n");
1592 #endif
1593   if (aztSendCmd(ACMD_SEEK_TO_LEADIN)) return -1;
1594   STEN_LOW_WAIT;
1595   test=0;
1596   for (limit=300;limit>0;limit--)
1597    {  if (aztGetQChannelInfo(&qInfo)<0) return -1;
1598       if (qInfo.pointIndex==0xA0)   /*Number of FirstTrack*/
1599         { DiskInfo.first=qInfo.diskTime.min;
1600           DiskInfo.first = azt_bcd2bin(DiskInfo.first);
1601           test=test|0x01;
1602         }
1603       if (qInfo.pointIndex==0xA1)   /*Number of LastTrack*/
1604         { DiskInfo.last=qInfo.diskTime.min;
1605           DiskInfo.last  = azt_bcd2bin(DiskInfo.last);
1606           test=test|0x02;
1607         }
1608       if (qInfo.pointIndex==0xA2)   /*DiskLength*/
1609         { DiskInfo.diskLength.min=qInfo.diskTime.min;
1610           DiskInfo.diskLength.sec=qInfo.diskTime.sec-2;
1611           DiskInfo.diskLength.frame=qInfo.diskTime.frame;
1612           test=test|0x04;
1613         }
1614       if ((qInfo.pointIndex==DiskInfo.first)&&(test&0x01))   /*StartTime of First Track*/
1615         { DiskInfo.firstTrack.min=qInfo.diskTime.min;
1616           DiskInfo.firstTrack.sec=qInfo.diskTime.sec;
1617           DiskInfo.firstTrack.frame=qInfo.diskTime.frame;
1618           test=test|0x08;
1619         }
1620       if (test==0x0F) break;
1621    }
1622 #ifdef AZT_DEBUG
1623 printk ("aztcd: exiting aztGetDiskInfo\n");
1624 printk("Disk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x\n",
1625         DiskInfo.first,
1626         DiskInfo.last,
1627         DiskInfo.diskLength.min,
1628         DiskInfo.diskLength.sec,
1629         DiskInfo.diskLength.frame,
1630         DiskInfo.firstTrack.min,
1631         DiskInfo.firstTrack.sec,
1632         DiskInfo.firstTrack.frame);
1633 #endif
1634   if (test!=0x0F) return -1;
1635   return 0;
1636 }
1637 
1638 
1639 /*
1640  * Read the table of contents (TOC)
1641  */
1642 static int aztGetToc()
     /* [previous][next][first][last][top][bottom][index][help] */
1643 {       int i, px;
1644         int limit;
1645         struct azt_Toc qInfo;
1646 
1647 #ifdef AZT_DEBUG
1648         printk("aztcd: starting aztGetToc\n");
1649 #endif
1650         for (i = 0; i < MAX_TRACKS; i++)
1651                 Toc[i].pointIndex = 0;
1652 
1653         i = DiskInfo.last + 3;
1654 
1655 /* Is there a good reason to stop motor before TOC read?
1656         if (aztSendCmd(ACMD_STOP)) return -1;
1657         STEN_LOW_WAIT;
1658 */
1659 
1660         azt_mode = 0x05;
1661         if (aztSendCmd(ACMD_SEEK_TO_LEADIN)) return -1; /*???*/
1662         STEN_LOW_WAIT;
1663 
1664         for (limit = 300; limit > 0; limit--)
1665         {
1666                 if (aztGetQChannelInfo(&qInfo) < 0)
1667                         break;
1668 
1669                 px = azt_bcd2bin(qInfo.pointIndex);
1670                 if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
1671                         if (Toc[px].pointIndex == 0)
1672                         {
1673                                 Toc[px] = qInfo;
1674                                 i--;
1675                         }
1676 
1677                 if (i <= 0)
1678                         break;
1679         }
1680 
1681         Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
1682 
1683 #ifdef AZT_DEBUG
1684 printk("aztcd: exiting aztGetToc\n");
1685 for (i = 1; i <= DiskInfo.last+1; i++)
1686 printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
1687 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1688 Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
1689 Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1690 for (i = 100; i < 103; i++)
1691 printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
1692 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1693 Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
1694 Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1695 #endif
1696 
1697         return limit > 0 ? 0 : -1;
1698 }
1699 
1700 #ifdef MODULE
1701 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1702 { if (MOD_IN_USE)
1703     { printk("aztcd module in use - can't remove it.\n");
1704       return;
1705     }
1706   if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL))    
1707     { printk("What's that: can't unregister aztcd\n");
1708       return;
1709     }
1710    release_region(azt_port,4);
1711    printk("aztcd module released.\n");
1712 }   
1713 #endif MODULE

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