~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/cdrom/aztcd.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.