OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [cdrom/] [aztcd.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
#define AZT_VERSION "2.50"
2
/*      $Id: aztcd.c,v 1.1 2005-12-20 10:16:38 jcastillo Exp $
3
        linux/drivers/block/aztcd.c - Aztech CD268 CDROM driver
4
 
5
        Copyright (C) 1994,95,96 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 Aztech 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
        V1.10   Implemented soundcard configuration for Orchid CDS-3110 drives
108
                connected to Soundwave32 cards. Release for LST 2.1.
109
                (still experimental)
110
                Werner Zimmermann, May 8, 95
111
        V1.20   Implemented limited support for DOSEMU0.60's cdrom.c. Now it works, but
112
                sometimes DOSEMU may hang for 30 seconds or so. A fully functional ver-
113
                sion needs an update of Dosemu0.60's cdrom.c, which will come with the
114
                next revision of Dosemu.
115
                Also Soundwave32 support now works.
116
                Werner Zimmermann, May 22, 95
117
        V1.30   Auto-eject feature. Inspired by Franc Racis (racis@psu.edu)
118
                Werner Zimmermann, July 4, 95
119
        V1.40   Started multisession support. Implementation copied from mcdx.c
120
                by Heiko Schlittermann. Not tested yet.
121
                Werner Zimmermann, July 15, 95
122
        V1.50   Implementation of ioctl CDROMRESET, continued multisession, began
123
                XA, but still untested. Heavy modifications to drive status de-
124
                tection.
125
                Werner Zimmermann, July 25, 95
126
        V1.60   XA support now should work. Speeded up drive recognition in cases,
127
                where no drive is installed.
128
                Werner Zimmermann, August 8, 1995
129
        V1.70   Multisession support now is completed, but there is still not
130
                enough testing done. If you can test it, please contact me. For
131
                details please read /usr/src/linux/Documentation/cdrom/aztcd
132
                Werner Zimmermann, August 19, 1995
133
        V1.80   Modification to suit the new kernel boot procedure introduced
134
                with kernel 1.3.33. Will definitely not work with older kernels.
135
                Programming done by Linus himself.
136
                Werner Zimmermann, October 11, 1995
137
        V1.90   Support for Conrad TXC drives, thank's to Jochen Kunz and Olaf Kaluza.
138
                Werner Zimmermann, October 21, 1995
139
        V2.00   Changed #include "blk.h" to <linux/blk.h> as the directory
140
                structure was changed. README.aztcd is now /usr/src/docu-
141
                mentation/cdrom/aztcd
142
                Werner Zimmermann, November 10, 95
143
        V2.10   Started to modify azt_poll to prevent reading beyond end of
144
                tracks.
145
                Werner Zimmermann, December 3, 95
146
        V2.20   Changed some comments
147
                Werner Zimmermann, April 1, 96
148
        V2.30   Implemented support for CyCDROM CR520, CR940, Code for CR520
149
                delivered by H.Berger with preworks by E.Moenkeberg.
150
                Werner Zimmermann, April 29, 96
151
        V2.40   Reorganized the placement of functions in the source code file
152
                to reflect the layered approach; did not actually change code
153
                Werner Zimmermann, May 1, 96
154
        V2.50   Heiko Eissfeldt suggested to remove some VERIFY_READs in
155
                aztcd_ioctl; check_aztcd_media_change modified
156
                Werner Zimmermann, May 16, 96
157
*/
158
#include <linux/module.h>
159
#include <linux/errno.h>
160
#include <linux/sched.h>
161
#include <linux/mm.h>
162
#include <linux/timer.h>
163
#include <linux/fs.h>
164
#include <linux/kernel.h>
165
#include <linux/cdrom.h>
166
#include <linux/ioport.h>
167
#include <linux/string.h>
168
#include <linux/major.h>
169
 
170
#include <asm/system.h>
171
#include <asm/io.h>
172
#include <asm/segment.h>
173
 
174
#define MAJOR_NR AZTECH_CDROM_MAJOR 
175
 
176
#include <linux/blk.h>
177
#include <linux/aztcd.h>
178
 
179
/*###########################################################################
180
  Defines
181
  ###########################################################################
182
*/
183
#define SET_TIMER(func, jifs)   delay_timer.expires = jiffies + (jifs); \
184
                                delay_timer.function = (void *) (func); \
185
                                add_timer(&delay_timer);
186
 
187
#define CLEAR_TIMER             del_timer(&delay_timer);
188
 
189
#define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
190
                                return value;}
191
#define RETURN(message)        {printk("aztcd: Warning: %s failed\n",message);\
192
                                return;}
193
 
194
/* Macros to switch the IDE-interface to the slave device and back to the master*/
195
#define SWITCH_IDE_SLAVE  outb_p(0xa0,azt_port+6); \
196
                          outb_p(0x10,azt_port+6); \
197
                          outb_p(0x00,azt_port+7); \
198
                          outb_p(0x10,azt_port+6);
199
#define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
200
 
201
 
202
#if 0
203
#define AZT_TEST
204
#define AZT_TEST1 /* <int-..> */
205
#define AZT_TEST2 /* do_aztcd_request */
206
#define AZT_TEST3 /* AZT_S_state */
207
#define AZT_TEST4 /* QUICK_LOOP-counter */
208
#define AZT_TEST5 /* port(1) state */
209
#define AZT_DEBUG
210
#define AZT_DEBUG_MULTISESSION
211
#endif
212
 
213
#define CURRENT_VALID \
214
  (CURRENT && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
215
   && CURRENT -> sector != -1)
216
 
217
#define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
218
#define AZT_BUF_SIZ 16
219
 
220
#define READ_TIMEOUT 3000
221
 
222
#define azt_port aztcd  /*needed for the modutils*/
223
 
224
/*##########################################################################
225
  Type Definitions
226
  ##########################################################################
227
*/
228
enum azt_state_e
229
{ AZT_S_IDLE,    /* 0 */
230
  AZT_S_START,   /* 1 */
231
  AZT_S_MODE,    /* 2 */
232
  AZT_S_READ,    /* 3 */
233
  AZT_S_DATA,    /* 4 */
234
  AZT_S_STOP,    /* 5 */
235
  AZT_S_STOPPING /* 6 */
236
};
237
enum azt_read_modes
238
{ AZT_MODE_0,     /*read mode for audio disks, not supported by Aztech firmware*/
239
  AZT_MODE_1,     /*read mode for normal CD-ROMs*/
240
  AZT_MODE_2      /*read mode for XA CD-ROMs*/
241
};
242
 
243
/*##########################################################################
244
  Global Variables
245
  ##########################################################################
246
*/
247
static int aztPresent = 0;
248
 
249
static volatile int azt_transfer_is_active=0;
250
 
251
static char azt_buf[CD_FRAMESIZE_RAW*AZT_BUF_SIZ];/*buffer for block size conversion*/
252
#if AZT_PRIVATE_IOCTLS
253
static char buf[CD_FRAMESIZE_RAW];              /*separate buffer for the ioctls*/
254
#endif
255
 
256
static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
257
static volatile int azt_buf_in, azt_buf_out = -1;
258
static volatile int azt_error=0;
259
static int azt_open_count=0;
260
static volatile enum azt_state_e azt_state = AZT_S_IDLE;
261
#ifdef AZT_TEST3
262
static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
263
static volatile int azt_st_old = 0;
264
#endif
265
static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
266
 
267
static int azt_mode = -1;
268
static volatile int azt_read_count = 1;
269
 
270
static int azt_port = AZT_BASE_ADDR;
271
 
272
static char  azt_cont = 0;
273
static char  azt_init_end = 0;
274
static char  azt_auto_eject = AZT_AUTO_EJECT;
275
 
276
static int AztTimeout, AztTries;
277
static struct wait_queue *azt_waitq = NULL;
278
static struct timer_list delay_timer = { NULL, NULL, 0, 0, NULL };
279
 
280
static struct azt_DiskInfo DiskInfo;
281
static struct azt_Toc Toc[MAX_TRACKS];
282
static struct azt_Play_msf azt_Play;
283
 
284
static int  aztAudioStatus = CDROM_AUDIO_NO_STATUS;
285
static char aztDiskChanged = 1;
286
static char aztTocUpToDate = 0;
287
 
288
static unsigned char aztIndatum;
289
static unsigned long aztTimeOutCount;
290
static int aztCmd = 0;
291
 
292
/*###########################################################################
293
   Function Prototypes
294
  ###########################################################################
295
*/
296
/* CDROM Drive Low Level I/O Functions */
297
void        op_ok(void);
298
void        pa_ok(void);
299
void        sten_low(void);
300
void        dten_low(void);
301
void        statusAzt(void);
302
static void aztStatTimer(void);
303
 
304
/* CDROM Drive Command Functions */
305
static int  aztSendCmd(int cmd);
306
static int  sendAztCmd(int cmd, struct azt_Play_msf *params);
307
static int  aztSeek(struct azt_Play_msf *params);
308
static int  aztSetDiskType(int type);
309
static int  aztStatus(void);
310
static int  getAztStatus(void);
311
static int  aztPlay(struct azt_Play_msf *arg);
312
static void aztCloseDoor(void);
313
static void aztLockDoor(void);
314
static void aztUnlockDoor(void);
315
static int  aztGetValue(unsigned char *result);
316
static int  aztGetQChannelInfo(struct azt_Toc *qp);
317
static int  aztUpdateToc(void);
318
static int  aztGetDiskInfo(void);
319
#if AZT_MULTISESSION 
320
 static int aztGetMultiDiskInfo(void);
321
#endif
322
static int  aztGetToc(int multi);
323
 
324
/* Kernel Interface Functions */
325
void        aztcd_setup(char *str, int *ints);
326
static int  check_aztcd_media_change(kdev_t full_dev);
327
static int  aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg);
328
static void azt_transfer(void);
329
static void do_aztcd_request(void);
330
static void azt_invalidate_buffers(void);
331
int         aztcd_open(struct inode *ip, struct file *fp);
332
static void aztcd_release(struct inode * inode, struct file * file);
333
int         aztcd_init(void);
334
#ifdef MODULE
335
 int        init_module(void);
336
 void       cleanup_module(void);
337
#endif MODULE
338
static struct file_operations azt_fops = {
339
        NULL,                   /* lseek - default */
340
        block_read,             /* read - general block-dev read */
341
        block_write,            /* write - general block-dev write */
342
        NULL,                   /* readdir - bad */
343
        NULL,                   /* select */
344
        aztcd_ioctl,            /* ioctl */
345
        NULL,                   /* mmap */
346
        aztcd_open,             /* open */
347
        aztcd_release,          /* release */
348
        NULL,                   /* fsync */
349
        NULL,                   /* fasync*/
350
        check_aztcd_media_change, /*media change*/
351
        NULL                    /* revalidate*/
352
};
353
 
354
/* Aztcd State Machine: Controls Drive Operating State */
355
static void azt_poll(void);
356
 
357
/* Miscellaneous support functions */
358
static void azt_hsg2msf(long hsg, struct msf *msf);
359
static long azt_msf2hsg(struct msf *mp);
360
static void azt_bin2bcd(unsigned char *p);
361
static int  azt_bcd2bin(unsigned char bcd);
362
 
