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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [cdrom/] [aztcd.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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