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