patch-2_6_7-vs1_9_1_12
[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(void)
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         void __user *argp = (void __user *)arg;
1171
1172 #ifdef AZT_DEBUG
1173         printk("aztcd: starting aztcd_ioctl - Command:%x   Time: %li\n",
1174                cmd, jiffies);
1175         printk("aztcd Status %x\n", getAztStatus());
1176 #endif
1177         if (!ip)
1178                 RETURNM("aztcd_ioctl 1", -EINVAL);
1179         if (getAztStatus() < 0)
1180                 RETURNM("aztcd_ioctl 2", -EIO);
1181         if ((!aztTocUpToDate) || (aztDiskChanged)) {
1182                 if ((i = aztUpdateToc()) < 0)
1183                         RETURNM("aztcd_ioctl 3", i);    /* error reading TOC */
1184         }
1185
1186         switch (cmd) {
1187         case CDROMSTART:        /* Spin up the drive. Don't know, what to do,
1188                                    at least close the tray */
1189 #if AZT_PRIVATE_IOCTLS
1190                 if (aztSendCmd(ACMD_CLOSE))
1191                         RETURNM("aztcd_ioctl 4", -1);
1192                 STEN_LOW_WAIT;
1193 #endif
1194                 break;
1195         case CDROMSTOP: /* Spin down the drive */
1196                 if (aztSendCmd(ACMD_STOP))
1197                         RETURNM("aztcd_ioctl 5", -1);
1198                 STEN_LOW_WAIT;
1199                 /* should we do anything if it fails? */
1200                 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1201                 break;
1202         case CDROMPAUSE:        /* Pause the drive */
1203                 if (aztAudioStatus != CDROM_AUDIO_PLAY)
1204                         return -EINVAL;
1205
1206                 if (aztGetQChannelInfo(&qInfo) < 0) {   /* didn't get q channel info */
1207                         aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1208                         RETURNM("aztcd_ioctl 7", 0);
1209                 }
1210                 azt_Play.start = qInfo.diskTime;        /* remember restart point */
1211
1212                 if (aztSendCmd(ACMD_PAUSE))
1213                         RETURNM("aztcd_ioctl 8", -1);
1214                 STEN_LOW_WAIT;
1215                 aztAudioStatus = CDROM_AUDIO_PAUSED;
1216                 break;
1217         case CDROMRESUME:       /* Play it again, Sam */
1218                 if (aztAudioStatus != CDROM_AUDIO_PAUSED)
1219                         return -EINVAL;
1220                 /* restart the drive at the saved position. */
1221                 i = aztPlay(&azt_Play);
1222                 if (i < 0) {
1223                         aztAudioStatus = CDROM_AUDIO_ERROR;
1224                         return -EIO;
1225                 }
1226                 aztAudioStatus = CDROM_AUDIO_PLAY;
1227                 break;
1228         case CDROMMULTISESSION: /*multisession support -- experimental */
1229                 {
1230                         struct cdrom_multisession ms;
1231 #ifdef AZT_DEBUG
1232                         printk("aztcd ioctl MULTISESSION\n");
1233 #endif
1234                         if (copy_from_user(&ms, argp,
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(argp, &ms,
1252                              sizeof(struct cdrom_multisession)))
1253                                 return -EFAULT;
1254 #ifdef AZT_DEBUG
1255                         if (ms.addr_format == CDROM_MSF)
1256                                 printk
1257                                     ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1258                                      ms.xa_flag, ms.addr.msf.minute,
1259                                      ms.addr.msf.second, ms.addr.msf.frame,
1260                                      DiskInfo.lastSession.min,
1261                                      DiskInfo.lastSession.sec,
1262                                      DiskInfo.lastSession.frame);
1263                         else
1264                                 printk
1265                                     ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1266                                      ms.xa_flag, ms.addr.lba,
1267                                      DiskInfo.lastSession.min,
1268                                      DiskInfo.lastSession.sec,
1269                                      DiskInfo.lastSession.frame);
1270 #endif
1271                         return 0;
1272                 }
1273         case CDROMPLAYTRKIND:   /* Play a track.  This currently ignores index. */
1274                 if (copy_from_user(&ti, argp, sizeof ti))
1275                         return -EFAULT;
1276                 if (ti.cdti_trk0 < DiskInfo.first
1277                     || ti.cdti_trk0 > DiskInfo.last
1278                     || ti.cdti_trk1 < ti.cdti_trk0) {
1279                         return -EINVAL;
1280                 }
1281                 if (ti.cdti_trk1 > DiskInfo.last)
1282                         ti.cdti_trk1 = DiskInfo.last;
1283                 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
1284                 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
1285 #ifdef AZT_DEBUG
1286                 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1287                        azt_Play.start.min, azt_Play.start.sec,
1288                        azt_Play.start.frame, azt_Play.end.min,
1289                        azt_Play.end.sec, azt_Play.end.frame);
1290 #endif
1291                 i = aztPlay(&azt_Play);
1292                 if (i < 0) {
1293                         aztAudioStatus = CDROM_AUDIO_ERROR;
1294                         return -EIO;
1295                 }
1296                 aztAudioStatus = CDROM_AUDIO_PLAY;
1297                 break;
1298         case CDROMPLAYMSF:      /* Play starting at the given MSF address. */
1299 /*              if (aztAudioStatus == CDROM_AUDIO_PLAY) 
1300                 { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1301                   STEN_LOW;
1302                   aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1303                 }
1304 */
1305                 if (copy_from_user(&msf, argp, sizeof msf))
1306                         return -EFAULT;
1307                 /* convert to bcd */
1308                 azt_bin2bcd(&msf.cdmsf_min0);
1309                 azt_bin2bcd(&msf.cdmsf_sec0);
1310                 azt_bin2bcd(&msf.cdmsf_frame0);
1311                 azt_bin2bcd(&msf.cdmsf_min1);
1312                 azt_bin2bcd(&msf.cdmsf_sec1);
1313                 azt_bin2bcd(&msf.cdmsf_frame1);
1314                 azt_Play.start.min = msf.cdmsf_min0;
1315                 azt_Play.start.sec = msf.cdmsf_sec0;
1316                 azt_Play.start.frame = msf.cdmsf_frame0;
1317                 azt_Play.end.min = msf.cdmsf_min1;
1318                 azt_Play.end.sec = msf.cdmsf_sec1;
1319                 azt_Play.end.frame = msf.cdmsf_frame1;
1320 #ifdef AZT_DEBUG
1321                 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1322                        azt_Play.start.min, azt_Play.start.sec,
1323                        azt_Play.start.frame, azt_Play.end.min,
1324                        azt_Play.end.sec, azt_Play.end.frame);
1325 #endif
1326                 i = aztPlay(&azt_Play);
1327                 if (i < 0) {
1328                         aztAudioStatus = CDROM_AUDIO_ERROR;
1329                         return -EIO;
1330                 }
1331                 aztAudioStatus = CDROM_AUDIO_PLAY;
1332                 break;
1333
1334         case CDROMREADTOCHDR:   /* Read the table of contents header */
1335                 tocHdr.cdth_trk0 = DiskInfo.first;
1336                 tocHdr.cdth_trk1 = DiskInfo.last;
1337                 if (copy_to_user(argp, &tocHdr, sizeof tocHdr))
1338                         return -EFAULT;
1339                 break;
1340         case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
1341                 if (copy_from_user(&entry, argp, sizeof entry))
1342                         return -EFAULT;
1343                 if ((!aztTocUpToDate) || aztDiskChanged)
1344                         aztUpdateToc();
1345                 if (entry.cdte_track == CDROM_LEADOUT)
1346                         tocPtr = &Toc[DiskInfo.last + 1];
1347                 else if (entry.cdte_track > DiskInfo.last
1348                          || entry.cdte_track < DiskInfo.first) {
1349                         return -EINVAL;
1350                 } else
1351                         tocPtr = &Toc[entry.cdte_track];
1352                 entry.cdte_adr = tocPtr->ctrl_addr;
1353                 entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
1354                 if (entry.cdte_format == CDROM_LBA)
1355                         entry.cdte_addr.lba =
1356                             azt_msf2hsg(&tocPtr->diskTime);
1357                 else if (entry.cdte_format == CDROM_MSF) {
1358                         entry.cdte_addr.msf.minute =
1359                             azt_bcd2bin(tocPtr->diskTime.min);
1360                         entry.cdte_addr.msf.second =
1361                             azt_bcd2bin(tocPtr->diskTime.sec);
1362                         entry.cdte_addr.msf.frame =
1363                             azt_bcd2bin(tocPtr->diskTime.frame);
1364                 } else {
1365                         return -EINVAL;
1366                 }
1367                 if (copy_to_user(argp, &entry, sizeof entry))
1368                         return -EFAULT;
1369                 break;
1370         case CDROMSUBCHNL:      /* Get subchannel info */
1371                 if (copy_from_user
1372                     (&subchnl, argp, sizeof(struct cdrom_subchnl)))
1373                         return -EFAULT;
1374                 if (aztGetQChannelInfo(&qInfo) < 0) {
1375 #ifdef AZT_DEBUG
1376                         printk
1377                             ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
1378                              cmd);
1379 #endif
1380                         return -EIO;
1381                 }
1382                 subchnl.cdsc_audiostatus = aztAudioStatus;
1383                 subchnl.cdsc_adr = qInfo.ctrl_addr;
1384                 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
1385                 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
1386                 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
1387                 if (subchnl.cdsc_format == CDROM_LBA) {
1388                         subchnl.cdsc_absaddr.lba =
1389                             azt_msf2hsg(&qInfo.diskTime);
1390                         subchnl.cdsc_reladdr.lba =
1391                             azt_msf2hsg(&qInfo.trackTime);
1392                 } else {        /*default */
1393                         subchnl.cdsc_format = CDROM_MSF;
1394                         subchnl.cdsc_absaddr.msf.minute =
1395                             azt_bcd2bin(qInfo.diskTime.min);
1396                         subchnl.cdsc_absaddr.msf.second =
1397                             azt_bcd2bin(qInfo.diskTime.sec);
1398                         subchnl.cdsc_absaddr.msf.frame =
1399                             azt_bcd2bin(qInfo.diskTime.frame);
1400                         subchnl.cdsc_reladdr.msf.minute =
1401                             azt_bcd2bin(qInfo.trackTime.min);
1402                         subchnl.cdsc_reladdr.msf.second =
1403                             azt_bcd2bin(qInfo.trackTime.sec);
1404                         subchnl.cdsc_reladdr.msf.frame =
1405                             azt_bcd2bin(qInfo.trackTime.frame);
1406                 }
1407                 if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl)))
1408                         return -EFAULT;
1409                 break;
1410         case CDROMVOLCTRL:      /* Volume control 
1411                                    * With my Aztech CD268-01A volume control does not work, I can only
1412                                    turn the channels on (any value !=0) or off (value==0). Maybe it
1413                                    works better with your drive */
1414                 if (copy_from_user(&volctrl, argp, sizeof(volctrl)))
1415                         return -EFAULT;
1416                 azt_Play.start.min = 0x21;
1417                 azt_Play.start.sec = 0x84;
1418                 azt_Play.start.frame = volctrl.channel0;
1419                 azt_Play.end.min = volctrl.channel1;
1420                 azt_Play.end.sec = volctrl.channel2;
1421                 azt_Play.end.frame = volctrl.channel3;
1422                 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
1423                 STEN_LOW_WAIT;
1424                 break;
1425         case CDROMEJECT:
1426                 aztUnlockDoor();        /* Assume user knows what they're doing */
1427                 /* all drives can at least stop! */
1428                 if (aztAudioStatus == CDROM_AUDIO_PLAY) {
1429                         if (aztSendCmd(ACMD_STOP))
1430                                 RETURNM("azt_ioctl 10", -1);
1431                         STEN_LOW_WAIT;
1432                 }
1433                 if (aztSendCmd(ACMD_EJECT))
1434                         RETURNM("azt_ioctl 11", -1);
1435                 STEN_LOW_WAIT;
1436                 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1437                 break;
1438         case CDROMEJECT_SW:
1439                 azt_auto_eject = (char) arg;
1440                 break;
1441         case CDROMRESET:
1442                 outb(ACMD_SOFT_RESET, CMD_PORT);        /*send reset */
1443                 STEN_LOW;
1444                 if (inb(DATA_PORT) != AFL_OP_OK) {      /*OP_OK? */
1445                         printk
1446                             ("aztcd: AZTECH CD-ROM drive does not respond\n");
1447                 }
1448                 break;
1449 /*Take care, the following code is not compatible with other CD-ROM drivers,
1450   use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1451   if you do not want to use it!
1452 */
1453 #if AZT_PRIVATE_IOCTLS
1454         case CDROMREADCOOKED:   /*read data in mode 1 (2048 Bytes) */
1455         case CDROMREADRAW:      /*read data in mode 2 (2336 Bytes) */
1456                 {
1457                         if (copy_from_user(&msf, argp, sizeof msf))
1458                                 return -EFAULT;
1459                         /* convert to bcd */
1460                         azt_bin2bcd(&msf.cdmsf_min0);
1461                         azt_bin2bcd(&msf.cdmsf_sec0);
1462                         azt_bin2bcd(&msf.cdmsf_frame0);
1463                         msf.cdmsf_min1 = 0;
1464                         msf.cdmsf_sec1 = 0;
1465                         msf.cdmsf_frame1 = 1;   /*read only one frame */
1466                         azt_Play.start.min = msf.cdmsf_min0;
1467                         azt_Play.start.sec = msf.cdmsf_sec0;
1468                         azt_Play.start.frame = msf.cdmsf_frame0;
1469                         azt_Play.end.min = msf.cdmsf_min1;
1470                         azt_Play.end.sec = msf.cdmsf_sec1;
1471                         azt_Play.end.frame = msf.cdmsf_frame1;
1472                         if (cmd == CDROMREADRAW) {
1473                                 if (DiskInfo.xa) {
1474                                         return -1;      /*XA Disks can't be read raw */
1475                                 } else {
1476                                         if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play))
1477                                                 return -1;
1478                                         DTEN_LOW;
1479                                         insb(DATA_PORT, buf, CD_FRAMESIZE_RAW);
1480                                         if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW))
1481                                                 return -EFAULT;
1482                                 }
1483                         } else
1484                                 /*CDROMREADCOOKED*/ {
1485                                 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
1486                                         return -1;
1487                                 DTEN_LOW;
1488                                 insb(DATA_PORT, buf, CD_FRAMESIZE);
1489                                 if (copy_to_user(argp, &buf, CD_FRAMESIZE))
1490                                         return -EFAULT;
1491                                 }
1492                 }
1493                 break;
1494         case CDROMSEEK: /*seek msf address */
1495                 if (copy_from_user(&msf, argp, sizeof msf))
1496                         return -EFAULT;
1497                 /* convert to bcd */
1498                 azt_bin2bcd(&msf.cdmsf_min0);
1499                 azt_bin2bcd(&msf.cdmsf_sec0);
1500                 azt_bin2bcd(&msf.cdmsf_frame0);
1501                 azt_Play.start.min = msf.cdmsf_min0;
1502                 azt_Play.start.sec = msf.cdmsf_sec0;
1503                 azt_Play.start.frame = msf.cdmsf_frame0;
1504                 if (aztSeek(&azt_Play))
1505                         return -1;
1506                 break;
1507 #endif                          /*end of incompatible code */
1508         case CDROMREADMODE1:    /*set read data in mode 1 */
1509                 return aztSetDiskType(AZT_MODE_1);
1510         case CDROMREADMODE2:    /*set read data in mode 2 */
1511                 return aztSetDiskType(AZT_MODE_2);
1512         default:
1513                 return -EINVAL;
1514         }
1515 #ifdef AZT_DEBUG
1516         printk("aztcd: exiting aztcd_ioctl Command:%x  Time:%li\n", cmd,
1517                jiffies);
1518 #endif
1519         return 0;
1520 }
1521
1522 /*
1523  * Take care of the different block sizes between cdrom and Linux.
1524  * When Linux gets variable block sizes this will probably go away.
1525  */
1526 static void azt_transfer(void)
1527 {
1528 #ifdef AZT_TEST
1529         printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
1530 #endif
1531         if (!current_valid())
1532                 return;
1533
1534         while (CURRENT->nr_sectors) {
1535                 int bn = CURRENT->sector / 4;
1536                 int i;
1537                 for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i);
1538                 if (i < AZT_BUF_SIZ) {
1539                         int offs = (i * 4 + (CURRENT->sector & 3)) * 512;
1540                         int nr_sectors = 4 - (CURRENT->sector & 3);
1541                         if (azt_buf_out != i) {
1542                                 azt_buf_out = i;
1543                                 if (azt_buf_bn[i] != bn) {
1544                                         azt_buf_out = -1;
1545                                         continue;
1546                                 }
1547                         }
1548                         if (nr_sectors > CURRENT->nr_sectors)
1549                             nr_sectors = CURRENT->nr_sectors;
1550                         memcpy(CURRENT->buffer, azt_buf + offs,
1551                                 nr_sectors * 512);
1552                         CURRENT->nr_sectors -= nr_sectors;
1553                         CURRENT->sector += nr_sectors;
1554                         CURRENT->buffer += nr_sectors * 512;
1555                 } else {
1556                         azt_buf_out = -1;
1557                         break;
1558                 }
1559         }
1560 }
1561
1562 static void do_aztcd_request(request_queue_t * q)
1563 {
1564 #ifdef AZT_TEST
1565         printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
1566                CURRENT->nr_sectors, jiffies);
1567 #endif
1568         if (DiskInfo.audio) {
1569                 printk("aztcd: Error, tried to mount an Audio CD\n");
1570                 end_request(CURRENT, 0);
1571                 return;
1572         }
1573         azt_transfer_is_active = 1;
1574         while (current_valid()) {
1575                 azt_transfer();
1576                 if (CURRENT->nr_sectors == 0) {
1577                         end_request(CURRENT, 1);
1578                 } else {
1579                         azt_buf_out = -1;       /* Want to read a block not in buffer */
1580                         if (azt_state == AZT_S_IDLE) {
1581                                 if ((!aztTocUpToDate) || aztDiskChanged) {
1582                                         if (aztUpdateToc() < 0) {
1583                                                 while (current_valid())
1584                                                         end_request(CURRENT, 0);
1585                                                 break;
1586                                         }
1587                                 }
1588                                 azt_state = AZT_S_START;
1589                                 AztTries = 5;
1590                                 SET_TIMER(azt_poll, HZ / 100);
1591                         }
1592                         break;
1593                 }
1594         }
1595         azt_transfer_is_active = 0;
1596 #ifdef AZT_TEST2
1597         printk
1598             ("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n",
1599              azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1600         printk(" do_aztcd_request ends  Time:%li\n", jiffies);
1601 #endif
1602 }
1603
1604
1605 static void azt_invalidate_buffers(void)
1606 {
1607         int i;
1608
1609 #ifdef AZT_DEBUG
1610         printk("aztcd: executing azt_invalidate_buffers\n");
1611 #endif
1612         for (i = 0; i < AZT_BUF_SIZ; ++i)
1613                 azt_buf_bn[i] = -1;
1614         azt_buf_out = -1;
1615 }
1616
1617 /*
1618  * Open the device special file.  Check that a disk is in.
1619  */
1620 static int aztcd_open(struct inode *ip, struct file *fp)
1621 {
1622         int st;
1623
1624 #ifdef AZT_DEBUG
1625         printk("aztcd: starting aztcd_open\n");
1626 #endif
1627
1628         if (aztPresent == 0)
1629                 return -ENXIO;  /* no hardware */
1630
1631         if (!azt_open_count && azt_state == AZT_S_IDLE) {
1632                 azt_invalidate_buffers();
1633
1634                 st = getAztStatus();    /* check drive status */
1635                 if (st == -1)
1636                         goto err_out;   /* drive doesn't respond */
1637
1638                 if (st & AST_DOOR_OPEN) {       /* close door, then get the status again. */
1639                         printk("aztcd: Door Open?\n");
1640                         aztCloseDoor();
1641                         st = getAztStatus();
1642                 }
1643
1644                 if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) {       /*no disk in drive or changed */
1645                         printk
1646                             ("aztcd: Disk Changed or No Disk in Drive?\n");
1647                         aztTocUpToDate = 0;
1648                 }
1649                 if (aztUpdateToc())
1650                         goto err_out;
1651
1652         }
1653         ++azt_open_count;
1654         aztLockDoor();
1655
1656 #ifdef AZT_DEBUG
1657         printk("aztcd: exiting aztcd_open\n");
1658 #endif
1659         return 0;
1660
1661       err_out:
1662         return -EIO;
1663 }
1664
1665
1666 /*
1667  * On close, we flush all azt blocks from the buffer cache.
1668  */
1669 static int aztcd_release(struct inode *inode, struct file *file)
1670 {
1671 #ifdef AZT_DEBUG
1672         printk("aztcd: executing aztcd_release\n");
1673         printk("inode: %p, device: %s    file: %p\n", inode,
1674                inode->i_bdev->bd_disk->disk_name, file);
1675 #endif
1676         if (!--azt_open_count) {
1677                 azt_invalidate_buffers();
1678                 aztUnlockDoor();
1679                 if (azt_auto_eject)
1680                         aztSendCmd(ACMD_EJECT);
1681                 CLEAR_TIMER;
1682         }
1683         return 0;
1684 }
1685
1686 static struct gendisk *azt_disk;
1687
1688 /*
1689  * Test for presence of drive and initialize it.  Called at boot time.
1690  */
1691
1692 static int __init aztcd_init(void)
1693 {
1694         long int count, max_count;
1695         unsigned char result[50];
1696         int st;
1697         void* status = NULL;
1698         int i = 0;
1699         int ret = 0;
1700
1701         if (azt_port == 0) {
1702                 printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization");
1703                 return -EIO;
1704         }
1705
1706         printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM "
1707                "CD-ROM Driver\n");
1708         printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
1709         if (azt_port == -1) {
1710                 printk
1711                     ("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
1712                      UTS_RELEASE, AZT_VERSION);
1713         } else
1714                 printk
1715                     ("aztcd: DriverVersion=%s BaseAddress=0x%x  For IDE/ATAPI-drives use ide-cd.c\n",
1716                      AZT_VERSION, azt_port);
1717         printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/"
1718                "Documentation/cdrom/aztcd\n");
1719
1720
1721 #ifdef AZT_SW32                 /*CDROM connected to Soundwave32 card */
1722         if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
1723                 printk
1724                     ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1725                      AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
1726                      AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
1727                 return -EIO;
1728         } else {
1729                 printk(KERN_INFO
1730                        "aztcd: Soundwave32 card detected at %x  Version %x\n",
1731                        AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1732                 outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
1733                 for (count = 0; count < 10000; count++);        /*delay a bit */
1734         }
1735 #endif
1736
1737         /* check for presence of drive */
1738
1739         if (azt_port == -1) {   /* autoprobing for proprietary interface  */
1740                 for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
1741                         azt_port = azt_port_auto[i];
1742                         printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x"
1743                                "\n", azt_port);
1744                          /*proprietary interfaces need 4 bytes */
1745                         if (!request_region(azt_port, 4, "aztcd")) {
1746                                 continue;
1747                         }
1748                         outb(POLLED, MODE_PORT);
1749                         inb(CMD_PORT);
1750                         inb(CMD_PORT);
1751                         outb(ACMD_GET_VERSION, CMD_PORT);       /*Try to get version info */
1752
1753                         aztTimeOutCount = 0;
1754                         do {
1755                                 aztIndatum = inb(STATUS_PORT);
1756                                 aztTimeOutCount++;
1757                                 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1758                                         break;
1759                         } while (aztIndatum & AFL_STATUS);
1760                         if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */
1761                                 break;
1762                         }
1763                         else {  /* Drive not found on this port - try next one */
1764                                 release_region(azt_port, 4);
1765                         }
1766                 }
1767                 if ((azt_port_auto[i] == 0) || (i == 16)) {
1768                         printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n");
1769                         return -EIO;
1770                 }
1771         } else {                /* no autoprobing */
1772                 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1773                         status = request_region(azt_port, 8, "aztcd");  /*IDE-interfaces need 8 bytes */
1774                 else
1775                         status = request_region(azt_port, 4, "aztcd");  /*proprietary interfaces need 4 bytes */
1776                 if (!status) {
1777                         printk(KERN_WARNING "aztcd: conflict, I/O port (%X) "
1778                                "already used\n", azt_port);
1779                         return -EIO;
1780                 }
1781
1782                 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1783                         SWITCH_IDE_SLAVE;       /*switch IDE interface to slave configuration */
1784
1785                 outb(POLLED, MODE_PORT);
1786                 inb(CMD_PORT);
1787                 inb(CMD_PORT);
1788                 outb(ACMD_GET_VERSION, CMD_PORT);       /*Try to get version info */
1789
1790                 aztTimeOutCount = 0;
1791                 do {
1792                         aztIndatum = inb(STATUS_PORT);
1793                         aztTimeOutCount++;
1794                         if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1795                                 break;
1796                 } while (aztIndatum & AFL_STATUS);
1797
1798                 if (inb(DATA_PORT) != AFL_OP_OK) {      /*OP_OK? If not, reset and try again */
1799 #ifndef MODULE
1800                         if (azt_cont != 0x79) {
1801                                 printk(KERN_WARNING "aztcd: no AZTECH CD-ROM "
1802                                        "drive found-Try boot parameter aztcd="
1803                                        "<BaseAddress>,0x79\n");
1804                                 ret = -EIO;
1805                                 goto err_out;
1806                         }
1807 #else
1808                         if (0) {
1809                         }
1810 #endif
1811                         else {
1812                                 printk(KERN_INFO "aztcd: drive reset - "
1813                                        "please wait\n");
1814                                 for (count = 0; count < 50; count++) {
1815                                         inb(STATUS_PORT);       /*removing all data from earlier tries */
1816                                         inb(DATA_PORT);
1817                                 }
1818                                 outb(POLLED, MODE_PORT);
1819                                 inb(CMD_PORT);
1820                                 inb(CMD_PORT);
1821                                 getAztStatus(); /*trap errors */
1822                                 outb(ACMD_SOFT_RESET, CMD_PORT);        /*send reset */
1823                                 STEN_LOW;
1824                                 if (inb(DATA_PORT) != AFL_OP_OK) {      /*OP_OK? */
1825                                         printk(KERN_WARNING "aztcd: no AZTECH "
1826                                                "CD-ROM drive found\n");
1827                                         ret = -EIO;
1828                                         goto err_out;
1829                                 }
1830
1831                                 for (count = 0; count < AZT_TIMEOUT;
1832                                      count++)
1833                                         barrier();      /* Stop gcc 2.96 being smart */
1834                                 /* use udelay(), damnit -- AV */
1835
1836                                 if ((st = getAztStatus()) == -1) {
1837                                         printk(KERN_WARNING "aztcd: Drive Status"
1838                                                " Error Status=%x\n", st);
1839                                         ret = -EIO;
1840                                         goto err_out;
1841                                 }
1842 #ifdef AZT_DEBUG
1843                                 printk(KERN_DEBUG "aztcd: Status = %x\n", st);
1844 #endif
1845                                 outb(POLLED, MODE_PORT);
1846                                 inb(CMD_PORT);
1847                                 inb(CMD_PORT);
1848                                 outb(ACMD_GET_VERSION, CMD_PORT);       /*GetVersion */
1849                                 STEN_LOW;
1850                                 OP_OK;
1851                         }
1852                 }
1853         }
1854
1855         azt_init_end = 1;
1856         STEN_LOW;
1857         result[0] = inb(DATA_PORT);     /*reading in a null byte??? */
1858         for (count = 1; count < 50; count++) {  /*Reading version string */
1859                 aztTimeOutCount = 0;    /*here we must implement STEN_LOW differently */
1860                 do {
1861                         aztIndatum = inb(STATUS_PORT);  /*because we want to exit by timeout */
1862                         aztTimeOutCount++;
1863                         if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1864                                 break;
1865                 } while (aztIndatum & AFL_STATUS);
1866                 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1867                         break;  /*all chars read? */
1868                 result[count] = inb(DATA_PORT);
1869         }
1870         if (count > 30)
1871                 max_count = 30; /*print max.30 chars of the version string */
1872         else
1873                 max_count = count;
1874         printk(KERN_INFO "aztcd: FirmwareVersion=");
1875         for (count = 1; count < max_count; count++)
1876                 printk("%c", result[count]);
1877         printk("<<>> ");
1878
1879         if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
1880                 printk("AZTECH drive detected\n");
1881         /*AZTECH*/}
1882                 else if ((result[2] == 'C') && (result[3] == 'D')
1883                          && (result[4] == 'D')) {
1884                 printk("ORCHID or WEARNES drive detected\n");   /*ORCHID or WEARNES */
1885         } else if ((result[1] == 0x03) && (result[2] == '5')) {
1886                 printk("TXC or CyCDROM drive detected\n");      /*Conrad TXC, CyCDROM */
1887         } else {                /*OTHERS or none */
1888                 printk("\nunknown drive or firmware version detected\n");
1889                 printk
1890                     ("aztcd may not run stable, if you want to try anyhow,\n");
1891                 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1892                 if ((azt_cont != 0x79)) {
1893                         printk("aztcd: FirmwareVersion=");
1894                         for (count = 1; count < 5; count++)
1895                                 printk("%c", result[count]);
1896                         printk("<<>> ");
1897                         printk("Aborted\n");
1898                         ret = -EIO;
1899                         goto err_out;
1900                 }
1901         }
1902         azt_disk = alloc_disk(1);
1903         if (!azt_disk)
1904                 goto err_out;
1905
1906         if (register_blkdev(MAJOR_NR, "aztcd")) {
1907                 ret = -EIO;
1908                 goto err_out2;
1909         }
1910
1911         azt_queue = blk_init_queue(do_aztcd_request, &aztSpin);
1912         if (!azt_queue) {
1913                 ret = -ENOMEM;
1914                 goto err_out3;
1915         }
1916
1917         blk_queue_hardsect_size(azt_queue, 2048);
1918         azt_disk->major = MAJOR_NR;
1919         azt_disk->first_minor = 0;
1920         azt_disk->fops = &azt_fops;
1921         sprintf(azt_disk->disk_name, "aztcd");
1922         sprintf(azt_disk->devfs_name, "aztcd");
1923         azt_disk->queue = azt_queue;
1924         add_disk(azt_disk);
1925         azt_invalidate_buffers();
1926         aztPresent = 1;
1927         aztCloseDoor();
1928         return 0;
1929 err_out3:
1930         unregister_blkdev(MAJOR_NR, "aztcd");
1931 err_out2:
1932         put_disk(azt_disk);
1933 err_out:
1934         if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1935                 SWITCH_IDE_MASTER;
1936                 release_region(azt_port, 8);    /*IDE-interface */
1937         } else
1938                 release_region(azt_port, 4);    /*proprietary interface */
1939         return ret;
1940
1941 }
1942
1943 static void __exit aztcd_exit(void)
1944 {
1945         del_gendisk(azt_disk);
1946         put_disk(azt_disk);
1947         if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
1948                 printk("What's that: can't unregister aztcd\n");
1949                 return;
1950         }
1951         blk_cleanup_queue(azt_queue);
1952         if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1953                 SWITCH_IDE_MASTER;
1954                 release_region(azt_port, 8);    /*IDE-interface */
1955         } else
1956                 release_region(azt_port, 4);    /*proprietary interface */
1957         printk(KERN_INFO "aztcd module released.\n");
1958 }
1959
1960 module_init(aztcd_init);
1961 module_exit(aztcd_exit);
1962
1963 /*##########################################################################
1964   Aztcd State Machine: Controls Drive Operating State
1965   ##########################################################################
1966 */
1967 static void azt_poll(void)
1968 {
1969         int st = 0;
1970         int loop_ctl = 1;
1971         int skip = 0;
1972
1973         if (azt_error) {
1974                 if (aztSendCmd(ACMD_GET_ERROR))
1975                         RETURN("azt_poll 1");
1976                 STEN_LOW;
1977                 azt_error = inb(DATA_PORT) & 0xFF;
1978                 printk("aztcd: I/O error 0x%02x\n", azt_error);
1979                 azt_invalidate_buffers();
1980 #ifdef WARN_IF_READ_FAILURE
1981                 if (AztTries == 5)
1982                         printk
1983                             ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
1984                              azt_next_bn);
1985 #endif
1986                 if (!AztTries--) {
1987                         printk
1988                             ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
1989                              azt_next_bn);
1990                         if (azt_transfer_is_active) {
1991                                 AztTries = 0;
1992                                 loop_ctl = 0;
1993                         }
1994                         if (current_valid())
1995                                 end_request(CURRENT, 0);
1996                         AztTries = 5;
1997                 }
1998                 azt_error = 0;
1999                 azt_state = AZT_S_STOP;
2000         }
2001
2002         while (loop_ctl) {
2003                 loop_ctl = 0;   /* each case must flip this back to 1 if we want
2004                                    to come back up here */
2005                 switch (azt_state) {
2006
2007                 case AZT_S_IDLE:
2008 #ifdef AZT_TEST3
2009                         if (azt_state != azt_state_old) {
2010                                 azt_state_old = azt_state;
2011                                 printk("AZT_S_IDLE\n");
2012                         }
2013 #endif
2014                         return;
2015
2016                 case AZT_S_START:
2017 #ifdef AZT_TEST3
2018                         if (azt_state != azt_state_old) {
2019                                 azt_state_old = azt_state;
2020                                 printk("AZT_S_START\n");
2021                         }
2022 #endif
2023                         if (aztSendCmd(ACMD_GET_STATUS))
2024                                 RETURN("azt_poll 2");   /*result will be checked by aztStatus() */
2025                         azt_state =
2026                             azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
2027                         AztTimeout = 3000;
2028                         break;
2029
2030                 case AZT_S_MODE:
2031 #ifdef AZT_TEST3
2032                         if (azt_state != azt_state_old) {
2033                                 azt_state_old = azt_state;
2034                                 printk("AZT_S_MODE\n");
2035                         }
2036 #endif
2037                         if (!skip) {
2038                                 if ((st = aztStatus()) != -1) {
2039                                         if ((st & AST_DSK_CHG)
2040                                             || (st & AST_NOT_READY)) {
2041                                                 aztDiskChanged = 1;
2042                                                 aztTocUpToDate = 0;
2043                                                 azt_invalidate_buffers();
2044                                                 end_request(CURRENT, 0);
2045                                                 printk
2046                                                     ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
2047                                         }
2048                                 } else
2049                                         break;
2050                         }
2051                         skip = 0;
2052
2053                         if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2054                                 aztDiskChanged = 1;
2055                                 aztTocUpToDate = 0;
2056                                 printk
2057                                     ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
2058                                 end_request(CURRENT, 0);
2059                                 printk((st & AST_DOOR_OPEN) ?
2060                                        "aztcd: door open\n" :
2061                                        "aztcd: disk removed\n");
2062                                 if (azt_transfer_is_active) {
2063                                         azt_state = AZT_S_START;
2064                                         loop_ctl = 1;   /* goto immediately */
2065                                         break;
2066                                 }
2067                                 azt_state = AZT_S_IDLE;
2068                                 while (current_valid())
2069                                         end_request(CURRENT, 0);
2070                                 return;
2071                         }
2072
2073 /*        if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
2074           outb(0x01, DATA_PORT);
2075           PA_OK;
2076           STEN_LOW;
2077 */
2078                         if (aztSendCmd(ACMD_GET_STATUS))
2079                                 RETURN("azt_poll 4");
2080                         STEN_LOW;
2081                         azt_mode = 1;
2082                         azt_state = AZT_S_READ;
2083                         AztTimeout = 3000;
2084
2085                         break;
2086
2087
2088                 case AZT_S_READ:
2089 #ifdef AZT_TEST3
2090                         if (azt_state != azt_state_old) {
2091                                 azt_state_old = azt_state;
2092                                 printk("AZT_S_READ\n");
2093                         }
2094 #endif
2095                         if (!skip) {
2096                                 if ((st = aztStatus()) != -1) {
2097                                         if ((st & AST_DSK_CHG)
2098                                             || (st & AST_NOT_READY)) {
2099                                                 aztDiskChanged = 1;
2100                                                 aztTocUpToDate = 0;
2101                                                 azt_invalidate_buffers();
2102                                                 printk
2103                                                     ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
2104                                                 end_request(CURRENT, 0);
2105                                         }
2106                                 } else
2107                                         break;
2108                         }
2109
2110                         skip = 0;
2111                         if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2112                                 aztDiskChanged = 1;
2113                                 aztTocUpToDate = 0;
2114                                 printk((st & AST_DOOR_OPEN) ?
2115                                        "aztcd: door open\n" :
2116                                        "aztcd: disk removed\n");
2117                                 if (azt_transfer_is_active) {
2118                                         azt_state = AZT_S_START;
2119                                         loop_ctl = 1;
2120                                         break;
2121                                 }
2122                                 azt_state = AZT_S_IDLE;
2123                                 while (current_valid())
2124                                         end_request(CURRENT, 0);
2125                                 return;
2126                         }
2127
2128                         if (current_valid()) {
2129                                 struct azt_Play_msf msf;
2130                                 int i;
2131                                 azt_next_bn = CURRENT->sector / 4;
2132                                 azt_hsg2msf(azt_next_bn, &msf.start);
2133                                 i = 0;
2134                                 /* find out in which track we are */
2135                                 while (azt_msf2hsg(&msf.start) >
2136                                        azt_msf2hsg(&Toc[++i].trackTime)) {
2137                                 };
2138                                 if (azt_msf2hsg(&msf.start) <
2139                                     azt_msf2hsg(&Toc[i].trackTime) -
2140                                     AZT_BUF_SIZ) {
2141                                         azt_read_count = AZT_BUF_SIZ;   /*fast, because we read ahead */
2142                                         /*azt_read_count=CURRENT->nr_sectors;    slow, no read ahead */
2143                                 } else  /* don't read beyond end of track */
2144 #if AZT_MULTISESSION
2145                                 {
2146                                         azt_read_count =
2147                                             (azt_msf2hsg(&Toc[i].trackTime)
2148                                              / 4) * 4 -
2149                                             azt_msf2hsg(&msf.start);
2150                                         if (azt_read_count < 0)
2151                                                 azt_read_count = 0;
2152                                         if (azt_read_count > AZT_BUF_SIZ)
2153                                                 azt_read_count =
2154                                                     AZT_BUF_SIZ;
2155                                         printk
2156                                             ("aztcd: warning - trying to read beyond end of track\n");
2157 /*               printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2158 */ }
2159 #else
2160                                 {
2161                                         azt_read_count = AZT_BUF_SIZ;
2162                                 }
2163 #endif
2164                                 msf.end.min = 0;
2165                                 msf.end.sec = 0;
2166                                 msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
2167 #ifdef AZT_TEST3
2168                                 printk
2169                                     ("---reading msf-address %x:%x:%x  %x:%x:%x\n",
2170                                      msf.start.min, msf.start.sec,
2171                                      msf.start.frame, msf.end.min,
2172                                      msf.end.sec, msf.end.frame);
2173                                 printk
2174                                     ("azt_next_bn:%x  azt_buf_in:%x azt_buf_out:%x  azt_buf_bn:%x\n",
2175                                      azt_next_bn, azt_buf_in, azt_buf_out,
2176                                      azt_buf_bn[azt_buf_in]);
2177 #endif
2178                                 if (azt_read_mode == AZT_MODE_2) {
2179                                         sendAztCmd(ACMD_PLAY_READ_RAW, &msf);   /*XA disks in raw mode */
2180                                 } else {
2181                                         sendAztCmd(ACMD_PLAY_READ, &msf);       /*others in cooked mode */
2182                                 }
2183                                 azt_state = AZT_S_DATA;
2184                                 AztTimeout = READ_TIMEOUT;
2185                         } else {
2186                                 azt_state = AZT_S_STOP;
2187                                 loop_ctl = 1;
2188                                 break;
2189                         }
2190
2191                         break;
2192
2193
2194                 case AZT_S_DATA:
2195 #ifdef AZT_TEST3
2196                         if (azt_state != azt_state_old) {
2197                                 azt_state_old = azt_state;
2198                                 printk("AZT_S_DATA\n");
2199                         }
2200 #endif
2201
2202                         st = inb(STATUS_PORT) & AFL_STATUSorDATA;
2203
2204                         switch (st) {
2205
2206                         case AFL_DATA:
2207 #ifdef AZT_TEST3
2208                                 if (st != azt_st_old) {
2209                                         azt_st_old = st;
2210                                         printk("---AFL_DATA st:%x\n", st);
2211                                 }
2212 #endif
2213                                 if (!AztTries--) {
2214                                         printk
2215                                             ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
2216                                              azt_next_bn);
2217                                         if (azt_transfer_is_active) {
2218                                                 AztTries = 0;
2219                                                 break;
2220                                         }
2221                                         if (current_valid())
2222                                                 end_request(CURRENT, 0);
2223                                         AztTries = 5;
2224                                 }
2225                                 azt_state = AZT_S_START;
2226                                 AztTimeout = READ_TIMEOUT;
2227                                 loop_ctl = 1;
2228                                 break;
2229
2230                         case AFL_STATUSorDATA:
2231 #ifdef AZT_TEST3
2232                                 if (st != azt_st_old) {
2233                                         azt_st_old = st;
2234                                         printk
2235                                             ("---AFL_STATUSorDATA st:%x\n",
2236                                              st);
2237                                 }
2238 #endif
2239                                 break;
2240
2241                         default:
2242 #ifdef AZT_TEST3
2243                                 if (st != azt_st_old) {
2244                                         azt_st_old = st;
2245                                         printk("---default: st:%x\n", st);
2246                                 }
2247 #endif
2248                                 AztTries = 5;
2249                                 if (!current_valid() && azt_buf_in == azt_buf_out) {
2250                                         azt_state = AZT_S_STOP;
2251                                         loop_ctl = 1;
2252                                         break;
2253                                 }
2254                                 if (azt_read_count <= 0)
2255                                         printk
2256                                             ("aztcd: warning - try to read 0 frames\n");
2257                                 while (azt_read_count) {        /*??? fast read ahead loop */
2258                                         azt_buf_bn[azt_buf_in] = -1;
2259                                         DTEN_LOW;       /*??? unsolved problem, very
2260                                                            seldom we get timeouts
2261                                                            here, don't now the real
2262                                                            reason. With my drive this
2263                                                            sometimes also happens with
2264                                                            Aztech's original driver under
2265                                                            DOS. Is it a hardware bug? 
2266                                                            I tried to recover from such
2267                                                            situations here. Zimmermann */
2268                                         if (aztTimeOutCount >= AZT_TIMEOUT) {
2269                                                 printk
2270                                                     ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
2271                                                      azt_read_count,
2272                                                      CURRENT->nr_sectors,
2273                                                      azt_buf_in);
2274                                                 printk
2275                                                     ("azt_transfer_is_active:%x\n",
2276                                                      azt_transfer_is_active);
2277                                                 azt_read_count = 0;
2278                                                 azt_state = AZT_S_STOP;
2279                                                 loop_ctl = 1;
2280                                                 end_request(CURRENT, 1);        /*should we have here (1) or (0)? */
2281                                         } else {
2282                                                 if (azt_read_mode ==
2283                                                     AZT_MODE_2) {
2284                                                         insb(DATA_PORT,
2285                                                              azt_buf +
2286                                                              CD_FRAMESIZE_RAW
2287                                                              * azt_buf_in,
2288                                                              CD_FRAMESIZE_RAW);
2289                                                 } else {
2290                                                         insb(DATA_PORT,
2291                                                              azt_buf +
2292                                                              CD_FRAMESIZE *
2293                                                              azt_buf_in,
2294                                                              CD_FRAMESIZE);
2295                                                 }
2296                                                 azt_read_count--;
2297 #ifdef AZT_TEST3
2298                                                 printk
2299                                                     ("AZT_S_DATA; ---I've read data- read_count: %d\n",
2300                                                      azt_read_count);
2301                                                 printk
2302                                                     ("azt_next_bn:%d  azt_buf_in:%d azt_buf_out:%d  azt_buf_bn:%d\n",
2303                                                      azt_next_bn,
2304                                                      azt_buf_in,
2305                                                      azt_buf_out,
2306                                                      azt_buf_bn
2307                                                      [azt_buf_in]);
2308 #endif
2309                                                 azt_buf_bn[azt_buf_in] =
2310                                                     azt_next_bn++;
2311                                                 if (azt_buf_out == -1)
2312                                                         azt_buf_out =
2313                                                             azt_buf_in;
2314                                                 azt_buf_in =
2315                                                     azt_buf_in + 1 ==
2316                                                     AZT_BUF_SIZ ? 0 :
2317                                                     azt_buf_in + 1;
2318                                         }
2319                                 }
2320                                 if (!azt_transfer_is_active) {
2321                                         while (current_valid()) {
2322                                                 azt_transfer();
2323                                                 if (CURRENT->nr_sectors ==
2324                                                     0)
2325                                                         end_request(CURRENT, 1);
2326                                                 else
2327                                                         break;
2328                                         }
2329                                 }
2330
2331                                 if (current_valid()
2332                                     && (CURRENT->sector / 4 < azt_next_bn
2333                                         || CURRENT->sector / 4 >
2334                                         azt_next_bn + AZT_BUF_SIZ)) {
2335                                         azt_state = AZT_S_STOP;
2336                                         loop_ctl = 1;
2337                                         break;
2338                                 }
2339                                 AztTimeout = READ_TIMEOUT;
2340                                 if (azt_read_count == 0) {
2341                                         azt_state = AZT_S_STOP;
2342                                         loop_ctl = 1;
2343                                         break;
2344                                 }
2345                                 break;
2346                         }
2347                         break;
2348
2349
2350                 case AZT_S_STOP:
2351 #ifdef AZT_TEST3
2352                         if (azt_state != azt_state_old) {
2353                                 azt_state_old = azt_state;
2354                                 printk("AZT_S_STOP\n");
2355                         }
2356 #endif
2357                         if (azt_read_count != 0)
2358                                 printk("aztcd: discard data=%x frames\n",
2359                                        azt_read_count);
2360                         while (azt_read_count != 0) {
2361                                 int i;
2362                                 if (!(inb(STATUS_PORT) & AFL_DATA)) {
2363                                         if (azt_read_mode == AZT_MODE_2)
2364                                                 for (i = 0;
2365                                                      i < CD_FRAMESIZE_RAW;
2366                                                      i++)
2367                                                         inb(DATA_PORT);
2368                                         else
2369                                                 for (i = 0;
2370                                                      i < CD_FRAMESIZE; i++)
2371                                                         inb(DATA_PORT);
2372                                 }
2373                                 azt_read_count--;
2374                         }
2375                         if (aztSendCmd(ACMD_GET_STATUS))
2376                                 RETURN("azt_poll 5");
2377                         azt_state = AZT_S_STOPPING;
2378                         AztTimeout = 1000;
2379                         break;
2380
2381                 case AZT_S_STOPPING:
2382 #ifdef AZT_TEST3
2383                         if (azt_state != azt_state_old) {
2384                                 azt_state_old = azt_state;
2385                                 printk("AZT_S_STOPPING\n");
2386                         }
2387 #endif
2388
2389                         if ((st = aztStatus()) == -1 && AztTimeout)
2390                                 break;
2391
2392                         if ((st != -1)
2393                             && ((st & AST_DSK_CHG)
2394                                 || (st & AST_NOT_READY))) {
2395                                 aztDiskChanged = 1;
2396                                 aztTocUpToDate = 0;
2397                                 azt_invalidate_buffers();
2398                                 printk
2399                                     ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2400                                 end_request(CURRENT, 0);
2401                         }
2402
2403 #ifdef AZT_TEST3
2404                         printk("CURRENT_VALID %d azt_mode %d\n",
2405                                current_valid(), azt_mode);
2406 #endif
2407
2408                         if (current_valid()) {
2409                                 if (st != -1) {
2410                                         if (azt_mode == 1) {
2411                                                 azt_state = AZT_S_READ;
2412                                                 loop_ctl = 1;
2413                                                 skip = 1;
2414                                                 break;
2415                                         } else {
2416                                                 azt_state = AZT_S_MODE;
2417                                                 loop_ctl = 1;
2418                                                 skip = 1;
2419                                                 break;
2420                                         }
2421                                 } else {
2422                                         azt_state = AZT_S_START;
2423                                         AztTimeout = 1;
2424                                 }
2425                         } else {
2426                                 azt_state = AZT_S_IDLE;
2427                                 return;
2428                         }
2429                         break;
2430
2431                 default:
2432                         printk("aztcd: invalid state %d\n", azt_state);
2433                         return;
2434                 }               /* case */
2435         }                       /* while */
2436
2437
2438         if (!AztTimeout--) {
2439                 printk("aztcd: timeout in state %d\n", azt_state);
2440                 azt_state = AZT_S_STOP;
2441                 if (aztSendCmd(ACMD_STOP))
2442                         RETURN("azt_poll 6");
2443                 STEN_LOW_WAIT;
2444         };
2445
2446         SET_TIMER(azt_poll, HZ / 100);
2447 }
2448
2449
2450 /*###########################################################################
2451  * Miscellaneous support functions
2452   ###########################################################################
2453 */
2454 static void azt_hsg2msf(long hsg, struct msf *msf)
2455 {
2456         hsg += 150;
2457         msf->min = hsg / 4500;
2458         hsg %= 4500;
2459         msf->sec = hsg / 75;
2460         msf->frame = hsg % 75;
2461 #ifdef AZT_DEBUG
2462         if (msf->min >= 70)
2463                 printk("aztcd: Error hsg2msf address Minutes\n");
2464         if (msf->sec >= 60)
2465                 printk("aztcd: Error hsg2msf address Seconds\n");
2466         if (msf->frame >= 75)
2467                 printk("aztcd: Error hsg2msf address Frames\n");
2468 #endif
2469         azt_bin2bcd(&msf->min); /* convert to BCD */
2470         azt_bin2bcd(&msf->sec);
2471         azt_bin2bcd(&msf->frame);
2472 }
2473
2474 static long azt_msf2hsg(struct msf *mp)
2475 {
2476         return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
2477             + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
2478 }
2479
2480 static void azt_bin2bcd(unsigned char *p)
2481 {
2482         int u, t;
2483
2484         u = *p % 10;
2485         t = *p / 10;
2486         *p = u | (t << 4);
2487 }
2488
2489 static int azt_bcd2bin(unsigned char bcd)
2490 {
2491         return (bcd >> 4) * 10 + (bcd & 0xF);
2492 }
2493
2494 MODULE_LICENSE("GPL");
2495 MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);