363
/*##########################################################################
364
  CDROM Drive Low Level I/O Functions
365
  ##########################################################################
366
*/
367
/* Macros for the drive hardware interface handshake, these macros use
368
   busy waiting */
369
/* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
370
# define OP_OK op_ok()
371
void op_ok(void)
372
{ aztTimeOutCount=0;
373
  do { aztIndatum=inb(DATA_PORT);
374
       aztTimeOutCount++;
375
       if (aztTimeOutCount>=AZT_TIMEOUT)
376
        { printk("aztcd: Error Wait OP_OK\n");
377
          break;
378
        }
379
     } while (aztIndatum!=AFL_OP_OK);
380
}
381
 
382
/* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
383
# define PA_OK pa_ok()
384
void pa_ok(void)
385
{ aztTimeOutCount=0;
386
  do { aztIndatum=inb(DATA_PORT);
387
       aztTimeOutCount++;
388
       if (aztTimeOutCount>=AZT_TIMEOUT)
389
        { printk("aztcd: Error Wait PA_OK\n");
390
          break;
391
        }
392
     } while (aztIndatum!=AFL_PA_OK);
393
}
394
 
395
/* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
396
# define STEN_LOW  sten_low()
397
void sten_low(void)
398
{ aztTimeOutCount=0;
399
  do { aztIndatum=inb(STATUS_PORT);
400
       aztTimeOutCount++;
401
       if (aztTimeOutCount>=AZT_TIMEOUT)
402
        { if (azt_init_end) printk("aztcd: Error Wait STEN_LOW commands:%x\n",aztCmd);
403
          break;
404
        }
405
     } while (aztIndatum&AFL_STATUS);
406
}
407
 
408
/* Wait for DTEN=Low = handshake signal 'Data available'*/
409
# define DTEN_LOW dten_low()
410
void dten_low(void)
411
{ aztTimeOutCount=0;
412
  do { aztIndatum=inb(STATUS_PORT);
413
       aztTimeOutCount++;
414
       if (aztTimeOutCount>=AZT_TIMEOUT)
415
        { printk("aztcd: Error Wait DTEN_OK\n");
416
          break;
417
        }
418
     } while (aztIndatum&AFL_DATA);
419
}
420
 
421
/*
422
 * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
423
 * may cause kernel panic when used in the wrong place
424
*/
425
#define STEN_LOW_WAIT   statusAzt()
426
void statusAzt(void)
427
{ AztTimeout = AZT_STATUS_DELAY;
428
  SET_TIMER(aztStatTimer, HZ/100);
429
  sleep_on(&azt_waitq);
430
  if (AztTimeout <= 0) printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",aztCmd);
431
  return;
432
}
433
 
434
static void aztStatTimer(void)
435
{ if (!(inb(STATUS_PORT) & AFL_STATUS))
436
     { wake_up(&azt_waitq);
437
       return;
438
     }
439
  AztTimeout--;
440
  if (AztTimeout <= 0)
441
     { wake_up(&azt_waitq);
442
       printk("aztcd: Error aztStatTimer: Timeout\n");
443
       return;
444
     }
445
  SET_TIMER(aztStatTimer, HZ/100);
446
}
447
 
448
/*##########################################################################
449
  CDROM Drive Command Functions
450
  ##########################################################################
451
*/
452
/*
453
 * Send a single command, return -1 on error, else 0
454
*/
455
static int aztSendCmd(int cmd)
456
{  unsigned char data;
457
   int retry;
458
 
459
#ifdef AZT_DEBUG
460
   printk("aztcd: Executing command %x\n",cmd);
461
#endif
462
 
463
   if ((azt_port==0x1f0)||(azt_port==0x170))
464
      SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration*/
465
 
466
   aztCmd=cmd;
467
   outb(POLLED,MODE_PORT);
468
   do { if (inb(STATUS_PORT)&AFL_STATUS) break;
469
        inb(DATA_PORT);    /* if status left from last command, read and */
470
      } while (1);         /* discard it */
471
   do { if (inb(STATUS_PORT)&AFL_DATA) break;
472
        inb(DATA_PORT);    /* if data left from last command, read and */
473
      } while (1);         /* discard it */
474
   for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
475
     { outb((unsigned char) cmd,CMD_PORT);
476
       STEN_LOW;
477
       data=inb(DATA_PORT);
478
       if (data==AFL_OP_OK)
479
         { return 0;}           /*OP_OK?*/
480
       if (data==AFL_OP_ERR)
481
         { STEN_LOW;
482
           data=inb(DATA_PORT);
483
           printk("### Error 1 aztcd: aztSendCmd %x  Error Code %x\n",cmd,data);
484
         }
485
     }
486
   if (retry>=AZT_RETRY_ATTEMPTS)
487
     { printk("### Error 2 aztcd: aztSendCmd %x \n",cmd);
488
       azt_error=0xA5;
489
     }
490
   RETURNM("aztSendCmd",-1);
491
}
492
 
493
/*
494
 * Send a play or read command to the drive, return -1 on error, else 0
495
*/
496
static int sendAztCmd(int cmd, struct azt_Play_msf *params)
497
{  unsigned char data;
498
   int retry;
499
 
500
#ifdef AZT_DEBUG
501
   printk("aztcd: play start=%02x:%02x:%02x  end=%02x:%02x:%02x\n", \
502
           params->start.min, params->start.sec, params->start.frame, \
503
           params->end.min,   params->end.sec,   params->end.frame);
504
#endif   
505
   for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
506
     { aztSendCmd(cmd);
507
       outb(params -> start.min,CMD_PORT);
508
       outb(params -> start.sec,CMD_PORT);
509
       outb(params -> start.frame,CMD_PORT);
510
       outb(params -> end.min,CMD_PORT);
511
       outb(params -> end.sec,CMD_PORT);
512
       outb(params -> end.frame,CMD_PORT);
513
       STEN_LOW;
514
       data=inb(DATA_PORT);
515
       if (data==AFL_PA_OK)
516
         { return 0;}           /*PA_OK ?*/
517
       if (data==AFL_PA_ERR)
518
         { STEN_LOW;
519
           data=inb(DATA_PORT);
520
           printk("### Error 1 aztcd: sendAztCmd %x  Error Code %x\n",cmd,data);
521
         }
522
     }
523
   if (retry>=AZT_RETRY_ATTEMPTS)
524
     { printk("### Error 2 aztcd: sendAztCmd %x\n ",cmd);
525
       azt_error=0xA5;
526
     }
527
   RETURNM("sendAztCmd",-1);
528
}
529
 
530
/*
531
 * Send a seek command to the drive, return -1 on error, else 0
532
*/
533
static int aztSeek(struct azt_Play_msf *params)
534
{  unsigned char data;
535
   int retry;
536
 
537
#ifdef AZT_DEBUG
538
   printk("aztcd: aztSeek %02x:%02x:%02x\n", \
539
           params->start.min, params->start.sec, params->start.frame);
540
#endif   
541
   for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
542
     { aztSendCmd(ACMD_SEEK);
543
       outb(params -> start.min,CMD_PORT);
544
       outb(params -> start.sec,CMD_PORT);
545
       outb(params -> start.frame,CMD_PORT);
546
       STEN_LOW;
547
       data=inb(DATA_PORT);
548
       if (data==AFL_PA_OK)
549
         { return 0;}           /*PA_OK ?*/
550
       if (data==AFL_PA_ERR)
551
         { STEN_LOW;
552
           data=inb(DATA_PORT);
553
           printk("### Error 1 aztcd: aztSeek\n");
554
         }
555
     }
556
   if (retry>=AZT_RETRY_ATTEMPTS)
557
     { printk("### Error 2 aztcd: aztSeek\n ");
558
       azt_error=0xA5;
559
     }
560
   RETURNM("aztSeek",-1);
561
}
562
 
563
/* Send a Set Disk Type command
564
   does not seem to work with Aztech drives, behavior is completely indepen-
565
   dent on which mode is set ???
566
*/
567
static int aztSetDiskType(int type)
568
{  unsigned char data;
569
   int retry;
570
 
571
#ifdef AZT_DEBUG
572
   printk("aztcd: set disk type command: type= %i\n",type);
573
#endif
574
   for (retry=0;retry<AZT_RETRY_ATTEMPTS;retry++)
575
     { aztSendCmd(ACMD_SET_DISK_TYPE);
576
       outb(type,CMD_PORT);
577
       STEN_LOW;
578
       data=inb(DATA_PORT);
579
       if (data==AFL_PA_OK)     /*PA_OK ?*/
580
         { azt_read_mode=type;
581
           return 0;
582
         }
583
       if (data==AFL_PA_ERR)
584
         { STEN_LOW;
585
           data=inb(DATA_PORT);
586
           printk("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",type,data);
587
         }
588
     }
589
   if (retry>=AZT_RETRY_ATTEMPTS)
590
     { printk("### Error 2 aztcd: aztSetDiskType %x\n ",type);
591
       azt_error=0xA5;
592
     }
593
   RETURNM("aztSetDiskType",-1);
594
}
595
 
596
 
597
/* used in azt_poll to poll the status, expects another program to issue a
598
 * ACMD_GET_STATUS directly before
599
 */
600
static int aztStatus(void)
601
{       int st;
602
/*      int i;
603
 
604
        i = inb(STATUS_PORT) & AFL_STATUS;    is STEN=0?    ???
605
        if (!i)
606
*/      STEN_LOW;
607
        if (aztTimeOutCount<AZT_TIMEOUT)
608
        {       st = inb(DATA_PORT) & 0xFF;
609
                return st;
610
        }
611
        else
612
                RETURNM("aztStatus",-1);
613
}
614
 
615
/*
616
 * Get the drive status
617
 */
618
static int getAztStatus(void)
619
{       int st;
620
 
621
        if (aztSendCmd(ACMD_GET_STATUS)) RETURNM("getAztStatus 1",-1);
622
        STEN_LOW;
623
        st = inb(DATA_PORT) & 0xFF;
624
#ifdef AZT_DEBUG
625
        printk("aztcd: Status = %x\n",st);
626
#endif
627
        if ((st == 0xFF)||(st&AST_CMD_CHECK))
628
         { printk("aztcd: AST_CMD_CHECK error or no status available\n");
629
           return -1;
630
         }
631
 
632
        if (((st&AST_MODE_BITS)!=AST_BUSY) && (aztAudioStatus == CDROM_AUDIO_PLAY))
633
           /* XXX might be an error? look at q-channel? */
634
           aztAudioStatus = CDROM_AUDIO_COMPLETED;
635
 
636
        if ((st & AST_DSK_CHG)||(st & AST_NOT_READY))
637
         { aztDiskChanged = 1;
638
           aztTocUpToDate = 0;
639
           aztAudioStatus = CDROM_AUDIO_NO_STATUS;
640
         }
641
        return st;
642
}
643
 
644
 
645
/*
646
 * Send a 'Play' command and get the status.  Use only from the top half.
647
 */
648
static int aztPlay(struct azt_Play_msf *arg)
649
{       if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0) RETURNM("aztPlay",-1);
650
        return 0;
651
}
652
 
653
/*
654
 * Subroutines to automatically close the door (tray) and
655
 * lock it closed when the cd is mounted.  Leave the tray
656
 * locking as an option
657
 */
