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