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