658
static void aztCloseDoor(void)
659
{
660
  aztSendCmd(ACMD_CLOSE);
661
  STEN_LOW;
662
  return;
663
}
664
 
665
static void aztLockDoor(void)
666
{
667
#if AZT_ALLOW_TRAY_LOCK
668
  aztSendCmd(ACMD_LOCK);
669
  STEN_LOW;
670
#endif
671
  return;
672
}
673
 
674
static void aztUnlockDoor(void)
675
{
676
#if AZT_ALLOW_TRAY_LOCK
677
  aztSendCmd(ACMD_UNLOCK);
678
  STEN_LOW;
679
#endif
680
  return;
681
}
682
 
683
/*
684
 * Read a value from the drive.  Should return quickly, so a busy wait
685
 * is used to avoid excessive rescheduling. The read command itself must
686
 * be issued with aztSendCmd() directly before
687
 */
688
static int aztGetValue(unsigned char *result)
689
{       int s;
690
 
691
        STEN_LOW;
692
        if (aztTimeOutCount>=AZT_TIMEOUT)
693
        {       printk("aztcd: aztGetValue timeout\n");
694
                return -1;
695
        }
696
        s = inb(DATA_PORT) & 0xFF;
697
        *result = (unsigned char) s;
698
        return 0;
699
}
700
 
701
/*
702
 * Read the current Q-channel info.  Also used for reading the
703
 * table of contents.
704
 */
705
int aztGetQChannelInfo(struct azt_Toc *qp)
706
{       unsigned char notUsed;
707
        int st;
708
 
709
#ifdef AZT_DEBUG
710
        printk("aztcd: starting aztGetQChannelInfo  Time:%li\n",jiffies);
711
#endif
712
        if ((st=getAztStatus())==-1)        RETURNM("aztGetQChannelInfo 1",-1);
713
        if (aztSendCmd(ACMD_GET_Q_CHANNEL)) RETURNM("aztGetQChannelInfo 2",-1);
714
        /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here*/
715
        if (aztGetValue(&notUsed)) RETURNM("aztGetQChannelInfo 3",-1); /*??? Nullbyte einlesen*/
716
        if ((st&AST_MODE_BITS)==AST_INITIAL)
717
         { qp->ctrl_addr=0;      /* when audio stop ACMD_GET_Q_CHANNEL returns */
718
           qp->track=0;          /* only one byte with Aztech drives */
719
           qp->pointIndex=0;
720
           qp->trackTime.min=0;
721
           qp->trackTime.sec=0;
722
           qp->trackTime.frame=0;
723
           qp->diskTime.min=0;
724
           qp->diskTime.sec=0;
725
           qp->diskTime.frame=0;
726
           return 0;
727
         }
728
        else
729
         { if (aztGetValue(&qp -> ctrl_addr) < 0)       RETURNM("aztGetQChannelInfo 4",-1);
730
           if (aztGetValue(&qp -> track) < 0)           RETURNM("aztGetQChannelInfo 4",-1);
731
           if (aztGetValue(&qp -> pointIndex) < 0)      RETURNM("aztGetQChannelInfo 4",-1);
732
           if (aztGetValue(&qp -> trackTime.min) < 0)   RETURNM("aztGetQChannelInfo 4",-1);
733
           if (aztGetValue(&qp -> trackTime.sec) < 0)   RETURNM("aztGetQChannelInfo 4",-1);
734
           if (aztGetValue(&qp -> trackTime.frame) < 0) RETURNM("aztGetQChannelInfo 4",-1);
735
           if (aztGetValue(&notUsed) < 0)               RETURNM("aztGetQChannelInfo 4",-1);
736
           if (aztGetValue(&qp -> diskTime.min) < 0)    RETURNM("aztGetQChannelInfo 4",-1);
737
           if (aztGetValue(&qp -> diskTime.sec) < 0)    RETURNM("aztGetQChannelInfo 4",-1);
738
           if (aztGetValue(&qp -> diskTime.frame) < 0)  RETURNM("aztGetQChannelInfo 4",-1);
739
         }
740
#ifdef AZT_DEBUG
741
        printk("aztcd: exiting aztGetQChannelInfo  Time:%li\n",jiffies);
742
#endif
743
        return 0;
744
}
745
 
746
/*
747
 * Read the table of contents (TOC) and TOC header if necessary
748
 */
749
static int aztUpdateToc()
750
{       int st;
751
 
752
#ifdef AZT_DEBUG
753
        printk("aztcd: starting aztUpdateToc  Time:%li\n",jiffies);
754
#endif  
755
        if (aztTocUpToDate)
756
                return 0;
757
 
758
        if (aztGetDiskInfo() < 0)
759
                return -EIO;
760
 
761
        if (aztGetToc(0) < 0)
762
                return -EIO;
763
 
764
        /*audio disk detection
765
          with my Aztech drive there is no audio status bit, so I use the copy
766
          protection bit of the first track. If this track is copy protected
767
          (copy bit = 0), I assume, it's an audio  disk. Strange, but works ??? */
768
        if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
769
           DiskInfo.audio=1;
770
        else
771
           DiskInfo.audio=0;
772
 
773
        /* XA detection */
774
        if (! DiskInfo.audio)
775
           { azt_Play.start.min   = 0;  /*XA detection only seems to work*/
776
             azt_Play.start.sec   = 2;  /*when we play a track*/
777
             azt_Play.start.frame = 0;
778
             azt_Play.end.min     = 0;
779
             azt_Play.end.sec     = 0;
780
             azt_Play.end.frame   = 1;
781
             if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) return -1;
782
             DTEN_LOW;
783
             for (st=0;st<CD_FRAMESIZE;st++) inb(DATA_PORT);
784
           }
785
        DiskInfo.xa = getAztStatus() & AST_MODE;
786
        if (DiskInfo.xa)
787
           { printk("aztcd: XA support experimental - mail results to zimmerma@rz.fht-esslingen.de\n");
788
           }
789
 
790
        /*multisession detection
791
          support for multisession CDs is done automatically with Aztech drives,
792
          we don't have to take care about TOC redirection; if we want the isofs
793
          to take care about redirection, we have to set AZT_MULTISESSION to 1*/
794
        DiskInfo.multi=0;
795
#if AZT_MULTISESSION
796
        if (DiskInfo.xa)
797
           { aztGetMultiDiskInfo(); /*here Disk.Info.multi is set*/
798
           }
799
#endif
800
        if (DiskInfo.multi)
801
           { DiskInfo.lastSession.min  = Toc[DiskInfo.next].diskTime.min;
802
             DiskInfo.lastSession.sec  = Toc[DiskInfo.next].diskTime.sec;
803
             DiskInfo.lastSession.frame= Toc[DiskInfo.next].diskTime.frame;
804
             printk("aztcd: Multisession support experimental\n");
805
           }
806
        else
807
           { DiskInfo.lastSession.min  = Toc[DiskInfo.first].diskTime.min;
808
             DiskInfo.lastSession.sec  = Toc[DiskInfo.first].diskTime.sec;
809
             DiskInfo.lastSession.frame= Toc[DiskInfo.first].diskTime.frame;
810
           }
811
 
812
        aztTocUpToDate = 1;
813
#ifdef AZT_DEBUG
814
        printk("aztcd: exiting aztUpdateToc  Time:%li\n",jiffies);
815
#endif
816
        return 0;
817
}
818
 
819
 
820
/* Read the table of contents header, i.e. no. of tracks and start of first
821
 * track
822
 */
823
static int aztGetDiskInfo()
824
{ int limit;
825
  unsigned char test;
826
  struct azt_Toc qInfo;
827
 
828
#ifdef AZT_DEBUG
829
  printk("aztcd: starting aztGetDiskInfo  Time:%li\n",jiffies);
830
#endif
831
  if (aztSendCmd(ACMD_SEEK_TO_LEADIN)) RETURNM("aztGetDiskInfo 1",-1);
832
  STEN_LOW_WAIT;
833
  test=0;
834
  for (limit=300;limit>0;limit--)
835
   {  if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetDiskInfo 2",-1);
836
      if (qInfo.pointIndex==0xA0)   /*Number of FirstTrack*/
837
        { DiskInfo.first = qInfo.diskTime.min;
838
          DiskInfo.first = azt_bcd2bin(DiskInfo.first);
839
          test=test|0x01;
840
        }
841
      if (qInfo.pointIndex==0xA1)   /*Number of LastTrack*/
842
        { DiskInfo.last  = qInfo.diskTime.min;
843
          DiskInfo.last  = azt_bcd2bin(DiskInfo.last);
844
          test=test|0x02;
845
        }
846
      if (qInfo.pointIndex==0xA2)   /*DiskLength*/
847
        { DiskInfo.diskLength.min=qInfo.diskTime.min;
848
          DiskInfo.diskLength.sec=qInfo.diskTime.sec;
849
          DiskInfo.diskLength.frame=qInfo.diskTime.frame;
850
          test=test|0x04;
851
        }
852
      if ((qInfo.pointIndex==DiskInfo.first)&&(test&0x01))   /*StartTime of First Track*/
853
        { DiskInfo.firstTrack.min=qInfo.diskTime.min;
854
          DiskInfo.firstTrack.sec=qInfo.diskTime.sec;
855
          DiskInfo.firstTrack.frame=qInfo.diskTime.frame;
856
          test=test|0x08;
857
        }
858
      if (test==0x0F) break;
859
   }
860
#ifdef AZT_DEBUG
861
  printk ("aztcd: exiting aztGetDiskInfo  Time:%li\n",jiffies);
862
  printk("Disk Info: first %d last %d length %02X:%02X.%02X dez  first %02X:%02X.%02X dez\n",
863
          DiskInfo.first,
864
          DiskInfo.last,
865
          DiskInfo.diskLength.min,
866
          DiskInfo.diskLength.sec,
867
          DiskInfo.diskLength.frame,
868
          DiskInfo.firstTrack.min,
869
          DiskInfo.firstTrack.sec,
870
          DiskInfo.firstTrack.frame);
871
#endif
872
  if (test!=0x0F) return -1;
873
  return 0;
874
}
875
 
876
#if AZT_MULTISESSION
877
/*
878
 * Get Multisession Disk Info
879
 */
