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

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