880
static int aztGetMultiDiskInfo(void)
881
{ int limit, k=5;
882
  unsigned char test;
883
  struct azt_Toc qInfo;
884
 
885
#ifdef AZT_DEBUG
886
  printk("aztcd: starting aztGetMultiDiskInfo\n");
887
#endif
888
 
889
  do { azt_Play.start.min   = Toc[DiskInfo.last+1].diskTime.min;
890
       azt_Play.start.sec   = Toc[DiskInfo.last+1].diskTime.sec;
891
       azt_Play.start.frame = Toc[DiskInfo.last+1].diskTime.frame;
892
       test=0;
893
 
894
       for (limit=30;limit>0;limit--)   /*Seek for LeadIn of next session*/
895
           { if (aztSeek(&azt_Play)) RETURNM("aztGetMultiDiskInfo 1",-1);
896
             if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetMultiDiskInfo 2",-1);
897
             if ((qInfo.track==0)&&(qInfo.pointIndex)) break;  /*LeadIn found*/
898
             if ((azt_Play.start.sec+=10) > 59)
899
                { azt_Play.start.sec=0;
900
                  azt_Play.start.min++;
901
                }
902
           }
903
       if (!limit) break;  /*Check, if a leadin track was found, if not we're
904
                             at the end of the disk*/
905
#ifdef AZT_DEBUG_MULTISESSION
906
       printk("leadin found track %d  pointIndex %x  limit %d\n",qInfo.track,qInfo.pointIndex,limit);
907
#endif
908
       for (limit=300;limit>0;limit--)
909
           { if (++azt_Play.start.frame>74)
910
                { azt_Play.start.frame=0;
911
                  if (azt_Play.start.sec > 59)
912
                     { azt_Play.start.sec=0;
913
                       azt_Play.start.min++;
914
                     }
915
                }
916
             if (aztSeek(&azt_Play)) RETURNM("aztGetMultiDiskInfo 3",-1);
917
             if (aztGetQChannelInfo(&qInfo)<0) RETURNM("aztGetMultiDiskInfo 4",-1);
918
             if (qInfo.pointIndex==0xA0)   /*Number of NextTrack*/
919
                { DiskInfo.next = qInfo.diskTime.min;
920
                  DiskInfo.next = azt_bcd2bin(DiskInfo.next);
921
                  test=test|0x01;
922
                }
923
             if (qInfo.pointIndex==0xA1)   /*Number of LastTrack*/
924
                { DiskInfo.last  = qInfo.diskTime.min;
925
                  DiskInfo.last  = azt_bcd2bin(DiskInfo.last);
926
                  test=test|0x02;
927
                }
928
             if (qInfo.pointIndex==0xA2)   /*DiskLength*/
929
                { DiskInfo.diskLength.min  =qInfo.diskTime.min;
930
                  DiskInfo.diskLength.sec  =qInfo.diskTime.sec;
931
                  DiskInfo.diskLength.frame=qInfo.diskTime.frame;
932
                  test=test|0x04;
933
                }
934
             if ((qInfo.pointIndex==DiskInfo.next)&&(test&0x01))   /*StartTime of Next Track*/
935
                { DiskInfo.nextSession.min=qInfo.diskTime.min;
936
                  DiskInfo.nextSession.sec=qInfo.diskTime.sec;
937
                  DiskInfo.nextSession.frame=qInfo.diskTime.frame;
938
                  test=test|0x08;
939
                }
940
             if (test==0x0F) break;
941
           }
942
#ifdef AZT_DEBUG_MULTISESSION
943
       printk ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez  first %02x:%02x.%02x dez  next %02x:%02x.%02x dez\n",
944
                DiskInfo.first,
945
                DiskInfo.next,
946
                DiskInfo.last,
947
                DiskInfo.diskLength.min,
948
                DiskInfo.diskLength.sec,
949
                DiskInfo.diskLength.frame,
950
                DiskInfo.firstTrack.min,
951
                DiskInfo.firstTrack.sec,
952
                DiskInfo.firstTrack.frame,
953
                DiskInfo.nextSession.min,
954
                DiskInfo.nextSession.sec,
955
                DiskInfo.nextSession.frame);
956
#endif
957
       if (test!=0x0F)
958
           break;
959
       else
960
           DiskInfo.multi=1;   /*found TOC of more than one session*/
961
       aztGetToc(1);
962
     } while(--k);
963
 
964
#ifdef AZT_DEBUG
965
  printk ("aztcd: exiting aztGetMultiDiskInfo  Time:%li\n",jiffies);
966
#endif
967
  return 0;
968
}
969
#endif
970
 
971
/*
972
 * Read the table of contents (TOC)
973
 */
974
static int aztGetToc(int multi)
975
{ int i, px;
976
  int limit;
977
  struct azt_Toc qInfo;
978
 
979
#ifdef AZT_DEBUG
980
  printk("aztcd: starting aztGetToc  Time:%li\n",jiffies);
981
#endif
982
  if (!multi)
983
     { for (i = 0; i < MAX_TRACKS; i++)
984
            Toc[i].pointIndex = 0;
985
       i = DiskInfo.last + 3;
986
     }
987
  else
988
     { for (i = DiskInfo.next; i < MAX_TRACKS; i++)
989
            Toc[i].pointIndex = 0;
990
       i = DiskInfo.last + 4 - DiskInfo.next;
991
     }
992
 
993
/*Is there a good reason to stop motor before TOC read?
994
  if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
995
      STEN_LOW_WAIT;
996
*/
997
 
998
  if (!multi)
999
     { azt_mode = 0x05;
1000
       if (aztSendCmd(ACMD_SEEK_TO_LEADIN)) RETURNM("aztGetToc 2",-1);
1001
       STEN_LOW_WAIT;
1002
     }
1003
  for (limit = 300; limit > 0; limit--)
1004
      { if (multi)
1005
           { if (++azt_Play.start.sec > 59)
1006
                { azt_Play.start.sec=0;
1007
                  azt_Play.start.min++;
1008
                }
1009
             if (aztSeek(&azt_Play)) RETURNM("aztGetToc 3",-1);
1010
           }
1011
        if (aztGetQChannelInfo(&qInfo) < 0)
1012
            break;
1013
 
1014
        px = azt_bcd2bin(qInfo.pointIndex);
1015
 
1016
        if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
1017
            if (Toc[px].pointIndex == 0)
1018
               { Toc[px] = qInfo;
1019
                 i--;
1020
               }
1021
 
1022
        if (i <= 0)
1023
            break;
1024
      }
1025
 
1026
  Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
1027
  Toc[DiskInfo.last].trackTime    = DiskInfo.diskLength;
1028
 
1029
#ifdef AZT_DEBUG_MULTISESSION 
1030
  printk("aztcd: exiting aztGetToc\n");
1031
  for (i = 1; i <= DiskInfo.last+1; i++)
1032
       printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\n",
1033
               i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1034
               Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
1035
               Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1036
  for (i = 100; i < 103; i++)
1037
       printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez  %02X:%02X.%02X dez\n",
1038
               i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1039
               Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
1040
               Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1041
#endif
1042
 
1043
  return limit > 0 ? 0 : -1;
1044
}
1045
 
1046
 
1047
/*##########################################################################
1048
  Kernel Interface Functions
1049
  ##########################################################################
1050
*/
1051
void aztcd_setup(char *str, int *ints)
1052
{  if (ints[0] > 0)
1053
      azt_port = ints[1];
1054
   if (ints[0] > 1)
1055
      azt_cont = ints[2];
1056
}
1057
 
1058
/*
1059
 * Checking if the media has been changed
1060
*/
1061
static int check_aztcd_media_change(kdev_t full_dev)
1062
{ if (aztDiskChanged)          /* disk changed */
1063
     { aztDiskChanged=0;
1064
       return 1;
1065
     }
1066
  else
1067
       return 0;               /* no change */
1068
}
1069
 
1070
/*
1071
 * Kernel IO-controls
1072
*/
1073
static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
1074
{       int i, st;
1075
        struct azt_Toc qInfo;
1076
        struct cdrom_ti ti;
1077
        struct cdrom_tochdr tocHdr;
1078
        struct cdrom_msf msf;
1079
        struct cdrom_tocentry entry;
1080
        struct azt_Toc *tocPtr;
1081
        struct cdrom_subchnl subchnl;
1082
        struct cdrom_volctrl volctrl;
1083
 
1084
#ifdef AZT_DEBUG
1085
        printk("aztcd: starting aztcd_ioctl - Command:%x   Time: %li\n",cmd, jiffies);
1086
        printk("aztcd Status %x\n", getAztStatus());
1087
#endif
1088
        if (!ip) RETURNM("aztcd_ioctl 1",-EINVAL);
1089
        if (getAztStatus()<0) RETURNM("aztcd_ioctl 2", -EIO);
1090
        if ((!aztTocUpToDate)||(aztDiskChanged))
1091
        { if ((i=aztUpdateToc())<0) RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
1092
        }
1093
 
1094
        switch (cmd)
1095
        {
1096
        case CDROMSTART:     /* Spin up the drive. Don't know, what to do,
1097
                                at least close the tray */
1098
#if AZT_PRIVATE_IOCTLS 
1099
                if (aztSendCmd(ACMD_CLOSE)) RETURNM("aztcd_ioctl 4",-1);
1100
                STEN_LOW_WAIT;
1101
#endif
1102
                break;
1103
        case CDROMSTOP:      /* Spin down the drive */
1104
                if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 5",-1);
1105
                STEN_LOW_WAIT;
1106
                /* should we do anything if it fails? */
1107
                aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1108
                break;
1109
        case CDROMPAUSE:     /* Pause the drive */
1110
                if (aztAudioStatus != CDROM_AUDIO_PLAY) return -EINVAL;
1111
 
1112
                if (aztGetQChannelInfo(&qInfo) < 0)
1113
                { /* didn't get q channel info */
1114
                  aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1115
                  RETURNM("aztcd_ioctl 7",0);
1116
                }
1117
                azt_Play.start = qInfo.diskTime;        /* remember restart point */
1118
 
1119
                if (aztSendCmd(ACMD_PAUSE)) RETURNM("aztcd_ioctl 8",-1);
1120
                STEN_LOW_WAIT;
1121
                aztAudioStatus = CDROM_AUDIO_PAUSED;
1122
                break;
1123
        case CDROMRESUME:    /* Play it again, Sam */
1124
                if (aztAudioStatus != CDROM_AUDIO_PAUSED) return -EINVAL;
1125
                /* restart the drive at the saved position. */
1126
                i = aztPlay(&azt_Play);
1127
                if (i < 0)
1128
                { aztAudioStatus = CDROM_AUDIO_ERROR;
1129
                  return -EIO;
1130
                }
1131
                aztAudioStatus = CDROM_AUDIO_PLAY;
1132
                break;
1133
        case CDROMMULTISESSION: /*multisession support -- experimental*/
1134
                { struct cdrom_multisession ms;
1135
#ifdef AZT_DEBUG
1136
                  printk("aztcd ioctl MULTISESSION\n");
1137
#endif
1138
                  st = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct cdrom_multisession));
1139
                  if (st) return st;
1140
                  memcpy_fromfs(&ms, (void*) arg, sizeof(struct cdrom_multisession));
1141
                  if (ms.addr_format == CDROM_MSF)
1142
                     { ms.addr.msf.minute = azt_bcd2bin(DiskInfo.lastSession.min);
1143
                       ms.addr.msf.second = azt_bcd2bin(DiskInfo.lastSession.sec);
1144
                       ms.addr.msf.frame  = azt_bcd2bin(DiskInfo.lastSession.frame);
1145
                     }
1146
                  else if (ms.addr_format == CDROM_LBA)
1147
                       ms.addr.lba = azt_msf2hsg(&DiskInfo.lastSession);
1148
                  else
1149
                       return -EINVAL;
1150
                  ms.xa_flag = DiskInfo.xa;
1151
                  memcpy_tofs((void*) arg, &ms, sizeof(struct cdrom_multisession));
1152
#ifdef AZT_DEBUG 
1153
                  if (ms.addr_format == CDROM_MSF)
1154
                      printk("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1155
                              ms.xa_flag, ms.addr.msf.minute, ms.addr.msf.second,
1156
                              ms.addr.msf.frame, DiskInfo.lastSession.min,
1157
                              DiskInfo.lastSession.sec, DiskInfo.lastSession.frame);
1158
                  else
1159
                      printk("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1160
                              ms.xa_flag, ms.addr.lba, DiskInfo.lastSession.min,
1161
                              DiskInfo.lastSession.sec, DiskInfo.lastSession.frame);
1162
#endif
1163
                  return 0;
1164
                }
1165
        case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
1166
                st = verify_area(VERIFY_READ, (void *) arg, sizeof ti);
1167
                if (st) return st;
1168
                memcpy_fromfs(&ti, (void *) arg, sizeof ti);
1169
                if (ti.cdti_trk0 < DiskInfo.first
1170
                        || ti.cdti_trk0 > DiskInfo.last
1171
                        || ti.cdti_trk1 < ti.cdti_trk0)
1172
                { return -EINVAL;
1173
                }
1174
                if (ti.cdti_trk1 > DiskInfo.last)
1175
                    ti.cdti_trk1 = DiskInfo.last;
1176
                azt_Play.start = Toc[ti.cdti_trk0].diskTime;
1177
                azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
1178
#ifdef AZT_DEBUG
1179
printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1180
        azt_Play.start.min, azt_Play.start.sec, azt_Play.start.frame,
1181
        azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
1182
#endif
1183
                i = aztPlay(&azt_Play);
1184
                if (i < 0)
1185
                { aztAudioStatus = CDROM_AUDIO_ERROR;
1186
                  return -EIO;
1187
                }
1188
                aztAudioStatus = CDROM_AUDIO_PLAY;
1189
                break;
1190
        case CDROMPLAYMSF:   /* Play starting at the given MSF address. */
1191
/*              if (aztAudioStatus == CDROM_AUDIO_PLAY)
1192
                { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1193
                  STEN_LOW;
1194
                  aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1195
                }
1196
*/
1197
                st = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
1198
                if (st) return st;
1199
                memcpy_fromfs(&msf, (void *) arg, sizeof msf);
1200
                /* convert to bcd */
1201
                azt_bin2bcd(&msf.cdmsf_min0);
1202
                azt_bin2bcd(&msf.cdmsf_sec0);
1203
                azt_bin2bcd(&msf.cdmsf_frame0);
1204
                azt_bin2bcd(&msf.cdmsf_min1);
1205
                azt_bin2bcd(&msf.cdmsf_sec1);
1206
                azt_bin2bcd(&msf.cdmsf_frame1);
1207
                azt_Play.start.min = msf.cdmsf_min0;
1208
                azt_Play.start.sec = msf.cdmsf_sec0;
1209
                azt_Play.start.frame = msf.cdmsf_frame0;
1210
                azt_Play.end.min = msf.cdmsf_min1;
1211
                azt_Play.end.sec = msf.cdmsf_sec1;
1212
                azt_Play.end.frame = msf.cdmsf_frame1;
1213
#ifdef AZT_DEBUG
1214
printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1215
azt_Play.start.min, azt_Play.start.sec, azt_Play.start.frame,
1216
azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
1217
#endif
1218
                i = aztPlay(&azt_Play);
1219
                if (i < 0)
1220
                { aztAudioStatus = CDROM_AUDIO_ERROR;
1221
                  return -EIO;
1222
                }
1223
                aztAudioStatus = CDROM_AUDIO_PLAY;
1224
                break;
1225
 
1226
        case CDROMREADTOCHDR:        /* Read the table of contents header */
1227
                st = verify_area(VERIFY_WRITE, (void *) arg, sizeof tocHdr);
1228
                if (st) return st;
1229
                tocHdr.cdth_trk0 = DiskInfo.first;
1230
                tocHdr.cdth_trk1 = DiskInfo.last;
1231
                memcpy_tofs((void *) arg, &tocHdr, sizeof tocHdr);
1232
                break;
1233
        case CDROMREADTOCENTRY:      /* Read an entry in the table of contents */
1234
                st = verify_area(VERIFY_WRITE, (void *) arg, sizeof entry);
1235
                if (st) return st;
1236
                memcpy_fromfs(&entry, (void *) arg, sizeof entry);
1237
                if ((!aztTocUpToDate)||aztDiskChanged) aztUpdateToc();
1238
                if (entry.cdte_track == CDROM_LEADOUT)
1239
                  tocPtr = &Toc[DiskInfo.last + 1];
1240
                else if (entry.cdte_track > DiskInfo.last
1241
                                || entry.cdte_track < DiskInfo.first)
1242
                { return -EINVAL;
1243
                }
1244
                else
1245
                  tocPtr = &Toc[entry.cdte_track];
1246
                entry.cdte_adr = tocPtr -> ctrl_addr;
1247
                entry.cdte_ctrl = tocPtr -> ctrl_addr >> 4;
1248
                if (entry.cdte_format == CDROM_LBA)
1249
                  entry.cdte_addr.lba = azt_msf2hsg(&tocPtr -> diskTime);
1250
                else if (entry.cdte_format == CDROM_MSF)
1251
                { entry.cdte_addr.msf.minute = azt_bcd2bin(tocPtr -> diskTime.min);
1252
                  entry.cdte_addr.msf.second = azt_bcd2bin(tocPtr -> diskTime.sec);
1253
                  entry.cdte_addr.msf.frame  = azt_bcd2bin(tocPtr -> diskTime.frame);
1254
                }
1255
                else
1256
                { return -EINVAL;
1257
                }
1258
                memcpy_tofs((void *) arg, &entry, sizeof entry);
1259
                break;
1260
        case CDROMSUBCHNL:   /* Get subchannel info */
1261
                st = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_subchnl));
1262
                if (st) {
1263
#ifdef AZT_DEBUG
1264
                          printk("aztcd: exiting aztcd_ioctl - Error 1 - Command:%x\n",cmd);
1265
#endif
1266
                          return st;
1267
                        }
1268
                memcpy_fromfs(&subchnl, (void *) arg, sizeof (struct cdrom_subchnl));
1269
                if (aztGetQChannelInfo(&qInfo) < 0)
1270
                if (st) {
1271
#ifdef AZT_DEBUG
1272
                          printk("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",cmd);
1273
#endif
1274
                          return -EIO;
1275
                        }
1276
                subchnl.cdsc_audiostatus = aztAudioStatus;
1277
                subchnl.cdsc_adr = qInfo.ctrl_addr;
1278
                subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
1279
                subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
1280
                subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
1281
                if (subchnl.cdsc_format == CDROM_LBA)
1282
                { subchnl.cdsc_absaddr.lba = azt_msf2hsg(&qInfo.diskTime);
1283
                  subchnl.cdsc_reladdr.lba = azt_msf2hsg(&qInfo.trackTime);
1284
                }
1285
                else  /*default*/
1286
                { subchnl.cdsc_format = CDROM_MSF;
1287
                  subchnl.cdsc_absaddr.msf.minute = azt_bcd2bin(qInfo.diskTime.min);
1288
                  subchnl.cdsc_absaddr.msf.second = azt_bcd2bin(qInfo.diskTime.sec);
1289
                  subchnl.cdsc_absaddr.msf.frame  = azt_bcd2bin(qInfo.diskTime.frame);
1290
                  subchnl.cdsc_reladdr.msf.minute = azt_bcd2bin(qInfo.trackTime.min);
1291
                  subchnl.cdsc_reladdr.msf.second = azt_bcd2bin(qInfo.trackTime.sec);
1292
                  subchnl.cdsc_reladdr.msf.frame  = azt_bcd2bin(qInfo.trackTime.frame);
1293
                }
1294
                memcpy_tofs((void *) arg, &subchnl, sizeof (struct cdrom_subchnl));
1295
                break;
1296
        case CDROMVOLCTRL:   /* Volume control
1297
         * With my Aztech CD268-01A volume control does not work, I can only
1298
           turn the channels on (any value !=0) or off (value==0). Maybe it
1299
           works better with your drive */
1300
                st=verify_area(VERIFY_READ,(void *) arg, sizeof(volctrl));
1301
                if (st) return (st);
1302
                memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl));
1303
                azt_Play.start.min = 0x21;
1304
                azt_Play.start.sec = 0x84;
1305
                azt_Play.start.frame = volctrl.channel0;
1306
                azt_Play.end.min =     volctrl.channel1;
1307
                azt_Play.end.sec =     volctrl.channel2;
1308
                azt_Play.end.frame =   volctrl.channel3;
1309
                sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
1310
                STEN_LOW_WAIT;
1311
                break;
1312
        case CDROMEJECT:
1313
                aztUnlockDoor(); /* Assume user knows what they're doing */
1314
               /* all drives can at least stop! */
1315
                if (aztAudioStatus == CDROM_AUDIO_PLAY)
1316
                { if (aztSendCmd(ACMD_STOP)) RETURNM("azt_ioctl 10",-1);
1317
                  STEN_LOW_WAIT;
1318
                }
1319
                if (aztSendCmd(ACMD_EJECT)) RETURNM("azt_ioctl 11",-1);
1320
                STEN_LOW_WAIT;
1321
                aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1322
                break;
1323
        case CDROMEJECT_SW:
1324
                azt_auto_eject = (char) arg;
1325
                break;
1326
        case CDROMRESET:
1327
                outb(ACMD_SOFT_RESET,CMD_PORT);   /*send reset*/
1328
                STEN_LOW;
1329
                if (inb(DATA_PORT)!=AFL_OP_OK)    /*OP_OK?*/
1330
                  { printk("aztcd: AZTECH CD-ROM drive does not respond\n");
1331
                  }
1332
                break;
1333
/*Take care, the following code is not compatible with other CD-ROM drivers,
1334
  use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1335
  if you do not want to use it!
1336
*/
1337
#if AZT_PRIVATE_IOCTLS 
1338
        case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes)*/
1339
        case CDROMREADRAW:    /*read data in mode 2 (2336 Bytes)*/
1340
                { st = verify_area(VERIFY_WRITE, (void *) arg, sizeof buf);
1341
                  if (st) return st;
1342
                  memcpy_fromfs(&msf, (void *) arg, sizeof msf);
1343
                  /* convert to bcd */
1344
                  azt_bin2bcd(&msf.cdmsf_min0);
1345
                  azt_bin2bcd(&msf.cdmsf_sec0);
1346
                  azt_bin2bcd(&msf.cdmsf_frame0);
1347
                  msf.cdmsf_min1=0;
1348
                  msf.cdmsf_sec1=0;
1349
                  msf.cdmsf_frame1=1; /*read only one frame*/
1350
                  azt_Play.start.min = msf.cdmsf_min0;
1351
                  azt_Play.start.sec = msf.cdmsf_sec0;
1352
                  azt_Play.start.frame = msf.cdmsf_frame0;
1353
                  azt_Play.end.min = msf.cdmsf_min1;
1354
                  azt_Play.end.sec = msf.cdmsf_sec1;
1355
                  azt_Play.end.frame = msf.cdmsf_frame1;
1356
                  if (cmd==CDROMREADRAW)
1357
                  { if (DiskInfo.xa)
1358
                       { return -1;         /*XA Disks can't be read raw*/
1359
                       }
1360
                    else
1361
                       { if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play)) return -1;
1362
                         DTEN_LOW;
1363
                         insb(DATA_PORT,buf,CD_FRAMESIZE_RAW);
1364
                         memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE_RAW);
1365
                       }
1366
                  }
1367
                  else /*CDROMREADCOOKED*/
1368
                  { if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) return -1;
1369
                    DTEN_LOW;
1370
                    insb(DATA_PORT,buf,CD_FRAMESIZE);
1371
                    memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE);
1372
                  }
1373
                 }
1374
                break;
1375
        case CDROMSEEK:    /*seek msf address*/
1376
                st = verify_area(VERIFY_READ,  (void *) arg, sizeof msf);
1377
                if (st) return st;
1378
                memcpy_fromfs(&msf, (void *) arg, sizeof msf);
1379
                /* convert to bcd */
1380
                azt_bin2bcd(&msf.cdmsf_min0);
1381
                azt_bin2bcd(&msf.cdmsf_sec0);
1382
                azt_bin2bcd(&msf.cdmsf_frame0);
1383
                azt_Play.start.min = msf.cdmsf_min0;
1384
                azt_Play.start.sec = msf.cdmsf_sec0;
1385
                azt_Play.start.frame = msf.cdmsf_frame0;
1386
                if (aztSeek(&azt_Play)) return -1;
1387
                break;
1388
#endif /*end of incompatible code*/       
1389
        case CDROMREADMODE1: /*set read data in mode 1*/
1390
                return aztSetDiskType(AZT_MODE_1);
1391
        case CDROMREADMODE2: /*set read data in mode 2*/
1392
                return aztSetDiskType(AZT_MODE_2);
1393
        default:
1394
                return -EINVAL;
1395
        }
1396
#ifdef AZT_DEBUG
1397
        printk("aztcd: exiting aztcd_ioctl Command:%x  Time:%li\n",cmd,jiffies);
1398
#endif
1399
        return 0;
1400
}
1401
 
1402
/*
1403
 * Take care of the different block sizes between cdrom and Linux.
1404
 * When Linux gets variable block sizes this will probably go away.
1405
 */
1406
static void azt_transfer(void)
1407
{
1408
#ifdef AZT_TEST
1409
  printk("aztcd: executing azt_transfer Time:%li\n",jiffies);
1410
#endif
1411
  if (CURRENT_VALID) {
1412
    while (CURRENT -> nr_sectors) {
1413
      int bn = CURRENT -> sector / 4;
1414
      int i;
1415
      for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i)
1416
        ;
1417
      if (i < AZT_BUF_SIZ) {
1418
        int offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
1419
        int nr_sectors = 4 - (CURRENT -> sector & 3);
1420
        if (azt_buf_out != i) {
1421
          azt_buf_out = i;
1422
          if (azt_buf_bn[i] != bn) {
1423
            azt_buf_out = -1;
1424
            continue;
1425
          }
1426
        }
1427
        if (nr_sectors > CURRENT -> nr_sectors)
1428
          nr_sectors = CURRENT -> nr_sectors;
1429
        memcpy(CURRENT -> buffer, azt_buf + offs, nr_sectors * 512);
1430
        CURRENT -> nr_sectors -= nr_sectors;
1431
        CURRENT -> sector += nr_sectors;
1432
        CURRENT -> buffer += nr_sectors * 512;
1433
      } else {
1434
        azt_buf_out = -1;
1435
        break;
1436
      }
1437
    }
1438
  }
1439
}
1440
 
1441
static void do_aztcd_request(void)
1442
{
1443
#ifdef AZT_TEST
1444
  printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT -> sector, CURRENT -> nr_sectors,jiffies);
1445
#endif
1446
  if (DiskInfo.audio)
1447
    { printk("aztcd: Error, tried to mount an Audio CD\n");
1448
      end_request(0);
1449
      return;
1450
    }
1451
  azt_transfer_is_active = 1;
1452
  while (CURRENT_VALID) {
1453
    if (CURRENT->bh) {
1454
      if (!buffer_locked(CURRENT->bh))
1455
        panic(DEVICE_NAME ": block not locked");
1456
    }
1457
    azt_transfer();
1458
    if (CURRENT -> nr_sectors == 0) {
1459
      end_request(1);
1460
    } else {
1461
      azt_buf_out = -1;         /* Want to read a block not in buffer */
1462
      if (azt_state == AZT_S_IDLE) {
1463
        if ((!aztTocUpToDate)||aztDiskChanged) {
1464
          if (aztUpdateToc() < 0) {
1465
            while (CURRENT_VALID)
1466
              end_request(0);
1467
            break;
1468
          }
1469
        }
1470
        azt_state = AZT_S_START;
1471
        AztTries = 5;
1472
        SET_TIMER(azt_poll, HZ/100);
1473
      }
1474
      break;
1475
    }
1476
  }
1477
  azt_transfer_is_active = 0;
1478
#ifdef AZT_TEST2
1479
  printk("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n", \
1480
          azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1481
  printk(" do_aztcd_request ends  Time:%li\n",jiffies);
1482
#endif
1483
}
1484
 
1485
 
1486
static void azt_invalidate_buffers(void)
1487
{ int i;
1488
 
1489
#ifdef AZT_DEBUG
1490
  printk("aztcd: executing azt_invalidate_buffers\n");
1491
#endif
1492
  for (i = 0; i < AZT_BUF_SIZ; ++i)
1493
    azt_buf_bn[i] = -1;
1494
  azt_buf_out = -1;
1495
}
1496
 
1497
/*
1498
 * Open the device special file.  Check that a disk is in.
1499
 */
1500
int aztcd_open(struct inode *ip, struct file *fp)
1501
{       int st;
1502
 
1503
#ifdef AZT_DEBUG
1504
        printk("aztcd: starting aztcd_open\n");
1505
#endif
1506
        if (aztPresent == 0)
1507
                return -ENXIO;                  /* no hardware */
1508
 
1509
        if (!azt_open_count && azt_state == AZT_S_IDLE)
1510
          { azt_invalidate_buffers();
1511
 
1512
            st = getAztStatus();                    /* check drive status */
1513
            if (st == -1) return -EIO;              /* drive doesn't respond */
1514
 
1515
            if (st & AST_DOOR_OPEN)
1516
               { /* close door, then get the status again. */
1517
                 printk("aztcd: Door Open?\n");
1518
                 aztCloseDoor();
1519
                 st = getAztStatus();
1520
               }
1521
 
1522
            if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) /*no disk in drive or changed*/
1523
               { printk("aztcd: Disk Changed or No Disk in Drive?\n");
1524
                 aztTocUpToDate=0;
1525
               }
1526
            if (aztUpdateToc()) return -EIO;
1527
 
1528
          }
1529
        ++azt_open_count;
1530
        MOD_INC_USE_COUNT;
1531
        aztLockDoor();
1532
 
1533
 
1534
#ifdef AZT_DEBUG
1535
        printk("aztcd: exiting aztcd_open\n");
1536
#endif
1537
        return 0;
1538
}
1539
 
1540
 
1541
/*
1542
 * On close, we flush all azt blocks from the buffer cache.
1543
 */
1544
static void aztcd_release(struct inode * inode, struct file * file)
1545
{
1546
#ifdef AZT_DEBUG
1547
  printk("aztcd: executing aztcd_release\n");
1548
  printk("inode: %p, inode->i_rdev: %x    file: %p\n",inode,inode->i_rdev,file);
1549
#endif
1550
  MOD_DEC_USE_COUNT;
1551
  if (!--azt_open_count) {
1552
        azt_invalidate_buffers();
1553
        sync_dev(inode->i_rdev);             /*??? isn't it a read only dev?*/
1554
        invalidate_buffers(inode -> i_rdev);
1555
        aztUnlockDoor();
1556
        if (azt_auto_eject)
1557
           aztSendCmd(ACMD_EJECT);
1558
        CLEAR_TIMER;
1559
  }
1560
  return;
1561
}
1562
 
1563
 
1564
 
1565
/*
1566
 * Test for presence of drive and initialize it.  Called at boot time.
1567
 */
1568
 
1569
int aztcd_init(void)
1570
{       long int count, max_count;
1571
        unsigned char result[50];
1572
        int st;
1573
 
1574
        if (azt_port <= 0) {
1575
          printk("aztcd: no Aztech CD-ROM Initialization");
1576
          return -EIO;
1577
        }
1578
        printk("aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM CD-ROM Driver\n");
1579
        printk("aztcd: (C) 1994-96 W.Zimmermann\n");
1580
        printk("aztcd: DriverVersion=%s BaseAddress=0x%x  For IDE/ATAPI-drives use ide-cd.c\n",AZT_VERSION,azt_port);
1581
        printk("aztcd: If you have problems, read /usr/src/linux/Documentation/cdrom/aztcd\n");
1582
 
1583
        if ((azt_port==0x1f0)||(azt_port==0x170))
1584
          st = check_region(azt_port, 8);  /*IDE-interfaces need 8 bytes*/
1585
        else
1586
          st = check_region(azt_port, 4);  /*proprietary interfaces need 4 bytes*/
1587
        if (st)
1588
        { printk("aztcd: conflict, I/O port (%X) already used\n",azt_port);
1589
          return -EIO;
1590
        }
1591
 
1592
#ifdef AZT_SW32   /*CDROM connected to Soundwave32 card*/
1593
        if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500)
1594
           { printk("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1595
                 AZT_SW32_BASE_ADDR,AZT_SW32_INIT,AZT_SW32_CONFIG_REG,AZT_SW32_ID_REG);
1596
                 return -EIO;
1597
           }
1598
        else
1599
           { printk(KERN_INFO "aztcd: Soundwave32 card detected at %x  Version %x\n",
1600
                 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1601
             outw(AZT_SW32_INIT,AZT_SW32_CONFIG_REG);
1602
             for (count=0;count<10000;count++);          /*delay a bit*/
1603
           }
1604
#endif  
1605
 
1606
        /* check for presence of drive */
1607
 
1608
        if ((azt_port==0x1f0)||(azt_port==0x170))
1609
            SWITCH_IDE_SLAVE;  /*switch IDE interface to slave configuration*/
1610
 
1611
        outb(POLLED,MODE_PORT);
1612
        inb(CMD_PORT);
1613
        inb(CMD_PORT);
1614
        outb(ACMD_GET_VERSION,CMD_PORT); /*Try to get version info*/
1615
 
1616
/*      STEN_LOW  - special implementation for drive recognition
1617
*/      aztTimeOutCount=0;
1618
        do { aztIndatum=inb(STATUS_PORT);
1619
             aztTimeOutCount++;
1620
             if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break;
1621
           } while (aztIndatum&AFL_STATUS);
1622
 
1623
        if (inb(DATA_PORT)!=AFL_OP_OK) /*OP_OK? If not, reset and try again*/
1624
           {
1625
#ifndef MODULE
1626
             if (azt_cont!=0x79)
1627
                { printk("aztcd: no AZTECH CD-ROM drive found-Try boot parameter aztcd=<BaseAddress>,0x79\n");
1628
                  return -EIO;
1629
                }
1630
#else        
1631
             if (0)
1632
                {
1633
                }
1634
#endif       
1635
             else
1636
                { printk("aztcd: drive reset - please wait\n");
1637
                  for (count=0;count<50;count++)
1638
                    { inb(STATUS_PORT);    /*removing all data from earlier tries*/
1639
                      inb(DATA_PORT);
1640
                    }
1641
                  outb(POLLED,MODE_PORT);
1642
                  inb(CMD_PORT);
1643
                  inb(CMD_PORT);
1644
                  getAztStatus();                   /*trap errors*/
1645
                  outb(ACMD_SOFT_RESET,CMD_PORT);   /*send reset*/
1646
                  STEN_LOW;
1647
                  if (inb(DATA_PORT)!=AFL_OP_OK)    /*OP_OK?*/
1648
                     { printk("aztcd: no AZTECH CD-ROM drive found\n");
1649
                       return -EIO;
1650
                     }
1651
                  for (count = 0; count < AZT_TIMEOUT; count++);
1652
                     { count=count*2;          /* delay a bit */
1653
                       count=count/2;
1654
                     }
1655
                  if ((st=getAztStatus())==-1)
1656
                     { printk("aztcd: Drive Status Error Status=%x\n",st);
1657
                       return -EIO;
1658
                     }
1659
#ifdef AZT_DEBUG
1660
                  printk("aztcd: Status = %x\n",st);
1661
#endif
1662
                  outb(POLLED,MODE_PORT);
1663
                  inb(CMD_PORT);
1664
                  inb(CMD_PORT);
1665
                  outb(ACMD_GET_VERSION,CMD_PORT); /*GetVersion*/
1666
                  STEN_LOW;
1667
                  OP_OK;
1668
                }
1669
           }
1670
        azt_init_end=1;
1671
        STEN_LOW;
1672
        result[0]=inb(DATA_PORT);        /*reading in a null byte???*/
1673
        for (count=1;count<50;count++)   /*Reading version string*/
1674
         { aztTimeOutCount=0;            /*here we must implement STEN_LOW differently*/
1675
           do { aztIndatum=inb(STATUS_PORT);/*because we want to exit by timeout*/
1676
                aztTimeOutCount++;
1677
                if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break;
1678
              } while (aztIndatum&AFL_STATUS);
1679
           if (aztTimeOutCount>=AZT_FAST_TIMEOUT) break;  /*all chars read?*/
1680
           result[count]=inb(DATA_PORT);
1681
         }
1682
        if (count>30) max_count=30;  /*print max.30 chars of the version string*/
1683
        else          max_count=count;
1684
        printk(KERN_INFO "aztcd: FirmwareVersion=");
1685
        for (count=1;count<max_count;count++) printk("%c",result[count]);
1686
        printk("<<>> ");
1687
 
1688
        if ((result[1]=='A')&&(result[2]=='Z')&&(result[3]=='T'))
1689
         { printk("AZTECH drive detected\n"); /*AZTECH*/
1690
         }
1691
        else if ((result[2]=='C')&&(result[3]=='D')&&(result[4]=='D'))
1692
         { printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES*/
1693
         }
1694
        else if ((result[1]==0x03)&&(result[2]=='5'))
1695
         { printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM*/
1696
         }
1697
        else                                             /*OTHERS or none*/
1698
         { printk("\nunknown drive or firmware version detected\n");
1699
           printk("aztcd may not run stable, if you want to try anyhow,\n");
1700
           printk("boot with: aztcd=<BaseAddress>,0x79\n");
1701
           if ((azt_cont!=0x79))
1702
             { printk("aztcd: FirmwareVersion=");
1703
               for (count=1;count<5;count++) printk("%c",result[count]);
1704
               printk("<<>> ");
1705
               printk("Aborted\n");
1706
               return -EIO;
1707
             }
1708
         }
1709
        if (register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0)
1710
        {
1711
                printk("aztcd: Unable to get major %d for Aztech CD-ROM\n",
1712
                       MAJOR_NR);
1713
                return -EIO;
1714
        }
1715
        blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
1716
        read_ahead[MAJOR_NR] = 4;
1717
 
1718
        if ((azt_port==0x1f0)||(azt_port==0x170))
1719
           request_region(azt_port, 8, "aztcd");  /*IDE-interface*/
1720
        else
1721
           request_region(azt_port, 4, "aztcd");  /*proprietary interface*/
1722
 
1723
        azt_invalidate_buffers();
1724
        aztPresent = 1;
1725
        aztCloseDoor();
1726
/*      printk("aztcd: End Init\n");
1727
*/      return (0);
1728
}
1729
 
1730
#ifdef MODULE
1731
 
1732
int init_module(void)
1733
{
1734
        return aztcd_init();
1735
}
1736
 
1737
void cleanup_module(void)
1738
{
1739
  if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL))
1740
    { printk("What's that: can't unregister aztcd\n");
1741
      return;
1742
    }
1743
  if ((azt_port==0x1f0)||(azt_port==0x170))
1744
    { SWITCH_IDE_MASTER;
1745
      release_region(azt_port,8);  /*IDE-interface*/
1746
    }
1747
  else
1748
      release_region(azt_port,4);  /*proprietary interface*/
1749
  printk(KERN_INFO "aztcd module released.\n");
1750
}
1751
#endif MODULE
1752
 
1753
 
1754
/*##########################################################################
1755
  Aztcd State Machine: Controls Drive Operating State
1756
  ##########################################################################
1757
*/
1758
static void azt_poll(void)
1759
{
1760
    int st = 0;
1761
    int loop_ctl = 1;
1762
    int skip = 0;
1763
 
1764
    if (azt_error) {
1765
        if (aztSendCmd(ACMD_GET_ERROR)) RETURN("azt_poll 1");
1766
        STEN_LOW;
1767
        azt_error=inb(DATA_PORT)&0xFF;
1768
        printk("aztcd: I/O error 0x%02x\n", azt_error);
1769
        azt_invalidate_buffers();
1770
#ifdef WARN_IF_READ_FAILURE
1771
        if (AztTries == 5)
1772
          printk("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n", azt_next_bn);
1773
#endif
1774
        if (!AztTries--) {
1775
          printk("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n", azt_next_bn);
1776
          if (azt_transfer_is_active) {
1777
            AztTries = 0;
1778
            loop_ctl = 0;
1779
          }
1780
          if (CURRENT_VALID)
1781
            end_request(0);
1782
          AztTries = 5;
1783
        }
1784
    azt_error = 0;
1785
    azt_state = AZT_S_STOP;
1786
    }
1787
 
1788
    while (loop_ctl)
1789
    {
1790
      loop_ctl = 0;   /* each case must flip this back to 1 if we want
1791
                         to come back up here */
1792
      switch (azt_state) {
1793
 
1794
        case AZT_S_IDLE:
1795
#ifdef AZT_TEST3
1796
          if (azt_state!=azt_state_old) {
1797
            azt_state_old=azt_state;
1798
            printk("AZT_S_IDLE\n");
1799
            }
1800
#endif
1801
          return;
1802
 
1803
        case AZT_S_START:
1804
#ifdef AZT_TEST3
1805
          if (azt_state!=azt_state_old) {
1806
            azt_state_old=azt_state;
1807
            printk("AZT_S_START\n");
1808
          }
1809
#endif
1810
          if(aztSendCmd(ACMD_GET_STATUS)) RETURN("azt_poll 2");  /*result will be checked by aztStatus() */
1811
          azt_state = azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
1812
          AztTimeout = 3000;
1813
          break;
1814
 
1815
        case AZT_S_MODE:
1816
#ifdef AZT_TEST3
1817
          if (azt_state!=azt_state_old) {
1818
            azt_state_old=azt_state;
1819
            printk("AZT_S_MODE\n");
1820
          }
1821
#endif
1822
          if (!skip) {
1823
            if ((st = aztStatus()) != -1) {
1824
              if ((st & AST_DSK_CHG)||(st & AST_NOT_READY)) {
1825
                aztDiskChanged = 1;
1826
                aztTocUpToDate = 0;
1827
                azt_invalidate_buffers();
1828
                end_request(0);
1829
                printk("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
1830
              }
1831
            } else break;
1832
          }
1833
          skip = 0;
1834
 
1835
          if ((st & AST_DOOR_OPEN)||(st & AST_NOT_READY)) {
1836
            aztDiskChanged = 1;
1837
            aztTocUpToDate = 0;
1838
            printk("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
1839
            end_request(0);
1840
            printk((st & AST_DOOR_OPEN) ? "aztcd: door open\n" : "aztcd: disk removed\n");
1841
            if (azt_transfer_is_active) {
1842
              azt_state = AZT_S_START;
1843
              loop_ctl = 1;   /* goto immediately */
1844
              break;
1845
            }
1846
            azt_state = AZT_S_IDLE;
1847
            while (CURRENT_VALID)
1848
              end_request(0);
1849
            return;
1850
          }
1851
 
1852
/*        if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
1853
          outb(0x01, DATA_PORT);
1854
          PA_OK;
1855
          STEN_LOW;
1856
*/        if (aztSendCmd(ACMD_GET_STATUS)) RETURN("azt_poll 4");
1857
          STEN_LOW;
1858
          azt_mode = 1;
1859
          azt_state = AZT_S_READ;
1860
          AztTimeout = 3000;
1861
 
1862
          break;
1863
 
1864
 
1865
        case AZT_S_READ:
1866
#ifdef AZT_TEST3
1867
          if (azt_state!=azt_state_old)  {
1868
            azt_state_old=azt_state;
1869
            printk("AZT_S_READ\n");
1870
          }
1871
#endif
1872
          if (!skip) {
1873
              if ((st = aztStatus()) != -1) {
1874
                if ((st & AST_DSK_CHG)||(st & AST_NOT_READY)) {
1875
                aztDiskChanged = 1;
1876
                aztTocUpToDate = 0;
1877
                azt_invalidate_buffers();
1878
                printk("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
1879
                end_request(0);
1880
                }
1881
              } else break;
1882
          }
1883
 
1884
          skip = 0;
1885
          if ((st & AST_DOOR_OPEN)||(st & AST_NOT_READY)) {
1886
            aztDiskChanged = 1;
1887
            aztTocUpToDate = 0;
1888
            printk((st & AST_DOOR_OPEN) ? "aztcd: door open\n" : "aztcd: disk removed\n");
1889
            if (azt_transfer_is_active) {
1890
              azt_state = AZT_S_START;
1891
              loop_ctl = 1;
1892
              break;
1893
            }
1894
            azt_state = AZT_S_IDLE;
1895
            while (CURRENT_VALID)
1896
            end_request(0);
1897
            return;
1898
          }
1899
 
1900
          if (CURRENT_VALID) {
1901
            struct azt_Play_msf msf;
1902
            int i;
1903
            azt_next_bn = CURRENT -> sector / 4;
1904
            azt_hsg2msf(azt_next_bn, &msf.start);
1905
            i = 0;
1906
            /* find out in which track we are */
1907
            while (azt_msf2hsg(&msf.start)>azt_msf2hsg(&Toc[++i].trackTime)) {};
1908
            if (azt_msf2hsg(&msf.start)<azt_msf2hsg(&Toc[i].trackTime)-AZT_BUF_SIZ)
1909
               { azt_read_count=AZT_BUF_SIZ;  /*fast, because we read ahead*/
1910
               /*azt_read_count=CURRENT->nr_sectors;    slow, no read ahead*/
1911
               }
1912
            else /* don't read beyond end of track */
1913
#if AZT_MULTISESSION 
1914
               { azt_read_count=(azt_msf2hsg(&Toc[i].trackTime)/4)*4-azt_msf2hsg(&msf.start);
1915
                 if (azt_read_count < 0) azt_read_count=0;
1916
                 if (azt_read_count > AZT_BUF_SIZ) azt_read_count=AZT_BUF_SIZ;
1917
                 printk("aztcd: warning - trying to read beyond end of track\n");
1918
/*               printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
1919
*/             }
1920
#else
1921
               { azt_read_count=AZT_BUF_SIZ;
1922
               }
1923
#endif
1924
            msf.end.min = 0;
1925
            msf.end.sec = 0;
1926
            msf.end.frame = azt_read_count ;/*Mitsumi here reads 0xffffff sectors*/
1927
#ifdef AZT_TEST3
1928
            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);
1929
            printk("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n", \
1930
                    azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1931
#endif 
1932
            if (azt_read_mode==AZT_MODE_2)
1933
               { sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode*/
1934
               }
1935
            else
1936
               { sendAztCmd(ACMD_PLAY_READ, &msf);     /*others in cooked mode*/
1937
               }
1938
            azt_state = AZT_S_DATA;
1939
            AztTimeout = READ_TIMEOUT;
1940
          } else {
1941
            azt_state = AZT_S_STOP;
1942
            loop_ctl = 1;
1943
            break;
1944
          }
1945
 
1946
          break;
1947
 
1948
 
1949
        case AZT_S_DATA:
1950
#ifdef AZT_TEST3
1951
          if (azt_state!=azt_state_old)  {
1952
            azt_state_old=azt_state;
1953
            printk("AZT_S_DATA\n");
1954
          }
1955
#endif
1956
 
1957
          st = inb(STATUS_PORT) & AFL_STATUSorDATA;
1958
 
1959
          switch (st) {
1960
 
1961
            case AFL_DATA:
1962
#ifdef AZT_TEST3
1963
              if (st!=azt_st_old)  {
1964
                azt_st_old=st;
1965
                printk("---AFL_DATA st:%x\n",st);
1966
              }
1967
#endif
1968
              if (!AztTries--) {
1969
                printk("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n", azt_next_bn);
1970
                if (azt_transfer_is_active) {
1971
                  AztTries = 0;
1972
                  break;
1973
                }
1974
                if (CURRENT_VALID)
1975
                  end_request(0);
1976
                AztTries = 5;
1977
              }
1978
              azt_state = AZT_S_START;
1979
              AztTimeout = READ_TIMEOUT;
1980
              loop_ctl = 1;
1981
              break;
1982
 
1983
            case AFL_STATUSorDATA:
1984
#ifdef AZT_TEST3
1985
              if (st!=azt_st_old)  {
1986
                azt_st_old=st;
1987
                printk("---AFL_STATUSorDATA st:%x\n",st);
1988
              }
1989
#endif
1990
              break;
1991
 
1992
            default:
1993
#ifdef AZT_TEST3
1994
              if (st!=azt_st_old)  {
1995
                azt_st_old=st;
1996
                printk("---default: st:%x\n",st);
1997
              }
1998
#endif
1999
              AztTries = 5;
2000
              if (!CURRENT_VALID && azt_buf_in == azt_buf_out) {
2001
                azt_state = AZT_S_STOP;
2002
                loop_ctl = 1;
2003
                break;
2004
              }
2005
              if (azt_read_count<=0)
2006
                printk("aztcd: warning - try to read 0 frames\n");
2007
              while (azt_read_count)      /*??? fast read ahead loop*/
2008
               { azt_buf_bn[azt_buf_in] = -1;
2009
                 DTEN_LOW;                      /*??? unsolved problem, very
2010
                                                      seldom we get timeouts
2011
                                                      here, don't now the real
2012
                                                      reason. With my drive this
2013
                                                      sometimes also happens with
2014
                                                      Aztech's original driver under
2015
                                                      DOS. Is it a hardware bug?
2016
                                                      I tried to recover from such
2017
                                                      situations here. Zimmermann*/
2018
                 if (aztTimeOutCount>=AZT_TIMEOUT)
2019
                  { printk("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n", azt_read_count,CURRENT->nr_sectors,azt_buf_in);
2020
                    printk("azt_transfer_is_active:%x\n",azt_transfer_is_active);
2021
                    azt_read_count=0;
2022
                    azt_state = AZT_S_STOP;
2023
                    loop_ctl = 1;
2024
                    end_request(1);  /*should we have here (1) or (0)? */
2025
                  }
2026
                 else
2027
                  { if (azt_read_mode==AZT_MODE_2)
2028
                       { insb(DATA_PORT, azt_buf + CD_FRAMESIZE_RAW * azt_buf_in, CD_FRAMESIZE_RAW);
2029
                       }
2030
                    else
2031
                       { insb(DATA_PORT, azt_buf + CD_FRAMESIZE * azt_buf_in, CD_FRAMESIZE);
2032
                       }
2033
                    azt_read_count--;
2034
#ifdef AZT_TEST3
2035
                    printk("AZT_S_DATA; ---I've read data- read_count: %d\n",azt_read_count);
2036
                    printk("azt_next_bn:%d  azt_buf_in:%d azt_buf_out:%d  azt_buf_bn:%d\n", \
2037
                         azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
2038
#endif
2039
                    azt_buf_bn[azt_buf_in] = azt_next_bn++;
2040
                    if (azt_buf_out == -1)
2041
                      azt_buf_out = azt_buf_in;
2042
                    azt_buf_in = azt_buf_in + 1 == AZT_BUF_SIZ ? 0 : azt_buf_in + 1;
2043
                  }
2044
               }
2045
              if (!azt_transfer_is_active) {
2046
                while (CURRENT_VALID) {
2047
                  azt_transfer();
2048
                  if (CURRENT -> nr_sectors == 0)
2049
                    end_request(1);
2050
                  else
2051
                    break;
2052
                }
2053
              }
2054
 
2055
              if (CURRENT_VALID
2056
                && (CURRENT -> sector / 4 < azt_next_bn ||
2057
                CURRENT -> sector / 4 > azt_next_bn + AZT_BUF_SIZ)) {
2058
                azt_state = AZT_S_STOP;
2059
                loop_ctl = 1;
2060
                break;
2061
              }
2062
              AztTimeout = READ_TIMEOUT;
2063
              if (azt_read_count==0) {
2064
                azt_state = AZT_S_STOP;
2065
                loop_ctl = 1;
2066
                break;
2067
              }
2068
              break;
2069
            }
2070
    break;
2071
 
2072
 
2073
        case AZT_S_STOP:
2074
#ifdef AZT_TEST3
2075
          if (azt_state!=azt_state_old) {
2076
            azt_state_old=azt_state;
2077
            printk("AZT_S_STOP\n");
2078
          }
2079
#endif
2080
          if (azt_read_count!=0) printk("aztcd: discard data=%x frames\n",azt_read_count);
2081
          while (azt_read_count!=0) {
2082
            int i;
2083
            if ( !(inb(STATUS_PORT) & AFL_DATA) ) {
2084
              if (azt_read_mode==AZT_MODE_2)
2085
                 for (i=0; i<CD_FRAMESIZE_RAW; i++) inb(DATA_PORT);
2086
              else
2087
                 for (i=0; i<CD_FRAMESIZE; i++) inb(DATA_PORT);
2088
            }
2089
            azt_read_count--;
2090
          }
2091
          if (aztSendCmd(ACMD_GET_STATUS)) RETURN("azt_poll 5");
2092
          azt_state = AZT_S_STOPPING;
2093
          AztTimeout = 1000;
2094
          break;
2095
 
2096
        case AZT_S_STOPPING:
2097
#ifdef AZT_TEST3
2098
          if (azt_state!=azt_state_old) {
2099
            azt_state_old=azt_state;
2100
            printk("AZT_S_STOPPING\n");
2101
          }
2102
#endif
2103
 
2104
          if ((st = aztStatus()) == -1 && AztTimeout)
2105
            break;
2106
 
2107
          if ((st != -1) && ((st & AST_DSK_CHG)||(st & AST_NOT_READY))) {
2108
            aztDiskChanged = 1;
2109
            aztTocUpToDate = 0;
2110
            azt_invalidate_buffers();
2111
            printk("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2112
            end_request(0);
2113
          }
2114
 
2115
 
2116
#ifdef AZT_TEST3
2117
          printk("CURRENT_VALID %d azt_mode %d\n",
2118
             CURRENT_VALID, azt_mode);
2119
#endif
2120
 
2121
          if (CURRENT_VALID) {
2122
            if (st != -1) {
2123
              if (azt_mode == 1) {
2124
                azt_state = AZT_S_READ;
2125
                loop_ctl = 1;
2126
                skip = 1;
2127
                break;
2128
              } else {
2129
                azt_state = AZT_S_MODE;
2130
                loop_ctl = 1;
2131
                skip = 1;
2132
                break;
2133
              }
2134
            } else {
2135
              azt_state = AZT_S_START;
2136
              AztTimeout = 1;
2137
            }
2138
          } else {
2139
            azt_state = AZT_S_IDLE;
2140
            return;
2141
          }
2142
          break;
2143
 
2144
        default:
2145
          printk("aztcd: invalid state %d\n", azt_state);
2146
          return;
2147
      }  /* case */
2148
    } /* while */
2149
 
2150
 
2151
   if (!AztTimeout--)
2152
    { printk("aztcd: timeout in state %d\n", azt_state);
2153
      azt_state = AZT_S_STOP;
2154
      if (aztSendCmd(ACMD_STOP)) RETURN("azt_poll 6");
2155
      STEN_LOW_WAIT;
2156
    };
2157
 
2158
  SET_TIMER(azt_poll, HZ/100);
2159
}
2160
 
2161
 
2162
/*###########################################################################
2163
 * Miscellaneous support functions
2164
  ###########################################################################
2165
*/
2166
static void azt_hsg2msf(long hsg, struct msf *msf)
2167
{       hsg += 150;
2168
        msf -> min = hsg / 4500;
2169
        hsg %= 4500;
2170
        msf -> sec = hsg / 75;
2171
        msf -> frame = hsg % 75;
2172
#ifdef AZT_DEBUG
2173
        if (msf->min  >=70) printk("aztcd: Error hsg2msf address Minutes\n");
2174
        if (msf->sec  >=60) printk("aztcd: Error hsg2msf address Seconds\n");
2175
        if (msf->frame>=75) printk("aztcd: Error hsg2msf address Frames\n");
2176
#endif
2177
        azt_bin2bcd(&msf -> min);           /* convert to BCD */
2178
        azt_bin2bcd(&msf -> sec);
2179
        azt_bin2bcd(&msf -> frame);
2180
}
2181
 
2182
static long azt_msf2hsg(struct msf *mp)
2183
{ return azt_bcd2bin(mp -> frame) + azt_bcd2bin(mp -> sec) * 75
2184
                                  + azt_bcd2bin(mp -> min) * 4500 - CD_BLOCK_OFFSET;
2185
}
2186
 
2187
static void azt_bin2bcd(unsigned char *p)
2188
{       int u, t;
2189
 
2190
        u = *p % 10;
2191
        t = *p / 10;
2192
        *p = u | (t << 4);
2193
}
2194
 
2195
static int azt_bcd2bin(unsigned char bcd)
2196
{       return (bcd >> 4) * 10 + (bcd & 0xF);
2197
}
2198
 
2199
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.